XkbOutOfRangeGroupInfo(3)
π XkbOutOfRangeGroupInfo(3) β XKB FUNCTIONS β¨
okay so this is a page from the XKB FUNCTIONS manual, and honestly? it's giving "niche but iconic" π like, it's a tiny function but it's holding together a whole vibe of group-range normalization, iykyk.
πΈ NAME πΈ
XkbOutOfRangeGroupInfo β bestie, this one returns only the out-of-range processing information from the group_info field of an XkbSymMapRec structure. that's it, that's the whole job π
β¨ SYNOPSIS β¨
unsigned char XkbOutOfRangeGroupInfo (unsigned char grp_inf);
π«Ά ARGUMENTS π«Ά
grp_infβ the Xkb description of interest. yeah that's the whole description, it's a mystery but we respect it π
π DESCRIPTION π
XkbOutOfRangeGroupInfo returns only the out-of-range processing information from the group_info field of an XkbSymMapRec structure. literally just that one little slice of the byte, and it ate π₯
so the group_info field of an XkbSymMapRec is a whole encoded value situation β it's packing the number of groups of symbols bound to the key and the specification of the treatment of out-of-range groups into one little byte. multitasking icon π
fun fact (and by fun i mean a real technical fact): it's legal for a key to have zero groups, in which case it also has zero symbols and all events from that key yield NoSymbol. zero groups, zero symbols, zero drama, we love a clean slate π
here's the friend group of related functions, no cap:
- to obtain the number of groups of symbols bound to the key, use
XkbKeyNumGroups. - to change the number of groups bound to a key, use
XkbChangeTypesOfKey. - to obtain a mask that determines the treatment of out-of-range groups, use
XkbKeyGroupInfoandXkbOutOfRangeGroupInfo.
now. the keyboard controls contain a groups_wrap field specifying the handling of illegal groups on a global basis. like, when the user performs an action causing the effective group to go out of the legal range, the groups_wrap field specifies how to normalize the effective keyboard group to a group that is legal for the keyboard as a whole β but (and this is the important part π¨) there is no guarantee that the normalized group will be within the range of legal groups for any individual key. so the global fix is not a per-key fix, and that's just how it is fr fr.
the per-key group_info field specifies how a key treats a legal effective group if the key does not have a type specified for the group of concern. example time, because this one's actually kind of iconic: the Enter key usually has just one group defined. so if the user performs an action causing the global keyboard group to change to Group2, the group_info field for the Enter key describes how to handle this situation. main character problem, tiny little byte solution π
out-of-range groups for individual keys are mapped to a legal group using the same options as are used for the overall keyboard group. the particular type of mapping used is controlled by the bits set in the group_info flag, as shown in Table 1 π
Table 1 β group_info Range Normalization
- Bits set in
group_info:XkbRedirectIntoRangeβ Normalization method:XkbRedirectIntoRange - Bits set in
group_info:XkbClampIntoRangeβ Normalization method:XkbClampIntoRange - Bits set in
group_info: none of the above β Normalization method:XkbWrapIntoRange
π¦ STRUCTURES π¦
The KeySymMapRec structure is defined as follows:
#define XkbNumKbdGroups 4
#define XkbMaxKbdGroup (XkbNumKbdGroups-1)
typedef struct { /* map to keysyms for a single keycode */
unsigned char kt_index[XkbNumKbdGroups]; /* key type index for each group */
unsigned char group_info; /* # of groups and out of range group handling */
unsigned char width; /* max # of shift levels for key */
unsigned short offset; /* index to keysym table in syms array */
} XkbSymMapRec, *XkbSymMapPtr;
The XkbControlsRec structure is defined as follows:
#define XkbMaxLegalKeyCode 255
#define XkbPerKeyBitArraySize ((XkbMaxLegalKeyCode+1)/8)
typedef struct {
unsigned char mk_dflt_btn; /* default button for keyboard driven mouse */
unsigned char num_groups; /* number of keyboard groups */
unsigned char groups_wrap; /* how to wrap out-of-bounds groups */
XkbModsRec internal; /* defines server internal modifiers */
XkbModsRec ignore_lock; /* modifiers to ignore when checking for grab */
unsigned int enabled_ctrls; /* 1 bit => corresponding boolean control enabled */
unsigned short repeat_delay; /* ms delay until first repeat */
unsigned short repeat_interval; /* ms delay between repeats */
unsigned short slow_keys_delay; /* ms minimum time key must be down to be ok */
unsigned short debounce_delay; /* ms delay before key reactivated */
unsigned short mk_delay; /* ms delay to second mouse motion event */
unsigned short mk_interval; /* ms delay between repeat mouse events */
unsigned short mk_time_to_max; /* # intervals until constant mouse move */
unsigned short mk_max_speed; /* multiplier for maximum mouse speed */
short mk_curve; /* determines mouse move curve type */
unsigned short ax_options; /* 1 bit => Access X option enabled */
unsigned short ax_timeout; /* seconds until Access X disabled */
unsigned short axt_opts_mask; /* 1 bit => options to reset on Access X timeout */
unsigned short axt_opts_values; /* 1 bit => turn option on, 0=> off */
unsigned int axt_ctrls_mask; /* which bits in enabled_ctrls to modify */
unsigned int axt_ctrls_values; /* values for new bits in enabled_ctrls */
unsigned char per_key_repeat[XkbPerKeyBitArraySize]; /* per key auto repeat */
} XkbControlsRec, *XkbControlsPtr;
The XkbControlsRec structure is defined as follows:
#define XkbMaxLegalKeyCode 255
#define XkbPerKeyBitArraySize ((XkbMaxLegalKeyCode+1)/8)
typedef struct {
unsigned char mk_dflt_btn; /* default button for keyboard driven mouse */
unsigned char num_groups; /* number of keyboard groups */
unsigned char groups_wrap; /* how to wrap out-of-bounds groups */
XkbModsRec internal; /* defines server internal modifiers */
XkbModsRec ignore_lock; /* modifiers to ignore when checking for grab */
unsigned int enabled_ctrls; /* 1 bit => corresponding boolean control enabled */
unsigned short repeat_delay; /* ms delay until first repeat */
unsigned short repeat_interval; /* ms delay between repeats */
unsigned short slow_keys_delay; /* ms minimum time key must be down to be ok */
unsigned short debounce_delay; /* ms delay before key reactivated */
unsigned short mk_delay; /* ms delay to second mouse motion event */
unsigned short mk_interval; /* ms delay between repeat mouse events */
unsigned short mk_time_to_max; /* # intervals until constant mouse move */
unsigned short mk_max_speed; /* multiplier for maximum mouse speed */
short mk_curve; /* determines mouse move curve type */
unsigned short ax_options; /* 1 bit => Access X option enabled */
unsigned short ax_timeout; /* seconds until Access X disabled */
unsigned short axt_opts_mask; /* 1 bit => options to reset on Access X timeout */
unsigned short axt_opts_values; /* 1 bit => turn option on, 0=> off */
unsigned int axt_ctrls_mask; /* which bits in enabled_ctrls to modify */
unsigned int axt_ctrls_values; /* values for new bits in enabled_ctrls */
unsigned char per_key_repeat[XkbPerKeyBitArraySize]; /* per key auto repeat */
} XkbControlsRec, *XkbControlsPtr;
yes bestie, the XkbControlsRec block really is defined twice in here. we don't ask questions, we just copy it faithfully. it's part of the lore π
π SEE ALSO π
XkbChangeTypesOfKey(3)XkbKeyGroupInfo(3)XkbOutOfRangeGroupInfo.(3)β yeah there's a lil period in there, and no we're not "fixing" it, it's canon π
okay that's the whole page, and it was a whole journey π stay hydrated, go read your group_info bits responsibly, and remember: out-of-range groups deserve normalization too π«Ά
sign-off time, bestie: this cutie came to you from X Version 11, libX11 1.8.14, and the page itself is XkbOutOfRangeGroupInfo(3) β mwah πβ¨π
π¦ where this page comes from
- alpine 3.24: libx11-doc 1.8.14-r0 Β· X11
- arch rolling: libx11 1.8.14-1 Β· MIT AND X11
- nixos 26.05: libx11 1.8.14
- nixpkgs unstable: libx11 1.8.14
- Copyright (c) 1999, Oracle and/or its affiliates
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms