summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>2016-11-16 14:15:18 +0200
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2017-01-18 13:21:02 +0200
commit882aff09324ba72d1d9136d6ad9f3c99dab1631b (patch)
treeaab969dfdb04dec843a07a37fa4debb8f19844cd
parent37111e157a10217a37b30f0d12605ba14b28667b (diff)
xwayland: detect initially positioned X11 windows
X11 applications expect -geometry command line option to work for setting the initial window position, but currently this does not work. During map, detect X11 windows that set an explicit position. This works by heuristics: if window position is not 0,0 then it is explicitly positioned. Legacy fullscreen windows are also at 0,0 but these are detected earlier. Explicitly store the window position at map request time to detect client-positioned windows, and use it as the suggested initial position. weston_wm_window::x and y have been overwritten due to reparenting when we eventually need the initial position. This patch requires that the new set_toplevel_with_position() hook is implemented in the shell. Note that this patch is about positioning xwayland toplevels, not override-redirect windows which are already handled. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Quentin Glidic <sardemff7+git@sardemff7.net> Reviewed-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--xwayland/window-manager.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 832f824a..ea28e71f 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -35,6 +35,7 @@
#include <errno.h>
#include <unistd.h>
#include <signal.h>
+#include <limits.h>
#include <assert.h>
#include <X11/Xcursor/Xcursor.h>
#include <linux/input.h>
@@ -152,8 +153,11 @@ struct weston_wm_window {
uint32_t protocols;
xcb_atom_t type;
int width, height;
- int x, y;
+ int x;
+ int y;
bool pos_dirty;
+ int map_request_x;
+ int map_request_y;
struct weston_output_weak_ref legacy_fullscreen_output;
int saved_width, saved_height;
int decorate;
@@ -1030,12 +1034,16 @@ weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
*/
assert(!window->shsurf);
+ window->map_request_x = window->x;
+ window->map_request_y = window->y;
+
if (window->frame_id == XCB_WINDOW_NONE)
weston_wm_window_create_frame(window);
wm_log("XCB_MAP_REQUEST (window %d, %p, frame %d, %dx%d @ %d,%d)\n",
window->id, window, window->frame_id,
- window->width, window->height, window->x, window->y);
+ window->width, window->height,
+ window->map_request_x, window->map_request_y);
weston_wm_window_set_wm_state(window, ICCCM_NORMAL_STATE);
weston_wm_window_set_net_wm_state(window);
@@ -1283,6 +1291,8 @@ weston_wm_window_create(struct weston_wm *wm,
window->x = x;
window->y = y;
window->pos_dirty = false;
+ window->map_request_x = INT_MIN; /* out of range for valid positions */
+ window->map_request_y = INT_MIN; /* out of range for valid positions */
weston_output_weak_ref_init(&window->legacy_fullscreen_output);
geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, NULL);
@@ -2581,6 +2591,17 @@ legacy_fullscreen(struct weston_wm *wm,
}
static bool
+weston_wm_window_is_positioned(struct weston_wm_window *window)
+{
+ if (window->map_request_x == INT_MIN ||
+ window->map_request_y == INT_MIN)
+ weston_log("XWM warning: win %d did not see map request\n",
+ window->id);
+
+ return window->map_request_x != 0 || window->map_request_y != 0;
+}
+
+static bool
weston_wm_window_type_inactive(struct weston_wm_window *window)
{
struct weston_wm *wm = window->wm;
@@ -2670,6 +2691,10 @@ xserver_map_shell_surface(struct weston_wm_window *window,
xwayland_interface->set_xwayland(window->shsurf,
window->x,
window->y);
+ } else if (weston_wm_window_is_positioned(window)) {
+ xwayland_interface->set_toplevel_with_position(window->shsurf,
+ window->map_request_x,
+ window->map_request_y);
} else {
xwayland_interface->set_toplevel(window->shsurf);
}