From e89a101be5d9d7d680cdd7fdb475b5aa5605f4ae Mon Sep 17 00:00:00 2001 From: Syed Daanish Date: Thu, 8 Oct 2026 15:07:51 +0100 Subject: [PATCH] Writeup --- writeup.md | 202 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 146 insertions(+), 56 deletions(-) diff --git a/writeup.md b/writeup.md index ed6df59..dca38e8 100644 --- a/writeup.md +++ b/writeup.md @@ -1,14 +1,35 @@ # Kutu WM -Firstly, why im interested in wm's citing i3 and awsome etc as my inspiration but the fact that using similar systems for a while now, and i wish to explore every part of the software everyone uses and doesnt even feel the existence of. +## What is a window manager? + +A graphical desktop is made of many separate programs (a browser, a terminal, a file manager) all sharing one screen. Each application only knows how to draw its own contents inside a rectangle called a window. They have no idea where that window should sit on the screen, how big it should be, or what should happen when several windows overlap. This is the job of a window manager (WM). + +A window manager is the software that controls the placement and appearance of windows on a graphical display. + +The things a window manager is usually responsible for are: +- Placement and sizing: deciding where a new window appears and how large it is, and handling the user moving or resizing it. +- Focus and stacking: tracking which window currently receives input and which windows are in front of others. +- Workspaces: grouping windows onto virtual desktops that can be switched between. (This is not always implmented but I personally like the concept.) +- Input handling: reacting to global keyboard shortcuts and mouse actions that don't belong to any one application. +- Minimized state: WM's also handle minimized windows with sometimes a taskbar which shows these windows. (I do not plan on making this work.) + +Window managers are generally split into a few categories based on how they arrange windows. Stacking (floating) window managers let windows overlap freely, like papers on a desk, which is what Windows and macOS do. Tiling window managers automatically arrange windows so that they never overlap and fill the screen, usually controlled almost entirely from the keyboard. Dynamic window managers can switch between these approaches. + +A window manager is not the same thing as a desktop environment (DE). +A desktop environment such as KDE or GNOME bundles a window manager together with panels, settings tools, file managers and more. +A basic window manager does only the window management and leaves the rest to the user, which is what makes it a good scope for a project like this one. + +On X11 specifically, the window manager is just another client program that talks to the X server. It is not built into the display system. It asks the server to redirect window requests to it, so that when an application asks to show or resize a window, the WM gets to decide what actually happens. This is exactly why X11 allows replacing the window manager entirely, and why I can build my own. + +^ Wikipedia (2026). Window manager. [online] Available at: https://en.wikipedia.org/wiki/Window_manager [Accessed 7 October 2026]. ## X11 -On Windows, window management is handled by the **Desktop Window Manager (DWM)** by Microsoft. Since window management is directly integrated into the operating system, it is not designed to be replaced by users with a completely custom window manager. (although extentions can be made they are not as complete.) +On Windows the window management is handled by the **Desktop Window Manager (DWM)** by Microsoft. Since window management is directly integrated into the operating system, it is not designed to be replaced by users with a completely custom window manager. (although extentions can be made, they are not as complete.) MacOS's also have a similar situation where they build and roll out the WM along with the core operating system itself. -Because of this, if I want to build my own window manager, Linux provides a much more suitable environment. Linux is highly customisable, and its graphical stack allows users to build alternative window management systems on top of established display server protocols. +If I want to build my own window manager, Linux provides a much more suitable environment. Linux is highly customisable, and the graphical session on linux devices can be chosen by the user, as such they can start thier own programs as the graphical session directly from the tty or through their init system (like `systemd`). The two main display server protocols to consider are: @@ -51,6 +72,61 @@ It will be programmable at runtime where they can change the behaviour and add k This will need to be done by a runtime embedded scripting system. +## i3 + +i3 arranges windows in a tree of containers, which the user splits horizontally or vertically as they open windows. This gives a lot of control over layout, and it is one of the most widely used tiling window managers, with a large community and plenty of documentation. + +The main difference is in how it is customised. i3 is configured through a plain text file with a fixed set of commands and directives. The user can bind keys to those commands and to external programs, but the behaviour of the WM itself cannot be programmed. Changing the configuration also means editing the file and reloading, rather than changing behaviour while it runs. i3 does provide an IPC interface over a socket that external programs can use to send it commands and query its state, but this means writing a separate program that sits outside the WM and talks to it, rather than writing logic inside it. + +The WM I plan on building uses a scripting language to run the code live and allows the user to design their workflow to do anything cool they can think of in a live runtime. + +^ i3 (2026). i3 User's Guide. [online] i3wm.org. Available at: https://i3wm.org/docs/userguide.html [Accessed 7 October 2026]. + +## Target users + +The window manager is aimed at advanced Linux users who want to control their workflow through code rather than a fixed configuration file. + +### Stakeholder 1: Keyboard-driven tiling WM users + +Users of window managers such as `i3`, `bspwm` or `dwm` who are comfortable in a terminal, edit their configuration by hand and control most of their desktop from the keyboard. + +These users already bind keys to launch programs and move windows, but they are limited to the commands the WM provides. With this window manager they could write their own behaviour, such as a keybind that cycles through windows of the same application, or a rule that automatically moves new terminal windows to a particular workspace. + +### Stakeholder 2: Developers and sysadmins who work remotely + +Users who regularly connect to remote servers over SSH and sometimes run graphical applications on them through X11 forwarding. I am part of this group, so I can also act as a source of requirements here. + +They would run the window manager locally and expect forwarded applications to behave like any other window: placed, tiled, focused and moved between workspaces. They could also script context-specific layouts, for example a keybind that opens a terminal and an editor side by side for a particular project. + +X11 compatibility (which is why I chose X11 over Wayland), workspaces to separate projects or machines, reliable focus handling and fast response to input. + +Stability matters most to this group. If the window manager crashes, they lose their whole graphical session, including any forwarded applications. A mistake in a script should be reported clearly without taking the session down. + +Since the project is aimed at advanced users, I am not providing a graphical settings tool, panels or a taskbar, and I do not plan to support minimised windows. These are the responsibilities of a desktop environment rather than a basic window manager, and the stakeholders above are comfortable working without them. + +They can script these features in using my api and other libraries if they want however. + +## Success criteria + +|No.|Stakeholder need|Feature|Success criterion| +|---:|---|---|---| +|1|Change behaviour without restarting the session|Runtime mruby scripting|Editing a script and reloading it changes the WM's behaviour without restarting the WM or the X session| +|2|Fast keyboard-driven control|Scriptable global keybinds|A script can bind a key combination to an action, and it triggers every time with no noticeable delay| +|3|Automate behaviour when windows appear|Window event handling|A script can run code when a new window is created and change its position or workspace| +|4|Organise tasks and projects|Workspaces|The user can switch workspaces and move windows between them using keybinds| +|5|Predictable layout|Tiling and placement|New windows are placed automatically, do not overlap and fill the screen| +|6|Control over which window receives input|Focus and stacking|The focused window receives keyboard input and the user can change focus using the keyboard and mouse| +|7|Remote graphical workflow|X11 compatibility|An application forwarded over SSH is managed in the same way as a local window| +|8|Trust that the session is safe|Error handling|A script containing an error is caught and reported without crashing the WM| +|9|Responsive desktop|Performance|Opening, moving and switching windows feels immediate| +|10|Approachable scripting|Scripting interface|A new user can write a working keybind in a few lines of Ruby using the documentation provided| + +## Language choice + +This project involves two language decisions. +The first is the scripting language, the one users write their configuration and behaviour in. +The second is the host language, the one the window manager itself is written in. + ### Embedded Scripting Embedded scripting languages are programming lanaguges that are designed to be embedded in a host programming language. The embedded language is often an interpreted language while the host is a compiled static typed language. They allow adding code to the program that can be modified and interpreted at runtime. They are often used to extend on the functionality of the host language. And they also allow using functions defined in the host language which are usually much more performance optimized. @@ -91,12 +167,75 @@ More specifically we will use the `mruby` version as it allows for embedding a l ^ Mruby.org. (2026). mruby - Lightweight Ruby. [online] Available at: https://mruby.org/ [Accessed 13 May 2026]. ^ Ruby (2019). Ruby Programming Language. [online] Ruby-lang.org. Available at: https://www.ruby-lang.org/en/ [Accessed 13 May 2026]. -## i3 +### Host language. -A similar alternative to my WM is i3WM, +I did not settle on the host language by reasoning alone. I built three prototypes, and the final choice comes from what each one taught me. -It follows a similar concept of customizable and tiling WM system but its configuration is static +#### Criteria +Before describing the prototypes, I've set out what I am judging them on. +These come directly from my success criteria, so the choice rests on the needs of my stakeholders. + +|Criterion|Linked success criteria|Why it matters| +|---|---|---| +|Runtime performance|2, 9|Keybinds and window operations must feel immediate| +|Stability and type safety|8|A crash ends the user's whole graphical session| +|C interoperability|1, 7|Needed to call xcb and to embed the mruby VM| +|Distribution|10|One program is easier to install and run than a collection of scripts| +|Tooling and iteration speed|n/a|I am the only developer, so slow builds directly slow the project| + +I included tooling deliberately. For a solo project, a toolchain that costs hours each week is a genuine technical constraint, not a matter of taste. + +#### Prototype 1: Ruby with FFI bindings to xcb + +My first version used standard Ruby, calling xcb through FFI bindings. I started here because I already knew the language well, and it let me learn the X11 protocol (connections, event loops, MapRequest handling, key grabs) without also learning a new language. + +This worked as a learning tool. I got a basic window manager running in a couple weeks, and it confirmed that my understanding of the X event model was correct. + +I abandoned it for two reasons. +1. The first was performance. Ruby is not built for performance. +2. The second was structure. The prototype had grown into a collection of scripts rather than a single program, with no clear module boundaries and no compile-time checking of the layout logic. For software whose main failure mode is crashing a user's desktop, finding errors only at runtime was a poor fit. It also meant users would need a Ruby interpreter and the FFI gem installed, which weakens the distribution criterion. + +Ruby was the right tool for prototyping but the wrong one for the finished product. + +#### Prototype 2: Haskell + +For the second version I wanted a compiled, statically typed language. I chose Haskell because a tiling window manager is largely a state-transformation problem: the layout tree, the workspaces and the focus are all data, and each event produces a new state. Haskell's algebraic data types, pattern matching and emphasis on pure functions suit this well. (A popular window manager `xmonad` is written in Haskell, which supports this reasoning.) + +I built [Add actual fueature set i made here.] in Haskell. +The state model was noticeably cleaner than in Ruby, and the project looked much better written. + +I stopped because of the toolchain. A full GHC installation took around 9 GB of disk space, [built it and add time taken here.] for a full build, and I found the surrounding tooling (Stack and Cabal, package resolution, version compatibility) difficult to work with. Each of these slowed down the edit, build and test loop, which matters when most of the work is trial and error against a live X server. + +Haskell showed me that the style of language was perfect for this problem, but the toolchain did not suit my workflow. + +#### Final choice: OCaml + +I moved to OCaml because it kept what I had worked with in Haskell and removed what had not. + +It kept a very similar code style, so much of my Haskell design carried over directly. + +It also kept the pattern matching and immutable datastructures as-is and the recursive style functions for a layout tree is the best way to work with such a project. + +But the compiler and tooling are far lighter (395MB, 463ms), and dune handles building and dependency management with far less friction than my experience of Stack. OCaml also compiles to native code, giving a single binary and solving the distribution problem that Ruby had. + +However OCaml has a smaller ecosystem, and no maintained xcb bindings that suited my needs existed. +So I wrote the bindings myself using ctypes, with a few small C shims where the C API was awkward to call directly. +This was more work than using an existing library. + +#### Comparison + +|Criterion|Ruby|Haskell|OCaml| +|---|---|---|---| +|Runtime performance|[measurement]|[measurement]|[measurement]| +|Build / iteration time|None (interpreted)|[time]|[time]| +|Toolchain size|[size]|~9 GB|[size]| +|C interoperability|FFI gem|[your experience]|ctypes + shims| +|Compile-time safety|None|Strong|Strong| +|Single-binary distribution|No|Yes|Yes| +|How far I got|Working prototype|[~X%]|Full implementation| + +Looking back, the main thing I would change is the order of work. Each rewrite cost weeks, and the real deciding factors (toolchain weight and C interoperability) were things I could have tested in a single afternoon. If I started again, I would write a small test in each candidate language that opens an xcb connection, receives one event and calls into mruby, and compare the results before writing any real logic. That said, the prototypes were not wasted: the Ruby version taught me the protocol, the Haskell version taught me how to model the problem, and the OCaml version applied both lessons. ## @@ -122,8 +261,7 @@ This was kinda the preface section on X11 and WM's, now we do analysis of the pr starting with what im deciding to build to actually go through this, with a section comparing xcb and the X11 library and then other x11 tools like xrandr etc. -and here about other similar systems like i3, awsome, bspwm, the suckless one, and similar for minimalism, and also gnome and xcfe and why that would be out of scope for this but how these work with X11 with -focus on the reparenting system that is standardised among these even though it is not stricly a rule needed. +focus on the reparenting system that is standardised among these even though it is not stricly a rule needed. (and the fact that im not doing it.) and here focus on teh exact rules laid out by icccm and netwm and how much would be needed to get working and how much would be needed for full compliance which might not even be possible in certain situations @@ -135,52 +273,4 @@ while using O notation to show what complexity every component has and maybe eve Then a sort of indev testing report of what works what changes i had to make to the initial requiremnts due to complexities arising etc. ---- - -and now for sections on each additional component - ---- - -first the bar, research on common bars used in minimalist systems and comparisions with bars in like windows, feature wise. (also ones like polybar etc.) - -and then a list of info i might need on the bar building on top of that section of what is commonly done - -then a diagram of the flow of states etc. of teh code and what objects and stuff i need to do, with requirements i plan on fulfilling with the bar - -then the actual implementation and logs etc. from that - ---- - -Then i talk about abstaction and code reusablity - -which i then exapnd on to talk about why i can reuse the same underlying system for command runner, clipboard and unicode selector, the fact that they all have a simple menu that can be sorted using searches and one can type a text at the top and hit enter to run it - ---- - -then a log of building this menu and then using it to build those 3 sub systems - ---- - -then teh notification daemon - -- i first focus on research for dbus and how it works and how do i get the notification data from the apps in the first place - -- then i focus on research behind existing notification systems like dunst etc. - ---- - -tying it up together - ---- - -here i can now show testing of the system and how it works and a little self evaluation on the implementation part of them first - -and performance reports and any bugs etc. i was unable to address. - -then i can show the integration of these components in a normal working situation while tying it up with the starting secion on trying to use a system without any WM, and showing how even with such a minimalistic setup we can work so much more efficiently than then - -and then comparing what i built out with other ones liek xfce i3 and all in terms of how it turned out. - ---- - then a section on what i learnt from building this system and what i could do more and how it makes me appriciate windowing systems and parts of our computers that most people ignore while actively using