From fb2adba3da09e9a613b1702bf3c49885ad7ca225 Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Wed, 12 Jun 2013 15:43:21 -0300 Subject: [PATCH] xwayland: Forward global position to X xeyes works as expected now. subwindows are popped also as expected. This patch should fix the following: https://bugs.freedesktop.org/show_bug.cgi?id=59983 Signed-off-by: Tiago Vignatti --- src/compositor.c | 3 ++ src/compositor.h | 5 +++ src/shell.c | 24 +++++++++++- src/xwayland/window-manager.c | 73 ++++++++++++++++++++++------------- src/xwayland/xwayland.h | 2 +- 5 files changed, 79 insertions(+), 28 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 42011f58..d44ffaad 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -728,6 +728,8 @@ weston_surface_update_transform(struct weston_surface *surface) weston_surface_damage_below(surface); weston_surface_assign_output(surface); + + wl_signal_emit(&surface->compositor->transform_signal, surface); } WL_EXPORT void @@ -2778,6 +2780,7 @@ weston_compositor_init(struct weston_compositor *ec, ec->wl_display = display; wl_signal_init(&ec->destroy_signal); wl_signal_init(&ec->activate_signal); + wl_signal_init(&ec->transform_signal); wl_signal_init(&ec->kill_signal); wl_signal_init(&ec->idle_signal); wl_signal_init(&ec->wake_signal); diff --git a/src/compositor.h b/src/compositor.h index c87d9f1f..865b01c4 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -94,6 +94,8 @@ struct weston_shell_interface { uint32_t method, uint32_t framerate, struct weston_output *output); + void (*set_xwayland)(struct shell_surface *shsurf, + int x, int y, uint32_t flags); int (*move)(struct shell_surface *shsurf, struct weston_seat *ws); int (*resize)(struct shell_surface *shsurf, struct weston_seat *ws, uint32_t edges); @@ -502,7 +504,10 @@ struct weston_compositor { struct weston_shell_interface shell_interface; struct weston_config *config; + /* surface signals */ struct wl_signal activate_signal; + struct wl_signal transform_signal; + struct wl_signal kill_signal; struct wl_signal idle_signal; struct wl_signal wake_signal; diff --git a/src/shell.c b/src/shell.c index 57dbb0a1..cfdb19ce 100644 --- a/src/shell.c +++ b/src/shell.c @@ -171,7 +171,8 @@ enum shell_surface_type { SHELL_SURFACE_TRANSIENT, SHELL_SURFACE_FULLSCREEN, SHELL_SURFACE_MAXIMIZED, - SHELL_SURFACE_POPUP + SHELL_SURFACE_POPUP, + SHELL_SURFACE_XWAYLAND }; struct ping_timer { @@ -1581,6 +1582,7 @@ reset_shell_surface_type(struct shell_surface *surface) case SHELL_SURFACE_TOPLEVEL: case SHELL_SURFACE_TRANSIENT: case SHELL_SURFACE_POPUP: + case SHELL_SURFACE_XWAYLAND: break; } @@ -1622,6 +1624,11 @@ set_surface_type(struct shell_surface *shsurf) } break; + case SHELL_SURFACE_XWAYLAND: + weston_surface_set_position(surface, shsurf->transient.x, + shsurf->transient.y); + break; + default: break; } @@ -1925,6 +1932,16 @@ shell_surface_set_fullscreen(struct wl_client *client, set_fullscreen(shsurf, method, framerate, output); } +static void +set_xwayland(struct shell_surface *shsurf, int x, int y, uint32_t flags) +{ + /* XXX: using the same fields for transient type */ + shsurf->transient.x = x; + shsurf->transient.y = y; + shsurf->transient.flags = flags; + shsurf->next_type = SHELL_SURFACE_XWAYLAND; +} + static const struct weston_pointer_grab_interface popup_grab_interface; static void @@ -3398,6 +3415,7 @@ map(struct desktop_shell *shell, struct weston_surface *surface, case SHELL_SURFACE_FULLSCREEN: case SHELL_SURFACE_NONE: break; + case SHELL_SURFACE_XWAYLAND: default: ws = get_current_workspace(shell); wl_list_insert(&ws->layer.surface_list, &surface->layer_link); @@ -3411,6 +3429,8 @@ map(struct desktop_shell *shell, struct weston_surface *surface, } switch (surface_type) { + /* XXX: xwayland's using the same fields for transient type */ + case SHELL_SURFACE_XWAYLAND: case SHELL_SURFACE_TRANSIENT: if (shsurf->transient.flags == WL_SHELL_SURFACE_TRANSIENT_INACTIVE) @@ -3489,6 +3509,7 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32 { struct shell_surface *shsurf = get_shell_surface(es); struct desktop_shell *shell = shsurf->shell; + struct weston_compositor *compositor = shsurf->surface->compositor; int type_changed = 0; @@ -4433,6 +4454,7 @@ module_init(struct weston_compositor *ec, ec->shell_interface.set_toplevel = set_toplevel; ec->shell_interface.set_transient = set_transient; ec->shell_interface.set_fullscreen = set_fullscreen; + ec->shell_interface.set_xwayland = set_xwayland; ec->shell_interface.move = surface_move; ec->shell_interface.resize = surface_resize; diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c index 3fc56337..6b9e38b8 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -593,12 +593,49 @@ weston_wm_window_activate(struct wl_listener *listener, void *data) if (wm->focus_window) weston_wm_window_schedule_repaint(wm->focus_window); wm->focus_window = window; - if (window) - wm->focus_latest = window; if (wm->focus_window) weston_wm_window_schedule_repaint(wm->focus_window); } +static void +weston_wm_window_transform(struct wl_listener *listener, void *data) +{ + struct weston_surface *surface = data; + struct weston_wm_window *window = get_wm_window(surface); + struct weston_wm *wm = + container_of(listener, struct weston_wm, transform_listener); + struct weston_output *output = surface->output; + uint32_t mask, values[2]; + float sxf, syf; + int sx, sy; + static int old_sx = -1, old_sy = -1; + + if (!window || !wm) + return; + + if (!weston_surface_is_mapped(surface)) + return; + + weston_surface_to_global_float(surface, output->x, output->y, + &sxf, &syf); + + sx = (int) sxf; + sy = (int) syf; + + if (old_sx == sx && old_sy == sy) + return; + + values[0] = sx; + values[1] = sy; + mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; + + xcb_configure_window(wm->conn, window->frame_id, mask, values); + xcb_flush(wm->conn); + + old_sx = sx; + old_sy = sy; +} + static int our_resource(struct weston_wm *wm, uint32_t id) { @@ -1684,6 +1721,9 @@ weston_wm_create(struct weston_xserver *wxs) wm->activate_listener.notify = weston_wm_window_activate; wl_signal_add(&wxs->compositor->activate_signal, &wm->activate_listener); + wm->transform_listener.notify = weston_wm_window_transform; + wl_signal_add(&wxs->compositor->transform_signal, + &wm->transform_listener); wm->kill_listener.notify = weston_wm_kill_client; wl_signal_add(&wxs->compositor->kill_signal, &wm->kill_listener); @@ -1807,9 +1847,7 @@ xserver_map_shell_surface(struct weston_wm *wm, { struct weston_shell_interface *shell_interface = &wm->server->compositor->shell_interface; - struct weston_wm_window *parent; struct theme *t = window->wm->theme; - int parent_id, x = 0, y = 0; if (!shell_interface->create_shell_surface) return; @@ -1827,31 +1865,14 @@ xserver_map_shell_surface(struct weston_wm *wm, 0, NULL); return; } else if (!window->override_redirect) { - /* ICCCM 4.1.1 */ shell_interface->set_toplevel(window->shsurf); return; + } else { + shell_interface->set_xwayland(window->shsurf, + window->x + t->margin, + window->y + t->margin, + WL_SHELL_SURFACE_TRANSIENT_INACTIVE); } - - /* not all non-toplevel has transient_for set. So we need this - * workaround to guess a parent that will determine the relative - * position of the transient surface */ - if (!window->transient_for) - parent_id = wm->focus_latest->id; - else - parent_id = window->transient_for->id; - - parent = hash_table_lookup(wm->window_hash, parent_id); - - /* non-decorated and non-toplevel windows, e.g. sub-menus */ - if (!parent->decorate && parent->override_redirect) { - x = parent->x + t->margin; - y = parent->y + t->margin; - } - - shell_interface->set_transient(window->shsurf, parent->surface, - window->x + t->margin - x, - window->y + t->margin - y, - WL_SHELL_SURFACE_TRANSIENT_INACTIVE); } static void diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h index 9151cce0..c68a517e 100644 --- a/src/xwayland/xwayland.h +++ b/src/xwayland/xwayland.h @@ -53,7 +53,6 @@ struct weston_wm { struct weston_xserver *server; xcb_window_t wm_window; struct weston_wm_window *focus_window; - struct weston_wm_window *focus_latest; struct theme *theme; xcb_cursor_t *cursors; int last_cursor; @@ -61,6 +60,7 @@ struct weston_wm { xcb_visualid_t visual_id; xcb_colormap_t colormap; struct wl_listener activate_listener; + struct wl_listener transform_listener; struct wl_listener kill_listener; xcb_window_t selection_window;