Commit Graph

59 Commits

Author SHA1 Message Date
1337cookie
c84fa50fc9 fear(bar): add storage_display_name option 2026-03-22 16:11:43 -07:00
Csaba
ea35d818a1 feat(bar): windows systray widget
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.
2026-03-21 12:35:39 -07:00
Csaba
c165172b5a feat(cli): new layout-ratios command
The implementation adds a new layout-ratio CLI command to komorebi that
allows users to dynamically set column and row ratios for layouts at
runtime via komorebic layout-ratio --columns 0.3 0.4 --rows 0.5.

A public validate_ratios function was added to komorebi-layouts that
clamps ratio values between 0.1 and 0.9, truncates when the cumulative
sum would reach or exceed 1.0, and limits to a maximum of 5 ratios. This
function is shared between config file deserialization and the new CLI
command, ensuring consistent validation behavior.

The SocketMessage enum in komorebi/src/core/mod.rs has a new
LayoutRatios variant. The handler in process_command.rs uses the shared
validate_ratios function to process the ratios before applying them to
the focused workspace's layout options.

When the CLI command is called without any arguments, it prints a
helpful message instead of returning an error.
2026-02-13 11:24:57 -08:00
Csaba
9977cca500 feat(bar): enhancing the media widget
The Media widget has been enhanced with a new MediaDisplayFormat
configuration option that controls how the widget is displayed. It
supports seven formats: Icon, Text, IconAndText (the default),
ControlsOnly, IconAndControls, TextAndControls, and Full.

The widget now detects whether the Previous and Next buttons are
actually available for the current media session using the Windows Media
Control API. When a button is not available, it appears dimmed at 50
percent opacity and clicking it has no effect.

Tooltips were added to improve usability. Hovering over the media info
label shows the full artist and title text, which is helpful when the
text is truncated. The Play/Pause button also shows the media info on
hover.

The rendering logic was refactored to properly handle right-aligned
widgets.

When the Media widget is placed in right_widgets, the UI renders items
from right to left, so the code now renders elements in reverse order to
ensure the visual appearance remains consistent regardless of which
panel the widget is placed in.
2026-02-12 20:39:16 -08:00
Csaba
22e8a79833 feat(wm): add layout_options with ratios support
Added customizable split ratios for layouts via layout_options
configuration. Users can now specify column_ratios and row_ratios arrays
to control window sizing in various layouts.

Ratios are validated at config load time: values are clamped between 0.1
and 0.9 to prevent zero-sized windows, and arrays are automatically
truncated when their cumulative sum would reach or exceed 1.0. This
ensures there's always remaining space for additional windows.

Ratio support varies by layout:

- Columns and Rows layouts use the full arrays for each column/row width
  or height
- VerticalStack, RightMainVerticalStack, and HorizontalStack use the
  first ratio for the primary split and the remaining ratios for stack
  windows
- BSP uses the first value from each array for horizontal and vertical
  splits respectively
- Grid only supports column_ratios since row counts vary dynamically.
- UltrawideVerticalStack uses the first two column ratios for center and
  left columns.

All ratio-related values are now defined as constants in
default_layout.rs: MAX_RATIOS (5), MIN_RATIO (0.1), MAX_RATIO (0.9),
DEFAULT_RATIO (0.5), and DEFAULT_SECONDARY_RATIO (0.25 for
UltrawideVerticalStack).
2026-02-07 15:27:48 -08:00
LGUG2Z
6cef8d9ef6 refactor(schema): simplify defaults in static_config 2025-12-31 13:04:34 -08:00
LGUG2Z
0758c7d900 refactor(theme): centralize theme-related code in komorebi-themes
Getting tired of making little changes in both this and the komorebi for
Mac repo - I think eventually either komorebi-themes will live in its
own repo or komorebi for Mac will be integrated here.

