A longcat, you say? Yep, a very looong cat…

Long cat is an accidental byproduct of my misadventures with something called Hyprland. Hyprland is an ambitious attempt to combine a tiling window manager, extreme eye candy, and a Unix style approach to the desktop environment. Nearly everything in Hyprland is controlled by small dedicated scripts or programs, so you can “just” swap out individual components.
I like weird computers, and one of my favourite weird computers in recent times is a sort of science experiment which escaped the lab and now runs feral. It’s a first generation dual screen laptop called a YogaBook 9i, made by a much loved vendor of tech for Salarymen and Catgirls. You can find it in clearance sales and suchlike as it has been superseded by newer models.
After a ropey start my machine runs Linux pretty well now, but when using Hyprland the screen wouldn’t auto rotate when you change the laptop’s orientation, like you might expect it to. It’s not the end of the world, because you can always set up a keyboard mapping to run the necessary commands to change the screens’ orientation. But I wanted it to happen automatically, like this…
Because Hyprland’s motto is essentially some assembly required, sometimes we have to figure out how something like automatic screen rotation actually works. In the YogaBook’s case it turned out that first of all I needed to get the iio-sensor-proxy subsystem working. This sends sensor events such as accelerometer data through to the D-Bus desktop bus where they can conveniently be processed by user apps.
Once I had iio-sensor-proxy up and running, I tried some code that other people had written to plug IIO data into Hyprland, like iio-hyprland. However, the YogaBook is weird hardware so there are some gotchas, like the fact that one screen is technically mounted upside down. To get around this, I ended up writing my own hacky shell script to track accelerometer events using the monitor-sensor tool (this blocks waiting for input, so it’s OK to use in a shell script) and the hyprctl tool to rotate both screens appropriately. Here it is, in case it’s useful for you - just call it from your Hyprland config using exec-once = PATH-TO-THE-SCRIPT:
#!/bin/bash
notif="$HOME/.config/swaync/images/ja.png"
monitor-sensor --accel 2>/dev/null | while read -r LINE; do
ROT=${LINE#*: }
case "$ROT" in
"normal")
hyprshade on retromod.glsl
hyprctl keyword monitor eDP-1,preferred,3082x0,1.5,transform,2
hyprctl keyword monitor eDP-2,preferred,3082x1200,1.5,transform,0
hyprshade off
notify-send -e -u low -i "$notif" " Supine Position"
;;
"left-up")
hyprshade on retromod.glsl
hyprctl keyword monitor eDP-1,preferred,left,1.5,transform,3
hyprctl keyword monitor eDP-2,preferred,right,1.5,transform,1
hyprshade off
notify-send -e -u low -i "$notif" " Sinistral Vector"
;;
"right-up")
hyprshade on retromod.glsl
hyprctl keyword monitor eDP-1,preferred,left,1.5,transform,1
hyprctl keyword monitor eDP-2,preferred,right,1.5,transform,3
hyprshade off
notify-send -e -u low -i "$notif" " Conduire à Droite"
;;
"bottom-up")
hyprshade on retromod.glsl
hyprctl keyword monitor eDP-1,preferred,3082x0,1.5,transform,0
hyprctl keyword monitor eDP-2,preferred,3082x1200,1.5,transform,2
hyprshade off
notify-send -e -u low -i "$notif" " Bottoms Up!"
;;
*)
# we'll ignore anything else
;;
esac
done
What’s that hyprshade? Well, a big part of Hyprland is the eye candy, and I thought it might be fun to apply a shader to the display as the orientation changes. The hyprshade tool lets you do this from a script, although please note that not all shaders are compatible with Hyprland. The shader I’m using is a modified version of a modified version, found somewhere on teh Interwebs, so your mileage may vary. But if things work out right it should briefly turn the screen into something like an old CRT display as the screen(s) rotate. NB If it doesn’t work, you might get a blank screen and need to type hyprshade off to get things back to normal!
//modified version of [this shader](https://github.com/wessles/GLSL-CRT/blob/master/shader.frag)
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D tex;
void main() {
vec2 tc = vec2(v_texcoord.x, v_texcoord.y);
// Distance from the center
float dx = abs(0.5-tc.x);
float dy = abs(0.5-tc.y);
// Square it to smooth the edges
dx *= dx;
dy *= dy;
tc.x -= 0.5;
tc.x *= 1.0 + (dy * 0.23);
tc.x += 0.5;
tc.y -= 0.5;
tc.y *= 1.0 + (dx * 0.23);
tc.y += 0.5;
// Get texel, and add in scanline if need be
vec4 cta = texture2D(tex, vec2(tc.x, tc.y));
cta.rgb += sin(tc.y * 1250.0) * 0.02;
// Cutoff
if(tc.y > 1.0 || tc.x < 0.0 || tc.x > 1.0 || tc.y < 0.0)
cta = vec4(0.0);
// Apply
gl_FragColor = cta;
And the looooonng cat? Well, it turns out that Hyprland gets a bit confused when the screen dimensions change. I’ve taken to calling it a composting compositor because of some of its weird glitches, like this:

We should really refresh the desktop background image as part of that script. But you know what - long cat is growing on me!