mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-11-23 06:59:44 -05:00
Merge pull request #804 from swaywm/keyboard-layers
Add keyboard input to layer surfaces
This commit is contained in:
commit
9ce53d7dc4
13 changed files with 193 additions and 9 deletions
|
|
@ -271,6 +271,13 @@ static void roots_cursor_press_button(struct roots_cursor *cursor,
|
|||
break;
|
||||
case WLR_BUTTON_PRESSED:
|
||||
roots_seat_set_focus(seat, view);
|
||||
if (wlr_surface_is_layer_surface(surface)) {
|
||||
struct wlr_layer_surface *layer =
|
||||
wlr_layer_surface_from_wlr_surface(surface);
|
||||
if (layer->current.keyboard_interactive) {
|
||||
roots_seat_set_focus_layer(seat, layer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,6 +192,33 @@ void arrange_layers(struct roots_output *output) {
|
|||
arrange_layer(output->wlr_output,
|
||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
|
||||
&usable_area, false);
|
||||
|
||||
// Find topmost keyboard interactive layer, if such a layer exists
|
||||
uint32_t layers_above_shell[] = {
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
||||
};
|
||||
size_t nlayers = sizeof(layers_above_shell) / sizeof(layers_above_shell[0]);
|
||||
struct roots_layer_surface *layer, *topmost = NULL;
|
||||
for (size_t i = 0; i < nlayers; ++i) {
|
||||
wl_list_for_each_reverse(layer,
|
||||
&output->layers[layers_above_shell[i]], link) {
|
||||
if (layer->layer_surface->current.keyboard_interactive) {
|
||||
topmost = layer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (topmost != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct roots_input *input = output->desktop->server->input;
|
||||
struct roots_seat *seat;
|
||||
wl_list_for_each(seat, &input->seats, link) {
|
||||
roots_seat_set_focus_layer(seat,
|
||||
topmost ? topmost->layer_surface : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_output_destroy(struct wl_listener *listener, void *data) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <wayland-server.h>
|
||||
#include <wlr/config.h>
|
||||
#include <wlr/types/wlr_idle.h>
|
||||
#include <wlr/types/wlr_layer_shell.h>
|
||||
#include <wlr/types/wlr_xcursor_manager.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "rootston/cursor.h"
|
||||
|
|
@ -723,7 +724,6 @@ void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) {
|
|||
wl_list_insert(&seat->input->server->desktop->views, &view->link);
|
||||
}
|
||||
|
||||
|
||||
bool unfullscreen = true;
|
||||
|
||||
#ifdef WLR_HAS_XWAYLAND
|
||||
|
|
@ -781,14 +781,18 @@ void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) {
|
|||
return;
|
||||
}
|
||||
|
||||
view_activate(view, true);
|
||||
|
||||
seat->has_focus = true;
|
||||
wl_list_remove(&seat_view->link);
|
||||
wl_list_insert(&seat->views, &seat_view->link);
|
||||
|
||||
view_damage_whole(view);
|
||||
|
||||
if (seat->focused_layer) {
|
||||
return;
|
||||
}
|
||||
|
||||
view_activate(view, true);
|
||||
seat->has_focus = true;
|
||||
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->seat);
|
||||
if (keyboard != NULL) {
|
||||
wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface,
|
||||
|
|
@ -800,6 +804,37 @@ void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus semantics of layer surfaces are somewhat detached from the normal focus
|
||||
* flow. For layers above the shell layer, for example, you cannot unfocus them.
|
||||
* You also cannot alt-tab between layer surfaces and shell surfaces.
|
||||
*/
|
||||
void roots_seat_set_focus_layer(struct roots_seat *seat,
|
||||
struct wlr_layer_surface *layer) {
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->seat);
|
||||
if (!layer) {
|
||||
seat->focused_layer = NULL;
|
||||
return;
|
||||
}
|
||||
if (seat->has_focus) {
|
||||
struct roots_view *prev_focus = roots_seat_get_focus(seat);
|
||||
wlr_seat_keyboard_clear_focus(seat->seat);
|
||||
view_activate(prev_focus, false);
|
||||
}
|
||||
seat->has_focus = false;
|
||||
if (layer->layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
|
||||
seat->focused_layer = layer;
|
||||
}
|
||||
if (keyboard != NULL) {
|
||||
wlr_seat_keyboard_notify_enter(seat->seat, layer->surface,
|
||||
keyboard->keycodes, keyboard->num_keycodes,
|
||||
&keyboard->modifiers);
|
||||
} else {
|
||||
wlr_seat_keyboard_notify_enter(seat->seat, layer->surface,
|
||||
NULL, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void roots_seat_cycle_focus(struct roots_seat *seat) {
|
||||
if (wl_list_empty(&seat->views)) {
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue