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:
Kristian Rietveld
2010-08-15 13:24:58 +02:00
parent 370dfc16ca
commit 77b703c2fc
2 changed files with 29 additions and 18 deletions

View File

@ -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;

View File

@ -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,
}
}
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]);
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];