spmenu-wiki/pages/Keybinds.md

168 lines
7.9 KiB
Markdown
Raw Normal View History

2023-02-03 16:40:18 +01:00
Keybinds
========
Like the `BarRules` array mentioned, there is a `Key keys` array in `keybinds.h` which contains all keybinds speedwm will recognize. While this isn't the only way to add keybinds in speedwm, it does not require any additional software to be installed.
### Key structure (user-friendly)
1. Event
Type: `int`
2. Modifier
Type: `unsigned int`
3. Chain key
Type: `KeySym`
4. Key
Type: `KeySym`
5. Function
Type: `void (*func)`
6. Function arguments
Type: `const Arg`
### Key structure (internally)
`typedef struct {`
`int type;`
`unsigned int mod;`
`KeySym chain;`
`KeySym keysym;`
`void (*func)(const Arg *);`
`const Arg arg;`
`} Key;`
### Event
The event value allow you to specify when a keybind is executed. Internally this is known as `int type` and it specifies when the function is executed.
- KeyPress: Activate immediately on key press.
- KeyRelease: Activate immediately on key release.
### Modifier
There are a lot of different modifiers, this list is only going to list the ones declared in speedwm. You can, of course declare more if necessary although it should be noted that doing so is out of the scope of this documentation. We will be focusing on the defined modifiers which are defined in `speedwm.c` like this:
`/* Modifiers */`
`#define CONTROL ControlMask`
`#define SHIFT ShiftMask`
`#define ALT Mod1Mask`
`#define ALTR Mod3Mask`
`#define SUPER Mod4Mask`
`#define SUPERR Mod5Mask`
Below is a list of defined modifiers:
- CONTROL Left Control (Ctrl) key.
- SHIFT Left Shift key.
- ALT Left Alt key.
- SUPER Left Super (Windows) key.
- SUPERR Right Super (Windows) key.
In keybinds.h, MODIFIER1 and MODIFIER2 are also defined. MODIFIER1 is defined in order to make modifying keybinds easier. MODIFIER1 is by default defined as SUPER or Mod4Mask. For instance, if you want to use MODIFIER1 as your modifier, `MODIFIER1` would be the right value here.
Do note that you can may use multiple modifiers. Do this by adding two or more modifiers separated by a pipe (MODIFIER1|SHIFT)
### Chain key
This value *is* mandatory, but it does not have to be used. speedwm has supported chained keybinds since 0.4. Chained keybinds allow more keybinds as like the name implies, the user has to press multiple keys to activate it. You can think of it as in Vim where there's different modes.
The first key that needs to be pressed to activate a chain needs to be the key specified here. In order to see a list of possible keys, see `/usr/include/X11/keysymdef.h`. If, let's say we want to use simply the letter `a` as the key to start a chain, the value here would be `XK_a`.
If we want a normal key, one that is **not** chained, we can accomplish that by simply setting the Chain key to `-1`. You can see this in the `keypress()` function in `speedwm.c`. This line of code is responsible for this behavior.
`if (keysym == keys[i].keysym && keys[i].chain == -1`
### Key
The next value, similar to the Chain key also needs to be a keysym. If the key is a chained key, this is the second key that needs to be pressed. If it isn't a chained key, this is the key that needs to be pressed while the Modifier is pressed.
In order to see a list of possible keys, see `/usr/include/X11/keysymdef.h`. Note that this path may differ depending on your operating system.
There are a lot more keys technically defined, see `/usr/include/X11/XF86keysym.h` for a list of media keys.
### Function
Many functions expect `const Arg *arg` to be passed to them. However this value does require any function argument to be specified because it simply passes the next value to the function and calls it.
There is no list of functions, but `speedwm.c` has a lot of declared functions which you may use in keybinds provided the function expects `const Arg *arg`.
### Function arguments
This is the actual argument passed to the function we're calling when the keybind is activated. Explaining this well would be fairly simple, but instead of doing so I recommend you read the `typedef union Arg` in `speedwm.c`. It looks like this:
`typedef union {`
`long i;`
`unsigned long ui;`
`float f;`
`const void *v;`
`} Arg;`
In short, Arg is a list of different types, which may be used to set different things in the argument.
Passing a float (such as mfact) through would mean I should override `.f`, passing an integer (such as barposition) through would mean I should override `.i`. There's also `.v` for `void` and `.ui` for tags. This is not used unless you want to mess with tag keybinds.
When you don't care about the value given to the function, you may simply enter a `0`.
### Example keybind
With all that said, you probably get the idea of how it works. But you still don't know how to put all this knowledge together.
1. `{ KeyPress,`
2. `MODIFIER1|SHIFT,`
3. `-1,`
4. `XK_w,`
5. `spawn,`
6. `cmd( "firefox" ) },`
Combined into one line: `{ KeyPress, MODIFIER1|SHIFT, -1, XK_w, spawn, cmd( "firefox" ) },`
Let's break down the above.
1. This is our type. If it's `KeyPress`, it will be activated when the keybind is pressed. If it is `KeyRelease` it will be activated when the keybind is released.
2. This is our modifier. `MODIFIER1` is defined in `keybinds.h`. We're adding SHIFT to it, (defined in `speedwm.c`) which means we have to press BOTH `MODIFIER1` and `SHIFT` at the same time to activate this keybind.
3. This is our **chain** key. `-1` here indicates that we do not want it to be chained. We want a regular keybind. See the example below for an example *with* a chained keybind instead.
4. This is our regular key. `XK_w` is defined in `/usr/include/X11/keysymdef.h` on most operating systems and it means we have to press `w` on our keyboard along with the modifier to activate this keybind.
5. This is our function. We call this, passing the next value (`const Arg *arg`) to it.
6. This is our function argument. Do note that in this case `cmd()` is a macro and it is defined in `speedwm.c`. This macro will pass the contents of the macro to a shell it will spawn.
Feel free to copy the above to `keybinds.h` if you want to experiment with it.
### Example chained keybind
1. `{ KeyPress,`
2. `MODIFIER1|SHIFT,`
3. `XK_a,`
4. `XK_w,`
5. `togglebar,`
6. `{0} },`
Combined into one line: `{ KeyPress, MODIFIER1|SHIFT, XK_a, XK_w, togglebar, {0} },`
Let's break down the above.
1. This is our type. If it's `KeyPress`, it will be activated when the keybind is pressed. If it is `KeyRelease` it will be activated when the keybind is released.
2. This is our modifier. `MODIFIER1` is defined in `keybinds.h`. We're adding SHIFT to it, (defined in `speedwm.c`) which means we have to press BOTH `MODIFIER1` and `SHIFT` at the same time to activate this keybind.
3. This is our **chain** key. `XK_a` here is the key we have to press along with our modifier to activate this keybind. `XK_a` is defined in `/usr/include/X11/keysymdef.h` on most operating systems.
4. This is our regular key. `XK_w` is defined in `/usr/include/X11/keysymdef.h` on most operating systems and it means we have to press `w` on our keyboard to activate this keybind. Note that we do **not** need to press the modifier here, because it is a chained keybind.
5. This is our function. We call this, passing the next value (`const Arg *arg`) to it.
6. This is our function argument. We simply pass `0` here because we don't need to pass anything to the function, because the function does not care.
Feel free to copy the above to `keybinds.h` if you want to experiment with it.
This should give you a brief idea of how keybinds work in speedwm. Most of this carries over to `dwm` as well, although it does not have some of this stuff. It should be noted that as I mentioned previously, you don't HAVE to use this system. You can use external programs to handle keybinds, and `libspeedwm` to perform actions in speedwm. sxkbd is one popular program for this purpose and window managers like `bspwm` use it. However such a solution is out of the scope of this documentation!