Desktop-spanning backgrounds in KDE 4.x

One of the simplest ways to make a multi-monitor system look more impressive is to set a desktop background which spans across all of the monitors. Just scale the image up to the smallest size that fills all of the visible desktop space, then cut out monitor-shaped pieces to display.

Every system (even lightweight, older Linux desktops) supports this… every system except one. When KDE went from 3.5.x to 4.x, they dropped support for spanning a background across all desktops and, to this day, they still haven’t brought it back.

…and since everything more lightweight has bugs with the desktop layout I’m currently dealing with while I wait for the new monitor bracket I ordered, that’s a problem. (Even worse, there’s no API I could find to programmatically set a background either!)

The solution I settled on was to write a little Python script which uses maybe half a dozen lines of PyQt 4.x/5.x calls (before line-wrapping and boilerplate) to do what KDE should have, then spits out image files to be set as per-monitor backgrounds.

I also implemented a --randomize option which can be used with cron to produce input for KDE’s slideshow mode. (Basically, you set each monitor background to be a single-entry slideshow that the script updates)

Just give it an image (or --randomize and a list of files and/or folders) and an output directory. (See --help for more details)

UPDATE: It now also gives more control over how the background is matched to the desktop’s aspect ratio via --gravity and I included, as an example, the .desktop file I use to integrate it with Geeqie via Zenity. (KDialog’s equivalent to zenity --list is inferior.)

Posted in Geek Stuff | 2 Comments

Extracting The Soundtrack From Your Copy of Desktop Dungeons

As I mentioned on previous occasions, I don’t take too kindly to people trying to make me pay once for a game and again for its soundtrack and, as a matter of principle, I rip my soundtracks straight from the data files I paid for rather than pirating the officially separated versions.

This time, it’s Desktop Dungeons. Unfortunately, this is a relatively recent Unity Engine game, so the only tool I’ve found which will extract the audio is Unity Assets Explorer.

Thankfully, it’ll run just fine inside Wine, so I wrote a script similar to what I did for Cave Story+.

So, here are the Linux instructions for extracting your Desktop Dungeons soundtrack from the game you bought:

  1. Download Unity Assets Explorer 1.2 or newer
  2. Use it to open DesktopDungeons_Data/resources.assets
  3. Extract all of the .ogg files
  4. Load them all in your music player and manually delete the ones which are sound effects. (You should be left with pairs of Intro and Loop files.)
  5. Download the following script and install the packages listed in the Requirements section
  6. Place the script in the same folder as your .ogg files, run it, and wait.
Posted in Geek Stuff | 2 Comments

Simple CD-Ripping Wrapper

Not much to report over the last few days. I was mainly busy ripping old CDs so I could store them in the closet.

cdparanoia -B and ddrescue (instructions) are essential for damaged audio tracks and CD-Rs. However, for old DOS/Win3.1-era CD-ROM games which use Redbook audio, they don’t really produce something that DOSBox or CDEmu+Wine can mount and play.

As such, I whipped up a quick little script for generating BIN/CUE pairs based on advice for ripping Playstation games under Linux. Here it is in case anyone wants it (you’ll also want my script that works but is long overdue for a rewrite):

Posted in Geek Stuff | Leave a comment

How to easily jekyll-import a WordPress site hosted on NearlyFreeSpeech.NET

In the time since I last tried migrating my blog to Jekyll, it has gained an official WordPress importer. Unfortunately, that importer requires direct database access and NearlyFreeSpeech.NET doesn’t have the requisite Ruby dependencies.