But for now, at least everything is defined in komorebi-themes and I
don't have to redefine any theme-related stuff in komorebi for Mac.
2025-12-27 21:58:39 -08:00
LGUG2Z
f77a303b30 docs(schema): ensure every enum variant has a renderable title 2025-12-27 20:34:31 -08:00
LGUG2Z
3a81f7babb docs(schema): ensure all public-facing bar config opts have docstrings 2025-12-27 13:40:45 -08:00
LGUG2Z
3d8778a7d6 docs(schema): ensure all public-facing static config opts have docstrings 2025-12-27 12:58:46 -08:00
LGUG2Z
a42e809ade docs(config): encode defaults of unwrapped options into schema
This commit ensures that the various default values that the different
Option<T> config properties can be unwrapped to are encoded by schemars
so that they can be picked up by docgen.
2025-12-26 18:16:55 -08:00
LGUG2Z
c91224295f docs(schema): avoid duplicating display format enums in bar 2025-12-22 19:30:29 -08:00
LGUG2Z
4b1e3bd448 docs(schema): add deprecations and improve formatting 2025-12-21 21:56:17 -08:00
LGUG2Z
1cb8ed7f10 chore(deps): bump schemars to 1.1 2025-12-21 16:26:25 -08:00
LGUG2Z
ff4187aecf chore(dev): begin v0.1.40-dev 2025-12-14 14:07:44 -08:00
LGUG2Z
ac67c41377 docs(schema): update jsonschema 2025-11-23 10:56:01 -08:00
LGUG2Z
e07b464b0d chore(dev): begin 0.1.39-dev 2025-09-20 12:59:09 -07:00
LGUG2Z
78177af6b8 docs(mkdocs): run docgen, depgen and jsonschema targets 2025-09-09 08:56:29 -07:00
omark96
59c3c14731 feat(config): add work-area-offset per workspace
This commit adds the option to set 'work_area_offset' per workspace. If
no workspace work area offset is set for that workspace it will instead
use the value of the globals.work_area_offset for that workspace.

This commit adds a command to set the work area offset of a workspace
given a monitor index and a workspace index.
2025-08-27 18:05:07 -07:00
LGUG2Z
3d373b3630 fix(schema): flatten bar mouse config opts 2025-05-26 09:52:14 -07:00
LGUG2Z
b4e61b079c feat(wm): add scrolling layout
This commit adds a new DefaultLayout::Scrolling variant, along with a
new LayoutOptions configuration which will initially be used to allow
the user to declaratively specify the number of visible columns for the
Scrolling layout, and a new komorebic "scrolling-layout-columns" command
to allow the user to modify this value for the focused workspace at
runtime.

The Scrolling layout is inspired by the Niri scrolling window manager,
presenting a workspace as an infinite scrollable horizontal strip with a
viewport which includes the focused window + N other windows in columns.
There is no support for splitting columns into multiple rows.

This layout can currently only be applied to single-monitor setups as
the scrolling would result in layout calculations which push the windows
in the columns moving out of the viewport onto adjacent monitors.

This implementation in the current state is enough to be useable for me
personally, but if others want to iterate on this, make it handle
hiding/restoring windows correctly when scrolling the viewport so that
adjacent monitors don't get impacted etc., patches are always welcome.

resolve #1434
2025-05-17 21:12:51 -07:00
LGUG2Z
3feff1dca9 docs(schema): update jsonschema and docgen 2025-05-15 18:28:27 -07:00
Csaba
3d8f68e559 feat(bar): send commands by mouse/touchpad/screen
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
2025-05-10 15:19:24 -07:00
Alisher Galiev
10424b696f feat(bar): add applications widget
This pull request introduces a new Applications widget that displays a
user-defined list of application launchers in the UI. Each app entry
supports an icon, a label, and executes its configured command on click.

The design of this widget is inspired by the Applications Widget of YASB
Reborn. I personally missed this functionality and aimed to bring a
similar experience to komorebi-bar.

