This commit introduces an implementation of workspace layers to
komorebi.
Workspace layers change the kinds of windows that certain commands
operate on. This implementation features two variants,
WorkspaceLayer::Tiling and WorkspaceLayer::Floating.
The default behaviour until now has been WorkspaceLayer::Tiling.
When the user sets WorkspaceLayer::Floating, either through the
'toggle-workspace-layer' command or the new bar widget, the 'move',
'focus', 'cycle-focus' and 'resize-axis' commands will operate on
floating windows, if the currently focused window is a floating window.
As I don't have 'cycle-focus' bound to anything, 'focus up' and 'focus
down' double as incrementing and decrementing cycle focus commands,
iterating focus through the floating windows assigned to a workspace.
Floating windows in komorebi belong to specific workspaces, therefore
commands such as 'move' and 'resize-axis' will restrict movement and
resizing to the bounds of their workspace's work area (or more
accurately, the work area of the monitor that the workspace belongs to,
as floating windows are never constrained by workspace-specific work
area restrictions).
This commit adds a new komorebic command, focus-monitor-at-cursor, which
can optionally be chained with the focus-workspace command in
keybindings to reproduce the previous default behaviour of auto-focusing
whichever monitor the cursor was on before attempting to change the
focused workspace.
This commit removes the code on the workspace `update` on `layout-rules`
where it was setting the `layout-flip` to `None` if the layout was
different from `BSP`. This appears to be some old code when the
layout-flip would only apply to the `BSP` layout. However now it appears
to apply to all layouts so this code shouldn't exist. This commit also
changes the docs from the `FlipLayout` command to remove the statement
that only applied to `BSP` since it is no longer true.
This commit updates various docs with information on the long-promised
individual commercial use license which will be available to purchase
from 01 Jan 2025 onwards.
This commit adds a new komorebic command "eager-focus", which takes a
full case-sensitive exe identifier as an argument. When komorebi
receives this message, it will look through each monitor and workspace
for the first matching managed window and then focus it.
This allows users who have well defined workspaces and rules to bind
semantic hotkeys to commands like "komorebic eager-focus Discord.exe" to
immediately jump to applications instead of mentally looking up their
assigned workspaces or positions within container stacks.
This commit adds the following new socket messages and commands:
- `EnforceWorkspaceRules`: resets the `already_moved_window_handles` and
calls `enforce_workspace_rules` so that all workspace rules, including
initial workspace rules are applied again
- `enforce-workspace-rules`: cli command which sends the
EnforceWorkspaceRules socket message
This commit creates a new `SocketMessage` called `StopIgnoreRestore`
which makes komorebi stop without calling `window.restore()` on all
windows. This way every maximized window will stay maximized once you
start komorebi again and it is able to use the previous `State`.
If it fails to restore the previous state you might have to call
`komorebic restore-windows` in case you had hidden windows, for example
when when using the `window_hiding_behaviour` as `Hide`, or you can
simply unminimize them if you were using `Cloak` or `Minimize`.
This commit adds changes to the main wm process to dump a state file to
temp_dir() when the process is exited either via komorebic stop or
ctrl-c, and to automatically try to reload that dumped state file if it
exists on the next run.
A new flag "--clean-state" has been added to both komorebi.exe and the
komorebic start command to override this behaviour.
The dumped state file can only be applied if the number of connected
monitors matches the number of monitors recorded in the state, and if
every HWND listed in the state file still exists.
This is validated by calling Window.exe(), which under the hood checks
for the continued existence of the process associated with the HWND.
Only the "workspace" subsection of the state for each matching
connecting monitor will be applied.
This commit corrects a typo which adds the "--masir" flag to the
autostart shortcut when the user has passed the "--bar" flag to the
enable-autostart command.
fix#1178
This commit adds a new komorebic command, "kill", to kill background
processes that may be started by "komorebic start", without terminating
the main komorebi process.
This is useful when iterating on changes to external components like the
bar which may require restarts.
This is a small change to the start command which moves the check for
the komorebi processes to come a little bit earlier.
This small change will make running commands like "komorebic start
--bar" around 3s faster when komorebi is already running.
This commit is comprised of the following interactively rebased commits
from PR #1002 by @thearturca.
1a184a4442
refactor(animation): move animations to its own mod
First step for more rusty version animations. The goal is to make
animations more generic so its easier to add new animations to komorebi!
d3ac6b72c2
refactor(animation): reduce mutex calls on `ANIMATION_STYLE`
8a42b738fe
refactor(animation): introduce `Lerp` trait
e449861c10
refactor(animation): generalized ANIMATION_MANAGER
Instead of a isize key for the ANIMATION_MANAGER HashMap, now we use a
String key. For window move animation, the key would be
`window_move:{hwnd}`.
This allows us to use single manager for more types of animations.
67b2a7a284
feat(animation): introduce `AnimationPrefix` enum
8290f143a6
feat(animation): introduce `RenderDispatcher` trait
2400d757fe
feat(animation): implement window transparency animation
This commit also fixes graceful shutdown of animations by disabling them
before exit and wait for all remaining animations for 20 seconds.
44189d8382
refactor(animation): move generation of `animation key` to `RenderDispatcher`
e502cb3ffb
refactor(animation): rename `animation` mod to `engine`
Linter was upset about this:
> error: module has the same name as its containing module
369107f5e0
feat(config): adds per animation configuration options
Originally static config only allowed global config for animations.
Since this refactor introduces the abilty to add more type of
animations, this change allows us to configure `enabled`, `duration` and
`style` state per animation type.
Now each of them take either the raw value or a JSON object where keys
are the animation types and values are desired config value. Also adds
support for per animation configuration for komorebic commands.
This commit adds a new komorebi command "cycle-stack-index" which allows
the user to manipulate the index position of the focused window in the
focused stack by swapping it with either the previous or the next window
until the desired index position has been found.
This commit introduces a new komorebic command, close-workspace. This
command will remove the focused workspace from the window manager state
if the following conditions are met:
1. The number of workspaces on the focused monitor are >1
2. The workspace is empty
3. The workspace is unnamed
The third condition is to ensure that we are not removing workspaces
which have been declared in the static configuration file.
This commit switches all relevant commands to treat the v2
applications.json asc format as the default format in all commands.
The v1 applications.yaml file will still be processed correctly if
passed.
This commit adds support for a v2 format of the application specific
configuration file, centralizing on JSON to maximize the knowledge
crossover for people already familiar with the types used in
komorebi.json.
The biggest difference besides the format change is that matchers must
be used explicitly for every kind of rule, rather than being able to
specify options on a default rule. This is a bit more verbose, but
ultimately allows for significantly more flexibility.
This commit introduces a new option `float_override`, which makes it so
every every window opened, shown or uncloaked will be set to floating,
but it won't be ignored. It will be added to the floating_windows of the
workspace, meaning that the user can later tile that window with
toggle-float command.
This allows the users to have all windows open as floating and then
manually tile the ones they want.
This interactively rebased commit contains changes from the following
individual commits:
0e8dc85fb1
feat(wm): add new float override option
30bdaf33d5
feat(cli): add command for new option `ToggleFloatOverride`
b7bedce1ca
feat(wm): add window_container_behaviour and float_override to workspaces
221e4ea545
feat(cli): add commands for workspace new window behaviour and float_override
b182cb5818
fix(wm): show floating apps in front of stacked windows as well
7c9cb11a9b
fix(wm): Remove unecessary duplicated code
This commit introduces a distinction between ignored applications
(previously identified with float_rules) and floating applications.
All instances of "float_" with the initial meaning of "ignored" have
been renamed with backwards compatibility aliases.
Floating applications will be managed under Workspace.floating_windows
if identified using a rule, and this allows them to now be moved across
workspaces.
A new border type has been added for floating applications, and the
colour can be configured via theme.floating_border.
This interactively rebased commit contains changes from the following
individual commits:
17ea1e6869
feat(wm): separate floating and ignored apps
8b344496e6
feat(wm): allow ws moves of floating apps
7d8e2ad814
refactor(wm): float_rules > ignore_rules w/ compat
d68346a640
fix(borders): no redraws on floating win title change
a93e937772
fix(borders): update on floating win drag
68e9365dda
fix(borders): send notif on ignored hwnd events
This commit ensures that whenever komorebi.json is read and deserialized
into StaticConfig via StaticConfig::read, all known paths where
$Env:KOMOREBI_CONFIG_HOME and $Env:USERPROFILE are accepted will be run
through the resolve_home_path helper fn.
This commit adds a "bar_configurations" option to the static config file
which takes an array of PathBufs.
If this option is defined and the --bar flag is passed to the "komorebic
start" command, komorebic will attempt to launch multiple instances of
komorebi-bar.exe with the --config flag pointing to the PathBufs given.
This configuration option is only consumed by komorebic, not by the
window manager directly, so it could also be used by other status bar
projects to read configuration file locations from.
There is no requirement for the PathBufs to point specifically to
komorebi bar configuration files if the --bar flag is not being used
with "komorebic start".
This commit replaces almost all uses of the egui Viewport API for bar
window positioning with calls to SetWindowPos via komorebi_client's
Window struct.
This seems to play much more smoothly with multi-monitor setups where
each monitor has a different scaling factor, opening the door for
multiple instances of komorebi-bar.exe to run against multiple monitors.
As a result of this change, the "viewport" configuration option has been
renamed to "position" and doc strings have been changed to remove the
reference to the egui crate docs. Similarly, "viewport.position" and
"viewport.inner_size" have been renamed to "position.start" and
"position.end" respectively. Backwards-compatibility aliases have been
included for all renames.
Not a huge fan of these updates in the windows-rs crate which swap the
isize values which were previously wrapped in various handles with *mut
core::ffi:c_void pointers.
In order to at least keep this codebase sane, all of the wrapper
functions exposed in WindowsApi now take isize wherever they previously
took HWND, HMONITOR, HINSTANCE etc.
Going forward any pub fn in WindowsApi should prefer isize over Windows
handles which wrap c_void pointers.
This commit updates the various komorebic json schema generation
commands to generate the schemas locally, without requiring a running
instance of komorebi to communicate with over IPC.
This commit introduces a new SocketMessage, ReplaceConfiguration, which
attempts to replace a running instance of WindowManager with another
created from a (presumably) different komorebi.json file.
This will likely be useful for people who have multiple different
monitor setups that they connect and disconnect from throughout the day,
but definitely needs more testing.
An experimental sub-widget which calls this SocketMessage has been added
to komorebi-bar to aid with initial testing.
This commit adds instructions for komorebi-bar to the Getting Started
section of the documentation website, adds an example komorebi.bar.json
configuration file, integrates that file with the quickstart command,
and updates the start and stop commands to take --bar flags similar to
the --whkd flags.
In updating the documentation I also decided to rename in the internal
tag for the KomobarTheme and KomorebiTheme enums to "palette" instead of
the previous generic "type" tag which was copied from the serde docs.
This commit adds a new command, focus-stack-window, which allows users
to focus windows in the focused container stack by their index
(zero-indexed) within the stack.
If the user tries to focus an index which does not correspond to a
window within the container stack, an error will be logged.
This commit demotes the komorebi-core crate to a module (core) inside of
the komorebi lib, resulting in the komorebi-client crate lib becoming
the single public interface for programming in Rust against komorebi.
komorebic and komorebi-gui now consume komorebi-client exclusively as
the means for sending and receiving messages to and from komorebi, so
that anyone wishing to integrate with komorebi will have all of the same
functionality to them as I do.
Work on this feature was first started by @thearturca in November 2023
before komorebi v0.1.21 in #597 and has undergone numerous revisions
to reach the point of this commit.
Although this is a single squashed commit, almost all of the heavy
lifting for this feature was done by @thearturca, which is where all of
the kudos and gratitude should be directed.
This commit adds a new static configuration block for animations, where
they can be enabled, and have their style, fps and duration set.
Corresponding SocketMessages and komorebic cli commands have also been
exposed.
There are some caveats to the use of this feature, which revolve around
the quality of the Windows compositor (it is not very good):
* There will be visual artifacts with various apps when animations are
taking place - komorebi can't do anything about this as it is a
limitation of the Windows compositor
* Since komorebi's borders are implemented as independent windows are
are not a part of the windows they are drawn around, these borders
will be hidden while animations are in progress
* If you wish to use borders with this feature, you'll probably better
off using BorderImplementation::Windows, which uses the native thin
"accent" borders, which are part of the windows they are drawn around,
and can be moved with those windows during animations
As a result of these and other caveats, this feature will be marked as
"experimental" for the foreseeable future and will be off-by-default.
Below, a number of now-squashed commits that contributed to the
stabilization of this feature are referenced to help with code
archeology in the future.
fix(animation): Fixed cancelling logic
(57e9b2f4bcaedb4fdfa71adf785d661690d81dfc)
Added static animation state manager for tracking "in_progress" and
"is_cancelled" states. The idea is not to have states in Animation
struct but to keep them in HashMap<hwnd, AnimationState> behind
reference (Arc<Mutex<>>). So we each animation frame we have access to
state and can cancel animation if we have to.
Need review and testings
refactor(animation): avoid unwrap
(fa6d5bbc77c1882f85ee1ce73733ff7e53b39eaa)
fix(animation): Move cancel call to Animation struct
(306513f5dbe5f6bd6ce817f3edca0bfda13d9442)
Only focused window was cancelling its animation because we call cancel
in window::set_position and waiting for its cancelling. And because we
waiting for cancelling second window is still moving. Second window will stop
moving only after the first window. So I moved `cancel` call to
Animation struct so its happening in its own thread and doesn't block
others animation moves and cancels.
refactor(animation): renamed args parameters and variables names
(8abb4b9618bbb3823b868fc37551f0a70b98281e)
refactor(animation): inverse if-statement in `window::animate_position`
(3de2c6e932614651892da4a8c626946e427375dd)
There is was a bug when ease function generates `t` greater the
`SetWindowPos` function will be called instead of `move_window`.
`SetWindowPos` is only for last frame of animation.
fix(wm): add shadow rect to `move_window` calls
(b58620fb4de36d8e422a80541bedf9c1c1579a31)
This fixes a bug when windows get shunk during the animation
This commit adds three new commands, clear-workspace-rules,
clear-named-workspace-rules and clear-all-workspace-rules, to allow
users to remove workspace rules at runtime.
These commands do not distinguish between initial or persistent
workspace rules. If there is a clear use case for this distinction, this
decision can be revisited at a later date.
resolve#908