From b6ff862705d21799f12ff57f578090c032ff8e3c Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Sun, 15 Aug 2021 14:26:13 -0700 Subject: [PATCH] feat(ahk): add config watching + reloading cmds Adds two new commands that enable the manual reloading of an AHK config file in the default location and the watching and automatic reloading of an AHK config file in the default location. --- Cargo.lock | 273 +++++++++++++++++++++++++++--- README.md | 23 ++- komorebi-core/src/lib.rs | 2 + komorebi.sample.ahk | 42 +++-- komorebi/Cargo.toml | 1 + komorebi/src/main.rs | 28 ++- komorebi/src/process_command.rs | 6 + komorebi/src/window_manager.rs | 55 ++++++ komorebi/src/windows_callbacks.rs | 4 +- komorebic/src/main.rs | 17 +- 10 files changed, 402 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77bd5fae..3820d61d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -34,7 +34,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -51,7 +51,7 @@ checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" dependencies = [ "addr2line", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "miniz_oxide", "object", @@ -77,6 +77,12 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -93,7 +99,7 @@ dependencies = [ "num-integer", "num-traits", "time", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -173,7 +179,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", ] @@ -183,7 +189,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-epoch", "crossbeam-utils", ] @@ -194,7 +200,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", "lazy_static", "memoffset", @@ -207,7 +213,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "lazy_static", ] @@ -218,7 +224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "377c9b002a72a0b2c1a18c62e2f3864bdfea4a015e3683a96e24aa45dd6c02d1" dependencies = [ "nix", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -238,7 +244,7 @@ checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" dependencies = [ "libc", "redox_users", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -257,19 +263,66 @@ dependencies = [ "once_cell", ] +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "winapi 0.3.9", +] + +[[package]] +name = "fsevent" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +dependencies = [ + "bitflags", + "fsevent-sys", +] + +[[package]] +name = "fsevent-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" +dependencies = [ + "libc", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + [[package]] name = "getrandom" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi", ] @@ -316,6 +369,16 @@ dependencies = [ "libc", ] +[[package]] +name = "hotwatch" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61ee702e77f237b41761361a82e5c4bf6277dbb4bc8b6b7d745cb249cc82b31" +dependencies = [ + "log", + "notify", +] + [[package]] name = "indenter" version = "0.3.3" @@ -332,12 +395,51 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inotify" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + [[package]] name = "itoa" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "komorebi" version = "0.1.0" @@ -351,6 +453,7 @@ dependencies = [ "dirs", "eyre", "getset", + "hotwatch", "komorebi-core", "lazy_static", "nanoid", @@ -399,6 +502,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.99" @@ -411,7 +520,7 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -448,6 +557,49 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio", + "slab", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + [[package]] name = "nanoid" version = "0.4.0" @@ -457,6 +609,17 @@ dependencies = [ "rand 0.8.4", ] +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + [[package]] name = "nix" version = "0.22.0" @@ -465,18 +628,36 @@ checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187" dependencies = [ "bitflags", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "memoffset", ] +[[package]] +name = "notify" +version = "4.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" +dependencies = [ + "bitflags", + "filetime", + "fsevent", + "fsevent-sys", + "inotify", + "libc", + "mio", + "mio-extras", + "walkdir", + "winapi 0.3.9", +] + [[package]] name = "ntapi" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -611,7 +792,7 @@ dependencies = [ "libc", "rand_core 0.3.1", "rdrand", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -752,7 +933,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -767,6 +948,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -813,6 +1003,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + [[package]] name = "smallvec" version = "1.6.1" @@ -863,13 +1059,13 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0af066e6272f2175c1783cfc2ebf3e2d8dfe2c182b00677fdeccbf8291af83fb" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "core-foundation-sys", "libc", "ntapi", "once_cell", "rayon", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -916,7 +1112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -925,7 +1121,7 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1022,7 +1218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "486992108df0fe0160680af1941fe856c521be931d5a5ecccefe0de86dc47e4a" dependencies = [ "tempdir", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1055,6 +1251,17 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi 0.3.9", + "winapi-util", +] + [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" @@ -1072,6 +1279,12 @@ dependencies = [ "libc", ] +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" @@ -1082,6 +1295,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -1094,7 +1313,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1129,3 +1348,13 @@ dependencies = [ "syn", "windows_gen", ] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] diff --git a/README.md b/README.md index 053f4ed2..349087cd 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ _komorebi_ is a tiling window manager that works as an extension to Microsoft's [Desktop Window Manager](https://docs.microsoft.com/en-us/windows/win32/dwm/dwm-overview) in Windows 10 and above. -_komorebi_ allows you to control application windows, virtual workspaces and display monitors with a CLI which can be used -with third-party software such as [AutoHotKey](https://github.com/Lexikos/AutoHotkey_L) to set user-defined keyboard -shortcuts. +_komorebi_ allows you to control application windows, virtual workspaces and display monitors with a CLI which can be +used with third-party software such as [AutoHotKey](https://github.com/Lexikos/AutoHotkey_L) to set user-defined +keyboard shortcuts. ## Description @@ -79,8 +79,8 @@ By running `komorebic start` at a Powershell prompt, you should see the followin Start-Process komorebi -WindowStyle hidden ``` -This means that `komorebi` is now running in the background, tiling all your windows, and listening for commands sent to it -by `komorebic`. +This means that `komorebi` is now running in the background, tiling all your windows, and listening for commands sent to +it by `komorebic`. You can similarly stop the process by running `komorebic stop`. @@ -118,7 +118,11 @@ sample [komorebi.ahk](komorebi.sample.ahk) AHK script that you can use as a star - [x] Toggle floating windows - [x] Toggle monocle window - [x] Toggle focus follows mouse +- [x] Toggle automatic tiling - [x] Pause all window management +- [x] Load configuration on startup +- [x] Manually reload configuration +- [x] Watch configuration for changes - [x] View window manager state ## Development @@ -135,6 +139,15 @@ code quality, consistency and commit hygiene: - Provide at least one short sentence or paragraph in your commit message body to describe your thought process for the changes being committed +If you use IntelliJ, you should enable the following settings to ensure that code generated by macros is recognised by +the IDE for completions and navigation: + +- Set `Expand declarative macros` + to `Use new engine` [here](jetbrains://idea/settings?name=Languages+%26+Frameworks--Rust) +- Enable the following experimental features: + - `org.rust.cargo.evaluate.build.scripts` + - `org.rust.macros.proc` + ## Logs and Debugging Logs from `komorebi` will be appended to `~/komorebi.log`; this file is never rotated or overwritten, so it will keep diff --git a/komorebi-core/src/lib.rs b/komorebi-core/src/lib.rs index fe642760..411e4e1c 100644 --- a/komorebi-core/src/lib.rs +++ b/komorebi-core/src/lib.rs @@ -52,6 +52,8 @@ pub enum SocketMessage { WorkspaceName(usize, usize, String), WorkspaceLayout(usize, usize, Layout), // Configuration + ReloadConfiguration, + WatchConfiguration(bool), FloatClass(String), FloatExe(String), FloatTitle(String), diff --git a/komorebi.sample.ahk b/komorebi.sample.ahk index 4801279e..a1393ed4 100644 --- a/komorebi.sample.ahk +++ b/komorebi.sample.ahk @@ -1,20 +1,24 @@ #SingleInstance Force +; Enable hot reloading of changes to this file +Run, komorebic.exe watch-configuration enable + ; Enable focus follows mouse Run, komorebic.exe focus-follows-mouse enable ; Ensure there are 3 workspaces created on monitor 0 -Run, komorebic.exe ensure-workspaces 0 4 +Run, komorebic.exe ensure-workspaces 0 5 ; Give the workspaces some optional names Run, komorebic.exe workspace-name 0 0 bsp Run, komorebic.exe workspace-name 0 1 columns Run, komorebic.exe workspace-name 0 2 thicc Run, komorebic.exe workspace-name 0 3 matrix +Run, komorebic.exe workspace-name 0 4 floaty ; Set the padding of the different workspaces -Run, komorebic.exe workspace-padding 0 1 50 -Run, komorebic.exe container-padding 0 1 50 +Run, komorebic.exe workspace-padding 0 1 30 +Run, komorebic.exe container-padding 0 1 30 Run, komorebic.exe workspace-padding 0 2 200 Run, komorebic.exe workspace-padding 0 3 0 Run, komorebic.exe container-padding 0 3 0 @@ -22,6 +26,9 @@ Run, komorebic.exe container-padding 0 3 0 ; Set the layouts of different workspaces Run, komorebic.exe workspace-layout 0 1 columns +; Set the floaty layout to not tile any windows +Run, komorebic.exe workspace-tiling 0 4 off + ; Always float IntelliJ popups, matching on class Run, komorebic.exe float-class SunAwtDialog, , Hide ; Always float Control Panel, matching on title @@ -30,6 +37,7 @@ Run, komorebic.exe float-title "Control Panel", , Hide Run, komorebic.exe float-class TaskManagerWindow, , Hide ; Always float Wally, matching on executable name Run, komorebic.exe float-exe Wally.exe, , Hide +Run, komorebic.exe float-exe wincompose.exe, , Hide ; Always float Calculator app, matching on window title Run, komorebic.exe float-title Calculator, , Hide Run, komorebic.exe float-exe 1Password.exe, , Hide @@ -68,20 +76,20 @@ return Run, komorebic.exe move right, Hide return -; Stack the focused window in a given direction, Alt + direction keys -!Left:: +; Stack the focused window in a given direction, Alt + Shift + direction keys +!+Left:: Run, komorebic.exe stack left, Hide return -!Down:: +!+Down:: Run, komorebic.exe stack down, Hide return -!Up:: +!+Up:: Run, komorebic.exe stack up, Hide return -!Right:: +!+Right:: Run, komorebic.exe stack right, Hide return @@ -93,8 +101,8 @@ return Run, komorebic.exe cycle-stack previous, , Hide return -; Unstack the focused window -!d:: +; Unstack the focused window, Alt + Shift + D +!+d:: Run, komorebic.exe unstack, Hide return @@ -138,6 +146,11 @@ return Run, komorebic.exe toggle-float, Hide return +; Reload ~/komorebi.ahk, Alt + O +!o:: +Run, komorebic.exe reload-configuration, Hide +return + ; Pause responding to any window events or komorebic commands, Alt + P !p:: Run, komorebic.exe toggle-pause, Hide @@ -164,6 +177,11 @@ Send ! Run, komorebic.exe focus-workspace 3, Hide return +!5:: +Send ! +Run, komorebic.exe focus-workspace 4, Hide +return + ; Move window to workspace !+1:: Run, komorebic.exe move-to-workspace 0, Hide @@ -180,3 +198,7 @@ return !+4:: Run, komorebic.exe move-to-workspace 3, Hide return + +!+5:: +Run, komorebic.exe move-to-workspace 4, Hide +return diff --git a/komorebi/Cargo.toml b/komorebi/Cargo.toml index 4b01e7a1..479ba6c0 100644 --- a/komorebi/Cargo.toml +++ b/komorebi/Cargo.toml @@ -17,6 +17,7 @@ ctrlc = "3" dirs = "3" eyre = "0.6" getset = "0.1" +hotwatch = "0.4" lazy_static = "1" nanoid = "0.4" paste = "1" diff --git a/komorebi/src/main.rs b/komorebi/src/main.rs index bd2e25a9..ab39eadf 100644 --- a/komorebi/src/main.rs +++ b/komorebi/src/main.rs @@ -54,6 +54,10 @@ lazy_static! { "ApplicationFrameHost.exe".to_string(), "steam.exe".to_string() ])); + static ref OBJECT_NAME_CHANGE_ON_LAUNCH: Arc>> = Arc::new(Mutex::new(vec![ + "firefox.exe".to_string(), + "idea64.exe".to_string(), + ])); } fn setup() -> Result { @@ -110,6 +114,20 @@ fn setup() -> Result { Ok(guard) } +pub fn load_configuration() -> Result<()> { + let home = dirs::home_dir().context("there is no home directory")?; + let mut config = home; + config.push("komorebi.ahk"); + + if config.exists() && which("autohotkey.exe").is_ok() { + Command::new("autohotkey.exe") + .arg(config.as_os_str()) + .output()?; + } + + Ok(()) +} + #[tracing::instrument] fn main() -> Result<()> { match std::env::args().count() { @@ -142,15 +160,7 @@ fn main() -> Result<()> { listen_for_commands(wm.clone()); listen_for_events(wm.clone()); - let home = dirs::home_dir().context("there is no home directory")?; - let mut config = home; - config.push("komorebi.ahk"); - - if config.exists() && which("autohotkey.exe").is_ok() { - Command::new("autohotkey.exe") - .arg(config.as_os_str()) - .output()?; - } + load_configuration()?; let (ctrlc_sender, ctrlc_receiver) = crossbeam_channel::bounded(1); ctrlc::set_handler(move || { diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 6a13c4fc..2a8d1944 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -170,6 +170,12 @@ impl WindowManager { WindowsApi::disable_focus_follows_mouse()?; } } + SocketMessage::ReloadConfiguration => { + Self::reload_configuration(); + } + SocketMessage::WatchConfiguration(enable) => { + self.watch_configuration(enable)?; + } } tracing::info!("processed"); diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 2225cafc..1c9f3414 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -3,10 +3,13 @@ use std::io::ErrorKind; use std::num::NonZeroUsize; use std::sync::Arc; use std::sync::Mutex; +use std::thread; use color_eyre::eyre::ContextCompat; use color_eyre::Result; use crossbeam_channel::Receiver; +use hotwatch::notify::DebouncedEvent; +use hotwatch::Hotwatch; use serde::Serialize; use uds_windows::UnixListener; @@ -18,6 +21,7 @@ use komorebi_core::Rect; use komorebi_core::Sizing; use crate::container::Container; +use crate::load_configuration; use crate::monitor::Monitor; use crate::ring::Ring; use crate::window::Window; @@ -33,6 +37,8 @@ pub struct WindowManager { #[serde(skip_serializing)] pub command_listener: UnixListener, pub is_paused: bool, + #[serde(skip_serializing)] + pub hotwatch: Hotwatch, } impl_ring_elements!(WindowManager, Monitor); @@ -62,6 +68,7 @@ pub fn new(incoming: Arc>>) -> Result Result<()> { + let home = dirs::home_dir().context("there is no home directory")?; + let mut config = home; + config.push("komorebi.ahk"); + + if config.exists() { + if enable { + tracing::info!("watching configuration for changes"); + // Always make absolutely sure that there isn't an already existing watch, because + // hotwatch allows multiple watches to be registered for the same path + match self.hotwatch.unwatch(config.clone()) { + Ok(_) => {} + Err(error) => match error { + hotwatch::Error::Notify(error) => match error { + hotwatch::notify::Error::WatchNotFound => {} + error => return Err(error.into()), + }, + error @ hotwatch::Error::Io(_) => return Err(error.into()), + }, + } + + self.hotwatch.watch(config, |event| match event { + // Editing in Notepad sends a NoticeWrite while editing in (Neo)Vim sends + // a NoticeRemove, presumably because of the use of swap files? + DebouncedEvent::NoticeWrite(_) | DebouncedEvent::NoticeRemove(_) => { + tracing::info!("reloading changed configuration file"); + thread::spawn(|| { + load_configuration().expect("could not load configuration"); + }); + } + _ => {} + })?; + } else { + tracing::info!("no longer watching configuration for changes"); + self.hotwatch.unwatch(config)?; + }; + } + + Ok(()) + } + #[tracing::instrument(skip(self))] pub fn update_focused_workspace(&mut self, mouse_follows_focus: bool) -> Result<()> { tracing::info!("updating"); diff --git a/komorebi/src/windows_callbacks.rs b/komorebi/src/windows_callbacks.rs index c1a7157c..293fb5cf 100644 --- a/komorebi/src/windows_callbacks.rs +++ b/komorebi/src/windows_callbacks.rs @@ -16,6 +16,7 @@ use crate::window_manager_event::WindowManagerEvent; use crate::windows_api::WindowsApi; use crate::winevent::WinEvent; use crate::winevent_listener::WINEVENT_CALLBACK_CHANNEL; +use crate::OBJECT_NAME_CHANGE_ON_LAUNCH; pub extern "system" fn enum_display_monitor( hmonitor: HMONITOR, @@ -79,8 +80,7 @@ pub extern "system" fn win_event_hook( // // [yatta\src\windows_event.rs:110] event = 32780 ObjectNameChange // [yatta\src\windows_event.rs:110] event = 32779 ObjectLocationChange - let object_name_change_on_launch = - vec!["firefox.exe".to_string(), "idea64.exe".to_string()]; + let object_name_change_on_launch = OBJECT_NAME_CHANGE_ON_LAUNCH.lock().unwrap(); if let Ok(exe) = window.exe() { if winevent == WinEvent::ObjectNameChange { diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 123fd5be..3c2b2a8f 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -54,6 +54,8 @@ enum SubCommand { TogglePause, ToggleMonocle, RestoreWindows, + ReloadConfiguration, + WatchConfiguration(BooleanState), State, Start, Stop, @@ -95,9 +97,12 @@ struct LayoutForMonitorWorkspace { fn on_or_off(s: &str) -> Result { match s { + "enable" => Ok(true), + "disable" => Ok(false), + // in order to not break backwards compat for mouse follows focus "on" => Ok(true), "off" => Ok(false), - _ => Err("expected `on` or `off`"), + _ => Err("expected `enable` or `disable`"), } } @@ -339,6 +344,16 @@ fn main() -> Result<()> { send_message(&*SocketMessage::FocusFollowsMouse(enable).as_bytes()?)?; } + SubCommand::ReloadConfiguration => { + send_message(&*SocketMessage::ReloadConfiguration.as_bytes()?)?; + } + SubCommand::WatchConfiguration(enable) => { + let enable = match enable { + BooleanState::Enable => true, + BooleanState::Disable => false, + }; + send_message(&*SocketMessage::WatchConfiguration(enable).as_bytes()?)?; + } } Ok(())