diff options
-rw-r--r-- | src/compositor.h | 7 | ||||
-rw-r--r-- | src/shell.c | 38 | ||||
-rw-r--r-- | src/xwayland/window-manager.c | 28 |
3 files changed, 63 insertions, 10 deletions
diff --git a/src/compositor.h b/src/compositor.h index e8e8ecf..04a9773 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -70,6 +70,7 @@ struct weston_mode { struct weston_shell_client { void (*send_configure)(struct weston_surface *surface, uint32_t edges, int32_t width, int32_t height); + void (*send_popup_done)(struct weston_surface *surface); }; struct weston_shell_interface { @@ -84,6 +85,12 @@ struct weston_shell_interface { void (*set_transient)(struct shell_surface *shsurf, struct shell_surface *pshsurf, int x, int y, uint32_t flags); + + void (*set_popup) (struct shell_surface *shsurf, + struct shell_surface *pshsurf, + struct wl_seat *seat, uint32_t serial, + int32_t x, int32_t 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); diff --git a/src/shell.c b/src/shell.c index 73af751..efd90c2 100644 --- a/src/shell.c +++ b/src/shell.c @@ -646,8 +646,17 @@ send_configure(struct weston_surface *surface, edges, width, height); } +static void +send_popup_done(struct weston_surface *surface) +{ + struct shell_surface *shsurf = get_shell_surface(surface); + + wl_shell_surface_send_popup_done(&shsurf->resource); +} + static const struct weston_shell_client shell_client = { - send_configure + send_configure, + send_popup_done }; static void @@ -1160,7 +1169,7 @@ popup_grab_button(struct wl_pointer_grab *grab, } else if (state == WL_POINTER_BUTTON_STATE_RELEASED && (shsurf->popup.initial_up || time - shsurf->popup.seat->pointer->grab_time > 500)) { - wl_shell_surface_send_popup_done(&shsurf->resource); + shsurf->client->send_popup_done(shsurf->surface); wl_pointer_end_grab(grab->pointer); shsurf->popup.grab.pointer = NULL; } @@ -1208,11 +1217,24 @@ shell_map_popup(struct shell_surface *shsurf) if (seat->pointer->grab_serial == shsurf->popup.serial) { wl_pointer_start_grab(seat->pointer, &shsurf->popup.grab); } else { - wl_shell_surface_send_popup_done(&shsurf->resource); + shsurf->client->send_popup_done(shsurf->surface); } } static void +set_popup(struct shell_surface *shsurf, struct shell_surface *pshsurf, + struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y, + uint32_t flags) +{ + shsurf->type = SHELL_SURFACE_POPUP; + shsurf->parent = pshsurf; + shsurf->popup.seat = seat; + shsurf->popup.serial = serial; + shsurf->popup.x = x; + shsurf->popup.y = y; +} + +static void shell_surface_set_popup(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, @@ -1221,13 +1243,10 @@ shell_surface_set_popup(struct wl_client *client, int32_t x, int32_t y, uint32_t flags) { struct shell_surface *shsurf = resource->data; + struct shell_surface *pshsurf = parent_resource->data; + struct wl_seat *seat = seat_resource->data; - shsurf->type = SHELL_SURFACE_POPUP; - shsurf->parent = parent_resource->data; - shsurf->popup.seat = seat_resource->data; - shsurf->popup.serial = serial; - shsurf->popup.x = x; - shsurf->popup.y = y; + set_popup(shsurf, pshsurf, seat, serial, x, y, flags); } static const struct wl_shell_surface_interface shell_surface_implementation = { @@ -2751,6 +2770,7 @@ shell_init(struct weston_compositor *ec) ec->shell_interface.create_shell_surface = create_shell_surface; ec->shell_interface.set_toplevel = set_toplevel; ec->shell_interface.set_transient = set_transient; + ec->shell_interface.set_popup = set_popup; 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 3ef8fc0..bb5796c 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -462,6 +462,7 @@ weston_wm_window_activate(struct wl_listener *listener, void *data) container_of(listener, struct weston_wm, activate_listener); xcb_client_message_event_t client_message; + fprintf(stderr, "%s\n", __func__); if (window) { if (!weston_wm_focus_assistance(window)) return; @@ -1400,8 +1401,22 @@ send_configure(struct weston_surface *surface, weston_wm_window_configure, window); } +static void +send_popup_done(struct weston_surface *surface) +{ + struct weston_wm_window *window = get_wm_window(surface); + struct weston_wm *wm = window->wm; + + fprintf(stderr, "%s\n", __func__); + xcb_set_input_focus (wm->conn, XCB_INPUT_FOCUS_POINTER_ROOT, XCB_NONE, + XCB_TIME_CURRENT_TIME); + /* force unmap */ + xcb_unmap_window(wm->conn, window->id); +} + static const struct weston_shell_client shell_client = { - send_configure + send_configure, + send_popup_done }; static void @@ -1412,6 +1427,9 @@ xserver_map_shell_surface(struct weston_wm *wm, &wm->server->compositor->shell_interface; struct weston_wm_window *parent; struct theme *t = window->wm->theme; + struct weston_compositor *compositor = wm->server->compositor; + struct wl_seat *seat = &compositor->seat->seat; + uint32_t grab_serial = seat->pointer->grab_serial; int parent_id; int x = 0, y = 0; @@ -1445,6 +1463,14 @@ xserver_map_shell_surface(struct weston_wm *wm, y = parent->y + t->margin; } + if (window->type == wm->atom.net_wm_window_type_popup) { + shell_interface->set_popup(window->shsurf, parent->shsurf, + seat, grab_serial, + window->x + t->margin - x, + window->y + t->margin - y, 0); + return; + } + shell_interface->set_transient(window->shsurf, parent->shsurf, window->x + t->margin - x, window->y + t->margin - y, |