Add gdk_window_restack

This lets you restack a window above or below a specified sibling.
At least eclipse wants this functionallity.
This commit is contained in:
Alexander Larsson 2009-09-02 23:38:55 +02:00
parent 45956aea21
commit d67a7eda16
7 changed files with 157 additions and 0 deletions

View File

@ -651,6 +651,7 @@ gdk_window_get_events
gdk_window_set_events
gdk_window_raise
gdk_window_lower
gdk_window_restack
gdk_window_move
gdk_window_resize
gdk_window_move_resize

View File

@ -6448,6 +6448,122 @@ gdk_window_lower (GdkWindow *window)
gdk_window_invalidate_in_parent (private);
}
/**
* gdk_window_restack:
* @window: a #GdkWindow
* @sibling: a #GdkWindow that is a sibling of @window, or %NULL
* @above: a boolean
*
* Changes the position of @window in the Z-order (stacking order), so that
* it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
* %FALSE).
*
* If @sibling is %NULL, then this either raises (if @above is %TRUE) or
* lowers the window.
*
* If @window is a toplevel, the window manager may choose to deny the
* request to move the window in the Z-order, gdk_window_restack() only
* requests the restack, does not guarantee it.
*
* Since: 2.18
*/
void
gdk_window_restack (GdkWindow *window,
GdkWindow *sibling,
gboolean above)
{
GdkWindowObject *private;
GdkWindowImplIface *impl_iface;
GdkWindowObject *parent;
GdkWindowObject *above_native;
GList *sibling_link;
GList *native_children;
GList *l, listhead;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
private = (GdkWindowObject *) window;
if (private->destroyed)
return;
if (sibling == NULL)
{
if (above)
gdk_window_raise (window);
else
gdk_window_lower (window);
return;
}
if (gdk_window_is_toplevel (private))
{
g_return_if_fail (gdk_window_is_toplevel (sibling));
impl_iface->restack_toplevel (window, sibling, above);
return;
}
parent = private->parent;
if (parent)
{
sibling_link = g_list_find (parent->children, sibling);
g_return_if_fail (sibling_link != NULL);
if (sibling_link == NULL)
return;
parent->children = g_list_remove (parent->children, window);
if (above)
parent->children = g_list_insert_before (parent->children,
sibling_link,
window);
else
parent->children = g_list_insert_before (parent->children,
sibling_link->next,
window);
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
if (gdk_window_has_impl (private))
{
above_native = find_native_sibling_above (parent, private);
if (above_native)
{
listhead.data = window;
listhead.next = NULL;
listhead.prev = NULL;
impl_iface->restack_under ((GdkWindow *)above_native, &listhead);
}
else
impl_iface->raise (window);
}
else
{
native_children = NULL;
get_all_native_children (private, &native_children);
if (native_children != NULL)
{
above_native = find_native_sibling_above (parent, private);
if (above_native)
impl_iface->restack_under ((GdkWindow *)above_native,
native_children);
else
{
/* Right order, since native_children is bottom-topmost first */
for (l = native_children; l != NULL; l = l->next)
impl_iface->raise (l->data);
}
g_list_free (native_children);
}
}
}
recompute_visible_regions (private, TRUE, FALSE);
_gdk_synthesize_crossing_events_for_geometry_change (window);
gdk_window_invalidate_in_parent (private);
}
/**
* gdk_window_show:
* @window: a #GdkWindow

View File

@ -364,6 +364,9 @@ void gdk_window_clear_area_e (GdkWindow *window,
gint height);
void gdk_window_raise (GdkWindow *window);
void gdk_window_lower (GdkWindow *window);
void gdk_window_restack (GdkWindow *window,
GdkWindow *sibling,
gboolean above);
void gdk_window_focus (GdkWindow *window,
guint32 timestamp);
void gdk_window_set_user_data (GdkWindow *window,

View File

@ -51,6 +51,9 @@ struct _GdkWindowImplIface
void (* lower) (GdkWindow *window);
void (* restack_under) (GdkWindow *window,
GList *native_siblings);
void (* restack_toplevel) (GdkWindow *window,
GdkWindow *sibling,
gboolean above);
void (* move_resize) (GdkWindow *window,
gboolean with_move,

View File

@ -1541,6 +1541,14 @@ gdk_window_quartz_lower (GdkWindow *window)
}
}
static void
gdk_window_quartz_restack_toplevel (GdkWindow *window,
GdkWindow *sibling,
gboolean above)
{
/* FIXME: Implement this */
}
static void
gdk_window_quartz_set_background (GdkWindow *window,
const GdkColor *color)
@ -2907,6 +2915,7 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
iface->get_events = gdk_window_quartz_get_events;
iface->raise = gdk_window_quartz_raise;
iface->lower = gdk_window_quartz_lower;
iface->restack_toplevel = gdk_window_quartz_restack_toplevel;
iface->move_resize = gdk_window_quartz_move_resize;
iface->set_background = gdk_window_quartz_set_background;
iface->set_back_pixmap = gdk_window_quartz_set_back_pixmap;

View File

@ -2092,6 +2092,14 @@ gdk_win32_window_restack_under (GdkWindow *window,
// ### TODO
}
static void
gdk_win32_window_restack_toplevel (GdkWindow *window,
GdkWindow *sibling,
gboolean above)
{
// ### TODO
}
void
gdk_window_get_root_origin (GdkWindow *window,
gint *x,
@ -3634,6 +3642,7 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
iface->raise = gdk_win32_window_raise;
iface->lower = gdk_win32_window_lower;
iface->restack_under = gdk_win32_window_restack_under;
iface->restack_toplevel = gdk_win32_window_restack_toplevel;
iface->move_resize = gdk_win32_window_move_resize;
iface->set_background = gdk_win32_window_set_background;
iface->set_back_pixmap = gdk_win32_window_set_back_pixmap;

View File

@ -1715,6 +1715,21 @@ gdk_window_x11_restack_under (GdkWindow *window,
g_free (windows);
}
static void
gdk_window_x11_restack_toplevel (GdkWindow *window,
GdkWindow *sibling,
gboolean above)
{
XWindowChanges changes;
changes.sibling = GDK_WINDOW_XID (sibling);
changes.stack_mode = above ? Above : Below;
XReconfigureWMWindow (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
GDK_WINDOW_SCREEN (window),
CWStackMode | CWSibling, &changes);
}
static void
gdk_window_x11_lower (GdkWindow *window)
{
@ -5562,6 +5577,7 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
iface->raise = gdk_window_x11_raise;
iface->lower = gdk_window_x11_lower;
iface->restack_under = gdk_window_x11_restack_under;
iface->restack_toplevel = gdk_window_x11_restack_toplevel;
iface->move_resize = gdk_window_x11_move_resize;
iface->set_background = gdk_window_x11_set_background;
iface->set_back_pixmap = gdk_window_x11_set_back_pixmap;