Further information is in the text of PR #1415
2025-04-27 11:45:06 -07:00
alex-ds13
3ee3aac806 feat(wm): float placement configs
This commit adds a few more options to combine with the
`FloatingLayerBehaviour` which determine placement in different
situations:

- `"toggle_float_placement"`: the placement to be used by a floating
  window when it is forced to float with the `toggle-float` command.
- `"floating_layer_placement"`: the placement to be used by a floating
  window when it is spawned on the floating layer and the user has the
  floating layer behaviour set to float.
- `"floating_override_placement"`: the placement to be used by a window
  that is spawned when float override is active.
- `"float_rule_placement"`: the placement to be used by a window that
  matches a 'floating_applications' rule.

Each `Placement` can be one of the following types:

- "None": windows are spawned wherever Windows positions them with
  whatever size they had. Komorebi does not change its size or position.
- "Center": windows are centered without changing their size.
- "CenterAndResize": windows are centered and resized according to the
defined aspect ratio.

By default the placements are as follows:
- `"toggle_float_placement"`: `"CenterAndResize"`
- `"floating_layer_placement"`: `"Center"`
- `"floating_override_placement"`: `"None"`
- `"float_rule_placement"`: `"None"`

This commit also adds the `floating_layer_behaviour` as a global config.
2025-04-20 10:25:57 -07:00
Csaba
f4bbee0a2e feat(bar): auto select/hide widget based on value
This commit adds new settings to some widgets that allows to auto
select/hide them based on their current values.

The cpu/memory/network/storage widgets get a setting that auto selects
the widget if the current value/percentage is over a value.

The battery widget gets a setting that auto selects the widget if the
current percentage is under a value.

The storage widget gets a setting that auto hides the disk widget if the
percentage is under a value.

Also added 2 new settings (auto_select_fill and auto_select_text) to the
theme, in order to select the fill and text colors of an auto selected
widget.

(Easter egg: the network icons change if the value is over the limit)

PR: #1353
2025-04-03 07:42:27 -07:00
LGUG2Z
b4b400b236 feat(themes): add custom base16 theme variant
This commit adds a custom Base16 theme variant and plumbs it throughout
the komorebi and komorebi-bar packages.
2025-04-02 13:23:31 -07:00
Csaba
d38d3c956d feat(bar): add locked container widget, use accent colour for icons
This commit adds a new komorebi widget to indicate whether or not the
focused container is locked.

This commit also includes an icon colour change on the layer and layout
widgets to the accent colour.

The commit also renames the locked_window widget to locked_container as
it is more suitable.

PR: #1394
2025-04-02 13:23:02 -07:00
LGUG2Z
a98968d179 feat(config): add floating ws layer behaviour opt
This commit adds a new option to the WorkspaceConfig object,
floating_layer_behaviour, which allows the user to either set
FloatingLayerBehaviour::Tile or FloatingLayerBehaviour::Float. Although

I prefer Float as a default, there was a good enough argument to make
Tile the default based on the fact that the Floating layer is
automatically engaged based on the focused window, and previously when
the focused window was a floating window, new windows would be tiled
unless they matched floating rules.
2025-03-28 16:38:00 -07:00
Csaba
acf780767c feat(bar): add changing icons based on the time
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
2025-03-09 11:48:46 -07:00
Csaba
81a7951312 feat(bar): added timezone to time and date widgets
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
2025-03-07 16:28:45 -08:00
Csaba
a837fea40c feat(bar): add icons to workspace-layer widget
This commits adds the ability to set icons for the `workspace-layer` with
the `DisplayFormat` and a setting to specify if it should `show_when_tiling`
or not.

collab with @alex-ds13
2025-03-03 08:13:29 -08:00
Csaba
d69dfeb715 feat(bar): add opts to show all icons on workspace widget
This commit adds 3 new display options on the komorebi workspace widget
to show all icons.
2025-02-24 08:12:07 -08:00
LGUG2Z
9d41a293f6 feat(wm): add tiling and floating ws layers
This commit introduces an implementation of workspace layers to
komorebi.

