Skip to content

No fallback when using multiple keysyms per level #528

@wismill

Description

@wismill

In order to support multiple keysyms per level, one has to use e.g. xkb_state_key_get_syms and not xkb_state_key_get_one_sym. From the doc of xkb_state_key_get_one_sym:

This function is similar to xkb_state_key_get_syms(), but intended for users which cannot or do not want to handle the case where multiple keysyms are returned (in which case this function is preferred).

But there are cases when we would like xkb_state_key_get_one_sym to return a fallback keysym:

  1. The initial use case for multiple keysyms per level was to be able to type glyphs that requires multiple Unicode code points to be encoded. The issue is that such key:
    1. Provides no feedback to the user when an app uses only xkb_state_key_get_one_sym: it simply does nothing at all.
    2. Cannot be used in shortcuts, which usually require only one keysym.
  2. key <LCTL> { [ { Control_L, ISO_Group_Shift } ] };: Here ISO_Group_Shift is a considered a side effect, but if multiple keysyms are not supported then we loose Control_L completely. It would be very useful to be able to fallback to a single keysym Control_L, e.g. when loading the keymap into XWayland. Else no interpretation is run on the key and it may affect virtual modifiers mappings to real modifiers.

Issue 1.1 can be solved using e.g. a Unicode keysym in Unicode PUA and a corresponding entry in a Compose file. However, there is no alternative for issues 1.2 and 2. EDIT: since #487 we can have actions with a different count than keysyms.

We cannot blindly fallback to the first keysym of a list, because it may not make sense. But what about proposing to specify the fallback explicitly? E.g. (note the |):

EDIT: the following examples make less sense now that we have #487. But a fallback is still useful for compatibility with e.g. X11.

// Fallback to simply `Control_L` when using `xkb_state_key_get_one_sym` or similar functions.
key <LCTL> { [ { Control_L, ISO_Group_Shift } | Control_L ] };
// Different order, same result.
// It depends if we read the previous as “graceful degradation” or the next as “progressive enhancement”.
key <LCTL> { [ Control_L | { Control_L, ISO_Group_Shift } ] };
// Invalid: must be a single keysym and a single list
key <LCTL> { [ { Control_L, x } | { Control_L, ISO_Group_Shift } ] };
// Invalid: must be a single keysym and a single list
key <LCTL> { [ a | b | c ] };

// Some other ideas
// Better grouping?
key <LCTL> { [ { Control_L, ISO_Group_Shift | Control_L } ] };
// Better to be explicit but verbose?
key <LCTL> { [ { Control_L, ISO_Group_Shift, fallback=Control_L } ] };

What about the actions? If we have a fallback for actions too, I think we should run the interpretations on all keysyms (normal+fallback), even if the resulting actions differ: we defer the decision whether it makes sense or no to the layout designer. Note that the action on the single keysym will be unused by the state; it would be used only in an hypothetical compatibility format for e.g. loading into X servers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    keysymsstateIndicates a need for improvements or additions to the xkb_state API

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions