[xmonad] Is it possible to reset Xmobar without restarting Xmonad?

Toby Cubitt tsc25 at cantab.net
Sun Feb 12 12:22:42 CET 2012


On Sat, Feb 11, 2012 at 07:22:03PM -0600, Leo Alekseyev wrote:
> I am using xmonad on a tablet PC where I sometimes change the screen
> orientation.  Unfortunately, Xmobar doesn't properly rescale itself
> when the screen goes from portrait to landscape.  If I kill it and
> then restart, the new Xmobar instance doesn't communicate with the
> Xmonad LogHook anymore.  The only solution for me right now is
> restarting Xmonad, which is suboptimal because
> (1) config takes noticeable time to compile and
> (2) my workspace / window configuration gets completely fubared on
> every Xmonad restart (e.g. all the terminal windows like to move
> themselves to a single workspace even though there isn't a doShift
> directive to do so in the config (it might have something to do with
> my using compositing).

I don't have an answer to your xmobar question (I use dzen). But I also
use Xmonad on a tablet. Rather than restarting being sub-optimal, I
actually find it rather useful to restart Xmonad with a different
configuration when I switch to tablet mode. It's useful to have things
configured differently when running in tablet mode, where there's no
(physical) keyboard and the primary input method is a stylus.

I have two separate Xmonad configurations, and use scripts to switch
between them automatically when switching between laptop to tablet mode.

The two Xmonad configurations are stored in xmonad-laptop.hs and
xmonad-tablet.hs (taking advantage of modular configs to factor out the
common parts into a separate module), and the compiled versions are saved
to xmonad-laptop-i386-linux and xmonad-tablet-i386-linux.

xmonad.hs and xmonad-i386-linux are initially symlinks to the "laptop"
files. When switching to tablet mode, the script updates these symlinks
to point to the "tablet" files, and restarts Xmonad. Switching back to
laptop mode reverses the process. Since the source and compiled configs
that the symlinks point to always match, Xmonad detects that they don't
need to be recompiled, so it restarts very quickly.

(The script actually does a bit of additional juggling to avoid having to
compile the two Xmonad configs manually, and allow the usual Xmonad
compile-after-update magic to work for both configs.)

I've attached my xmonad-rotate-screend script, which does the symlink
juggling and restarts Xmonad. It actually does this automatically when it
sees that I've switched to tablet mode, but you could adapt it to your
needs if interested.

(The automatic screen rotation relies on another pair of scripts, which
detect when I switch to tablet mode (unfortunately by polling, as my
laptop doesn't generate an ACPI event when rotating the screen) and uses
xrandr to rotate the screen orientation. I've also attached those
scripts, in case they're useful, though you'd have to modify them for
your system.)

HTH,

Toby
-- 
Dr T. S. Cubitt
Mathematics and Quantum Information group
Department of Mathematics
Complutense University
Madrid, Spain

email: tsc25 at cantab.net
web:   www.dr-qubit.org
-------------- next part --------------
#!/bin/bash

### Configuration
LID="/proc/acpi/button/lid/LID"                  # lid status path
SPOOL_FILE="/var/spool/rotate-screen/rotation"   # 'rotate-screen' command run-file
###


ROTATED=0
while inotifywait "$SPOOL_FILE"; do
    # get current rotation state from run file if it exists
    DISPLAY="$(cat $SPOOL_FILE | cut -d' ' -f2)"
    XAUTH="$(cat $SPOOL_FILE | cut -d' ' -f3)"
    ROTATION="$(XAUTHORITY=$XAUTH DISPLAY=$DISPLAY xrandr --query --verbose | grep " connected" | cut -d' ' -f5)"
    LID_STATE="$(cat $LID/state | awk '{print $2}')"
    HIBERNATING=$(ps aux | grep '[h]ibernate')

    if [ $ROTATED = 0 -a x"$LID_STATE" = x"closed" -a ! x"$ROTATION" = x"normal" -a x"$HIBERNATING" = x ]; then
	# commands to run when transitionaing to tablet mode
	ln -sf ~/.xmonad/xmonad-tablet.hs ~/.xmonad/xmonad.hs
	ln -sf ~/.xmonad/xmonad-tablet-i386-linux ~/.xmonad/xmonad-i386-linux
	xmonad --restart
	ROTATED=1

    elif [ $ROTATED = 1 -a x"$LID_STATE" = x"open" -a x"$ROTATION" = x"normal" ]; then
	# commands to run when transitionaing to laptop mode
    	dzen-pager stop
	ln -sf ~/.xmonad/xmonad-laptop.hs ~/.xmonad/xmonad.hs
	ln -sf ~/.xmonad/xmonad-laptop-i386-linux ~/.xmonad/xmonad-i386-linux
	xmonad --restart
	ROTATED=0
    fi

done
-------------- next part --------------
#!/bin/bash

### Configuration
SLEEP=5                                         # poll lid state every SLEEP seconds
UNROTATE="yes"                                  # restore normal orientation when lid is open
ROTATE="/usr/local/bin/rotate-screen"           # rotate-screen command
LID="/proc/acpi/button/lid/LID"                 # lid status path
SPOOL_FILE="/var/spool/rotate-screen/rotation"  # 'rotate-screen' command spool file
###



while true; do
    # get current rotation state from run file if it exists
    DISPLAY="$(cat $SPOOL_FILE | cut -d' ' -f2)"
    XAUTH="$(cat $SPOOL_FILE | cut -d' ' -f3)"
    ROTATION="$(XAUTHORITY=$XAUTH DISPLAY=$DISPLAY xrandr --query --verbose | grep ' connected' | cut -d' ' -f5)"
    LID_STATE="$(cat $LID/state | awk '{print $2}')"
    HIBERNATING="$(ps aux | grep '[h]ibernate')"

    if [ x"$LID_STATE" = x"closed" -a x"$ROTATION" = x"normal" -a x"$HIBERNATING" = x ]; then
        "$ROTATE"
	echo rotate
    elif [ x"$LID_STATE" = x"open" -a ! x"$ROTATION" = x"normal" ]; then
	[ "$UNROTATE" = "yes" ] && "$ROTATE" normal && 	echo restore
    fi

    sleep $SLEEP
done
-------------- next part --------------
#!/bin/bash


### Configuration:
ORIENTATION=("normal" "left" "inverted" "right")
REDEFINE_KEYSYMS="yes"
RUNFILE="/var/spool/rotate-screen/rotation"
DEVICE="Serial Wacom Tablet stylus"
###



rotate_normal () {
  /usr/bin/xrandr --orientation normal
  /usr/bin/xsetwacom set "$DEVICE" rotate NONE
}

keysyms_normal () {
  /usr/bin/xmodmap -e "keycode 10 = 1 exclam Down"
  /usr/bin/xmodmap -e "keycode 11 = 2 quotedbl Up"
  /usr/bin/xmodmap -e "keycode 12 = 3 sterling Left"
  /usr/bin/xmodmap -e "keycode 13 = 4 dollar Right"
}

rotate_right () {
  /usr/bin/xrandr --orientation right
  /usr/bin/xsetwacom set "$DEVICE" rotate CW
}

keysyms_right () {
  /usr/bin/xmodmap -e "keycode 10 = 1 exclam Right"
  /usr/bin/xmodmap -e "keycode 11 = 2 quotedbl Left"
  /usr/bin/xmodmap -e "keycode 12 = 3 sterling Down"
  /usr/bin/xmodmap -e "keycode 13 = 4 dollar Up"
}

rotate_left () {
  /usr/bin/xrandr --orientation left
  /usr/bin/xsetwacom set "$DEVICE" rotate CCW
}

keysyms_left () {
  /usr/bin/xmodmap -e "keycode 10 = 1 exclam Left"
  /usr/bin/xmodmap -e "keycode 11 = 2 quotedbl Right"
  /usr/bin/xmodmap -e "keycode 12 = 3 sterling Up"
  /usr/bin/xmodmap -e "keycode 13 = 4 dollar Down"
}

rotate_inverted () {
  /usr/bin/xrandr --orientation inverted
  /usr/bin/xsetwacom set "$DEVICE" rotate HALF
}

keysyms_inverted () {
  /usr/bin/xmodmap -e "keycode 10 = 1 exclam Up"
  /usr/bin/xmodmap -e "keycode 11 = 2 quotedbl Down"
  /usr/bin/xmodmap -e "keycode 12 = 3 sterling Right"
  /usr/bin/xmodmap -e "keycode 13 = 4 dollar Left"
}



# get current orientation
if [ -f "$RUNFILE" ]; then
    read CURR_ORIENTATION DUMMY1 DUMMY2 < "$RUNFILE"
fi
if [ ! -z "$CURR_ORIENTATION" ]; then
    CURR_ORIENTATION=`xrandr --query --verbose | grep " connected" | cut -d\  -f5`
fi


# setup variables so we can determine next orientation
NUM=${#ORIENTATION[*]}
for (( i=0 ; i<4 ; i++ )); do
  eval ORIENTATION_${ORIENTATION[$i]}=$i
done

# make sure system Xmodmap is loaded to set up buttons
# (it must at least map super_R to Mode_switch)
/usr/bin/xmodmap /etc/X11/Xmodmap


# get orientation from command line parameter if any
if [ -n "$1" ]; then
    ORIENTATION="$1"
# otherwise, cycle to next orientation
else
    N="ORIENTATION_$CURR_ORIENTATION"
    (( N = (${!N} + 1) % $NUM ))
    ORIENTATION="${ORIENTATION[$N]}"
fi

# rotate and redefine keysyms
"rotate_$ORIENTATION"
[[ -n "$REDEFINE_KEYSYMS" ]] && "keysyms_$ORIENTATION"

# record orientation in spool file
[ -n "$DISPLAY" ] || DISPLAY=:0.0   # for some reason, it's sometimes empty
echo "$ORIENTATION $DISPLAY $XAUTHORITY" > "$RUNFILE"


More information about the xmonad mailing list