diff options
author | Christian Hammond <chipx86@chipx86.com> | 2011-01-19 09:06:02 -0500 |
---|---|---|
committer | Thomas Thurman <tthurman@gnome.org> | 2011-01-19 09:09:49 -0500 |
commit | 0b5a50c85095a426f7070c5c8fe0af285ac02f62 (patch) | |
tree | 64687e0cadcd819f6c5bd9ec8e69eb869ff58279 /src | |
parent | ef0a601819fd0b10932b7ffb1babcbce7ac29daf (diff) | |
download | metacity-0b5a50c85095a426f7070c5c8fe0af285ac02f62.tar.gz |
Honour _NET_RESTACK_WINDOW and sibling-relative stacking
A test case for this patch is available at
https://view.svn.sourceforge.net/svnroot/view/trunk/wm-test-suite/
Diffstat (limited to 'src')
-rw-r--r-- | src/core/atomnames.h | 6 | ||||
-rw-r--r-- | src/core/display.c | 43 | ||||
-rw-r--r-- | src/core/window-private.h | 2 | ||||
-rw-r--r-- | src/core/window.c | 116 |
4 files changed, 95 insertions, 72 deletions
diff --git a/src/core/atomnames.h b/src/core/atomnames.h index 43710f37..338d0555 100644 --- a/src/core/atomnames.h +++ b/src/core/atomnames.h @@ -156,11 +156,7 @@ item(_NET_WM_ACTION_ABOVE) item(_NET_WM_ACTION_BELOW) item(_NET_WM_STATE_STICKY) item(_NET_WM_FULLSCREEN_MONITORS) - -#if 0 -/* We apparently never use: */ -/* item(_NET_RESTACK_WINDOW) */ -#endif +item(_NET_RESTACK_WINDOW) /* eof atomnames.h */ diff --git a/src/core/display.c b/src/core/display.c index b59571d5..e816823a 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1358,44 +1358,6 @@ meta_display_queue_autoraise_callback (MetaDisplay *display, display->autoraise_window = window; } -#if 0 -static void -handle_net_restack_window (MetaDisplay* display, - XEvent *event) -{ - MetaWindow *window; - - window = meta_display_lookup_x_window (display, - event->xclient.window); - - if (window) - { - /* FIXME: The EWMH includes a sibling for the restack request, but we - * (stupidly) don't currently support these types of raises. - * - * Also, unconditionally following these is REALLY stupid--we should - * combine this code with the stuff in - * meta_window_configure_request() which is smart about whether to - * follow the request or do something else (though not smart enough - * and is also too stupid to handle the sibling stuff). - */ - switch (event->xclient.data.l[2]) - { - case Above: - meta_window_raise (window); - break; - case Below: - meta_window_lower (window); - break; - case TopIf: - case BottomIf: - case Opposite: - break; - } - } -} -#endif - /** * This is the most important function in the whole program. It is the heart, * it is the nexus, it is the Grand Central Station of Metacity's world. @@ -2171,11 +2133,6 @@ event_callback (XEvent *event, else if (event->xproperty.atom == display->atom__NET_DESKTOP_NAMES) meta_screen_update_workspace_names (screen); -#if 0 - else if (event->xproperty.atom == - display->atom__NET_RESTACK_WINDOW) - handle_net_restack_window (display, event); -#endif /* we just use this property as a sentinel to avoid * certain race conditions. See the comment for the diff --git a/src/core/window-private.h b/src/core/window-private.h index da3fc526..7cf5b04a 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -622,6 +622,8 @@ const char* meta_window_get_startup_id (MetaWindow *window); void meta_window_recalc_features (MetaWindow *window); void meta_window_recalc_window_type (MetaWindow *window); +void meta_window_stack_just_above (MetaWindow *window, + MetaWindow *above_this_one); void meta_window_stack_just_below (MetaWindow *window, MetaWindow *below_this_one); diff --git a/src/core/window.c b/src/core/window.c index 9af5283d..11994d51 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -58,6 +58,9 @@ static int destroying_windows_disallowed = 0; static void update_sm_hints (MetaWindow *window); static void update_net_frame_extents (MetaWindow *window); +static void restack_window (MetaWindow *window, + MetaWindow *sibling, + int direction); static void recalc_window_type (MetaWindow *window); static void recalc_window_features (MetaWindow *window); static void invalidate_work_areas (MetaWindow *window); @@ -4713,19 +4716,13 @@ meta_window_configure_request (MetaWindow *window, event->xconfigurerequest.width, event->xconfigurerequest.height); - /* Handle stacking. We only handle raises/lowers, mostly because - * stack.c really can't deal with anything else. I guess we'll fix - * that if a client turns up that really requires it. Only a very - * few clients even require the raise/lower (and in fact all client - * attempts to deal with stacking order are essentially broken, - * since they have no idea what other clients are involved or how - * the stack looks). - * - * I'm pretty sure no interesting client uses TopIf, BottomIf, or - * Opposite anyway, so the only possible missing thing is - * Above/Below with a sibling set. For now we just pretend there's - * never a sibling set and always do the full raise/lower instead of - * the raise-just-above/below-sibling. + + /* Handle stacking. We only handle raises/lowers (both absolute and + * relative to siblings), mostly because stack.c really can't deal with + * anything else. I guess we'll fix that if a client turns up that really + * requires it. Only a very few clients even require the raise/lower. I'm + * pretty sure no interesting client uses TopIf, BottomIf, or Opposite + * anyway. */ if (event->xconfigurerequest.value_mask & CWStackMode) { @@ -4757,19 +4754,15 @@ meta_window_configure_request (MetaWindow *window, } else { - switch (event->xconfigurerequest.detail) + MetaWindow *sibling = NULL; + + if (event->xconfigurerequest.above != None) { - case Above: - meta_window_raise (window); - break; - case Below: - meta_window_lower (window); - break; - case TopIf: - case BottomIf: - case Opposite: - break; + sibling = meta_display_lookup_x_window (window->display, + event->xconfigurerequest.above); } + + restack_window(window, sibling, event->xconfigurerequest.detail); } } @@ -4796,6 +4789,51 @@ meta_window_property_notify (MetaWindow *window, #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 #define _NET_WM_MOVERESIZE_CANCEL 11 +static void +restack_window (MetaWindow *window, + MetaWindow *sibling, + int direction) +{ + switch (direction) + { + case Above: + if (sibling) + meta_window_stack_just_above (window, sibling); + else + meta_window_raise (window); + break; + case Below: + if (sibling) + meta_window_stack_just_below (window, sibling); + else + meta_window_lower (window); + break; + case TopIf: + case BottomIf: + case Opposite: + break; + } +} + +static void +handle_net_restack_window (MetaDisplay* display, + XEvent *event) +{ + MetaWindow *window, *sibling = NULL; + + window = meta_display_lookup_x_window (display, + event->xclient.window); + + if (window) + { + if (event->xclient.data.l[1]) + sibling = meta_display_lookup_x_window (display, + event->xclient.data.l[1]); + + restack_window (window, sibling, event->xclient.data.l[2]); + } +} + gboolean meta_window_client_message (MetaWindow *window, XEvent *event) @@ -4824,6 +4862,11 @@ meta_window_client_message (MetaWindow *window, return TRUE; } + else if (event->xproperty.atom == + display->atom__NET_RESTACK_WINDOW) + { + handle_net_restack_window (display, event); + } else if (event->xclient.message_type == display->atom__NET_WM_DESKTOP) { @@ -7997,6 +8040,31 @@ ensure_mru_position_after (MetaWindow *window, } void +meta_window_stack_just_above (MetaWindow *window, + MetaWindow *above_this_one) +{ + g_return_if_fail (window != NULL); + g_return_if_fail (above_this_one != NULL); + + if (window->stack_position < above_this_one->stack_position) + { + meta_topic (META_DEBUG_STACK, + "Setting stack position of window %s (%d) to %d (making it above window %s).\n", + window->desc, + window->stack_position, + above_this_one->stack_position, + above_this_one->desc); + meta_window_set_stack_position (window, above_this_one->stack_position); + } + else + { + meta_topic (META_DEBUG_STACK, + "Window %s was already above window %s.\n", + window->desc, above_this_one->desc); + } +} + +void meta_window_stack_just_below (MetaWindow *window, MetaWindow *below_this_one) { |