Tuesday, July 9, 2013

Desktop Friendly Standby, Hibernation, Shutdown and Reboot in Openbox Through Dbus and ConsoleKit

There are quick ways to to shutdown, reboot or put your computer into standby or hibernation in Linux if you have permission to do so. Openbox however does not come with a way of facilitating this and you're stuck with becoming superuser to do so. This is a way to do all this as a normal user.

Basically, we will do what all the desktop environments pretty much also do - we will ask ConsoleKit to handle the machine for us. As normal users, we cannot shutdown the machine ourselves, but we do have permission to instruct ConsoleKit to do it. You most probably won't need to install it, since a lot of desktop programmes on distros that still use dbus depend on it.
This still, for instance, works properly on Debian 7 Wheezy. Bear in mind however that ConsoleKit is not very actively maintained anymore with many distros slowly going over to systemd. If you're using this, then YMMV as to whether and how well this will work. I might tackle that in the future if I ever move to a systemd distro.

We will also need zenity for the dialogue scripts. This is what you'll be seeing as a user:



I have the scripts all assigned to key combos. For instance, CTRL + SUPER (or WIN) + x gives me shutdown, CTRL + SUPER + r is restart, the same but with an h instead would be hibernate and  an s would give me standby.
The combos are basically calling the following scripts that firstly give you an "Are you sure" kind of dialogue, so you can still opt out. Answering No cancels everything, answering Yes commits to running said action. Basically, you paste the scripts from here into a text editor, save it under

 .  

 ~/.bin/  


You then have to make the scripts executable.


1. Shutdown Script

 .  

 #!/bin/bash  
 zenity --question --text="Shutdown?"  
 if [ $? == 0 ]  
 then  
  dbus-send --system --print-reply --dest="org.freedesktop.ConsoleKit" /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop  
 else  
  exit  
 fi  


WARNING! The long command between then and else must be in one line! Otherwise it won't work. Sorry, but I am yet to devise a better means for showing code samples properly. :( Bear with me!


2. Reboot Script

 .  

 #!/bin/bash  
 zenity --question --text="Restart?"  
 if [ $? == 0 ]  
 then  
  dbus-send --system --print-reply --dest="org.freedesktop.ConsoleKit" /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Restart  
 else  
  exit  
 fi  


Again, the dbus command has to be all in 1 line!


3. Suspend

This command will be a bit different, but you can leave out the parts that differ here and that I put out of convenience.
I personally use tint2 as my panel. It had a bug and I'm not sure if that's fixed or not. I keep this workaround just the same. When I resume out of suspend or hibernate, tint2 will show the clock incorrectly at the date I had suspended or hibernated at, that is until it eventually refreshes. Now, if you turned of the machine hours ago, this can be a bit fatal. The command will thus kill all instances of tint2, suspend, and when it resumes, it will start tint2 again.

There is another workaround - resuming from either standby or hibernation will open the desktop without asking for a password. To prevent others from easily using my computer I have told the script to lock the screen right before shutting down.
I have used xtrlock, but am sure that other screen locking or screensaver tools can be used just as well. I prefer xtrlock for its simplicity.

 .  

 #!/bin/bash  
 zenity --question --text="Suspend?"  
 if [ $? == 0 ]  
 then  
  killall tint2 && xtrlock & dbus-send --system --print-reply --dest="org.freedesktop.UPower" /org/freedesktop/UPower org.freedesktop.UPower.Suspend && tint2  
 else  
  exit  
 fi  


Again, pay attention to the commands between then and else staying in 1 line!
The bold parts are the optional workarounds you can ignore.


4. Hibernate

Quite similar, the only thing that's different is the dbus command:

 .  

 #!/bin/bash  
 zenity --question --text="Hibernate?"  
 if [ $? == 0 ]  
 then  
  killall tint2 && xtrlock & dbus-send --system --print-reply --dest="org.freedesktop.UPower" /org/freedesktop/UPower org.freedesktop.UPower.Hibernate && tint2  
 else  
  exit  
 fi  



