Package for devuan: keyboard-leds-trayicons

I recently purchased a ThinkPad P50s and I love it! However, it doesn’t have indicators for capslock and numlock. So I wrote a tool to simulate them! Keyboard-leds-trayicons is my solution. You can go install it in Devuan Ceres from my OBS.

Reading the status of capslock and numlock is trivial on the command line:

xset q | awk 'function d2b(d,b) {while(d) {b=d%2b;d=int(d/2)}return(b)} /LED/{print d2b($NF)}'

The awk is there to convert the provided decimal value into a binary. But how do you poll this, and display it in your X11 session in an unobtrusive way? With a POSIX shell script, of course! But what about the actual icons? Use my fork of mktrayicon. My fork adds a few patches, and you can also get it at the OBS link above.

capslock and numlock indicators in system tray, both on

capslock and numlock indicators in system tray, capslock off and numlock on

Obviously most people have no need for this package. And by now anyone without the indicators probably doesn’t need them. This project was 99% for myself, but I like to share.

The default icons are a bit boring, which fits my style. But the tool uses the xdg icon spec, so you can add your own icons for capslock-on and similar. Patches are welcome to the project, so if you really think this package should include more icons, or use yours by default, please open a merge request!

Making my HTPC easier for non-technical people to use

I have a Ubuntu 16.04 instance (I’m not proud) because at the time, Kodi only supported 16.04 of the Ubuntu family and I didn’t feel like compiling it myself on another platform, or depending on prebuilt binaries (if that’s even an option). I ended up not really liking the 10-foot interface that Kodi had to offer (as well as it seemed to really stink at populating its indices of my own local content!), and I really like the paradigm of a desktop environment with traditional file manager and media player programs. So I will reimage the system with Devuan at some point, but that’s another day’s problem.
One of the little issues that I have discovered somehow between PulseAudio and HDMI is that upon each boot, the default audio out is the built-in speakers in the computer case. I have to manually adjust pavucontrol to set it to be the HDMI out audio that sends it to the big screen.
I decided to automate this so others don’t have to know what option to select on what tab in what program, in order to get the sound to goto the TV. I remember (fondly, actually) my automation days in obsolete, proprietary OSes using AutoHotKey. A great way to simulate key presses in X11 (because Wayland seems as scary as systemd or pulseaudio) is to use xdotool (which I’ve written about before).
Using my tried-and-true desktop-file-calls-shell-script method, I have whipped up a nice desktop icon for the user to call after first logging in.

[Desktop Entry]
Name=Output audio to HDMI
Exec=/home/kodi/bin/set-sound.sh
Type=Application
StartupNotify=true
Path=/home/kodi
Icon=multimedia-volume-control
StartupWMClass=pavucontrol
Terminal=true
Comment=Configures pulseaudio to send audio to HDMI automatically

And the shell script:

#!/bin/sh -x
# goal: set sound to have audio output to HDMI for the television.
# startdate: 2019-08-01 22:09
# dependencies:
#    pavucontrol
#    xdotool

pavucontrol &
sleep .5
xdotool key --delay 25 alt+c Down alt+Down End Up Up Up Return
# Return
# 3 up buttons to select the option fourth from the bottom in the list.
# this is very hard-coded for the kodi machine in the living room.

The hard part of course was finding how to notate the different keystrokes very precisely, with the capitalization and special characters.

Auxiliary info and asides

Pro tip: Don’t ever configure “Alt+F4” in an xdotool script, especially when you load it up into ~/.config/autostart, and not bound to a specific window class. I really messed up the Xfce session almost permanently because I magically closed out xfwm, xfdesktop, and I think even xfpanel. That was embarrassing, big-time. Took me a while to even figure out what I had done. I couldn’t figure out how to use the “search” window stack population function of xdotool, to identify the pavucontrol window, so I couldn’t restrict my simulated keypresses to just pavucontrol. I also learned later that when the terminal window running the shell script is terminated, it kills even the backgrounded job of pavucontrol, so no ALT+F4 was required.

Run game in dosbox and make nice menu icon for it

When I want to play an old-school DOS game, I use the emulator DOSBox. I discovered that DOSBox has its own icon and uses its title in the window, and not the name of the game running inside. I now have a solution to change the icon and title that I want.

First of all, I make my .desktop file call my shell script.

