diff --git a/include/labwc.h b/include/labwc.h index c4848a11..cd43be5f 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -375,6 +375,7 @@ void desktop_focus_topmost_view(struct server *server); void seat_init(struct server *server); void seat_finish(struct server *server); void seat_reconfigure(struct server *server); +void seat_force_focus_surface(struct seat *seat, struct wlr_surface *surface); void seat_focus_surface(struct seat *seat, struct wlr_surface *surface); void seat_pointer_end_grab(struct seat *seat, struct wlr_surface *surface); diff --git a/include/layers.h b/include/layers.h index da1bdb86..0ea00669 100644 --- a/include/layers.h +++ b/include/layers.h @@ -30,6 +30,7 @@ struct lab_layer_popup { struct wlr_xdg_popup *wlr_popup; struct wlr_scene_tree *scene_tree; struct server *server; + struct lab_layer_surface *lab_layer_surface; /* To simplify moving popup nodes from the bottom to the top layer */ struct wlr_box output_toplevel_sx_box; @@ -38,6 +39,7 @@ struct lab_layer_popup { struct wl_listener destroy; struct wl_listener new_popup; struct wl_listener reposition; + struct wl_listener grab; }; void layers_init(struct server *server); diff --git a/src/layers.c b/src/layers.c index f26208ef..46c692a1 100644 --- a/src/layers.c +++ b/src/layers.c @@ -417,6 +417,7 @@ handle_popup_destroy(struct wl_listener *listener, void *data) wl_list_remove(&popup->destroy.link); wl_list_remove(&popup->new_popup.link); wl_list_remove(&popup->reposition.link); + wl_list_remove(&popup->grab.link); /* Usually already removed unless there was no commit at all */ if (popup->commit.notify) { @@ -444,6 +445,19 @@ handle_popup_commit(struct wl_listener *listener, void *data) } } +static void +handle_popup_grab(struct wl_listener *listener, void *data) +{ + struct lab_layer_popup *popup = wl_container_of(listener, popup, grab); + wlr_log(WLR_ERROR, "grab layer-shell popup"); + struct seat *seat = &popup->server->seat; + //seat_force_focus_surface(seat, popup->wlr_popup->base->surface); + + struct wlr_surface *wlr_surface = + popup->lab_layer_surface->layer_surface->surface; + seat_force_focus_surface(seat, wlr_surface); +} + static void handle_popup_reposition(struct wl_listener *listener, void *data) { @@ -484,6 +498,9 @@ create_popup(struct server *server, struct wlr_xdg_popup *wlr_popup, popup->commit.notify = handle_popup_commit; wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit); + popup->grab.notify = handle_popup_grab; + wl_signal_add(&wlr_popup->events.grab, &popup->grab); + popup->reposition.notify = handle_popup_reposition; wl_signal_add(&wlr_popup->events.reposition, &popup->reposition); @@ -509,6 +526,7 @@ handle_popup_new_popup(struct wl_listener *listener, void *data) new_popup->output_toplevel_sx_box = lab_layer_popup->output_toplevel_sx_box; + new_popup->lab_layer_surface = lab_layer_popup->lab_layer_surface; } /* @@ -574,6 +592,7 @@ handle_new_popup(struct wl_listener *listener, void *data) } popup->output_toplevel_sx_box = output_toplevel_sx_box; + popup->lab_layer_surface = toplevel; if (surface->layer_surface->current.layer <= ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) { diff --git a/src/seat.c b/src/seat.c index a5cdf3ee..1260abaf 100644 --- a/src/seat.c +++ b/src/seat.c @@ -759,6 +759,17 @@ seat_reconfigure(struct server *server) } } +void +seat_force_focus_surface(struct seat *seat, struct wlr_surface *surface) +{ + uint32_t *pressed_sent_keycodes = key_state_pressed_sent_keycodes(); + int nr_pressed_sent_keycodes = key_state_nr_pressed_sent_keycodes(); + struct wlr_keyboard *kb = &seat->keyboard_group->keyboard; + + wlr_seat_keyboard_enter(seat->seat, surface, + pressed_sent_keycodes, nr_pressed_sent_keycodes, &kb->modifiers); +} + static void seat_focus(struct seat *seat, struct wlr_surface *surface, bool replace_exclusive_layer, bool is_lock_surface)