quartz: stop offscreen windows code from crashing.
This is an adapted version of commit bde0f9a8f68b626aac364690e8658b28decb3ee1 on master. Mainly fixes to properly differentiate bewteen toplevel and offscreen windows, since these sometimes need different treatment. Furthermore, usage of gdk_window_get_effective_foo() instead of gdk_window_get_foo() where applicable. There is an drawing issue left when scrolling e.g. tree views in offscreen windows. I think this is likely an issue with gdk_quartz_draw_drawable() which is used for the copy area code in offscreen windows. It works fine in master, since this was converted to Cairo.
This commit is contained in:
@ -36,6 +36,11 @@
|
||||
#define GRIP_WIDTH 15
|
||||
#define GRIP_HEIGHT 15
|
||||
|
||||
#define WINDOW_IS_TOPLEVEL(window) \
|
||||
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
|
||||
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
|
||||
GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
|
||||
|
||||
/* This is the window corresponding to the key window */
|
||||
static GdkWindow *current_keyboard_window;
|
||||
|
||||
@ -87,7 +92,7 @@ gdk_keyboard_grab (GdkWindow *window,
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
|
||||
|
||||
display = gdk_drawable_get_display (window);
|
||||
toplevel = gdk_window_get_toplevel (window);
|
||||
toplevel = gdk_window_get_effective_toplevel (window);
|
||||
|
||||
_gdk_display_set_has_keyboard_grab (display,
|
||||
window,
|
||||
@ -520,7 +525,7 @@ find_toplevel_under_pointer (GdkDisplay *display,
|
||||
GdkWindow *toplevel;
|
||||
|
||||
toplevel = display->pointer_info.toplevel_under_pointer;
|
||||
if (toplevel)
|
||||
if (toplevel && WINDOW_IS_TOPLEVEL (toplevel))
|
||||
{
|
||||
GdkWindowObject *private;
|
||||
NSWindow *nswindow;
|
||||
@ -599,7 +604,7 @@ find_window_for_ns_event (NSEvent *nsevent,
|
||||
* events are discarded.
|
||||
*/
|
||||
grab = _gdk_display_get_last_pointer_grab (display);
|
||||
if (grab)
|
||||
if (WINDOW_IS_TOPLEVEL (toplevel) && grab)
|
||||
{
|
||||
/* Implicit grabs do not go through XGrabPointer and thus the
|
||||
* event mask should not be checked.
|
||||
@ -637,7 +642,7 @@ find_window_for_ns_event (NSEvent *nsevent,
|
||||
GdkWindowObject *grab_private;
|
||||
NSWindow *grab_nswindow;
|
||||
|
||||
grab_toplevel = gdk_window_get_toplevel (grab->window);
|
||||
grab_toplevel = gdk_window_get_effective_toplevel (grab->window);
|
||||
grab_private = (GdkWindowObject *)grab_toplevel;
|
||||
|
||||
grab_nswindow = ((GdkWindowImplQuartz *)grab_private->impl)->toplevel;
|
||||
@ -673,7 +678,8 @@ find_window_for_ns_event (NSEvent *nsevent,
|
||||
toplevel_under_pointer = find_toplevel_under_pointer (display,
|
||||
screen_point,
|
||||
&x_tmp, &y_tmp);
|
||||
if (toplevel_under_pointer)
|
||||
if (toplevel_under_pointer
|
||||
&& WINDOW_IS_TOPLEVEL (toplevel_under_pointer))
|
||||
{
|
||||
GdkWindowObject *toplevel_private;
|
||||
GdkWindowImplQuartz *toplevel_impl;
|
||||
@ -730,7 +736,7 @@ find_window_for_ns_event (NSEvent *nsevent,
|
||||
case NSKeyUp:
|
||||
case NSFlagsChanged:
|
||||
if (_gdk_display->keyboard_grab.window && !_gdk_display->keyboard_grab.owner_events)
|
||||
return gdk_window_get_toplevel (_gdk_display->keyboard_grab.window);
|
||||
return gdk_window_get_effective_toplevel (_gdk_display->keyboard_grab.window);
|
||||
|
||||
return toplevel;
|
||||
|
||||
|
@ -386,8 +386,8 @@ _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
|
||||
{
|
||||
GdkWindow *toplevel;
|
||||
|
||||
toplevel = gdk_window_get_toplevel (window);
|
||||
if (toplevel)
|
||||
toplevel = gdk_window_get_effective_toplevel (window);
|
||||
if (toplevel && WINDOW_IS_TOPLEVEL (toplevel))
|
||||
{
|
||||
GdkWindowObject *toplevel_private;
|
||||
GdkWindowImplQuartz *toplevel_impl;
|
||||
@ -409,12 +409,17 @@ _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
gdk_region_get_rectangles (region, &rects, &n_rects);
|
||||
if (WINDOW_IS_TOPLEVEL (window))
|
||||
{
|
||||
gdk_region_get_rectangles (region, &rects, &n_rects);
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
_gdk_quartz_window_set_needs_display_in_rect (window, &rects[i]);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
_gdk_quartz_window_set_needs_display_in_rect (window, &rects[i]);
|
||||
|
||||
g_free (rects);
|
||||
g_free (rects);
|
||||
}
|
||||
else
|
||||
_gdk_window_process_updates_recurse (window, region);
|
||||
|
||||
/* NOTE: I'm not sure if we should displayIfNeeded here. It slows down a
|
||||
* lot (since it triggers the beam syncing) and things seem to work
|
||||
@ -583,7 +588,7 @@ _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number)
|
||||
return;
|
||||
}
|
||||
|
||||
toplevel = gdk_window_get_toplevel (window);
|
||||
toplevel = gdk_window_get_effective_toplevel (window);
|
||||
get_ancestor_coordinates_from_child (window, 0, 0, toplevel, &x, &y);
|
||||
|
||||
gdk_window_get_origin (toplevel, &tx, &ty);
|
||||
@ -816,7 +821,7 @@ _gdk_quartz_window_did_resign_main (GdkWindow *window)
|
||||
if (new_window &&
|
||||
new_window != window &&
|
||||
GDK_WINDOW_IS_MAPPED (new_window) &&
|
||||
GDK_WINDOW_OBJECT (new_window)->window_type != GDK_WINDOW_TEMP)
|
||||
WINDOW_IS_TOPLEVEL (new_window))
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *) new_window;
|
||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
|
||||
@ -1180,7 +1185,7 @@ gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped)
|
||||
else
|
||||
focus_on_map = TRUE;
|
||||
|
||||
if (impl->toplevel)
|
||||
if (impl->toplevel && WINDOW_IS_TOPLEVEL (window))
|
||||
{
|
||||
gboolean make_key;
|
||||
|
||||
@ -1275,7 +1280,7 @@ gdk_window_quartz_hide (GdkWindow *window)
|
||||
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
|
||||
|
||||
if (impl->toplevel)
|
||||
if (window && WINDOW_IS_TOPLEVEL (window))
|
||||
{
|
||||
/* Update main window. */
|
||||
main_window_stack = g_slist_remove (main_window_stack, window);
|
||||
@ -1917,7 +1922,7 @@ gdk_window_quartz_get_pointer_helper (GdkWindow *window,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (window));
|
||||
toplevel = GDK_WINDOW_OBJECT (gdk_window_get_effective_toplevel (window));
|
||||
|
||||
*mask = _gdk_quartz_events_get_current_event_mask ();
|
||||
|
||||
@ -2574,7 +2579,7 @@ gdk_window_get_frame_extents (GdkWindow *window,
|
||||
rect->width = 1;
|
||||
rect->height = 1;
|
||||
|
||||
toplevel = gdk_window_get_toplevel (window);
|
||||
toplevel = gdk_window_get_effective_toplevel (window);
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
|
||||
|
||||
ns_rect = [impl->toplevel frame];
|
||||
|
Reference in New Issue
Block a user