Assorted tidbits and projects


How do I run a Java program?

Java expects a certain behaviour (reparenting of client windows) of a window manager which is not part of any standard, therefore some Java programs just show a white canvas.

If this happens just try to start your program like this:

AWT_TOOLKIT=MToolkit program

This changes the default tookit of Java to MToolkit, which is known to work with non-reparenting windows managers like subtle. Depending on your OpenJDK version and your architecture this may either lead to a segmentation fault or your OpenJDK just has no support for MToolkit. In this case check if your distribution has applied a patch for this issue which allows something like this to change the default behaviour:


In case both doesn't work there is a third option: Java seems to use an internally hardcoded list of window managers that are non-reparenting, the suckless guys made a tool (wmname) to change the name of the wm.

Since r2520 subtle can do that for you, just enable the :wmname option.

Generally this problem is really long lasting, see here:

Note: Many problems only affect the JRE and can be avoided by using the OpenJDK.

How does subtle match clients?

subtle matches the WM_NAME and the WM_CLASS property of a window and not the title. This to ensure the match is correct.
There are several ways to get these values, here are the most common:

Select the window with xprop have a look for the WM_NAME and WM_CLASS lines which usually look like this:

{{subforge_color(#0000ff, WM_NAME)}}(STRING) = "urxvt" 
{{subforge_color(#ff0000, WM_CLASS)}}(STRING) = {{subforge_color(#aa0000, "irssi")}}, {{subforge_color(#ff00ff, "URxvt")}}

Run subtler -cl and look for the matching line:

0x800007 * 1 1020x374 2 1 --- {{subforge_color(#ff0000, urxvt)}} ({{subforge_color(#0000ff,URxvt)}})

What is required for the volume sublet?

The volume sublet uses /dev/mixer to set/get the volume levels, which is an older interface introduced with OSS and still available via ALSA OSS emulation. Apparently, newer kernels refuse to autoload that module anymore and you need to load it manually or via any init file.

Please check to the docs of your distribution how to do it.

modprobe snd_mixer_oss

Following explanation is technical!

The sublet needs a way to access a mixer without any asynchronous callbacks. The reason for that is that subtle is single-threaded and can't use a dedicated thread to wait for the reply, but the APIs of ALSA and PulseAudio are both designed to be asynchronous. Normally event drivven is fine but it is troublesome when you can't use their mainloop.

Since there is no way to add e.g. a control socket to the event main loop of subtle, the /dev/mixer approach is the only way and works for all sound systems.

How do I run a program on startup/autostart?

Let's say you want urxvt to start after subtle, and for some reason echo "urxvt" >> ~/.xinitrc is just not cutting it. Using the :start hook and subtlext we can simulate autostart like so:

{{hide}}on :start do
  Subtlext::Subtle.spawn "urxvt" 

How to match a GLFW window

GLFW set the name of the window after the window get created, so you can't match a particular window by his name.

to match any GLFW window :

tag "glfw" do
        match name: "GLFW.*" 
        # your code

Why does subtle cause to many wakeups?

The wakeups are caused by a Ruby internal polling thread that runs every 10ms to schedule/handle other threads and signals. There is currently no way to avoid that in YARV, although the problem is well known.

There is finally some progress regarding this:

How can I manually delete a sublet?

[[Sublets]] usually consist of a *.rb file, a *.spec file and one or more icons. All these files can be found in their respective folder in $XDG_DATA_HOME/subtle resp. ~/.local/share/subtle. After deleting the [[sublets|sublet]] files the cache of [[sur]] needs to be updated or otherwise [[sur]] will think the [[sublets|sublet]] is still installed: sur update -l

Why does program XYZ appears/turns as/to a gray canvas?

Generally, this happens, when a program needs a specific aspect ratio and [[subtle]] sets a gravity that violates this. Windows can tell the window manager about this kind of preferences via their size hints and [[subtle]] can honor those.

There are two possible ways:

  1. Enable size hints globally with the :resize option
    {{hide}}set :resize, true
  2. Enable this per program via [[tagging|tag]]
    {{hide}}tag "name" do
      match  "name" 
      resize true

Note: This can happen with Java too, see here for more information.

Where does sur store sublets and icons?

[[sur]] follows the XDG Base Directory specifications to store data, which includes some base path for specific data types.

Following paths are used:

|_. Type |_. XDG path |_. Default path | | Sublets


~/.local/share/subtle/sublets | | Icons


~/.local/share/subtle/icons |

What is the difference between ViewSwitch and ViewJump?

Boths keys change the [[view]] of the current active [[screens|screen]], but the behavior how they do that depends on if the system consists either of a single [[screens|screen]] or more.

Single screen

Here both [[grabs]] do exactly the same.

Multi screen

Here the behavior depends on if the selected [[views|view]] is visible on another [[screens|screen]] or not.

  • ViewSwitch either swaps the current [[views|view]] with the selected if it is visible on another [[screens|screen]] or just sets the selected [[views|view]] on current [[screens|screen]].
  • ViewJump either focus the selected [[views|view]] if it is visible on another [[screens|screen]] or just sets the select [[views|view]] on current [[screens|screen]].

Why don't my grabs work with xyz keyboard layout?

Actually, I have no idea why setting the keyboard layout in your xorg.conf isn't suffucient, but apparently you need to call setxkbmap in one of your startup files to set the keymap. My suggestion is to use the ~/.xinitrc, because it is perfectly suited to setup Xorg and usually read.

Just add something like this to your ~/.xinitrc before you start [[subtle]]:

setxkbmap -layout 'de(nodeadkeys)'

How do I tag console based programs?

When console based programs like irssi are started with a terminal like urxvt -e irssi, they usually just change the WM_NAME of the terminal and per default, [[subtle]] uses both of the WM_CLASS values for tagging.

The problem about that is, that the [[tagging]] is normally done before the terminal really starts the desired app. To avoid that all better known terminals support the -name argument which changes the instance value (first string) of the WM_CLASS: urxvt -name irssi -e irssi

Another problem is that terminals retain their class value (second string) of the WM_CLASS and may match other [[tagging|tags]] like:

tag "terms" do
  match "urxvt" 

The common solution to bypass is this to use the :instance matcher, which just matches when for the specific instance value. So the easiest way to reliable match this client is a [[tagging|tag]] like this:

tag "irssi" do
  match :instance => "irssi" 

Following table shows the WM_NAME and WM_CLASS output of xprop of the various combinations:

|_. Command |_. WM_NAME |_. WM_CLASS | | urxvt


urxvt, URxvt | | urxvt -e irssi


urxvt, URxvt | | urxvt -name irssi


irssi, URxvt | | urxvt -name irssi -e irssi


irssi, URxvt |

Please have a look at the [[Tagging|tagging wiki page]] for more information.

How to match a GLFW window

GLFW set the windows name after the window get created, so you can't match a particular GLFW window by his name.

to match any GLFW window :

tag "glfw" do
        match name: "GLFW.*" 
        # Your code....

How do I move a program to another view?

Placement in [[subtle]] is strict and completely done via [[tagging]]. There are many ways to change [[tagging|tags]] per runtime, common is to use either [[subtler]] or [[subtlext]].


[[subtler]] can be used on the commandline:

{{hide}}subtler -ta tag         #< Add new tag 'tag'
subtler -cT client tag  #< Tag client 'client' with tag 'tag'
subtler -vT view tag    #< Tag view 'view' with tag 'tag'


[[subtlext]] requires basic ruby knowledge:

{{hide}}require "subtle/subtlext" 

tag ="tag").save  #< Add new tag 'tag'
Subtlext::Client["client"] + "tag"   #< Tag client 'client' with tag 'tag'
Subtlext::View["view"] + "tag"       #< Tag view 'view' with tag 'tag'


The [[snippets]] wiki page includes examples how to [[snippets#Move-windows|move to another view]].



subtle-contrib contains [[subtle-contrib:vitag|vitag]] a script to change the [[tagging|tags]] of windows and views with an editor.


The launcher uses quite the opposite way, instead of moving a window to a certain screen it just provides a way to launch a window directly on the right view with the correct [[tagging|tags]].


Most of the time, setting the window to stick does the trick too. Stick just displays the window on all views until the mode is disabled again. This can be done with [[grabs]] (default keys: W-s) or with [[subtler]]. (click on the window: subtler -cXS)

How do I tag gimp?

[[Tagging]] GIMP can be nasty, because the current version (2.6) uses inconsistent window names and roles. The window roles are fixed in the current development snapshot and will hopefully find their way into the 2.8 release.

How do I (auto)start programs?

There are several way how to start a certain programm, here are the most common:

  • Start your program via your $HOME/.xinitrc:
subtle &
sleep 2
wait $PID
  • Start your program via [[grabs]]:
"A-x" => "urxvt" 

There are many launchers available like dmenu and there is even a launcher especially designed for [[subtle]], you can find it in [[subtle-contrib:Launcher|here]].

Where is the output window of flash in fullscreen?

For flash, browsers seem to use window instance and class names that doesn't match the browser values. Therefore the windows will usually appear on the default view.

Following names are currently in use:

|_. Browser |_. Arch |_. WM_NAME |_. WM_CLASS | | Firefox <7.0.1



"<unknown>", "<unknown>" | | Firefox >=7.0.1



"plugin-container", "Plugin-container" | | Chromium



"exe", "Exe" | | Opera



"operapluginwrapper", "Operapluginwrapper" | | nspluginwrapper



"Npviewer.bin" |

The easiest way to avoid that is to add a [[tagging|tag]] that makes these windows sticky:

{{hide}}tag "flash" do
  match "<unknown>|plugin-container|exe|operapluginwrapper|npviewer.bin" 
  stick true

How can I use subtle without numpad?

Per default [[subtle]] uses the numpad, because it's easier to remind the different postions when you can see them. Generally this is just a suggestion, it's up to you to change the grabs to your needs - any keys will work.

Keys that also have proven to work well are q-w-e, a-s-d and y-x-c:

{{hide}}grab "W-q", [ :top_left,     :top_left66,     :top_left33     ]
grab "W-w", [ :top,          :top66,          :top33          ]
grab "W-e", [ :top_right,    :top_right66,    :top_right33    ]
grab "W-a", [ :left,         :left66,         :left33         ]
grab "W-s", [ :center,       :center66,       :center33       ]
grab "W-d", [ :right,        :right66,        :right33        ]

grab "W-y", [ :bottom_left,  :bottom_left66,  :bottom_left33  ]

grab "W-z", [ :bottom_left,  :bottom_left66,  :bottom_left33  ]

grab "W-x", [ :bottom,       :bottom66,       :bottom33       ]
grab "W-c", [ :bottom_right, :bottom_right66, :bottom_right33 ]

You can find more about assigning keys [[Grabs|here]].

How do I set a wallpaper in subtle?

On start, [[subtle]] sets a background color (if set) to the root window and therefore overwrites any root pixmap set before. To avoid this, you just need to comment out the :background line from your config.

[[subtle]] itself has no and will never have either an autostart or way to set a wallpaper directly. Normally you just want to setup your X session and and not [[subtle]]. Your ~/.xinitrc is the right place for stuff like this.

A background can easily set with a tool like feh.

Is subtle a reparenting window manager?

Nope, [[subtle]] doesn't reparent windows and there is in fact no reason to do that. The layout in [[subtle]] is a really loose set, the only relation between a [[views|view]] and a [[client]] is [[tagging]] and this is checked on every [[views|view]] update.

Reparenting windows would require following additional steps, when a window is visible on a certain [[views|view]]:

  1. Resize the [[views|view]] toplevel window to the size of the current [[screen]]
  2. Reparent the [[client]] window to the toplevel window
  3. Handle (ignore here) the generated expose and crossing events

Probably sounds like not much overhead, but keep in mind this is just required because the developer of Java and Qt cannot understand following line from the ICCCM:

Clients must be aware that some window managers will reparent their top-level windows so that a window that was created as a child of the root will be displayed as a child of some window belonging to the window manager

Is there any log file?

Nope, there is no log file. In case you need one for e.g. reporting a bug please read to the [[bugs|reporting a bug]] wiki page and check the paragraph about [[bugs#enable-logging|logging]].