The layout should leave the space configured for the border, so that the
border always stays within the workspace bounds.
Border offset is cleaned up, as it is no longer a rect, but instead just
a fixed value.
The rect function for adjusting padding now takes a concrete value, as
the optional has no local meaning to the operation, being equivalent to
the default value.
A margin function is added to centralize the notion of increasing the
size of a rect by the given margin, the opposite of the padding
operation.
This fixes a regression from an earlier commit that dropped the DWM
style borders without fixing corner rounding on Windows 11. This is now
fixed for Windows 11 again, while avoiding the extra system border
decorations.
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.
Switch to using the DWM API to get Window bounds so as to exclude the
outside of window decorations from the computation.
This is getting close to a precise window size, you can now set an
active border width of 1 and an offset of 1 and get a 1 pixel line
around most windows, except that there's some extra top padding I have
yet to find the cause of.
This implementation needs to be DPI aware, but I haven't yet tested if
the DPI scaling approach is entirely valid - we may instead need to get
the per-monitor DPI scale, identify the monitor the window is on, and
scale to that, rather than using the system wide scale.
Maybe fixes#574
Maybe updates #622
This commit introduces the ability for users to specify colours in the
static config file in either RGB or Hex format.
This is done by introducing a new enum, Colour, which provides variants
wrapping the internal Rgb type, and the HexColour type from the
hex_colour crate. HexColour itself is wrapped in a new struct, Hex, in
order to allow the implementation of the JsonSchema trait.
A number of From<T> implementations have been done in order to make
working with the Colour enum more ergonomic.
Ultimately, the core representation for colours in komorebi remains the
Rgb struct, any and Hex-specified colours will be converted to this Rgb
type before being converted to u32 to pass them on to various Win32 API
calls.
This commit addresses and number of bugs and improves the experience of
working with floating workspaces (ie. Workspace.tile = false).
- When the user moves or resizes a window on a floating workspace,
WindowManagerEvent::MoveResizeStart will no longer trigger, which
prevents the mouse focus from going to the middle of the window rect
after the resize or move action (if mouse_follows_focus = true)
- If active_window_border = true, it will no longer be shown on focused
windows in floating workspaces
- When windows are moved using a komorebic command from a floating
workspace to a tiling workspace and active_window_border = true, the
active window border will be shown again
This commit addresses a few bugs with regards to maximized window
handling.
- Correctly restoring and focusing when switching to a workspace
containing a window previously maximized with the toggle-maximize
command
- Unmaximizing a window during the initial window scan when the wm
initializes so that windows that are maximized before running komorebi
will no longer have the ugly white bar at the top
- When updating workspace layouts, windows that have been maximized
without using the komorebic toggle-maximize command will be
unmaximized to prevent the wm state drifting out of sync with what is
happening on the screen
This commit ensures that the focus changes to the appropriate window
when a container stack is being cycled through by a user who has
disabled the mouse_follows_focus feature.
fix#680
- Use a single thread to bind the hook, and then start dispatching.
- Use a blocking loop for message dispatching.
- Remove the locks around crossbeam channel, as it's already Send + Sync
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
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.
Replace the client socket with replies sent on the other side of the
querying stream, for both UDS and TCP clients. This has two results:
unix socket clients such as komorebic no longer race on the socket bind,
fixing the out of order bind error, and the response mixup conditions
that could occur. Queries over TCP now receive replies over TCP, rather
than replies being sent to a future or in-flight command line client.
This commit ensures that the $Env:LOCALAPPDATA/komorebi dir is created
by the quickstart command, as it cannot be assumed that this will always
exist, especially on new machines with recent versions of Windows 11.
fix#671
This commit is a fix that handles a subtle breaking change in
sysinfo::Process:root() which no longer can be used to see if a process
is a scoop shim.
Instead we can stringify the executable path and see if the absolute exe
path contains the substring "shims".
With this fix duplicate process detection is once again working
correctly.
This commit uses a more reliable Win32 API call to determine the scaling
factor / DPI of user monitors, so that the scale of a window can be
correctly adjusted when moved between monitors with different DPI
settings.
fix#622
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!
This commit builds on @EBNull's comment shedding light on the uses of
the -A and -W functions in the Win32 API, and standardizes the calling
of the -W functions across the project.
Since UTF-16 String handling is a bit lacking in the Rust standard
library, I have pulled in the widestring crate to use the
from_slice_truncate fn to automagically remove all of the trailing null
chars when handling values returned from the various Win32 -W fns.
Comment ref: https://github.com/LGUG2Z/komorebi/commit/657ac441ae3bc6c748908a6e88b9e1a37d411420#r135643553
This commit handles an edge case where the first registered display
monitor has an index preference that is greater than the current length
of the Ring data structure storing the monitors.
re #612
Thanks to @ids1024 for pointing out that the failing system calls were
likely due to optimizations being made with the release profile's
opt-level=3 and to @saethlin for pointing out that in the previous
commit I was returning a pointer to a temporary that was about to be
deallocated.
https://fosstodon.org/@ids1024/111627094548141620https://hachyderm.io/@saethlin/111627135615930244
With this commit, the display ids are now successfully returned from
calls to EnumDisplayDevicesA on release builds.
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
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.
This commit makes the --config flag on komorebi.exe optional, and
updates the configuration loading logic to try to find a komorebi.json
file in the HOME_DIR, which is either $Env:KOMOREBI_CONFIG_HOME or
$Env:PROFILE.
This unlocks the way for Amr's PR to make the --config flag optional on
the enable-autostart command.
re #596
After another round of deep diving to find a workaround to all of the
mechanisms within Windows that prevent a process from changing the
focused window, I came across this gist which I saw setting
SPI_SETFOREGROUNDLOCKTIMEOUT to 0:
https://gist.github.com/EBNull/1419093
This tentatively seems like it works and it removes the need for the
alt_focus_hack setting.
However, according to this StackOverflow discussion, it seems like on
Win10+ changes to ForegroundLockTimeout in the registry are no longer
respected and changes made via SPI_SETFOREGROUNDLOCKTIMEOUT are not
persisted:
https://stackoverflow.com/questions/73735129/setforegroundwindow-relationship-between-the-foregroundlocktimeout-registry-val
Therefore on starting, komorebi will now check the value with
SPI_GETFOREGROUNDLOCKTIMEOUT and if it is not 0, it will be set to 0.
Logging has been added to inform the user of the changes that are
happening.
This commit ensures that the required calls are made to the system to
enable and disable the Windows focus-follows-mouse implementation when
users make changes to the focus_follows_mouse option in the static
config file.
fix#603
- 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
This commit ensures that when a layout or a custom layout is not defined
for a workspace in the static configuration file, Workspace.tile will be
set to false. Thanks to M. Kichel on Discord for pointing out the need
for this!