# -*- python -*-
from common import *
class MyXMonad(Entry):
def __init__(self, *args, mod = Xlib.XK.XK_Super_L, ppWsSep = '', ppSep = ' ', **kwargs):
self.text = ''
self.text_short = ''
self.ws_sep_len = len(ppWsSep)
self.sep_len = len(ppSep)
self.mod = mod
self.show_full = True
self.short_layout = None
Entry.__init__(self, *args, **kwargs)
xasync(lambda : forever(t(self.refresh)), name = 'xmonad')
def action(self, col, button, x, y):
if button == MIDDLE_BUTTON:
self.show_full = not self.show_full
self.invalidate()
return
text = self.text
full = self.show_full
UTF8_STRING = G.display.intern_atom('UTF8_STRING')
_XMONAD_LOG = G.display.intern_atom('_XMONAD_LOG')
_NET_DESKTOP_NAMES = G.display.intern_atom('_NET_DESKTOP_NAMES')
xmonad_log = G.display.screen().root.get_full_property(_XMONAD_LOG, UTF8_STRING).value.decode('utf-8', 'replace')
xmonad_log = xmonad_log.split(' : ')
net_desktop_names = G.display.screen().root.get_full_property(_NET_DESKTOP_NAMES, UTF8_STRING).value.decode('utf-8', 'replace')
net_desktop_names = net_desktop_names[:-1].split('\0')
ws = 0
ws_hit = False
while ws < len(net_desktop_names):
if ws > 0:
col -= self.ws_sep_len
if col < 0:
break
width = len(net_desktop_names[ws] if full else str(ws + 1)) + 2
if col < width:
ws_hit = True
break
ws += 1
col -= width
if ws < len(net_desktop_names):
if button == LEFT_BUTTON:
self.switch_workspace(ws + 1)
elif button in (SCROLL_UP, SCROLL_DOWN):
xmonad_log = xmonad_log[0].split(' ')
active = [net_desktop_names.index(w[1:-1]) for w in xmonad_log if w[:1] == '<']
ws = [net_desktop_names.index(w[1:-1]) for w in xmonad_log if w[:1] == '['][0]
ws += -1 if button == SCROLL_UP else +1
ws %= len(net_desktop_names)
while ws in active:
ws += -1 if button == SCROLL_UP else +1
ws %= len(net_desktop_names)
self.switch_workspace(ws + 1)
elif button == LEFT_BUTTON:
col -= self.sep_len
layout = xmonad_log[1]
if not self.show_full and self.short_layout is not None:
layout = self.short_layout
if col < len(layout) + 2:
G.display.xtest_fake_input(Xlib.X.KeyPress, G.display.keysym_to_keycode(self.mod))
G.display.xtest_fake_input(Xlib.X.KeyPress, G.display.keysym_to_keycode(Xlib.XK.XK_space))
G.display.xtest_fake_input(Xlib.X.KeyRelease, G.display.keysym_to_keycode(Xlib.XK.XK_space))
G.display.xtest_fake_input(Xlib.X.KeyRelease, G.display.keysym_to_keycode(self.mod))
G.display.flush()
def refresh(self):
try:
text = input()
except:
sys.exit(0)
buf, esc = '', None
for c in text:
if esc is not None:
esc += c
if esc == '^':
buf += '^'
esc = None
elif esc[-1] == ')':
if esc.startswith('bg(') or esc.startswith('fg('):
c = 4 if esc.startswith('bg(') else 3
esc = esc[3 : -1]
if esc == '':
buf += '\033[%i9m' % c
else:
r, g, b = esc[1 : 3], esc[3 : 5], esc[5 : 7]
r, g, b = int(r, 16), int(g, 16), int(b, 16)
r, g, b = str(r), str(g), str(b)
buf += '\033[%i8;2;%sm' % (c, ';'.join([r, g, b]))
esc = None
elif c == '^':
esc = ''
else:
buf += c
self.text = buf
short = ''
space, esc, layout, lbuf = False, False, 0, ''
ws = 1
for c in buf:
if esc:
short += c
esc = not (c == '~' or 'a' <= c.lower() <= 'z')
elif c == '\033':
esc = True
if layout == 2:
layout = 3
end = ''
while lbuf.startswith(' '):
short += ' '
lbuf = lbuf[1:]
while lbuf.endswith(' '):
end += ' '
lbuf = lbuf[:-1]
self.short_layout = self.shorten_layout(lbuf)
short += self.short_layout + end
short += c
elif ws <= 9:
if c in ' <>[]':
space = not space
if not space:
short += '%i' % ws
ws += 1
if ws == 10:
layout = 1
short += c
elif not space:
short += c
elif layout == 1:
if c == ' ':
short += c
else:
layout = 2
lbuf += c
elif layout == 2:
lbuf += c
else:
short += c
self.text_short = short
self.invalidate()
def shorten_layout(self, text):
text = text.split(' ')
incl = []
for word in text:
if word not in ('ImageButtonDeco', 'Maximize', 'Minimize'):
incl.append(word)
return ' '.join(incl).replace('Mirror ', '\\')
def switch_workspace(self, ws):
G.display.xtest_fake_input(Xlib.X.KeyPress, G.display.keysym_to_keycode(self.mod))
G.display.xtest_fake_input(Xlib.X.KeyPress, G.display.keysym_to_keycode(Xlib.XK.XK_0 + ws))
G.display.xtest_fake_input(Xlib.X.KeyRelease, G.display.keysym_to_keycode(Xlib.XK.XK_0 + ws))
G.display.xtest_fake_input(Xlib.X.KeyRelease, G.display.keysym_to_keycode(self.mod))
G.display.flush()
def function(self):
return self.text if self.show_full else self.text_short