stardance has been extended another month! the new deadline is october 31 :)

You are browsing as a guest. Sign up (or log in) to start making projects!

nwwm

  • 8 Devlogs
  • 30 Total hours

a WIP tiling window manager for X, inspired by dwm

Ship #1 Changes requested

I made nwwm, a simple tiling window manager for the X windowing system, a popular display server for Linux. Its job is basically to decide where windows go on the screen and how they should look, as well as listen to keypresses and decide what should happen. I ran into quite a few issues since I was using Rust which is not a language I’m 100% familiar with, and this was also my first proper systems-level project, but I managed to pull through and I’m really happy with where nwwm has gotten.

Some features include:

  • Tiling
  • Multiple workspaces
  • Support for docked windows, like statusbars
  • Config loading from ~/.config/nwwm/config.toml
  • Configurable keybinds
  • (Barebones) EWMH support

Since this is a Linux project, I know that most people won’t be able to test it so I’ve made a small video showing off some of the core features. You can view this video on the website, just scroll down to the “Demo” section and play the video.

  • 8 devlogs
  • 30h
Try project → See source code →
Open comments for this post

5h 57m 33s logged

devlog #8 - the end is near

stardance is coming to a close, the school holidays are nearing, and I’m running out of things to add to nwwm so I think I’m going to ship it here. I’m really happy with how far I’ve come in this project and I’ve learned a ton about X11, Rust, and myself.

GAPS!!

every good modern tiling window manager has gaps, so naturally I added them to nwwm. you can configure them in the config.toml through the gaps_inner and gaps_outer rules. gaps_inner controls the gaps between the windows themselves, and gaps_outer controls the gaps between the windows and the outer edge of the screen.

other essentials

I also added the ability to move windows between two workspaces. you can now set keybinds with the movetoworkspace <workspace> action to move the currently focused window to <workspace>. this was fairly easy to implement but I did run into a bug where the wm wasn’t correctly selecting a new window to focus after the focused window was moved to another workspace. I also finally added the ability to move focus backwards instead of just forwards, which you can do with the focus last action.

promotional material

I also sunk a few hours into making a cool little website for nwwm. it’s pretty generic but it gets the job done, and has a demo, config, screenshot, project description, and an example config file. you can see the website at annaxiomm.github.io/nwwm. finally, I made a simple logo in the form of a compass (because nwwm stands for North West Window Manager :wink2: )

next steps

  • ship it
  • cash in my loot
0
0
26
Open comments for this post

1h 2m 25s logged

devlog #7 - sanity check

a bit of a short devlog here, but I decided to take a break from programming to make the repo look a bit more presentable (I’m planning to ship soon so it needs to look good for the camera!)

README changes

the existing README was quite barebones so I fully fleshed it out with a bunch of new stuff, including a proper testing tutorial, configuration help, and an entire section dedicated to what’s wrong with the project and what I’m going to fix when I decide to try and rewrite this bowl of spaghetti at some point

next steps

  • cleaning up the project, writting code comments, etc
  • polishing up the project with some final features, like vanity gaps
  • making a landing page for the wm because I know that when it comes time to ship, most people won’t be able to try out nwwm for themselves so I want to make a little showcase (so I don’t get a bad grade for usability!)
0
0
127
Open comments for this post

3h 59m 22s logged

devlog #6 - CONFIGURATION!!!

adding a config file has been in the next steps of just about every devlog i’ve made, and i finally got around to doing it!

config.toml

nwwm wouldn’t be a cliche rust project without a config.toml. but in all seriousness, i really like toml as a configuration language and it integrates really cleanly with rust anyway. so far, you can set parameters like window border, mod key, and default layout in $HOME/.config/nwwm/config.toml and nwwm will read those and apply them at runtime. unfortunately, config isn’t reloadable at the moment (next step?). you can also configure keybinds and even startup commands! i would really have liked to have lua scripting as a config but it’s just a bit too hard for a first wm project. the error handling is pretty hairy at the moment but i’ll fix that soon i promise

other stuff i’ve changed

not much else happened, but i added a feature where debug logging only happens if you run nwwm with -v or --verbose.

next steps

  • better error handling in config loading
  • config reloading at runtime
  • better documentation (maybe a website?)
1
0
18
Open comments for this post

6h 26m 15s logged

devlog #5 - self hosted?

ok it’s been quite a while since my last devlog but i’ve added a ton of new stuff - to the point where nwwm might become my main window manager soon!

docks n’ struts

“what even are those?” i hear you ask, and fear not because i am here to answer. a docked window is any kind of window that isn’t tiled, doesn’t belong to any workspace, and reserves space on the screen that other windows can’t take up. a really common example is a status bar: it persists between desktops, and reserves space on the screen. a strut is basically the space on the screen that it reserves. i implemented support for this so you can now use your favourite status bar with nwwm! i also spent like 3 hours debugging an error that happened sometimes when you closed a docked window, and ended up fixing it by complete accident

workspaces 🧰

