You are not logged in.
Often when my wife hits a keyboard command to launch a program she is either impatient and hits it too much or holds the key down - this can lead to multimple instances of a program launching.
Now I have altered my keyboard shortcuts to be like this
~/mybin/start-one-instance-of firefox
~/mybin/start-one-instance-of chromium
~/mybin/start-one-instance-of gimp
~/mybin/start-one-instance-of skype
~/mybin/start-one-instance-of abiword(noted this does not work for Chromium seemingly because each tab is an instance)
etc so that all programs are launched via a script where the program name is passed to the script as a variable.
the script (requires zenity for user feedback but can be reworked to xmessage or even no feedback at all)
#!/bin/bash
# script is called with scriptname programname and program name becomes $1
# we then use the variable name myprog to refer to this value in the script
myprog=$1
# sleep time before checking, can be 0 (zero)
mytime="0"
###
# program starts here
###
echo "Looking for multiple instances of $myprog ..."
# Snooze here to let system settle if required
sleep $mytime
mypid="$(pidof $myprog)"
echo "$mypid"
if [ $mypid -ge "1" ]
then
# one $myprog - we have a genuine pid
# expr fails with multiple pids or no pid at all
echo "one $myprog loaded, all good"
zenity --title="Launch $myprog" --warning --text="$myprog is already running" --timeout="3"
else
## optionally completely kill the program
## no need to do this in most cases
#echo "killing $myprog"
#killall $myprog
#sleep 1s
echo "loading one instance of $myprog"
# load just one instance of program (in the background (&))
$myprog &
fi
exitLast edited by tawan (2011-01-30 07:14:55)
Offline
I think the StumpWM way is better. It has a nice run-or-raise function, that uses WM_CLASS etc, so it also works for Chromium etc. C-t e does that for Emacs by default, and you can create your own commands, like so:
(defcommand chromium () ()
(run-or-raise "chromium" '(:class "Chromium")))
(define-key *root-map* (kbd "b") "chromium")Awesome can also do this IIRC.
Offline
Well, you can switch WM, or implement run-or-raise as a standalone program.
Offline
Now requiring wmctrl the script will call a program to focus if it already running, even switch you to the relevant desktop.
added
# try to bring it to focus
wmctrl -a "$myprog"#!/bin/bash
# edit as you need
# name of program you want one instance of
myprog=$1
# sleep time before checking, can be 0 (zero)
mytime="0"
###
# program starts here
###
echo "Looking for multiple instances of $myprog ..."
# Snooze here to let system settle if required
sleep $mytime
mypid="$(pidof $myprog)"
echo "$mypid"
if [ $mypid -ge "1" ]
then
# one $myprog - we have a genuine pid
# expr fails with multiple pids or no pid at all
echo "one $myprog loaded, all good"
# try to bring it to focus
wmctrl -a "$myprog"
zenity --title="Launch $myprog" --warning --text="$myprog is already running" --timeout="3"
else
## optionally completely kill the program
## no need to do this in most cases
#echo "killing $myprog"
#killall $myprog
#sleep 1s
echo "loading one instance of $myprog"
# load just one instance of program (in the background (&))
$myprog &
fi
exitOffline
Hey.
There's a teensy problem with that approach. wmctrl -a won't work if it's an ncurses program that doesn't set the terminal title for example or if it runs inside screen but isn't focussed.
Looking into that i found you can get the xid as well by looking into /proc/$pid/environ. It's a binary file that usually contains XINDOWID=$xwindowid.
Just my 2 cents ![]()
ADD:
I've found the following a nice way around it
sed -n 's|.*WINDOWID=\([0-9]*\).*|\1|p' /proc/$(pgrep cmus)/environ
As an example ![]()
hacked away and it's fugly not formatted, happy for any pointers to improve it.
you'd put it in your menu or keys file in fluxbox e.g. with myscript.sh $APPNAME and urxvt -e if it's a terminal app, e.g.:
myscript.sh mocp urxvt -e
That will either start it in new Terminal then which you'd have to edit inside the script to whatever you use, or use wmctrl -a to raise and focus. also can deal with stuff like mocp that spawns multiple processes. Well here it is:
#!/bin/sh
if ! [ $1 ] ; then exit ; fi
if [ -z "$(pgrep $1)" ] ; then ${@:2} $1 ; exit ; fi
for i in $(pgrep $1); do if (( $(cut -d " " -f 7 /proc/${i}/stat) )) ;then wmctrl -i -a $(sed -n 's|.*WINDOWID=\([0-9]*\).*|\1|p' /proc/${i}/environ ) ;fi;done
Last edited by demonicmaniac (2011-02-27 15:28:58)
Offline