Commit Graph

41 Commits

Author SHA1 Message Date
alex-ds13
3b20e4b2fe refacor(wm): use helper function on move to workspace
Use the same `add_container_with_direction` function on
`move_container_to_workspace` as it is being used on
`move_container_to_monitor` or `move_container_in_direction`.

This way we bring parity between all methods and make it easier to
change the way a container is added on a monitor workspace when taking
the move direction into consideration.
2024-11-29 15:19:56 +00:00
alex-ds13
8f4bc101bc fix(wm): move floats in direction across monitors
This commit fixes an issue where when trying to move floating windows or
windows on a floating workspace across boundaries to another monitor
using the `move_container_in_direction` it wouldn't move the floating
windows physically, although it moved them internally on komorebi,
resulting in weird and wrong behavior.

This commit creates a new method on `Monitor` to
`add_container_with_direction` which takes a move direction and then
uses the same logic that was previously on the
`move_container_in_direction` function.
It changes the `move_container_to_monitor` function to take an optional
move direction which if it is some will have this function call the new
method `add_container_with_direction` instead of just `add_container`.
Lastly the `move_container_in_direction` function now when it realizes
the move will be across monitors simply calls the
`move_container_to_monitor` with the direction that was initially given
to it.
These changes require that all callers of `move_container_to_monitor`
add an direction option, instead of passing `None` on all of them, a new
helper function was created, named `direction_from_monitor_idx` which
calculates the direction a move will have from the currently focused
monitor and the target monitor return `None` if they are the same or
returning `Some(direction)` if not. This way now all commands that call
a move across monitor will use the logic to check from the direction if
it should add the container on front or end.
2024-11-29 15:15:23 +00:00
LGUG2Z
6db317d425 feat(wm): separate floating and ignored apps
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
2024-10-13 10:05:11 -07:00
LGUG2Z
21bd09e419 fix(wm): add layout edge index awareness
This commit builds on c3f135703e and
1080159e68 to add layout-specific edge
index awareness to all default layouts.

This is most useful for UltrawideVerticalStack and
RightMostVerticalStack, which have a lot of edge cases due to the
positioning of the 0th index changing with the number of containers on a
workspace.
2024-09-24 15:39:19 -07:00
LGUG2Z
c06d9afa3b fix(wm): grow monitors vec to accomodate idx prefs
This commit fixes a bug in load_monitor_information which resulted in an
infinite while loop due to a misunderstanding of how VecDeque::reserve
works.
2024-08-27 16:21:59 -07:00
LGUG2Z
b799fd3077 feat(wm): add cross boundary behaviour options
This commit introduces a new configuration option,
cross_boundary_behaviour, which allows the user to decide if they want
Focus and Move operations to operate across Workspace or Monitor
boundaries.

The default behaviour in komorebi has always been Monitor.  Setting this
to Workspace will make komorebi act a little like PaperWM, where
"komorebic focus left" and "komorebic focus right" will switch to the
next or previous workspace respectively if the currently focused window
as at either the left or right monitor boundary.

resolve #959
2024-08-26 21:49:08 -07:00
LGUG2Z
81451cb17a refactor(client): use public interface exclusively
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.
2024-07-15 17:11:35 -07:00
LGUG2Z
67a3c3546f refactor(wm): use saturating_sub for idx-1 updates
This commit ensures that we use the saturating_sub function uniformly
when decrementing usize values by 1.
2024-06-10 14:51:53 -07:00
LGUG2Z
6b9a0843fd perf(borders): introduce state snapshot checks
This commit introduce state snapshot checks in the border manager, which
will ensure that we don't even attempt to acquire any mutex locks if the
state hasn't changed.
2024-06-09 07:17:13 -07:00
LGUG2Z
a29ab4cfb3 feat(wm): add monitor reconciliator module
This commit adds the monitor_reconciliator module which uses a tightly
bounded channel (cap: 1) to handle monitor connection and disconnection
events, as well as resolution and work area change events.

Before, all this logic lived in a the WindowManager.reconcile_monitors
function, which ran on pretty much every process_event iteration, and
sometimes led to undesirable behaviour, but now the logic is split up to
only run when the appropriate notifications are dispatched from the
hidden window which listens for monitor and display-related events.

The monitor cache has been moved out of WindowManager and into the
monitor_reconciliator module, and in addition to the previous behaviour
of attempting to cache monitors which had been identified as
disconnected, now when the static configuration file is loaded, if the
user has set display_index_preferences, the device IDs will be used to
pre-populate the cache for the event where a known monitor is connected
later in a session.

The monitor cache itself now uses the unique device ID as a key rather
than the hmonitor which is known to be inconsistent.

This commit also delegates all display monitor-related Win32 calls to
the "win32-display-data" crate, which was extracted from the larger
"brightness" crate for its use in komorebi.

As a result of these changes, "device" and "device_id" on Monitor have
been changed from Option<String> to String types, as failures in
retrieving these values with directly attached monitors has not been
possible to reproduce. However, it remains to be seen if this will
adversely impact users who use display docks which may prevent display
monitor device IDs from being read and stored by the operating system.

