summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Oberhuber <lukaso@gmail.com>2021-12-16 13:00:02 +0000
committerLukas Oberhuber <lukaso@gmail.com>2021-12-16 13:00:02 +0000
commit71e2821578c32e5680739415ce7a38bb57ac0ceb (patch)
treeb1ff345251d11e5e70e8ff7a43c6c07c85fa0095
parentff06d5d59faeb6071c0d34d251c0f6061590463e (diff)
downloadgtk+-71e2821578c32e5680739415ce7a38bb57ac0ceb.tar.gz
gdkquartz: fix crash on uninitialized attribute
`gdk_quartz_display_get_monitor_at_window` crashes when it tries to access the NSWindow on an offscreen window. The attribute `toplevel` of `impl` is uninitialized and causes a segfault. This partially fixes: https://gitlab.gnome.org/GNOME/gimp/-/issues/7608
-rw-r--r--gdk/quartz/gdkdisplay-quartz.c26
-rw-r--r--gdk/quartz/gdkwindow-quartz.c1
2 files changed, 24 insertions, 3 deletions
diff --git a/gdk/quartz/gdkdisplay-quartz.c b/gdk/quartz/gdkdisplay-quartz.c
index 6186b32925..0587ca8f2f 100644
--- a/gdk/quartz/gdkdisplay-quartz.c
+++ b/gdk/quartz/gdkdisplay-quartz.c
@@ -33,6 +33,7 @@
#include "gdkmonitor-quartz.h"
#include "gdkglcontext-quartz.h"
#include "gdkinternal-quartz.h"
+#include "gdkwindow.h"
/* Note about coordinates: There are three coordinate systems at play:
*
@@ -453,10 +454,29 @@ static GdkMonitor *
gdk_quartz_display_get_monitor_at_window (GdkDisplay *display,
GdkWindow *window)
{
- GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
- NSWindow *nswindow = impl->toplevel;
- NSScreen *screen = [nswindow screen];
+ GdkWindowImplQuartz *impl = NULL;
+ NSWindow *nswindow = NULL;
+ NSScreen *screen = NULL;
GdkMonitor *monitor = NULL;
+ GdkWindow *onscreen_window = window;
+
+ /*
+ * This stops crashes when there is no NSWindow available on
+ * an offscreen window which occurs for children of children
+ * of an onscreen window (children of an onscreen window do
+ * have NSWindow set)
+ * https://gitlab.gnome.org/GNOME/gimp/-/issues/7608
+ */
+ while (onscreen_window && onscreen_window->window_type == GDK_WINDOW_OFFSCREEN)
+ onscreen_window = onscreen_window->parent;
+
+ if (!onscreen_window)
+ return NULL;
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (onscreen_window->impl);
+ nswindow = impl->toplevel;
+ screen = [nswindow screen];
+
if (screen)
{
GdkQuartzDisplay *quartz_display = GDK_QUARTZ_DISPLAY (display);
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
index a5c5c31945..30e62a7574 100644
--- a/gdk/quartz/gdkwindow-quartz.c
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -879,6 +879,7 @@ _gdk_quartz_display_create_window_impl (GdkDisplay *display,
NULL));
impl->view = NULL;
+ impl->toplevel = NULL;
if (attributes_mask & GDK_WA_TYPE_HINT)
{