Posts Tagged ‘sawfish’

Sawfish and the Gnome “Run Application” dialog

Friday, September 24th, 2004

It has long annoyed me that I couldn’t attach a keyboard short cut to the Gnome panels “Run Application” dialog in Sawfish.

When people ask on the net about it, the answer is usually “Press Alt-F2”, but that only works in metacity, not in sawfish.

In earlier versions of Gnome there was a gnome-run program, but that has gone.

Then, on this blog, I found an explanation and a little program that opens the “Run Application” dialog. All that’s missing is to use add a Sawfish binding to the program, using the sawfish function run-shell-command.

Download a copy of gnome-run.c here. The program is a simple X11 program, compiled with:

gcc gnome-run.c -o gnome-run -L/usr/X11R6/lib -lX11

Looking at the program, I would expect to be able to do it directly from sawfish, but somehow it didn’t work. What I tried was this:

(send-client-message 'root (x-atom '_GNOME_PANEL_ACTION)
     [(x-atom '_GNOME_PANEL_ACTION_RUN_DIALOG) 0] 32)

but, alas, it didn’t work. Would have been neat, though 🙂

Sawfish functions for hotkeys and panel launchers

Monday, August 30th, 2004

One of my laptops has a series of hotkeys that send ACPI events, so I made a script to handle these events, which I later extended to be usable from the desktop or the panel too.

The various applications have different needs, and I use them in different ways. I only have one mail reader open, and its always in the same workspace, while I have many browser windows open in different workspaces. Others, like my calendar application, are used more like dialogs, where I show and hide them in the current workspace. Many require a close interaction with my window manager.

The core of the script looks like this:

case "$1" in
    hotkey)
	case "$3" in
	    00000030) aumix -v+5;;
	    00000031) aumix -v-5;;
	    00000032) mute;;

	    00000040) xmms --rew & ;;
	    00000041) xmms --fwd & ;;
	    00000043) xmms --stop & ;;
	    00000045) xmms --play-pause & ;;

	    00000050) launch_mailer;;
	    00000051) launch_browser;;
	    00000052) launch_xchat;;
	    00000053) launch_calendar ;;

	    0000005c) show_hide_desktop ;;
	esac
	;;

    weblogs)	launch_web_logs;;
    xchat)	launch_xchat;;
    calendar)	launch_calendar;;
    mail)	launch_mailer;;
    vmware)	launch_vmware;;
esac

When called by acpid the invokation is like this:

hotkey hotkey ATKD 00000052

and from a Gnome launcher in the panel or on the desktop:

hotkey calendar

Sound keys

The cd player keys and the volume controls are all software controlled, so if I don’t do anything, they won’t work. I usually play music with xmms and use aumix or setmixer for volume control, so they are the programs used in my scripts.

The volume up/down and play/rew/fwd/stop commands above are all self explanatory. Its all the in the manuals for xmms and aumix. There is no mute function in aumix, so I had to invent one, and it had to restore the correct volume after muting. After some attempts I came up with this:

function mute () {
    case "$(aumix -vq)" in
	"vol 0, 0")
	    (grep '^vol:' ~/.aumixrc-mute 2>/dev/null || echo 'vol:100:100:P') |
	    aumix -f /dev/stdin -L >/dev/null
	    ;;
        *)
            aumix -f ~/.aumixrc-mute -S -v0
	    ;;
    esac
}

It’ll mute and restore the volume at alternating invocations, perfect for a mute button.

Hide and show all windows

I think the button is intended to turn the wifi trasmitter on and off, but I use it for the desktop. The code is this:

function show_hide_desktop () {
    exec sawfish-client -- << EOF
(if (showing-desktop-p)
    (hide-desktop)
  (show-desktop))
EOF
}

Only one application instance open

For some applications I only want one instance open at a given time. It can be my mail reader, vmware, my irc client or any other applications where several instances can be confusing or harmful.

I use the window manager to decide what to do, for example for the mail client:

function launch_mailer () {
    exec sawfish-client -- << EOF
(let ((window (or (get-window-by-name-re "^Mutt")
		  (get-window-by-name-re " - Ximian Evolution$")
		  (get-window-by-name-re "Mozilla Thunderbird$"))))
  (if window
      (display-window window)
    (select-workspace (cdr (workspace-limits )))
    (start-process nil "mozilla-thunderbird")
    )
  )
EOF
}

This function will check for an open mail reader, and if found switch to that window (changing workspace if necessary), and if not found, it will move to the last workspace and launch Mozilla Thunderbird.

Dialog-type application

This is a bit more complicated. I want my calendar to always be around when I need it, but not get in the way when I don’t need it.

I do this by always keeping it in the current workspace, but iconified. This function does it all:

function launch_calendar () {
    exec sawfish-client -- << EOF
(let ((window (or (get-window-by-name "Mozilla Sunbird")
                  (get-window-by-name "Mozilla Calendar"))))
  (if window
      (if (and (window-in-workspace-p window current-workspace)
	       (not (window-iconified-p window))
	       (eq (window-visibility window) 'unobscured))
	  (iconify-window window)
	(move-window-to-workspace window (car (window-workspaces window)) current-workspace)
	(display-window window))
    (start-process nil "sunbird")
    )
  )
EOF
}

If the calendar application is already started, it will check if it is in the current workspace and fully visible. If it is it is iconified, otherwise it is moved into the current workspace, de-iconified and brought to the front. If the calendar is not running, it is started.

The overall effect of this is that alternately display and hide the calendar, regardless of where it was left the last time. One click opens the calendar, the next click closes it.

None of this is quite rocket science, but they are some of those little things that makes day to day work move a bit swifter.