WindowManagerEvent::DisplayChange has been removed in favour of
the monitor_reconciliator::Notification enum, as these events are no
longer being handled in process_events.

Attempts are now made to eagerly update hmonitors both within the
monitor_reconciliator loop on DisplayConnectionChange notifications and
when failing to find a matching hmonitor in functions like
monitor_idx_from_current_pos and monitor_idx_from_window.
2024-05-19 06:26:45 -07:00
LGUG2Z
3d53c602a7 feat(wm): single_window -> window_based offset
This commit updates the initial design of single_window_work_area_offset
to window_based_work_area_offset where the user can set
window_based_work_area_offset_limit to determine the limit of windows on
the screen that this offset should apply to.

By default this is 1, and in the most extreme case of someone using a
super ultrawide monitor this might be 2.
2024-05-15 09:51:57 -07:00
LGUG2Z
0330dfe250 feat(wm): add single window work area offsets
This commit adds a new monitor configuration option, single_window_work_area_offset, which will
apply to a monitor when only a single window is open on a workspace. This is implemented as a Rect
to enable its use on both horizontally and vertically positioned monitors. This option will be
particularly useful for ultrawide monitor users, where a single window taking up the full width of
the work area can often hinder usability.

resolve #434
2024-05-15 09:51:56 -07:00
LGUG2Z
c65060fbd9 feat(wm): add stackbar for multi-window containers
This commit introduces the stackbar feature through careful extracting
and refactoring of code from the Komorebi-UI hard-fork.

Unfortunately on the fork, this feature was not implemented using atomic
commits, which resulted in the implementation here being more of a
"reinterpretation" than a lift-and-shit of the referenced code.

Nevertheless, this commit represents a working version of the stackbar
feature.

resolve #681
2024-03-25 14:30:30 -07:00
LGUG2Z
e0e3afa5b9 feat(config): update border opts, add deprecations
This commit includes backwards-compatible renames of
active_window_border_offset and active_window_border_width to
border_offset and border_width respectively.

Since the invisible window border adjustments were removed in #678, the
invisible window borders set by the OS can now also be adjusted via
border_offset and border_width, which is the primary reason for the
rename.

invisible_borders has been marked as deprecated and the previously
deprecated alt_focus_hack option has been removed.
2024-02-25 17:41:49 -08:00
James Tucker
4affefad88 fix(cfg,komorebi): remove all uses of invisible borders
This makes the borders pixel-perfect, and border_overflow can be
disabled on all applications.

Unfortunately this also means we lose the corner rounding, so that may
need to be done differently or the offsets refined in some way to
address that.
2024-02-25 16:27:16 -08:00
LGUG2Z
f519cbaf1e refactor(wm): split komorebi into bin and lib
This commit splits the komorebi crate into a mixed binary and library
crate.

All types and logic related to window management have been moved under
lib.rs, and are imported from there for use in main.rs, which is now
only responsible for starting and running the window manager process.

In preparation for exposing a new komorebi-client crate in the future,
serde::Deserialize has been derived on Notification and any struct that
may appear in a notification receievd by a process that has subscribed
to event updates.

re #659
2024-02-18 15:14:59 -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
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
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
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
37edbcfebc refactor(clippy): apply various lint fixes 2022-11-13 15:31:19 -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
37f1a163cc fix(wm): match display name / avoid id volatility
This commit replaces all usages of MONITORINFO with MONITORINFOEX in
order to retrieve a name for each connected display device.

This display device name makes for easier deduping during monitor
reconciliation, so that matching display monitor names can simply have
their hmonitor id updated instead of trying to figure out which id
corresponds to which monitor by looking at the windows currently visible
on each.

fix #267
2022-10-31 12:38:59 -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
LGUG2Z
a55069df48 feat(wm): add mouse follows focus toggle
This commit adds a toggle for the mouse follows focus behaviour that has
been the default for komorebi until now.

resolve #63
2021-10-29 13:41:55 -07:00
LGUG2Z
65bc1a966e feat(wm): add cmd to specify work area offsets
This commit adds a new komorebic command to specify offsets for work
areas to be applied across all monitors. The areas covered by these
offsets will be excluded from the tiling area, and can be used for
custom task bars, Rainmeter desktop widgets etc.

When setting an offset at the top, the same offset will need to be
applied to the bottom to ensure that the tiling area is not pushed off
of the screen, but this is not necessary when applying an offset to the
bottom as the top of the work area will never go lower than 0.

resolve #46
2021-10-14 11:08:25 -07:00
LGUG2Z
5b923a135c feat(wm): adapt to scaling and resolution changes
This commit expands the reconcile_monitors fn to also update resolution
and work area sizes if they are different from what is stored in the
window manager state.

Another WindowManagerEvent has been added as a polling mechanism for
monitor-related changes (scaling, dpi, resolution etc.), and this will
now also trigger the reconcile_monitors fn in the existing event
pre-processing block.

