summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasilis Liaskovitis <vliaskovitis@suse.com>2017-09-29 16:57:22 +0200
committerRui Matos <tiagomatos@gmail.com>2017-09-29 18:30:26 +0200
commite3d59832c56dbc6acb4301836bc54c467889d515 (patch)
treed3e5f9fe15ce7d142f474a13c053d1bbc6169394
parent2c85bb41782069ab400e20885f5a05b3fe7c440f (diff)
downloadmutter-e3d59832c56dbc6acb4301836bc54c467889d515.tar.gz
x11/window: Implement _NET_RESTACK_WINDOW and XConfigureRequestEvent sibling
Implement _NET_RESTACK_WINDOW, based on metacity commit 0b5a50c8. Also respect "above" field (sibling) of XConfigureRequestEvent. When it is set, perform a stack operation relative to that sibling. https://bugzilla.gnome.org/show_bug.cgi?id=786363 https://bugzilla.gnome.org/show_bug.cgi?id=786365
-rw-r--r--src/core/window-private.h3
-rw-r--r--src/core/window.c24
-rw-r--r--src/x11/atomnames.h1
-rw-r--r--src/x11/window-x11.c86
4 files changed, 99 insertions, 15 deletions
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 013bad7aa..c3a1c0250 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -682,6 +682,9 @@ void meta_window_frame_size_changed (MetaWindow *window);
void meta_window_stack_just_below (MetaWindow *window,
MetaWindow *below_this_one);
+void meta_window_stack_just_above (MetaWindow *window,
+ MetaWindow *above_this_one);
+
void meta_window_set_user_time (MetaWindow *window,
guint32 timestamp);
diff --git a/src/core/window.c b/src/core/window.c
index 1fc483d16..d450a5ce0 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -6728,6 +6728,30 @@ meta_window_stack_just_below (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 to %d (making it above window %s).\n",
+ window->desc,
+ 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);
+ }
+}
+
/**
* meta_window_get_user_time:
* @window: a #MetaWindow
diff --git a/src/x11/atomnames.h b/src/x11/atomnames.h
index e37e8fa59..ff6c6cc2d 100644
--- a/src/x11/atomnames.h
+++ b/src/x11/atomnames.h
@@ -176,6 +176,7 @@ item(_NET_WM_OPAQUE_REGION)
item(_NET_WM_FRAME_DRAWN)
item(_NET_WM_FRAME_TIMINGS)
item(_NET_WM_WINDOW_OPACITY)
+item(_NET_RESTACK_WINDOW)
/* eof atomnames.h */
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index ad5058b8a..bc922c12a 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -2092,6 +2092,32 @@ meta_window_move_resize_request (MetaWindow *window,
}
}
+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;
+ }
+}
+
gboolean
meta_window_x11_configure_request (MetaWindow *window,
XEvent *event)
@@ -2125,10 +2151,7 @@ meta_window_x11_configure_request (MetaWindow *window,
* 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.
+ * Opposite anyway.
*/
if (event->xconfigurerequest.value_mask & CWStackMode)
{
@@ -2160,19 +2183,23 @@ meta_window_x11_configure_request (MetaWindow *window,
}
else
{
- switch (event->xconfigurerequest.detail)
+ MetaWindow *sibling = NULL;
+ /* Handle Above/Below with a sibling set */
+ 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;
+ MetaDisplay *display;
+
+ display = meta_window_get_display (window);
+ sibling = meta_display_lookup_x_window (display,
+ event->xconfigurerequest.above);
+ if (sibling == NULL)
+ return TRUE;
+
+ meta_topic (META_DEBUG_STACK,
+ "xconfigure stacking request from window %s sibling %s stackmode %d\n",
+ window->desc, sibling->desc, event->xconfigurerequest.detail);
}
+ restack_window (window, sibling, event->xconfigurerequest.detail);
}
}
@@ -2245,6 +2272,30 @@ query_pressed_buttons (MetaWindow *window)
return button;
}
+static void
+handle_net_restack_window (MetaDisplay *display,
+ XEvent *event)
+{
+ MetaWindow *window, *sibling = NULL;
+
+ /* Ignore if this does not come from a pager, see the WM spec
+ */
+ if (event->xclient.data.l[0] != 2)
+ return;
+
+ 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_x11_client_message (MetaWindow *window,
XEvent *event)
@@ -2728,6 +2779,11 @@ meta_window_x11_client_message (MetaWindow *window,
meta_window_show_menu (window, META_WINDOW_MENU_WM, x, y);
}
+ else if (event->xclient.message_type ==
+ display->atom__NET_RESTACK_WINDOW)
+ {
+ handle_net_restack_window (display, event);
+ }
return FALSE;
}