Workspace layers change the kinds of windows that certain commands
operate on. This implementation features two variants,
WorkspaceLayer::Tiling and WorkspaceLayer::Floating.

The default behaviour until now has been WorkspaceLayer::Tiling.

When the user sets WorkspaceLayer::Floating, either through the
'toggle-workspace-layer' command or the new bar widget, the 'move',
'focus', 'cycle-focus' and 'resize-axis' commands will operate on
floating windows, if the currently focused window is a floating window.

As I don't have 'cycle-focus' bound to anything, 'focus up' and 'focus
down' double as incrementing and decrementing cycle focus commands,
iterating focus through the floating windows assigned to a workspace.

Floating windows in komorebi belong to specific workspaces, therefore
commands such as 'move' and 'resize-axis' will restrict movement and
resizing to the bounds of their workspace's work area (or more
accurately, the work area of the monitor that the workspace belongs to,
as floating windows are never constrained by workspace-specific work
area restrictions).
2025-02-22 15:57:22 -08:00
LGUG2Z
c903cdbb75 chore(dev): begin v0.1.35-dev 2025-02-20 19:31:27 -08:00
David
2d2b6e5c15 feat(bar): add keyboard language widget
This commit is a squashed commit containing the below commits from
PR #1266, which introduces a new "Keyboard" widget, which is used to
display information about the user's currently selected keyboard input
language. This new widget has a data refresh interval of 1 second if not
specified by the user.

721d2ef408
58373cd26c
ce27a76b36
fb9054a18b
55cc2fd889
461a73833e
781b8d0bd0
fa6bf6ff76
2025-02-07 20:57:46 -08:00
DhanushAdithiya
bbd232f649 fix(docs): update base16 gallery link 2025-02-05 13:13:49 -08:00
Samu-K
cfd89c274c feat(bar): add modifiers for strftime integer formatters
Added the ability of use modifiers with custom format on the Date widget.

For example if using %U returns 04, you can add a modifier so that bar
date widget shows 05.
2025-01-24 10:41:48 -08:00
LGUG2Z
473e7cd6a0 feat(config): add aspect ratios for float toggling
This commit adds a new configuration option
"floating_window_aspect_ratio", which users can manipulate to set their
desired window size when using the toggle-float command.

resolve #1230
2025-01-24 10:41:45 -08:00
alex-ds13
3e1fc6123a fix(bar): simplify komorebi-bar config
This interactively rebased commit is comprised of the subsequent
individual commits listed further below.

At a high level:

- work_area_offset is now automatically calculated by default
- monitor can now take an index in addition to the previous object
- position can largely be replaced by margin and padding for bars that
  are positioned at the top of the screen
- frame can now largely be replaced by margin and padding for bars that
  are positioned at the top of the screen
- height is now a more intuitive configuration option for setting the
  height of the bar

Detailed explainations and examples are included in the body of PR #1224
on GitHub: https://github.com/LGUG2Z/komorebi/pull/1224

fix(bar): add simplified config for bar

This commit creates a few new config options for the bar that should
make it a lot simpler for new users to configure the bar.

- Remove the need for `position`: if a position is given the bar will
  still use it with priority over the new config. Instead of position
  you can now use the following:
  - `height`: defines the height of the bar (50 by default)
  - `horizontal_margin`: defines the left and right offset of the bar, it
  is the same as setting a `position.start.x` and then remove the same
  amount on `position.end.x`.
  - `vertical_margin`: defines the top and bottom offset of the bar, it is
  the same as setting a `position.start.y` and then add a correct amount
  on the `work_area_offset`.

- Remove the need for `frame`: some new configs were added that take
  priority over the old `frame`. These are:
  - `horizontal_padding`: defines the left and right padding of the bar.
    Similar to `frame.inner_margin.x`.
  - `vertical_padding`: defines the top and bottom padding of the bar.
    Similar to `frame.inner_margin.y`.

