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 <[email protected]> --- Hey guys, This fix the problem mentioned above but exposes something that was already buggy before: XWM (and probably all X clients) is getting wrong EnterNotify, setting wrong cursor. This happens sometimes only. To check the problem, I've added a printf in weston_wm_handle_enter and set WAYLAND_DEBUG=1. You will see that the coordinates wl_pointer_enter comes to XWayland vary from what it sends along to the X clients. It's not all the time as I said, so probably there's a race between the two protocols. Another way to check is clobber one window with another, leaving the cursor right on the decoration border where it should change the icon if you alternate the windows with ctrl+tab: http://i.troll.ws/4c2cbb1b.png Grab cursor not being set all the times is another way to see the bug. I hope this help someone else find the problem. I'm not continuing the investigations here in principle. Tiago src/compositor.c | 1 + src/compositor.h | 5 +++ src/shell.c | 30 ++++++++++++++++- src/xwayland/window-manager.c | 73 ++++++++++++++++++++++++++--------------- src/xwayland/xwayland.h | 2 +- 5 files changed, 83 insertions(+), 28 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 099600d..f019441 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -2777,6 +2777,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->position_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 22700b7..bcca468 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; + /* xwayland */ struct wl_signal activate_signal; + struct wl_signal position_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 3d10eef..d9038b2 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 { @@ -340,9 +341,13 @@ shell_grab_start(struct shell_grab *grab, static void shell_grab_end(struct shell_grab *grab) { + struct weston_compositor *compositor = + grab->shsurf->surface->compositor; + if (grab->shsurf) wl_list_remove(&grab->shsurf_destroy_listener.link); + wl_signal_emit(&compositor->position_signal, grab->shsurf->surface); weston_pointer_end_grab(grab->pointer); } @@ -1581,6 +1586,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 +1628,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 +1936,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 @@ -3399,6 +3420,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); @@ -3412,6 +3434,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) @@ -3490,6 +3514,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; @@ -3521,6 +3546,8 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32 es->geometry.y + to_y - from_y, width, height); } + + wl_signal_emit(&compositor->position_signal, shsurf->surface); } static void launch_desktop_shell_process(void *data); @@ -4434,6 +4461,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 366f2e0..466f049 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -584,12 +584,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_position(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, position_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) { @@ -1675,6 +1712,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->position_listener.notify = weston_wm_window_position; + wl_signal_add(&wxs->compositor->position_signal, + &wm->position_listener); wm->kill_listener.notify = weston_wm_kill_client; wl_signal_add(&wxs->compositor->kill_signal, &wm->kill_listener); @@ -1799,9 +1839,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; @@ -1819,31 +1857,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 9151cce..1b957ca 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 position_listener; struct wl_listener kill_listener; xcb_window_t selection_window; -- 1.7.9.5 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
