1. Project Overview & Quickstart (LGUG2Z/komorebi)
File: README.md
komorebi
Tiling Window Management for Windows.
Note: Students using devices enrolled in mobile device management (MDM)
Your usage still falls under the Komorebi License 2.0.0.
You can email me at the address I sign my commits with (add .patch to the end
of any commit URL on GitHub to find it) from the address associated with your
institution with the subject "komorebi - student with an MDM device", and I will
be able to remove the splash intended for corporate users, whose usage falls
under the Individual Commercial Use
License.
This is currently a manual process - most days this shouldn't take more than
12h, and you will receive an email reply from me when the process is complete.
If you haven't had a reply to your email within 24h you can reach out to me on
Discord.
Note: Unexpected mobile device management (MDM) detection prompts
You have most likely unintentionally enrolled your device in "Bring Your Own
Device" (BYOD) MDM. You can confirm if this is the case by running dsregcmd /status and then take the appropriate steps to remove the MDM profile and take
back full control of your system.
If you need help doing this you can ask on Discord.
Note: komorebi for Mac
komorebi for Mac lives here :)
Overview
komorebi is a tiling window manager that works as an extension to Microsoft's
Desktop Window
Manager in
Windows 10 and above.
komorebi allows you to control application windows, virtual workspaces and display monitors with a CLI which can be
used with third-party software such as whkd
and AutoHotKey to set user-defined keyboard shortcuts.
komorebi aims to make as few modifications as possible to the operating
system and desktop environment by default. Users are free to make such
modifications in their own configuration files for komorebi, but these will
remain opt-in and off-by-default for the foreseeable future.
Please refer to the documentation for instructions on how
to install and
configure
komorebi, common workflows, a complete
configuration schema reference and a
complete CLI reference.
Community
There is a Discord server available for
komorebi-related discussion, help, troubleshooting etc. If you have any
specific feature requests or bugs to report, please create an issue in this
repository.
There is a YouTube
channel where I post
komorebi development videos, feature previews and release overviews. Subscribing
to the channel (which is monetized as part of the YouTube Partner Program) and
watching videos is a really simple and passive way to contribute financially to
the development and maintenance of komorebi.
There is an Awesome List which
showcases the many awesome projects that exist in the komorebi ecosystem.
Licensing for Personal Use
komorebi is educational source
software.
komorebi is licensed under the Komorebi 2.0.0
license, which is a fork of the
PolyForm Strict 1.0.0
license. On a high level
this means that you are free to do whatever you want with komorebi for
personal use other than redistribution, or distribution of new works (i.e.
hard-forks) based on the software.
Anyone is free to make their own fork of komorebi with changes intended either
for personal use or for integration back upstream via pull requests.
The Komorebi 2.0.0 License does
not permit any kind of commercial use (i.e. using komorebi at work).
Sponsorship for Personal Use
komorebi is a free and educational source project, and one that encourages you
to make charitable donations if you find the software to be useful and have the
financial means.
I encourage you to make a charitable donation to the Palestine Children's
Relief Fund or to contribute
to a Gaza Funds campaign before you consider sponsoring
me on GitHub.
GitHub Sponsors is enabled for this
project. Sponsors can claim custom roles on
the Discord server, get shout outs at the end of komorebi-related videos on
YouTube, gain the ability to submit feature requests on the issue tracker, and
receive releases of komorebi with "easter eggs" on physical media.
If you would like to tip or sponsor the project but are unable to use GitHub
Sponsors, you may also sponsor through Ko-fi, or
make an anonymous Bitcoin donation to bc1qv73wzspc77k46uty4vp85x8sdp24mphvm58f6q.
Licensing for Commercial Use
A dedicated Individual Commercial Use License is available for those who want to
use komorebi at work.
The Individual Commerical Use License adds βCommercial Useβ as a βPermitted Useβ
for the licensed individual only, for the duration of a valid paid license
subscription only. All provisions and restrictions enumerated in the Komorebi
License continue to apply.
More information, pricing and purchase links for Individual Commercial Use
Licenses can be found here.
Installation
A detailed installation and quickstart
guide is available which shows how to get started
using scoop, winget or building from source.
Comparison With Fancy Zones
Community member Olge has created an
excellent video which compares the default window management features of
Windows 11, Fancy Zones and komorebi.
If you are not familiar with tiling window managers or if you are looking at
komorebi and wondering "how is this different from Fancy Zones? π€", this short
video will answer the majority of your questions.
Demonstrations
@amnweb showing komorebi v0.1.28 running on Windows 11 with window borders,
unfocused window transparency and animations enabled, using a custom status bar integrated using
komorebi'
s Window Manager Event Subscriptions.
https://github.com/LGUG2Z/komorebi/assets/13164844/21be8dc4-fa76-4f70-9b37-1d316f4b40c2
@haxibami showing komorebi running on Windows
11 with a terminal emulator, a web browser and a code editor. The original
video can be viewed
here.
@aik2mlj showing komorebi running on Windows 11
with multiple workspaces, terminal emulators, a web browser, and the
yasb status bar with the komorebi workspace
widget enabled. The original video can be viewed
here.
Contribution Guidelines
If you would like to contribute to komorebi please take the time to carefully
read the guidelines below.
Please see CONTRIBUTING.md for more information about how
code contributions to komorebi are licensed.
Commit hygiene
- Flatten all
usestatements - Run
cargo +stable clippyand ensure that all lints and suggestions have been addressed before committing - Run
cargo +nightly fmt --allto ensure consistent formatting before committing - Use
git czwith
the Commitizen CLI to prepare
commit messages - Provide at least one short sentence or paragraph in your commit message body to describe your thought process for
the changes being committed
PRs should contain only a single feature or bug fix
It is very difficult to review pull requests which touch multiple unrelated features and parts of the codebase.
Please do not submit pull requests like this; you will be asked to separate them into smaller PRs that deal only with
one feature or bug fix at a time.
If you are working on multiple features and bug fixes, I suggest that you cut a branch called local-trunk
from master which you keep up to date, and rebase the various independent branches you are working on onto that branch
if you want to test them together or create a build with everything integrated.
Refactors to the codebase must have prior approval
komorebi is a mature codebase with an internal consistency and structure that has developed organically over close to
half a decade.
There are countless hours of live coding videos demonstrating work on this project and
showing new contributors how to do everything from basic tasks like implementing new komorebic commands to
distinguishing monitors by manufacturer hardware identifiers and video card ports.
Refactors to the structure of the codebase are not taken lightly and require prior discussion and approval.
Please do not start refactoring the codebase with the expectation of having your changes integrated until you receive an
explicit approval or a request to do so.
Similarly, when implementing features and bug fixes, please stick to the structure of the codebase as much as possible
and do not take this as an opportunity to do some "refactoring along the way".
It is extremely difficult to review PRs for features and bug fixes if they are lost in sweeping changes to the structure
of the codebase.
Breaking changes to user-facing interfaces are unacceptable
This includes but is not limited to:
- All
komorebiccommands - The
komorebi.jsonschema - The
komorebi-application-specific-configuration
schema
No user should ever find that their configuration file has stopped working after upgrading to a new version
of komorebi.
More often than not there are ways to reformulate changes that may initially seem like they require breaking user-facing
interfaces into additive changes.
For some inspiration please take a look
at this commit which added the
ability for users to specify colours in komorebi.json in Hex format alongside RGB.
There is also a process in place for graceful, non-breaking, deprecation of configuration options that are no longer
required.
Development
If you use IntelliJ, you should enable the following settings to ensure that code generated by macros is recognised by
the IDE for completions and navigation:
- Set
Expand declarative macros
toUse new engineunder "Settings > Langauges & Frameworks > Rust" - Enable the following experimental features:
org.rust.cargo.evaluate.build.scriptsorg.rust.macros.proc
Logs and Debugging
Logs from komorebi will be appended to %LOCALAPPDATA%/komorebi/komorebi.log; this file is never rotated or
overwritten, so it will keep growing until it is deleted by the user.
Whenever running the komorebic stop command or sending a Ctrl-C signal to komorebi directly, the komorebi process
ensures that all hidden windows are restored before termination.
If however, you ever end up with windows that are hidden and cannot be restored, a list of window handles known
to komorebi are stored and continuously updated in %LOCALAPPDATA%/komorebi//komorebi.hwnd.json.
Restoring Windows
Running komorebic restore-windows will read the list of window handles and forcibly restore them, regardless of
whether the main komorebi process is running.
Panics and Deadlocks
If komorebi ever stops responding, it is most likely either due to either a panic or a deadlock. In the case of a
panic, this will be reported in the log. In the case of a deadlock, there will not be any errors in the log, but the
process and the log will appear frozen.
If you believe you have encountered a deadlock, you can compile komorebi with --features deadlock_detection and try
reproducing the deadlock again. This will check for deadlocks every 5 seconds in the background, and if a deadlock is
found, information about it will appear in the log which can be shared when opening an issue.
Window Manager State and Integrations
The current state of the window manager can be queried using the komorebic state command, which returns a JSON
representation of the State struct.
This may also be polled to build further integrations and widgets on top of.
Window Manager Event Subscriptions
Named Pipes
It is possible to subscribe to notifications of every WindowManagerEvent and SocketMessage handled
by komorebi using Named Pipes.
First, your application must create a named pipe. Once the named pipe has been created, run the following command:
komorebic.exe subscribe-pipe <your pipe name>Note that you do not have to include the full path of the named pipe, just the name.
If the named pipe exists, komorebi will start pushing JSON data of successfully handled events and messages:
{"event":{"type":"AddSubscriber","content":"yasb"},"state":{}}
{"event":{"type":"FocusWindow","content":"Left"},"state":{}}
{"event":{"type":"FocusChange","content":["SystemForeground",{"hwnd":131444,"title":"komorebi β README.md","exe":"idea64.exe","class":"SunAwtFrame","rect":{"left":13,"top":60,"right":1520,"bottom":1655}}]},"state":{}}
{"event":{"type":"MonitorPoll","content":["ObjectCreate",{"hwnd":5572450,"title":"OLEChannelWnd","exe":"explorer.exe","class":"OleMainThreadWndClass","rect":{"left":0,"top":0,"right":0,"bottom":0}}]},"state":{}}
{"event":{"type":"FocusWindow","content":"Right"},"state":{}}
{"event":{"type":"FocusChange","content":["SystemForeground",{"hwnd":132968,"title":"Windows PowerShell","exe":"WindowsTerminal.exe","class":"CASCADIA_HOSTING_WINDOW_CLASS","rect":{"left":1539,"top":60,"right":1520,"bottom":821}}]},"state":{}}
{"event":{"type":"FocusWindow","content":"Down"},"state":{}}
{"event":{"type":"FocusChange","content":["SystemForeground",{"hwnd":329264,"title":"den β Mozilla Firefox","exe":"firefox.exe","class":"MozillaWindowClass","rect":{"left":1539,"top":894,"right":1520,"bottom":821}}]},"state":{}}
{"event":{"type":"FocusWindow","content":"Up"},"state":{}}
{"event":{"type":"FocusChange","content":["SystemForeground",{"hwnd":132968,"title":"Windows PowerShell","exe":"WindowsTerminal.exe","class":"CASCADIA_HOSTING_WINDOW_CLASS","rect":{"left":1539,"top":60,"right":1520,"bottom":821}}]},"state":{}}You may then filter on the type key to listen to the events that you are interested in. For a full list of possible
notification types, refer to the enum variants of WindowManagerEvent in komorebi and SocketMessage
in komorebi::core.
Below is an example of how you can subscribe to and filter on events using a named pipe in nodejs.
const { exec } = require("child_process");
const net = require("net");
const pipeName = "\\\\.\\pipe\\komorebi-js";
const server = net.createServer((stream) => {
console.log("Client connected");
// Every time there is a workspace-related event, let's log the names of all
// workspaces on the currently focused monitor, and then log the name of the
// currently focused workspace on that monitor
stream.on("data", (data) => {
let json = JSON.parse(data.toString());
let event = json.event;
if (event.type.includes("Workspace")) {
let monitors = json.state.monitors;
let current_monitor = monitors.elements[monitors.focused];
let workspaces = monitors.elements[monitors.focused].workspaces;
let current_workspace = workspaces.elements[workspaces.focused];
console.log(
workspaces.elements
.map((workspace) => workspace.name)
.filter((name) => name !== null)
);
console.log(current_workspace.name);
}
});
stream.on("end", () => {
console.log("Client disconnected");
});
});
server.listen(pipeName, () => {
console.log("Named pipe server listening");
});
const command = "komorebic subscribe-pipe komorebi-js";
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`Error executing command: ${error}`);
return;
}
});Unix Domain Sockets
It is possible to subscribe to notifications of every WindowManagerEvent and SocketMessage handled
by komorebi using Unix Domain Sockets.
UDS are also the only mode of communication between komorebi and komorebic.
First, your application must create a socket in $ENV:LocalAppData\komorebi. Once the socket has been created, run the
following command:
komorebic.exe subscribe-socket <your socket name>If the socket exists, komorebi will start pushing JSON data of successfully handled events and messages as in the
example above in the Named Pipes section.
Rust Client
As of v0.1.22 it is possible to use the komorebi-client crate to subscribe to notifications of
every WindowManagerEvent and SocketMessage handled by komorebi in a Rust codebase.
Below is a simple example of how to use komorebi-client in a basic Rust application.
// komorebi-client = { git = "https://github.com/LGUG2Z/komorebi" }
use anyhow::Result;
use komorebi_client::Notification;
use komorebi_client::NotificationEvent;
use komorebi_client::UnixListener;
use komorebi_client::WindowManagerEvent;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Read;
pub fn main() -> anyhow::Result<()> {
let socket = komorebi_client::subscribe(NAME)?;
for incoming in socket.incoming() {
match incoming {
Ok(data) => {
let reader = BufReader::new(data.try_clone()?);
for line in reader.lines().flatten() {
let notification: Notification = match serde_json::from_str(&line) {
Ok(notification) => notification,
Err(error) => {
log::debug!("discarding malformed komorebi notification: {error}");
continue;
}
};
// match and filter on desired notifications
}
}
Err(error) => {
log::debug!("{error}");
}
}
}
}A read-world example can be found
in komokana.
Subscription Event Notification Schema
A JSON Schema of the event notifications emitted to subscribers can be generated with
the komorebic notification-schema command. The output of this command can be redirected to the clipboard or a file,
which can be used with services such as Quicktype to generate type definitions in different
programming languages.
Communication over TCP
A TCP listener can optionally be exposed on a port of your choosing with the --tcp-port=N flag. If this flag is not
provided to komorebi or komorebic start, no TCP listener will be created.
Once created, your client may send
any SocketMessage to komorebi in the
same way that komorebic would.
This can be used if you would like to create your own alternative to komorebic which incorporates scripting and
various middleware layers, and similarly it can be used if you would like to integrate komorebi with
a custom input handler.
If a client sends an unrecognized message, it will be disconnected and have to reconnect before trying to communicate
again.
Socket Message Schema
A JSON Schema of socket messages used to send instructions to komorebi can be generated
with the komorebic socket-schema command. The output of this command can be redirected to the clipboard or a file,
which can be used with services such as Quicktype to generate type definitions in different
programming languages.
Appreciations
First and foremost, thank you to my wife, both for naming this project and for her patience throughout its
never-ending developmentThank you to @sitiom for
being an exemplary open source community leaderThank you to the developers of nog who came before me and whose work taught
me more than I can ever hope to repayThank you to the developers of GlazeWM for pushing the boundaries of tiling
window management on Windows with me and having an excellent spirit of collaborationThank you to @Ciantic for helping me bring
the hidden Virtual Desktops cloaking function tokomorebi
File: docs/common-workflows/animations.md
Animations
If you would like to add window movement animations, ensure the following options are
defined in the komorebi.json configuration file.
{
"animation": {
"enabled": true,
"duration": 250,
"fps": 60,
"style": "EaseOutSine"
}
}Window movement animations only apply to actions taking place within the same monitor
workspace.
You can optionally set a custom duration in ms with animation.duration (default: 250),
a custom style with animation.style (default: Linear), and a custom FPS value withanimation.fps (default: 60).
It is important to note that higher fps and a longer duration settings will result
in increased CPU usage.
This feature is not considered stable, and you may encounter visual artifacts
from time to time.
File: docs/common-workflows/autohotkey.md
AutoHotkey
If you would like to use Autohotkey, please make sure you have AutoHotKey v2
installed.
Generally, users who opt for AHK will have specific needs that can only be
addressed by the advanced functionality of AHK, and so they are assumed to be
able to craft their own configuration files.
If you would like to try out AHK, here is a simple sample configuration which
largely matches the whkdrc sample configuration.
{% include "./komorebi.ahk.txt" %}By default, the komorebi.ahk file should be located in the $Env:USERPROFILE
directory, however, if $Env:KOMOREBI_CONFIG_HOME is set, it should be located
there.
Once the file is in place, you can stop komorebi and whkd by running komorebic stop --whkd,
and then start komorebi with Autohotkey by running komorebic start --ahk.
File: docs/common-workflows/autostart.md
Autostart
If you would like to autostart komorebi, you can use the komorebic enable-autostart command to generate a shortcut
in the shell:startup folder.
Generates the komorebi.lnk shortcut in shell:startup to autostart komorebi
Usage: komorebic.exe enable-autostart [OPTIONS]
Options:
-c, --config <CONFIG>
Path to a static configuration JSON file
-f, --ffm
Enable komorebi's custom focus-follows-mouse implementation
--whkd
Enable autostart of whkd
--ahk
Enable autostart of ahk
--bar
Enable autostart of komorebi-bar
-h, --help
Print helpFile: docs/common-workflows/borders.md
Borders
If you would like to add a visual border around both the currently focused window
and unfocused windows ensure the following options are defined in the komorebi.json
configuration file.
{
"border": true,
"border_width": 8,
"border_offset": -1,
"border_style": "System",
"border_colours": {
"single": "#42a5f5",
"stack": "#00a542",
"monocle": "#ff3399",
"unfocused": "#808080"
}
}It is important to note that borders will only apply to windows managed by komorebi.
This feature is not considered stable, and you may encounter visual artifacts
from time to time.
File: docs/common-workflows/dynamic-layout-switching.md
Dynamic Layout Switching
With komorebi it is possible to define rules to automatically change the
layout on a specified workspace when a threshold of window containers is met.
{
"monitors": [
{
"workspaces": [
{
"name": "personal",
"layout_rules": {
"1": "BSP"
}
"custom_layout_rules": {
"5": "C:/Users/LGUG2Z/my-custom-layout.json"
}
},
]
}
]
}In this example, when there are one or more window containers visible on the
screen, the BSP layout is used, and when there are five or more window
containers visible, a custom layout is used.
However, if you add workspace layout rules, you will not be able to manually
change the layout of a workspace until all layout rules for that workspace have
been cleared.
# for example, to clear rules from monitor 0, workspace 0
komorebic clear-workspace-layout-rules 0 0File: docs/common-workflows/floating-applications.md
Floating Windows
Sometimes you will want a specific application to be managed as a floating window.
You can add rules to enforce this behaviour in the komorebi.json configuration file.
{
"floating_applications": [
{
"kind": "Title",
"id": "Media Player",
"matching_strategy": "Equals"
}
]
}File: docs/common-workflows/force-manage-windows.md
Force Manage Windows
βοΈNOTE: A significant number of force-manage window rules for the most
common applications are already generated for
you
In some rare cases, a window may not automatically be registered to be managed
by komorebi. You can add rules to enforce this behaviour in thekomorebi.json configuration file.
{
"manage_rules": [
{
"kind": "Title",
"id": "Media Player",
"matching_strategy": "Equals"
}
]
}File: docs/common-workflows/ignore-windows.md
Ignore Windows
βοΈNOTE: A significant number of ignored window rules for the most common
applications are already generated for
you
Sometimes you will want a specific application to never be tiled, and instead
be completely ignored. You can add rules to enforce this behaviour in thekomorebi.json configuration file.
{
"ignore_rules": [
{
"kind": "Title",
"id": "Media Player",
"matching_strategy": "Equals"
}
]
}File: docs/common-workflows/komorebi-config-home.md
`KOMOREBI_CONFIG_HOME`
If you do not want to keep komorebi-related files in your $Env:USERPROFILE
directory, you can specify a custom directory by setting the$Env:KOMOREBI_CONFIG_HOME environment variable.
For example, to use the ~/.config/komorebi directory:
# Run this command to make sure that the directory has been created
mkdir -p ~/.config/komorebi
# Run this command to open up your PowerShell profile configuration in Notepad
notepad $PROFILE
# Add this line (with your login user!) to the bottom of your PowerShell profile configuration
$Env:KOMOREBI_CONFIG_HOME = 'C:\Users\LGUG2Z\.config\komorebi'
# Save the changes and then reload the PowerShell profile
. $PROFILEIf you already have configuration files that you wish to keep, move them to the~/.config/komorebi directory.
The next time you run komorebic start, any files created by or loaded by
komorebi will be placed or expected to exist in this folder.
After setting $Env:KOMOREBI_CONFIG_HOME, make sure to update the path in komorebi.json:
{
"app_specific_configuration_path": "$Env:KOMOREBI_CONFIG_HOME/applications.json"
}This ensures that komorebi can locate all configuration files correctly.
2. Official Technical Reference & Guides (LGUG2Z/website)
Astro Starter Kit: Basics
npm create astro@latest -- --template basicsπ§βπ Seasoned astronaut? Delete this file. Have fun!
π Project Structure
Inside of your Astro project, you'll see the following folders and files:
/
βββ public/
β βββ favicon.svg
βββ src/
β βββ components/
β β βββ Card.astro
β βββ layouts/
β β βββ Layout.astro
β βββ pages/
β βββ index.astro
βββ package.jsonAstro looks for .astro or .md files in the src/pages/ directory. Each page is exposed as a route based on its file name.
There's nothing special about src/components/, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
Any static assets, like images, can be placed in the public/ directory.
π§ Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
|---|---|
npm install |
Installs dependencies |
npm run dev |
Starts local dev server at localhost:4321 |
npm run build |
Build your production site to ./dist/ |
npm run preview |
Preview your build locally, before deploying |
npm run astro ... |
Run CLI commands like astro add, astro check |
npm run astro -- --help |
Get help using the Astro CLI |
π Want to learn more?
Feel free to check our documentation or jump into our Discord server.

