Merge pull request #1431 from S0lll0s/develop

Rename bar (bar-aint-recursive) to lemonbar
This commit is contained in:
Nikolai Aleksandrovich Pavlov 2016-01-09 01:19:46 +03:00
commit 63af1456b4
20 changed files with 563 additions and 88 deletions

View File

@ -187,6 +187,10 @@ Common configuration is a subdictionary that is a value of ``ext`` key in
``out`` and ``rewrite`` prompts (refer to IPython documentation for more ``out`` and ``rewrite`` prompts (refer to IPython documentation for more
details) while ``in`` prompt is the default. details) while ``in`` prompt is the default.
For wm (:ref:`lemonbar <lemonbar-usage>` only) it is a dictionary
``{output : theme_name}`` that maps the ``xrandr`` output names to the
local themes to use on that output.
``components`` ``components``
Determines which extension components should be enabled. This key is highly Determines which extension components should be enabled. This key is highly
extension-specific, here is the table of extensions and corresponding extension-specific, here is the table of extensions and corresponding

View File

@ -6,6 +6,7 @@ import re
import codecs import codecs
from collections import namedtuple from collections import namedtuple
from argparse import REMAINDER
from functools import reduce from functools import reduce
@ -61,9 +62,9 @@ def parse_argument(*args, **kwargs):
is_option = args[0].startswith('-') is_option = args[0].startswith('-')
is_long_option = args[0].startswith('--') is_long_option = args[0].startswith('--')
is_short_option = is_option and not is_long_option is_short_option = is_option and not is_long_option
action = kwargs.get('action', 'store_true') action = kwargs.get('action', 'store')
multi = kwargs.get('action') in ('append',) multi = kwargs.get('action') in ('append',) or kwargs.get('nargs') is REMAINDER
nargs = kwargs.get('nargs') or (1 if kwargs.get('metavar') or action in ('append',) else 0) nargs = kwargs.get('nargs', (1 if action in ('append', 'store') else 0))
return Argument( return Argument(
names=args, names=args,
help=u(kwargs.get('help', '')), help=u(kwargs.get('help', '')),
@ -165,9 +166,20 @@ def format_usage_arguments(arguments, base_length=None):
# `--` is automatically transformed into &#8211; (EN DASH) # `--` is automatically transformed into &#8211; (EN DASH)
# when parsing into HTML. We do not need this. # when parsing into HTML. We do not need this.
line[-1] += [nodes.Text(char) for char in name] line[-1] += [nodes.Text(char) for char in name]
elif argument.nargs is REMAINDER:
line.append(nodes.Text('['))
line.append(nodes.strong())
line[-1] += [nodes.Text(char) for char in '--']
line.append(nodes.Text('] '))
if argument.nargs: if argument.nargs:
assert(argument.nargs in (1, '?')) assert(argument.nargs in (1, '?', REMAINDER))
with SurroundWith(line, argument.nargs == '?' and argument.is_option): with SurroundWith(
line, (
True
if argument.nargs is REMAINDER
else (argument.nargs == '?' and argument.is_option)
)
):
if argument.is_long_option: if argument.is_long_option:
line.append(nodes.Text('=')) line.append(nodes.Text('='))
line.append(nodes.emphasis(text=argument.metavar)) line.append(nodes.emphasis(text=argument.metavar))
@ -337,15 +349,21 @@ class AutoManParser(object):
class AutoMan(Directive): class AutoMan(Directive):
required_arguments = 1 required_arguments = 1
optional_arguments = 0 optional_arguments = 0
option_spec = dict(prog=unchanged_required) option_spec = dict(prog=unchanged_required, minimal=bool)
has_content = False has_content = False
def run(self): def run(self):
minimal = self.options.get('minimal')
module = self.arguments[0] module = self.arguments[0]
template_args = {} template_args = {}
template_args.update(get_authors()) template_args.update(get_authors())
get_argparser = __import__(str(module), fromlist=[str('get_argparser')]).get_argparser get_argparser = __import__(str(module), fromlist=[str('get_argparser')]).get_argparser
parser = get_argparser(AutoManParser) parser = get_argparser(AutoManParser)
if minimal:
container = nodes.container()
container += parser.automan_usage(self.options['prog'])
container += parser.automan_description()
return [container]
synopsis_section = nodes.section( synopsis_section = nodes.section(
'', '',
nodes.title(text='Synopsis'), nodes.title(text='Synopsis'),

View File

@ -50,26 +50,35 @@ Add the following to :file:`~/.config/qtile/config.py`:
), ),
] ]
.. _bar-usage: .. _lemonbar-usage:
bar-aint-recursive lemonbar (formerly bar-aint-recursive)
================== ======================================
To run the bar simply pipe the output of the binding script into ``bar`` and To run the bar simply start the binding script:
specify appropriate options, for example like this::
python /path/to/powerline/bindings/bar/powerline-bar.py | bar python /path/to/powerline/bindings/lemonbar/powerline-lemonbar.py
to run with i3, simply ``exec`` this in i3 config file:: You can specify options to be passed to ``lemonbar`` after ``--``, like so:
exec python /path/to/powerline/bindings/bar/powerline-bar.py --i3 | bar python /path/to/powerline/bindings/lemonbar/powerline-lemonbar.py --height 16 -- -f "Source Code Pro for Powerline-9"
to run with i3, simply ``exec`` this in the i3 config file and set the ``--i3`` switch:
exec python /path/to/powerline/bindings/lemonbar/powerline-lemonbar.py --i3
Running the binding in i3-mode will require `i3ipc <https://github.com/acrisci/i3ipc-python>`_ Running the binding in i3-mode will require `i3ipc <https://github.com/acrisci/i3ipc-python>`_
(or the outdated `i3-py <https://github.com/ziberna/i3-py>`_). (or the outdated `i3-py <https://github.com/ziberna/i3-py>`_).
See the `bar documentation <https://github.com/LemonBoy/bar>`_ for more See the `lemonbar documentation <https://github.com/LemonBoy/bar>`_ for more
information and options. information and options.
All ``powerline-lemonbar.py`` arguments:
.. automan:: powerline.commands.lemonbar
:prog: powerline-lemonbar.py
:minimal: true
I3 bar I3 bar
====== ======

