Skip to content

Commit

Permalink
Adds support for 'exclusive' keyboard interactivity on top and bottom…
Browse files Browse the repository at this point in the history
… layers.
  • Loading branch information
phkaeser committed Feb 13, 2025
1 parent 91cdd1c commit 8eb58ec
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 9 deletions.
51 changes: 44 additions & 7 deletions src/layer_panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ static void _wlmaker_layer_panel_destroy(

static bool _wlmaker_layer_panel_apply_keyboard(
wlmaker_layer_panel_t *layer_panel_ptr,
enum zwlr_layer_surface_v1_keyboard_interactivity interactivity);
enum zwlr_layer_surface_v1_keyboard_interactivity interactivity,
enum zwlr_layer_shell_v1_layer zwlr_layer);
static bool _wlmaker_layer_panel_apply_layer(
wlmaker_layer_panel_t *layer_panel_ptr,
enum zwlr_layer_shell_v1_layer zwlr_layer);
Expand Down Expand Up @@ -251,19 +252,54 @@ wlmtk_workspace_layer_t _wlmaker_layer_from_zwlr_layer(
}

/* ------------------------------------------------------------------------- */
/** Applies the requested keyboard setting. Currently warns on non-zero. */
/**
* Applies the requested keyboard setting.
*
* Supports 'NONE' and 'EXCLUSIVE' interactivity, but the latter only on
* top and overlay layers.
*
* TODO([email protected]): Implement full support, once layer elements have a
* means to organically obtain and release keyboard focus (eg. through pointer
* button clicks).
*
* @param layer_panel_ptr
* @param interactivity
* @param zwlr_layer
*
* @return true on success.
*/
bool _wlmaker_layer_panel_apply_keyboard(
wlmaker_layer_panel_t *layer_panel_ptr,
enum zwlr_layer_surface_v1_keyboard_interactivity interactivity)
enum zwlr_layer_surface_v1_keyboard_interactivity interactivity,
enum zwlr_layer_shell_v1_layer zwlr_layer)
{
if (ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE != interactivity) {
switch (interactivity) {
case ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE:
break;

case ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE:
if (ZWLR_LAYER_SHELL_V1_LAYER_TOP != zwlr_layer &&
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY != zwlr_layer) {
wl_resource_post_error(
layer_panel_ptr->wlr_layer_surface_v1_ptr->resource,
WL_DISPLAY_ERROR_IMPLEMENTATION,
"Exclusive interactivity unsupported on layer %d", zwlr_layer);
return false;
}

wlmtk_surface_set_activated(layer_panel_ptr->wlmtk_surface_ptr, true);
break;

case ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND:
default:
wl_resource_post_error(
layer_panel_ptr->wlr_layer_surface_v1_ptr->resource,
WL_DISPLAY_ERROR_IMPLEMENTATION,
"Unsupported setting for keyboard interactivity: %d",
interactivity);
return false;
}

return true;
}

Expand Down Expand Up @@ -380,12 +416,13 @@ void _wlmaker_layer_panel_handle_surface_commit(
&pos);

// Updates keyboard and layer values. Ignore failures here.
_wlmaker_layer_panel_apply_keyboard(
layer_panel_ptr,
state_ptr->keyboard_interactive);
_wlmaker_layer_panel_apply_layer(
layer_panel_ptr,
state_ptr->layer);
_wlmaker_layer_panel_apply_keyboard(
layer_panel_ptr,
state_ptr->keyboard_interactive,
state_ptr->layer);
}

/* ------------------------------------------------------------------------- */
Expand Down
22 changes: 22 additions & 0 deletions src/toolkit/content.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ static void _wlmtk_content_element_get_dimensions(
int *right_ptr,
int *bottom_ptr);

static void _wlmtk_content_element_keyboard_blur(
wlmtk_element_t *element_ptr);

/* == Data ================================================================= */

/** Virtual method table for the content's superclass @ref wlmtk_element_t. */
static const wlmtk_element_vmt_t _wlmtk_content_element_vmt = {
.get_dimensions = _wlmtk_content_element_get_dimensions,
.keyboard_blur = _wlmtk_content_element_keyboard_blur,
};

/* == Exported methods ===================================================== */
Expand Down Expand Up @@ -290,6 +294,24 @@ void _wlmtk_content_element_get_dimensions(
left_ptr, top_ptr, right_ptr, bottom_ptr);
}

/* ------------------------------------------------------------------------- */
/**
* De-activates keyboard focus for the content: Propagates the blur to all
* children, and then de-activates the content's window.
*
* @param element_ptr
*/
void _wlmtk_content_element_keyboard_blur(wlmtk_element_t *element_ptr)
{
wlmtk_content_t *content_ptr = BS_CONTAINER_OF(
element_ptr, wlmtk_content_t, super_container.super_element);

content_ptr->orig_super_element_vmt.keyboard_blur(element_ptr);
if (NULL != content_ptr->window_ptr) {
wlmtk_window_set_activated(content_ptr->window_ptr, false);
}
}

/* == Fake content, for tests ============================================== */

static void _wlmtk_fake_content_request_close(wlmtk_content_t *content_ptr);
Expand Down
4 changes: 4 additions & 0 deletions src/toolkit/content.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ struct _wlmtk_content_vmt_t {
/**
* Sets whether this content as activated (keyboard focus).
*
* The implementation must (for the effective contained element) issue a
* call to @ref wlmtk_container_set_keyboard_focus_element to claim or
* release keyboard focus.
*
* @param content_ptr
* @param activated
*/
Expand Down
7 changes: 7 additions & 0 deletions src/toolkit/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ void wlmtk_window_set_activated(
wlmtk_window_t *window_ptr,
bool activated)
{
if (window_ptr->activated == activated) return;

window_ptr->activated = activated;
wlmtk_content_set_activated(window_ptr->content_ptr, activated);
if (NULL != window_ptr->titlebar_ptr) {
Expand All @@ -324,6 +326,11 @@ void wlmtk_window_set_activated(

if (!activated) {
wlmtk_window_menu_set_enabled(window_ptr, false);

// TODO([email protected]): Should test this behaviour.
if (NULL != window_ptr->workspace_ptr) {
wlmtk_workspace_activate_window(window_ptr->workspace_ptr, NULL);
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/toolkit/workspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,16 +615,17 @@ void wlmtk_workspace_activate_window(
if (workspace_ptr->activated_window_ptr == window_ptr) return;

if (NULL != workspace_ptr->activated_window_ptr) {
wlmtk_window_set_activated(workspace_ptr->activated_window_ptr, false);
wlmtk_window_t *w_ptr = workspace_ptr->activated_window_ptr;
workspace_ptr->formerly_activated_window_ptr =
workspace_ptr->activated_window_ptr;
workspace_ptr->activated_window_ptr = NULL;
wlmtk_window_set_activated(w_ptr, false);
}

if (NULL != window_ptr) {
if (workspace_ptr->enabled) {
wlmtk_window_set_activated(window_ptr, true);
workspace_ptr->activated_window_ptr = window_ptr;
wlmtk_window_set_activated(window_ptr, true);
}
workspace_ptr->formerly_activated_window_ptr = window_ptr;
}
Expand Down

0 comments on commit 8eb58ec

Please sign in to comment.