Commit Graph

88 Commits

Author SHA1 Message Date
LGUG2Z
40b0f80a99 feat(borders): add border manager module
This commit removes all border-related code from process_command,
process_event etc. and centralizes it in the new border_manager module.

Instead of trying to figure out where in process_event and
process_command we should make border-related changes, a notification
gets sent to a channel that border_manager listens to whenever an event
or command has finished processing.

The border_manager listener, upon receiving a notification, acquires a
lock on the WindowManager instance and updates borders for the focused
workspace on every monitor; this allows us to centralize all edge case
handling within the border_manager listener's loop.

Borders on workspaces that lose focus are now destroyed and recreated
when those workspaces regain focus, instead of trying to share
individual border instances across workspaces.

A number of common edge cases that have been addressed in this commit
are:

* Paused window manager
* Floating workspaces
* Maximized windows
* Fullscreen videos
* Monocle containers
* Ghost borders on workspace switching
* Incorrect focused window border colours

Global state related to borders has also been moved into the
border_manager module, which also tracks the state of border objects
(BORDER_STATE), their rects (RECT_STATE) and their focus kinds
(FOCUS_STATE).

This allows us to now track multiple borders per-container, enabling
unfocused border windows for the first time.

Additionally, the Z-Order for border windows is now also configurable.

ActiveWindowBorderColours has been expanded to include Unfocused, but in
order to not introduce a breaking configuration change for end users,
all members of this struct have been made Option<Colour>.
2024-05-11 17:44:06 -07:00
LGUG2Z
dfd0d604aa feat(cli): add move-to-monitor-workspace command
This commit adds a move-to-monitor-workspace command, which, following
the existing convention, does the same action as
send-to-monitor-workspace, but sets the focused monitor, workspace and
container to the window container once it is inserted into the target
monitor and workspace indices.
2024-04-20 14:58:57 -07:00
LGUG2Z
1671f31e3e feat(wm): add window debugging
This commit adds support for debugging windows and emitting information
about how they go through komorebi's decision making pipeline and rules
engines which ultimately decide how they are or aren't managed.
2024-04-15 15:05:20 -07:00
LGUG2Z
6fe46610fc refactor(wm): ensure configurability via ipc
This commit ensures that new features such as stackbar, particularly
where the configuration is located in the global state, can be
configured via SocketMessages.

A few structs had to be moved to komorebi-core to make this possible.
I've also cleaned up a bunch of strum snake_case attrs which seemed to
be unused.

A new GlobalState SocketMessage has been introduced, and going forward
we should make sure that this can send all global state to a requester,
and move global state out of the State handler, which should only handle
window manager state.
2024-04-15 08:36:28 -07:00
eythaann
2bceff4edc feat(wm): add path variant to application identifiers
This commit add a new way to match applications
through its paths, allowing to match a bunch
of applications that share a parent folder.
2024-02-28 12:04:46 -08:00
LGUG2Z
ef1ce4a389 feat(subscriptions): add uds subscription support
This commit adds support for subscriptions via Unix Domain Sockets which
are better suited for IPC between Rust processes compared to Named Pipes
which have issues that I don't want to spend time resolving.

The main motivation for this change is to provide an easy way for the
new zebar project to consume information about komorebi's state in the
Rust backend so that a bar module can be created for komorebi users.

The next step in this process will be to finally refactor the komorebi
crate into a mixed bin/lib crate, and expose all notification-related
structs and maybe some connection helper methods in a new
komorebi-client crate.

The previous "subscribe" and "unsubscribe" komorebic commands have had
the "-pipe" suffix added to them, with aliases in place for the previous
names in order to ensure backwards compat.
2024-02-17 18:14:14 -08:00
LGUG2Z
b64c0e127d feat(config): recognize komorebi_config_home for asc path
This commit ensures that the KOMOREBI_CONFIG_HOME environment variable is recognized by the
komorebic check command and the static config loader when used to specify the location of the
applications.yaml file.

