Scripting wmii column widths with Python
I mentioned in my previous post on using wmii with Gnome that I had written a script for resizing the column widths in wmii. This is the followup post. Note, I am using the 20080520 snapshot of wmii. This doesn't work with wmii 3.6 (as Marco commented below).
To incrementally change window sizes, I use the following in my
~/.wmii-3.5/wmiirc file:
Key $MODKEY-y # shrink horizontally wmiir xwrite /tag/sel/ctl grow sel sel right -10 wmiir xwrite /tag/sel/ctl grow sel sel left -10 Key $MODKEY-u # grow horizontally wmiir xwrite /tag/sel/ctl grow sel sel right 10 wmiir xwrite /tag/sel/ctl grow sel sel left 10 Key $MODKEY-i # shrink vertically wmiir xwrite /tag/sel/ctl grow sel sel down -10 wmiir xwrite /tag/sel/ctl grow sel sel up -10 Key $MODKEY-o # grow vertically wmiir xwrite /tag/sel/ctl grow sel sel down 10 wmiir xwrite /tag/sel/ctl grow sel sel up 10 Key $MODKEY-Shift-y # shrink horizontally wmiir xwrite /tag/sel/ctl grow sel sel right -2 wmiir xwrite /tag/sel/ctl grow sel sel left -2 Key $MODKEY-Shift-u # grow horizontally wmiir xwrite /tag/sel/ctl grow sel sel right 2 wmiir xwrite /tag/sel/ctl grow sel sel left 2 Key $MODKEY-Shift-i # shrink vertically wmiir xwrite /tag/sel/ctl grow sel sel down -2 wmiir xwrite /tag/sel/ctl grow sel sel up -2 Key $MODKEY-Shift-o # grow vertically wmiir xwrite /tag/sel/ctl grow sel sel down 2 wmiir xwrite /tag/sel/ctl grow sel sel up 2
In addition to incrementally changing column widths, I wanted to
be able to switch to predetermined column width ratios with a keyboard
shortcut. For example, I wanted to be able to set the column widths
at a 20/80 ratio, a 40/60 ratio, a 50/50 ratio, a 60/40 ratio, and so on.
So I hacked a Python script to do this. It is pretty ugly because
I first grow the window by a set amount, measure the change in size,
then grow it again to the correct width. If anyone knows of a better
way to do this, please let me know. I'm posting my solution here
in case anyone else wanted to do the same thing and got stuck.
(Note, this script only works with two columns)
UPDATE 2009-12-21: I just learned from the new wmii documentation that I can specify a grow amount in pixels by suffixing it with "px". This means I no longer have to perform the ugly, extra grow-then-measure step in my script. I'm not sure if this is a newly added change or if it is just newly documented. I am now using wmii 3.9b1. I have updated the script below to use the new method. Also, the script now works with more than two columns. I kept the old method for reference.
#!/usr/bin/env python
import os
import re
import sys
class Wmii:
"""
wmiir xwrite /tag/sel/ctl grow col row side increment
col: column number of the window to grow
row: row number of the window to grow
side: the side to grow. one of left, right, up, or down
increment: the number of pixels to grow. use a positive number to grow larger
and a negative number to grow smaller
"""
def set_column_widths(self, width_list):
"""Use the 'grow' command to set the column widths to those specified.
Widths are specified in percentages.
"""
total_width_perc = sum([float(width) for width in width_list])
for i, width_perc in enumerate(width_list[:-1]):
self.read_current_col_widths()
total_width_px = float(sum(self.curr_colwidths))
new_width_px = float(width_perc) / total_width_perc * total_width_px
grow_amount_px = int(round(new_width_px - self.curr_colwidths[i]))
self.xwrite("/tag/sel/ctl grow %d 1 right %dpx" % (i+1, grow_amount_px))
def read_current_col_widths(self):
"""'wmiir read /tag/sel/index' and set the attribute, self.curr_colwidths.
self.curr_colwidths is a list of the width (ints) (in pixels) of each
column in the view.
"""
lines = self.read("/tag/sel/index")
self.curr_colwidths = []
for line in lines:
match = re.search(r"# [^~]+ \d+ (\d+)", line)
if match:
self.curr_colwidths.append(int(match.group(1)))
print self.curr_colwidths
def xwrite(self, path_and_value):
"""Use the xwrite form."""
cmd = "wmiir xwrite %s" % path_and_value
print cmd
os.system(cmd)
def read(self, path):
"""Return a list of the lines returned by "wmii read path" """
return os.popen4("wmiir read " + path)[1].readlines()
if __name__ == "__main__":
w = Wmii()
w.set_column_widths(sys.argv[1:])
#!/usr/bin/env python
import os
import re
import sys
class Wmii:
"""
wmiir xwrite /tag/sel/ctl grow col row side increment
col: column number of the window to grow
row: row number of the window to grow
side: the side to grow. one of left, right, up, or down
increment: the number of pixels to grow. use a positive number to grow larger
and a negative number to grow smaller
"""
def __init__(self):
pass
def set_column_widths(self, width0, width1):
"""Use the 'grow' command to set the column widths to those specified.
Widths are specified in percentages.
Currently only works with 2 columns.
"""
self.determine_pixels_per_grow_horiz()
new_width0 = sum(self.curr_colwidths) * (float(width0) /
(float(width0)+float(width1)))
grow_amount = int(round((new_width0-self.curr_colwidths[0]) /
self.pixels_per_grow_increment))
self.xwrite("/tag/sel/ctl grow 1 1 right %d" % grow_amount)
def determine_pixels_per_grow_horiz(self):
"""Try growing by an increment of 1 and record the number of pixels changed.
"""
self.read_current_col_widths()
prev_colwidth0 = self.curr_colwidths[0]
self.xwrite("/tag/sel/ctl grow 1 1 right 1")
self.read_current_col_widths()
self.pixels_per_grow_increment = self.curr_colwidths[0] - prev_colwidth0
def read_current_col_widths(self):
"""'wmiir read /tag/sel/index' and set the attribute, self.curr_colwidths.
self.curr_colwidths is a list of the width (ints) (in pixels) of each
column in the view.
"""
lines = self.read("/tag/sel/index")
self.curr_colwidths = []
for line in lines:
match = re.search(r"# [^~]+ \d+ (\d+)", line)
if match:
self.curr_colwidths.append(int(match.group(1)))
print self.curr_colwidths
def read_current_column_number(self):
"""'wmiir read /tag/sel/ctl' and set the attribute, self.curr_col."""
lines = self.read("/tag/sel/ctl")
self.curr_col = re.split(" ", lines[1])[1]
print "curr_col = %s" % self.curr_col
def xwrite(self, path_and_value):
"""Use the xwrite form."""
cmd = "wmiir xwrite %s" % path_and_value
print cmd
os.system(cmd)
def read(self, path):
"""Return a list of the lines returned by "wmii read path" """
return os.popen4("wmiir read " + path)[1].readlines()
if __name__ == "__main__":
w = Wmii()
w.set_column_widths(sys.argv[1], sys.argv[2])
I named the script wmii.py, made it executable,
and put it on my path. Then I modified my wmiirc:
Key $MODKEY-q wmii.py 20 80 Key $MODKEY-w wmii.py 40 60 Key $MODKEY-e wmii.py 50 50 Key $MODKEY-r wmii.py 60 40 Key $MODKEY-t wmii.py 80 20
Hope that's helpful to someone. Let me know if you've written some cool python wmii scripts.
3
Comments
—
Comments feed for this post
#2 Eliot commented on 2009-04-15:
Hi Marco, OK, thanks for the information-- I'll update my post. Good luck with upgrading wmii. I recommend the 20080520 snapshot over 3.6. Here are my install notes for wmii snapshot: http://www.saltycrane.com/blog/2008/07/install-wmii-snapshot/
Post a comment
About
I'm Eliot and this is my notepad for programming topics such as Python, Django, Ubuntu, Emacs, etc... more »
Search Blog
Tags
-
algorithms
(4)
-
aws
(8)
-
blogproject
(20)
-
c_cplusplus
(12)
-
cardstore
(8)
-
colinux
(2)
-
concurrency
(9)
-
conkeror
(2)
-
cygwin
(18)
-
datastructures
(15)
-
datetime
(3)
-
dell
(3)
-
django
(39)
-
emacs
(20)
-
files_directories
(10)
-
install_setup
(7)
-
javascript
(3)
-
keyboard
(6)
-
matplotlib
(5)
-
mercurial
(4)
-
nginx
(2)
-
preferences
(8)
-
processes
(3)
-
pyqt
(18)
-
python
(122)
-
ratpoison
(3)
-
regexes
(5)
-
rsync
(3)
-
softwaretools
(17)
-
sql
(13)
-
ssh
(7)
-
subversion
(6)
-
twisted
(6)
-
ubuntu
(60)
-
urxvt
(5)
-
vxworks
(25)
-
webservices
(4)
-
wmii
(7)
Blogroll
- Adam Gomaa
- Alex Clemesha
- Amir Salihefendic
- Armin Ronacher
- David Beazley
- David Ziegler
- Duncan McGreggor
- Gareth Rushgrave
- Glyph Lefkowitz
- Guido van Rossum
- Ian Bicking
- Jacob Kaplan-Moss
- James Bennett
- James Tauber
- Jesper Noehr
- Matt Harrison
- Nikolay Kolev
- Parand Darugar
- Peter Baumgartner
- Peter Bengtsson
- Rob Hudson
- Simon Willison
- Will McGugan
#1 Marco R. commented on 2009-04-15:
Hi sofeng, thanks for the post! Unfortunately the stable wmii-3.6 (dated 2007-11-16) doesn't have the grow command, as confirmed here.
The idea of fixed column width ratios is good, but I would have used just one key shortcut to cycle between the predefined widths. I will experiment with that code after a wmii upgrade...
Bye, Marco