mirror of
https://github.com/YaLTeR/niri.git
synced 2024-10-26 11:48:09 +03:00
Add configuration file
This commit is contained in:
parent
bdc86032e4
commit
5225bc9e55
268
Cargo.lock
generated
268
Cargo.lock
generated
@ -2,12 +2,32 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.5"
|
||||
@ -244,6 +264,36 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace-ext"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
@ -377,6 +427,15 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chumsky"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23170228b96236b5a7299057ac284a321457700bc8c41a4476052f0f4ba5349d"
|
||||
dependencies = [
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.2"
|
||||
@ -844,6 +903,12 @@ dependencies = [
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
|
||||
|
||||
[[package]]
|
||||
name = "gl_generator"
|
||||
version = "0.14.0"
|
||||
@ -860,6 +925,9 @@ name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
@ -872,6 +940,9 @@ name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
@ -964,6 +1035,23 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"rustix 0.38.11",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_ci"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
@ -1009,6 +1097,33 @@ version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
||||
|
||||
[[package]]
|
||||
name = "knuffel"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04bee6ddc6071011314b1ce4f7705fef6c009401dba4fd22cb0009db6a177413"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"chumsky",
|
||||
"knuffel-derive",
|
||||
"miette",
|
||||
"thiserror",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "knuffel-derive"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91977f56c49cfb961e3d840e2e7c6e4a56bde7283898cf606861f1421348283d"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@ -1159,6 +1274,38 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miette"
|
||||
version = "5.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"backtrace-ext",
|
||||
"is-terminal",
|
||||
"miette-derive",
|
||||
"once_cell",
|
||||
"owo-colors",
|
||||
"supports-color",
|
||||
"supports-hyperlinks",
|
||||
"supports-unicode",
|
||||
"terminal_size",
|
||||
"textwrap",
|
||||
"thiserror",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miette-derive"
|
||||
version = "5.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
@ -1226,9 +1373,12 @@ dependencies = [
|
||||
"directories",
|
||||
"image",
|
||||
"keyframe",
|
||||
"knuffel",
|
||||
"logind-zbus",
|
||||
"miette",
|
||||
"profiling",
|
||||
"sd-notify",
|
||||
"serde",
|
||||
"smithay",
|
||||
"smithay-drm-extras",
|
||||
"time",
|
||||
@ -1405,6 +1555,15 @@ dependencies = [
|
||||
"objc-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
@ -1442,6 +1601,12 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.1.0"
|
||||
@ -1517,6 +1682,30 @@ dependencies = [
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.66"
|
||||
@ -1673,6 +1862,12 @@ version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.23"
|
||||
@ -1824,6 +2019,12 @@ version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
||||
|
||||
[[package]]
|
||||
name = "smawk"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"
|
||||
|
||||
[[package]]
|
||||
name = "smithay"
|
||||
version = "0.3.0"
|
||||
@ -1917,6 +2118,34 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "supports-color"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4950e7174bffabe99455511c39707310e7e9b440364a2fcb1cc21521be57b354"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
"is_ci",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "supports-hyperlinks"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "supports-unicode"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b6c2cb240ab5dd21ed4906895ee23fe5a48acdbd15a3ce388e7b62a9b66baf7"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
@ -1952,6 +2181,27 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "terminal_size"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d"
|
||||
dependencies = [
|
||||
"smawk",
|
||||
"unicode-linebreak",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.48"
|
||||
@ -2144,6 +2394,24 @@ version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-linebreak"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
|
@ -13,9 +13,12 @@ clap = { version = "4.3.21", features = ["derive"] }
|
||||
directories = "5.0.1"
|
||||
image = { version = "0.24.7", default-features = false, features = ["png"] }
|
||||
keyframe = { version = "1.1.1", default-features = false }
|
||||
knuffel = "3.2.0"
|
||||
logind-zbus = "3.1.2"
|
||||
miette = { version = "5.10.0", features = ["fancy"] }
|
||||
profiling = "1.0.9"
|
||||
sd-notify = "0.4.1"
|
||||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
time = { version = "0.3.28", features = ["formatting", "local-offset", "macros"] }
|
||||
tracing = { version = "0.1.37", features = ["max_level_trace", "release_max_level_debug"] }
|
||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||
|
14
README.md
14
README.md
@ -50,7 +50,7 @@ You can also autostart systemd services like [mako] by symlinking them into `$HO
|
||||
|
||||
Niri also somewhat-works with xdg-desktop-portal-gnome for Flatpak apps.
|
||||
|
||||
## Hotkeys
|
||||
## Default Hotkeys
|
||||
|
||||
When running on a TTY, the Mod key is <kbd>Super</kbd>.
|
||||
When running in a window, the Mod key is <kbd>Alt</kbd>.
|
||||
@ -60,11 +60,9 @@ The general system is: if a hotkey switches somewhere, then adding <kbd>Ctrl</kb
|
||||
| Hotkey | Description |
|
||||
| ------ | ----------- |
|
||||
| <kbd>Mod</kbd><kbd>T</kbd> | Spawn `alacritty` |
|
||||
| <kbd>Mod</kbd><kbd>D</kbd> | Spawn `fuzzel` |
|
||||
| <kbd>Mod</kbd><kbd>N</kbd> | Spawn `nautilus` |
|
||||
| <kbd>Mod</kbd><kbd>Q</kbd> | Close the focused window |
|
||||
| <kbd>Mod</kbd><kbd>H</kbd> or <kbd>Mod</kbd><kbd>←</kbd> | Focus the window to the left |
|
||||
| <kbd>Mod</kbd><kbd>L</kbd> or <kbd>Mod</kbd><kbd>→</kbd> | Focus the window to the right |
|
||||
| <kbd>Mod</kbd><kbd>H</kbd> or <kbd>Mod</kbd><kbd>←</kbd> | Focus the column to the left |
|
||||
| <kbd>Mod</kbd><kbd>L</kbd> or <kbd>Mod</kbd><kbd>→</kbd> | Focus the column to the right |
|
||||
| <kbd>Mod</kbd><kbd>J</kbd> or <kbd>Mod</kbd><kbd>↓</kbd> | Focus the window below in a column |
|
||||
| <kbd>Mod</kbd><kbd>K</kbd> or <kbd>Mod</kbd><kbd>↑</kbd> | Focus the window above in a column |
|
||||
| <kbd>Mod</kbd><kbd>Ctrl</kbd><kbd>H</kbd> or <kbd>Mod</kbd><kbd>Ctrl</kbd><kbd>←</kbd> | Move the focused column to the left |
|
||||
@ -86,6 +84,12 @@ The general system is: if a hotkey switches somewhere, then adding <kbd>Ctrl</kb
|
||||
| <kbd>Mod</kbd><kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>T</kbd> | Toggle debug tinting of rendered elements |
|
||||
| <kbd>Mod</kbd><kbd>Shift</kbd><kbd>E</kbd> | Exit niri |
|
||||
|
||||
## Configuration
|
||||
|
||||
Niri will load configuration from `$XDG_CONFIG_HOME/.config/niri/config.kdl` or `~/.config/niri/config.kdl`.
|
||||
If this fails, it will load [the default configuration file](resources/default-config.kdl).
|
||||
Please use the default configuration file as the starting point for your custom configuration.
|
||||
|
||||
[PaperWM]: https://github.com/paperwm/PaperWM
|
||||
[mako]: https://github.com/emersion/mako
|
||||
|
||||
|
88
resources/default-config.kdl
Normal file
88
resources/default-config.kdl
Normal file
@ -0,0 +1,88 @@
|
||||
// This config is in the KDL format: https://kdl.dev
|
||||
// "/-" comments out the following node.
|
||||
|
||||
input {
|
||||
keyboard {
|
||||
xkb {
|
||||
// You can set rules, model, layout, variant and options.
|
||||
// For more information, see xkeyboard-config(7).
|
||||
|
||||
// For example:
|
||||
/-layout "us,ru"
|
||||
/-options "grp:win_space_toggle,compose:ralt,ctrl:nocaps"
|
||||
}
|
||||
}
|
||||
|
||||
// Next sections contain libinput settings.
|
||||
// Omitting settings disables them, or leaves them at their default values.
|
||||
touchpad {
|
||||
tap
|
||||
natural-scroll
|
||||
/-accel-speed 0.2
|
||||
}
|
||||
}
|
||||
|
||||
binds {
|
||||
// Keys consist of modifiers separated by + signs, followed by an XKB key name
|
||||
// in the end. To find an XKB name for a particular key, you may use a program
|
||||
// like wev.
|
||||
//
|
||||
// "Mod" is a special modifier equal to Super when running on a TTY, and to Alt
|
||||
// when running as a winit window.
|
||||
|
||||
Mod+T { spawn "alacritty"; }
|
||||
Mod+Q { close-window; }
|
||||
|
||||
Mod+H { focus-column-left; }
|
||||
Mod+J { focus-window-down; }
|
||||
Mod+K { focus-window-up; }
|
||||
Mod+L { focus-column-right; }
|
||||
Mod+Left { focus-column-left; }
|
||||
Mod+Down { focus-window-down; }
|
||||
Mod+Up { focus-window-up; }
|
||||
Mod+Right { focus-column-right; }
|
||||
|
||||
Mod+Ctrl+H { move-column-left; }
|
||||
Mod+Ctrl+J { move-window-down; }
|
||||
Mod+Ctrl+K { move-window-up; }
|
||||
Mod+Ctrl+L { move-column-right; }
|
||||
Mod+Ctrl+Left { move-column-left; }
|
||||
Mod+Ctrl+Down { move-window-down; }
|
||||
Mod+Ctrl+Up { move-window-up; }
|
||||
Mod+Ctrl+Right { move-column-right; }
|
||||
|
||||
Mod+Shift+H { focus-monitor-left; }
|
||||
Mod+Shift+J { focus-monitor-down; }
|
||||
Mod+Shift+K { focus-monitor-up; }
|
||||
Mod+Shift+L { focus-monitor-right; }
|
||||
Mod+Shift+Left { focus-monitor-left; }
|
||||
Mod+Shift+Down { focus-monitor-down; }
|
||||
Mod+Shift+Up { focus-monitor-up; }
|
||||
Mod+Shift+Right { focus-monitor-right; }
|
||||
|
||||
Mod+Shift+Ctrl+H { move-window-to-monitor-left; }
|
||||
Mod+Shift+Ctrl+J { move-window-to-monitor-down; }
|
||||
Mod+Shift+Ctrl+K { move-window-to-monitor-up; }
|
||||
Mod+Shift+Ctrl+L { move-window-to-monitor-right; }
|
||||
Mod+Shift+Ctrl+Left { move-window-to-monitor-left; }
|
||||
Mod+Shift+Ctrl+Down { move-window-to-monitor-down; }
|
||||
Mod+Shift+Ctrl+Up { move-window-to-monitor-up; }
|
||||
Mod+Shift+Ctrl+Right { move-window-to-monitor-right; }
|
||||
|
||||
Mod+U { focus-workspace-down; }
|
||||
Mod+I { focus-workspace-up; }
|
||||
Mod+Ctrl+U { move-window-to-workspace-down; }
|
||||
Mod+Ctrl+I { move-window-to-workspace-up; }
|
||||
|
||||
Mod+Comma { consume-window-into-column; }
|
||||
Mod+Period { expel-window-from-column; }
|
||||
|
||||
Mod+R { switch-preset-column-width; }
|
||||
Mod+F { maximize-column; }
|
||||
Mod+Shift+F { fullscreen-window; }
|
||||
|
||||
Print { screenshot; }
|
||||
Mod+Shift+E { quit; }
|
||||
|
||||
Mod+Shift+Ctrl+T { toggle-debug-tint; }
|
||||
}
|
297
src/config.rs
Normal file
297
src/config.rs
Normal file
@ -0,0 +1,297 @@
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use bitflags::bitflags;
|
||||
use directories::ProjectDirs;
|
||||
use miette::{miette, Context, IntoDiagnostic};
|
||||
use smithay::input::keyboard::xkb::{keysym_from_name, KEY_NoSymbol, KEYSYM_CASE_INSENSITIVE};
|
||||
use smithay::input::keyboard::Keysym;
|
||||
|
||||
#[derive(knuffel::Decode, Debug, PartialEq)]
|
||||
pub struct Config {
|
||||
#[knuffel(child, default)]
|
||||
pub input: Input,
|
||||
#[knuffel(child, default)]
|
||||
pub binds: Binds,
|
||||
}
|
||||
|
||||
// FIXME: Add other devices.
|
||||
#[derive(knuffel::Decode, Debug, Default, PartialEq)]
|
||||
pub struct Input {
|
||||
#[knuffel(child, default)]
|
||||
pub keyboard: Keyboard,
|
||||
#[knuffel(child, default)]
|
||||
pub touchpad: Touchpad,
|
||||
}
|
||||
|
||||
#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)]
|
||||
pub struct Keyboard {
|
||||
#[knuffel(child, default)]
|
||||
pub xkb: Xkb,
|
||||
}
|
||||
|
||||
#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)]
|
||||
pub struct Xkb {
|
||||
#[knuffel(child, unwrap(argument), default)]
|
||||
pub rules: String,
|
||||
#[knuffel(child, unwrap(argument), default)]
|
||||
pub model: String,
|
||||
#[knuffel(child, unwrap(argument))]
|
||||
pub layout: Option<String>,
|
||||
#[knuffel(child, unwrap(argument), default)]
|
||||
pub variant: String,
|
||||
#[knuffel(child, unwrap(argument))]
|
||||
pub options: Option<String>,
|
||||
}
|
||||
|
||||
// FIXME: Add the rest of the settings.
|
||||
#[derive(knuffel::Decode, Debug, Default, PartialEq)]
|
||||
pub struct Touchpad {
|
||||
#[knuffel(child)]
|
||||
pub tap: bool,
|
||||
#[knuffel(child)]
|
||||
pub natural_scroll: bool,
|
||||
#[knuffel(child, unwrap(argument), default)]
|
||||
pub accel_speed: f64,
|
||||
}
|
||||
|
||||
#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)]
|
||||
pub struct Binds(#[knuffel(children)] pub Vec<Bind>);
|
||||
|
||||
#[derive(knuffel::Decode, Debug, PartialEq, Eq)]
|
||||
pub struct Bind {
|
||||
#[knuffel(node_name)]
|
||||
pub key: Key,
|
||||
#[knuffel(children)]
|
||||
pub actions: Vec<Action>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Key {
|
||||
pub keysym: Keysym,
|
||||
pub modifiers: Modifiers,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Modifiers : u8 {
|
||||
const CTRL = 1;
|
||||
const SHIFT = 2;
|
||||
const ALT = 4;
|
||||
const SUPER = 8;
|
||||
const COMPOSITOR = 16;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Action {
|
||||
#[knuffel(skip)]
|
||||
None,
|
||||
Quit,
|
||||
#[knuffel(skip)]
|
||||
ChangeVt(i32),
|
||||
Suspend,
|
||||
ToggleDebugTint,
|
||||
Spawn(#[knuffel(arguments)] Vec<String>),
|
||||
Screenshot,
|
||||
CloseWindow,
|
||||
FullscreenWindow,
|
||||
FocusColumnLeft,
|
||||
FocusColumnRight,
|
||||
FocusWindowDown,
|
||||
FocusWindowUp,
|
||||
MoveColumnLeft,
|
||||
MoveColumnRight,
|
||||
MoveWindowDown,
|
||||
MoveWindowUp,
|
||||
ConsumeWindowIntoColumn,
|
||||
ExpelWindowFromColumn,
|
||||
FocusWorkspaceDown,
|
||||
FocusWorkspaceUp,
|
||||
MoveWindowToWorkspaceDown,
|
||||
MoveWindowToWorkspaceUp,
|
||||
FocusMonitorLeft,
|
||||
FocusMonitorRight,
|
||||
FocusMonitorDown,
|
||||
FocusMonitorUp,
|
||||
MoveWindowToMonitorLeft,
|
||||
MoveWindowToMonitorRight,
|
||||
MoveWindowToMonitorDown,
|
||||
MoveWindowToMonitorUp,
|
||||
SwitchPresetColumnWidth,
|
||||
MaximizeColumn,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn load(path: Option<PathBuf>) -> miette::Result<Self> {
|
||||
let path = if let Some(path) = path {
|
||||
path
|
||||
} else {
|
||||
let mut path = ProjectDirs::from("", "", "niri")
|
||||
.ok_or_else(|| miette!("error retrieving home directory"))?
|
||||
.config_dir()
|
||||
.to_owned();
|
||||
path.push("config.kdl");
|
||||
path
|
||||
};
|
||||
|
||||
let contents = std::fs::read_to_string(&path)
|
||||
.into_diagnostic()
|
||||
.with_context(|| format!("error reading {path:?}"))?;
|
||||
|
||||
let config = Self::parse("config.kdl", &contents).context("error parsing")?;
|
||||
debug!("loaded config from {path:?}");
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
pub fn parse(filename: &str, text: &str) -> Result<Self, knuffel::Error> {
|
||||
knuffel::parse(filename, text)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Config::parse(
|
||||
"default-config.kdl",
|
||||
include_str!("../resources/default-config.kdl"),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Key {
|
||||
type Err = miette::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut modifiers = Modifiers::empty();
|
||||
|
||||
let mut split = s.split('+');
|
||||
let key = split.next_back().unwrap();
|
||||
|
||||
for part in split {
|
||||
let part = part.trim();
|
||||
if part.eq_ignore_ascii_case("mod") {
|
||||
modifiers |= Modifiers::COMPOSITOR
|
||||
} else if part.eq_ignore_ascii_case("ctrl") || part.eq_ignore_ascii_case("control") {
|
||||
modifiers |= Modifiers::CTRL;
|
||||
} else if part.eq_ignore_ascii_case("shift") {
|
||||
modifiers |= Modifiers::SHIFT;
|
||||
} else if part.eq_ignore_ascii_case("alt") {
|
||||
modifiers |= Modifiers::ALT;
|
||||
} else if part.eq_ignore_ascii_case("super") || part.eq_ignore_ascii_case("win") {
|
||||
modifiers |= Modifiers::SUPER;
|
||||
} else {
|
||||
return Err(miette!("invalid modifier: {part}"));
|
||||
}
|
||||
}
|
||||
|
||||
let keysym = keysym_from_name(key, KEYSYM_CASE_INSENSITIVE);
|
||||
if keysym == KEY_NoSymbol {
|
||||
return Err(miette!("invalid key: {key}"));
|
||||
}
|
||||
|
||||
Ok(Key { keysym, modifiers })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use smithay::input::keyboard::xkb::keysyms::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[track_caller]
|
||||
fn check(text: &str, expected: Config) {
|
||||
let parsed = Config::parse("test.kdl", text)
|
||||
.map_err(miette::Report::new)
|
||||
.unwrap();
|
||||
assert_eq!(parsed, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse() {
|
||||
check(
|
||||
r#"
|
||||
input {
|
||||
keyboard {
|
||||
xkb {
|
||||
layout "us,ru"
|
||||
options "grp:win_space_toggle"
|
||||
}
|
||||
}
|
||||
|
||||
touchpad {
|
||||
tap
|
||||
accel-speed 0.2
|
||||
}
|
||||
}
|
||||
|
||||
binds {
|
||||
Mod+T { spawn "alacritty"; }
|
||||
Mod+Q { close-window; }
|
||||
Mod+Shift+H { focus-monitor-left; }
|
||||
Mod+Ctrl+Shift+L { move-window-to-monitor-right; }
|
||||
Mod+Comma { consume-window-into-column; }
|
||||
}
|
||||
"#,
|
||||
Config {
|
||||
input: Input {
|
||||
keyboard: Keyboard {
|
||||
xkb: Xkb {
|
||||
layout: Some("us,ru".to_owned()),
|
||||
options: Some("grp:win_space_toggle".to_owned()),
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
touchpad: Touchpad {
|
||||
tap: true,
|
||||
natural_scroll: false,
|
||||
accel_speed: 0.2,
|
||||
},
|
||||
},
|
||||
binds: Binds(vec![
|
||||
Bind {
|
||||
key: Key {
|
||||
keysym: KEY_t,
|
||||
modifiers: Modifiers::COMPOSITOR,
|
||||
},
|
||||
actions: vec![Action::Spawn(vec!["alacritty".to_owned()])],
|
||||
},
|
||||
Bind {
|
||||
key: Key {
|
||||
keysym: KEY_q,
|
||||
modifiers: Modifiers::COMPOSITOR,
|
||||
},
|
||||
actions: vec![Action::CloseWindow],
|
||||
},
|
||||
Bind {
|
||||
key: Key {
|
||||
keysym: KEY_h,
|
||||
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
|
||||
},
|
||||
actions: vec![Action::FocusMonitorLeft],
|
||||
},
|
||||
Bind {
|
||||
key: Key {
|
||||
keysym: KEY_l,
|
||||
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT | Modifiers::CTRL,
|
||||
},
|
||||
actions: vec![Action::MoveWindowToMonitorRight],
|
||||
},
|
||||
Bind {
|
||||
key: Key {
|
||||
keysym: KEY_comma,
|
||||
modifiers: Modifiers::COMPOSITOR,
|
||||
},
|
||||
actions: vec![Action::ConsumeWindowIntoColumn],
|
||||
},
|
||||
]),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_create_default_config() {
|
||||
let _ = Config::default();
|
||||
}
|
||||
}
|
190
src/input.rs
190
src/input.rs
@ -17,45 +17,10 @@ use smithay::input::pointer::{
|
||||
use smithay::utils::SERIAL_COUNTER;
|
||||
use smithay::wayland::tablet_manager::{TabletDescriptor, TabletSeatTrait};
|
||||
|
||||
use crate::config::{Action, Config, Modifiers};
|
||||
use crate::niri::State;
|
||||
use crate::utils::get_monotonic_time;
|
||||
|
||||
enum Action {
|
||||
None,
|
||||
Quit,
|
||||
ChangeVt(i32),
|
||||
Suspend,
|
||||
ToggleDebugTint,
|
||||
Spawn(String),
|
||||
Screenshot,
|
||||
CloseWindow,
|
||||
ToggleFullscreen,
|
||||
FocusLeft,
|
||||
FocusRight,
|
||||
FocusDown,
|
||||
FocusUp,
|
||||
MoveLeft,
|
||||
MoveRight,
|
||||
MoveDown,
|
||||
MoveUp,
|
||||
ConsumeIntoColumn,
|
||||
ExpelFromColumn,
|
||||
SwitchWorkspaceDown,
|
||||
SwitchWorkspaceUp,
|
||||
MoveToWorkspaceDown,
|
||||
MoveToWorkspaceUp,
|
||||
FocusMonitorLeft,
|
||||
FocusMonitorRight,
|
||||
FocusMonitorDown,
|
||||
FocusMonitorUp,
|
||||
MoveToMonitorLeft,
|
||||
MoveToMonitorRight,
|
||||
MoveToMonitorDown,
|
||||
MoveToMonitorUp,
|
||||
ToggleWidth,
|
||||
ToggleFullWidth,
|
||||
}
|
||||
|
||||
pub enum CompositorMod {
|
||||
Super,
|
||||
Alt,
|
||||
@ -70,13 +35,17 @@ impl From<Action> for FilterResult<Action> {
|
||||
}
|
||||
}
|
||||
|
||||
fn action(comp_mod: CompositorMod, keysym: KeysymHandle, mods: ModifiersState) -> Action {
|
||||
fn action(
|
||||
config: &Config,
|
||||
comp_mod: CompositorMod,
|
||||
keysym: KeysymHandle,
|
||||
mods: ModifiersState,
|
||||
) -> Action {
|
||||
use keysyms::*;
|
||||
|
||||
let modified = keysym.modified_sym();
|
||||
|
||||
// Handle hardcoded binds.
|
||||
#[allow(non_upper_case_globals)] // wat
|
||||
match modified {
|
||||
match keysym.modified_sym() {
|
||||
modified @ KEY_XF86Switch_VT_1..=KEY_XF86Switch_VT_12 => {
|
||||
let vt = (modified - KEY_XF86Switch_VT_1 + 1) as i32;
|
||||
return Action::ChangeVt(vt);
|
||||
@ -85,59 +54,45 @@ fn action(comp_mod: CompositorMod, keysym: KeysymHandle, mods: ModifiersState) -
|
||||
_ => (),
|
||||
}
|
||||
|
||||
let mod_down = match comp_mod {
|
||||
CompositorMod::Super => mods.logo,
|
||||
CompositorMod::Alt => mods.alt,
|
||||
// Handle configured binds.
|
||||
let mut modifiers = Modifiers::empty();
|
||||
if mods.ctrl {
|
||||
modifiers |= Modifiers::CTRL;
|
||||
}
|
||||
if mods.shift {
|
||||
modifiers |= Modifiers::SHIFT;
|
||||
}
|
||||
if mods.alt {
|
||||
modifiers |= Modifiers::ALT;
|
||||
}
|
||||
if mods.logo {
|
||||
modifiers |= Modifiers::SUPER;
|
||||
}
|
||||
|
||||
let (mod_down, mut comp_mod) = match comp_mod {
|
||||
CompositorMod::Super => (mods.logo, Modifiers::SUPER),
|
||||
CompositorMod::Alt => (mods.alt, Modifiers::ALT),
|
||||
};
|
||||
if mod_down {
|
||||
modifiers |= Modifiers::COMPOSITOR;
|
||||
} else {
|
||||
comp_mod = Modifiers::empty();
|
||||
}
|
||||
|
||||
if !mod_down {
|
||||
let Some(&raw) = keysym.raw_syms().first() else {
|
||||
return Action::None;
|
||||
};
|
||||
for bind in &config.binds.0 {
|
||||
if bind.key.keysym != raw {
|
||||
continue;
|
||||
}
|
||||
|
||||
if bind.key.modifiers | comp_mod == modifiers {
|
||||
return bind.actions.first().cloned().unwrap_or(Action::None);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: these don't work in the Russian layout. I guess I'll need to
|
||||
// find a US keymap, then map keys somehow.
|
||||
#[allow(non_upper_case_globals)] // wat
|
||||
match modified {
|
||||
KEY_E => Action::Quit,
|
||||
KEY_t => Action::Spawn("alacritty".to_owned()),
|
||||
KEY_d => Action::Spawn("fuzzel".to_owned()),
|
||||
KEY_n => Action::Spawn("nautilus".to_owned()),
|
||||
// Alt + PrtSc = SysRq
|
||||
KEY_Sys_Req | KEY_Print => Action::Screenshot,
|
||||
KEY_T if mods.shift && mods.ctrl => Action::ToggleDebugTint,
|
||||
KEY_q => Action::CloseWindow,
|
||||
KEY_F => Action::ToggleFullscreen,
|
||||
KEY_comma => Action::ConsumeIntoColumn,
|
||||
KEY_period => Action::ExpelFromColumn,
|
||||
KEY_r => Action::ToggleWidth,
|
||||
KEY_f => Action::ToggleFullWidth,
|
||||
// Move to monitor.
|
||||
KEY_H | KEY_Left if mods.shift && mods.ctrl => Action::MoveToMonitorLeft,
|
||||
KEY_L | KEY_Right if mods.shift && mods.ctrl => Action::MoveToMonitorRight,
|
||||
KEY_J | KEY_Down if mods.shift && mods.ctrl => Action::MoveToMonitorDown,
|
||||
KEY_K | KEY_Up if mods.shift && mods.ctrl => Action::MoveToMonitorUp,
|
||||
// Focus monitor.
|
||||
KEY_H | KEY_Left if mods.shift => Action::FocusMonitorLeft,
|
||||
KEY_L | KEY_Right if mods.shift => Action::FocusMonitorRight,
|
||||
KEY_J | KEY_Down if mods.shift => Action::FocusMonitorDown,
|
||||
KEY_K | KEY_Up if mods.shift => Action::FocusMonitorUp,
|
||||
// Move.
|
||||
KEY_h | KEY_Left if mods.ctrl => Action::MoveLeft,
|
||||
KEY_l | KEY_Right if mods.ctrl => Action::MoveRight,
|
||||
KEY_j | KEY_Down if mods.ctrl => Action::MoveDown,
|
||||
KEY_k | KEY_Up if mods.ctrl => Action::MoveUp,
|
||||
// Focus.
|
||||
KEY_h | KEY_Left => Action::FocusLeft,
|
||||
KEY_l | KEY_Right => Action::FocusRight,
|
||||
KEY_j | KEY_Down => Action::FocusDown,
|
||||
KEY_k | KEY_Up => Action::FocusUp,
|
||||
// Workspaces.
|
||||
KEY_u if mods.ctrl => Action::MoveToWorkspaceDown,
|
||||
KEY_i if mods.ctrl => Action::MoveToWorkspaceUp,
|
||||
KEY_u => Action::SwitchWorkspaceDown,
|
||||
KEY_i => Action::SwitchWorkspaceUp,
|
||||
_ => Action::None,
|
||||
}
|
||||
Action::None
|
||||
}
|
||||
|
||||
impl State {
|
||||
@ -166,9 +121,9 @@ impl State {
|
||||
event.state(),
|
||||
serial,
|
||||
time,
|
||||
|_, mods, keysym| {
|
||||
|self_, mods, keysym| {
|
||||
if event.state() == KeyState::Pressed {
|
||||
action(comp_mod, keysym, *mods).into()
|
||||
action(&self_.config, comp_mod, keysym, *mods).into()
|
||||
} else {
|
||||
FilterResult::Forward
|
||||
}
|
||||
@ -192,8 +147,10 @@ impl State {
|
||||
self.backend.toggle_debug_tint();
|
||||
}
|
||||
Action::Spawn(command) => {
|
||||
if let Err(err) = Command::new(command).spawn() {
|
||||
warn!("error spawning alacritty: {err}");
|
||||
if let Some((command, args)) = command.split_first() {
|
||||
if let Err(err) = Command::new(command).args(args).spawn() {
|
||||
warn!("error spawning {command}: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Action::Screenshot => {
|
||||
@ -211,78 +168,78 @@ impl State {
|
||||
window.toplevel().send_close();
|
||||
}
|
||||
}
|
||||
Action::ToggleFullscreen => {
|
||||
Action::FullscreenWindow => {
|
||||
let focus = self.niri.monitor_set.focus().cloned();
|
||||
if let Some(window) = focus {
|
||||
self.niri.monitor_set.toggle_fullscreen(&window);
|
||||
}
|
||||
}
|
||||
Action::MoveLeft => {
|
||||
Action::MoveColumnLeft => {
|
||||
self.niri.monitor_set.move_left();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::MoveRight => {
|
||||
Action::MoveColumnRight => {
|
||||
self.niri.monitor_set.move_right();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::MoveDown => {
|
||||
Action::MoveWindowDown => {
|
||||
self.niri.monitor_set.move_down();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::MoveUp => {
|
||||
Action::MoveWindowUp => {
|
||||
self.niri.monitor_set.move_up();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::FocusLeft => {
|
||||
Action::FocusColumnLeft => {
|
||||
self.niri.monitor_set.focus_left();
|
||||
}
|
||||
Action::FocusRight => {
|
||||
Action::FocusColumnRight => {
|
||||
self.niri.monitor_set.focus_right();
|
||||
}
|
||||
Action::FocusDown => {
|
||||
Action::FocusWindowDown => {
|
||||
self.niri.monitor_set.focus_down();
|
||||
}
|
||||
Action::FocusUp => {
|
||||
Action::FocusWindowUp => {
|
||||
self.niri.monitor_set.focus_up();
|
||||
}
|
||||
Action::MoveToWorkspaceDown => {
|
||||
Action::MoveWindowToWorkspaceDown => {
|
||||
self.niri.monitor_set.move_to_workspace_down();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::MoveToWorkspaceUp => {
|
||||
Action::MoveWindowToWorkspaceUp => {
|
||||
self.niri.monitor_set.move_to_workspace_up();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::SwitchWorkspaceDown => {
|
||||
Action::FocusWorkspaceDown => {
|
||||
self.niri.monitor_set.switch_workspace_down();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::SwitchWorkspaceUp => {
|
||||
Action::FocusWorkspaceUp => {
|
||||
self.niri.monitor_set.switch_workspace_up();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::ConsumeIntoColumn => {
|
||||
Action::ConsumeWindowIntoColumn => {
|
||||
self.niri.monitor_set.consume_into_column();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::ExpelFromColumn => {
|
||||
Action::ExpelWindowFromColumn => {
|
||||
self.niri.monitor_set.expel_from_column();
|
||||
// FIXME: granular
|
||||
self.niri.queue_redraw_all();
|
||||
}
|
||||
Action::ToggleWidth => {
|
||||
Action::SwitchPresetColumnWidth => {
|
||||
self.niri.monitor_set.toggle_width();
|
||||
}
|
||||
Action::ToggleFullWidth => {
|
||||
Action::MaximizeColumn => {
|
||||
self.niri.monitor_set.toggle_full_width();
|
||||
}
|
||||
Action::FocusMonitorLeft => {
|
||||
@ -309,25 +266,25 @@ impl State {
|
||||
self.move_cursor_to_output(&output);
|
||||
}
|
||||
}
|
||||
Action::MoveToMonitorLeft => {
|
||||
Action::MoveWindowToMonitorLeft => {
|
||||
if let Some(output) = self.niri.output_left() {
|
||||
self.niri.monitor_set.move_to_output(&output);
|
||||
self.move_cursor_to_output(&output);
|
||||
}
|
||||
}
|
||||
Action::MoveToMonitorRight => {
|
||||
Action::MoveWindowToMonitorRight => {
|
||||
if let Some(output) = self.niri.output_right() {
|
||||
self.niri.monitor_set.move_to_output(&output);
|
||||
self.move_cursor_to_output(&output);
|
||||
}
|
||||
}
|
||||
Action::MoveToMonitorDown => {
|
||||
Action::MoveWindowToMonitorDown => {
|
||||
if let Some(output) = self.niri.output_down() {
|
||||
self.niri.monitor_set.move_to_output(&output);
|
||||
self.move_cursor_to_output(&output);
|
||||
}
|
||||
}
|
||||
Action::MoveToMonitorUp => {
|
||||
Action::MoveWindowToMonitorUp => {
|
||||
if let Some(output) = self.niri.output_up() {
|
||||
self.niri.monitor_set.move_to_output(&output);
|
||||
self.move_cursor_to_output(&output);
|
||||
@ -740,9 +697,10 @@ impl State {
|
||||
// According to Mutter code, this setting is specific to touchpads.
|
||||
let is_touchpad = device.config_tap_finger_count() > 0;
|
||||
if is_touchpad {
|
||||
let _ = device.config_tap_set_enabled(true);
|
||||
let _ = device.config_scroll_set_natural_scroll_enabled(true);
|
||||
let _ = device.config_accel_set_speed(0.2);
|
||||
let c = &self.config.input.touchpad;
|
||||
let _ = device.config_tap_set_enabled(c.tap);
|
||||
let _ = device.config_scroll_set_natural_scroll_enabled(c.natural_scroll);
|
||||
let _ = device.config_accel_set_speed(c.accel_speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
22
src/main.rs
22
src/main.rs
@ -3,6 +3,7 @@ extern crate tracing;
|
||||
|
||||
mod animation;
|
||||
mod backend;
|
||||
mod config;
|
||||
mod dbus;
|
||||
mod frame_clock;
|
||||
mod handlers;
|
||||
@ -13,8 +14,11 @@ mod utils;
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
use config::Config;
|
||||
use miette::Context;
|
||||
use niri::{Niri, State};
|
||||
use smithay::reexports::calloop::EventLoop;
|
||||
use smithay::reexports::wayland_server::Display;
|
||||
@ -23,6 +27,9 @@ use tracing_subscriber::EnvFilter;
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Cli {
|
||||
/// Path to config file (default: `$XDG_CONFIG_HOME/niri/config.kdl`).
|
||||
#[arg(short, long)]
|
||||
config: Option<PathBuf>,
|
||||
/// Command to run upon compositor startup.
|
||||
#[arg(last = true)]
|
||||
command: Vec<OsString>,
|
||||
@ -47,9 +54,22 @@ fn main() {
|
||||
|
||||
let _client = tracy_client::Client::start();
|
||||
|
||||
let config = match Config::load(cli.config).context("error loading config") {
|
||||
Ok(config) => config,
|
||||
Err(err) => {
|
||||
warn!("{err:?}");
|
||||
Config::default()
|
||||
}
|
||||
};
|
||||
|
||||
let mut event_loop = EventLoop::try_new().unwrap();
|
||||
let mut display = Display::new().unwrap();
|
||||
let state = State::new(event_loop.handle(), event_loop.get_signal(), &mut display);
|
||||
let state = State::new(
|
||||
config,
|
||||
event_loop.handle(),
|
||||
event_loop.get_signal(),
|
||||
&mut display,
|
||||
);
|
||||
let mut data = LoopData { display, state };
|
||||
|
||||
if let Some((command, args)) = cli.command.split_first() {
|
||||
|
27
src/niri.rs
27
src/niri.rs
@ -56,6 +56,7 @@ use smithay::wayland::tablet_manager::TabletManagerState;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use crate::backend::{Backend, Tty, Winit};
|
||||
use crate::config::Config;
|
||||
use crate::dbus::mutter_service_channel::ServiceChannel;
|
||||
use crate::frame_clock::FrameClock;
|
||||
use crate::layout::{MonitorRenderElement, MonitorSet};
|
||||
@ -115,12 +116,14 @@ pub struct OutputState {
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
pub config: Config,
|
||||
pub backend: Backend,
|
||||
pub niri: Niri,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new(
|
||||
config: Config,
|
||||
event_loop: LoopHandle<'static, LoopData>,
|
||||
stop_signal: LoopSignal,
|
||||
display: &mut Display<State>,
|
||||
@ -134,10 +137,20 @@ impl State {
|
||||
Backend::Tty(Tty::new(event_loop.clone()))
|
||||
};
|
||||
|
||||
let mut niri = Niri::new(event_loop, stop_signal, display, backend.seat_name());
|
||||
let mut niri = Niri::new(
|
||||
&config,
|
||||
event_loop,
|
||||
stop_signal,
|
||||
display,
|
||||
backend.seat_name(),
|
||||
);
|
||||
backend.init(&mut niri);
|
||||
|
||||
Self { backend, niri }
|
||||
Self {
|
||||
config,
|
||||
backend,
|
||||
niri,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_cursor(&mut self, location: Point<f64, Logical>) {
|
||||
@ -178,6 +191,7 @@ impl State {
|
||||
|
||||
impl Niri {
|
||||
pub fn new(
|
||||
config: &Config,
|
||||
event_loop: LoopHandle<'static, LoopData>,
|
||||
stop_signal: LoopSignal,
|
||||
display: &mut Display<State>,
|
||||
@ -202,11 +216,12 @@ impl Niri {
|
||||
PresentationState::new::<State>(&display_handle, CLOCK_MONOTONIC as u32);
|
||||
|
||||
let mut seat: Seat<State> = seat_state.new_wl_seat(&display_handle, seat_name);
|
||||
// FIXME: get Xkb and repeat interval from GNOME dconf.
|
||||
let xkb = XkbConfig {
|
||||
layout: "us,ru",
|
||||
options: Some("grp:win_space_toggle,compose:ralt,ctrl:nocaps".to_owned()),
|
||||
..Default::default()
|
||||
rules: &config.input.keyboard.xkb.rules,
|
||||
model: &config.input.keyboard.xkb.model,
|
||||
layout: &config.input.keyboard.xkb.layout.as_deref().unwrap_or("us"),
|
||||
variant: &config.input.keyboard.xkb.variant,
|
||||
options: config.input.keyboard.xkb.options.clone(),
|
||||
};
|
||||
seat.add_keyboard(xkb, 400, 30).unwrap();
|
||||
seat.add_pointer();
|
||||
|
Loading…
Reference in New Issue
Block a user