This commit adds a new option under layout_options.scrolling -
"center_focused_column", which defaults to false. When
set to true, and when the number of scrolling columns is an odd number
>=3, komorebi will, if there are enough windows being managed on the
workspace, and if the focused window is not too close to either the
beginning or the end of the workspace ring, keep the focused window in a
centered position in the layout
This commit standardizes the codebase to disallow usage of the raw eyre!
macro for creating errors, instead using ok_or_eyre() when constructing
ad-hoc errors from Result and Option types, and otherwise using the
bail! macro in response to failed boolean conditions.
Following discussing in #1475, and considering the default of the
komorebi widget in komorebi-bar, this commit updates the default
StackbarLabel from Process to Title.
resolve#1475
This commit ensures that unstack_all is called on a workspace before
attempting to proceed with stack_all to avoid stacking loops that can
occur when there are multiple pre-existing stacks already created on the
workspace.
This commit ensures that the WM_SETCURSOR message is handled by stackbar
windows by setting the cursor to the default IDC_ARROW, which prevents
the spinning "Loading" icon from showing on hover.
re #1456
This commit adds a new DefaultLayout::Scrolling variant, along with a
new LayoutOptions configuration which will initially be used to allow
the user to declaratively specify the number of visible columns for the
Scrolling layout, and a new komorebic "scrolling-layout-columns" command
to allow the user to modify this value for the focused workspace at
runtime.
The Scrolling layout is inspired by the Niri scrolling window manager,
presenting a workspace as an infinite scrollable horizontal strip with a
viewport which includes the focused window + N other windows in columns.
There is no support for splitting columns into multiple rows.
This layout can currently only be applied to single-monitor setups as
the scrolling would result in layout calculations which push the windows
in the columns moving out of the viewport onto adjacent monitors.
This implementation in the current state is enough to be useable for me
personally, but if others want to iterate on this, make it handle
hiding/restoring windows correctly when scrolling the viewport so that
adjacent monitors don't get impacted etc., patches are always welcome.
resolve#1434
This commit ensures that the user can't get into a weird state by
attempting to float a monocle container. If a user attempts to call
toggle-float on a monocle container, a warning will be logged and the
command will be ignored.
This commit adds a new StateQuery variant, FocusedContainerKind, which
will will return None if there is not focused container on the current
workspace (ie. it is empty), Single if the focused container contains a
single window, or Stack if the focused container contains more than one
window.
This commit adds a simple egui helper application which shows a list of
shortcuts defined in a user's whkdrc file. Parsing AHK files is not
supported.
In addition to listing out shortcuts defined in the whkdrc file, the top
line allows users to add filter a filter to narrow down the list of
commands and key bindings to the ones they are interested in.
A new komorebic command "toggle-shortcuts" has been introduced which
will first attempt to kill "komorebi-shortcuts.exe", and then exit if
the kill signal was successful (ie. a process was closed), or proceed to
open "komorebi-shortcuts.exe" if the kill signal was not successful (ie.
no process was closed, so we should open one).
"komorebi-shortcuts.exe" has been added as a floating application in
lib.rs to allow for users to use the "komorebic move" command to
manipulate its position via their existing keyboard bindings.
This commit ensures that if a user sends one of the various messages
which ultimately call move_container_to_monitor, if the target workspace
on the target monitor currently has a monocle container, it will be
toggled off to allow space for the container being moved to be rendered.
This commit ensures that if a user sends one of the various messages
which ultimately call move_container_to_workspace, if the target
workspace currently has a monocle container, it will be toggled off to
allow space for the container being moved to be rendered.
This startup Win32 API call can sporadically fail, so this commit adds
some retry logic and logging of errors every time it fails. If it
crosses the retry threshold, the application will exit (because you
can't really have a tiling window manager running that doesn't let you
set the foreground window).
This commit ensures that workspace windows that are hidden when the user
is using HidingBehaviour::Hide will not be unintentionally reaped by a
hard-coded workaround for Microsoft Office's continuing
enshittification.
HidingBehaviour::Hide has also been marked in the docs as an EOL
feature, and some dead code that was ultimately migrated to reaper.rs
has been cleaned up.
fix#1426
This commit adds a new VirtualDesktopNotification which is used to
notify subscribers when the user leaves and enters the virtual desktop
associated with komorebi.
komorebi-bar consumes these notifications to minmize and restore the bar
appropriately depending on the currently focused virtual desktop.
re #1420
This commit improves path handling for commands and icons in the new
Application widget by making use of PathExt::replace_env when loading
the user-specified ApplicationsConfig.
Crucially for scoop users, this means that user-agnostic references to
scoop apps can now be made like this:
```
$Env:USERPROFILE/scoop/apps/zed-nightly/current/zed.exe
```
When attempting to look up an icon for a command, we now split the
command on ".exe", and if this is a complete path to a file, we try to
use it to extract an icon, otherwise we try to resolve a complete path
using "which" before doing the same.
This commit ensures that all borders will destroyed if komorebi detects
that the user has switched to a Windows Virtual Desktop different from
the one it was launched on and associated with.
There is still some work to be done to forcibly redraw the borders when
a navigation back to the VD associated with komorebi is detected, but
that requires tracking the state of the current VD ID outside of the
process_event handler somewhere.
re #1420
This commit adds a dedicated WindowHandlingBehaviour enum with Sync and
Async variants, and reverts a change to the render fn in window.rs to
use move_window instead of position_window if the
WindowHandlingBehaviour variant is Sync.
This commit adds an option to set the floating layer behaviour for all
workspaces on a monitor.
Overrides set on an individual workspace level will take precedence over
the option set at the monitor level.
This commit removes RetileWithResizeDimensions messages from the batches
that are sent to komorebi when changing workspace.
I'm not really sure why this was added in the first place, but removing
it doesn't seem to impact layouts on workspace switch, and more
important, by removing this message I'm no longer able to reproduce the
sudden exits of komorebi.exe under sustained workspace switching calls
made via the bar.
This commit addresses a deadlock on WINDOW_BORDERS which can occur under
load, particularly when switching workspaces.
When switching workspaces using the komorebi-bar,
RetileWithResizeDimensions is also called, which calls
border_manager::destroy_all_borders.
At the same time, border_manager::window_border is called when hiding
borders from the previous workspace. Both of these functions try to take
locks on WINDOWS_BORDERS and BORDER_STATE.
border_manager::window_border is called in a new thread by hide_border,
so if this has not finished with the lock by the time
destroy_all_borders requests it, we get stuck in a deadlock.
The changes in this commit ensure that the BORDER_STATE lock is dropped
as early as possible in destroy_all_borders, and that we are not holding
the WINDOWS_BORDERS lock in window_border while trying to get the
BORDER_STATE lock to look up BorderInfo.
The logs which show the initial deadlock being detected:
2025-04-08T22:49:37.641888Z WARN komorebi::process_command: could not acquire window manager lock, not processing message: FocusWorkspaceNumber
2025-04-08T22:49:38.294952Z WARN komorebi::process_command: could not acquire window manager lock, not processing message: FocusWorkspaceNumber
2025-04-08T22:49:39.225645Z ERROR komorebi: 1 deadlocks detected
2025-04-08T22:49:39.225826Z ERROR komorebi: deadlock #0
2025-04-08T22:49:39.225950Z ERROR komorebi: thread id: 9896
2025-04-08T22:49:39.226072Z ERROR komorebi: 0: 0x7ff68fd33dec - backtrace::backtrace::dbghelp64::trace
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\backtrace\dbghelp64.rs:99
backtrace::backtrace::trace_unsynchronized<backtrace::capture::impl$1::create::closure_env$0>
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\backtrace\mod.rs:66
1: 0x7ff68fd33c87 - backtrace::backtrace::trace<backtrace::capture::impl$1::create::closure_env$0>
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\backtrace\mod.rs:53
2: 0x7ff68fd3c03e - backtrace::capture::Backtrace::create
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\capture.rs:193
3: 0x7ff68fd3bfae - backtrace::capture::Backtrace::new
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\capture.rs:158
4: 0x7ff68f937b54 - parking_lot_core::parking_lot::deadlock_impl::on_unpark
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:1211
5: 0x7ff68f921f0e - parking_lot_core::parking_lot::deadlock::on_unpark
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:1144
6: 0x7ff68f92bf88 - parking_lot_core::parking_lot::park::closure$0<parking_lot::raw_mutex::impl$3::lock_slow::closure_env$0,parking_lot::raw_mutex::impl$3::lock_slow::closure_env$1,parking_lot::raw_mutex::impl$3::lock_slow::closure_env$2>
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:637
7: 0x7ff68f92a777 - parking_lot_core::parking_lot::with_thread_data
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:207
parking_lot_core::parking_lot::park<parking_lot::raw_mutex::impl$3::lock_slow::closure_env$0,parking_lot::raw_mutex::impl$3::lock_slow::closure_env$1,parking_lot::raw_mutex::impl$3::lock_slow::closure_env$2>
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:600
8: 0x7ff68f926fa0 - parking_lot::raw_mutex::RawMutex::lock_slow
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot-0.12.3\src\raw_mutex.rs:262
9: 0x7ff68f1daac6 - parking_lot::raw_mutex::impl$0::lock
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot-0.12.3\src\raw_mutex.rs:72
10: 0x7ff68ef05eb3 - lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex,std::collections::hash::map::HashMap<isize,alloc::string::String,std::hash::random::RandomState> >::lock<parking_lot::raw_mutex::RawMutex,std::collections::hash::map::HashMap<isize,alloc::string::Str
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\lock_api-0.4.12\src\mutex.rs:223
11: 0x7ff68ef0713d - komorebi::border_manager::destroy_all_borders
at komorebi\src\border_manager\mod.rs:139
12: 0x7ff68f194e61 - komorebi::window_manager::WindowManager::process_command<ref_mut$<uds_windows::stdnet::net::UnixStream> >
at komorebi\src\process_command.rs:918
13: 0x7ff68ef1fdcf - komorebi::process_command::read_commands_uds
at komorebi\src\process_command.rs:2292
14: 0x7ff68f231eb5 - komorebi::process_command::listen_for_commands::closure$0::closure$0::closure$0
at komorebi\src\process_command.rs:123
15: 0x7ff68f32bcf3 - core::hint::black_box
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\hint.rs:477
std::sys::backtrace::__rust_begin_short_backtrace<komorebi::process_command::listen_for_commands::closure$0::closure$0::closure_env$0,tuple$<> >
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\sys\backtrace.rs:152
16: 0x7ff68f00d1b4 - std::thread::impl$0::spawn_unchecked_::closure$1::closure$0<komorebi::process_command::listen_for_commands::closure$0::closure$0::closure_env$0,tuple$<> >
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:559
17: 0x7ff68f356ea1 - core::panic::unwind_safe::impl$25::call_once<tuple$<>,std::thread::impl$0::spawn_unchecked_::closure$1::closure_env$0<komorebi::process_command::listen_for_commands::closure$0::closure$0::closure_env$0,tuple$<> > >
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\panic\unwind_safe.rs:272
18: 0x7ff68f1d1e00 - std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<std::thread::impl$0::spawn_unchecked_::closure$1::closure_env$0<komorebi::process_command::listen_for_commands::closure$0::closure$0::closure_env$0,tuple$<> > >,tuple$<> >
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:587
19: 0x7ff68f0102b3 - std::thread::impl$7::drop::closure$0<enum2$<core::result::Result<tuple$<>,eyre::Report> > >
20: 0x7ff68f007be7 - std::panicking::try
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:550
std::panic::catch_unwind
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:358
std::thread::impl$0::spawn_unchecked_::closure$1<komorebi::process_command::listen_for_commands::closure$0::closure$0::closure_env$0,tuple$<> >
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:557
21: 0x7ff68ecfeb8e - core::ops::function::FnOnce::call_once<std::thread::impl$0::spawn_unchecked_::closure_env$1<komorebi::process_command::listen_for_commands::closure$0::closure$0::closure_env$0,tuple$<> >,tuple$<> >
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
22: 0x7ff68fe84f1d - alloc::boxed::impl$28::call_once
at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\alloc\src\boxed.rs:1976
alloc::boxed::impl$28::call_once
at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\alloc\src\boxed.rs:1976
std::sys::pal::windows::thread::impl$0::new::thread_start
at /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library\std\src\sys\pal\windows\thread.rs:56
23: 0x7ff8ef27257d - BaseThreadInitThunk
24: 0x7ff8f042af28 - RtlUserThreadStart
2025-04-08T22:49:39.228617Z ERROR komorebi: thread id: 62364
2025-04-08T22:49:39.228731Z ERROR komorebi: 0: 0x7ff68fd33dec - backtrace::backtrace::dbghelp64::trace
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\backtrace\dbghelp64.rs:99
backtrace::backtrace::trace_unsynchronized<backtrace::capture::impl$1::create::closure_env$0>
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\backtrace\mod.rs:66
1: 0x7ff68fd33c87 - backtrace::backtrace::trace<backtrace::capture::impl$1::create::closure_env$0>
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\backtrace\mod.rs:53
2: 0x7ff68fd3c03e - backtrace::capture::Backtrace::create
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\capture.rs:193
3: 0x7ff68fd3bfae - backtrace::capture::Backtrace::new
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\backtrace-0.3.71\src\capture.rs:158
4: 0x7ff68f937b54 - parking_lot_core::parking_lot::deadlock_impl::on_unpark
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:1211
5: 0x7ff68f921f0e - parking_lot_core::parking_lot::deadlock::on_unpark
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:1144
6: 0x7ff68f92bf88 - parking_lot_core::parking_lot::park::closure$0<parking_lot::raw_mutex::impl$3::lock_slow::closure_env$0,parking_lot::raw_mutex::impl$3::lock_slow::closure_env$1,parking_lot::raw_mutex::impl$3::lock_slow::closure_env$2>
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:637
7: 0x7ff68f92a777 - parking_lot_core::parking_lot::with_thread_data
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:207
parking_lot_core::parking_lot::park<parking_lot::raw_mutex::impl$3::lock_slow::closure_env$0,parking_lot::raw_mutex::impl$3::lock_slow::closure_env$1,parking_lot::raw_mutex::impl$3::lock_slow::closure_env$2>
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot_core-0.9.10\src\parking_lot.rs:600
8: 0x7ff68f926fa0 - parking_lot::raw_mutex::RawMutex::lock_slow
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot-0.12.3\src\raw_mutex.rs:262
9: 0x7ff68f1daac6 - parking_lot::raw_mutex::impl$0::lock
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\parking_lot-0.12.3\src\raw_mutex.rs:72
10: 0x7ff68ef05d93 - lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex,std::collections::hash::map::HashMap<alloc::string::String,alloc::boxed::Box<komorebi::border_manager::border::Border,alloc::alloc::Global>,std::hash::random::RandomState> >::lock<parking_lot::raw_mu
at C:\Users\LGUG2Z\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\lock_api-0.4.12\src\mutex.rs:223
11: 0x7ff68f2064de - komorebi::border_manager::window_border::closure$0
at komorebi\src\border_manager\mod.rs:109
12: 0x7ff68eddeca9 - enum2$<core::option::Option<ref$<alloc::string::String> > >::and_then<ref$<alloc::string::String>,komorebi::border_manager::BorderInfo,komorebi::border_manager::window_border::closure_env$0>
at C:\Users\LGUG2Z\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\option.rs:1452
13: 0x7ff68ef06339 - komorebi::border_manager::window_border
at komorebi\src\border_manager\mod.rs:108
We shouldn't ever have empty containers, but never say never because
someone on the Discord has an empty container with no Windows that
continues to take up a tile. This commit adds a call to drop all
containers without any windows whenever Workspace::update is called.
This commit introduces three new commands, session-float-rule,
session-float-rules, and clear-session-float-rules, which add a
composite float rule for the currently focused window for the duration
of the komorebi session, print the float rules scoped to the current
komorebi session, and clear any float rules scoped to the current
komorebi session respectively.
The composite rule created is fairly strict, using
MatchingStrategy::Equals on the Exe, Class and Title.
Users can run session-float-rule as they are working to avoid having to
break their workflow and edit their configuration file, and when they
are ready, they can run session-float-rules to print out the composite
rules which have been generated and added to the current session to
further refine before adding them to their configuration files.
re #1402
This commit adds a new Wallpaper configuration option to the
WorkspaceConfig, allowing the user to specify a path to a wallpaper
image file, and to specify whether to generate a base16 palette from the
colours of that image file.
Theme generation is enabled by default when a wallpaper is selected.
A set of theme options can be given to customize the colours of various
borders and accents.
The themes generated are also plumbed through to the komorebi-bar.
The palette generation algorithm from "flavours" (which has been forked
and updated) is quite slow, so the outputs are cached to file in
DATA_DIR, and keyed by ThemeVariant (Light or Dark).
The Win32 COM API to set the desktop wallpaper is also quite slow,
however this calls is async so it doesn't block komorebi's main thread.
This commit adds a new StateQuery::Version, which allows integrators to
make decisions about how to handle different versions of komorebi's
state schema based on the version of komorebi that is running on a
user's machine.
This commit adds a --log-level flag to komorebi.exe which allows the
user to set the logging verbosity without setting the RUST_LOG
environment variable directly. If the RUST_LOG environment variable is
set, it will take precedence over the --log-level flag.
This commit adds a new option to the WorkspaceConfig object,
floating_layer_behaviour, which allows the user to either set
FloatingLayerBehaviour::Tile or FloatingLayerBehaviour::Float. Although
I prefer Float as a default, there was a good enough argument to make
Tile the default based on the fact that the Floating layer is
automatically engaged based on the focused window, and previously when
the focused window was a floating window, new windows would be tiled
unless they matched floating rules.
This commit imports an older revision of my fork of windows-icons to
call when attempting to look up the icon of an application by it's
process id. This needs to be cleaned up before the next release.
This commit adds two new komorebic commands, move-to-last-workspace and
send-to-last-workspace, which move or send the focused window to the
last focused workspace on the focused monitor.
This commit integrates the excellent investigation and work done by
@davor-skontra on the windows-icons repo to enable the retrieval of UWP
applications, including all those annoying Microsoft applications which
all share the ApplicationFrameHost.exe executable and the
ApplicationFrameWindow class.
Since these applications share the same executable, the icon cache in
komorei-bar has been updated to use the window hwnd as a key intead of
the window executable.
resolve#1226
This commit adds some dependency injection to the monitor reconciliator
module to make it easier to test the behaviour when different kinds of
data are returned from win32_display_data.
This commit adds the concept of locked container indexes to komorebi
workspaces.
When a container index is locked, it can only be displaced by manual
user actual - usually when another container is moved there, and when
this happens, that container becomes the locked container.
In the locked state, the container at the locked index should never be
displaced by new windows opening or existing windows around it being
closed.
When the total number of containers on a workspace falls below the
number of the locked index, the locked index will be removed.
A locked index can be identified by a special border color linked to the
new WindowKind::UnfocusedLocked variant.
The implementation of locked container indexes is backed by a new data
structure called a LockedDeque, which is a VecDeque with an auxiliary
HashSet which keeps track of locked indices.
A new komorebic command "toggle-lock" has been added to support
programmatic use of this feature, as well as the
LockMonitorWorkspaceContainer and UnlockMonitorWorkspaceContainer
SocketMessage variants which can be used by status bars.
This commit fixes a rare issue, seen exclusively with Acer monitors so
far, where two monitors of the same model can have an identical serial
number id.
If we encounter a system which has two connected monitors with the same
serial id number, the serial id number will be forcefully unset and
blacklisted for the rest of the session.
In this case, users must fall back to using device_id for options like
display_index_preferences.
Possibly a little overkill, but since this has been such a headache I'm
going to opt for this approach over #1368 for now.
This commit ensures that the WM_SETCURSOR message is handled by border
windows by setting the cursor to the default IDC_ARROW, which prevents
the spinning "Loading" icon from showing on hover.
Some credit is due to the user steiner5 on Discord for whining about me
not being interested in working on this while more generally complaining
about komorebi, which consequently made me want to work on this out of
spite since he's probably going to bounce off the software anyway.
It's very annoying and unclear when enabling the float override to open
the next window as floating to have that window appear immediately over
an existing tile.
This commit sets an explicit behaviour to center windows spawned while
the float override is active.
This commit addresses a border rendering issue when moving a window from
a higher-indexed monitor to a lower-indexed monitor.
Previously, we would do a single render pass across all monitors in
order of their indexes, destroying borders no longer needed, and
creating new borders for new windows.
This resulted in the window being moved to the lower-indexed monitor
still existing in the global border cache when that monitor's borders
were updated, but then being removed when the borders of the origin,
higher-indexed monitor were updated.
With the changes in this commit, if we encounter a situation like this,
an additional render pass will be executed to ensure that the window
will have a corresponding border created on the destination
lower-indexed monitor.
This commit ensures that a workspace float override will also be applied
when the user switches to the floating layer, and removed when the user
switches to the tiling layer. This results in a workflow which makes it
easier to spawn floating windows on the fly.
This commit ensures that if a user switches from a workspace with
managed windows to a workspace without any managed windows but only
floating windows, the focused window from the previous workspace will
lose focus as it should, and the first floating window on the new
workspace will gain focus as it should.
This commit allows either the single canonical applications.json file,
or multiple files which adhere to the asc scheme to be given to the
app_specific_configuration_path config option.
I thought I had already implemented this earlier, but evidently I
hadn't.
This will be useful for people who want to maintain their own
independent set of asc rules, as they can be kept in a dedicated file
which won't be overwritten by the fetch-asc command.
resolve#736
This commit adds a variation of the cycle-workspace command which will
attempt to focus the next empty workspace in the given direction (with
the usual wraparound). If there are no empty workspaces available, this
command will do nothing.
This commit makes all schemars::JsonSchema derives optional. After
analyzing the output of cargo build timings and llvm-lines, it was clear
that the majority of the 2m+ incremental dev build times was taken up by
codegen, and the majority of it by schemars.
Developers can now run cargo commands with --no-default-features to
disable schemars::JsonSchema codegen, and all justfile commands have
been updated to take this flag by default, with the exception of the
jsonschema target, which will compile with all derives required to
export the various jsonschema files.
Incremental dev build times for komorebi.exe on my machine are now at
around ~18s, while clean dev build times for the entire workspace are at
around ~1m.