Skip to content

Commit

Permalink
WIP: state: add API for updating latched and locked mods & layout in …
Browse files Browse the repository at this point in the history
…server state

Up to now, the "server state" xkb_state API only offered one entry point
to update the server state - `xkb_state_update_key`, which reflects the
direct keyboard keys state. But some updates come out-of-band from
keyboard input events stream, for example, a GUI layout switcher.

The X11 XKB protocol has a request which allows for such updates,
`XkbLatchLockState`[0], but xkbcommon does not have similar
functionality. So server applications ended up using
`xkb_state_update_state` for this, but that's a function intended for
client applications, not servers.

Add support for updating the latched & locked state of the mods and
layout. Note that the depressed states cannot be updated in this way --
XKB does not expect them to be updated out of band.

[0] https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Querying_and_Changing_Keyboard_State

Fixes: #310
Signed-off-by: Ran Benita <ran@unusedvar.com>
  • Loading branch information
bluetech committed Dec 17, 2022
1 parent 5ba075a commit b8706be
Showing 1 changed file with 58 additions and 2 deletions.
60 changes: 58 additions & 2 deletions include/xkbcommon/xkbcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@
#ifndef _XKBCOMMON_H_
#define _XKBCOMMON_H_

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>

#include <xkbcommon/xkbcommon-names.h>
#include <xkbcommon/xkbcommon-keysyms.h>
Expand Down Expand Up @@ -1441,12 +1442,67 @@ enum xkb_state_component
xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
enum xkb_key_direction direction);

/**
* Update the keyboard state to change the latched and locked state of
* the modifiers and layout.
*
* This entry point is intended for *server* applications and should not be used
* by *client* applications; see @ref server-client-state for details.
*
* Use this function to update the latched and locked state according to
* "out of band" (non-device) inputs, such as UI layout switchers.
*
* @par Layout out of range
* @parblock
*
* If the effective layout, after taking into account the depressed, latched and
* locked layout, is out of range (negative or greater than the maximum layout),
* it is brought into range. Currently, the layout is wrapped using integer
* modulus (with negative values wrapping from the end). The wrapping behavior
* may be made configurable in the future.
*
* @endparblock
*
* @param affect_latched_mods
* @param latched_mods
* Modifiers to set as latched or unlatched. Only modifiers in
* `affect_latched_mods` are considered.
* @param affect_latched_layout
* @param latched_layout
* Layout to latch. Only considered if `affect_latched_layout` is true.
* Maybe be out of range (including negative) -- see note above.
* @param affect_locked_mods
* @param locked_mods
* Modifiers to set as locked or unlocked. Only modifiers in
* `affect_locked_mods` are considered.
* @param affect_locked_layout
* @param locked_layout
* Layout to lock. Only considered if `affect_locked_layout` is true.
* Maybe be out of range (including negative) -- see note above.
*
* @returns A mask of state components that have changed as a result of
* the update. If nothing in the state has changed, returns 0.
*
* @memberof xkb_state
*
* @sa xkb_state_update_mask()
*/
enum xkb_state_component
xkb_state_update_latched_locked(xkb_mod_mask_t affect_latched_mods,
xkb_mod_mask_t latched_mods,
bool affect_latched_layout,
int32_t latched_layout,
xkb_mod_mask_t affect_locked_mods,
xkb_mod_mask_t locked_mods,
bool affect_locked_layout,
int32_t locked_layout);

/**
* Update a keyboard state from a set of explicit masks.
*
* This entry point is intended for *client* applications; see @ref
* server-client-state for details. *Server* applications should use
* xkb_state_update_key() instead.
* xkb_state_update_key() and xkb_state_update_latched_locked() instead.
*
* All parameters must always be passed, or the resulting state may be
* incoherent.
Expand Down

0 comments on commit b8706be

Please sign in to comment.