That's all.

Monday, July 1, 2013

Sound Volume Management Through Multimedia Keys in Openbox

My laptop has those multimedia keys which don't work automatically in Openbox. This is how I fix it. You can use the same method for LXDE, just take note of the different config file location.
A lot of the Openbox stuff I use is from here.

Open the Openbox main config file. Check here for a preliminary reading on how to edit the bugger. It's XML, so it looks like a mess, but if you use a nice editor that has coloured mark up, like vim or nano, it will be easier.
The standard location for the config file in Openbox should be:



 .  
 ~/.config/openbox/rc.xml  



and for LXDE:



 .  
 ~/.config/openbox/lxde-rc.xml  



In the section called
 <keyboard> 
 you can add all your keyboard shortcuts.
In most cases, the kernel will automatically recognise your multimedia key input. However, in some cases you might have to manually assign those keys. In case these instructions don't work, this might be the culprit. See here for more help.

Make sure that amixer is available on your machine (in Debian, that would be the package alsa-utils). Even though this is an ALSA utility, this works perfectly well with Pulseaudio, too.

We will add the following code so the Volume Up button works:



 .  
   <keybind key="XF86AudioRaiseVolume">  
    <action name="Execute">  
     <startupnotify>  
      <enabled>true</enabled>  
      <name>volumeup</name>  
     </startupnotify>  
     <command>amixer -c 0 set Master 2%+ unmute</command>  
    </action>  
   </keybind>  



I've rendered the amixer command in bold letters. I've also set the command to raise the volume by 2% each time I hit the key. If that is too finely grained for you, just pick a higher percentage.

Here's the same example for a command to lower the volume:



 .  
   <keybind key="XF86AudioLowerVolume">  
    <action name="Execute">  
     <startupnotify>  
      <enabled>true</enabled>  
      <name>volumedown</name>  
     </startupnotify>  
     <command>amixer -c 0 set Master 2%- unmute</command>  
    </action>  
   </keybind>  



The only difference here is a minus instead of a plus sign.
Finally, we need a way to mute/unmute sound.
There is a little issue here which makes unmuting the sound on Pulseaudio not work, which is why I will present 2 separate configurations for ALSA and Pulseaudio, respectively.  I've fixed this issue based on this post.
For ALSA:


 .  
   <keybind key="XF86AudioMute">  
    <action name="Execute">  
     <startupnotify>  
      <enabled>true</enabled>  
      <name>volumemute</name>  
     </startupnotify>  
     <command>amixer -c 0 set Master toggle</command>  
    </action>  
   </keybind>  



For Pulseaudio:



 .  
   <keybind key="XF86AudioMute">  
    <action name="Execute">  
     <startupnotify>  
      <enabled>true</enabled>  
      <name>volumemute</name>  
     </startupnotify>  
     <command>amixer -D pulse set Master 1+ toggle</command>  
    </action>  
   </keybind>  



I hope you get the idea behind all this. The multimedia keys mostly already have a certain denominator in X.org, making it easier to assign anything to these keys. You could use xev as described in the preliminary link above on the Arch Wiki to find out what the other keys have as denominators. You can thus set up the rest of the bunch, such as the calculator or the play/pause/skip buttons and you could assign any command to them you like.

However, there is just one issue with all this - we don't get any visual feedback as to whether anything is happening, since amixer is a command line programme run in the background.
Fortunately, there is a nifty tool from the Xfce desktop environment that only pulls in gstreamer and a few basic libs you have on any Linux installation anyway. The tool is called Xfce Volume Daemon. In Debian, the package is xfce4-volumed.
You have to run the command in your .xinitrc / .xsession or Openbox autostart file. Just put this among your other commands:



 .  
 xfce4-volumed &  



You will get a libnotify pop-up window that actually follows your GTK theme.
Of course, in order for this to work, you need a notification daemon. I suggest xfce4-notifyd. It even comes with a very nifty tool to customise the looks of the notification bubble:



 .  
 xfce4-notifyd-config &  



That's all.