mirror of
https://github.com/labwc/labwc.git
synced 2026-02-18 22:05:32 -05:00
layer: change logic for giving keyboard-interactivity
Use the following logic: - Exclusive: Grant regardless of layer (previously it was only given if in top or overlay layers) AND grant if in the same or higher layer (nearer overlay) compared with other clients with exclusive interactivity. - On-demand: Grant only if no other layer-shell client has exclusive keyboard interactivity. Previously it was treated the same as exclusive. - None: Unset focus if the commit associated with the 'none' came from the currently focused layer. Previously it was just unset regardless.
This commit is contained in:
parent
7e419f7584
commit
36058a63e2
2 changed files with 60 additions and 36 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
struct server;
|
struct server;
|
||||||
struct output;
|
struct output;
|
||||||
|
struct seat;
|
||||||
|
|
||||||
struct lab_layer_surface {
|
struct lab_layer_surface {
|
||||||
struct wlr_scene_layer_surface_v1 *scene_layer_surface;
|
struct wlr_scene_layer_surface_v1 *scene_layer_surface;
|
||||||
|
|
@ -36,5 +37,7 @@ struct lab_layer_popup {
|
||||||
void layers_init(struct server *server);
|
void layers_init(struct server *server);
|
||||||
|
|
||||||
void layers_arrange(struct output *output);
|
void layers_arrange(struct output *output);
|
||||||
|
void layer_try_set_focus(struct seat *seat,
|
||||||
|
struct wlr_layer_surface_v1 *layer_surface);
|
||||||
|
|
||||||
#endif /* LABWC_LAYERS_H */
|
#endif /* LABWC_LAYERS_H */
|
||||||
|
|
|
||||||
93
src/layers.c
93
src/layers.c
|
|
@ -118,45 +118,64 @@ handle_output_destroy(struct wl_listener *listener, void *data)
|
||||||
wlr_layer_surface_v1_destroy(layer->scene_layer_surface->layer_surface);
|
wlr_layer_surface_v1_destroy(layer->scene_layer_surface->layer_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
process_keyboard_interactivity(struct lab_layer_surface *layer)
|
focused_layer_has_exclusive_interactivity(struct seat *seat)
|
||||||
{
|
{
|
||||||
struct wlr_layer_surface_v1 *layer_surface = layer->scene_layer_surface->layer_surface;
|
if (!seat->focused_layer) {
|
||||||
struct seat *seat = &layer->server->seat;
|
return false;
|
||||||
|
}
|
||||||
|
return seat->focused_layer->current.keyboard_interactive ==
|
||||||
|
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
||||||
|
}
|
||||||
|
|
||||||
if (layer_surface->current.keyboard_interactive
|
/*
|
||||||
&& layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
|
* Precedence is defined as being in the same or higher (overlay is highest)
|
||||||
/*
|
* than the layer with current keyboard focus.
|
||||||
* Give keyboard focus to surface if
|
*/
|
||||||
* - keyboard-interactivity is 'exclusive' or 'on-demand'; and
|
static bool
|
||||||
* - surface is in top/overlay layers; and
|
has_precedence(struct seat *seat, enum zwlr_layer_shell_v1_layer layer)
|
||||||
* - currently focused layer has a lower precedence
|
{
|
||||||
*
|
if (!seat->focused_layer) {
|
||||||
* In other words, when dealing with two surfaces with
|
return true;
|
||||||
* exclusive/on-demand keyboard-interactivity (firstly the
|
}
|
||||||
* currently focused 'focused_layer' and secondly the
|
if (!focused_layer_has_exclusive_interactivity(seat)) {
|
||||||
* 'layer_surface' for which we're just responding to a
|
return true;
|
||||||
* map/commit event), the following logic applies:
|
}
|
||||||
*
|
if (layer >= seat->focused_layer->current.layer) {
|
||||||
* | focused_layer | layer_surface | who gets keyboard focus |
|
return true;
|
||||||
* |---------------|---------------|-------------------------|
|
}
|
||||||
* | overlay | top | focused_layer |
|
return false;
|
||||||
* | overlay | overlay | layer_surface |
|
}
|
||||||
* | top | top | layer_surface |
|
|
||||||
* | top | overlay | layer_surface |
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!seat->focused_layer || seat->focused_layer->current.layer
|
void
|
||||||
<= layer_surface->current.layer) {
|
layer_try_set_focus(struct seat *seat, struct wlr_layer_surface_v1 *layer_surface)
|
||||||
|
{
|
||||||
|
switch (layer_surface->current.keyboard_interactive) {
|
||||||
|
case ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE:
|
||||||
|
wlr_log(WLR_DEBUG, "interactive-exclusive '%p'", layer_surface);
|
||||||
|
if (has_precedence(seat, layer_surface->current.layer)) {
|
||||||
seat_set_focus_layer(seat, layer_surface);
|
seat_set_focus_layer(seat, layer_surface);
|
||||||
}
|
}
|
||||||
} else if (seat->focused_layer
|
break;
|
||||||
&& !seat->focused_layer->current.keyboard_interactive) {
|
case ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND:
|
||||||
/*
|
wlr_log(WLR_DEBUG, "interactive-on-demand '%p'", layer_surface);
|
||||||
* Clear focus if keyboard-interactivity has been set to
|
if (!focused_layer_has_exclusive_interactivity(seat)) {
|
||||||
* ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE
|
seat_set_focus_layer(seat, layer_surface);
|
||||||
*/
|
}
|
||||||
seat_set_focus_layer(seat, NULL);
|
break;
|
||||||
|
case ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE:
|
||||||
|
wlr_log(WLR_DEBUG, "interactive-none '%p'", layer_surface);
|
||||||
|
if (seat->focused_layer == layer_surface) {
|
||||||
|
wlr_log(WLR_DEBUG, "unset focus '%p'", layer_surface);
|
||||||
|
/*
|
||||||
|
* TODO: consider transferring focus other layer-shell
|
||||||
|
* clients with exclusive focus (that in the case of
|
||||||
|
* multiple clients we could have stolen it from and
|
||||||
|
* arguably should give it back to).
|
||||||
|
*/
|
||||||
|
seat_set_focus_layer(seat, NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,7 +203,8 @@ handle_surface_commit(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
/* Process keyboard-interactivity change */
|
/* Process keyboard-interactivity change */
|
||||||
if (committed & WLR_LAYER_SURFACE_V1_STATE_KEYBOARD_INTERACTIVITY) {
|
if (committed & WLR_LAYER_SURFACE_V1_STATE_KEYBOARD_INTERACTIVITY) {
|
||||||
process_keyboard_interactivity(layer);
|
struct seat *seat = &layer->server->seat;
|
||||||
|
layer_try_set_focus(seat, layer_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (committed || layer->mapped != layer_surface->surface->mapped) {
|
if (committed || layer->mapped != layer_surface->surface->mapped) {
|
||||||
|
|
@ -250,7 +270,8 @@ handle_map(struct wl_listener *listener, void *data)
|
||||||
* the scene. See wlr_scene_surface_create() documentation.
|
* the scene. See wlr_scene_surface_create() documentation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
process_keyboard_interactivity(layer);
|
struct seat *seat = &layer->server->seat;
|
||||||
|
layer_try_set_focus(seat, layer->scene_layer_surface->layer_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue