mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-18 15:33:56 +01:00
277 lines
10 KiB
Markdown
277 lines
10 KiB
Markdown
# komorebi
|
||
|
||
Tiling Window Management for Windows.
|
||
|
||

|
||
|
||
## About
|
||
|
||
_komorebi_ is a tiling window manager that works as an extension to
|
||
Microsoft's [Desktop Window Manager](https://docs.microsoft.com/en-us/windows/win32/dwm/dwm-overview) 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 [AutoHotKey](https://github.com/Lexikos/AutoHotkey_L) to set user-defined keyboard
|
||
shortcuts.
|
||
|
||
## Description
|
||
|
||
_komorebi_ only responds to [WinEvents](https://docs.microsoft.com/en-us/windows/win32/winauto/event-constants) and the
|
||
messages it receives on a dedicated socket.
|
||
|
||
_komorebic_ is a CLI that writes messages on _komorebi_'s socket.
|
||
|
||
_komorebi_ doesn't handle any keyboard or mouse inputs; a third party program (e.g. AutoHotKey) is needed in order to
|
||
translate keyboard and mouse events to _komorebic_ commands.
|
||
|
||
This architecture, popularised by [_bspwm_](https://github.com/baskerville/bspwm) on Linux and
|
||
[_yabai_](https://github.com/koekeishiya/yabai) on macOS, is outlined as follows:
|
||
|
||
```
|
||
PROCESS SOCKET
|
||
ahk --------> komorebic <------> komorebi
|
||
```
|
||
|
||
## Design
|
||
|
||
_komorebi_ is the successor to [_yatta_](https://github.com/LGUG2Z/yatta) and as such aims to build on the learnings
|
||
from that project.
|
||
|
||
While _yatta_ was primary an attempt to learn how to work with and call Windows APIs from Rust, while secondarily
|
||
implementing a minimal viable tiling window manager for my own needs (largely single monitor, single workspace),
|
||
_komorebi_ has been redesigned from the ground-up to support more complex features that have become standard in tiling
|
||
window managers on other platforms.
|
||
|
||
_komorebi_ holds a list of physical monitors.
|
||
|
||
A monitor is just a rectangle of the available work area which contains one or more virtual workspaces.
|
||
|
||
A workspace holds a list of containers.
|
||
|
||
A container is just a rectangle where one or more application windows can be displayed.
|
||
|
||
This means that:
|
||
|
||
- Every monitor has its own collection of virtual workspaces
|
||
- Workspaces only know about containers and their dimensions, not about individual application windows
|
||
- Every application window must belong to a container, even if that container only contains one application window
|
||
- Many application windows can be stacked and cycled through in the same container within a workspace
|
||
|
||
## Getting Started
|
||
|
||
This project is still heavily under development and there are no prebuilt binaries available yet.
|
||
|
||
If you would like to use _komorebi_, you will need
|
||
a [working Rust development environment on Windows 10](https://rustup.rs/). If you are using
|
||
the `x86_64-pc-windows-msvc` toolchain, make sure you have also installed
|
||
the [Build Tools for Visual Studio 2019](https://stackoverflow.com/a/55603112).
|
||
|
||
You can then clone this repo and compile the source code to install the binaries for `komorebi` and `komorebic`:
|
||
|
||
```powershell
|
||
cargo install --path komorebi
|
||
cargo install --path komorebic
|
||
```
|
||
|
||
By running `komorebic start` at a Powershell prompt, you should see the following output:
|
||
|
||
```
|
||
Start-Process komorebi -WindowStyle hidden
|
||
```
|
||
|
||
This means that `komorebi` is now running in the background, tiling all your windows, and listening for commands sent to it
|
||
by `komorebic`.
|
||
|
||
You can similarly stop the process by running `komorebic stop`.
|
||
|
||
## Configuration
|
||
|
||
As previously mentioned, this project does not handle anything related to keybindings and shortcuts directly. I
|
||
personally use AutoHotKey to manage my window management shortcuts, and have provided a
|
||
sample [komorebi.ahk](komorebi.sample.ahk) AHK script that you can use as a starting point for your own.
|
||
|
||
## Features
|
||
|
||
- [x] Multi-monitor
|
||
- [x] Virtual workspaces
|
||
- [x] Window stacks
|
||
- [x] Cycle through stacked windows
|
||
- [x] Change focused window by direction
|
||
- [x] Move focused window container in direction
|
||
- [x] Move focused window container to monitor
|
||
- [x] Move focused window container to workspace
|
||
- [x] Mouse follows focused container
|
||
- [x] Resize window container in direction
|
||
- [ ] Resize child window containers by split ratio
|
||
- [x] Mouse drag to swap window container position
|
||
- [x] Mouse drag to resize window container
|
||
- [x] Configurable workspace and container gaps
|
||
- [x] BSP tree layout
|
||
- [x] Flip BSP tree layout horizontally or vertically
|
||
- [x] Equal-width, max-height column layout
|
||
- [x] Floating rules based on exe name
|
||
- [x] Floating rules based on window title
|
||
- [x] Floating rules based on window class
|
||
- [x] Toggle floating windows
|
||
- [x] Toggle monocle window
|
||
- [x] Toggle focus follows mouse
|
||
- [x] Pause all window management
|
||
- [x] View window manager state
|
||
|
||
## Development
|
||
|
||
If you would like to contribute code to this repository, there are a few requests that I have to ensure a foundation of
|
||
code quality, consistency and commit hygiene:
|
||
|
||
- Flatten all `use` statements except in `bindings/build.rs`
|
||
- Run `cargo +nightly clippy` and ensure that all lints and suggestions have been addressed before committing
|
||
- Run `cargo +nightly fmt --all` to ensure consistent formatting before committing
|
||
- Use `git cz` with
|
||
the [Commitizen CLI](https://github.com/commitizen/cz-cli#conventional-commit-messages-as-a-global-utility) 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
|
||
|
||
## Logs and Debugging
|
||
|
||
Logs from `komorebi` will be appended to `~/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 `~/komorebi.hwnd.json`.
|
||
|
||
Running `komorebic restore-windows` will read the list of window handles and forcibly restore them, regardless of
|
||
whether the main `komorebi` process is running.
|
||
|
||
## 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 `WindowManager` struct.
|
||
|
||
This may also be polled to build further integrations and widgets on top of (if you ever wanted to build something
|
||
like [Stackline](https://github.com/AdamWagner/stackline) for Windows, you could do it by polling this command).
|
||
|
||
```json
|
||
{
|
||
"monitors": {
|
||
"elements": [
|
||
{
|
||
"id": 65537,
|
||
"monitor_size": {
|
||
"left": 0,
|
||
"top": 0,
|
||
"right": 3840,
|
||
"bottom": 2160
|
||
},
|
||
"work_area_size": {
|
||
"left": 0,
|
||
"top": 40,
|
||
"right": 3840,
|
||
"bottom": 2120
|
||
},
|
||
"workspaces": {
|
||
"elements": [
|
||
{
|
||
"name": "bsp",
|
||
"containers": {
|
||
"elements": [
|
||
{
|
||
"windows": {
|
||
"elements": [
|
||
{
|
||
"hwnd": 2623596,
|
||
"title": "komorebi – README.md",
|
||
"exe": "idea64.exe",
|
||
"class": "SunAwtFrame",
|
||
"rect": {
|
||
"left": 8,
|
||
"top": 60,
|
||
"right": 1914,
|
||
"bottom": 2092
|
||
}
|
||
}
|
||
],
|
||
"focused": 0
|
||
}
|
||
},
|
||
{
|
||
"windows": {
|
||
"elements": [
|
||
{
|
||
"hwnd": 198266,
|
||
"title": "LGUG2Z/komorebi: A(nother) tiling window manager for Windows 10 based on binary space partitioning - Mozilla Firefox",
|
||
"exe": "firefox.exe",
|
||
"class": "MozillaWindowClass",
|
||
"rect": {
|
||
"left": 1918,
|
||
"top": 60,
|
||
"right": 1914,
|
||
"bottom": 1042
|
||
}
|
||
}
|
||
],
|
||
"focused": 0
|
||
}
|
||
},
|
||
{
|
||
"windows": {
|
||
"elements": [
|
||
{
|
||
"hwnd": 1247352,
|
||
"title": "Windows PowerShell",
|
||
"exe": "WindowsTerminal.exe",
|
||
"class": "CASCADIA_HOSTING_WINDOW_CLASS",
|
||
"rect": {
|
||
"left": 1918,
|
||
"top": 1110,
|
||
"right": 959,
|
||
"bottom": 1042
|
||
}
|
||
}
|
||
],
|
||
"focused": 0
|
||
}
|
||
},
|
||
{
|
||
"windows": {
|
||
"elements": [
|
||
{
|
||
"hwnd": 395464,
|
||
"title": "Signal",
|
||
"exe": "Signal.exe",
|
||
"class": "Chrome_WidgetWin_1",
|
||
"rect": {
|
||
"left": 2873,
|
||
"top": 1110,
|
||
"right": 959,
|
||
"bottom": 1042
|
||
}
|
||
}
|
||
],
|
||
"focused": 0
|
||
}
|
||
}
|
||
],
|
||
"focused": 2
|
||
},
|
||
"monocle_container": null,
|
||
"floating_windows": [],
|
||
"layout": "BSP",
|
||
"layout_flip": null,
|
||
"workspace_padding": 10,
|
||
"container_padding": 10
|
||
}
|
||
],
|
||
"focused": 0
|
||
}
|
||
}
|
||
],
|
||
"focused": 0
|
||
},
|
||
"is_paused": false
|
||
}
|
||
```
|