diff options
author | Lukas Oberhuber <lukaso@gmail.com> | 2021-12-16 13:00:02 +0000 |
---|---|---|
committer | Lukas Oberhuber <lukaso@gmail.com> | 2021-12-16 13:00:02 +0000 |
commit | 71e2821578c32e5680739415ce7a38bb57ac0ceb (patch) | |
tree | b1ff345251d11e5e70e8ff7a43c6c07c85fa0095 | |
parent | ff06d5d59faeb6071c0d34d251c0f6061590463e (diff) | |
download | gtk+-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.c | 26 | ||||
-rw-r--r-- | gdk/quartz/gdkwindow-quartz.c | 1 |
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) { |