resolve #660
2024-02-09 16:49:49 -08:00
LGUG2Z
d6e83e1778 feat(cli): add last focused workspace cmd
This commit adds a new komorebic command, focus-last-workspace, which
switches to the last focused workspace on the focused monitor (if there
is one).
2024-01-11 18:51:41 -08:00
LGUG2Z
b4ae043b9c feat(cli): add visible-windows cmd
This commit adds a new komorebic command, "visible-windows", to make
tracking down ghost windows easier. The returned JSON structure will try
to use the device id to identify a monitor if it is available, or fall
back to the monitor index. Thanks to raggi on Discord for suggesting
this command!
2024-01-02 10:37:22 -08:00
LGUG2Z
657ac441ae feat(wm): use device id for monitor index pref
This commit begins to build on some of the knowledge shared by EBNull in
allowing users to specify monitor index preferences using physical
device identifiers. This does not presently go all the way to EDIDs, but
the display model and what I believe is a port identifier on the display
adapter(s) can be used to uniquely identify a display in most use cases.

However, I believe I may have unfortunately run into a bug in either
windows-rs or Rust itself, as when the code calling EnumDisplayDevices
is called, it always fails when running a release build, and always
succeeds when running a debug build. This needs to be investigated
further.

re #612
2023-12-22 17:01:59 -08:00
LGUG2Z
5a99a688a6 feat(asc): add json schema cmd and output
This commit adds a command to output a JSON Schema for the
applications.yaml file maintained in the
komorebi-application-specific-configuration repo, and also adds an
up-to-date version of the JSON Schema as a file in the root of this
repository so that users can reference it as an autocompletion source.
2023-12-02 13:42:23 -08:00
amrbashir
b39e65642b refactor(rust): cleanup path handling
- Avoids unnecessary string allocation when tracing paths
- Replaces `mut path & path.push()` with `path.join()`
- Avoids unncessary cloning of paths where applicable
- Use `dunce` crate to remove `UNC` prefix
- Improve performance of resolving `~` by avoiding unnecessary string allocations
- Resolve `~`, `$Env:USERPROFILE` and `$HOME` consistenly between different code paths
- Use `PathBuf` instead of `String` for paths in CLI args

I may have missed a couple of places but I think I covered 90% of path handling in the codebase
2023-11-26 15:25:43 -08:00
LGUG2Z
0d1595e543 feat(cli): add focused ws padding cmds
This commit adds dedicated komorebic commands for setting the padding
values of the focused workspace and containers.