View File

@ -2,31 +2,27 @@
# vim:fileencoding=utf-8:noet # vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function) from __future__ import (unicode_literals, division, absolute_import, print_function)
import os
import sys import sys
import time import time
from threading import Lock, Timer from threading import Lock, Timer
from argparse import ArgumentParser from argparse import ArgumentParser
from powerline import Powerline from powerline.lemonbar import LemonbarPowerline
from powerline.lib.encoding import get_unicode_writer from powerline.lib.encoding import get_unicode_writer
class BarPowerline(Powerline):
get_encoding = staticmethod(lambda: 'utf-8')
def init(self):
super(BarPowerline, self).init(ext='wm', renderer_module='bar')
if __name__ == '__main__': if __name__ == '__main__':
parser = ArgumentParser(description='Powerline BAR bindings.') parser = ArgumentParser(description='Powerline lemonbar bindings.')
parser.add_argument( parser.add_argument(
'--i3', action='store_true', '--i3', action='store_true',
help='Subscribe for i3 events.' help='Subscribe for i3 events.'
) )
args = parser.parse_args() args = parser.parse_args()
powerline = BarPowerline() powerline = LemonbarPowerline()
powerline.update_renderer()
powerline.pl.warn("The 'bar' bindings are deprecated, please switch to 'lemonbar'")
lock = Lock() lock = Lock()
modes = ['default'] modes = ['default']
write = get_unicode_writer(encoding='utf-8') write = get_unicode_writer(encoding='utf-8')
@ -60,4 +56,4 @@ if __name__ == '__main__':
conn.main() conn.main()
while True: while True:
time.sleep(1e10) time.sleep(1e8)

View File

