A Weird Imagination

Relative links in feeds

The problem#

In an RSS/Atom feed, relative links are a bad idea because it's unclear what they're relative to. There are ways to specify a base for them to be relative to, but since feed readers do not consistently respect those mechanisms, it's safer to just always use absolute URLs in feeds. And Pelican recommends setting RELATIVE_URLS = False to always generate absolute URLs. But that setting does not apply to the anchor links generated by the Markdown toc extension to link to headers.

The solution#

I wrote a Pelican plugin, absolute_anchors which rewrites all link destinations starting with # in every article to add the absolute URL of the article at the beginning of the link.

The details#

Read more…

100% CPU usage in games with Nvidia Linux drivers

The problem#

Every game, no matter how old and simple, I run on my computer constantly uses an entire CPU thread even when idling at a menu. (Except for some newer multi-threaded games that do the same with multiple threads!) To raise this from a curiosity to a problem, this means that my computer's fans are on at full blast whenever I have a game going, so I notice.

The solution#

To be clear, that symptom could be the result of many different possible causes, others of which I may explore in future blog posts.1 But specifically for systems with Nvidia GPUs using the Nvidia proprietary driver (as opposed to nouveau), setting the environmental variable __GL_YIELD to USLEEP fixed the issue in some games for me. To do so when running a single game, run __GL_YIELD="USLEEP" /path/to/game or to do so permanently, add the line

export __GL_YIELD="USLEEP"

to ~/.profile and restart X.

The details#

Read more…

Eliminating Control.Monad.Error

The problem#

Compiling the Haskell package language-python (a dependency of xcffib), I got the following warning stating that the typeclass Error is deprecated:

language-python/src/Language/Python/Common/ParseError.hs:25:10: warning: [-Wdeprecations]
    In the use of type constructor or class Error
    (imported from Control.Monad.Error.Class, but defined in Control.Monad.Trans.Error):
    Deprecated: "Use Control.Monad.Trans.Except instead"
   |                                 
25 | instance Error ParseError where 
   |          ^^^^^                  

I wasn't sure how to "Use Control.Monad.Trans.Except instead", as Except is not a drop-in replacement for Error.

The solution#

As this StackOverflow answer recommended,

Short answer is: Replace Error by nothing at all

The code used throwError, which I replaced with

throwError = lift . Left

Other than that, I just removed the imports of Control.Monad.Error and the typeclass instance of Error. The full diff is in this pull request.

The details#

Read more…

Troubleshooting python-xcffib

The problem#

The monitor-lock.py script in my previous blog post uses python-xlib, which currently mainly relies on manually porting Xlib functions to Python. This is why it is missing the barrier-related functions I needed in that post. There is work on automating this process, but it appears to be abandoned. I started trying to pick up where they had left off before finding the python-xcffib project which provides auto-generated bindings for libxcb and therefore gives full support for interacting with X at a low level from Python.

python-xcffib (named after the cffi library it uses for binding to the C XCB library) gives a slightly lower-level API than python-xlib, but they are both fairly thin wrappers over the X protocol, so the differences are minor. It was fairly straightforward to port my script from the previous post to use python-xcffib, available as monitor-lock-xcb.py.

Unfortunately, I ran into a bug in python-xcffib:

Traceback (most recent call last):
...
  File "./monitor-lock-xcb.py", line 38, in main
    devices = conn.xinput.XIQueryDevice(xcffib.xinput.Device.AllMaster).reply().infos
...
  File "/usr/lib/python3/dist-packages/xcffib/__init__.py", line 139, in _resize
    assert self.size + increment <= self.known_max
AssertionError

The solution#

I've submitted the fix upstream, so most likely you will not encounter this error. Updating to the latest version (after v0.8.1) should be sufficient to fix the problem.

The fix I applied was to modify the module's __init__.py (the location, which may be different on your machine, is in the stack trace). Specifically, on line 108 in the function Unpacker.unpack(), in the call to struct.calcsize(), change fmt to "=" + fmt.

