summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Palfrader <peter@palfrader.org>2012-09-28 13:44:44 +0000
committerweasel <weasel@bc3d92e2-beff-0310-a7cd-cc87d7ac0ede>2012-09-28 13:44:44 +0000
commitdc28cdcd211c6f7923829ff3b76b28d9d740b77d (patch)
tree3de1f3e8997b3e89c3bf61cdc7f7ea6ad9b4eb61
parent0839330461fa86d5115fe39063f926aec3bf5b71 (diff)
Add wss
git-svn-id: svn+ssh://asteria.noreply.org/svn/weaselutils/trunk@551 bc3d92e2-beff-0310-a7cd-cc87d7ac0ede
-rwxr-xr-xwss209
1 files changed, 209 insertions, 0 deletions
diff --git a/wss b/wss
new file mode 100755
index 0000000..7bce0eb
--- /dev/null
+++ b/wss
@@ -0,0 +1,209 @@
+#!/usr/bin/python
+
+# workspace switcher status
+#
+# display the workspaces of e.g. an xfce desktop during workspaces switches,
+# including a sketch of all windows
+
+# Copyright (c) 2012 Peter Palfrader
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+
+import pygtk, gtk, glib
+import wnck
+
+SCALE=50
+BORDER=3
+DELAY=500
+
+class WSS:
+ def cb_hide(self, data=None):
+ self.window.hide()
+ return False
+
+ def cb_update(self, widget, data=None):
+ workspace = self.screen.get_active_workspace()
+ if self.previous is not None:
+ self.label.set_markup("<span size='xx-large'>%s</span>"%(workspace.get_name()))
+
+ if not self.timerid is None:
+ glib.source_remove(self.timerid)
+ self.timerid = glib.timeout_add(DELAY, self.cb_hide)
+
+ self.paint()
+ self.window.queue_draw()
+ self.window.show()
+ self.previous = workspace
+
+ def get_layout(self):
+ wsposmap = {}
+ if self.layout is None:
+ wss = self.screen.get_workspaces()
+ maxrow = 0
+ maxcol = 0
+ for ws in wss:
+ r = ws.get_layout_row()
+ c = ws.get_layout_column()
+ if r > maxrow: maxrow = r
+ if c > maxcol: maxcol = c
+ wsposmap[ws.get_number()] = (r,c)
+ w = self.screen.get_width()
+ h = self.screen.get_height()
+
+ self.layout = (w, h, maxrow+1, maxcol+1)
+ self.wsposmap = wsposmap
+ return self.layout
+
+ def setup_table(self):
+ if self.table is not None: return
+ width, height, rows, cols = self.get_layout()
+
+ table = gtk.Table(rows, cols, True)
+ table.set_col_spacings(BORDER)
+ table.set_row_spacings(BORDER)
+ cells = []
+ areainfo = {}
+
+ for r in xrange(0,rows):
+ cells.append([])
+ for c in xrange(0,cols):
+ area = gtk.DrawingArea()
+ area.set_size_request(width/SCALE+2, height/SCALE+2)
+ area.connect("expose-event", self.area_expose_cb)
+ table.attach(area, c, c+1, r, r+1, xpadding=0, ypadding=0)
+
+ i = {}
+ i['w'] = []
+
+ cells[r].append(i)
+ areainfo[area] = i
+
+
+ table.show_all()
+ self.box.add(table)
+ self.table = table
+ self.cells = cells
+ self.areainfo = areainfo
+
+ def area_expose_cb(self, area, event):
+ width, height, rows, cols = self.get_layout()
+
+ style = area.get_style()
+ defgc = style.fg_gc[gtk.STATE_NORMAL]
+
+ active_window = self.screen.get_active_window()
+
+ i = self.areainfo[area]
+ if 'gc' not in i:
+ c = area.window.get_colormap().alloc_color(gtk.gdk.Color('#666666'), writeable=False, best_match=True)
+ i['gc'] = area.window.new_gc(foreground=c)
+ c = area.window.get_colormap().alloc_color(gtk.gdk.Color('#bbbbff'), writeable=False, best_match=True)
+ i['gc-focus'] = area.window.new_gc(foreground=c)
+ c = area.window.get_colormap().alloc_color(gtk.gdk.Color('#0000FF'), writeable=False, best_match=True)
+ i['gc-border'] = area.window.new_gc(foreground=c, line_width=3)
+
+ for w in i['w']:
+ geom = w.get_geometry()
+ if w == active_window:
+ area.window.draw_rectangle(i['gc-focus'], True, geom[0]/SCALE+1, geom[1]/SCALE+1, geom[2]/SCALE, geom[3]/SCALE)
+ area.window.draw_rectangle(defgc, False, geom[0]/SCALE+1, geom[1]/SCALE+1, geom[2]/SCALE, geom[3]/SCALE)
+ else:
+ area.window.draw_rectangle(i['gc'], True, geom[0]/SCALE+1, geom[1]/SCALE+1, geom[2]/SCALE, geom[3]/SCALE)
+ area.window.draw_rectangle(defgc, False, geom[0]/SCALE+1, geom[1]/SCALE+1, geom[2]/SCALE, geom[3]/SCALE)
+
+ if i['active']:
+ area.window.draw_rectangle(i['gc-border'], False, 0, 0, width/SCALE+1, height/SCALE+1)
+ else:
+ area.window.draw_rectangle(defgc, False, 0, 0, width/SCALE+1, height/SCALE+1)
+
+ return True
+
+ def cell_info_from_workspace(self, ws):
+ wsn = ws.get_number()
+ wspos = self.wsposmap[wsn]
+ row, col = wspos
+ cell = self.cells[row][col]
+
+ return cell
+
+ def paint(self):
+ width, height, mr, mc = self.get_layout()
+ self.setup_table()
+
+ window_list = self.screen.get_windows()
+ for a in self.areainfo:
+ del self.areainfo[a]['w'][:]
+ self.areainfo[a]['active'] = False
+
+ for w in window_list:
+ ws = w.get_workspace()
+ if ws is not None:
+ cell = self.cell_info_from_workspace(ws)
+ cell['w'].append(w)
+
+ active = self.screen.get_active_workspace()
+ cell = self.cell_info_from_workspace(active)
+ cell['active'] = True
+
+
+ def __init__(self):
+ window = gtk.Window(gtk.WINDOW_POPUP)
+
+ label = gtk.Label()
+
+ box = gtk.VBox()
+ box.set_border_width(20)
+
+ box.add(label)
+ window.add(box)
+
+ window.set_position(gtk.WIN_POS_CENTER)
+
+ box.show_all()
+
+ screen = wnck.screen_get_default()
+ screen.connect('active-workspace-changed', self.cb_update)
+
+ self.window = window
+ self.label = label
+ self.box = box
+ self.screen = screen
+ self.previous = None
+ self.table = None
+ self.cells = None
+ self.layout = None
+ self.areainfo = None
+ self.timerid = None
+
+ def main(self):
+ # All PyGTK applications must have a gtk.main(). Control ends here
+ # and waits for an event to occur (like a key press or mouse event).
+ gtk.main()
+
+if __name__ == "__main__":
+ wss = WSS()
+ wss.main()
+
+# vim:set et:
+# vim:set ts=4:
+# vim:set shiftwidth=4: