Hacker News new | past | comments | ask | show | jobs | submit login
TinyWM – A tiny window manager in around 50 lines of C (incise.org)
211 points by metadat on Oct 25, 2022 | hide | past | favorite | 59 comments




I'm really keen to hear from someone who knows a bunch about X and WL to hear why there's such a huge difference in line count here. Is this analogous to OpenGL vs Vulkan where WL is a much lighter layer than X is?


Yeah Wayland takes like 90% of the features of X and goes "you're on your own, window managers / desktop environments!" and if you complain they just say that's out of spec, working as intended, wontfix.

It's like the exact opposite of what the Linux desktop needed.


Wayland is the protocol. It isn't analogous to X, so they really shouldn't be compared. Comparing Xorg to something like WLRoots makes more sense.


X is a protocol just like Wayland. One of those protocols contains a standardized interface to implement window managers the other doesn't. The argument people are trying to make is that a display stack should have such a standardized interface.


It’s always quite ironic to me that the same people that want to burn SystemD at the stake for ‘trying to do everything, Linux programs should be small and modular’ also lambast Wayland for ‘not just implementing everything and the kitchen sink, like good old X used to do’.


It is just your personal assumption that they are the "same people". But it would make sense because due to lack of standardized interfaces Wayland forces every functionality into a monolithic implementation which is the opposite of small and modular.

X does not implement everything and the kitchen sink. A bare Xserver won't even be usable without a dedicated window manager, the compositor is completely replaceable and runs as a separate process, etc. Just because it is perceived by some to be bloated doesn't mean it is monolithic.


Links to further reading would be appreciated!


What Wayland really is a way for multiple applications to get access to and share dri/drm and evdev (kernel interfaces for putting stuff on screen and getting input respectively), nothing less and not much more. To enable that Wayland defines an IPC channel which is designed for extensibility, and there are some defined extensions to cover more desktop-like usecases (clipboards and whatnot). Some extensions are more widely supported by different compositors than others.

For links, this docs page listing many (all?) wl extensions kinda gives you an idea what wayland core does not handle, and also what in general is available through wayland: https://wayland.app/protocols/


https://wiki.gentoo.org/wiki/Wayland

Found that pretty quickly and it doesn't go down a point-by-point feature comparison but gives you some idea of what's up in the "introduction" where it notes that Wayland doesn't include things like keymapping functionality, so that's all up to each compositor to implement. Excerpt:

