Solutions to the tiny window manager challenge
source link: https://jvns.ca/blog/2019/12/03/solutions-to-the-tiny-window-manager-challenge/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Hello! Last week I posted a small programming challenge to write a tiny window manager that bounces windows around the screen.
I’ll write a bit about my experience of solving the challenge, or you can just skip to the end to see the solutions.
what’s a window manager?
An X window manager is a program that sends messages to the X server (which is in charge of drawing your windows) to tell it which windows to display and where.
I found out that you can trace those events with xtrace
. Here’s some example
output from xtrace (for the toy window manager which is just moving windows
about)
000:<:02d8: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=560 y=8}
000:<:02da: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=554 y=12}
000:<:02dc: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=548 y=16}
000:<:02de: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=542 y=20}
000:<:02e0: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=536 y=24}
000:<:02e2: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=530 y=28}
000:<:02e4: 20: Request(12): ConfigureWindow window=0x004158e5 values={x=524 y=32}
you can run programs without a window manager
You technically don’t need a window manager to run graphical programs – if you want to start an xterm in a window-manager-less X session you can just run
xterm -display :1
and it’ll start the xterm. Here’s a screenshot of an X session with no window manager open. I even have 2 windows open! (chrome and an xterm). It has some major usability problems, for example I don’t think you can resize or move or switch between windows. Which is where the window manager comes in!
move a window with XMoveWindow
The challenge was to make the window bounce around the screen.
In the tinywm source they use XMoveResizeWindow
to move and resize windows,
but I found in the docs that there’s
also a function called XMoveWindow
. Perfect!
Here’s what it looks like. What could be simpler, right? And it works just the way I’d expect!
XMoveWindow(display, windowID, x, y)
Except…
problem: multiple XMoveWindow
s don’t work
I ran into a problem (which I got stuck on for a couple of hours) where when I ran XMoveWindow twice, it would only apply the last move.
XMoveWindow(display, windowID, 100, 200)
usleep(2000 * 1000); # sleep for 2 seconds
XMoveWindow(display, windowID, 300, 400)
I’d expect this to move the window once, wait 2 seconds, and them move it again. But that was not what happened! Instead, it would pause for 2 seconds and then move the window once (to the second location).
use xtrace to trace window manager events
I used xtrace to trace the events and found out that my ConfigureWindow
events that XMoveWindow
was sending were all being sent at the same time. So
it seemed like X was batching the events. But why?
XSync forces X to process events
I didn’t know why this was happening, but I emailed Julian about it and he pointed me in the direction of XSync, which forces X to process all the events you’ve sent it. Sure enough, I used XSync and everything worked beautifully.
solutions
I asked people to email me if they completed the challenge, and 4 people did! Here are their solutions. All the solutions I got implemented more features than I did, so I’d encourage you to look at all the solutions if you’re interested in how to solve this problem!
- Kacper Słomiński’s solution (which uses
XQueryTree
to find the windows to bounce, which is nice) - @whichxyj’s solution
- Alexsey Lagoshin’s stressfulwm, which allows bouncing multiple windows:
- Aldrin Martoq Ahumada’s bouncywm-ruby, which is the only solution in a language other than C I got! It uses an Xlib Ruby library that looks pretty straightforward to use.
- one really nice one with fancier bouncing effects which I’ll post here later if the person sends me the source
- my solution
Here’s a gif of Alexsey’s solution. Apparently XQuartz
on a Mac performs better than Xephyr!
And Aldrin’s solution, with a great use of xeyes
:
thanks!
Thanks to everyone who emailed me a solution, and if you write your own implementation I’d love to post it here too, especially if you write one that isn’t in C or Ruby! I’m [email protected]. (and if you write a solution but don’t want me to post it I’d still love to see it!)
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK