A new System Tray widget has been added to komorebi-bar, bringing native
Windows system tray functionality directly into the bar.
Special thanks to the Zebar project and its contributors for developing
the systray-util crate library that makes Windows system tray
integration possible.
The widget intercepts system tray icon data by creating a hidden "spy"
window that mimics the Windows taskbar. When applications use the
Shell_NotifyIcon API to manage their tray icons, the widget receives the
same broadcast messages, allowing it to monitor all system tray activity
while forwarding messages to the real taskbar to avoid disruption.
Users can configure which icons to hide using flexible rules. A plain
string matches by exe name (case-insensitive). A structured object can
match on exe, tooltip, and/or GUID fields using AND logic. Each field
supports matching strategies from komorebi's window rules (Equals,
StartsWith, EndsWith, Contains, Regex, and their negated variants),
allowing precise filtering even when multiple icons share the same exe
and GUID. An info button opens a floating panel listing all icons with
their properties and copy buttons, making it easy to identify which
values to use in filter rules.
The widget fully supports mouse interactions including left-click,
right-click, middle-click, and double-click actions on tray icons.
Double-click support uses the LeftDoubleClick action from systray-util
0.2.0, which sends WM_LBUTTONDBLCLK and NIN_SELECT messages. It handles
right-aligned placement correctly by adjusting the rendering order and
toggle button arrow directions to maintain consistent visual appearance
regardless of which panel the widget is placed in.
Some system tray icons register a click callback but never actually
respond to click messages, effectively becoming "zombie" icons from an
interaction standpoint. The widget includes fallback commands for known
problematic icons that override the native click action with a direct
shell command (e.g. opening Windows Security or volume settings).
The implementation uses a background thread with its own tokio runtime
to handle the async systray events, communicating with the UI thread
through crossbeam channels. Icon images are cached efficiently using
hash-based keys that update when icons change. Rapid icon updates are
deduplicated to prevent UI freezing, and image conversion (RgbaImage to
ColorImage) is performed on the background thread to keep the UI
responsive.
The widget automatically detects and removes stale icons whose owning
process has exited, using the Win32 IsWindow API on a configurable
interval. A manual refresh button is also available for immediate
cleanup.
A shortcuts button can be configured to toggle komorebi-shortcuts by
killing the process if running or starting it otherwise. The refresh,
info, and shortcuts buttons can each be placed in the main visible area
or in the overflow section.
I was getting really tired of having to switch between display inputs to
different platform-specific machines to be able to make and test changes
on komorebi for Windows and komorebi for Mac.
With this commit, the `flake.nix` provides a Nix devShell and crane
build for users to make and validate changes with `cargo check`, `cargo
clippy` and `cargo build` with the Windows MSVC toolchain on Linux and
macOS.
This commit makes it possible to send commands from the bar by using the
mouse/touchpad/touchscreen.
Komorebi or custom commands can be sent by clicking on the mouse's
primary, secondary, middle, back or forward buttons.
As the primary single click is already used by widgets, only primary
double clicks can send commands. This limitation is due to Egui also
triggering 2 single clicks before a double click is triggered. Egui does
not have an implementation for stopping event propagation out of the box
and would be too much work to include.
Similarly, commands can be sent on every "tick" of mouse scrolling,
touchpad or touchscreen swiping in any of the 4 directions. This "tick"
can be adjusted to fit user's preference.
This is due to the fact, that Egui does not have an event for when a
mouse "tick" occurs. It instead gives a number of points that the user
scrolled/swiped on each frame.
PR: #1403
This commit adds a simple egui helper application which shows a list of
shortcuts defined in a user's whkdrc file. Parsing AHK files is not
supported.
In addition to listing out shortcuts defined in the whkdrc file, the top
line allows users to add filter a filter to narrow down the list of
commands and key bindings to the ones they are interested in.
A new komorebic command "toggle-shortcuts" has been introduced which
will first attempt to kill "komorebi-shortcuts.exe", and then exit if
the kill signal was successful (ie. a process was closed), or proceed to
open "komorebi-shortcuts.exe" if the kill signal was not successful (ie.
no process was closed, so we should open one).
"komorebi-shortcuts.exe" has been added as a floating application in
lib.rs to allow for users to use the "komorebic move" command to
manipulate its position via their existing keyboard bindings.
This commit improves path handling for commands and icons in the new
Application widget by making use of PathExt::replace_env when loading
the user-specified ApplicationsConfig.
Crucially for scoop users, this means that user-agnostic references to
scoop apps can now be made like this:
```
$Env:USERPROFILE/scoop/apps/zed-nightly/current/zed.exe
```
When attempting to look up an icon for a command, we now split the
command on ".exe", and if this is a complete path to a file, we try to
use it to extract an icon, otherwise we try to resolve a complete path
using "which" before doing the same.
This commit imports an older revision of my fork of windows-icons to
call when attempting to look up the icon of an application by it's
process id. This needs to be cleaned up before the next release.
This commit integrates the excellent investigation and work done by
@davor-skontra on the windows-icons repo to enable the retrieval of UWP
applications, including all those annoying Microsoft applications which
all share the ApplicationFrameHost.exe executable and the
ApplicationFrameWindow class.
Since these applications share the same executable, the icon cache in
komorei-bar has been updated to use the window hwnd as a key intead of
the window executable.
resolve#1226
This commit adds a little Easter egg on the time widget.
Use the `changing_icon` setting to enable this feature.
Based on the current time, the widget will use different icons to
indicate certain activities of the day.
00:00 MOON
06:00 ALARM
06:01 BREAD
06:30 BARBELL
08:00 COFFEE
08:30 CLOCK
12:00 HAMBURGER
12:30 CLOCK_AFTERNOON
18:00 FORK_KNIFE
18:30 MOON_STARS
This commit adds the timezone on the time and date widgets as a new
setting.
In case the timezone is invalid, the output is replaced with an error
message.
Use a custom format to display additional information.
resolve#1312
This commit makes all schemars::JsonSchema derives optional. After
analyzing the output of cargo build timings and llvm-lines, it was clear
that the majority of the 2m+ incremental dev build times was taken up by
codegen, and the majority of it by schemars.
Developers can now run cargo commands with --no-default-features to
disable schemars::JsonSchema codegen, and all justfile commands have
been updated to take this flag by default, with the exception of the
jsonschema target, which will compile with all derives required to
export the various jsonschema files.
Incremental dev build times for komorebi.exe on my machine are now at
around ~18s, while clean dev build times for the entire workspace are at
around ~1m.
This commit adds a new widget, "Update", which will check for komorebi
version updates using the cargo package version of the running binary
and the latest release returned from the GitHub API.
If the latest release is newer than the current cargo package version, a
widget will be shown, which can be clicked to open the changelog of the
latest release.
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.
This commit ensures that the komorebi-bar.exe process is DPI aware and
applies DPI compensation to viewport.position and viewport.inner size
both on launch and on configuration reload. viewport.position changes
are now hotloaded wihtout having to restart the process.
re #1024
This commit adds a --quickstart flag to the komorebi-bar binary to
output an example komorebi.bar.json into the user's desired
configuration directory.
This is to avoid the case where running komorebic quickstart would
result in clobbering an existing komorebi.json file.
Additionally, if a user tries to run the bar for the first time without
a configuration file, the example configuration will be written to disk
for them.
Finally support for loading a komorebi.bar.yaml file has been removed
because I have no desire to support multiple configuration formats over
the long term.
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 abstracts the theme-related code from komorebi-bar into a
separate library which is now also consumed by komorebi.
The static configuration file for komorebi has been updated to allow
users to specify themes and provide palette overrides for various border
styles and stackbar configuration options.
In the event that both a theme and border-specific and/or
stackbar-specific colours have been specified, the theme will take
priority to make it as easy as possible for users who have already spent
time tweaking their colours to try out themes and quickly revert back if
they prefer their existing colours.
This change makes it easier for users to have unified themes between
komorebi and the komorebi status bar.
This commit adds an initial version of the komorebi status bar.
At this point the bar is still considered "alpha" and the configuration
format may see some small breaking changes based on usage and feedback.
There is an accompanying video series which details the creation of this
bar on YouTube: https://www.youtube.com/watch?v=x2Z5-K05bHs
Some high level notes on the bar:
* An external application which exclusively consumes komorebi_client's
public API surface - anyone can create this without hacking directly
on komorebi's internals
* Generally a very simple bar with limited configuration options - users
who want more configurability should use alternatives such as yasb or
zebar
* Scope is deliberately limited to provide a tighter, more focused
experience: Windows-only, komorebi-only, single-monitor-only,
horizontal-only
* No support for custom widgets or templating
* Colours are controlled exclusively through themes which adhere to a
palette framework such as Base16 or Catppuccin (and possibly others in
the future)
This commit contains all of the commits listed:
e5fa03c33c
feat(bar): initial commit
b3990590f3
feat(bar): add config struct with basic opts
bc2f4a172e
feat(bar): handle komorebi restarts gracefully
ca6bf69ac7
feat(bar): add basic widget config opts
18358efed8
feat(bar): add interactive layout and media widgets
92bb9f680b
perf(bar): use explicit redraw and data refresh strategies
8e74e97706
feat(bar): add battery and network widgets
fdc7706d23
feat(bar): add custom font loader
025162769b
feat(bar): allow right side widget ordering
a1688691cf
feat(bar): add app icon next to focused window title
9f78739c3f
feat(bar): add komorebi widget (+config) and themes
a4ef85859e
feat(bar): use phosphor icons for uniformity
e99138a97e
feat(bar): add first pass at configuration loader
d6ccf4cf9a
feat(bar): add logging and config hotwatch
34d2431947
feat(bar): handle monocle containers in komorebi widget
7907dfeb79
feat(bar): add optional data refresh intervals to config
96a9cb320e
feat(bar): add flag to list system fonts
42b7a13693
feat(bar): add activity to network widget
ac38f52407
feat(bar): to_pretty_bytes on network activity
6803ffd741
feat(bar): configurable network activity fill char len
7d7a5d758d99808cd2b81da2b3ddbb11c52aa92f
ci(github): add bar to wix and goreleaser configs
da307e36fc1faf84ecca3f91811fdd15f70ef2ff
feat(bar): expand theme sources
c580ff7899889309dfa849ad4fb05b80b6af8d9b
feat(bar): add accent config for themes
bc4dabda4a941c0c9764fae2c8d11abbfdc0a9f5
feat(bar): add accents to widget emojis
a574837529dd6c5add73edf394c1c9c2e6cc6315
feat(bar): add to hard-coded float identifiers
ff41b552613f911e56b1790e68389525ee7e603c
chore(deps): bump base16-egui-themes