Commit Graph

99 Commits

Author SHA1 Message Date
LGUG2Z 3d518f73ca perf(borders): selectively invalidate border rects
This commit ensures that we only invalidate a border rect to send a
WM_PAINT message either when the position of the focus state of the
border has changed.

re #862
2024-06-12 08:16:34 -07:00
LGUG2Z aa24c41967 fix(cli): add monitor-information command
This commit adds a new monitor-information command to make it easier for
people to find the values they need to use the display_index_preferences
configuration option.

re #860
2024-06-01 16:48:30 -07:00
LGUG2Z cad2eb9a63 feat(transparency): add transparency manager module
This commit adds the transparency manager module, which, when enabled,
will make unfocused windows transparent using a user-configurable alpha
value between 0-255.

The corresponding komorebic commands (transparency, transparency-alpha)
have been added, as well as the corresponding static configuration
values (transparency, transparency_alpha).

This feature is off-by-default and must be explicitly enabled by the user.

If the process is not shut down cleanly via the 'komorebic stop'
command, it is possible that the user will be left with transparent
windows which will not be managed by komorebi the next time it launches.

This is because the WS_EX_LAYERED style is required for transparency,
but is ignored by default in komorebi's window eligibility heuristics.
For this reason, a separate state tracker of windows that have had this
style added by the window manager is kept in the transparency manager
module.

For this edge case of shutdowns where the cleanup logic cannot be run,
the 'komorebic restore-windows' command has been updated to remove
transparency from all windows that were known to the window manager
during the last session before it was killed.

This must be run _before_ restarting komorebi, so that the previous
session's known window data is not overwritten.

In the worst case scenario that the previous session's data is
overwritten, the user will have to either kill and restart the
applications, or compile komorebi from source and explicitly set
"allow_layered" to "true" in the window_is_eligible function, before
setting the transparency alpha to 255 (fully opaque), and then resetting
to the desired value.
2024-05-31 09:54:16 -07:00
LGUG2Z 88684f991f feat(cli): add stack-all and unstack-all cmds
This commit adds two new commands, stack-all, which puts all windows in
the focused workspace into a single stack, and unstack-all, which
unstacks all windows in the currently focused container.
2024-05-24 11:13:35 -07:00
LGUG2Z 03fdbea5cd refactor(ahk): remove derive-ahk and references
This commit finally sunsets the derive-ahk proc macro and the
ahk-library cli command.

There is now a dedicated, stripped down komorebi.ahk example on the docs
website which mirrors the contents and style of the sample whkdrc:
https://lgug2z.github.io/komorebi/common-workflows/autohotkey.html
2024-05-23 22:57:27 -07:00
LGUG2Z 340c137342 fix(wm): dynamically reserve monitor ring space
This commit makes a small change to dynamically keep reserving space in
the VecDeque that backs Ring<Monitor> until an index preference can be
contained within the current length.

This commit also fixes some clippy lints and adds some allow
annotations.
2024-05-23 19:00:46 -07:00
LGUG2Z d5f4f916be feat(stackbar): make label configurable
This commit introduces a new stackbar label configuration option backed
by the StackbarLabel enum, which now has two variants, Process and
Title.

The state tracker for this option is kept in an AtomicCell, and the
state tracker for StackbarMode has also been changed from an
Arc<Mutex<T>> to an AtomicCell to match.

resolve #826
2024-05-16 14:17:54 -07:00
r3st 29b1794409 feat(cli): add promote-window cmd
This commit adds the promote-window command, which allows the user to
promote the window in the specified OperationDirection from the
currently focused window to the largest tile on the workspace layout.
2024-05-15 14:56:31 -07:00
LGUG2Z 1420334c94 feat(cli): add cycle-move-workspace-to-monitor cmd
This commit adds a new cli command, cycle-move-workspace-to-monitor.

After the introduction of the monitor reconciliator module in
combination with display_index_preferences, this command should never
really be necessary, however it is worth having as a backup.

resolve #718
2024-05-15 14:06:35 -07:00
LGUG2Z 82aa2edf8f docs(wm): border renames and aliases, ahk example
This commit renames a number of border-related code refs, removing the
ActiveWindow prefix since these borders are no longer just for the
active window.

Aliases have been added to preserve backwards compat for existing
configs.

An example AHK configuration file has been added to the Common Workflows
section of the docs site.

A link to the docs site has been added to the output of komorebic start.

A note has been added recommending that users disable system animations
for the best experience in the Getting Started guide.
2024-05-15 11:52:13 -07:00
LGUG2Z 855bb49804 feat(wm): add noop cross-monitor-move-behaviour
This commit adds a new "NoOp" MoveBehaviour for users who don't want any
moves to happen across monitor boundaries. The
toggle-cross-monitor-move-behaviour will only toggle between Swap and
Insert, and will do nothing if NoOp is the selected MoveBehaviour.

resolve #667
2024-05-15 09:51:56 -07:00
LGUG2Z 6a1ed3bcaa 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-12 09:14:50 -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