re #570
2023-11-16 15:05:14 -08:00
Kushashwa Ravi Shrimali
e9fb9297e9 feat(cli): add cycle-layout command (#556)
* Command to ToggleLayout

* Just improve logic of figuring out next layout

* Addr review: rename to "Cycle" instead of toggle, and add a small comment

* As per review comments, implement cycle method on DefaultLayout

* I forgot to remove this, my bad

* feat(cli): fixups for cycle-layout cmd

* Update komorebic/src/main.rs

Co-authored-by: Kushashwa Ravi Shrimali <kushashwaravishrimali@gmail.com>

---------

Co-authored-by: LGUG2Z <jadeiqbal@fastmail.com>
Co-authored-by: جاد <LGUG2Z@users.noreply.github.com>
2023-10-26 21:19:24 -07:00
LGUG2Z
0797316ee6 feat(rules): add explicit matching strategies
This commit is the first in a series of commits which will pave the way
for regex rule matching support in komorebi.

For now, in order to maintain backwards compat and not break anything,
all rules without a matching strategy will get assigned as using the
"Legacy" strategy.

This and the "Equals" strategy are the only two which have been
implemented so far.

There should not be any breaking changes in this commit, not any
functionality lost for users with pre-existing configurations.

re #60
2023-09-22 15:05:20 -07:00
LGUG2Z
4510cccc3e feat(config): add static json loader and whkd flag
This commit is an implementation of a static JSON configuration loader.

An example komorebi.json configuration file has been added.

The application-specific configurations can be loaded directly from a
file, and workspace configuration can be defined declaratively in the
JSON. Individual rules etc. can also be added directly in the static
configuration as one-offs.

A JSONSchema can be generated using komorebic's static-config-schema
command. This should be added to something like SchemaStore later.

Loading from static configuration is significantly faster on startup, as
the lock does not have to be reacquired for every command that is sent
over the socket.

When loading configuration from a static JSON file, a hotwatch instance
will automatically be created to listen to file changes and apply any
updates to both the global and window manager configuration state.

A new --whkd flag has been added to the komorebic start command to
optionally start whkd in a background process.

A new komorebic command 'generate-static-config' has been added to help
existing users migrate to a static JSON config file. Currently, custom
layout file path information can not be automatically populated in the
output of this command and must be added manually by the user if
required.

A new komorebic command 'fetch-asc' has been added to help users update
to the latest version of the application-specific configurations
in-place.

resolve #427
2023-07-13 08:12:43 -07:00
Yusuf007R
6fe2290d74 feat(swap-workspaces-monitor): command to swap focused monitor workspaces with another monitor
Basically this commit adds a command that allows you to swap two monitors, well it actually swaps
the workspaces between the monitors.
2023-06-24 07:04:07 -07:00
LGUG2Z
9103ce2b2b feat(wm): add focus-workspaces cmd
This commit adds a new command, focus-workspaces, to allow the user to
change workspaces across all monitors at the same time. I'm not
convinced of the stability of this command and I would strongly
discourage using komorebi in this manner.

resolve #426
2023-06-03 17:30:43 -07:00
LGUG2Z
c37ba42825 feat(wm): reintroduce remove-title-bar cmds
This commit reintroduces some old code from the feature/remove-titlebars
branch. This feature is very unstable and it is strongly advised that
nobody actually uses it. Wherever possible, please use the "remove
titlebar" functionality provided directly within an application.
2023-05-15 13:49:45 -07:00
Alvin Truong
27e0758089 feat(workspace-rules): add InitialWorkspaceRule and InitialNamedWorkspaceRule command
- Added the two new commands to prevent breaking changes due to AHK
  users.
2023-04-30 12:40:01 -07:00
Alvin Truong
4306a7bafe feat(workspace-rule): add ability to only apply workspace rule on first
show of app
2023-04-30 12:40:01 -07:00
LGUG2Z
2520c4abe1 feat(wm): add border colour for monocle
This commit adds a new WindowKind to allow the user to set a unique
colour to identify when a window container in monocle mode is active.

resolve #404
2023-04-24 13:08:29 -07:00
LGUG2Z
f41e8c151e feat(wm): add cycle move/send to monitor cmds
This commit introduces cyclical commands for moving (with focus) or
sending (without focus) windows between adjacent monitors.

resolve #363
2023-02-24 16:59:16 -08:00
LGUG2Z
8adff69b81 feat(wm): add more named-workspace cmd variants 2023-02-16 12:24:42 -08:00
LGUG2Z
6b918dae7f feat(wm): add named workspace commands
This commit introduces three new commands, ensure-named-workspaces,
named-workspace-rule, and focus-named-workspace, which email to reduce
the configuration complexity by allowing users to refer to workspace
names instead of monitor and workspace indices.
2023-02-12 15:18:16 -08:00
LGUG2Z
80c98596dd feat(wm): add "cloak" window-hiding-behaviour
This commit adds cloaking as a window-hiding-behaviour option.

https://devblogs.microsoft.com/oldnewthing/20200302-00/?p=103507 for
more information on cloaking.

Cloaking is the same mechanism used by the native Virtual Desktops
feature by the Windows team, however it is deliberately hidden from the
public Windows API.

GitHub user Ciantic's VirtualDesktopAccessor crate documents the private
IApplicationView COM interface which contains the hidden and
undocumented SetCloak method, which can be used to cloak and uncloak
application windows by their HWNDs.

With some help from Ciantic and manual exploration to determine the
correct flags values to use, komorebi is now able to use the cloaking
mechanism when switching workspaces, which results in significantly
higher reliability and significantly less jank on workspace transitions.
komorebi's use of this cloaking mechanism also retains the flexibility
of per-monitor workspaces that users have come to know and enjoy.

This has only been tested on Windows 11, it is not yet known if calling
the SetCloak function in IApplicationWindow will cause crashes on
Windows 10.
2023-02-11 15:14:20 -08:00
LGUG2Z
925f3bd87b feat(wm): add optional alt focus hack
This commit adds an optional focusing hack using simulated ALT key
presses to ensure that focus changes always succeed. As noted in the
documentation for LockSetForegroundWindow, the system automatically
enables calls to SetForegroundWindow if the user presses the ALT key.
2023-01-21 13:29:10 -08:00
LGUG2Z
4ee4d199a0 feat(wm): add new cmd to set active border offset
This commit introduces a new command, active-window-border-offset, which
allows the user to offset the starting position of the active window
border, thereby allowing for thicker or thinner active window borders,
when used in conjunction with the active-window-border-width command.

resolve #232
2022-12-19 19:01:46 -08:00
LGUG2Z
613d69a737 feat(wm): add force-focus command
On rare occasions and usually with Firefox, the desired application will
fail to be focused with the regular focus commands. This commit
introduces a new command, force-focus, which can be used to simulate a
left-click on a window that has failed to take focus, since this is what
I have to do to work around the issue anyway.
2022-12-15 17:08:25 -08:00
LGUG2Z
e764dad7a4 feat(wm): make active border with configurable
This commit introduces a new command which lets the user set a custom
width value for the active window border when it is enabled.

Unfortunately a little more width is required when working with rounded
windows on Windows 11 to fill the gap left by the rounding. The default
width remains set at 20.

re #232
2022-12-09 18:58:02 -08:00
LGUG2Z
97423fc8e9 feat(wm): move/send container to ws by direction
This commit introduces two new commands which will allow the user to
move or send the currently focused window to either the next or previous
workspace depending on the cycle direction.

re #297
2022-12-06 18:54:49 -08:00
LGUG2Z
b010215318 feat(wm): add per-monitor work area offsets
This commit introduces per-monitor work area offsets which will always
take precedence over global work area offsets.
2022-11-12 18:23:24 -08:00
LGUG2Z
2575ca2da4 feat(wm): add monitor index preference cmd
This commit adds a new komorebic command, monitor-index-preference,
which allows the user to set the index preference within the VecDeque of
monitors based on the "size" of a display.

This works as the size Rect identifies a unique display on the greater
virtual screen and persists across display connections and
disconnections unless the user deliberately changes the positioning of
the display monitor on the virtual screen.

When a new monitor is added to the state, the monitor preferences will
be checked, and if a preference exists, the new monitor will be inserted
at that index, otherwise, it will be pushed to the back of the VecDeque.

resolve #275
2022-10-31 12:38:59 -07:00
LGUG2Z
e20b4aabc3 fix(clap): address deprecations 2022-10-20 14:21:27 -07:00
Yusuf007R
33965f92ad feat(wm): add close and minimize cmd
this commit adds the ability to close and minimize the current focused window via SocketMessages and
komorebic commands

resolve #189
2022-10-13 01:08:35 -07:00
LGUG2Z
d3dc193d29 feat(tcp): add listener + export socket schema
This commit adds a TCP listener that can be optionally exposed on a port
provided by the user using the --tcp-port flag. If the flag is not
provided, the TCP listener will not be started.

Client state is tracked using the connecting address, and clients are
purged if they send unrecognised messages.

A JSON Schema of the SocketMessage enum can be exported via komorebic
and be used to generate type definitions in various programming
languages.

This commit also makes some improvements to the handling of 'komorebic
start'.

The previous backoff approach was not working as once the Windows API
denies access to the process for any call, no amount of retries with the
same process id will result in approval.

Therefore, 'komorebic start' now checks if the process has been started,
and if it hasn't (ie. it has errored out because of an access denied
error), it will continue to restart the process until all the komorebi
startup calls to the Windows API succeed.