The details#

Read more…

Timezones and scheduling tasks with at

The problem#

My system for automatically posting future-dated blog posts mysteriously stopped working recently. The posts would appear if I manually published the blog, but not with the automatic scheduling mechanism.

The solution#

In schedule_publish.sh, I changed the line

echo "$0" | at -q g $time

to

if [ "$(date -d "$time PST" +'%s')" -ge "$now" ]
then
    echo "$0" | at -q g -t "$(date +'%Y%m%d%H%M' -d "$time PST")"
fi

(where "PST" is the timezone of this blog; adjust as appropriate for your blog). $now is initialized with

now="$(date +'%s')"

before the call to make publish to avoid a race condition.

The details#

Read more…

PulseAudio headphone jack troubles

Posted in

The problem#

Since I got a new motherboard (and therefore new audio hardware as I'm using the basic one built into the motherboard) sometimes after I unplugged my headphones, my speakers would not output any sound.

pavucontrol showed the only available output as "Built-in Audio Digital Stereo" with a port of "S/PDIF", which does not describe any audio device I had ever used. If I plugged my headphones back in, they would work fine, and usually after unplugging and plugging back in my headphones enough times, my computer would eventually acknowledge that my speakers were connected by showing the expected "Built-in Audio Analog Stereo" with a port of "Line Out".

The solution#

In /usr/share/pulseaudio/alsa-mixer/paths/analog-output-lineout.conf change

[Jack Front Headphone]
state.plugged = no
state.unplugged = unknown

to

[Jack Front Headphone]
state.plugged = no
state.unplugged = yes       # changed from unknown

This forces PulseAudio to consider there to be speakers plugged into the "Line Out" port, so it may cause strange behavior if that is not the case.

To apply the change, run

pulseaudio --kill
pulseaudio --start

to restart PulseAudio.

Read more…

Nvidia GLX not working

The problem#

I recently replaced my old Nvidia graphics card with a newer one. Upon booting up, I ran glxgears to test that 3D graphics were working properly and got an error like

X Error of failed request:  BadWindow (invalid Window parameter)
 Major opcode of failed request:  155 (NV-GLX)
 Minor opcode of failed request:  4 ()
 Resource id in failed request:  0x1200003
 Serial number of failed request:  34
 Current serial number in output stream:  34

The solution#

Either delete /etc/X11/xorg.conf or edit it and remove (or comment out) the "Files" section; that is, the lines

Section "Files"
    ...
EndSection

Read more…

Application bypassing PulseAudio

Posted in

The problem#

Recently I ran a game1 and instead of the expected music, got distorted noise. At first I thought there was something physically wrong with my speakers or the connection to them, but running any other program resulted in normal sound, albeit mixed with the distorted sound of the game. Even more strangely, changing the volume in the game changed the volume of the distorted noise, implying the game was in fact generating the right thing but it was being misinterpreted, so the culprit was neither the game nor the sound driver but somewhere in between them.

As I had recently set up PulseAudio2, I suspected it was to blame. I opened up pavucontrol to find the game omitted from the list of applications producing sound, which suggested the problem was caused by the game trying to use some way to produce sound that PulseAudio was not capturing.

The solution#

The short version is that the problem was solved by restarting PulseAudio:

$ killall -9 pulseaudio

Read more…

SDL screensaver hangs on exit

The problem#

I was modifying a screensaver written using SDL and noticed that sometimes there were many instances of it left running, even after unlocking the screen. Another bug was causing the screensaver to use 100% CPU, resulting in it using up all of my processing power just for a simple screensaver.

The solution#

Make the program exit immediately when it receives a SIGTERM signal by including the function

void exitImmediately(int sig) {
    abort();
}

and making the SIGTERM signal handler call it:

signal(SIGTERM, exitImmediately);

Read more…