An Xlib-based Screen Ruler in Python

In my bad prediction (in both senses of the word) on what we'll see in the intensive care stations I've mentioned a screen ruler I've written.

Well, since I've still not properly published it and I doubt I'll ever do that without further encouragement, let me at least mention it here. It's pyscreenruler. I've written it because all the other screen rulers for X11 I found in Debian (and a bit beyond) would only let you measure either horizontal or vertical lines. I, however, needed to measure slopes, as in this part of the curve for the SARS-2 patient count in German critical care stations:

Plot: curve with a ruler

– which, by the way, shows that, surprisingly to me, our patient numbers still go down exponentially (if slowly, with a halving time of almost two months). Hm. But today's point is pyscreenruler, which is what has produced the ruler in that image.

When I wrote this last November, I quickly found Tkinter (which is what I still usually use to write quick graphical hacks) doesn't really support shaped windows – and anything but shaped windows would, I figured, be extremely painful here. Plain Xlib would make the shaping part relatively straighforward. So, I based the thing directly on the Xlib even for the remaining code.

That brought forth fond memories of programmes I wrote on Atari ST's GEM in the late 1980ies. For instance, with the explicit event loop; on the left code from November 2021, on the right code I touched last in March 1993 (according to the time stamp):

def loop(self):                     void event_loop(watch *clstr)
   drag_start = False               { [...]
   while 1:
       e = self.d.next_event()        do
                                       { event =  evnt_multi(
       if e.type==X.DestroyNotify:        MU_MESAG|(clstr->on?MU_TIMER:0),
           sys.exit(0)                      2,0x0,1, [...]
                                          if (event&MU_MESAG)
       elif e.type==X.Expose:               handle_message(pipe,clstr);
           [...]                          if (event&MU_TIMER)
       elif e.type==X.KeyPress:             updclck(clstr);
           [...]                       }
       elif e.type==X.ButtonPress:     while(1);
           [...]                    }

I'd not indent C like on the right any more.

For the record, Xlib's next_event call looks simpler that GEM's evnt_multi because you configure all the various parameters – what events to listen for, timeouts, and so forth – in other calls.

Oh, the contortions one has to go through to have updates when a part of the window is exposed (I'm playing it simple and just use offscreen pixmaps)! Or the fact that the whole thing will (I think) not run on displays with 8 and 16 bits of colour. Or the (seemingly) odd behaviour of programmes if you do not at least implicitly wait for the window to be mapped (in actual pyscreenrules, I sidestep the problem by deferring all painting to the screen to the expose handler). And X won't tell you about mapping unless you ask for it. And so on. Note to self: Next time you write an Xlib programme, let Christophe Tronche remind you of the various little quirks before hacking off.

Anyway: If you need a rotatable ruler, install the python3-xlib package (that's really all it needs), download pyscreenruler, make it executable and start it. If you click and drag in the inner half of the ruler, you can move it around, if you click and drag on the outer parts, you can rotate the thing (which you can also do by hitting + and -).

What's missing: Well, I could imagine letting people change the length of the thing (shift-drag on the edges, perhaps?), then giving length and angle in text somewhere. And it's thoroughly pixel-based right now, which it shouldn't be when there's displays with 200 dpi and more out there.

Send mails and/or patches to make me properly fix it up. Since I've really missed it, I could even imagine packing it up for Debian...

Kategorie: edv