resolve #176
2022-08-15 09:35:08 -07:00
LGUG2Z
458d1ef80a feat(wm): add promote-focus command
This commit adds a promote-focus command to complement the promote
command.

resolve #203
2022-08-13 17:10:55 -07:00
LGUG2Z
e466a17877 feat(wm): restrict border window to outline
This commit moves the border window drawing logic into the WNDPROC
callback and uses BeginPaint -> Rectangle -> Endpaint to draw a
rectangle around the outside of the window in a specific colour that is
not black, which is used as the transparency colour with
SetLayeredWindowAttributes.

All of this results in a non-filled border rect and a much nicer
experience for users who are using transparency or translucent effects
on their windows.

This commit also introduces an optional second active border colour when
the user is focused on a stack of windows. If this is not set, the
default colour for single windows will be used.

Finally, a bunch of small issues relating to the border window staying
drawn on the screen even when there are no active windows on a workspace
have been addressed.

resolve #201
2022-08-13 08:16:27 -07:00
LGUG2Z
07bd53876f feat(wm): add active window border
This commit adds an optional active window border with a user-defined
colour. This is achieved by spawning a dedicated "border window" and
constantly placing it behind the focused window, or hiding it whenever
necessary.

Some constraints to note:

- The border will only be applied to windows managed by komorebi
- This means that if you temporarily float a window, it will lose the
  active window border