$ cat ~/.local/share/applications/st25.desktop
[Desktop Entry]
Version=1.0
Name=Star Trek 25th Anniversary
Comment=1993 DOS computer game
Keywords=Game;Star Trek;
Exec=/usr/share/st25/st25.sh
Terminal=false
X-MultipleArgs=false
Type=Application
Icon=/usr/share/st25/st25.png
Categories=Game;AdventureGame;

The shell script calls dosbox with the custom batch file (from the olden days of non-free operating systems)

$ cat /usr/share/st25/st25.sh
#!/bin/sh
# Star Trek: 25th Anniversary game
GAMEDIR=/usr/share/st25
ICONFILE="${GAMEDIR}/st25.png"
cd "${GAMEDIR}"
dosbox ST25.BAT &
sleep 1
tid="$( xwininfo -root -children -all | grep -iE "dosbox.*STARTREK" | awk '{print $1}' )"
echo "modifying id ${tid}"
xseticon -id "${tid}" "${ICONFILE}"
xdotool set_window --name "STARTREK" "${tid}"
xdotool search --name "STARTREK" set_window --classname "STARTREK" --class "STARTREK" windowunmap windowmap

The above shell script is where the magic happens. The main emulator is executed and placed in the background. After a short delay, some X tools are used to find the specific application’s window ID.
A custom application named xseticon (available in my Fedora copr) written by Paul Evans is used to change the icon used by the window.
The more easily available xdotool (probably already bundled by your distro) can change the window name.
Additionally, xdotool can hide and re-show the window, to make the window manager and panel recognize the new icon and name!

And just for completeness’s sake, here is the batch file.

$ cat /usr/share/st25/ST25.BAT
REM ST25.BAT
REM Star Trek: 25th Anniversary game

MOUNT C /usr/share/st25
C:
STARTREK.EXE
exit

Conclusion

This is my preferred way to run a DOS-based application: desktop file, shell script, batch file. Yes, it spawns the extra process with the shell script, but I want to be able to call an application from the command line easily.

How do you make your DOS programs accessible to users on cli or the desktop?

References

For a complete list of Internet resources used to build this process, see my other post, X11 change application titlebar and icon in window manager panel.

X11 change application titlebar and icon in window manager panel

If you are trying to change the listing of a running application in the window list, regardless if you’re running XFCE or Cinnamon or another display manager, you might want to go down the same line of research I did.

In an upcoming article, I will talk exactly about how I run a game in DOSBox with a wrapping shell script and batch file. But today, this article is about how I rename the window and change its icon.

First, I run the application and I know what the titlebar looks like. I have to learn the window ID to set the icon.

I set the window title to the preferred name, and then use that window name to search and then execute a series of commands, which change the class and redraws the window so the panel learns the correct name.

tid="$( xwininfo -root -children -all | grep -iE "dosbox.*STARTREK" | awk '{print $1}' )"
echo "modifying id ${tid}"
xseticon -id "${tid}" "${ICONFILE}"
xdotool set_window --name "STARTREK" "${tid}"
xdotool search --name "STARTREK" set_window --classname "STARTREK" --class "STARTREK" windowunmap windowmap

I researched on the Internet to discover how to change the application icon. I had to compile a nifty little tool written in C (xseticon), so I bundled it into an rpm. But it does exactly as the description says.
Changing what appears on my Cinnamon panel was a different story, however.
I eventually remembered using xdotool for something in the past, and decided to read its man page. After a lot of experimentation, I got the classname and class adjusted. But it still didn’t do any good.
So I finally tried the windowunmap command, which was recommended after doing some other change. And then I had to hurriedly windowmap it again, so I could see the window. It doesn’t minimize the application; it removed it from the panel and display entirely, even though the process was still running. After the windowmap, it showed the custom icon, and the exact title I wanted!
I learned how to chain the commands together into fewer invocations.

References

Web links

link to xseticon https://unix.stackexchange.com/questions/179174/change-icon-for-an-application-form-command-line
compiling xseticon https://forum.xfce.org/viewtopic.php?id=11116
xseticon source http://www.leonerd.org.uk/code/xseticon/
rpm spec https://gitlab.com/bgstack15/stackrpms/tree/master/xseticon
xseticon rpm in copr https://copr.fedorainfracloud.org/coprs/bgstack15/stackrpms/package/xseticon/

Further reading

https://stackoverflow.com/questions/36650865/set-wm-class-with-wnck-xprop-or-something-else

Internet searches

xprop change icon of running application

Man pages

xdotool(1)