Skip to main content

Hyprland IIO Sensor Screen Rotation

·974 words·5 mins
Mayke Hyprland Shaders Yogabook Longcat Linux
Martin Hamilton
Author
Martin Hamilton
Futurist and innovation advisor. ADHD. Hacker. Solarpunk.
Using a composting compositor to make yourself a longcat.

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

Photo of a laptop screen showing a squishy glowy robot cat apparently contemplateing a ceiling with some very distinctive lighting, at a special time of year. Some readers may be familiar with this festive celebration. Oh, and the cat appears to have been stretched.

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…

Video showing a moodily lit YogaBook being slowly turned through 360 degrees. The full screen windows on both screens magically rotate in just the way that you’d expect them to. It’s quite boring really, except that one full screen window has an article about the Republic of Kugelmugel, a spherical art object located in Vienna, Austria. The other full screen window has a guide to making your own cardboard geodesic dome. Perhaps a geodesic dome hat is being considered?

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:

Photo of a laptop screen showing a yellow squishy glowy robot cat apparently contemplateing what looks like an EasyEffects window which has been, um, composted. The window is all weird and distorted. The cat looks as though it is contemplating its life choices.

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