diff --git a/.editorconfig b/.editorconfig index 1be9fca..9ae0246 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,8 +1,10 @@ [*] -charset = utf-8 end_of_line = lf insert_final_newline = true +charset = utf-8 trim_trailing_whitespace = true +indent_style = tab +indent_size = 4 [Makefile] indent_style = tab diff --git a/.gitignore b/.gitignore index f5f43be..4e83503 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ target bin/swhkd bin/swhks *.zip +*.gz diff --git a/docs/INSTALL.md b/INSTALL.md similarity index 97% rename from docs/INSTALL.md rename to INSTALL.md index d35b113..ab9f26c 100644 --- a/docs/INSTALL.md +++ b/INSTALL.md @@ -1,4 +1,5 @@ # AUR: + `swhkd-git` `swhkd-musl-git` have been packaged. `swhkd-bin` & `swhkd-musl-bin` will be released soon. # Install @@ -15,8 +16,10 @@ **Compile time:** -- rustup +- git +- scdoc - make +- rustup # Compiling: @@ -28,6 +31,7 @@ - `sudo make install` # Running: + ``` swhks & pkexec swhkd diff --git a/Makefile b/Makefile index 249303f..16a5b5b 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,8 @@ POLKIT_DIR := /usr/share/polkit-1/actions POLKIT_POLICY_FILE := com.github.swhkd.pkexec.policy # Remember to edit the TARGET_DIR in policy file too if you do change it. TARGET_DIR := /usr/bin +MAN1_DIR:= /usr/share/man/man1 +MAN5_DIR:= /usr/share/man/man5 VERSION=$(shell awk -F ' = ' '$$1 ~ /version/ { gsub(/["]/, "", $$2); printf("%s",$$2) }' Cargo.toml) all: build @@ -20,8 +22,18 @@ glibc: @cp ./target/release/$(SERVER_BINARY) ./bin/$(SERVER_BINARY) install: - @mkdir -p $(TARGET_DIR) + @scdoc < ./$(DAEMON_BINARY).1.scd > $(DAEMON_BINARY).1.gz + @scdoc < ./$(SERVER_BINARY).1.scd > $(SERVER_BINARY).1.gz + @scdoc < ./$(DAEMON_BINARY).5.scd > $(DAEMON_BINARY).5.gz + @scdoc < ./$(DAEMON_BINARY)-keys.5.scd > $(DAEMON_BINARY)-keys.5.gz + @mv $(DAEMON_BINARY).1.gz $(MAN1_DIR) + @mv $(SERVER_BINARY).1.gz $(MAN1_DIR) + @mv $(DAEMON_BINARY).5.gz $(MAN5_DIR) + @mv $(DAEMON_BINARY)-keys.5.gz $(MAN5_DIR) + @mkdir -p $(MAN1_DIR) + @mkdir -p $(MAN5_DIR) @mkdir -p $(POLKIT_DIR) + @mkdir -p $(TARGET_DIR) @mkdir -p /etc/$(DAEMON_BINARY) @touch /etc/$(DAEMON_BINARY)/$(DAEMON_BINARY)rc @cp ./bin/$(DAEMON_BINARY) $(TARGET_DIR) diff --git a/README.md b/README.md index ea0c416..2384ba4 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@

- SWHKD - + SWHKD +

A next-generation hotkey daemon for Wayland/X11 written in Rust.

- +

