Revising the spectacle hack-fix

Not too long ago I talked about my quick and dirty workaround for KDE’s screenshot capture utility being … less useful than I’d like thanks to a(n upstream) Qt bug.

To recap:

  • When you try to capture rectangular region of the screen, Spectacle (said screenshot utility) will freeze the entire desktop and allow you to draw a square
  • If you’re running a multi-monitor setup with high PPI monitor(s) under Xorg, the image of your frozen desktop will be moved partly off-screen.
  • This means that you will not be able to see or select a certain portion of the screen

My solution amounted to a few console commands bashed together that move the frozen desktop frame back where it’s supposed to be.

This has downsides. For example, the issue only gets fixed when you trigger screen capture with a keyboard shortcut. If you tell Spectacle to capture a screenshot after a timeout, the issue won’t get fixed. It’s also not guaranteed to work if you have multiple Spectacle windows already open from previous screen captures.

That’s not good enough.

What about fixing the problem at the source?

From this point forward, there are roughly two options. I can try to use Xlib (with which I had a very brief encounter some time ago) and watch for new Windows getting launched, or I can do the right way and fix Spectacle. After all, we are talking about open source software.

Thus I go ahead and clone Spectacle’s github repo. I start looking at the code and notice the first problem: it’s written in C++.

I’m doing javascript/typescript by the day, bash on a very odd weekend, python if I really have to. C# has been sitting on a shelf since my diploma, Java for longer (though it’s getting dusted off lately). C is a faded memory from like three classes in entire university. Obviously advanced C is the last program language I’d prefer to use.

Still, I dig through the code, trying to find if there’s any place I can see that sets the spawn position of the frozen frame. One and a half hour later, I just give up. It’s time for Xlib.

X gon give it to ya

After giving up on Spectacle, I go back to whipping up my dirty hacks. I start shopping for functions that I want and incorporate them into my program. Eventually, I’m far enough to do a test compile. This is where I get to witness this bullshit.

We are witnessing a missing import. The question on the table is which. As we start looking for an answer, we run into another problem: C and Xorg were both designed before stackoverflow existed.

They were designed in a time where people assumed people will actually read the _entire_ documentation before trying to write their first “hello world” thing. The “you need to import this file” will be hidden as an offhand mention in one of the two tutorials you were linked to kick things off (and it’s always gonna only be in the tutorial you didn’t check), and then never again.

If you’re doing your function-shopping on stackoverflow code or by browsing the list of functions on websites that are basically manpages but with links, you will miss that. Documentation and manpages for functions will treat the necessary import as if it were a recipe for coca-cola.

It’s X11/Xutil.h. Is it really that hard to put on a manpage, or am I just missing something because I have literally no experience?

Anyway, back to track.

The program is set to log window titles, which it does … Except the values aren’t quite what we’d want. We expect to see “Spectacle” appear (and nothing else) — but nothing of the sort pops up:

What gives? There’s two thing, actually. One: we’re requesting “WM_NAME” property, when we really want “_NET_WM_NAME.” Second: we’re requesting CreateNotify events, but Qt may be changing titles (and geometry) after creating windows. This means we need to catch ConfigureNotify events as well.

When we listen for ConfigureNotify events as well, we finally get what we want:

When we log _NET_WM_TITLE and WM_TITLE during the process of taking a screenshot, we can clearly see that title ‘Spectacle’ doesn’t get set immediately after window creation.

The hard part seems to be over now. All we need is another strcmp to compare _NET_WM_TITLE with and XMoveWindow, both pretty straightforward. (And we can’t forget to set up an error handler, because BadWindow will happen every now and then. We can ignore this error).

Now let’s try to figure if this hack can work with vlc and smplayer as well …

(Code is available on github)

Spain forget to check themselves, wreck themselves

So here’s a fun thing that happened today in the Spanish-Catalonian dispute. Catalonian leaders stated they want to follow the ‘Slovenian way’ to independence. Spain was quick to reply with: “ye you mean that violent conflict that ended dozens of lives?” Meanwhile in Slovenia, Slovenian foreign ministry invites Spanish ambassador to have a much-needed history lesson.
The abstract of the history lesson goes somewhere along these lines:
  • Slovenia to Yugoslavia: “gib independence”
  • Yugoslavia: “No.”
  • Slovenia: “But we insist.”
  • Yugoslavia: invades
  • Croatia and Bosnia: are also tossing shit around at the time
  • Yugoslavia: decides that waging war against Slovenia isn’t too viable when they also have to deal with Bosnia and Croatia, retreating from Slovenia only 10 days after invading
  • The end.
Which leaves us with two explanations for behaviour of Spanish politicians:
  • Spanish politicians are uneducated twats in a dire need of a history lesson
  • They had their history lesson, this is just them issuing a low-key threat to Catalonia
Knowing how badly Spain is reacting to Catalonian independence, both seem equally plausible. Oh and by the way: it’s okay to not know the history of every square inch of the planet. Nobody needs to know the entire history of every little country on the planet. But if you are going to make a reference to it, then at least check the facts. It’s really not that hard.