[quartz] Ensure valid GdkWindowImplQuartz references.

In case of an offscreen window find its onscreen embedder, and NULL
any GdkWindowImpl that's not quartz, checking all return values.

This replaces 16ded683, removing its unnecessary search_for_nearest
functions.

Any unchecked cast of a GdkWindowImpl to GdkWindowImplQuartz risks at
least getting an invalid member reference, not just the ones in
gdk_quartz_window_get_foo, and all calls to gdk_quartz_window_get_foo need
to be checked, not just Gtk's internal calls. The motivation was that
transient_for was getting set on a Gimp offscreen window and that caused a
crash in raise_transient.
This commit is contained in:
John Ralls 2022-06-06 12:29:42 -07:00
parent 749c863073
commit a2c54c739e
8 changed files with 245 additions and 208 deletions

View File

@ -27,6 +27,7 @@
#include "gdkprivate-quartz.h"
#include "gdkquartzdevice-core.h"
#include "gdkinternal-quartz.h"
#include "gdkquartz-cocoa-access.h"
struct _GdkQuartzDeviceCore
{
@ -230,7 +231,7 @@ gdk_quartz_device_core_query_state_helper (GdkWindow *window,
{
NSWindow *nswindow;
nswindow = gdk_quartz_window_search_for_nearest_nswindow (window);
nswindow = gdk_quartz_window_get_nswindow (window);
point = [nswindow mouseLocationOutsideOfEventStream];

View File

@ -35,6 +35,7 @@
#include "gdkquartzdisplay.h"
#include "gdkprivate-quartz.h"
#include "gdkinternal-quartz.h"
#include "gdkquartz-cocoa-access.h"
#include "gdkquartzdevicemanager-core.h"
#include "gdkquartzkeys.h"
#include "gdkkeys-quartz.h"
@ -387,7 +388,7 @@ get_window_point_from_screen_point (GdkWindow *window,
NSPoint point;
GdkQuartzNSWindow *nswindow;
nswindow = gdk_quartz_window_search_for_nearest_nswindow (window);
nswindow = gdk_quartz_window_get_nswindow (window);
point = [nswindow convertPointFromScreen:screen_point];
*x = point.x;
*y = window->height - point.y;

View File

@ -28,7 +28,7 @@
#include "gdkquartzglcontext.h"
#include "gdkquartzwindow.h"
#include "gdkprivate-quartz.h"
#include "gdkinternal-quartz.h"
#include "gdkquartz-cocoa-access.h"
#include "gdkinternals.h"
@ -138,7 +138,7 @@ gdk_quartz_window_create_gl_context (GdkWindow *window,
if (attached)
{
NSView *view = gdk_quartz_window_search_for_nearest_nsview (window);
NSView *view = gdk_quartz_window_get_nsview (window);
if ([view respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)])
[view setWantsBestResolutionOpenGLSurface:YES];

View File

@ -124,75 +124,41 @@ gdk_quartz_window_init (GdkQuartzWindow *quartz_window)
/*
* GdkQuartzWindowImpl
*/
static inline NSObject *
gdk_quartz_window_search_for_nearest_nsobject (GdkWindow *window, bool get_nswindow_instead_of_nsview)
static inline GdkWindowImplQuartz*
gdk_window_get_quartz_impl (GdkWindow* window)
{
GdkWindow *onscreen_window = window;
NSObject *nsobject = NULL;
GdkWindow *embedder;
if (GDK_WINDOW_DESTROYED (window))
return NULL;
/*
* if window is type GDK_WINDOW_OFFSCREEN
* you need to get the embedder in order to find the NSView
* see: gdkdevice.c:1461
*/
while (1)
embedder = gdk_offscreen_window_get_embedder (window);
while (embedder)
{
g_return_val_if_fail (onscreen_window != NULL, NULL);
if (GDK_IS_WINDOW_IMPL_QUARTZ (onscreen_window->impl))
{
if (get_nswindow_instead_of_nsview)
nsobject = GDK_WINDOW_IMPL_QUARTZ (onscreen_window->impl)->toplevel;
else
nsobject = GDK_WINDOW_IMPL_QUARTZ (onscreen_window->impl)->view;
if (nsobject != NULL)
break;
}
if (onscreen_window->window_type == GDK_WINDOW_OFFSCREEN)
onscreen_window = gdk_offscreen_window_get_embedder (onscreen_window);
else
onscreen_window = onscreen_window->parent;
window = embedder;
embedder = gdk_offscreen_window_get_embedder (window);
}
g_return_val_if_fail (nsobject != NULL, NULL);
g_return_val_if_fail (GDK_IS_WINDOW_IMPL_QUARTZ (window->impl), NULL);
return nsobject;
}
NSView *
gdk_quartz_window_search_for_nearest_nsview (GdkWindow *window)
{
return (NSView *)gdk_quartz_window_search_for_nearest_nsobject (window, FALSE);
}
NSWindow *
gdk_quartz_window_search_for_nearest_nswindow (GdkWindow *window)
{
return (NSWindow *)gdk_quartz_window_search_for_nearest_nsobject (window, TRUE);
return window->impl;
}
NSView *
gdk_quartz_window_get_nsview (GdkWindow *window)
{
if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW_IMPL_QUARTZ (window->impl))
return NULL;
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
return GDK_WINDOW_IMPL_QUARTZ (window->impl)->view;
return impl ? impl->view : NULL;
}
NSWindow *
gdk_quartz_window_get_nswindow (GdkWindow *window)
{
if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW_IMPL_QUARTZ (window->impl))
return NULL;
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
return GDK_WINDOW_IMPL_QUARTZ (window->impl)->toplevel;
return impl ? impl->toplevel : NULL;
}
static CGContextRef
@ -329,9 +295,9 @@ gdk_quartz_create_cairo_surface (GdkWindowImplQuartz *impl,
static cairo_surface_t *
gdk_quartz_ref_cairo_surface (GdkWindow *window)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
if (GDK_WINDOW_DESTROYED (window))
if (GDK_WINDOW_DESTROYED (window) || !impl)
return NULL;
if (!impl->cairo_surface)
@ -361,8 +327,8 @@ gdk_quartz_ref_cairo_surface (GdkWindow *window)
void
_gdk_quartz_unref_cairo_surface (GdkWindow *window)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
if (GDK_WINDOW_DESTROYED (window))
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
if (GDK_WINDOW_DESTROYED (window) || !impl)
return;
if (impl->cairo_surface)
@ -397,7 +363,10 @@ gdk_quartz_window_set_needs_display_in_region (GdkWindow *window,
GdkWindowImplQuartz *impl;
int i, n_rects;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (!impl)
return;
if (!impl->needs_display_region)
impl->needs_display_region = cairo_region_create ();
@ -423,16 +392,13 @@ _gdk_quartz_window_process_updates_recurse (GdkWindow *window,
*/
if (in_process_all_updates)
{
GdkWindow *toplevel;
GdkWindow *toplevel= gdk_window_get_effective_toplevel (window);
GdkWindowImplQuartz *toplevel_impl =
gdk_window_get_quartz_impl (toplevel);
toplevel = gdk_window_get_effective_toplevel (window);
if (toplevel && WINDOW_IS_TOPLEVEL (toplevel))
if (toplevel && WINDOW_IS_TOPLEVEL (toplevel) && toplevel_impl)
{
GdkWindowImplQuartz *toplevel_impl;
NSWindow *nswindow;
toplevel_impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
nswindow = toplevel_impl->toplevel;
NSWindow *nswindow = toplevel_impl->toplevel;
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
/* In theory, we could skip the flush disabling, since we only
* have one NSView.
@ -701,15 +667,17 @@ find_child_window_helper (GdkWindow *window,
GdkWindowImplQuartz *impl;
GList *l;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (window == _gdk_root)
update_toplevel_order ();
g_return_val_if_fail (impl, NULL);
for (l = impl->sorted_children; l; l = l->next)
{
GdkWindow *child = l->data;
GdkWindowImplQuartz *child_impl = GDK_WINDOW_IMPL_QUARTZ (child->impl);
GdkWindowImplQuartz *child_impl = gdk_window_get_quartz_impl (child);
int temp_x, temp_y;
if (!GDK_WINDOW_IS_MAPPED (child))
@ -724,7 +692,7 @@ find_child_window_helper (GdkWindow *window,
* better way to deal with the events in gdkevents-quartz, this
* might not be needed.)
*/
if (window == _gdk_root)
if (child_impl && window == _gdk_root)
{
NSRect frame = NSMakeRect (0, 0, 100, 100);
NSRect content;
@ -793,23 +761,27 @@ raise_transient (GdkWindowImplQuartz *impl)
* parent and then add it back in.
*/
GdkWindowImplQuartz *parent_impl =
GDK_WINDOW_IMPL_QUARTZ (impl->transient_for->impl);
[parent_impl->toplevel removeChildWindow:impl->toplevel];
[parent_impl->toplevel addChildWindow:impl->toplevel
ordered:NSWindowAbove];
gdk_window_get_quartz_impl (impl->transient_for);
if (parent_impl)
{
[parent_impl->toplevel removeChildWindow:impl->toplevel];
[parent_impl->toplevel addChildWindow:impl->toplevel
ordered:NSWindowAbove];
}
}
void
_gdk_quartz_window_did_become_main (GdkWindow *window)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
main_window_stack = g_slist_remove (main_window_stack, window);
if (window->window_type != GDK_WINDOW_TEMP)
main_window_stack = g_slist_prepend (main_window_stack, window);
if (impl->transient_for)
if (impl &&
impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
raise_transient (impl);
clear_toplevel_order ();
@ -837,9 +809,10 @@ _gdk_quartz_window_did_resign_main (GdkWindow *window)
GDK_WINDOW_IS_MAPPED (new_window) &&
WINDOW_IS_TOPLEVEL (new_window))
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (new_window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (new_window);
[impl->toplevel makeKeyAndOrderFront:impl->toplevel];
if (impl)
[impl->toplevel makeKeyAndOrderFront:impl->toplevel];
}
clear_toplevel_order ();
@ -883,12 +856,12 @@ static void
on_frame_clock_after_paint (GdkFrameClock *frame_clock,
GdkWindow *window)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
GdkDisplay *display = gdk_window_get_display (window);
GdkFrameTimings *timings;
timings = gdk_frame_clock_get_current_timings (frame_clock);
if (timings != NULL)
if (impl && timings != NULL)
impl->pending_frame_counter = timings->frame_counter;
_gdk_quartz_display_add_frame_callback (display, window);
@ -916,7 +889,7 @@ _gdk_quartz_display_create_window_impl (GdkDisplay *display,
window->impl = GDK_WINDOW_IMPL (impl);
impl->wrapper = window;
parent_impl = GDK_WINDOW_IMPL_QUARTZ (window->parent->impl);
parent_impl = gdk_window_get_quartz_impl (window->parent);
switch (window->window_type)
{
@ -925,12 +898,12 @@ _gdk_quartz_display_create_window_impl (GdkDisplay *display,
if (GDK_WINDOW_TYPE (window->parent) != GDK_WINDOW_ROOT)
{
/* The common code warns for this case */
parent_impl = GDK_WINDOW_IMPL_QUARTZ (_gdk_root->impl);
parent_impl = gdk_window_get_quartz_impl (_gdk_root);
}
}
/* Maintain the z-ordered list of children. */
if (window->parent != _gdk_root)
if (parent_impl && window->parent != _gdk_root)
parent_impl->sorted_children = g_list_prepend (parent_impl->sorted_children, window);
else
clear_toplevel_order ();
@ -1023,9 +996,9 @@ _gdk_quartz_display_create_window_impl (GdkDisplay *display,
case GDK_WINDOW_CHILD:
{
GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (window->parent->impl);
GdkWindowImplQuartz *parent_impl = gdk_window_get_quartz_impl (window->parent);
if (!window->input_only)
if (parent_impl && !window->input_only)
{
NSRect frame_rect = NSMakeRect (window->x + window->parent->abs_x,
window->y + window->parent->abs_y,
@ -1065,7 +1038,10 @@ _gdk_quartz_window_update_position (GdkWindow *window)
{
NSRect frame_rect;
NSRect content_rect;
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
if (!impl)
return;
GDK_QUARTZ_ALLOC_POOL;
@ -1076,7 +1052,6 @@ _gdk_quartz_window_update_position (GdkWindow *window)
content_rect.origin.y + content_rect.size.height,
&window->x, &window->y);
GDK_QUARTZ_RELEASE_POOL;
}
@ -1094,7 +1069,13 @@ _gdk_quartz_window_init_windowing (GdkDisplay *display,
_gdk_root->impl_window = _gdk_root;
_gdk_root->visual = gdk_screen_get_system_visual (screen);
impl = GDK_WINDOW_IMPL_QUARTZ (_gdk_root->impl);
impl = gdk_window_get_quartz_impl (_gdk_root);
/* If impl is somehow not a GdkWindowImplQuartz we're screwed, so crash. */
if (!impl)
{
g_error ("Initializing quartz windowing produced the wrong kind of impl!");
g_abort ();
}
_gdk_quartz_screen_update_window_sizes (screen);
@ -1115,7 +1096,10 @@ gdk_quartz_window_destroy (GdkWindow *window,
GdkWindow *parent;
GdkDisplay *display;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (!impl)
return;
display = gdk_window_get_display (window);
@ -1129,9 +1113,10 @@ gdk_quartz_window_destroy (GdkWindow *window,
parent = window->parent;
if (parent)
{
GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
GdkWindowImplQuartz *parent_impl = gdk_window_get_quartz_impl (parent);
parent_impl->sorted_children = g_list_remove (parent_impl->sorted_children, window);
if (parent_impl)
parent_impl->sorted_children = g_list_remove (parent_impl->sorted_children, window);
}
if (impl->cairo_surface)
@ -1170,9 +1155,12 @@ gdk_quartz_window_destroy_foreign (GdkWindow *window)
static void
gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
gboolean focus_on_map;
if (!impl)
return;
GDK_QUARTZ_ALLOC_POOL;
if (!GDK_WINDOW_IS_MAPPED (window))
@ -1223,17 +1211,20 @@ _gdk_quartz_window_detach_from_parent (GdkWindow *window)
g_return_if_fail (GDK_IS_WINDOW (window));
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
g_return_if_fail (impl->toplevel != NULL);
impl = gdk_window_get_quartz_impl (window);
g_return_if_fail (impl && impl->toplevel != NULL);
if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
{
GdkWindowImplQuartz *parent_impl;
parent_impl = GDK_WINDOW_IMPL_QUARTZ (impl->transient_for->impl);
[parent_impl->toplevel removeChildWindow:impl->toplevel];
clear_toplevel_order ();
parent_impl = gdk_window_get_quartz_impl (impl->transient_for);
if (parent_impl)
{
[parent_impl->toplevel removeChildWindow:impl->toplevel];
clear_toplevel_order ();
}
}
}
@ -1245,17 +1236,20 @@ _gdk_quartz_window_attach_to_parent (GdkWindow *window)
g_return_if_fail (GDK_IS_WINDOW (window));
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
g_return_if_fail (impl->toplevel != NULL);
impl = gdk_window_get_quartz_impl (window);
g_return_if_fail (impl && impl->toplevel != NULL);
if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
{
GdkWindowImplQuartz *parent_impl;
parent_impl = GDK_WINDOW_IMPL_QUARTZ (impl->transient_for->impl);
[parent_impl->toplevel addChildWindow:impl->toplevel ordered:NSWindowAbove];
clear_toplevel_order ();
parent_impl = gdk_window_get_quartz_impl (impl->transient_for);
if (parent_impl)
{
[parent_impl->toplevel addChildWindow:impl->toplevel ordered:NSWindowAbove];
clear_toplevel_order ();
}
}
}
@ -1275,9 +1269,11 @@ gdk_window_quartz_hide (GdkWindow *window)
_gdk_window_clear_update_area (window);
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (!impl)
return;
if (WINDOW_IS_TOPLEVEL (window))
if (WINDOW_IS_TOPLEVEL (window))
{
/* Update main window. */
main_window_stack = g_slist_remove (main_window_stack, window);
@ -1315,12 +1311,14 @@ move_resize_window_internal (GdkWindow *window,
cairo_region_t *old_region;
cairo_region_t *expose_region;
NSSize delta;
gboolean resized = FALSE;
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (!impl)
return;
if ((x == -1 || (x == window->x)) &&
(y == -1 || (y == window->y)) &&
@ -1364,15 +1362,11 @@ move_resize_window_internal (GdkWindow *window,
if (width != -1)
{
if (window->width != width)
resized = TRUE;
window->width = width;
}
if (height != -1)
{
if (window->height != height)
resized = TRUE;
window->height = height;
}
@ -1538,14 +1532,21 @@ gdk_window_quartz_reparent (GdkWindow *window,
return FALSE;
}
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (!impl)
return FALSE;
view = impl->view;
new_parent_impl = GDK_WINDOW_IMPL_QUARTZ (new_parent->impl);
new_parent_impl = gdk_window_get_quartz_impl (new_parent);
if (!new_parent_impl)
return FALSE;
new_parent_view = new_parent_impl->view;
old_parent = window->parent;
old_parent_impl = GDK_WINDOW_IMPL_QUARTZ (old_parent->impl);
old_parent_impl = gdk_window_get_quartz_impl (old_parent);
if (!old_parent_impl)
return FALSE;
[view retain];
@ -1578,9 +1579,9 @@ update_toplevel_order (void)
id nswindow;
GList *toplevels = NULL;
root_impl = GDK_WINDOW_IMPL_QUARTZ (_gdk_root->impl);
root_impl = gdk_window_get_quartz_impl (_gdk_root);
if (root_impl->sorted_children)
if (!root_impl || root_impl->sorted_children)
return;
GDK_QUARTZ_ALLOC_POOL;
@ -1607,10 +1608,12 @@ clear_toplevel_order (void)
{
GdkWindowImplQuartz *root_impl;
root_impl = GDK_WINDOW_IMPL_QUARTZ (_gdk_root->impl);
g_list_free (root_impl->sorted_children);
root_impl->sorted_children = NULL;
root_impl = gdk_window_get_quartz_impl (_gdk_root);
if (root_impl)
{
g_list_free (root_impl->sorted_children);
root_impl->sorted_children = NULL;
}
}
static void
@ -1623,9 +1626,10 @@ gdk_window_quartz_raise (GdkWindow *window)
{
GdkWindowImplQuartz *impl;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
if (impl->transient_for)
impl = gdk_window_get_quartz_impl (window);
if (!impl)
return;
if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
raise_transient (impl);
else
[impl->toplevel orderFront:impl->toplevel];
@ -1640,10 +1644,12 @@ gdk_window_quartz_raise (GdkWindow *window)
{
GdkWindowImplQuartz *impl;
impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
impl->sorted_children = g_list_remove (impl->sorted_children, window);
impl->sorted_children = g_list_prepend (impl->sorted_children, window);
impl = gdk_window_get_quartz_impl (parent);
if (impl)
{
impl->sorted_children = g_list_remove (impl->sorted_children, window);
impl->sorted_children = g_list_prepend (impl->sorted_children, window);
}
}
}
}
@ -1658,10 +1664,13 @@ gdk_window_quartz_lower (GdkWindow *window)
{
GdkWindowImplQuartz *impl;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
[impl->toplevel orderBack:impl->toplevel];
impl = gdk_window_get_quartz_impl (window);
if (impl)
{
[impl->toplevel orderBack:impl->toplevel];
clear_toplevel_order ();
clear_toplevel_order ();
}
}
else
{
@ -1671,10 +1680,12 @@ gdk_window_quartz_lower (GdkWindow *window)
{
GdkWindowImplQuartz *impl;
impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
impl->sorted_children = g_list_remove (impl->sorted_children, window);
impl->sorted_children = g_list_append (impl->sorted_children, window);
impl = gdk_window_get_quartz_impl (parent);
if (impl)
{
impl->sorted_children = g_list_remove (impl->sorted_children, window);
impl->sorted_children = g_list_append (impl->sorted_children, window);
}
}
}
}
@ -1685,13 +1696,15 @@ gdk_window_quartz_restack_toplevel (GdkWindow *window,
gboolean above)
{
GdkWindowImplQuartz *impl;
gint sibling_num;
gint sibling_num = -1;
impl = GDK_WINDOW_IMPL_QUARTZ (sibling->impl);
sibling_num = [impl->toplevel windowNumber];
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (sibling);
if (impl)
sibling_num = [impl->toplevel windowNumber];
impl = gdk_window_get_quartz_impl (window);
if (!(impl && sibling_num >= 0))
return;
if (above)
[impl->toplevel orderWindow:NSWindowAbove relativeTo:sibling_num];
else
@ -1735,7 +1748,9 @@ gdk_window_quartz_get_geometry (GdkWindow *window,
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (!impl)
return;
if (window == _gdk_root)
{
if (x)
@ -1827,7 +1842,10 @@ gdk_window_quartz_get_root_coords (GdkWindow *window,
}
toplevel = gdk_window_get_toplevel (window);
impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
impl = gdk_window_get_quartz_impl (toplevel);
if (!impl)
return;
content_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
@ -1894,8 +1912,8 @@ gdk_window_quartz_get_device_state_helper (GdkWindow *window,
GdkWindowImplQuartz *impl;
NSWindow *nswindow;
impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
nswindow = impl->toplevel;
impl = gdk_window_get_quartz_impl (toplevel);
nswindow = impl ? impl->toplevel : NULL;
point = [nswindow mouseLocationOutsideOfEventStream];
@ -1970,8 +1988,8 @@ gdk_quartz_window_set_geometry_hints (GdkWindow *window,
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
if (!impl->toplevel)
impl = gdk_window_get_quartz_impl (window);
if (!(impl && impl->toplevel))
return;
if (geom_mask & GDK_HINT_POS)
@ -2057,9 +2075,9 @@ gdk_quartz_window_set_title (GdkWindow *window,
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (impl->toplevel)
if (impl && impl->toplevel)
{
GDK_QUARTZ_ALLOC_POOL;
[impl->toplevel setTitle:[NSString stringWithUTF8String:title]];
@ -2096,8 +2114,8 @@ gdk_quartz_window_set_transient_for (GdkWindow *window,
!WINDOW_IS_TOPLEVEL (window))
return;
window_impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
if (!window_impl->toplevel)
window_impl = gdk_window_get_quartz_impl (window);
if (!(window_impl && window_impl->toplevel))
return;
GDK_QUARTZ_ALLOC_POOL;
@ -2110,8 +2128,8 @@ gdk_quartz_window_set_transient_for (GdkWindow *window,
window_impl->transient_for = NULL;
}
parent_impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
if (parent_impl->toplevel)
parent_impl = gdk_window_get_quartz_impl (parent);
if (parent_impl && parent_impl->toplevel)
{
/* We save the parent because it needs to be unset/reset when
* hiding and showing the window.
@ -2189,11 +2207,12 @@ gdk_quartz_window_focus (GdkWindow *window,
guint32 timestamp)
{
GdkWindowImplQuartz *impl;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (GDK_WINDOW_DESTROYED (window) ||
!WINDOW_IS_TOPLEVEL (window))
!WINDOW_IS_TOPLEVEL (window) ||
!impl)
return;
if (window->accept_focus && window->window_type != GDK_WINDOW_TEMP)
@ -2358,7 +2377,10 @@ gdk_quartz_window_set_type_hint (GdkWindow *window,
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (!impl)
return;
impl->type_hint = hint;
@ -2380,7 +2402,7 @@ gdk_quartz_window_get_type_hint (GdkWindow *window)
!WINDOW_IS_TOPLEVEL (window))
return GDK_WINDOW_TYPE_HINT_NORMAL;
return GDK_WINDOW_IMPL_QUARTZ (window->impl)->type_hint;
return gdk_window_get_quartz_impl (window)->type_hint;
}
static void
@ -2432,11 +2454,11 @@ gdk_quartz_window_begin_resize_drag (GdkWindow *window,
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (!impl->toplevel)
if (!(impl && impl->toplevel))
{
g_warning ("Can't call gdk_window_begin_resize_drag on non-toplevel window");
g_warning ("Can't call gdk_window_begin_resize_drag on non-quartz or non-toplevel window");
return;
}
@ -2457,11 +2479,11 @@ gdk_quartz_window_begin_move_drag (GdkWindow *window,
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (!impl->toplevel)
if (!(impl && impl->toplevel))
{
g_warning ("Can't call gdk_window_begin_move_drag on non-toplevel window");
g_warning ("Can't call gdk_window_begin_move_drag on non-quartz or non-toplevel window");
return;
}
@ -2492,7 +2514,10 @@ gdk_quartz_window_get_frame_extents (GdkWindow *window,
rect->height = 1;
toplevel = gdk_window_get_effective_toplevel (window);
impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
impl = gdk_window_get_quartz_impl (toplevel);
if (!impl)
return;
ns_rect = [impl->toplevel frame];
@ -2524,10 +2549,11 @@ gdk_quartz_window_set_decorations (GdkWindow *window,
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP ||
impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN )
(impl &&
impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN ))
{
new_mask = GDK_QUARTZ_BORDERLESS_WINDOW;
}
@ -2649,12 +2675,13 @@ gdk_quartz_window_get_decorations (GdkWindow *window,
!WINDOW_IS_TOPLEVEL (window))
return FALSE;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (decorations)
{
/* Borderless is 0, so we can't check it as a bit being set. */
if ([impl->toplevel styleMask] == GDK_QUARTZ_BORDERLESS_WINDOW)
if (impl &&
[impl->toplevel styleMask] == GDK_QUARTZ_BORDERLESS_WINDOW)
{
*decorations = 0;
}
@ -2677,7 +2704,7 @@ gdk_quartz_window_set_functions (GdkWindow *window,
g_return_if_fail (GDK_IS_WINDOW (window));
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (functions & GDK_FUNC_ALL)
{
@ -2692,7 +2719,7 @@ gdk_quartz_window_set_functions (GdkWindow *window,
close = (functions & GDK_FUNC_CLOSE);
}
if (impl->toplevel)
if (impl && impl->toplevel)
{
NSUInteger mask = [impl->toplevel styleMask];
@ -2741,10 +2768,11 @@ gdk_quartz_window_maximize (GdkWindow *window)
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
maximized = gdk_window_get_state (window) & GDK_WINDOW_STATE_MAXIMIZED;
if (GDK_WINDOW_IS_MAPPED (window))
if (GDK_WINDOW_IS_MAPPED (window) &&
impl)
{
GDK_QUARTZ_ALLOC_POOL;
@ -2765,10 +2793,11 @@ gdk_quartz_window_unmaximize (GdkWindow *window)
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
maximized = gdk_window_get_state (window) & GDK_WINDOW_STATE_MAXIMIZED;
if (GDK_WINDOW_IS_MAPPED (window))
if (GDK_WINDOW_IS_MAPPED (window) &&
impl)
{
GDK_QUARTZ_ALLOC_POOL;
@ -2788,9 +2817,10 @@ gdk_quartz_window_iconify (GdkWindow *window)
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (GDK_WINDOW_IS_MAPPED (window))
if (GDK_WINDOW_IS_MAPPED (window) &&
impl)
{
GDK_QUARTZ_ALLOC_POOL;
@ -2816,9 +2846,10 @@ gdk_quartz_window_deiconify (GdkWindow *window)
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (GDK_WINDOW_IS_MAPPED (window))
if (GDK_WINDOW_IS_MAPPED (window) &&
impl)
{
GDK_QUARTZ_ALLOC_POOL;
@ -2838,10 +2869,11 @@ gdk_quartz_window_deiconify (GdkWindow *window)
static gboolean
window_is_fullscreen (GdkWindow *window)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
if (gdk_quartz_osx_version() >= GDK_OSX_LION)
if (impl &&
gdk_quartz_osx_version() >= GDK_OSX_LION)
return ([impl->toplevel styleMask] & GDK_QUARTZ_FULLSCREEN_WINDOW) != 0;
else
#endif
@ -2857,10 +2889,11 @@ gdk_quartz_window_fullscreen (GdkWindow *window)
!WINDOW_IS_TOPLEVEL (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
if (gdk_quartz_osx_version() >= GDK_OSX_LION)
if (gdk_quartz_osx_version() >= GDK_OSX_LION &&
impl)
{
if (!window_is_fullscreen (window))
[impl->toplevel toggleFullScreen:nil];
@ -2869,11 +2902,12 @@ gdk_quartz_window_fullscreen (GdkWindow *window)
{
#endif
FullscreenSavedGeometry *geometry;
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
NSRect frame;
if (GDK_WINDOW_DESTROYED (window) ||
!WINDOW_IS_TOPLEVEL (window))
!WINDOW_IS_TOPLEVEL (window) ||
!impl)
return;
geometry = get_fullscreen_geometry (window);
@ -2925,19 +2959,21 @@ gdk_quartz_window_unfullscreen (GdkWindow *window)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
if (gdk_quartz_osx_version() >= GDK_OSX_LION)
{
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (window_is_fullscreen (window))
if (window_is_fullscreen (window) &&
impl)
[impl->toplevel toggleFullScreen:nil];
}
else
{
#endif
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
FullscreenSavedGeometry *geometry;
if (GDK_WINDOW_DESTROYED (window) ||
!WINDOW_IS_TOPLEVEL (window))
!WINDOW_IS_TOPLEVEL (window) ||
!impl)
return;
geometry = get_fullscreen_geometry (window);
@ -3002,10 +3038,11 @@ static void
gdk_quartz_window_set_keep_above (GdkWindow *window,
gboolean setting)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
gint level;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (impl);
if (GDK_WINDOW_DESTROYED (window) ||
!WINDOW_IS_TOPLEVEL (window))
@ -3021,10 +3058,11 @@ static void
gdk_quartz_window_set_keep_below (GdkWindow *window,
gboolean setting)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
gint level;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (impl);
if (GDK_WINDOW_DESTROYED (window) ||
!WINDOW_IS_TOPLEVEL (window))
@ -3062,10 +3100,11 @@ static void
gdk_quartz_window_set_opacity (GdkWindow *window,
gdouble opacity)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
g_return_if_fail (impl);
if (GDK_WINDOW_DESTROYED (window) ||
!WINDOW_IS_TOPLEVEL (window))
@ -3086,10 +3125,11 @@ gdk_quartz_window_set_shadow_width (GdkWindow *window,
gint top,
gint bottom)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
GdkWindowImplQuartz *impl = gdk_window_get_quartz_impl (window);
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
g_return_if_fail (impl);
if (GDK_WINDOW_DESTROYED (window) ||
!WINDOW_IS_TOPLEVEL (window))
@ -3127,9 +3167,10 @@ gdk_quartz_window_get_scale_factor (GdkWindow *window)
if (GDK_WINDOW_DESTROYED (window))
return 1;
impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl = gdk_window_get_quartz_impl (window);
if (impl->toplevel != NULL && gdk_quartz_osx_version() >= GDK_OSX_LION)
if (impl && impl->toplevel != NULL &&
gdk_quartz_osx_version() >= GDK_OSX_LION)
return [(id <ScaleFactor>) impl->toplevel backingScaleFactor];
return 1;
@ -3355,15 +3396,14 @@ _gdk_root_window_impl_quartz_get_type (void)
static CGContextRef
gdk_root_window_impl_quartz_get_context (GdkWindowImplQuartz *window,
gdk_root_window_impl_quartz_get_context (GdkWindowImplQuartz *window_impl,
gboolean antialias)
{
GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (window);
GdkRootWindowImplQuartz *impl = GDK_ROOT_WINDOW_IMPL_QUARTZ (window);
GdkRootWindowImplQuartz *impl = GDK_ROOT_WINDOW_IMPL_QUARTZ (window_impl);
CGSize size;
CGLayerRef layer;
if (GDK_WINDOW_DESTROYED (window_impl->wrapper))
if (!window_impl || GDK_WINDOW_DESTROYED (window_impl->wrapper))
return NULL;
size.width = gdk_window_get_width (window_impl->wrapper);

View File

@ -87,11 +87,6 @@ CGContextRef gdk_quartz_window_get_context (GdkWindowImplQuartz *window,
void gdk_quartz_window_release_context (GdkWindowImplQuartz *window,
CGContextRef context);
_GDK_EXTERN /* Required for immmodule.cache */
NSView * gdk_quartz_window_search_for_nearest_nsview (GdkWindow *window);
_GDK_EXTERN /* Required for immmodule.cache */
NSWindow * gdk_quartz_window_search_for_nearest_nswindow (GdkWindow *window);
/* Root window implementation for Quartz
*/

View File

@ -42,7 +42,7 @@
#include "gtkintl.h"
#include "gtkquartz.h"
#include "gdk/quartz/gdkquartz.h"
#include "gdk/quartz/gdkinternal-quartz.h"
#include "gdk/quartz/gdkquartz-cocoa-access.h"
#include "gdk/quartz/gdkquartz-gtk-only.h"
#include "gdk/quartz/gdkquartzdnd.h"
#include "gtkselectionprivate.h"
@ -364,7 +364,7 @@ get_toplevel_nswindow (GtkWidget *widget)
return NULL;
if (gtk_widget_is_toplevel (toplevel) && window)
return [gdk_quartz_window_search_for_nearest_nsview (window) window];
return [gdk_quartz_window_get_nsview (window) window];
else
return NULL;
}

View File

@ -40,7 +40,7 @@
#include "gtklabel.h"
#include "gtkfilechooserentry.h"
#include "gtkfilefilterprivate.h"
#include "gdk/quartz/gdkinternal-quartz.h"
#include <quartz/gdkquartz-cocoa-access.h>
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
typedef struct {
@ -533,7 +533,7 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
if (transient_for)
{
gtk_widget_realize (GTK_WIDGET (transient_for));
data->parent = gdk_quartz_window_search_for_nearest_nswindow (gtk_widget_get_window (GTK_WIDGET (transient_for)));
data->parent = gdk_quartz_window_get_nswindow (gtk_widget_get_window (GTK_WIDGET (transient_for)));
if (gtk_native_dialog_get_modal (GTK_NATIVE_DIALOG (self)))
data->modal = TRUE;

View File

@ -227,7 +227,7 @@ quartz_filter_keypress (GtkIMContext *context,
return gtk_im_context_filter_keypress (qc->slave, event);
}
nsview = gdk_quartz_window_search_for_nearest_nsview (qc->client_window);
nsview = gdk_quartz_window_get_nsview (qc->client_window);
win = (GdkWindow *)[(GdkQuartzView *)[[nsevent window] contentView] gdkWindow];
GTK_NOTE (MISC, g_print ("client_window: %p, win: %p, nsview: %p\n",
@ -272,7 +272,7 @@ discard_preedit (GtkIMContext *context)
if (!GDK_IS_QUARTZ_WINDOW (qc->client_window))
return;
NSView *nsview = gdk_quartz_window_search_for_nearest_nsview (qc->client_window);
NSView *nsview = gdk_quartz_window_get_nsview (qc->client_window);
if (!nsview)
return;
@ -361,7 +361,7 @@ quartz_set_cursor_location (GtkIMContext *context, GdkRectangle *area)
if (!GDK_IS_QUARTZ_WINDOW (qc->client_window))
return;
nsview = gdk_quartz_window_search_for_nearest_nsview (qc->client_window);
nsview = gdk_quartz_window_get_nsview (qc->client_window);
if (nsview == NULL)
return;