Originally created by @tsukasa on GitHub (Feb 23, 2025).
Summary
With the recent motherlode of changes related to monitor handling, a somewhat troubling behaviour has found its way into Komorebi.
When starting Komorebi via komorebic start with just one monitor connected, the output of komorebic monitor-info is as expected and presents the proper monitor data:
The "null" monitor causes windows to be sent to invalid coordinates. The only way to workaround this is by restarting komorebi completely.
When observing komorebic log, the reconciliator clearly finds the monitor based on the ID DELA0A2-5&2da744da&0&UID184854 (ID of the monitor being connected):
2025-02-23T18:09:05.797124Z INFO komorebi::monitor_reconciliator: monitor count mismatch (1 vs 2), adding connected monitors
2025-02-23T18:09:05.798173Z INFO komorebi::monitor_reconciliator: found monitor and workspace configuration for DELA0A2-5&2da744da&0&UID184854 in the monitor cache, applying
2025-02-23T18:09:05.798502Z INFO focus_monitor{idx=0}: komorebi::window_manager: focusing monitor
2025-02-23T18:09:05.799488Z INFO focus_workspace{idx=0}: komorebi::window_manager: focusing workspace
2025-02-23T18:09:05.799745Z INFO focus_workspace{idx=0}:focus_workspace{idx=0}: komorebi::monitor: focusing workspace
2025-02-23T18:09:05.804310Z INFO focus_workspace{idx=0}:focus_window{idx=0}: komorebi::container: focusing window
2025-02-23T18:09:05.807339Z INFO focus_workspace{idx=0}:update_focused_workspace{follow_focus=false trigger_focus=true}: komorebi::window_manager: updating
2025-02-23T18:09:05.809423Z WARN komorebi: removing stale subscription: komorebi-bar-siliconized
This is a most annoying behaviour that potentially causes data loss because applications being sent to the other monitor end up in purgatory and have to be closed through the task manager.
When all displays are already connected before starting Komorebi, komorebic monitor-info resolves them properly and the application works as expected:
However, this should not be considered an acceptable workaround, because it is wholly unclear when the cache might expires and a user runs into the issue again.
Version Information
OS Version
OS Name: Microsoft Windows 10 Pro
OS Version: 10.0.19045 N/A Build 19045
komorebi.json{"$schema":"https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/heads/master/schema.json","animation":{"duration":250,"enabled":true,"fps":60,"style":"EaseInQuad"},"app_specific_configuration_path":"$Env:KOMOREBI_CONFIG_HOME/applications.json","bar_configurations":["$Env:KOMOREBI_CONFIG_HOME/komorebi.bar.monitor00.json","$Env:KOMOREBI_CONFIG_HOME/komorebi.bar.monitor01.json"],"border":false,"border_implementation":"Komorebi","border_offset":-1,"border_style":"System","border_width":5,"cross_boundary_behaviour":"Monitor","cross_monitor_move_behaviour":"Insert","default_container_padding":3,"default_workspace_padding":3,// Get the informations via "komorebic monitor-information"
// Be sure to check the "left" property to see which one is which...
"display_index_preferences":{"0":"DELA0A2-5&2da744da&0&UID184852","1":"DELA0A2-5&2da744da&0&UID184854"},"float_override":false,"floating_applications":[// Borderless Gaming
{"id":"BorderlessGaming.exe","kind":"Exe","matching_strategy":"Equals"},// Crates.app Media Player
{"id":"Crates.exe","kind":"Exe","matching_strategy":"Equals"},// Directory Opus
{"id":"dopus.exe","kind":"Exe","matching_strategy":"Equals"},// Dwarf Fortress
{"id":"Dwarf Fortress.exe","kind":"Exe","matching_strategy":"Equals"},// eM Client
{"id":"MailClient.exe","kind":"Exe","matching_strategy":"Equals"},// mpv
{"id":"mpv","kind":"Class","matching_strategy":"Equals"},// OBS Studio
{"id":"obs64.exe","kind":"Exe","matching_strategy":"Equals"},// Wavebox
{"id":"Wavebox.exe","kind":"Exe","matching_strategy":"Equals"}],"ignore_rules":[// AltSnap
{"id":"AltSnap.exe","kind":"Exe","matching_strategy":"Equals"},// Animal Well
{"id":"Animal Well.exe","kind":"Exe","matching_strategy":"Equals"},// AutoHotkey
{"id":"AutoHotkey.exe","kind":"Exe","matching_strategy":"Equals"},{"id":"AutoHotkey32.exe","kind":"Exe","matching_strategy":"Equals"},{"id":"AutoHotkey64.exe","kind":"Exe","matching_strategy":"Equals"},// Citrix Workspace
{"id":"Citrix.DesktopViewer.App.exe","kind":"Exe","matching_strategy":"Equals"},{"id":"PrimaryAuthModule.exe","kind":"Exe","matching_strategy":"Equals"},// Clock64
{"id":"ClockFlyoutWindow","kind":"Class","matching_strategy":"Equals"},// DSXv2
{"id":"DSX.exe","kind":"Exe","matching_strategy":"Equals"},// Environmental Station Alpha
{"id":"Environmental Station Alpha.exe","kind":"Exe","matching_strategy":"Equals"},// Enshrouded
{"id":"enshrouded.exe","kind":"Exe","matching_strategy":"Equals"},// Final Fantasy XIV
{"id":"FFXIVGAME","kind":"Class","matching_strategy":"Equals"},// GoXLR App and Control Panel
{"id":"GoXLR App.exe","kind":"Exe","matching_strategy":"Equals"},{"id":"GoXLRAudioCplApp.exe","kind":"Exe","matching_strategy":"Equals"},// UUU (IGCSClient)
{"id":"IGCSClient.exe","kind":"Exe","matching_strategy":"Equals"},// tacky-borders
{"id":"tacky-borders.exe","kind":"Exe","matching_strategy":"Equals"},// Tray Runner
{"id":"TrayRunner.exe","kind":"Exe","matching_strategy":"Equals"},// TurboLaunch
{"id":"TurboLaunch.exe","kind":"Exe","matching_strategy":"Equals"},// Qt messages
{"id":"Qt\\d+QWindowIcon","kind":"Class","matching_strategy":"Regex"},// XIVLauncher
{"id":"XIVLauncher.exe","kind":"Exe","matching_strategy":"Equals"}],"manage_rules":[// Grabber
[{"id":"Grabber.exe","kind":"Exe","matching_strategy":"Equals"},{"id":"Qt\\d+QWindowIcon","kind":"Class","matching_strategy":"Regex"}],// mpv
[{"id":"mpv.exe","kind":"Exe","matching_strategy":"Equals"},{"id":"mpv","kind":"Class","matching_strategy":"Equals"}],// Qutebrowser
[{"id":"qutebrowser.exe","kind":"Exe","matching_strategy":"Equals"},{"id":"Qt\\d+QWindowIcon","kind":"Class","matching_strategy":"Regex"}]],"object_name_change_applications":[// Directory Opus
{"id":"dopus.exe","kind":"Exe","matching_strategy":"Equals"},// Wavebox
{"id":"Wavebox.exe","kind":"Exe","matching_strategy":"Equals"}],"tray_and_multi_window_applications":[// eM Client
{"id":"MailClient.exe","kind":"Exe","matching_strategy":"Equals"},// Vivaldi
{"id":"vivaldi.exe","kind":"Exe","matching_strategy":"Equals"},// Wavebox
{"id":"Wavebox.exe","kind":"Exe","matching_strategy":"Equals"}],"monitors":[{"workspaces":[{"name":"【一】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Create","float_override":true},{"name":"【二】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Create","float_override":true,"initial_workspace_rules":[{"id":"steam.exe","kind":"Exe","matching_strategy":"Equals"}]},{"name":"【三】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Create","float_override":false,},{"name":"【四】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Append","float_override":false,"initial_workspace_rules":[// Grabber
[{"id":"Grabber.exe","kind":"Exe","matching_strategy":"Equals"},{"id":"Qt\\d+QWindowIcon","kind":"Class","matching_strategy":"Regex"}]]},{"name":"【五】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Append","float_override":false,"initial_workspace_rules":[// Vivaldi
{"id":"vivaldi.exe","kind":"Exe","matching_strategy":"Equals"}]},{"name":"【六】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Append","float_override":false,"initial_workspace_rules":[// Visual Studio Code
{"id":"Code.exe","kind":"Exe","matching_strategy":"Equals"}]}]},{"workspaces":[{"name":"【一】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Create","float_override":true},{"name":"【二】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Create","float_override":true},{"name":"【三】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Create","float_override":false},{"name":"【四】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Create","float_override":false},{"name":"【五】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Create","float_override":false},{"name":"【六】","layout":"VerticalStack","apply_window_based_work_area_offset":true,"window_container_behaviour":"Create","float_override":false}]}],// Without m_f_f, switching workspaces happens on the monitor where the mouse is.
"mouse_follows_focus":true,"resize_delta":50,"slow_application_compensation_time":100,// Disable stackbar by setting "mode" to "Never".
// komorebi-bar shows the members of the stack in the bar.
"stackbar":{"height":24,"label":"Title","mode":"Never","tabs":{"font_family":"MonoLisa Variable","font_size":16,"width":200}},"theme":{"palette":"Catppuccin","name":"Mocha","bar_accent":"Peach","floating_border":"Blue","monocle_border":"Red","single_border":"Peach","stack_border":"Green","stackbar_background":"Crust","stackbar_focused_text":"Peach","stackbar_unfocused_text":"Overlay1","unfocused_border":"Mantle"},"transparency":false,"transparency_alpha":230,"unmanaged_window_operation_behaviour":"Op",// Automatically stack group new windows onto the existing window.
"window_container_behaviour":"Append","window_hiding_behaviour":"Cloak"}komorebi.bar.monitor00.json{"$schema":"https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/heads/master/schema.bar.json","monitor":{"index":0,"work_area_offset":{"left":0,// Would be 32 without AppBar registration!
"top":0,"right":0,// Would be 32 without AppBar registration!
"bottom":0}},"position":{"start":{"x":0,"y":0},"end":{"x":1920,"y":32}},"font_family":"MonoLisa Variable Regular","font_size":13,"max_label_width":350,"theme":{"palette":"Catppuccin","name":"Mocha","accent":"Peach"},"transparency_alpha":225,"left_widgets":[{"Komorebi":{"workspaces":{"enable":true,"display":"Text","hide_empty_workspaces":false},"layout":{"enable":true,"display":"Icon","options":["BSP","VerticalStack","RightMainVerticalStack","HorizontalStack","Columns","Rows"]},"workspace_layer":{"enable":true,"show_icon":true,"display":"IconAndText"},"focused_window":{"enable":true,"show_icon":true,"display":"IconAndText"}}}],"center_widgets":[],"right_widgets":[{"Media":{"enable":true}},{"Storage":{"enable":false}},{"Cpu":{"enable":false,"data_refresh_interval":5}},{"Memory":{"enable":false}},{"Network":{"enable":false,"show_total_data_transmitted":true,"show_network_activity":true}},{"Date":{"enable":true,"format":{"Custom":"%a, %Y-%m-%d"}}},{"Time":{"enable":true,"format":{"Custom":"%H:%M:%S"}}},{"Battery":{"enable":false}}]}komorebi.bar.monitor01.json{"$schema":"https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/heads/master/schema.bar.json","monitor":{"index":1,"work_area_offset":{"left":0,// Would be 32 without AppBar registration!
"top":0,"right":0,// Would be 32 without AppBar registration!
"bottom":0}},"position":{"start":{"x":1920,"y":0},"end":{"x":1920,"y":32}},"font_family":"MonoLisa Variable Regular","font_size":13,"max_label_width":350,"theme":{"palette":"Catppuccin","name":"Mocha","accent":"Peach"},"transparency_alpha":225,"left_widgets":[{"Komorebi":{"workspaces":{"enable":true,"display":"Text","hide_empty_workspaces":false},"layout":{"enable":true,"display":"Icon","options":["BSP","VerticalStack","RightMainVerticalStack","HorizontalStack","Columns","Rows"]},"workspace_layer":{"enable":true,"show_icon":true,"display":"IconAndText"},"focused_window":{"enable":true,"show_icon":true,"display":"IconAndText"}}}],"right_widgets":[{"Media":{"enable":false}},{"Storage":{"enable":false}},{"Memory":{"enable":false}},{"Network":{"enable":false,"show_total_data_transmitted":true,"show_network_activity":true}},{"Date":{"enable":true,"format":{"Custom":"%a, %Y-%m-%d"}}},{"Time":{"enable":true,"format":{"Custom":"%H:%M:%S"}}},{"Battery":{"enable":false}}]}
KOMOREBI_CONFIG_HOME detected: C:\Users\tsukasa\.config\komorebi
Looking for configuration files in C:\Users\tsukasa\.config\komorebi
Found komorebi.json; this file can be passed to the start command with the --config flag
Found C:\Users\tsukasa\.config\whkdrc; key bindings will be loaded from here when whkd is started, and you can start it automatically using the --whkd flag
Originally created by @tsukasa on GitHub (Feb 23, 2025).
### Summary
With the recent motherlode of changes related to monitor handling, a somewhat troubling behaviour has found its way into Komorebi.
When starting Komorebi via `komorebic start` with just one monitor connected, the output of `komorebic monitor-info` is as expected and presents the proper monitor data:
```json
[
{
"id": 3019343,
"name": "DISPLAY1",
"device": "DELA0A2",
"device_id": "DELA0A2-5&2da744da&0&UID184852",
"serial_number_id": "9TG465145HDL",
"size": {
"left": 0,
"top": 0,
"right": 1920,
"bottom": 1080
}
}
]
```
Connecting an additional monitor now causes an invalid entry:
```json
[
{
"id": 3019343,
"name": "DISPLAY1",
"device": "DELA0A2",
"device_id": "DELA0A2-5&2da744da&0&UID184852",
"serial_number_id": "9TG465145HDL",
"size": {
"left": 0,
"top": 0,
"right": 1920,
"bottom": 1080
}
},
{
"id": 0,
"name": "",
"device": "",
"device_id": "",
"serial_number_id": null,
"size": {
"left": 0,
"top": 0,
"right": 0,
"bottom": 0
}
}
]
```
The "null" monitor causes windows to be sent to invalid coordinates. The only way to workaround this is by restarting komorebi completely.
When observing `komorebic log`, the reconciliator clearly finds the monitor based on the ID DELA0A2-5&2da744da&0&UID184854 (ID of the monitor being connected):
```
2025-02-23T18:09:05.797124Z INFO komorebi::monitor_reconciliator: monitor count mismatch (1 vs 2), adding connected monitors
2025-02-23T18:09:05.798173Z INFO komorebi::monitor_reconciliator: found monitor and workspace configuration for DELA0A2-5&2da744da&0&UID184854 in the monitor cache, applying
2025-02-23T18:09:05.798502Z INFO focus_monitor{idx=0}: komorebi::window_manager: focusing monitor
2025-02-23T18:09:05.799488Z INFO focus_workspace{idx=0}: komorebi::window_manager: focusing workspace
2025-02-23T18:09:05.799745Z INFO focus_workspace{idx=0}:focus_workspace{idx=0}: komorebi::monitor: focusing workspace
2025-02-23T18:09:05.804310Z INFO focus_workspace{idx=0}:focus_window{idx=0}: komorebi::container: focusing window
2025-02-23T18:09:05.807339Z INFO focus_workspace{idx=0}:update_focused_workspace{follow_focus=false trigger_focus=true}: komorebi::window_manager: updating
2025-02-23T18:09:05.809423Z WARN komorebi: removing stale subscription: komorebi-bar-siliconized
```
This is a most annoying behaviour that potentially causes data loss because applications being sent to the other monitor end up in purgatory and have to be closed through the task manager.
When all displays are already connected before starting Komorebi, `komorebic monitor-info` resolves them properly and the application works as expected:
```json
[
{
"id": 43127399,
"name": "DISPLAY1",
"device": "DELA0A2",
"device_id": "DELA0A2-5&2da744da&0&UID184852",
"serial_number_id": "9TG465145HDL",
"size": {
"left": 0,
"top": 0,
"right": 1920,
"bottom": 1080
}
},
{
"id": 128258529,
"name": "DISPLAY2",
"device": "DELA0A2",
"device_id": "DELA0A2-5&2da744da&0&UID184854",
"serial_number_id": "9TG4656M294S",
"size": {
"left": 1920,
"top": 0,
"right": 1920,
"bottom": 1080
}
}
]
```
However, this should not be considered an acceptable workaround, because it is wholly unclear when the cache might expires and a user runs into the issue again.
### Version Information
OS Version
```
OS Name: Microsoft Windows 10 Pro
OS Version: 10.0.19045 N/A Build 19045
```
Komorebi Version
```
komorebic 0.1.35
branch:master
commit_hash:2bbc269b
build_time:2025-02-23 18:55:12 +01:00
build_env:rustc 1.84.0 (9fc6b4312 2025-01-07),stable-x86_64-pc-windows-msvc
```
### Komorebi Configuration
```json
komorebi.json
{
"$schema": "https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/heads/master/schema.json",
"animation": {
"duration": 250,
"enabled": true,
"fps": 60,
"style": "EaseInQuad"
},
"app_specific_configuration_path": "$Env:KOMOREBI_CONFIG_HOME/applications.json",
"bar_configurations": [
"$Env:KOMOREBI_CONFIG_HOME/komorebi.bar.monitor00.json",
"$Env:KOMOREBI_CONFIG_HOME/komorebi.bar.monitor01.json"
],
"border": false,
"border_implementation": "Komorebi",
"border_offset": -1,
"border_style": "System",
"border_width": 5,
"cross_boundary_behaviour": "Monitor",
"cross_monitor_move_behaviour": "Insert",
"default_container_padding": 3,
"default_workspace_padding": 3,
// Get the informations via "komorebic monitor-information"
// Be sure to check the "left" property to see which one is which...
"display_index_preferences": {
"0": "DELA0A2-5&2da744da&0&UID184852",
"1": "DELA0A2-5&2da744da&0&UID184854"
},
"float_override": false,
"floating_applications": [
// Borderless Gaming
{
"id": "BorderlessGaming.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Crates.app Media Player
{
"id": "Crates.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Directory Opus
{
"id": "dopus.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Dwarf Fortress
{
"id": "Dwarf Fortress.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// eM Client
{
"id": "MailClient.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// mpv
{
"id": "mpv",
"kind": "Class",
"matching_strategy": "Equals"
},
// OBS Studio
{
"id": "obs64.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Wavebox
{
"id": "Wavebox.exe",
"kind": "Exe",
"matching_strategy": "Equals"
}
],
"ignore_rules": [
// AltSnap
{
"id": "AltSnap.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Animal Well
{
"id": "Animal Well.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// AutoHotkey
{
"id": "AutoHotkey.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
{
"id": "AutoHotkey32.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
{
"id": "AutoHotkey64.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Citrix Workspace
{
"id": "Citrix.DesktopViewer.App.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
{
"id": "PrimaryAuthModule.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Clock64
{
"id": "ClockFlyoutWindow",
"kind": "Class",
"matching_strategy": "Equals"
},
// DSXv2
{
"id": "DSX.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Environmental Station Alpha
{
"id": "Environmental Station Alpha.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Enshrouded
{
"id": "enshrouded.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Final Fantasy XIV
{
"id": "FFXIVGAME",
"kind": "Class",
"matching_strategy": "Equals"
},
// GoXLR App and Control Panel
{
"id": "GoXLR App.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
{
"id": "GoXLRAudioCplApp.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// UUU (IGCSClient)
{
"id": "IGCSClient.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// tacky-borders
{
"id": "tacky-borders.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Tray Runner
{
"id": "TrayRunner.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// TurboLaunch
{
"id": "TurboLaunch.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Qt messages
{
"id": "Qt\\d+QWindowIcon",
"kind": "Class",
"matching_strategy": "Regex"
},
// XIVLauncher
{
"id": "XIVLauncher.exe",
"kind": "Exe",
"matching_strategy": "Equals"
}
],
"manage_rules": [
// Grabber
[
{
"id": "Grabber.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
{
"id": "Qt\\d+QWindowIcon",
"kind": "Class",
"matching_strategy": "Regex"
}
],
// mpv
[
{
"id": "mpv.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
{
"id": "mpv",
"kind": "Class",
"matching_strategy": "Equals"
}
],
// Qutebrowser
[
{
"id": "qutebrowser.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
{
"id": "Qt\\d+QWindowIcon",
"kind": "Class",
"matching_strategy": "Regex"
}
]
],
"object_name_change_applications": [
// Directory Opus
{
"id": "dopus.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Wavebox
{
"id": "Wavebox.exe",
"kind": "Exe",
"matching_strategy": "Equals"
}
],
"tray_and_multi_window_applications": [
// eM Client
{
"id": "MailClient.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Vivaldi
{
"id": "vivaldi.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
// Wavebox
{
"id": "Wavebox.exe",
"kind": "Exe",
"matching_strategy": "Equals"
}
],
"monitors": [
{
"workspaces": [
{
"name": "【一】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Create",
"float_override": true
},
{
"name": "【二】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Create",
"float_override": true,
"initial_workspace_rules": [
{
"id": "steam.exe",
"kind": "Exe",
"matching_strategy": "Equals"
}
]
},
{
"name": "【三】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Create",
"float_override": false,
},
{
"name": "【四】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Append",
"float_override": false,
"initial_workspace_rules": [
// Grabber
[
{
"id": "Grabber.exe",
"kind": "Exe",
"matching_strategy": "Equals"
},
{
"id": "Qt\\d+QWindowIcon",
"kind": "Class",
"matching_strategy": "Regex"
}
]
]
},
{
"name": "【五】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Append",
"float_override": false,
"initial_workspace_rules": [
// Vivaldi
{
"id": "vivaldi.exe",
"kind": "Exe",
"matching_strategy": "Equals"
}
]
},
{
"name": "【六】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Append",
"float_override": false,
"initial_workspace_rules": [
// Visual Studio Code
{
"id": "Code.exe",
"kind": "Exe",
"matching_strategy": "Equals"
}
]
}
]
},
{
"workspaces": [
{
"name": "【一】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Create",
"float_override": true
},
{
"name": "【二】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Create",
"float_override": true
},
{
"name": "【三】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Create",
"float_override": false
},
{
"name": "【四】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Create",
"float_override": false
},
{
"name": "【五】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Create",
"float_override": false
},
{
"name": "【六】",
"layout": "VerticalStack",
"apply_window_based_work_area_offset": true,
"window_container_behaviour": "Create",
"float_override": false
}
]
}
],
// Without m_f_f, switching workspaces happens on the monitor where the mouse is.
"mouse_follows_focus": true,
"resize_delta": 50,
"slow_application_compensation_time": 100,
// Disable stackbar by setting "mode" to "Never".
// komorebi-bar shows the members of the stack in the bar.
"stackbar": {
"height": 24,
"label": "Title",
"mode": "Never",
"tabs": {
"font_family": "MonoLisa Variable",
"font_size": 16,
"width": 200
}
},
"theme": {
"palette": "Catppuccin",
"name": "Mocha",
"bar_accent": "Peach",
"floating_border": "Blue",
"monocle_border": "Red",
"single_border": "Peach",
"stack_border": "Green",
"stackbar_background": "Crust",
"stackbar_focused_text": "Peach",
"stackbar_unfocused_text": "Overlay1",
"unfocused_border": "Mantle"
},
"transparency": false,
"transparency_alpha": 230,
"unmanaged_window_operation_behaviour": "Op",
// Automatically stack group new windows onto the existing window.
"window_container_behaviour": "Append",
"window_hiding_behaviour": "Cloak"
}
komorebi.bar.monitor00.json
{
"$schema": "https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/heads/master/schema.bar.json",
"monitor": {
"index": 0,
"work_area_offset": {
"left": 0,
// Would be 32 without AppBar registration!
"top": 0,
"right": 0,
// Would be 32 without AppBar registration!
"bottom": 0
}
},
"position": {
"start": {
"x": 0,
"y": 0
},
"end": {
"x": 1920,
"y": 32
}
},
"font_family": "MonoLisa Variable Regular",
"font_size": 13,
"max_label_width": 350,
"theme": {
"palette": "Catppuccin",
"name": "Mocha",
"accent": "Peach"
},
"transparency_alpha": 225,
"left_widgets": [
{
"Komorebi": {
"workspaces": {
"enable": true,
"display": "Text",
"hide_empty_workspaces": false
},
"layout": {
"enable": true,
"display": "Icon",
"options": [
"BSP",
"VerticalStack",
"RightMainVerticalStack",
"HorizontalStack",
"Columns",
"Rows"
]
},
"workspace_layer": {
"enable": true,
"show_icon": true,
"display": "IconAndText"
},
"focused_window": {
"enable": true,
"show_icon": true,
"display": "IconAndText"
}
}
}
],
"center_widgets": [],
"right_widgets": [
{
"Media": {
"enable": true
}
},
{
"Storage": {
"enable": false
}
},
{
"Cpu": {
"enable": false,
"data_refresh_interval": 5
}
},
{
"Memory": {
"enable": false
}
},
{
"Network": {
"enable": false,
"show_total_data_transmitted": true,
"show_network_activity": true
}
},
{
"Date": {
"enable": true,
"format": {
"Custom": "%a, %Y-%m-%d"
}
}
},
{
"Time": {
"enable": true,
"format": {
"Custom": "%H:%M:%S"
}
}
},
{
"Battery": {
"enable": false
}
}
]
}
komorebi.bar.monitor01.json
{
"$schema": "https://raw.githubusercontent.com/LGUG2Z/komorebi/refs/heads/master/schema.bar.json",
"monitor": {
"index": 1,
"work_area_offset": {
"left": 0,
// Would be 32 without AppBar registration!
"top": 0,
"right": 0,
// Would be 32 without AppBar registration!
"bottom": 0
}
},
"position": {
"start": {
"x": 1920,
"y": 0
},
"end": {
"x": 1920,
"y": 32
}
},
"font_family": "MonoLisa Variable Regular",
"font_size": 13,
"max_label_width": 350,
"theme": {
"palette": "Catppuccin",
"name": "Mocha",
"accent": "Peach"
},
"transparency_alpha": 225,
"left_widgets": [
{
"Komorebi": {
"workspaces": {
"enable": true,
"display": "Text",
"hide_empty_workspaces": false
},
"layout": {
"enable": true,
"display": "Icon",
"options": [
"BSP",
"VerticalStack",
"RightMainVerticalStack",
"HorizontalStack",
"Columns",
"Rows"
]
},
"workspace_layer": {
"enable": true,
"show_icon": true,
"display": "IconAndText"
},
"focused_window": {
"enable": true,
"show_icon": true,
"display": "IconAndText"
}
}
}
],
"right_widgets": [
{
"Media": {
"enable": false
}
},
{
"Storage": {
"enable": false
}
},
{
"Memory": {
"enable": false
}
},
{
"Network": {
"enable": false,
"show_total_data_transmitted": true,
"show_network_activity": true
}
},
{
"Date": {
"enable": true,
"format": {
"Custom": "%a, %Y-%m-%d"
}
}
},
{
"Time": {
"enable": true,
"format": {
"Custom": "%H:%M:%S"
}
}
},
{
"Battery": {
"enable": false
}
}
]
}
```
### Hotkey Configuration
Too long, see https://github.com/tsukasa/dotfiles-komorebi
### Output of komorebic check
```
KOMOREBI_CONFIG_HOME detected: C:\Users\tsukasa\.config\komorebi
Looking for configuration files in C:\Users\tsukasa\.config\komorebi
Found komorebi.json; this file can be passed to the start command with the --config flag
Found C:\Users\tsukasa\.config\whkdrc; key bindings will be loaded from here when whkd is started, and you can start it automatically using the --whkd flag
```
adam
added the bugkomorebi labels 2026-01-05 14:51:42 +01:00
Can you repro the same behaviour when using serial IDs in the display index preferences?
Also paging @alex-ds13
@LGUG2Z commented on GitHub (Feb 23, 2025):
Can you repro the same behaviour when using serial IDs in the display index preferences?
Also paging @alex-ds13
I replaced the display_index_preferences in komorebi.json with these updated values, based on the serial_number_id values reported by komorebic monitor-info:
For good measure, Komorebi gets a stop and start (with just one monitor connected initially, just like in the opening post). Connecting the second monitor:
komorebic log:
2025-02-23T19:38:20.208359Z INFO komorebi::monitor_reconciliator: monitor count mismatch (1 vs 2), adding connected monitors
2025-02-23T19:38:20.209379Z INFO komorebi::monitor_reconciliator: found monitor and workspace configuration for 9TG4656M294S in the monitor cache, applying
2025-02-23T19:38:20.209801Z INFO focus_monitor{idx=0}: komorebi::window_manager: focusing monitor
2025-02-23T19:38:20.210421Z INFO focus_workspace{idx=0}: komorebi::window_manager: focusing workspace
2025-02-23T19:38:20.211123Z INFO focus_workspace{idx=0}:focus_workspace{idx=0}: komorebi::monitor: focusing workspace
2025-02-23T19:38:20.216650Z INFO focus_workspace{idx=0}:focus_window{idx=0}: komorebi::container: focusing window
2025-02-23T19:38:20.219998Z INFO focus_workspace{idx=0}:update_focused_workspace{follow_focus=false trigger_focus=true}: komorebi::window_manager: updating
Querying komorebic monitor-info results in the same output:
Trying to send applications to the other monitor causes the same issue as before.
Additional information for clarification:
The second (freshly connected) monitor should be aligned to the right side of DISPLAY1 and is so in Windows. Komorebi's logic places it to the left instead, so instead of komorebic move right you can do a komorebic move left to send the applications to 0,0,0,0.
@tsukasa commented on GitHub (Feb 23, 2025):
I replaced the `display_index_preferences` in `komorebi.json` with these updated values, based on the `serial_number_id` values reported by `komorebic monitor-info`:
```json
"display_index_preferences": {
"0": "9TG465145HDL",
"1": "9TG4656M294S"
},
```
For good measure, Komorebi gets a stop and start (with just one monitor connected initially, just like in the opening post). Connecting the second monitor:
komorebic log:
```
2025-02-23T19:38:20.208359Z INFO komorebi::monitor_reconciliator: monitor count mismatch (1 vs 2), adding connected monitors
2025-02-23T19:38:20.209379Z INFO komorebi::monitor_reconciliator: found monitor and workspace configuration for 9TG4656M294S in the monitor cache, applying
2025-02-23T19:38:20.209801Z INFO focus_monitor{idx=0}: komorebi::window_manager: focusing monitor
2025-02-23T19:38:20.210421Z INFO focus_workspace{idx=0}: komorebi::window_manager: focusing workspace
2025-02-23T19:38:20.211123Z INFO focus_workspace{idx=0}:focus_workspace{idx=0}: komorebi::monitor: focusing workspace
2025-02-23T19:38:20.216650Z INFO focus_workspace{idx=0}:focus_window{idx=0}: komorebi::container: focusing window
2025-02-23T19:38:20.219998Z INFO focus_workspace{idx=0}:update_focused_workspace{follow_focus=false trigger_focus=true}: komorebi::window_manager: updating
```
Querying `komorebic monitor-info` results in the same output:
```json
[
{
"id": 107154863,
"name": "DISPLAY1",
"device": "DELA0A2",
"device_id": "DELA0A2-5&2da744da&0&UID184852",
"serial_number_id": "9TG465145HDL",
"size": {
"left": 0,
"top": 0,
"right": 1920,
"bottom": 1080
}
},
{
"id": 0,
"name": "",
"device": "",
"device_id": "",
"serial_number_id": null,
"size": {
"left": 0,
"top": 0,
"right": 0,
"bottom": 0
}
}
]
```
Trying to send applications to the other monitor causes the same issue as before.
Additional information for clarification:
The second (freshly connected) monitor should be aligned to the right side of DISPLAY1 and is so in Windows. Komorebi's logic places it to the left instead, so instead of `komorebic move right` you can do a `komorebic move left` to send the applications to 0,0,0,0.
@tsukasa If you want to stay on the bleeding edge I'd suggest removing the index preference for the monitor which may be disconnected and reconnected throughout your session until a fix can be identified
@LGUG2Z commented on GitHub (Feb 23, 2025):
@tsukasa If you want to stay on the bleeding edge I'd suggest removing the index preference for the monitor which may be disconnected and reconnected throughout your session until a fix can be identified
Works as expected for me so I'm gonna merge this in. @tsukasa please report back if the issue is resolved for you and we can close this issue.
@LGUG2Z commented on GitHub (Feb 24, 2025):
Works as expected for me so I'm gonna merge this in. @tsukasa please report back if the issue is resolved for you and we can close this issue.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Originally created by @tsukasa on GitHub (Feb 23, 2025).
Summary
With the recent motherlode of changes related to monitor handling, a somewhat troubling behaviour has found its way into Komorebi.
When starting Komorebi via
komorebic startwith just one monitor connected, the output ofkomorebic monitor-infois as expected and presents the proper monitor data:Connecting an additional monitor now causes an invalid entry:
The "null" monitor causes windows to be sent to invalid coordinates. The only way to workaround this is by restarting komorebi completely.
When observing
komorebic log, the reconciliator clearly finds the monitor based on the ID DELA0A2-5&2da744da&0&UID184854 (ID of the monitor being connected):This is a most annoying behaviour that potentially causes data loss because applications being sent to the other monitor end up in purgatory and have to be closed through the task manager.
When all displays are already connected before starting Komorebi,
komorebic monitor-inforesolves them properly and the application works as expected:However, this should not be considered an acceptable workaround, because it is wholly unclear when the cache might expires and a user runs into the issue again.
Version Information
OS Version
Komorebi Version
Komorebi Configuration
Hotkey Configuration
Too long, see https://github.com/tsukasa/dotfiles-komorebi
Output of komorebic check
@LGUG2Z commented on GitHub (Feb 23, 2025):
Can you repro the same behaviour when using serial IDs in the display index preferences?
Also paging @alex-ds13
@tsukasa commented on GitHub (Feb 23, 2025):
I replaced the
display_index_preferencesinkomorebi.jsonwith these updated values, based on theserial_number_idvalues reported bykomorebic monitor-info:For good measure, Komorebi gets a stop and start (with just one monitor connected initially, just like in the opening post). Connecting the second monitor:
komorebic log:
Querying
komorebic monitor-inforesults in the same output:Trying to send applications to the other monitor causes the same issue as before.
Additional information for clarification:
The second (freshly connected) monitor should be aligned to the right side of DISPLAY1 and is so in Windows. Komorebi's logic places it to the left instead, so instead of
komorebic move rightyou can do akomorebic move leftto send the applications to 0,0,0,0.@LGUG2Z commented on GitHub (Feb 23, 2025):
Adding my own attempt at reproduction:
With the following
display_index_preferences:Step 1
Starting komorebi with only
9SZGCP3connectedStep 2
Check
monitor-infooutput:Step 3
Connect
190909Step 4 [reproduction confirmed]
Check
monitor-infooutput:Step 5 [additional]
Disconnect
190909Step 6 [additional]
Reconnect
190909Step 7 [expected state]
Check
monitor-infooutput:@LGUG2Z commented on GitHub (Feb 23, 2025):
Further testing from me shows that this is only the case when the connected monitor is identified in
display_index_preferences:With the following
display_index_preferences:Step 1
Starting komorebi with only
9SZGCP3connectedStep 2
Check monitor-info output:
Step 3
Connect
190909Step 4 [expected state]
Check monitor-info output:
@LGUG2Z commented on GitHub (Feb 23, 2025):
@tsukasa If you want to stay on the bleeding edge I'd suggest removing the index preference for the monitor which may be disconnected and reconnected throughout your session until a fix can be identified
@alex-ds13 commented on GitHub (Feb 23, 2025):
I think I know what's causing this. I'll try to take a look tonight.
@alex-ds13 commented on GitHub (Feb 24, 2025):
This should be fixed with #1295
@tsukasa Thank you for the bug report!
@LGUG2Z commented on GitHub (Feb 24, 2025):
Works as expected for me so I'm gonna merge this in. @tsukasa please report back if the issue is resolved for you and we can close this issue.