a window manager is basically useless without workspaces, so naturally i’ve added them to nwwm. they were actually quite easy to implement since i’ve technically supported them since day 1 i just never added workspace switching. basically when you switch a workspace it checks to see if the workspace exists, then it unfocuses the current window, unmaps (hides) all the windows in the current workspace, switches to the new workspace, maps (shows) all the windows in the new workspace, and focuses the first window in the new workspace. phew, try saying that in one breath!

status bar compatibility

as i mentioned earlier, i added struts and docks so that status bars can reserve space on the screen, but i also added some ewmh hints that allow status bars to see and change the current desktop. this was really easy, i just had to add some atoms and listen for ClientMessage events, and then connect those to my existing code

next steps

  • config file loading
  • more ewmh 😭
2
0
146
Open comments for this post

3h 36m 35s logged

devlog #4 - +10 usability!

we’re now shifting from the realm of “experimental” to “experimental but usable”. i’ve added a ton of new features recently and i’m really happy with how nwwm is coming together.

actually good tiling

i’ve added 2 new tiling layouts: monocle, and master/stack. monocle is the easiest to understand: all windows are the same size as the screen, and the currently focused window is brought to the front. master/stack is the traditional layout you see in wms like dwm, where there is a “master” window that takes up half of the screen and the rest split vertically (or “stack”) on the other half of the screen. i also added keybinds that switch between layouts

revamped keybind system

previously, the keybind system was just using raw x11 keycodes which were really annoying because they don’t match up with any other system (25 = w??) and are keymap-dependant. so, i switched to using xkbcommon and now keybinds are defined with more human-readable keysyms like KEY_w or KEY_Return.

i also implemented a small command runner system so now you can launch commands with keybinds. so far i’ve set Mod+Enter to launch kitty and ofc these will all be configurable through the config file

mysterious bugs

i spent ages trying to debug some weird behaviour where bound keys wouldn’t register as keypresses if no windows had been opened in nwwm yet. after a lot of trial and error, and a few ChatGPT therapy sessions, i discovered that my error was one letter: i had keyboard_mode in the global mouse grab (which i need for click to focus) set to GrabMode::Sync instead of GrabMode::Async (fml)

next steps

  • more usability (moving windows, closing windows)
  • better EWMH compliance
  • support for temporary and permanent floating windows (i.e. tiled windows that you make float, and windows that only float like rofi)
  • config file when?
0
0
12
Open comments for this post

3h 34m 25s logged

devlog #3 - wow! visuals!

how many times can i call conn.send_request() in one program??

config file

i made a struct called Config which the wm owns, and it has values like border width, color, and keybinds. eventually it will read from a config.toml file but for now it’s all hard coded in the source code.

window borders

windows now have borders with color and width deriving from the Config (meaning they’ll be configurable through a config file at some point!). also, the currently focused window has a different border color (also configurable!)

modular keybinds

instead of hard-coding keybinds, i gave Config a child called Keybinds, which are hard coded in the source code… but eventually they’ll be part of the config file. when each keybind is called, it calls an Action which is linked to a function call in the wm. later there’ll be plenty of actions for anything you can think of, but for now theres only FocusNext which… focuses the next window!

next steps

  • config.toml loading
  • better tiling (again)
  • gaps
  • EWMH compliance
0
0
14
Open comments for this post

2h 52m 46s logged

devlog #2 - an actual window manager

x11 is an ancient beast, full of mismatched types (screen height is a u16, window height is a u32, window position is an i32, etc), difficult protocols, and more double colons than you can shake a stick at, but i’m working through it.

a (tiling) window manager

i started off by storing a list of open workspaces in the main wm struct, and each workspace has a list of open windows (and a tiling layout). then, i made the wm listen for DestroyNotify events and remove them from their respective workspaces. soon after marvelling at my creation i realised that i could only see one window at a time, so i worked on implementing a basic tiling algorithm. so far, all i have is columns (window_width = screen_width / num_of_windows) but i’m working on adding master-stack tiling (what dwm uses)

focus!

i also realised that it’s no use having multiple windows if you can only use type on one, so i made each window grab the left click, and then listen for ButtonPress events, focusing the clicked window.

next steps

  • more tiling layouts
  • cosmetic stuff (borders, gaps)
  • keyboard shortcuts
0
0
14
Open comments for this post

2h 36m 41s logged

devlog #1 - getting things started

after working on tundra I decided that I wanted to make a window manager for an actual os instead, so I loaded arch onto an old macbook and got started.

xlib woes

I initially started by loosely following a tutorial that uses xlib for rust, but I soon realised that any direct mapping to C from rust is going to be an absolute horror to use (literally every function call had to be unsafe), so I switched to xcb. it has a slightly different API but it’s cleaner and i3 uses it so it must be good.

current features:

  • it runs
  • it doesn’t crash
  • you can open a window (by externally injecting it from a command prompt

next steps:

  • storing open windows in a struct / list
  • basic tiling
0
0
13

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…