@ -0,0 +1,66 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
import time
import re
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
if __name__ == '__main__':
parser = get_argparser()
args = parser.parse_args()
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:
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))
lock = Lock()
modes = ['default']
def render(reschedule=False):
if reschedule:
Timer(args.interval, render, kwargs={'reschedule': True}).start()
global lock
with lock:
for output, process, width in bars:
process.stdin.write(powerline.render(mode=modes[0], width=width, matcher_info=output).encode('utf-8') + b'\n')
process.stdin.flush()
def update(evt):
modes[0] = evt.change
render()
render(reschedule=True)
if args.i3:
try:
import i3ipc
except ImportError:
import i3
i3.Subscription(lambda evt, data, sub: render(), 'workspace')
else:
conn = i3ipc.Connection()
conn.on('workspace::focus', lambda conn, evt: render())
conn.on('mode', lambda conn, evt: update(evt))
conn.main()
while True:
time.sleep(1e8)

View File

@ -0,0 +1,35 @@
# vim:fileencoding=utf-8:noet
# WARNING: using unicode_literals causes errors in argparse
from __future__ import (division, absolute_import, print_function)
import argparse
def get_argparser(ArgumentParser=argparse.ArgumentParser):
parser = ArgumentParser(
description='Powerline BAR bindings.'
)
parser.add_argument(
'--i3', action='store_true',
help='Subscribe for i3 events.'
)
parser.add_argument(
'--height', default='',
metavar='PIXELS', help='Bar height.'
)
parser.add_argument(
'--interval', '-i',
type=float, default=0.5,
metavar='SECONDS', help='Refresh interval.'
)
parser.add_argument(
'--bar-command', '-C',
default='lemonbar',
metavar='CMD', help='Name of the lemonbar executable to use.'
)
parser.add_argument(
'args', nargs=argparse.REMAINDER,
help='Extra arguments for lemonbar. Should be preceded with ``--`` '
'argument in order not to be confused with script own arguments.'
)
return parser

21
powerline/lemonbar.py Normal file
View File

@ -0,0 +1,21 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline import Powerline
from powerline.lib.dict import mergedicts
class LemonbarPowerline(Powerline):
def init(self):
super(LemonbarPowerline, self).init(ext='wm', renderer_module='lemonbar')
get_encoding = staticmethod(lambda: 'utf-8')
def get_local_themes(self, local_themes):
if not local_themes:
return {}
return dict((
(key, {'config': self.load_theme_config(val)})
for key, val in local_themes.items()
))

View File