- There are some issues where parts of the border will be broken by
  applications like Zoom, even if Zoom is behind the currently focused
  window
- You probably want to turn off window shadows globally in Advanced
  System Settings -> Performance for the borders to have a consistent
  colour all the way around the window
- There is some inevitable jank due to trying to reposition both the
  focused window and the "border window" behind it simultaneously
- There are no borders for unfocused windows

resolve #182
2022-08-08 09:59:26 -07:00
LGUG2Z
a6d46dbf45 feat(wm): optionally await config completion
This commit introduces a new flag to komorebi and komorebic,
--await-configuration, which when enabled, will stop the process from
processing window manager events and updating the layout until the
'komorebic complete-configuration' command has been sent.

This should typically be added at the end of a user's komorebi.ahk
configuration file if they decide to enable this feature.

resolve #190
2022-07-31 09:44:43 -07:00
LGUG2Z
3c84bfd27e feat(wm): add cross-monitor move behaviour config
This commit provides two new commands, to set and toggle the behaviour
(swap, insert) when moving window containers across monitor boundaries.
MoveBehaviour::Swap has been selected as the default as this seems to be
the default on bspwm.

resolve #145
2022-06-27 09:14:09 -07:00
LGUG2Z
711ab8d59b feat(wm): add cmd for unmanaged hwnd op behaviour
This commit adds a new command, 'unmanaged-window-operation-behaviour'
which allows the user to configure their desired behaviour in situations
when sending window container commands which operate on the focused
window container in the workspace state, but having an unmanaged window
as the foreground hwnd.

The default previously was previously Op (and this remains the default
with these new changes), but the user can now select NoOp, which will
return an error when the focused hwnd is unmanaged and not allow any
write operations to take place on the focused workspace state.

resolve #133
2022-04-19 17:13:27 -07:00
LGUG2Z
09a24b89e5 feat(config): add cfgen for apps based on yaml def
This commit introduces a configuration generator for
application-specific config options passed to the cli via a file path.

