Maintain a list for the stacking order of windows. Implement lower and
2007-10-23 Richard Hult <richard@imendio.com> * gdk/quartz/gdkwindow-quartz.c: (gdk_window_raise, gdk_window_lower, gdk_window_new, _gdk_windowing_window_destroy): Maintain a list for the stacking order of windows. Implement lower and raise for child windows. The list for toplevels is created on demand, and cleared when a window gets or resigns main status and when new windows are created. (find_child_window_helper): Use the sorted list to go through windows from top to bottom. Take any titlebar in consideration for toplevels, to stop events from sometimes punching through (bugs #473813 and #489370). svn path=/trunk/; revision=18940
This commit is contained in:
committed by
Richard Hult
parent
1f36660d8d
commit
c42c7be050
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
2007-10-23 Richard Hult <richard@imendio.com>
|
||||||
|
|
||||||
|
* gdk/quartz/gdkwindow-quartz.c:
|
||||||
|
(gdk_window_raise, gdk_window_lower, gdk_window_new,
|
||||||
|
_gdk_windowing_window_destroy): Maintain a list for the stacking
|
||||||
|
order of windows. Implement lower and raise for child windows. The
|
||||||
|
list for toplevels is created on demand, and cleared when a window
|
||||||
|
gets or resigns main status and when new windows are created.
|
||||||
|
(find_child_window_helper): Use the sorted list to go through
|
||||||
|
windows from top to bottom. Take any titlebar in consideration for
|
||||||
|
toplevels, to stop events from sometimes punching through (bugs
|
||||||
|
#473813 and #489370).
|
||||||
|
|
||||||
2007-10-22 Johan Dahlin <jdahlin@async.com.br>
|
2007-10-22 Johan Dahlin <jdahlin@async.com.br>
|
||||||
|
|
||||||
* gtk/gtkbuilder.c: Use gtk_ascii_tolower/toupper instead of the C
|
* gtk/gtkbuilder.c: Use gtk_ascii_tolower/toupper instead of the C
|
||||||
|
|||||||
@ -32,6 +32,9 @@ static guint update_idle;
|
|||||||
|
|
||||||
static GSList *main_window_stack;
|
static GSList *main_window_stack;
|
||||||
|
|
||||||
|
static void update_toplevel_order (void);
|
||||||
|
static void clear_toplevel_order (void);
|
||||||
|
|
||||||
#define WINDOW_IS_TOPLEVEL(window) \
|
#define WINDOW_IS_TOPLEVEL(window) \
|
||||||
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
|
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
|
||||||
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
|
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
|
||||||
@ -467,23 +470,59 @@ find_child_window_helper (GdkWindow *window,
|
|||||||
gint x_offset,
|
gint x_offset,
|
||||||
gint y_offset)
|
gint y_offset)
|
||||||
{
|
{
|
||||||
|
GdkWindowImplQuartz *impl;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
for (l = GDK_WINDOW_OBJECT (window)->children; l; l = l->next)
|
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
|
||||||
|
|
||||||
|
if (window == _gdk_root)
|
||||||
|
update_toplevel_order ();
|
||||||
|
|
||||||
|
for (l = impl->sorted_children; l; l = l->next)
|
||||||
{
|
{
|
||||||
GdkWindowObject *private = l->data;
|
GdkWindowObject *child_private = l->data;
|
||||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
|
GdkWindowImplQuartz *child_impl = GDK_WINDOW_IMPL_QUARTZ (child_private->impl);
|
||||||
int temp_x, temp_y;
|
int temp_x, temp_y;
|
||||||
|
|
||||||
if (!GDK_WINDOW_IS_MAPPED (private))
|
if (!GDK_WINDOW_IS_MAPPED (child_private))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
temp_x = x_offset + private->x;
|
temp_x = x_offset + child_private->x;
|
||||||
temp_y = y_offset + private->y;
|
temp_y = y_offset + child_private->y;
|
||||||
|
|
||||||
|
/* Special-case the root window. We have to include the title
|
||||||
|
* bar in the checks, otherwise the window below the title bar
|
||||||
|
* will be found i.e. events punch through. (If we can find a
|
||||||
|
* better way to deal with the events in gdkevents-quartz, this
|
||||||
|
* might not be needed.)
|
||||||
|
*/
|
||||||
|
if (window == _gdk_root)
|
||||||
|
{
|
||||||
|
NSRect frame = NSMakeRect (0, 0, 100, 100);
|
||||||
|
NSRect content;
|
||||||
|
int mask;
|
||||||
|
int titlebar_height;
|
||||||
|
|
||||||
|
mask = [child_impl->toplevel styleMask];
|
||||||
|
|
||||||
|
/* Get the title bar height. */
|
||||||
|
content = [NSWindow contentRectForFrameRect:frame
|
||||||
|
styleMask:mask];
|
||||||
|
titlebar_height = frame.size.height - content.size.height;
|
||||||
|
|
||||||
|
if (titlebar_height > 0 &&
|
||||||
|
x >= temp_x && y >= temp_y - titlebar_height &&
|
||||||
|
x < temp_x + child_impl->width && y < temp_y)
|
||||||
|
{
|
||||||
|
/* The root means "unknown" i.e. a window not managed by
|
||||||
|
* GDK.
|
||||||
|
*/
|
||||||
|
return (GdkWindow *)_gdk_root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: Are there off by one errors here? */
|
|
||||||
if (x >= temp_x && y >= temp_y &&
|
if (x >= temp_x && y >= temp_y &&
|
||||||
x < temp_x + impl->width && y < temp_y + impl->height)
|
x < temp_x + child_impl->width && y < temp_y + child_impl->height)
|
||||||
{
|
{
|
||||||
/* Look for child windows. */
|
/* Look for child windows. */
|
||||||
return find_child_window_helper (l->data,
|
return find_child_window_helper (l->data,
|
||||||
@ -520,6 +559,8 @@ _gdk_quartz_window_did_become_main (GdkWindow *window)
|
|||||||
|
|
||||||
if (GDK_WINDOW_OBJECT (window)->window_type != GDK_WINDOW_TEMP)
|
if (GDK_WINDOW_OBJECT (window)->window_type != GDK_WINDOW_TEMP)
|
||||||
main_window_stack = g_slist_prepend (main_window_stack, window);
|
main_window_stack = g_slist_prepend (main_window_stack, window);
|
||||||
|
|
||||||
|
clear_toplevel_order ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -549,6 +590,8 @@ _gdk_quartz_window_did_resign_main (GdkWindow *window)
|
|||||||
|
|
||||||
[impl->toplevel makeKeyAndOrderFront:impl->toplevel];
|
[impl->toplevel makeKeyAndOrderFront:impl->toplevel];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clear_toplevel_order ();
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkWindow *
|
GdkWindow *
|
||||||
@ -561,6 +604,7 @@ gdk_window_new (GdkWindow *parent,
|
|||||||
GdkWindowImplQuartz *impl;
|
GdkWindowImplQuartz *impl;
|
||||||
GdkDrawableImplQuartz *draw_impl;
|
GdkDrawableImplQuartz *draw_impl;
|
||||||
GdkVisual *visual;
|
GdkVisual *visual;
|
||||||
|
GdkWindowImplQuartz *parent_impl;
|
||||||
|
|
||||||
if (parent && GDK_WINDOW_DESTROYED (parent))
|
if (parent && GDK_WINDOW_DESTROYED (parent))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -577,6 +621,7 @@ gdk_window_new (GdkWindow *parent,
|
|||||||
draw_impl->wrapper = GDK_DRAWABLE (window);
|
draw_impl->wrapper = GDK_DRAWABLE (window);
|
||||||
|
|
||||||
private->parent = (GdkWindowObject *)parent;
|
private->parent = (GdkWindowObject *)parent;
|
||||||
|
parent_impl = GDK_WINDOW_IMPL_QUARTZ (private->parent->impl);
|
||||||
|
|
||||||
private->accept_focus = TRUE;
|
private->accept_focus = TRUE;
|
||||||
private->focus_on_map = TRUE;
|
private->focus_on_map = TRUE;
|
||||||
@ -675,8 +720,13 @@ gdk_window_new (GdkWindow *parent,
|
|||||||
g_object_ref (draw_impl->colormap);
|
g_object_ref (draw_impl->colormap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (private->parent)
|
private->parent->children = g_list_prepend (private->parent->children, window);
|
||||||
private->parent->children = g_list_prepend (private->parent->children, window);
|
|
||||||
|
/* Maintain the z-ordered list of children. */
|
||||||
|
if (parent != _gdk_root)
|
||||||
|
parent_impl->sorted_children = g_list_prepend (parent_impl->sorted_children, window);
|
||||||
|
else
|
||||||
|
clear_toplevel_order ();
|
||||||
|
|
||||||
gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
|
gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
|
||||||
(attributes->cursor) :
|
(attributes->cursor) :
|
||||||
@ -796,9 +846,27 @@ _gdk_windowing_window_destroy (GdkWindow *window,
|
|||||||
gboolean recursing,
|
gboolean recursing,
|
||||||
gboolean foreign_destroy)
|
gboolean foreign_destroy)
|
||||||
{
|
{
|
||||||
|
GdkWindowObject *private;
|
||||||
|
GdkWindowImplQuartz *impl;
|
||||||
|
GdkWindowObject *parent;
|
||||||
|
|
||||||
|
private = GDK_WINDOW_OBJECT (window);
|
||||||
|
impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
|
||||||
|
|
||||||
update_windows = g_slist_remove (update_windows, window);
|
update_windows = g_slist_remove (update_windows, window);
|
||||||
main_window_stack = g_slist_remove (main_window_stack, window);
|
main_window_stack = g_slist_remove (main_window_stack, window);
|
||||||
|
|
||||||
|
g_list_free (impl->sorted_children);
|
||||||
|
impl->sorted_children = NULL;
|
||||||
|
|
||||||
|
parent = private->parent;
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
|
||||||
|
|
||||||
|
parent_impl->sorted_children = g_list_remove (parent_impl->sorted_children, window);
|
||||||
|
}
|
||||||
|
|
||||||
/* If the destroyed window was targeted for a pointer or keyboard
|
/* If the destroyed window was targeted for a pointer or keyboard
|
||||||
* grab, release the grab.
|
* grab, release the grab.
|
||||||
*/
|
*/
|
||||||
@ -1284,6 +1352,53 @@ _gdk_windowing_window_clear_area_e (GdkWindow *window,
|
|||||||
/* FIXME: Implement */
|
/* FIXME: Implement */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the toplevel ordering from NSApp and update our own list. We do
|
||||||
|
* this on demand since the NSApp's list is not up to date directly
|
||||||
|
* after we get windowDidBecomeMain.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
update_toplevel_order (void)
|
||||||
|
{
|
||||||
|
GdkWindowObject *root;
|
||||||
|
GdkWindowImplQuartz *root_impl;
|
||||||
|
NSEnumerator *enumerator;
|
||||||
|
id nswindow;
|
||||||
|
GList *toplevels = NULL;
|
||||||
|
|
||||||
|
root = GDK_WINDOW_OBJECT (_gdk_root);
|
||||||
|
root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
|
||||||
|
|
||||||
|
if (root_impl->sorted_children)
|
||||||
|
return;
|
||||||
|
|
||||||
|
enumerator = [[NSApp orderedWindows] objectEnumerator];
|
||||||
|
while ((nswindow = [enumerator nextObject]))
|
||||||
|
{
|
||||||
|
GdkWindow *window;
|
||||||
|
|
||||||
|
if (![[nswindow contentView] isKindOfClass:[GdkQuartzView class]])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
window = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
|
||||||
|
toplevels = g_list_prepend (toplevels, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
root_impl->sorted_children = g_list_reverse (toplevels);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_toplevel_order (void)
|
||||||
|
{
|
||||||
|
GdkWindowObject *root;
|
||||||
|
GdkWindowImplQuartz *root_impl;
|
||||||
|
|
||||||
|
root = GDK_WINDOW_OBJECT (_gdk_root);
|
||||||
|
root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
|
||||||
|
|
||||||
|
g_list_free (root_impl->sorted_children);
|
||||||
|
root_impl->sorted_children = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdk_window_raise (GdkWindow *window)
|
gdk_window_raise (GdkWindow *window)
|
||||||
{
|
{
|
||||||
@ -1292,13 +1407,28 @@ gdk_window_raise (GdkWindow *window)
|
|||||||
if (GDK_WINDOW_DESTROYED (window))
|
if (GDK_WINDOW_DESTROYED (window))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* FIXME: Only supported for toplevels currently. */
|
|
||||||
if (WINDOW_IS_TOPLEVEL (window))
|
if (WINDOW_IS_TOPLEVEL (window))
|
||||||
{
|
{
|
||||||
GdkWindowImplQuartz *impl;
|
GdkWindowImplQuartz *impl;
|
||||||
|
|
||||||
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
|
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
|
||||||
[impl->toplevel orderFront:impl->toplevel];
|
[impl->toplevel orderFront:impl->toplevel];
|
||||||
|
|
||||||
|
clear_toplevel_order ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
GdkWindowImplQuartz *impl;
|
||||||
|
|
||||||
|
impl = (GdkWindowImplQuartz *)parent->impl;
|
||||||
|
|
||||||
|
impl->sorted_children = g_list_remove (impl->sorted_children, window);
|
||||||
|
impl->sorted_children = g_list_prepend (impl->sorted_children, window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1310,13 +1440,28 @@ gdk_window_lower (GdkWindow *window)
|
|||||||
if (GDK_WINDOW_DESTROYED (window))
|
if (GDK_WINDOW_DESTROYED (window))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* FIXME: Only supported for toplevels currently. */
|
|
||||||
if (WINDOW_IS_TOPLEVEL (window))
|
if (WINDOW_IS_TOPLEVEL (window))
|
||||||
{
|
{
|
||||||
GdkWindowImplQuartz *impl;
|
GdkWindowImplQuartz *impl;
|
||||||
|
|
||||||
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
|
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
|
||||||
[impl->toplevel orderBack:impl->toplevel];
|
[impl->toplevel orderBack:impl->toplevel];
|
||||||
|
|
||||||
|
clear_toplevel_order ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
GdkWindowImplQuartz *impl;
|
||||||
|
|
||||||
|
impl = (GdkWindowImplQuartz *)parent->impl;
|
||||||
|
|
||||||
|
impl->sorted_children = g_list_remove (impl->sorted_children, window);
|
||||||
|
impl->sorted_children = g_list_append (impl->sorted_children, window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2572,7 +2717,6 @@ gdk_window_unfullscreen (GdkWindow *window)
|
|||||||
|
|
||||||
if (geometry)
|
if (geometry)
|
||||||
{
|
{
|
||||||
|
|
||||||
ShowMenuBar ();
|
ShowMenuBar ();
|
||||||
|
|
||||||
move_resize_window_internal (window,
|
move_resize_window_internal (window,
|
||||||
|
|||||||
@ -66,6 +66,9 @@ struct _GdkWindowImplQuartz
|
|||||||
gint in_paint_rect_count;
|
gint in_paint_rect_count;
|
||||||
|
|
||||||
GdkWindow *transient_for;
|
GdkWindow *transient_for;
|
||||||
|
|
||||||
|
/* Sorted by z-order */
|
||||||
|
GList *sorted_children;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkWindowImplQuartzClass
|
struct _GdkWindowImplQuartzClass
|
||||||
|
|||||||
Reference in New Issue
Block a user