@ -126,6 +126,12 @@ main_spec = (Spec(
select=ext_theme_spec(), select=ext_theme_spec(),
), ),
).optional(), ).optional(),
wm=ext_spec().update(
local_themes=Spec().unknown_spec(
Spec().re('^[0-9A-Za-z-]+$'),
ext_theme_spec()
).optional()
).optional(),
).unknown_spec( ).unknown_spec(
check_ext, check_ext,
ext_spec(), ext_spec(),

View File

@ -1,45 +0,0 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline.renderer import Renderer
from powerline.colorscheme import ATTR_UNDERLINE
class BarRenderer(Renderer):
'''bar (bar ain't recursive) renderer
See documentation of `bar <https://github.com/LemonBoy/bar>`_ and :ref:`the usage instructions <bar-usage>`
'''
character_translations = Renderer.character_translations.copy()
character_translations[ord('%')] = '%%'
@staticmethod
def hlstyle(*args, **kwargs):
# We dont need to explicitly reset attributes, so skip those calls
return ''
def hl(self, contents, fg=None, bg=None, attrs=None):
text = ''
if fg is not None:
if fg is not False and fg[1] is not False:
text += '%{{F#ff{0:06x}}}'.format(fg[1])
if bg is not None:
if bg is not False and bg[1] is not False:
text += '%{{B#ff{0:06x}}}'.format(bg[1])
if attrs & ATTR_UNDERLINE:
text += '%{+u}'
return text + contents + '%{F-B--u}'
def render(self, *args, **kwargs):
return '%{{l}}{0}%{{r}}{1}'.format(
super(BarRenderer, self).render(side='left', *args, **kwargs),
super(BarRenderer, self).render(side='right', *args, **kwargs),
)
renderer = BarRenderer

View File

@ -0,0 +1,61 @@
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from powerline.renderer import Renderer
from powerline.theme import Theme
from powerline.colorscheme import ATTR_UNDERLINE
class LemonbarRenderer(Renderer):
'''lemonbar (formerly bar/bar ain't recursive) renderer
See documentation of `lemonbar <https://github.com/LemonBoy/bar>`_ and :ref:`the usage instructions <lemonbar-usage>`
'''
character_translations = Renderer.character_translations.copy()
character_translations[ord('%')] = '%%{}'
@staticmethod
def hlstyle(*args, **kwargs):
# We dont need to explicitly reset attributes, so skip those calls
return ''
def hl(self, contents, fg=None, bg=None, attrs=None):
text = ''
if fg is not None:
if fg is not False and fg[1] is not False:
text += '%{{F#ff{0:06x}}}'.format(fg[1])
if bg is not None:
if bg is not False and bg[1] is not False:
text += '%{{B#ff{0:06x}}}'.format(bg[1])
if attrs & ATTR_UNDERLINE:
text += '%{+u}'
return text + contents + '%{F-B--u}'
def render(self, *args, **kwargs):
return '%{{l}}{0}%{{r}}{1}'.format(
super(LemonbarRenderer, self).render(side='left', segment_info={'output': kwargs.get('matcher_info')}, *args, **kwargs),
super(LemonbarRenderer, self).render(side='right', segment_info={'output': kwargs.get('matcher_info')}, *args, **kwargs),
)
def get_theme(self, matcher_info):
if not matcher_info or matcher_info not in self.local_themes:
return self.theme
match = self.local_themes[matcher_info]
try:
return match['theme']
except KeyError:
match['theme'] = Theme(
theme_config=match['config'],
main_theme_config=self.theme_config,
**self.theme_kwargs
)
return match['theme']
renderer = LemonbarRenderer

View File

@ -19,7 +19,8 @@ def calcgrp(w):
return group return group
def workspaces(pl, only_show=None, output=None, strip=0): @requires_segment_info
def workspaces(pl, segment_info, only_show=None, output=None, strip=0):
'''Return list of used workspaces '''Return list of used workspaces
:param list only_show: :param list only_show:
@ -28,7 +29,9 @@ def workspaces(pl, only_show=None, output=None, strip=0):
are shown. are shown.
:param str output: :param str output:
If specified, only workspaces on this output are shown. May be set to the name of an X output. If specified, only workspaces
on that output are shown. Overrides automatic output detection by
the lemonbar renderer and bindings.
:param int strip: :param int strip:
Specifies how many characters from the front of each workspace name Specifies how many characters from the front of each workspace name
@ -45,6 +48,8 @@ def workspaces(pl, only_show=None, output=None, strip=0):
else: else:
conn = i3ipc.Connection() conn = i3ipc.Connection()
output = output or segment_info.get('output')
return [{ return [{
'contents': w['name'][min(len(w['name']), strip):], 'contents': w['name'][min(len(w['name']), strip):],
'highlight_groups': calcgrp(w) 'highlight_groups': calcgrp(w)

View File

@ -18,7 +18,9 @@ exit_suite() {
echo "${FAIL_SUMMARY}" echo "${FAIL_SUMMARY}"
fi fi
export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE%/*}" export POWERLINE_CURRENT_SUITE="${POWERLINE_CURRENT_SUITE%/*}"
if test "x$1" != "x--continue" ; then
exit $FAILED exit $FAILED
fi
} }
fail() { fail() {

201
tests/run_bar_tests.sh Executable file
View File

@ -0,0 +1,201 @@
#!/bin/sh
. tests/common.sh
enter_suite bar
TEST_ROOT="$ROOT/tests/bar"
TEST_PATH="$TEST_ROOT/path"
TEST_STATIC_ROOT="$ROOT/tests/test_bar"
test -d "$TEST_ROOT" && rm -r "$TEST_ROOT"
mkdir "$TEST_ROOT"
cp -r "$TEST_STATIC_ROOT/path" "$TEST_ROOT"
cp -r "$TEST_STATIC_ROOT/powerline" "$TEST_ROOT"
export PYTHONPATH="$ROOT${PYTHONPATH:+:}$PYTHONPATH"
ln -s "$(which "${PYTHON}")" "$TEST_PATH"/python
ln -s "$(which sed)" "$TEST_PATH"
ln -s "$(which cat)" "$TEST_PATH"
ln -s "$(which mkdir)" "$TEST_PATH"
ln -s "$(which basename)" "$TEST_PATH"
ln -s "$TEST_PATH/lemonbar" "$TEST_PATH/bar-aint-recursive"
DEPRECATED_SCRIPT="$ROOT/powerline/bindings/bar/powerline-bar.py"
run() {
env -i \
LANG=C \
PATH="$TEST_PATH" \
XDG_CONFIG_HOME="$TEST_ROOT" \
XDG_CONFIG_DIRS="$TEST_ROOT/dummy" \
PYTHONPATH="$PYTHONPATH" \
TEST_ROOT="$TEST_ROOT" \
LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
"$@" || true
}
display_log() {
local log_file="$1"
echo "$log_file:"
echo '============================================================'
cat -v "$log_file"
echo
echo '____________________________________________________________'
}
check_log() {
local log_file="$1"
local text="$2"
local warns="$3"
if test "$warns" = "warns" ; then
local warning="$(head -n1 "$log_file" | sed 's/.*://')"
local expwarning="The 'bar' bindings are deprecated, please switch to 'lemonbar'"
if test "x$warning" != "x$expwarning" ; then
echo "Got: $warning"
echo "Exp: $expwarning"
fail "warn" F "Expected warning"
fi
sed -r -i -e '1d' "$log_file"
fi
local line="$(head -n1 "$log_file")"
local linenum="$(cat "$log_file" | wc -l)"
if test $linenum -lt 5 ; then
fail "log:lt" F "Script was run not enough times"
return 1
elif test $linenum -gt 15 ; then
fail "log:gt" E "Script was run too many times"
return 1
fi
local expline="%{l}%{F#ffd0d0d0}%{B#ff303030} $text-left %{F-B--u}%{F#ff303030} %{F-B--u}%{r}%{F#ff303030} %{F-B--u}%{F#ffd0d0d0}%{B#ff303030} $text-right %{F-B--u}"
if test "x$expline" != "x$line" ; then
echo "Line: '$line'"
echo "Expected: '$expline'"
fail "log:line" F "Unexpected line"
return 1
fi
local ret=0
while test $linenum -gt 0 ; do
echo "$line" >> "$TEST_ROOT/ok"
linenum=$(( linenum - 1 ))
done
if ! diff "$TEST_ROOT/ok" "$log_file" ; then
fail "log:diff" F "Unexpected output"
ret=1
fi
rm "$TEST_ROOT/ok"
return $ret
}
killscript() {
kill -KILL $1 || true
}
if ! test -e "$DEPRECATED_SCRIPT" ; then
# TODO: uncomment when skip is available
# skip "deprecated" "Missing deprecated bar bindings script"
:
else
enter_suite "deprecated"
run python "$DEPRECATED_SCRIPT" $args > "$TEST_ROOT/deprecated.log" 2>&1 &
SPID=$!
sleep 5
killscript $SPID
if ! check_log "$TEST_ROOT/deprecated.log" "default" warns ; then
display_log "$TEST_ROOT/deprecated.log"
fail "log" F "Checking log failed"
fi
rm "$TEST_ROOT/deprecated.log"
exit_suite --continue
fi
LEMONBAR_SCRIPT="$ROOT/powerline/bindings/lemonbar/powerline-lemonbar.py"
if ! test -e "$LEMONBAR_SCRIPT" ; then
# TODO: uncomment when skip is available
# skip "lemonbar" "Missing lemonbar bindings script"
:
else
enter_suite "lemonbar"
for args in "" "-i0.5" "--interval=0.5" "-- test args" "--bar-command bar-aint-recursive" "--height=10"; do
rm -rf "$TEST_ROOT/results"
run python "$LEMONBAR_SCRIPT" $args > "$TEST_ROOT/lemonbar.log" 2>&1 &
SPID=$!
sleep 5
killscript $SPID
sleep 0.5
enter_suite "args($args)"
fnum=0
for file in "$TEST_ROOT/results"/*.log ; do
if ! test -e "$file" ; then
fail "log" E "Log file is missing"
break
fi
fnum=$(( fnum + 1 ))
args_file="${file%.log}.args"
if ! test -e "$args_file" ; then
fail "args" E "$args_file is missing"
else
cat "$args_file" >> "$TEST_ROOT/args.log"
fi
text="dvi"
if cat "$args_file" | grep -q +1 ; then
text="default"
fi
if ! check_log "$file" "$text" ; then
display_log "$file"
fail "log" F "Checking log failed"
fi
rm "$file"
done
if test "$fnum" -ne 2 ; then
fail "fnum" F "Expected two output files"
fi
if test "x${args#--height}" != "x$args" ; then
height="${args#--height}"
height="${height# }"
height="${height#=}"
height="${height%% *}"
fi
command="lemonbar"
if test "x${args#--bar-command}" != "x$args" ; then
command="${args#--bar-command}"
command="${command# }"
command="${command#=}"
command="${command%% *}"
fi
received_args="$(cat "$TEST_ROOT/args.log" | sort)"
rm "$TEST_ROOT/args.log"
script_args="${args#*-- }"
script_args="${script_args# }"
if test "x${script_args}" '=' "x$args" ; then
script_args=
fi
expected_args="$command -g 1920x$height+0${script_args:+ }$script_args${NL}$command -g 1920x$height+1${script_args:+ }$script_args"
if test "x$expected_args" != "x$received_args" ; then
echo "args:${NL}<$received_args>"
echo "expected:${NL}<$expected_args>"
fail "args" F "Expected different args"
fi
if ! test -z "$(cat "$TEST_ROOT/lemonbar.log")" ; then
display_log "$TEST_ROOT/lemonbar.log"
fail "stderr" E "Unexpected script output"
fi
rm "$TEST_ROOT/lemonbar.log"
exit_suite --continue
done
exit_suite --continue
fi
if ! powerline-lint \
-p "$ROOT/powerline/config_files" \
-p "$TEST_STATIC_ROOT/powerline"
then
fail "lint" F "Checking test config failed"
fi
if test $FAILED -eq 0 ; then
rm -r "$TEST_ROOT"
fi
exit_suite

11
tests/test_bar/path/lemonbar Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
RES_DIR="$TEST_ROOT/results"
mkdir -p "$RES_DIR"
RES_FILE="$RES_DIR/$$"
while test -e "$RES_FILE.log" ; do
RES_FILE="$RES_FILE.${RANDOM:-`date +%N | sed s/^0*//`}"
done
echo $(basename $0) "$@" > "$RES_FILE.args"
cat > "$RES_FILE.log"

31
tests/test_bar/path/xrandr Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
cat << EOF
Screen 0: minimum 8 x 8, current 1920 x 1200, maximum 16384 x 16384
DVI-I-0 disconnected (normal left inverted right x axis y axis)
VGA-0 connected 1920x1200+1+0 (normal left inverted right x axis y axis) 520mm x 330mm
1920x1200 59.95*+
1920x1080 60.00
1680x1050 59.95
1600x1200 60.00
1440x900 59.89
1280x1024 75.02 60.02
1280x800 59.81
1152x864 75.00
1024x768 75.03 60.00
800x600 75.00 60.32
640x480 75.00 59.94
DVI-I-1 connected 1920x1200+0+0 (normal left inverted right x axis y axis) 520mm x 330mm
1920x1200 59.95*+
1920x1080 60.00
1680x1050 59.95
1600x1200 60.00
1440x900 59.89
1280x1024 75.02 60.02
1280x800 59.81
1152x864 75.00
1024x768 75.03 60.00
800x600 75.00 60.32
640x480 75.00 59.94
HDMI-0 disconnected (normal left inverted right x axis y axis)
EOF

View File

@ -0,0 +1,9 @@
{
"ext": {
"wm": {
"local_themes": {
"DVI-I-1": "dvi"
}
}
}
}

View File

@ -0,0 +1,18 @@
{
"segments": {
"left": [
{
"type": "string",
"highlight_groups": ["time"],
"contents": "default-left"
}
],
"right": [
{
"type": "string",
"highlight_groups": ["time"],
"contents": "default-right"
}
]
}
}

View File

@ -0,0 +1,18 @@
{
"segments": {
"left": [
{
"type": "string",
"highlight_groups": ["time"],
"contents": "dvi-left"
}
],
"right": [
{
"type": "string",
"highlight_groups": ["time"],
"contents": "dvi-right"
}
]
}
}

View File

@ -825,28 +825,28 @@ class TestVim(TestCase):
sys.path.pop(0) sys.path.pop(0)
class TestBar(TestRender): class TestLemonbar(TestRender):
def test_bar(self): def test_lemonbar(self):
import powerline as powerline_module import powerline as powerline_module
with swap_attributes(config, powerline_module): with swap_attributes(config, powerline_module):
with get_powerline_raw(config, powerline_module.Powerline, replace_gcp=True, ext='wm', renderer_module='bar') as powerline: with get_powerline_raw(config, powerline_module.Powerline, replace_gcp=True, ext='wm', renderer_module='lemonbar') as powerline:
self.assertRenderEqual( self.assertRenderEqual(
powerline, powerline,
'%{l}%{F#ffc00000}%{B#ff008000}%{+u} A%{F-B--u}%{F#ff008000}%{B#ffc00000}>>%{F-B--u}%{F#ff008000}%{B#ffc00000}B%{F-B--u}%{F#ffc00000}>>%{F-B--u}%{r}%{F#ffc00000}<<%{F-B--u}%{F#ff804000}%{B#ffc00000}%{+u}C%{F-B--u}%{F#ff0000c0}%{B#ffc00000}<<%{F-B--u}%{F#ff008000}%{B#ff0000c0}D %{F-B--u}' '%{l}%{F#ffc00000}%{B#ff008000}%{+u} A%{F-B--u}%{F#ff008000}%{B#ffc00000}>>%{F-B--u}%{F#ff008000}%{B#ffc00000}B%{F-B--u}%{F#ffc00000}>>%{F-B--u}%{r}%{F#ffc00000}<<%{F-B--u}%{F#ff804000}%{B#ffc00000}%{+u}C%{F-B--u}%{F#ff0000c0}%{B#ffc00000}<<%{F-B--u}%{F#ff008000}%{B#ff0000c0}D %{F-B--u}'
) )
@with_new_config @with_new_config
def test_bar_escape(self, config): def test_lemonbar_escape(self, config):
import powerline as powerline_module import powerline as powerline_module
config['themes/wm/default']['segments']['left'] = ( config['themes/wm/default']['segments']['left'] = (
highlighted_string('%{asd}', 'hl1'), highlighted_string('%{asd}', 'hl1'),
highlighted_string('10% %', 'hl2'), highlighted_string('10% %', 'hl2'),
) )
with swap_attributes(config, powerline_module): with swap_attributes(config, powerline_module):
with get_powerline_raw(config, powerline_module.Powerline, replace_gcp=True, ext='wm', renderer_module='bar') as powerline: with get_powerline_raw(config, powerline_module.Powerline, replace_gcp=True, ext='wm', renderer_module='lemonbar') as powerline:
self.assertRenderEqual( self.assertRenderEqual(
powerline, powerline,
'%{l}%{F#ffc00000}%{B#ff008000}%{+u} %%{asd}%{F-B--u}%{F#ff008000}%{B#ffc00000}>>%{F-B--u}%{F#ff008000}%{B#ffc00000}10%% %%%{F-B--u}%{F#ffc00000}>>%{F-B--u}%{r}%{F#ffc00000}<<%{F-B--u}%{F#ff804000}%{B#ffc00000}%{+u}C%{F-B--u}%{F#ff0000c0}%{B#ffc00000}<<%{F-B--u}%{F#ff008000}%{B#ff0000c0}D %{F-B--u}' '%{l}%{F#ffc00000}%{B#ff008000}%{+u} %%{}{asd}%{F-B--u}%{F#ff008000}%{B#ffc00000}>>%{F-B--u}%{F#ff008000}%{B#ffc00000}10%%{} %%{}%{F-B--u}%{F#ffc00000}>>%{F-B--u}%{r}%{F#ffc00000}<<%{F-B--u}%{F#ff804000}%{B#ffc00000}%{+u}C%{F-B--u}%{F#ff0000c0}%{B#ffc00000}<<%{F-B--u}%{F#ff008000}%{B#ff0000c0}D %{F-B--u}'
) )

View File

@ -891,39 +891,48 @@ class TestI3WM(TestCase):
{'name': '3: w3', 'output': 'HDMI1', 'focused': False, 'urgent': True, 'visible': True}, {'name': '3: w3', 'output': 'HDMI1', 'focused': False, 'urgent': True, 'visible': True},
{'name': '4: w4', 'output': 'DVI01', 'focused': True, 'urgent': True, 'visible': True}, {'name': '4: w4', 'output': 'DVI01', 'focused': True, 'urgent': True, 'visible': True},
]))): ]))):
self.assertEqual(i3wm.workspaces(pl=pl), [ segment_info = {}
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info), [
{'contents': '1: w1', 'highlight_groups': ['workspace']}, {'contents': '1: w1', 'highlight_groups': ['workspace']},
{'contents': '2: w2', 'highlight_groups': ['w_visible', 'workspace']}, {'contents': '2: w2', 'highlight_groups': ['w_visible', 'workspace']},
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']}, {'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']}, {'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
]) ])
self.assertEqual(i3wm.workspaces(pl=pl, only_show=None), [ self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=None), [
{'contents': '1: w1', 'highlight_groups': ['workspace']}, {'contents': '1: w1', 'highlight_groups': ['workspace']},
{'contents': '2: w2', 'highlight_groups': ['w_visible', 'workspace']}, {'contents': '2: w2', 'highlight_groups': ['w_visible', 'workspace']},
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']}, {'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']}, {'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
]) ])
self.assertEqual(i3wm.workspaces(pl=pl, only_show=['focused', 'urgent']), [ self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['focused', 'urgent']), [
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']}, {'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']}, {'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
]) ])
self.assertEqual(i3wm.workspaces(pl=pl, only_show=['visible']), [ self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible']), [
{'contents': '2: w2', 'highlight_groups': ['w_visible', 'workspace']}, {'contents': '2: w2', 'highlight_groups': ['w_visible', 'workspace']},
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']}, {'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']}, {'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
]) ])
self.assertEqual(i3wm.workspaces(pl=pl, only_show=['visible'], strip=3), [ self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible'], strip=3), [
{'contents': 'w2', 'highlight_groups': ['w_visible', 'workspace']}, {'contents': 'w2', 'highlight_groups': ['w_visible', 'workspace']},
{'contents': 'w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']}, {'contents': 'w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
{'contents': 'w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']}, {'contents': 'w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
]) ])
self.assertEqual(i3wm.workspaces(pl=pl, only_show=['focused', 'urgent'], output='DVI01'), [ self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['focused', 'urgent'], output='DVI01'), [
{'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']}, {'contents': '4: w4', 'highlight_groups': ['w_focused', 'w_urgent', 'w_visible', 'workspace']},
]) ])
self.assertEqual(i3wm.workspaces(pl=pl, only_show=['visible'], output='HDMI1'), [ self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible'], output='HDMI1'), [
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']}, {'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
]) ])
self.assertEqual(i3wm.workspaces(pl=pl, only_show=['visible'], strip=3, output='LVDS1'), [ self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible'], strip=3, output='LVDS1'), [
{'contents': 'w2', 'highlight_groups': ['w_visible', 'workspace']},
])
segment_info['output'] = 'LVDS1'
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible'], output='HDMI1'), [
{'contents': '3: w3', 'highlight_groups': ['w_urgent', 'w_visible', 'workspace']},
])
self.assertEqual(i3wm.workspaces(pl=pl, segment_info=segment_info, only_show=['visible'], strip=3), [
{'contents': 'w2', 'highlight_groups': ['w_visible', 'workspace']}, {'contents': 'w2', 'highlight_groups': ['w_visible', 'workspace']},
]) ])