- Remove the need for `work_area_offset`: if a `work_area_offset` is
  given then it will take priority, if not, then it will calculate the
  necessary `work_area_offset` using the bar height, position and
  horizontal and vertical margins.

feat(bar): set margin/padding as one or two values

This commit changes the `horizontal_margin`, `vertical_margin`,
`horizontal_padding` and `vertical_padding` to now take a
`SpacingAxisConfig` which can take a single value or two values.

For example, you can set the vertical margin of the bar to add some
spacing above and below like this:

```json
"vertical_margin": 10
```

Which will add a spacing of 10 above and below the bar. Or you can set
it like this:

```json
"vertical_margin": [10, 0]
```

Which will add a spacing of 10 above the bar but no spacing below. You
can even set something like this:

```json
"vertical_margin": [0, -10]
```

To make no spacing above and a negative spacing below to make it so the
tiled windows show right next to the bar. This will basically be
removing the workspace and container padding between the tiled windows
and the bar.

fix(bar): use a right_to_left layout on right side

This commit changes the right area with the right widgets to have a
different layout that is still right_to_left as previously but behaves
much better in regards to its height.

fix(bar): use default bar height

When there is no `work_area_offset` and no `height` on the config it was
using the `BAR_HEIGHT` as default, however the automatica
work_area_offset calculation wasn't being done properly. Now it is!

feat(bar): monitor can be `MonitorConfig` or index

This commit allows the `"monitor":` config to take a `MonitorConfig`
object like it used to or simply a number (index).

docs(schema): update all json schemas

fix(bar): update example bar config

fix(bar): correct work_area_offset on secondary monitors

feat(bar): add multiple options for margin/padding

This commit removes the previous `horizontal_margin`, `vertical_margin`,
`horizontal_padding` and `vertical_padding`, replacing them all with
just `margin` and `padding`.

These new options can be set either with a single value that sets that
spacing on all sides, with an object specifying each individual side or
with an object specifying some "vertical" and/or "horizontal" spacing
which can have a single value, resulting on a symmetric spacing for that
specific axis or two values to define each side of the axis individually.
2025-01-22 18:57:32 -08:00
Csaba
a069db611f feat(bar): binary clock and no-second time formats 2025-01-11 15:11:20 -08:00
Csaba
b1db417df5 feat(bar): opt to hide battery widget when charged 2025-01-09 15:49:51 -08:00
LGUG2Z
3aa92a1255 feat(bar): add update widget
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.
2025-01-04 21:14:33 -08:00
LGUG2Z
c063302c91 feat(cli): add stackbar-mode command
This commit adds a new komorebic command "stackbar-mode" to allow users
to change stackbar modes programmatically.
2025-01-04 21:14:33 -08:00
LGUG2Z
79eda30f48 feat(config): add matchers for removing titlebars
This commit adds a new field to the static config file, "remove_titlebar_applications", which allows
users to now use the full range of matching strategies to identify applications for which titlebars
should be removed. This is heavily discouraged for a number of reasons, and is unlikely to work with
a wide range of applications which now draw their own titlebar regions. The previous advice to use
in-application configuration settings to hide title bars if they exist is still valid.

resolve #805
2024-12-27 11:37:00 -08:00
LGUG2Z
5dbf0f1b89 docs(schema): update all json schemas 2024-12-17 19:38:30 -08:00
LGUG2Z
53c1990442 docs(schema): update all json schemas 2024-12-09 17:04:18 -08:00
LGUG2Z
4f306e5bfd docs(schema): update all json schemas 2024-12-07 16:43:28 -08:00
LGUG2Z
779c12bc6a docs(schema): update all json schemas 2024-11-19 19:52:33 -08:00
LGUG2Z
374cd2c6d5 feat(wm): switch to asc v2 json format
This commit switches all relevant commands to treat the v2
applications.json asc format as the default format in all commands.

The v1 applications.yaml file will still be processed correctly if
passed.
2024-11-01 19:43:04 -07:00