Implement modes. Modes allow you to use different keybindings and switch between them.
For example, you can create a mode which will let you resize windows with some easy to use keys. So, instead of binding a combination of your homerow and modifiers to resize, like this: bind Mod4+44 resize right +10 bind Mod4+45 resize right -10 ... You can instead define a new mode: mode "resize" { bind 44 resize right +10 bind 45 resize right -10 ... bind 36 mode default } bindsym Mod4+r mode resize So, if you press Mod4+r now, your keybindings will be set to the ones defined in your resize mode above. You can then use your homerow (without any other modifier) to resize the current column/row and press enter to go back to the default mode when you are done. Note that using this option requires you to enable the new lexer/parser by passing the -l flag to i3 when starting.
This commit is contained in:
58
src/config.c
58
src/config.c
@ -31,6 +31,7 @@
|
||||
void parse_file(const char *f);
|
||||
|
||||
Config config;
|
||||
struct modes_head modes;
|
||||
|
||||
bool config_use_lexer = false;
|
||||
|
||||
@ -99,7 +100,7 @@ static void grab_keycode_for_binding(xcb_connection_t *conn, Binding *bind, uint
|
||||
*/
|
||||
void grab_all_keys(xcb_connection_t *conn) {
|
||||
Binding *bind;
|
||||
TAILQ_FOREACH(bind, &bindings, bindings) {
|
||||
TAILQ_FOREACH(bind, bindings, bindings) {
|
||||
/* The easy case: the user specified a keycode directly. */
|
||||
if (bind->keycode > 0) {
|
||||
grab_keycode_for_binding(conn, bind, bind->keycode);
|
||||
@ -137,6 +138,28 @@ void grab_all_keys(xcb_connection_t *conn) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Switches the key bindings to the given mode, if the mode exists
|
||||
*
|
||||
*/
|
||||
void switch_mode(xcb_connection_t *conn, const char *new_mode) {
|
||||
struct Mode *mode;
|
||||
|
||||
LOG("Switching to mode %s\n", new_mode);
|
||||
|
||||
SLIST_FOREACH(mode, &modes, modes) {
|
||||
if (strcasecmp(mode->name, new_mode) != 0)
|
||||
continue;
|
||||
|
||||
ungrab_all_keys(conn);
|
||||
bindings = mode->bindings;
|
||||
grab_all_keys(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG("ERROR: Mode not found\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads the configuration from ~/.i3/config or /etc/i3/config if not found.
|
||||
*
|
||||
@ -149,13 +172,22 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
|
||||
/* First ungrab the keys */
|
||||
ungrab_all_keys(conn);
|
||||
|
||||
/* Clear the old binding and assignment lists */
|
||||
struct Mode *mode;
|
||||
Binding *bind;
|
||||
while (!TAILQ_EMPTY(&bindings)) {
|
||||
bind = TAILQ_FIRST(&bindings);
|
||||
TAILQ_REMOVE(&bindings, bind, bindings);
|
||||
FREE(bind->command);
|
||||
FREE(bind);
|
||||
while (!SLIST_EMPTY(&modes)) {
|
||||
mode = SLIST_FIRST(&modes);
|
||||
FREE(mode->name);
|
||||
|
||||
/* Clear the old binding list */
|
||||
bindings = mode->bindings;
|
||||
while (!TAILQ_EMPTY(bindings)) {
|
||||
bind = TAILQ_FIRST(bindings);
|
||||
TAILQ_REMOVE(bindings, bind, bindings);
|
||||
FREE(bind->command);
|
||||
FREE(bind);
|
||||
}
|
||||
FREE(bindings);
|
||||
SLIST_REMOVE(&modes, mode, Mode, modes);
|
||||
}
|
||||
|
||||
struct Assignment *assign;
|
||||
@ -167,6 +199,16 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
|
||||
}
|
||||
}
|
||||
|
||||
SLIST_INIT(&modes);
|
||||
|
||||
struct Mode *default_mode = scalloc(sizeof(struct Mode));
|
||||
default_mode->name = sstrdup("default");
|
||||
default_mode->bindings = scalloc(sizeof(struct bindings_head));
|
||||
TAILQ_INIT(default_mode->bindings);
|
||||
SLIST_INSERT_HEAD(&modes, default_mode, modes);
|
||||
|
||||
bindings = default_mode->bindings;
|
||||
|
||||
SLIST_HEAD(variables_head, Variable) variables;
|
||||
|
||||
#define OPTION_STRING(name) \
|
||||
@ -364,7 +406,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
|
||||
LOG("keycode = %d, symbol = %s, modifiers = %d, command = *%s*\n", new->keycode, new->symbol, modifiers, rest);
|
||||
new->mods = modifiers;
|
||||
new->command = sstrdup(rest);
|
||||
TAILQ_INSERT_TAIL(&bindings, new, bindings);
|
||||
TAILQ_INSERT_TAIL(bindings, new, bindings);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user