Add listers for i3wm workspaces and outputs

This commit is contained in:
S0lll0s 2016-01-12 22:38:03 +01:00
parent bc7d571d00
commit 24fa03567e
7 changed files with 108 additions and 11 deletions

View File

@ -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 <dev-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:

View File

@ -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
=============

View File

@ -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<name>[0-9A-Za-z-]+) connected (?P<width>\d+)x(?P<height>\d+)\+(?P<x>\d+)\+(?P<y>\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))

View File

@ -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

View File

@ -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))

78
powerline/listers/i3wm.py Normal file
View File

@ -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<name>[0-9A-Za-z-]+) connected (?P<width>\d+)x(?P<height>\d+)\+(?P<x>\d+)\+(?P<y>\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)))
)

View File

@ -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))
]