resolve #36
2021-09-16 14:53:07 -07:00
LGUG2Z
f1ee5ea194 feat(wm): make invisible borders configurable
Following the changes I witnessed in the invisible window border size
following an OS update, this commit makes the invisible border offset
configurable via a new komorebic command 'invisible-borders'.

When sending a new set of invisible border offset dimensions via
komorebic, a full retile across all monitors will take place after the
new values have been set.

The default values have been set to what is currently correct for my
machine, and will likely be updated again in the same way in the future
if further changes occur in subsequent OS updates.

This commit also updates some dependencies to their latest releases, and
removes from the CI workflow a line that attempts to delete the
rustup-init.exe binary after installation which has been causing builds
to fail.

resolve #35
2021-09-14 21:26:18 -07:00
LGUG2Z
c4c8bd7d4b feat(wm): reconcile monitor state
When monitors turn on and off, they do not retain their hmonitor id,
therefore this commit introduces an initial attempt to reconcile invalid
and valid hmonitors after monitor changes based on the windows that are
assigned to them.

If a monitor has at least one window, and has been assigned a new
hmonitor id, komorebi will look up the current hmonitor of that window's
hwnd and update Monitor.id in-place.

When reconciling monitors, any monitor marked as invalid will be purged
from the window manager state.

This commit also applies some of the new clippy lints that come along
with the latest nightly release of Rust.

resolve #31
2021-09-13 07:24:09 -07:00
LGUG2Z
b61b03b1c9 refactor(eyre): handle options with combinators
This commit removes the unnecessary eyre dependency and instead uses the
relevant imports from color-eyre.

Additionally, after reading the eyre readme a little more closely, I
have switched out .compat() for the ok_or() combinator function as
suggested here: https://github.com/yaahc/eyre#compatibility-with-anyhow.
2021-08-23 09:52:13 -07:00
LGUG2Z
0725549d45 feat(wm): add native window maximization toggle
Windows that have been maximized do not retain their maximized state
across workspaces as workspaces are built on top of sending SW_HIDE and
SW_SHOW events which at various points of the event loop end up
overriding SW_SHOWMAXIMIZED and SW_SHOWMAXIMIZE.

To handle this use case, I have added a new 'komorebic toggle-maximize'
command which sends SW_MAXIMIZE for a window and keeps a record of the
window in the focused workspace in the same way that monocle windows are
tracked.

In this way, komorebi can know when switching to a workspace if it has
to restore a window to a native maximized state.

Some additional edge cases are caught in this commit in showing and
hiding workspaces, to also account for floating windows and monocle
containers.

resolve #12
2021-08-18 09:49:05 -07:00
LGUG2Z
b8929cbead feat(wm): add command to create new workspace
This commit adds a new command, 'komorebic.exe new-workspace', which
will append a new, empty workspace, to the list of workspaces on the
currently focused monitor, and then switch focus to it.

Also took the opportunity to clean up some unnecessary unwraps in
komorebic/src/main.rs.

resolve #4
2021-08-14 09:42:12 -07:00
LGUG2Z
0d3751a7cc refactor(wm): reduce boilerplate with getset
This commit introduces the getset crate to reduce a lot of the
boilerplate, especially in workspace.rs, around different variations of
getters. Hopefully this will make the codebase easier to navigate for
contributors in the future.

Also trying to avoid pinning to patch versions and minor versions
wherever possible.
2021-08-13 10:38:11 -07:00
LGUG2Z
579a5556cc refactor(ring): gen element impls using macro
Using macros to generate common type-specific Ring element accessors.
Should make codebase navigation a little easier my making logic-heavy
functions more visible in impl blocks.
2021-08-10 08:10:56 -07:00
LGUG2Z
0ca3320939 refactor(logging): make use of tracing::instrument 2021-08-05 13:46:22 -07:00
LGUG2Z
230b534735 feat(wm): add query command to cli
Added a query command to komorebic to return the WindowManager struct
serialized to JSON to help with debugging and maybe help others to build
tools like stackline for yabai in the future.
2021-07-30 14:11:09 -07:00
LGUG2Z
8c939328d1 feat(wm): ensure workspace count
Allow the number of workspaces for a given monitor to be pre-created, so
that configuration options can be sent (name, padding, layout) before
the workspace has ever been activated.
2021-07-30 12:06:31 -07:00
LGUG2Z
b0c3480262 fix(wm): float/monocle toggle, invisible borders
This commit fixes issues with toggling on and off Monocle and Floating
Window mode by ensuring that the relevant windows are always at the top
of the Z order, and in the latter case, ensuring that the top visible
window is used to search the local floating window state of the process.

After some experimenting I seem to have been able to adjust to remove
all of the invisible window borders by default, so if desired, a user
can now have no gaps at all.

Also upgraded to the latest version of the windows-rs crate since I saw
it was available. Thankfully no breaking changes.
2021-07-30 10:44:31 -07:00
LGUG2Z
61cee458a1 feat(wm): initial commit
One week of blissful, in-the-zone coding, applying all of the lessons
learnt from the development of yatta.
2021-07-29 16:23:42 -07:00