> From a user's point of view, Wayland is nothing more than a framework. In particular, Wayland itself does not implement any display server that should correspond to the Xorg server. In Wayland, compositors are display servers, implemented by various projects. A compositor also serves as X's window manager (and X's compositor).

> This means users first have to choose a compositor, and via that compositor they "configure the server", i.e. set screen resolutions, input and video drivers options, etc.

> [...]

> Some lack of specification results in chaos more or less. For example one common complaint as of 2021 is that key remapping is absent in the Wayland protocol - in Wayland there is nothing that corresponds to xmodmap of X. Each compositor offers, if any, their own way to remap keys.

> The situation however is not totally random - many compositors depend on the library "wlroots", which abstracts such common tasks, and is aimed to be impartial. First started as a subproject of the compositor Sway, it now is used by many compositors. Exceptions include mutter and KWin, i.e. GNOME and KDE, and Weston.

TL;DR minor WM/DE projects have circled around wlroots as a life-raft to fill in the missing functionality, while major ones have gone their own way, resulting in extremely basic functionality potentially being wildly different (and having a different set of bugs and quirks and how-to-configure-and-use-it) depending on which compositor you're running, or even simply being absent on some.

[EDIT]

Unsurprisingly, Gentoo's cousin distro (if you will), Arch, has an even better page on it:

https://wiki.archlinux.org/title/Wayland

Note especially the part where it's possible for a given compositor not to work with certain graphics hardware, while others will. That's how little help Wayland gives to desktop environments and window managers. To get the equivalent of Xorg you'd have to get everyone to agree on a single fairly-big and featureful compositor and only use that.

Or, good lord, look at the display manager support table. LOL.


It fits the UNIX philosophy just right though.


With x you're just bringing a window manager that plugs into the x-server. With wayland there's no standard 'window manager' plugin to arbitrary wayland servers. So the wayland example is doing more things (lots is handled by wlroots though).


TinyWM doesn't include an X server implementation, while TinyWL is a full wayland compositor (although most of the heavy lifting is done by wlroots)


Also not discussed - the wayland version implements a lot more features, comments, and boilerplate. The one in OP is 178 lines with comments and features basic window control.


It would be really interesting to see a Wayland version with equivalent functionally to the X one to get some idea of what the real difference is in complexity.


Can I make a wish? I would like a wm which sends SIGSTOP to processes which window I minimized and SIGCONT when I un-minimize it.

For processes which use multiple windows, I'd be OK with all being minimized when one is to allow above functionality.

There was a time when it was desirable to make room on the visible desktop while keeping long running processes running, but today we have lots of desktop real-estate and few legitimate long running processes, instead web pages leaching CPU cycles (I look at you, github!).


On i3, with `i3-msg -m -t subscribe '["window"]'` you can get events when you change focus. With that and possibly the aid of `i3-msg -t get_tree` or some generic X utility like `xdotool search --onlyvisible \^`, you should be able to figure out which windows are hidden and which aren't. With `wmctrl -lp` you can match window ids to process ids and send whatever signals you want from a daemon script.

> There was a time when it was desirable to make room on the visible desktop while keeping long running processes running, but today we have lots of desktop real-estate and few legitimate long running processes, instead web pages leaching CPU cycles (I look at you, github!).

That probably depends on the person. It's not weird for me to have a web server running in the foreground of a terminal that's sometimes hidden. If it's stopped, it's not going to respond to my requests. It's in the foreground because there are times where it'll provide me a console to inspect the running state of the backend.

Same when I'm running an strace on a PID. Sometimes that terminal gets hidden. If that's stopped, the program whose PID I'm tracing is going to get frozen at some point.


You could run the web server (or other long running processes) within screen in the terminal, but yeah, that's stretching it.

I look into i3, thanks!


If your concern are webpages, you should first try sending SIGSTOP manually to some PID. Stopping a particular webpage may not be doable by stopping PIDs. There's nothing stopping multiple processes being involved in managing multiple windows non-exclusively (i.e. not only can a process manage multiple windows, a window can be managed by multiple processes). Your web browser may be beast enough to really complicate what you're trying to do.


Better to just add a new stop button rather than overload minimization. In any case, if your concern is web pages, your browser needs to implement this, not your window manager (unless you are not using tabbed browsing, which I doubt).


Do you happen to know why web browsers don't already do something like this? I find that a large number of domains are called every minute. I say domains as most of them seem to be providing Javascript, although some of them are the web site I have loaded. Very occasionally I can see a legitimate purpose, such as refreshing a page showing a web interface to an email account, but most of the time there doesn't seem to be a legitimate purpose.

Btw, this is from using Little Snitch on the Mac. If I temporarily block the refresh, nothing bad ever seems to happen.


I suspect there are just too many real things it would actually break. Alarm clock websites, for instance, off the top of my head.


Actually, I avoid using tabs. Reason being that I often have way too many pages displayed and have then difficulties finding a give one (chrome's taskmanager comes to the rescue, but that's not the most convenient workflow). The 'window list' applet of the DE allows me to find windows, but not tabs.


FWIW, I think that feature can be added to StumpWM using a few lines of code in .stumpwmrc


From looking at the Issues on GitHub, it seems that someone ported it to XCB:

https://github.com/rtyler/tinywm-ada/blob/master/tinywm-xcb....


Also, as the repo name suggests, the Xlib version is ported to Ada in there.


I used this as a starting point when playing around with writing my own WM, was very surprised with how little there is to it


Even without the comments, it's so great to have concise, fully functional sample code when you're trying to understand how something works.

I love any time I can spend 2 minutes reading code instead of 20 minutes piecing together the basics from documentation.


Probably worth pointing out that while this will appear to work, it's certainly not ICCCM [0] compatible, so a lot of toolkits and applications that assume ICCCM compatibility will break.

[0] https://www.x.org/releases/current/doc/xorg-docs/icccm/icccm... , one of the standards for how WMs and X11 applications should communicate.


This kind of software really needs some screenshots.


Not much to show. Running startx with .xinitrc containing:

  xterm &
  glxgears &
  exec /usr/bin/tinywm
you get: https://files.catbox.moe/m0ejwr.png (pointer isn't shown but it's there)


From looking at the code there isn't much to screenshot. It doesn't seem to add decorations to the windows, just allows sizing and positioning. So a screenshot would show some windows from other applications without a frame. All value is in the source code showing principles.

(I might have missed something)


The absence of frames or other elements is extremely valuable to understanding what the window manager does/does not have control over.


It's like 50 lines, just imagine what it would look like :P

It doesn't look like it's drawing any title bars or borders or decorations of any kind.


If I’m not already very familiar with X, how am I supposed to know that?


The purpose of this code is not to provide a useful WM.

It's to illustrate the minimum, in case you want to play with it and become very familiar with X.


How to draw my own window decorations is exactly what I'd be interested in learning.


Twm, dwm or aewm might be good places to start for that


I would expect their code to be written in ancient C. Probably not an easy read (I once tried to figure out how to use non-bitmap fonts by reading xterm's code - so I could help Paul Mattes in adding my font to x3270, but came out with a headache).


Every line of code has paragraphs of text describing what it does.


We read it, but, still it's hard for someone with little experience with X window managers (fun story - I built a minimal graphical WM for the Apple II that fit in 1K) to have an idea.

Also, I'm a visual thinker - nothing picks my curiosity about software like a nice screenshot.



That’s really minimal, even for x11: it doesn’t even do reparenting and setting up window borders or xdamage/xfixes compositing


It looks like X Window does most the of rendering, correct? (based on header: "#include <X11/Xlib.h>")


Yes, that's sorta fundamental to how X works. Window managers aren't at all responsible for drawing the contents of the windows.


Wonder how hard could it be to add tiling support?


You don't even strictly need it in the WM, as you can resize windows from other programs, even shell script with xdotool etc, although xdotool/shell quickly becomes somewhat unwieldy I once wrote a "tiling WM" like this. It actually worked fairly well, and I kind of liked the modularity of it.

At any rate, I dug up the old thing: https://pastebin.com/i91yD96F – I also had some other scripts to control window placement, movement, etc. I once planned to rewrite it to a "real" language and combine it with a "slightly less tiny wm" as a full release, but never really got around to it, and I also don't really use tiling any more (I just have one full-screen window all the time).


Not very hard as long as you don't care about drawing window frames.


So... why C instead of at least C++ or an even better memory safe language?


The page linked offers a Python version calling into Python's Xlib binding python-xlib. It's the third code box down, after the bare C version and the heavily commented C version.

Xlib itself is in C.


Because it's the author's program, and they chose C.


Because then it's no longer minimal. And as mentioned there's a Python version.

This isn't a "real program", as such. It's a demo or "rainy Sunday fun to figure out a bit how X11 works".


> Because then it's no longer minimal.

C "might" be minimal but it brings with it a whole lot of dangerous baggage. Other languages can be just as minimal without the baggage.

> This isn't a "real program", as such. It's a demo

I didn't mean to imply anything different. I was just curious why C was used in the modern day where we (all?) know that C is a language that _should not_ be used for demoing because less experienced devs will think they can use C too and continue to create dangerous code


> why C was used in the modern day

  /* TinyWM is written by Nick Welch <mack@incise.org>, 2005.
   *
   * This software is in the public domain
   * and is provided AS IS, with NO WARRANTY. \*/
> we (all?) know that C is a language that _should not_ be used for demoing because less experienced devs will think they can use C too and continue to create dangerous code

That seems rather patronizing.

I have no great love for C; it has sharp edges for sure, but it can be used just fine for a great many things even today. I've written a bunch of C programs because it's simple, straight-forward, "just works" (mostly), and I'm not writing OpenSSL or a network daemon so if I have an occasional buffer overflow it's not even a big deal.


CWM written in C works better over the years. Compiling C++ software from 2004-2007 can be a nightmare.

Also, on C, please, get OpenBSD and check their security practices.


Pff, that's modern C. K&R C was a bit more of a challenge. I wonder if there's any of my old industrial code on QNX still in operation? I wrote it in the early 90's after ANSI C was available as the ANSI compiler didn't interwork with the GUI.


C is fine. It’s the programmer that makes mistakes


But that's exactly my point! Other languages help to prevent the programmer from making mistakes that are common in C


C is fine. Leave it alone




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: