Desktop environment manipulation from the command line

I recently discovered Regnum Online, a very good [[MMORPG]], with two interesting properties: it has a native Linux version, and is free to download and play (NGD, its owner, gets revenue through so called “premium items”, which are sold for real money. Premium items are not really necessary to play, but include convenience items like mounts, to travel faster than on foot).

It so happens that Regnum can be played either in windowed mode, or fullscreen. Obviously the latter takes advantage of the whole screen, but sadly it can not be minimized or alt-tabbed to a different window. Being able to minimize the Regnum window and switching to another task is interesting, for example, to leave your character resting after a battle (it takes some time to heal back to normality), and checking your e-mail meanwhile. However, playing in windowed mode feels uncomfortable, with not all the screen being used, and having your desktop bars above and/or below the window you are playing on.

To have the advantages of both windowed and fullscreen mode at the same time (and none of their disadvantages), I thought of the following: I can play on 1440×900 resolution (my whole screen), hiding the top and bottom bars (I use [[GNOME]], with both bars), and getting rid of the window decoration of the Regnum window (which would eat some of the 900 vertical pixels). While we are at it, it would be cool to stop [[Compiz Fusion]] before running Regnum (to dedicate the whole video card to the game), and starting it again after closing it.

The problem is, I do not like to have autohiding panels in GNOME, and I like window decorations and Compiz effects, so the desktop settings for playing would have to be turned on before playing, and off after that. The next problem in the line is that I don’t like performing repetitive tasks such as pointing, clicking and choosing options from menus every time I feel like playing a game. Since I already click a button to start Regnum, it would be cool to have all configuration stuff happen by just clicking that same button. Obviously, that means automating all the configuration by placing the corresponding commands in a script, and making the Regnum button execute that script.

Stopping Compiz

That part was easy. We want to switch from Compiz to [[Metacity]], which can be done with:

metacity --replace

Autohiding GNOME panels

Some googling yielded this ubuntu-tutorials page, which led me to:

gconftool-2 --set "/apps/panel/toplevels/top_panel_screen0/auto_hide" --type bool "true"
gconftool-2 --set "/apps/panel/toplevels/bottom_panel_screen0/auto_hide" --type bool "true"

Eliminating window decorations

All you can google about it will lead you to a little wonder called Devil’s Pie. In short, it’s a kind of daemon that checks for windows that match some user-defined rules, and performs on them the corresponding user-defined actions.

In my case, I defined a rule (in ~/.devilspie/regnum.ds):

(if
    (is (application_name) "Untitled window")
    (begin
        (undecorate)
    )
)

Running devilspie from the command line will show the properties of all open windows, which will help you create the appropriate condition for the rule. In my case, apparently the final Regnum window is identified only as “Untitled window”.

Running Regnum, and waiting for it to finish

Waiting for Regnum to finish is not trivial, since once fully running it returns the control to the shell. For that reason, the following will not work:

$ echo "start"
$ regnum-online
$ echo "end"

It will echo “start”, then start Regnum, then echo “end”, while Regnum is still running. To fix that, I added a loop to my script, which only exits once Regnum has finished. There must be more elegant and less hacky ways of doing it, but this one works:

while [[ -n "`ps aux| grep -e regnum-online -e "./game" | grep -v grep`" ]]
do
    sleep 5
done

Every 5 seconds, it runs some ps command, and exits when the output is empty. The command itself is a simple grep to a ps, adding the grep -v grep so that the grep command is not catched by itself.

After closing Regnum, and whole script

So, after the while loop above exits, all we have to do is undo the settings changes we just did, and exit. The whole script would read:

#!/bin/bash

# Substitute Compiz with Metacity:
metacity --replace &

# Autohide top and bottom pannels:
gconftool-2 --set "/apps/panel/toplevels/top_panel_screen0/auto_hide" --type bool "true"
gconftool-2 --set "/apps/panel/toplevels/bottom_panel_screen0/auto_hide" --type bool "true"

# Run devilspie, to remove decoration in Regnum Online windows:
/usr/bin/devilspie &

# Run Regnum Online:
/usr/bin/regnum-online

# Wait until RO finishes:
while [[ -n "`ps aux| grep -e regnum-online -e "./game" | grep -v grep`" ]]
do
    sleep 5
done

# Kill devilspie:
killall devilspie

# Show top and bottom pannels:
gconftool-2 --set "/apps/panel/toplevels/top_panel_screen0/auto_hide" --type bool "false"
gconftool-2 --set "/apps/panel/toplevels/bottom_panel_screen0/auto_hide" --type bool "false"