The hope is to have a public repository that any user can contribute
application-specific configs and fixes to, and for the generated AHK to
be available to any new user as part of the initial setup to make the
onboarding as frictionless as possible.

re #62
2022-04-01 18:25:05 -07:00
LGUG2Z
4686d5e346 feat(wm): add cmd to id layered apps
Users on Discord noted that Microsoft Office applications were not being
handled correctly by the wm. After some investigation it was clear that
this was because the application windows had WS_EX_LAYERED set.

This had only been seen once before with Steam, and so a whitelist for
layered applications was previously added to the codebase with steam.exe
hard-coded, but this had not been exposed via the cli.

This commit adds a command to allow users to specify layered
applications which should be managed, and also renames the whitelist to
reflect that classes can also be used to identify applications on the
whitelist.

A section has been added to the README to guide Microsoft Office users
to guide Microsoft Office users in configuring komorebi to correctly
handle Office applications with Word given as an example.

This commit also renames the identify-border-overflow command to
identify-border-overflow-application for consistency, while retaining
the previous command as an alias to maintain compatibility with existing
user configurations.

It should be noted however, that those like me who are using the
generated komorebic AHK library, will have to update any AHK function
calls to use IdentifyBorderOverflowApplication().

resolve #124
2022-03-30 11:04:41 -07:00
LGUG2Z
75234caa98 feat(wm): add dynamic layout selection rules
This commit adds a new feature which allows the user to specify a set of
rules for a specific workspace that will be used to calculate which
layout to apply to that workspace at any given time.

The rule consists of a usize, which identifies the threshold of window
containers which need to be visible on the workspace to activate the
rule, and a layout, which will be applied to the workspace when the rule
is activated.

Both default and custom layouts can be used in workspace layout rules.

When a workspace has layout rules in effect, manually changing the
layout will not work again until the rules for that workspace have been
cleared.

This feature came about after trying but failing to modify the custom
layout code in such a way that the width percentage of a primary column
in a custom layout might be propagated to the fallback columnar layout
when the tertiary column threshold is not met.

Although this new feature introduces more complexity, it is strictly
opt-in and can be completely ignored if the user has no interest in
adjusting layouts based on the visible window count.

re #121
2022-03-28 14:49:16 -07:00
LGUG2Z
31b8be1481 feat(wm): add cmd to id apps with odd launch event
A user on the Discord noted that PyCharm windows were not being managed
as expected when initially launched. After some digging this seems to be
the same issue that was addressed for IntelliJ and Firefox early on in
development, where these applications send EVENT_OBJECT_NAMECHANGE on
launch instead of the regular event when drawing a new window.

The OBJECT_NAME_CHANGE_ON_LAUNCH vec was not previously exposed via
komorebic to allow users to identify other applications that exhibit the
same behaviour. This commit adds a command to allow users to specify
further applications in their configuration files.
2022-03-28 10:08:34 -07:00
LGUG2Z
3eade94032 chore(deps): bump windows-rs from 0.33 to 0.34 2022-03-18 16:43:31 -07:00
LGUG2Z
02c54734fb feat(wm): add send-to-monitor-workspace cmd
This commit adds a dedicated command to send a window container to a
specific workspace on a target monitor.
2022-02-05 13:42:16 -08:00
LGUG2Z
2db0d888c1 feat(subscriptions): add cmd to gen json schema
This commit introduces the 'notification-schema' command to generate a
JSON schema of the Notification struct which gets sent when notifying
subscribers of updates.
2022-02-01 12:38:11 -08:00
LGUG2Z
39685dd615 feat(wm): add cmd to move ws to other monitors
This commit adds a new komorebic command to move the entire focused
workspace and all managed windows and containers to a target monitor
index. Windows that have been excluded from management using various
rules will not be moved as they are not tracked in the window manager
state.

resolve #88
2022-01-07 08:52:18 -08:00