# -*- 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