From 24fa03567e5034728ddb7cdff697dfed058b03ab Mon Sep 17 00:00:00 2001 From: S0lll0s Date: Tue, 12 Jan 2016 22:38:03 +0100 Subject: [PATCH] Add listers for i3wm workspaces and outputs --- docs/source/configuration/listers.rst | 8 +- docs/source/develop/segments.rst | 6 ++ .../bindings/lemonbar/powerline-lemonbar.py | 9 +-- powerline/lib/dict.py | 8 ++ powerline/lint/imp.py | 6 ++ powerline/listers/i3wm.py | 78 +++++++++++++++++++ powerline/segments/i3wm.py | 4 +- 7 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 powerline/listers/i3wm.py diff --git a/docs/source/configuration/listers.rst b/docs/source/configuration/listers.rst index 04e5371e..e6ba06e7 100644 --- a/docs/source/configuration/listers.rst +++ b/docs/source/configuration/listers.rst @@ -16,8 +16,6 @@ their type and ``segments`` key with a list of segments (a bit more details in More information in :ref:`Writing listers ` section. -Currently only Vim listers are available. - Vim listers ----------- @@ -29,3 +27,9 @@ Pdb listers .. automodule:: powerline.listers.pdb :members: + +i3wm listers +---------- + +.. automodule:: powerline.listers.i3wm + :members: diff --git a/docs/source/develop/segments.rst b/docs/source/develop/segments.rst index a47d0a52..30f4a664 100644 --- a/docs/source/develop/segments.rst +++ b/docs/source/develop/segments.rst @@ -527,6 +527,12 @@ i3wm ``xrandr`` output name currently drawing to. Currently only available in lemonbar bindings. +``workspace`` + dictionary containing the workspace name under the key ``"name"`` and + boolean values for the ``"visible"``, ``"urgent"`` and ``"focused"`` + keys, indicating the state of the workspace. Currently only provided by + the :py:func:`powerline.listers.i3wm.workspace_lister` lister. + Segment class ============= diff --git a/powerline/bindings/lemonbar/powerline-lemonbar.py b/powerline/bindings/lemonbar/powerline-lemonbar.py index ae4ffb34..5a272ab5 100755 --- a/powerline/bindings/lemonbar/powerline-lemonbar.py +++ b/powerline/bindings/lemonbar/powerline-lemonbar.py @@ -9,8 +9,8 @@ import subprocess from threading import Lock, Timer from powerline.lemonbar import LemonbarPowerline -from powerline.lib.shell import run_cmd from powerline.commands.lemonbar import get_argparser +from powerline.listers.i3wm import get_connected_xrandr_outputs if __name__ == '__main__': @@ -20,13 +20,8 @@ if __name__ == '__main__': powerline = LemonbarPowerline() powerline.update_renderer() bars = [] - active_screens = [match.groupdict() for match in re.finditer( - '^(?P[0-9A-Za-z-]+) connected (?P\d+)x(?P\d+)\+(?P\d+)\+(?P\d+)', - run_cmd(powerline.pl, ['xrandr', '-q']), - re.MULTILINE - )] - for screen in active_screens: + for screen in get_connected_xrandr_outputs(powerline.pl): command = [args.bar_command, '-g', '{0}x{1}+{2}'.format(screen['width'], args.height, screen['x'])] + args.args[1:] process = subprocess.Popen(command, stdin=subprocess.PIPE) bars.append((screen['name'], process, int(screen['width']) / 5)) diff --git a/powerline/lib/dict.py b/powerline/lib/dict.py index d8d2088b..c06ab30c 100644 --- a/powerline/lib/dict.py +++ b/powerline/lib/dict.py @@ -78,3 +78,11 @@ def mergedicts_copy(d1, d2): else: ret[k] = d2[k] return ret + + +def updated(d, *args, **kwargs): + '''Copy dictionary and update it with provided arguments + ''' + d = d.copy() + d.update(*args, **kwargs) + return d diff --git a/powerline/lint/imp.py b/powerline/lint/imp.py index 6e402132..399654e1 100644 --- a/powerline/lint/imp.py +++ b/powerline/lint/imp.py @@ -21,6 +21,12 @@ class WithPath(object): def import_function(function_type, name, data, context, echoerr, module): havemarks(name, module) + if module == 'powerline.segments.i3wm' and name == 'workspaces': + echoerr(context='Warning while checking segments (key {key})'.format(key=context.key), + context_mark=name.mark, + problem='segment {0} from {1} is deprecated'.format(name, module), + problem_mark=module.mark) + with WithPath(data['import_paths']): try: func = getattr(__import__(str(module), fromlist=[str(name)]), str(name)) diff --git a/powerline/listers/i3wm.py b/powerline/listers/i3wm.py new file mode 100644 index 00000000..fedb7c81 --- /dev/null +++ b/powerline/listers/i3wm.py @@ -0,0 +1,78 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +import re + +from powerline.theme import requires_segment_info +from powerline.lib.shell import run_cmd +from powerline.lib.dict import updated + + +conn = None +XRANDR_OUTPUT_RE = re.compile(r'^(?P[0-9A-Za-z-]+) connected (?P\d+)x(?P\d+)\+(?P\d+)\+(?P\d+)', re.MULTILINE) +def get_connected_xrandr_outputs(pl): + return (match.groupdict() for match in XRANDR_OUTPUT_RE.finditer( + run_cmd(pl, ['xrandr', '-q']) + )) + + +@requires_segment_info +def output_lister(pl, segment_info): + '''List all outputs in segment_info format + ''' + + return ( + ( + updated(segment_info, output=output['name']), + { + 'draw_inner_divider': None + } + ) + for output in get_connected_xrandr_outputs(pl) + ) + + +@requires_segment_info +def workspace_lister(pl, segment_info, only_show=None, output=None): + '''List all workspaces in segment_info format + + Sets the segment info values of ``workspace`` and ``output`` to the name of + the i3 workspace and the ``xrandr`` output respectively and the keys + ``"visible"``, ``"urgent"`` and ``"focused`` to a boolean indicating these + states. + + :param list only_show: + Specifies which workspaces to list. Valid entries are ``"visible"``, + ``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces + are listed. + + :param str output: + May be set to the name of an X output. If specified, only workspaces + on that output are listed. Overrides automatic output detection by + the lemonbar renderer and bindings. Set to ``false`` to force + all workspaces to be shown. + ''' + + if output == None: + output = output or segment_info.get('output') + + return ( + ( + updated( + segment_info, + output=w['output'], + workspace={ + 'name': w['name'], + 'visible': w['visible'], + 'urgent': w['urgent'], + 'focused': w['focused'], + }, + ), + { + 'draw_inner_divider': None + } + ) + for w in conn.get_workspaces() + if (((not only_show or any(w[typ] for typ in only_show)) + and (not output or w['output'] == output))) + ) diff --git a/powerline/segments/i3wm.py b/powerline/segments/i3wm.py index 29093072..8be8ada0 100644 --- a/powerline/segments/i3wm.py +++ b/powerline/segments/i3wm.py @@ -54,8 +54,8 @@ def workspaces(pl, segment_info, only_show=None, output=None, strip=0): 'contents': w['name'][strip:], 'highlight_groups': calcgrp(w) } for w in conn.get_workspaces() - if (not only_show or any(w[typ] for typ in only_show)) - and (not output or w['output'] == output) + if ((not only_show or any(w[typ] for typ in only_show)) + and (not output or w['output'] == output)) ]