…so I decided to hack around that. It’s much easier to run the importer locally, but NFSN doesn’t expose their database servers to the world at large… SSH port forwarding to the rescue.

  1. Install the development headers for libmysqlclient
  2. gem install jekyll-import sequel mysql2 unidecode`
    Note: Make sure it does complain about `htmlentities` being missing or you’ll get a broken import with things like the / in </a> escaped.
  3. Open up two terminal windows
  4. In one terminal, adjust this SSH command and run it to forward the MySQL client port
    ssh -L 3306:YOUR_DSN_HERE:3306
  5. In the other terminal, adjust and run this jekyll-import command to dump the blog
        ruby -rubygems -e 'require "jekyll-import";
              "dbname"   => "___________",
              "user"     => "___________",
              "password" => "___________",
              "host"     => "",
              "socket"   => "",
              "table_prefix"   => "wp_",
              "clean_entities" => true,
              "comments"       => true,
              "categories"     => true,
              "tags"           => true,
              "more_excerpt"   => true,
              "more_anchor"    => true,
              "status"         => ["publish"]

    Note: Make sure `host` is set to If you use localhost, it will try to use a UNIX domain socket rather than a TCP socket and fail.

  6. Exit the ssh connection to close the tunnel and start fine-tuning the exported content.

Unfortunately, I found jekyll-import insufficient (eg. it made no attempt to preserve permalinks) so I started investigating alternatives. I discovered that Pelican (a Python alternative to Jekyll) has some very appealing plugins (eg. [1] [2] [3] [4]), so I’ll probably use that instead.

Posted in Geek Stuff | 1 Comment

“Tasks Due Today” popup for TaskWarrior

I generally like using TaskWarrior to manage my tasks but I’ve found that, for daily recurring stuff, it just doesn’t feel quite right.

As such, I’ve put together a little tasklib-based glue script, runnable as a user cronjob if you set DISPLAY, which presents tasks due before the end of today (defined as 1:00:01 AM, local time, to work around a quirk caused by TiddlyWiki’s ignorance of daylight saving’s time) in a zenity checklist dialog.

It looks like this:


Clicking OK will commit the changes and then redisplay the dialog with refreshed content while clicking Cancel will quit the tool. The redisplay behaviour, window size, warning period, and zenity command can be customized by editing constants at the top of the file.

It’s available on GitHub Gist, as embedded below and here’s the download link. A requirements.txt is included which will install all of the dependencies except zenity.

Posted in Geek Stuff | Leave a comment

A Lightweight Low-Battery Warning Monitor for GTK+ 3.x desktops

Today, I decided to help someone out and, as is often the case with coding, I got carried away.

I set out to help fix up a shell script but, instead, I decided to “do it right” and produced a simple Python script which…

  • Uses a combination of GLib.timeout_add_seconds and UPower events to react to power supply changes immediately while still putting a limit on how often battery percentage changes should be able to cause wakeups.
  • Uses GStreamer and notify2 to provide audio and visual low-battery warnings without the weight and delay of calling subprocesses.
  • Is compact and easy to customize because it’s written in Python

By design, it doesn’t really have much of a UI (just a persistent notification popup and alert sound that come and go in response to changes in power state), but here’s what the popup looks like when using xfce4-notifyd:

It does require the 1.0 UPower API for its “Display Device” abstraction, so an 0.99.x-series version of UPower or newer is required, but for people on a new enough Debian/Ubuntu/Mint release (Vivid, in Ubuntu’s case), the dependencies can be installed as follows:

sudo apt-get install python-notify2 python-gi gir1.2-upowerglib-1.0 gir1.2-gstreamer-1.0 gir1.2-gst-plugins-base-1.0

It hasn’t been tested under Python 3.x but it looks like it should work perfectly if you just replace python-notify2 python-gi with python3-notify2 python3-gi in the dependencies and edit the shebang line at the top of the file.

I only wish I’d realized what I was doing sooner so I could start tracking its evolution properly in git. As-is, all I could do was translate the snapshots from Dropbox’s revision history.

As usual for small, single-file things, here’s the direct download link followed by a GitHub Gist embed.

Posted in Geek Stuff | 10 Comments

“Rubber Matrix” and “Sparse Montage” wrapper for ImageMagick

Last night, I was working on a bunch of images and I really wanted to just get a visual overview along the lines of a scatter plot, but with images rather than dots. Unfortunately, no matter what I searched for, I couldn’t find anything to do what I wanted.

ImageMagick’s montage tool can do it… but you have to manually fill in the empty cells with the special filename null:

…so I wrote a script to do just that.

Oh, and I got carried away and wrote a “rubber matrix” class to abstract away the actual generation of the grid. Basically, it’s a DictMixin-based class that insists on consistently sized tuples as keys and then adds some extra methods to traverse them as sparse points in a matrix dynamically sized to only the rows/columns/etc. which exist.

I haven’t yet decided on what command-line syntax I want, so you have to import it, but it works perfectly in my preliminary tests.

Posted in Geek Stuff | Leave a comment