# Run Compiz again:
compiz --replace --sm-disable --ignore-desktop-hints ccp --loose-binding --indirect-rendering &

Finally, I just named this script “RegnumRun.sh”, made it executable, placed it in a suitable place, and associated the Regnum icon on my top panel with RegnumRun.sh, instead of with regnum-online directly, and voilà: every time I click on that icon I get to play Regnum with purpose-chosen settings, and I get my regular settings back once I exit Regnum.

Comments

Amarok WTF

Warning: the following rant could be caused by my idiocy, more than by Amarok’s fault. See comments.

I have been using [[Amarok (software)|Amarok]] as music player even since I had first contact with it. I was really delighted with its capabilities, and everything was intuitive and useful in its [[User Interface|UI]]. That was until version 1.4.x.

Version 2.0 was an almost complete rewrite of the code, and as such many things changed. The UI suffered a large redesign, in my opinion for worse… but that’s just an opinion. There are, however, other issues that are facts, not opinion. Amarok 2.0 lacked many of the features of Amarok 1.x, as the developers themselves admitted (not much room to deny). Fine, I have no problem with that. It is understandable: until version 2.x things will not settle down. The only problem is that Linux distros (at least Ubuntu) adopted Amarok 2.0 almost immediately, leaving us users with a broken toy. Not nice.

My latest gripe with Amarok? I run Ubuntu 9.10 at work (Amarok 2.2.0), and latest Arch at home. In the latter, I just updated Amarok 2.2.1 to 2.2.2 in the weekend (Arch is much more up to date than Ubuntu, since it’s based in almost bleeding-edge rolling releases). Well, unlike Amarok 2.2.1 before (or Amarok 2.2.0 at work), the new Amarok 2.2.2 does not have an option for random play. Yes, you read correctly. There is no way I know of to avoid playing all the songs in the playlist in the exact order (in principle, alphabetical) they are laid on. In older versions, you could play songs or albums randomly. With 2.2.2, they lost this capability. Amazing feature regression, if you ask me.

Comments (3)

Changing font style in PyGTK ComboBox

I am using the [[Glade Interface Designer]] to produce (very) small (and simple) graphical apps for my [[Neo FreeRunner]]. I produce the graphical layout in the form of an [[XML]] file (using Glade), then load this XML from a [[PyGTK]] program.

The thing is some defaults are not really usable for a device such as the NFR. For example, default fonts are in general too small for the tiny screen of the Neo, which favors apps with only a few, big and shinny buttons. In the case of Label widgets, you can use Pango markup format with the set_markup method, as follows:

mylabel  = self.glade.get_widget('label1')
txt  = '<span font_size="80000" color="red">%s</span>' % (text_string)
mylabel.set_markup(txt)

However, for other widgets it is not so evident. For example, in ComboBoxes (buttons with a drop-down list), you can’t put in the item list anything other than strings, which are displayed literally (markup is not interpreted). Moreover, CBs do not have a “set_font_style” method, or anything similar.

Searching the web did not provide immediate results, but I managed to find this FAQ item at eccentric.cx. I quote:

4.1.581 How do I change font properties on gtk.Labels and other widgets?
Easy:

 label = gtk.Label("MyLabel")
 label.modify_font(pango.FontDescription("sans 48"))

This method applies to all widgets that use text, so you can change the text of gtk.Entry and other widgets in the same manner.

Note that, some widgets are only containers for others, like gtk.Button. For those you’d have to get the child widget. For a gtk.Button do this:

  if button.get_use_stock():
     label = button.child.get_children()[1]
  elif isinstance(button.child, gtk.Label):
     label = button.child
  else:
     raise ValueError("button does not have a label")

Last changed on Thu Sep 1 14:46:30 2005 by Johan Dahlin (johan-at-gnome-org)

In the case of a CB, we have to pick its child (which is the list itself), and modify it thusly:

cbox = self.glade.get_widget("CBlist")
cblist  = cbox.child
cblist.modify_font(pango.FontDescription("sans 32"))

In my examples above, a class has been created in the script beforehand, and it binds to the Glade XML:

class whatever:

  def __init__(self):

    #Set the Glade file
    self.glade    = gtk.glade.XML(gladefile)
    self.glade.signal_autoconnect(self)

Of course, the CBlist and MyLabel mentioned in my code are the appropriate widget names defined in that XML.

Comments