Don’t use SYNC key bindings for Mode_switch but re-grab keys
Before this commit, i3 used key bindings in SYNC mode for bindings like Mode_switch + <a> and replayed the key if the current state did not include Mode_switch. This had some problems: 1) The WM needed to acknowledge much more key presses than you actually had bindings for, thus making the system a bit laggy sometimes. 2) Users of layouts who constantly type in the third level (like russian layouts) did not get their cyrillic symbols correctly (they were not replayed right), neither did the keybindings work in both modes. So, the current implementation uses the following approach: XKB provides an event which contains the current state (including the current level). i3 signs up for this event and upon receival, it re-maps the bindings using Mode_switch (enables them when the level goes to the third level and disables them as soon as the level goes back to normal). This fixes both problems.
This commit is contained in:
@ -133,6 +133,12 @@ struct Config {
|
||||
*/
|
||||
void load_configuration(xcb_connection_t *conn, const char *override_configfile, bool reload);
|
||||
|
||||
/**
|
||||
* Translates keysymbols to keycodes for all bindings which use keysyms.
|
||||
*
|
||||
*/
|
||||
void translate_keysyms();
|
||||
|
||||
/**
|
||||
* Ungrabs all keys, to be called before re-grabbing the keys because of a
|
||||
* mapping_notify event or a configuration file reload
|
||||
@ -144,7 +150,7 @@ void ungrab_all_keys(xcb_connection_t *conn);
|
||||
* Grab the bound keys (tell X to send us keypress events for those keycodes)
|
||||
*
|
||||
*/
|
||||
void grab_all_keys(xcb_connection_t *conn);
|
||||
void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch);
|
||||
|
||||
/**
|
||||
* Switches the key bindings to the given mode, if the mode exists
|
||||
@ -152,6 +158,13 @@ void grab_all_keys(xcb_connection_t *conn);
|
||||
*/
|
||||
void switch_mode(xcb_connection_t *conn, const char *new_mode);
|
||||
|
||||
/**
|
||||
* Returns a pointer to the Binding with the specified modifiers and keycode
|
||||
* or NULL if no such binding exists.
|
||||
*
|
||||
*/
|
||||
Binding *get_binding(uint16_t modifiers, xcb_keycode_t keycode);
|
||||
|
||||
/* prototype for src/cfgparse.y */
|
||||
void parse_file(const char *f);
|
||||
|
||||
|
@ -13,14 +13,6 @@
|
||||
|
||||
#include <xcb/randr.h>
|
||||
|
||||
/**
|
||||
* Due to bindings like Mode_switch + <a>, we need to bind some keys in
|
||||
* XCB_GRAB_MODE_SYNC. Therefore, we just replay all key presses.
|
||||
*
|
||||
*/
|
||||
int handle_key_release(void *ignored, xcb_connection_t *conn,
|
||||
xcb_key_release_event_t *event);
|
||||
|
||||
/**
|
||||
* There was a key press. We compare this key code with our bindings table and
|
||||
* pass the bound action to parse_command().
|
||||
|
@ -27,6 +27,7 @@ extern xcb_connection_t *global_conn;
|
||||
extern xcb_key_symbols_t *keysyms;
|
||||
extern char **start_argv;
|
||||
extern Display *xkbdpy;
|
||||
extern int xkb_current_group;
|
||||
extern TAILQ_HEAD(bindings_head, Binding) *bindings;
|
||||
extern TAILQ_HEAD(autostarts_head, Autostart) autostarts;
|
||||
extern TAILQ_HEAD(assignments_head, Assignment) assignments;
|
||||
|
Reference in New Issue
Block a user