Lock screen triggering twice on Xubuntu

After upgrading Jupiter’s Xubuntu to 22.04 (Jammy Jellyfish) on the holidays, I had this weird bug with XFCE where you unlocked and right away you got a different lock screen again, but the text boxes didn’t work and it didn’t respond to mouse clicks or anything. And it’s super hard to search for that kind of thing.

Long story short, disable XFCE’s Screensaver. That second lock screen comes from the screen saver, yep. Why does this happen is beyond me. And since we don’t use a screen saver on Jupiter (it’s the family machine), and I had other things to fix and adjust after the upgrade, I’m OK with this solution.

Back to school

Kids are back to school. All morning routine and habits are currently broken, as expected.

Kids were excited and eager to return to school, which is a good thing.

The Lord has provided and we’ve covered the additional expenses.

Dabbling with Python again

My relationship with Python is a coming-and-going one. I was recently chatting with Oliver and he asked me what I didn’t like of Python and I said the answer was subjective, but didn’t have an otherwise straight, concise, informed answer. It’s more about feeling, actually. I want to have a better answer.

I currently prefer Ruby to Python, but I want to like Python. I’m not interested on finding out which one is better or picking a winner, I want to be fluent on both languages and use whichever does the best job for the task. I wouldn’t rewrite my Ruby xdotool wrapper in Python, for example. And I wouldn’t rewrite my code generator written in PHP because PHP is something Python and Ruby are not: a templating language. Best tool for the job.

While I can do (and have done) stuff with Python, I don’t consider myself a good Python programmer. There’s lots of gaps in my knowledge. I don’t feel comfortable with it. There goes that feel thing again, dargh. Whatever, I just want to learn Python properly.

I rewrote my latest Ruby script to Python, it automates getting the day’s Zoom invitation for sending it to my church’s WhatsApp group. Surely there’s better, pythonic ways of doing things, but it works and it gave me a better understanding on how to do things in Python based on how I usually write them in Ruby.

And I learnt about assignment expressions. I didn’t know Python couldn’t do that and I’m glad they added them to the language already. The reason behind them was exactly what I stumbled with: having a condition where a regular expression matches and needing the match object assigned to a variable. I was like, «why can’t I assign in a condition?»

Trying xdotool and pyautogui

I tried xdotool and it’s pretty cool. I was automating setting up my Slack status. It finds the Slack window, focuses it, clicks here and there and — tah-dah! — my status is updated. It totally depends on things being in fixed places, but it works.

Then I tried pyautogui planning to port this script and see how it compares with xdotool, but I was surprised right from the start to discover pyautogui doesn’t have any feature to find or operate on windows. So I’ve decided to stick with xdotool and dive deeper. I might try pyautogui some other time.

One thing I liked about pyautogui is it’s «failsafe» — if you slam the mouse and move the cursor to any screen corner, pyautogui will stop running. This is a great feature. One automation of mine with xdotool didn’t quite work (the popup appeared too late) and suddenly xdotool was blindly doing stuff on the wrong places and I couldn’t stop it. No damage was done, but it was scary.

I totally needed something like pyautogui’s, but this required a higher-level language. I went with Ruby. My failsafe is the top or bottom edge of the screen. Before it executes any xdotool command it checks the mouse location and throws an exception. Works pretty well and I recurred to it when I made a mistake and the automation misbehaved.

Lesson learnt: automating the GUI is powerful, but also dangerous. Unlike a shell script, the GUI is an unpredictable environment and things can quickly derail. I like the way pyautogui’s documentation describes this:

Like the enchanted brooms from the Sorcerer’s Apprentice programmed to keep filling (and then overfilling) the bath with water, a bug in your program could make it go out of control. It’s hard to use the mouse to close a program if the mouse cursor is moving around on its own.

It’s a powerful, but double-edged sword. And lots of fun too! Automating the GUI is another dimension and a very useful skill to have.

GUI Automation on Linux

Curious to learn automating GUI stuff on Linux, that is, moving the mouse, clicking on buttons, pressing keys, etc.

I’m planning to learn two: xdotool and pyautogui. I like that you can give an image to pyautogui and it will find it on the screen and click on it. Pretty powerful stuff.

Cropping my webcam with ffmpeg

My laptop is on a riser, at a healthy distance and height from me. But when I do video calls, you see a lot of my surroundings (which aren’t great) and little of me. I sometimes tilt the screen to be vertically centered.

Since I’ve learnt ffmpeg is designed for real-time processing, I decided this would be a good problem to solve and learn with!

I created a loopback video4linux device, then run ffmpeg to feed my built-in laptop webcam’s stream into it, crop it, sharpen it and add a tiny bit of color saturation. It looks pretty good! Not Macbook Pro-webcam-good, but good!

Here’s the original webcam output and the final ffmpeg result, side by side:

Here’s my ffmpeg command, broken up for readability:

ffmpeg -f v4l2 \
  -framerate 30 \
  -video_size 640x480 \
  -input_format mjpeg \
  -i /dev/video1 \
  -vcodec rawvideo \
  -pix_fmt yuv420p \
  -filter:v "crop=494:370:103:111,scale=640:480,setsar=1,unsharp,eq=saturation=1.2" \
  -f v4l2 \
  /dev/video3

The magic happens on -filter:v. If you break it by commas you’ll see the cropping, scaling it back to 640×480, (un)sharpening and color saturation.

I never took the proper time to learn ffmpeg and, while the learning curve is a bit high, it makes perfect sense, it’s very well designed.

I won’t be posting on Saturday and Sundays for now. I wanted to post every day, but I really need to take a break. See you on Monday!

ffmpeg can do that?

I was reading Drew DeVault’s In praise of ffmpeg and read this part:

I was recently hanging out at my local hackerspace and wanted to play some PS2 games on my laptop. My laptop is not powerful enough to drive PCSX2, but my workstation on the other side of town certainly was. So I forwarded my game controller to my workstation via USB/IP and pulled up the ffmpeg manual to figure out how to live-stream the game to my laptop. ffmpeg can capture video from KMS buffers directly, use the GPU to efficiently downscale them, grab audio from pulse, encode them with settings tuned for low-latency, and mux it into a UDP socket.

And I was like… ffmpeg can do that? I didn’t know it was possible to do such a complex thing using just ffmpeg. Fair enough, there’s the USB-over-IP thing for the gamepad, but still.

I commented it to Oliver and he was explaining me some stuff I know very little of and should set aside time to learn. KMS, the role of the Compositor, Wayland (I use X11), etc.