@@ -24,9 +24,7 @@ Because swhkd can be used anywhere, the same swhkd config can be used across Xor ## Installation: -See [INSTALL.md](./docs/INSTALL.md) for installing swhkd. - -Note: `swhks` is not a typo, it is the server process of the program. +[Installation instructions can be found here.](./INSTALL.md) ## Running: @@ -53,7 +51,7 @@ If you use Vim, you can get swhkd config syntax highlighting with the [swhkd-vim](https://github.com/waycrate/swhkd-vim) plugin. Install it in vim-plug with `Plug 'waycrate/swhkd-vim'`. -All supported key names are listed in the [following file.](https://github.com/waycrate/swhkd/blob/main/docs/KEYS.md) +All supported key and modifier names are listed in `man 5 swhkd-keys`. ## Autostart: diff --git a/docs/assets/swhkd-svg-bg.svg b/assets/swhkd-svg-bg.svg similarity index 100% rename from docs/assets/swhkd-svg-bg.svg rename to assets/swhkd-svg-bg.svg diff --git a/docs/assets/swhkd-svg.svg b/assets/swhkd-svg.svg similarity index 100% rename from docs/assets/swhkd-svg.svg rename to assets/swhkd-svg.svg diff --git a/docs/assets/swhkd.png b/assets/swhkd.png similarity index 100% rename from docs/assets/swhkd.png rename to assets/swhkd.png diff --git a/contrib/PKGBUILD/glibc/PKGBUILD b/contrib/PKGBUILD/glibc/PKGBUILD index b3dfea6..5089011 100644 --- a/contrib/PKGBUILD/glibc/PKGBUILD +++ b/contrib/PKGBUILD/glibc/PKGBUILD @@ -10,13 +10,17 @@ url="https://github.com/waycrate/swhkd" pkgdesc="A display server independent hotkey daemon inspired by sxhkd." license=('BSD') depends=('polkit') -makedepends=('rustup' 'make' 'git') +makedepends=('rustup' 'make' 'git' 'scdoc') conflicts=('swhkd-musl-git') source=("$_pkgname::git+https://github.com/waycrate/$_pkgname") sha256sums=('SKIP') build(){ cd "$_pkgname" + scdoc < ./swhkd.1.scd > swhkd.1.gz + scdoc < ./swhks.1.scd > swhks.1.gz + scdoc < ./swhkd.5.scd > swhkd.5.gz + scdoc < ./swhkd-keys.5.scd > swhkd-keys.5.gz make setup make glibc } @@ -27,6 +31,8 @@ package() { install -Dm 755 ./bin/swhks "$pkgdir/usr/bin/swhks" install -Dm 644 -o root ./com.github.swhkd.pkexec.policy -t "$pkgdir/usr/share/polkit-1/actions" + install -Dm 644 ./*.1.gz -t "$pkgdir/usr/share/man/man1/" + install -Dm 644 ./*.5.gz -t "$pkgdir/usr/share/man/man5/" } pkgver() { diff --git a/contrib/PKGBUILD/musl_libc/PKGBUILD b/contrib/PKGBUILD/musl_libc/PKGBUILD index 7a63ab0..28984b7 100644 --- a/contrib/PKGBUILD/musl_libc/PKGBUILD +++ b/contrib/PKGBUILD/musl_libc/PKGBUILD @@ -11,12 +11,16 @@ pkgdesc="A display server independent hotkey daemon inspired by sxhkd." license=('BSD') conflicts=('swhkd-glib-git') depends=('polkit') -makedepends=('rustup' 'make' 'git') +makedepends=('rustup' 'make' 'git' 'scdoc') source=("$_pkgname::git+https://github.com/waycrate/$_pkgname") sha256sums=('SKIP') build(){ cd "$_pkgname" + scdoc < ./swhkd.1.scd > swhkd.1.gz + scdoc < ./swhks.1.scd > swhks.1.gz + scdoc < ./swhkd.5.scd > swhkd.5.gz + scdoc < ./swhkd-keys.5.scd > swhkd-keys.5.gz make setup make } @@ -27,6 +31,8 @@ package() { install -Dm 755 ./bin/swhks "$pkgdir/usr/bin/swhks" install -Dm 644 -o root ./com.github.swhkd.pkexec.policy -t "$pkgdir/usr/share/polkit-1/actions" + install -Dm 644 ./*.1.gz -t "$pkgdir/usr/share/man/man1/" + install -Dm 644 ./*.5.gz -t "$pkgdir/usr/share/man/man5/" } pkgver() { diff --git a/docs/KEYS.md b/docs/KEYS.md deleted file mode 100644 index e719bf7..0000000 --- a/docs/KEYS.md +++ /dev/null @@ -1,152 +0,0 @@ -# List of supported keys: - -If we are missing support for any key, please do let us know. - -```rust -("q", evdev::Key::KEY_Q), -("w", evdev::Key::KEY_W), -("e", evdev::Key::KEY_E), -("r", evdev::Key::KEY_R), -("t", evdev::Key::KEY_T), -("y", evdev::Key::KEY_Y), -("u", evdev::Key::KEY_U), -("i", evdev::Key::KEY_I), -("o", evdev::Key::KEY_O), -("p", evdev::Key::KEY_P), -("a", evdev::Key::KEY_A), -("s", evdev::Key::KEY_S), -("d", evdev::Key::KEY_D), -("f", evdev::Key::KEY_F), -("g", evdev::Key::KEY_G), -("h", evdev::Key::KEY_H), -("j", evdev::Key::KEY_J), -("k", evdev::Key::KEY_K), -("l", evdev::Key::KEY_L), -("z", evdev::Key::KEY_Z), -("x", evdev::Key::KEY_X), -("c", evdev::Key::KEY_C), -("v", evdev::Key::KEY_V), -("b", evdev::Key::KEY_B), -("n", evdev::Key::KEY_N), -("m", evdev::Key::KEY_M), -("1", evdev::Key::KEY_1), -("2", evdev::Key::KEY_2), -("3", evdev::Key::KEY_3), -("4", evdev::Key::KEY_4), -("5", evdev::Key::KEY_5), -("6", evdev::Key::KEY_6), -("7", evdev::Key::KEY_7), -("8", evdev::Key::KEY_8), -("9", evdev::Key::KEY_9), -("0", evdev::Key::KEY_0), -("escape", evdev::Key::KEY_ESC), -("backspace", evdev::Key::KEY_BACKSPACE), -("capslock", evdev::Key::KEY_CAPSLOCK), -("return", evdev::Key::KEY_ENTER), -("enter", evdev::Key::KEY_ENTER), -("tab", evdev::Key::KEY_TAB), -("space", evdev::Key::KEY_SPACE), -("plus", evdev::Key::KEY_KPPLUS), -("kp0", evdev::Key::KEY_KP0), -("kp1", evdev::Key::KEY_KP1), -("kp2", evdev::Key::KEY_KP2), -("kp3", evdev::Key::KEY_KP3), -("kp4", evdev::Key::KEY_KP4), -("kp5", evdev::Key::KEY_KP5), -("kp6", evdev::Key::KEY_KP6), -("kp7", evdev::Key::KEY_KP7), -("kp8", evdev::Key::KEY_KP8), -("kp9", evdev::Key::KEY_KP9), -("kpasterisk", evdev::Key::KEY_KPASTERISK), -("kpcomma", evdev::Key::KEY_KPCOMMA), -("kpdot", evdev::Key::KEY_KPDOT), -("kpenter", evdev::Key::KEY_KPENTER), -("kpequal", evdev::Key::KEY_KPEQUAL), -("kpjpcomma", evdev::Key::KEY_KPJPCOMMA), -("kpleftparen", evdev::Key::KEY_KPLEFTPAREN), -("kpminus", evdev::Key::KEY_KPMINUS), -("kpplusminus", evdev::Key::KEY_KPPLUSMINUS), -("kprightparen", evdev::Key::KEY_KPRIGHTPAREN), -("minus", evdev::Key::KEY_MINUS), -("-", evdev::Key::KEY_MINUS), -("equal", evdev::Key::KEY_EQUAL), -("=", evdev::Key::KEY_EQUAL), -("grave", evdev::Key::KEY_GRAVE), -("`", evdev::Key::KEY_GRAVE), -("print", evdev::Key::KEY_SYSRQ), -("volumeup", evdev::Key::KEY_VOLUMEUP), -("xf86audioraisevolume", evdev::Key::KEY_VOLUMEUP), -("volumedown", evdev::Key::KEY_VOLUMEDOWN), -("xf86audiolowervolume", evdev::Key::KEY_VOLUMEDOWN), -("mute", evdev::Key::KEY_MUTE), -("xf86audiomute", evdev::Key::KEY_MUTE), -("brightnessup", evdev::Key::KEY_BRIGHTNESSUP), -("xf86monbrightnessup", evdev::Key::KEY_BRIGHTNESSUP), -("brightnessdown", evdev::Key::KEY_BRIGHTNESSDOWN), -("xf86audiomedia", evdev::Key::KEY_MEDIA), -("xf86audiomicmute", evdev::Key::KEY_MICMUTE), -("micmute", evdev::Key::KEY_MICMUTE), -("xf86audionext", evdev::Key::KEY_NEXTSONG), -("xf86audioplay", evdev::Key::KEY_PLAYPAUSE), -("xf86audioprev", evdev::Key::KEY_PREVIOUSSONG), -("xf86audiostop", evdev::Key::KEY_STOP), -("xf86monbrightnessdown", evdev::Key::KEY_BRIGHTNESSDOWN), -(",", evdev::Key::KEY_COMMA), -("comma", evdev::Key::KEY_COMMA), -(".", evdev::Key::KEY_DOT), -("dot", evdev::Key::KEY_DOT), -("period", evdev::Key::KEY_DOT), -("/", evdev::Key::KEY_SLASH), -("question", evdev::Key::KEY_QUESTION), -("slash", evdev::Key::KEY_SLASH), -("backslash", evdev::Key::KEY_BACKSLASH), -("leftbrace", evdev::Key::KEY_LEFTBRACE), -("[", evdev::Key::KEY_LEFTBRACE), -("bracketleft", evdev::Key::KEY_LEFTBRACE), -("rightbrace", evdev::Key::KEY_RIGHTBRACE), -("]", evdev::Key::KEY_RIGHTBRACE), -("bracketright", evdev::Key::KEY_RIGHTBRACE), -(";", evdev::Key::KEY_SEMICOLON), -("scroll_lock", evdev::Key::KEY_SCROLLLOCK), -("semicolon", evdev::Key::KEY_SEMICOLON), -("'", evdev::Key::KEY_APOSTROPHE), -("apostrophe", evdev::Key::KEY_APOSTROPHE), -("left", evdev::Key::KEY_LEFT), -("right", evdev::Key::KEY_RIGHT), -("up", evdev::Key::KEY_UP), -("down", evdev::Key::KEY_DOWN), -("pause", evdev::Key::KEY_PAUSE), -("home", evdev::Key::KEY_HOME), -("delete", evdev::Key::KEY_DELETE), -("insert", evdev::Key::KEY_INSERT), -("end", evdev::Key::KEY_END), -("pause", evdev::Key::KEY_PAUSE), -("prior", evdev::Key::KEY_PAGEDOWN), -("next", evdev::Key::KEY_PAGEUP), -("pagedown", evdev::Key::KEY_PAGEDOWN), -("pageup", evdev::Key::KEY_PAGEUP), -("f1", evdev::Key::KEY_F1), -("f2", evdev::Key::KEY_F2), -("f3", evdev::Key::KEY_F3), -("f4", evdev::Key::KEY_F4), -("f5", evdev::Key::KEY_F5), -("f6", evdev::Key::KEY_F6), -("f7", evdev::Key::KEY_F7), -("f8", evdev::Key::KEY_F8), -("f9", evdev::Key::KEY_F9), -("f10", evdev::Key::KEY_F10), -("f11", evdev::Key::KEY_F11), -("f12", evdev::Key::KEY_F12), -("f13", evdev::Key::KEY_F13), -("f14", evdev::Key::KEY_F14), -("f15", evdev::Key::KEY_F15), -("f16", evdev::Key::KEY_F16), -("f17", evdev::Key::KEY_F17), -("f18", evdev::Key::KEY_F18), -("f19", evdev::Key::KEY_F19), -("f20", evdev::Key::KEY_F20), -("f21", evdev::Key::KEY_F21), -("f22", evdev::Key::KEY_F22), -("f23", evdev::Key::KEY_F23), -("f24", evdev::Key::KEY_F24), -``` diff --git a/docs/swhkdrc b/docs/swhkdrc deleted file mode 100644 index ddd31e4..0000000 --- a/docs/swhkdrc +++ /dev/null @@ -1,42 +0,0 @@ -# This goes in /etc/swhkd/swhkdrc - -# terminal -super + ReTuRn # case insensitive - alacritty - -super + shift + enter # enter = return - kitty - -# file manager -super + shift + f - pcmanfm - -# web-browser -super + w - firefox - -# bspwm -super + {_,shift + }{h,j,k,l} - bspc node -{f,s} {west,south,north,east} - -super + ctrl + alt + {Left\ -,Down\ -,Up\ -,Right} - n=10; \ - { d1=left; d2=right; dx=-$n; dy=0; \ - , d1=bottom; d2=top; dx=0; dy=$n; \ - , d1=top; d2=bottom; dx=0; dy=-$n; \ - , d1=right; d2=left; dx=$n; dy=0; \ - } \ - bspc node --resize $d1 $dx $dy || bspc node --resize $d2 $dx $dy - -super + {\,, .} - bspc node -f {next.local,prev.local} - -# screenshot -print - scrot - -ctrl + print - scrot -s diff --git a/src/config.rs b/src/config.rs index 86389d6..9794d98 100644 --- a/src/config.rs +++ b/src/config.rs @@ -250,6 +250,7 @@ impl Value for &Hotkey { } pub fn parse_contents(path: PathBuf, contents: String) -> Result, Error> { + // Don't forget to update valid key list on the man page if you do change this list. let key_to_evdev_key: HashMap<&str, evdev::Key> = HashMap::from([ ("q", evdev::Key::KEY_Q), ("w", evdev::Key::KEY_W), @@ -399,6 +400,7 @@ pub fn parse_contents(path: PathBuf, contents: String) -> Result, Er ("f24", evdev::Key::KEY_F24), ]); + // Don't forget to update modifier list on the man page if you do change this list. let mod_to_mod_enum: HashMap<&str, Modifier> = HashMap::from([ ("ctrl", Modifier::Control), ("control", Modifier::Control), diff --git a/swhkd-keys.5.scd b/swhkd-keys.5.scd new file mode 100644 index 0000000..a5e0370 --- /dev/null +++ b/swhkd-keys.5.scd @@ -0,0 +1,174 @@ +swhkd(5) "github.com/waycrate/swhkd" "File Formats Manual" + +# NAME + +swhkd - Hotkey daemon inspired by sxhkd written in rust + +# VALID MODIFIERS + + - Ctrl + - Control + - Super + - Mod4 + - Alt + - Mod1 + - Shift + +# VALID KEYS + - q + - w + - e + - r + - t + - y + - u + - i + - o + - p + - a + - s + - d + - f + - g + - h + - j + - k + - l + - z + - x + - c + - v + - b + - n + - m + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 0 + - escape + - backspace + - capslock + - return + - enter + - tab + - space + - plus + - kp0 + - kp1 + - kp2 + - kp3 + - kp4 + - kp5 + - kp6 + - kp7 + - kp8 + - kp9 + - kpasterisk + - kpcomma + - kpdot + - kpenter + - kpequal + - kpjpcomma + - kpleftparen + - kpminus + - kpplusminus + - kprightparen + - minus + - - + - equal + - = + - grave + - ` + - print + - volumeup + - xf86audioraisevolume + - volumedown + - xf86audiolowervolume + - mute + - xf86audiomute + - brightnessup + - xf86monbrightnessup + - brightnessdown + - xf86audiomedia + - xf86audiomicmute + - micmute + - xf86audionext + - xf86audioplay + - xf86audioprev + - xf86audiostop + - xf86monbrightnessdown + - , + - comma + - . + - dot + - period + - / + - question + - slash + - backslash + - leftbrace + - [ + - bracketleft + - rightbrace + - ] + - bracketright + - ; + - scroll_lock + - semicolon + - ' + - apostrophe + - left + - right + - up + - down + - pause + - home + - delete + - insert + - end + - pause + - prior + - next + - pagedown + - pageup + - f1 + - f2 + - f3 + - f4 + - f5 + - f6 + - f7 + - f8 + - f9 + - f10 + - f11 + - f12 + - f13 + - f14 + - f15 + - f16 + - f17 + - f18 + - f19 + - f20 + - f21 + - f22 + - f23 + - f24 + +# AUTHORS + +Maintained by Shinyzenith , EdenQwQ , and Angelo Fallaria . +For more information about development, see . + +# SEE ALSO + +- *swhkd(1)* +- *swhkd(5)* +- *swhks(1)* diff --git a/swhkd.1.scd b/swhkd.1.scd new file mode 100644 index 0000000..a3e71e1 --- /dev/null +++ b/swhkd.1.scd @@ -0,0 +1,56 @@ +swhkd(1) "github.com/shinyzenith/swhkd" "General Commands Manual" + +# NAME + +swhkd - Hotkey daemon inspired by sxhkd written in rust + +# SYNOPSIS + +*pkexec swhkd* [_flags_] + +# CONFIG FILE + +The config file goes in */etc/swhkd/swhkdrc*. Since swhkd is written with a pkexec privilege escalation model in mind, we can't detect +*$XDG_CONFIG_HOME*. + +This can be avoided as such: + - Using the *include* statement in your config file + - Using the *-c* flag to mention a custom config file at runtime. + - Symlinking the config file from *~/.config/swhkd/swhkdrc* or any other directory of choice to */etc/swhkd/swhkdrc* + +More about the config file syntax in `swhkd(5)` + +# OPTIONS + +*-h*, *--help* + Print help message and quit. + +*-v*, *--version* + Print version information. + +*-c*, *--config* + Set a custom config file path. + +*-C*, *--cooldown* + Set a custom repeat cooldown duration. Default is 250ms. Most wayland + compositors handle this server side however, either way works. + +*-d*, *--debug* + Enable debug mode. + +# SIGNALS + + - Reload config file: `sudo pkill -HUP swhkd` + - Pause Hotkey checking: `sudo pkill -USR1 swhkd` + - Resume key checking: `sudo pkill -USR2 swhkd` + +# AUTHORS + +Maintained by Shinyzenith , EdenQwQ , and Angelo Fallaria . +For more information about development, see . + +# SEE ALSO + + - *swhkd(5)* + - *swhkd-keys(5)* + - *swhks(1)* diff --git a/swhkd.5.scd b/swhkd.5.scd new file mode 100644 index 0000000..0dc6202 --- /dev/null +++ b/swhkd.5.scd @@ -0,0 +1,85 @@ +swhkd(5) "github.com/waycrate/swhkd" "File Formats Manual" + +# NAME + +swhkd - Hotkey daemon inspired by sxhkd written in rust + +# CONFIG FILE + + - A global config can be defined in */etc/swhkd/swhkdrc*. Sniff attempts to look in your *$XDG_CONFIG_HOME*, failing which it defaults to *~/.config*. + - A local config overrides the global one. Local configs should be placed in the root of the project. + +# SYNTAX + +Each line of the configuration file is interpreted as so: + - If it is empty or starts with #, it is ignored. + - If it starts with a space, it is read as a command. + - Otherwise, it is read as a hotkey. + +For valid keys and modifiers, check *swhkd-keys(5)* + +# EXAMPLE + +``` +# Import another configuration file. +include /home/YourUserName/.config/swhkd/swhkdrc + +# terminal +super + ReTuRn # case insensitive + alacritty + +super + shift + enter # enter = return + kitty + +# file manager +super + shift + f + pcmanfm + +# web-browser +super + w + firefox + +# bspwm +super + {_,shift + }{h,j,k,l} + bspc node -{f,s} {west,south,north,east} + +super + ctrl + alt + {Left\ +,Down\ +,Up\ +,Right} + n=10; \ + { d1=left; d2=right; dx=-$n; dy=0; \ + , d1=bottom; d2=top; dx=0; dy=$n; \ + , d1=top; d2=bottom; dx=0; dy=-$n; \ + , d1=right; d2=left; dx=$n; dy=0; \ + } \ + bspc node --resize $d1 $dx $dy || bspc node --resize $d2 $dx $dy + +super + {\,, .} + bspc node -f {next.local,prev.local} + +# screenshot +print + scrot + +ctrl + print + scrot -s + +# Append with @ to run on key-release. +@super + shift + f + pcmanfm + +# Append with ~ to emit the hotkey after the command is triggered. Aka, don't swallow the hotkey. +~super + shift + f + pcmanfm +``` +# AUTHORS + +Maintained by Shinyzenith , EdenQwQ , and Angelo Fallaria . +For more information about development, see . + +# SEE ALSO + + - *swhkd(1)* + - *swhkd-keys(5)* + - *swhks(1)* diff --git a/swhks.1.scd b/swhks.1.scd new file mode 100644 index 0000000..13a7f7f --- /dev/null +++ b/swhks.1.scd @@ -0,0 +1,20 @@ +swhks(1) "github.com/shinyzenith/swhks" "General Commands Manual" + +# NAME + +swhks - Server for swhkd, used to run user level commands over IPC. + +# SYNOPSIS + +*swhks* [_flags_] + +# AUTHORS + +Maintained by Shinyzenith , EdenQwQ , and Angelo Fallaria . +For more information about development, see . + +# SEE ALSO + + - *swhkd(1)* + - *swhkd(5)* + - *swhkd-keys(5)*