My collection of plugins for the Qtile window manager.
git clone https://mcol.xyz/code/qtools
Log | Files | Refs | README

commit 991f20cc403d29863b530613972cae55cf85f235
parent 9c4c4d72c82d704fee6b3aa0dcd176f5471dd280
Author: mcol <mcol@posteo.net>
Date:   Fri,  4 Sep 2020 22:46:28 +0100

remove amixer, backlight and Popup as they have upstreamed

Diffstat:
Mqtools/__init__.py | 153-------------------------------------------------------------------------------
Dqtools/amixer/__init__.py | 2--
Dqtools/amixer/amixer.py | 107-------------------------------------------------------------------------------
Dqtools/backlight/__init__.py | 2--
Dqtools/backlight/backlight.py | 88-------------------------------------------------------------------------------
5 files changed, 0 insertions(+), 352 deletions(-)

diff --git a/qtools/__init__.py b/qtools/__init__.py @@ -97,156 +97,3 @@ def play_sound(path): playbin.set_state(Gst.State.NULL) else: logger.exception("qtools.play_sound failed with file: {0}".format(path)) - - -ALIGNMENTS = { - 'left': pangocffi.pango.PANGO_ALIGN_LEFT, - 'center': pangocffi.pango.PANGO_ALIGN_CENTER, - 'right': pangocffi.pango.PANGO_ALIGN_RIGHT, -} - - -class Popup(configurable.Configurable): - """ - This base class can be used to create popup windows for a variety of purposes. - """ - defaults = [ - ('opacity', 1.0, 'Opacity of notifications.'), - ('foreground', '#ffffff', 'Color of text.'), - ('background', '#111111', 'Background color.'), - ('border', '#111111', 'Border color.'), - ('border_width', 4, 'Line width of drawn borders.'), - ('corner_radius', None, 'Corner radius for round corners, or None.'), - ('font', 'sans', 'Font used in notifications.'), - ('fontsize', 14, 'Size of font.'), - ('fontshadow', None, 'Color for text shadows, or None for no shadows.'), - ('horizontal_padding', 0, 'Padding at sides of text.'), - ('vertical_padding', 0, 'Padding at top and bottom of text.'), - ('text_alignment', 'left', 'Text alignment: left, center or right.'), - ('wrap', True, 'Whether to wrap text.'), - ] - - def __init__(self, qtile, x=50, y=50, width=256, height=64, **config): - configurable.Configurable.__init__(self, **config) - self.add_defaults(Popup.defaults) - self.qtile = qtile - - win = qtile.conn.create_window(x, y, width, height) - win.set_property("QTILE_INTERNAL", 1) - self.win = window.Internal(win, qtile) - self.win.opacity = self.opacity - self.drawer = Drawer( - self.qtile, self.win.window.wid, width, height, - ) - self.layout = self.drawer.textlayout( - text='', - colour=self.foreground, - font_family=self.font, - font_size=self.fontsize, - font_shadow=self.fontshadow, - wrap=self.wrap, - markup=True, - ) - self.layout.layout.set_alignment(ALIGNMENTS[self.text_alignment]) - - if self.border_width: - self.win.window.configure(borderwidth=self.border_width) - if self.corner_radius: - self.win.window.round_corners( - width, height, self.corner_radius, self.border_width, - ) - - self.win.handle_Expose = self._handle_Expose - self.win.handle_KeyPress = self._handle_KeyPress - self.win.handle_ButtonPress = self._handle_ButtonPress - self.qtile.windows_map[self.win.window.wid] = self.win - - self.x = self.win.x - self.y = self.win.y - if not self.border_width: - self.border = None - - def _handle_Expose(self, e): - pass - - def _handle_KeyPress(self, event): - pass - - def _handle_ButtonPress(self, event): - if event.detail == 1: - self.hide() - - @property - def width(self): - return self.win.width - - @width.setter - def width(self, value): - self.win.width = value - self.drawer.width = value - - @property - def height(self): - return self.win.height - - @height.setter - def height(self, value): - self.win.height = value - self.drawer.height = value - - @property - def text(self): - return self.layout.text - - @text.setter - def text(self, value): - self.layout.text = value - - @property - def foreground(self): - return self._foreground - - @foreground.setter - def foreground(self, value): - self._foreground = value - if hasattr(self, 'layout'): - self.layout.colour = value - - def set_border(self, color): - self.win.window.set_attribute(borderpixel=color) - - def clear(self): - self.drawer.clear(self.background) - - def draw_text(self, x=None, y=None): - self.layout.draw( - x or self.horizontal_padding, - y or self.vertical_padding, - ) - - def draw(self): - self.drawer.draw() - - def place(self): - self.win.place( - self.x, self.y, self.width, self.height, - self.border_width, self.border, above=True - ) - - def unhide(self): - self.win.unhide() - self.win.window.configure(stackmode=StackMode.Above) - - def draw_image(self, image, x, y): - """ - Paint an image onto the window at point x, y. The image should be a surface e.g. - loaded from libqtile.images.Img.load_path. - """ - self.drawer.ctx.set_source_surface(image, x, y) - self.drawer.ctx.paint() - - def hide(self): - self.win.hide() - - def kill(self): - self.win.kill() diff --git a/qtools/amixer/__init__.py b/qtools/amixer/__init__.py @@ -1,2 +0,0 @@ -from .amixer import Volume -__all__ = ('Volume',) diff --git a/qtools/amixer/amixer.py b/qtools/amixer/amixer.py @@ -1,107 +0,0 @@ -""" -Qtile plugin to control an ALSA device volume level. - -Example usage: - - import qtools.amixer - vol = qtools.amixer.Volume() - keys.extend([EzKey(k, v) for k, v in { - '<XF86AudioMute>': vol.lazy_mute, - '<XF86AudioRaiseVolume>': vol.lazy_increase, - '<XF86AudioLowerVolume>': vol.lazy_decrease, - }.items()]) - -""" - - -import subprocess - -from libqtile.log_utils import logger -from qtools import Notifier - - -class Volume(Notifier): - """ - This Notifier can be used to control ALSA mixer volume and muting, sending - notifications when operations are performed. - - The 'mixer' option should be set to the name of the ALSA mixer you use to control - the volume. By default this will also be used for mute/unmute operations. - Alternatively, if you use the Master mixer for muting instead of the mixer used for - volume control, set 'mute_master' to true. - """ - defaults = [ - ('summary', 'Volume', 'Notification summary.'), - ('mixer', 'Master', 'ALSA mixer to control.'), - ('interval', 5, 'Percentage interval to change volume by.'), - ('mute_master', False, 'Use the Master mixer for mute operations'), - ] - - def __init__(self, **config): - Notifier.__init__(self, **config) - self.add_defaults(Volume.defaults) - if self.mute_master and self.mixer == 'Master': - self.mute_master = False - - def increase(self, qtile=None): - stdout = _run(['set', self.mixer, f'{self.interval}%+']) - volume = _get_volume(stdout) - self.show(self.interval * round(volume / self.interval)) - - def decrease(self, qtile=None): - stdout = _run(['set', self.mixer, f'{self.interval}%-']) - volume = _get_volume(stdout) - self.show(self.interval * round(volume / self.interval)) - - def toggle(self, qtile=None): - stdout = _run( - ['set', 'Master' if self.mute_master else self.mixer, 'toggle'] - ) - if _get_mute(stdout): - self.show('Muted') - else: - if self.mute_master: - stdout = _run(['get', self.mixer]) - volume = _get_volume(stdout) - self.show(self.interval * round(volume / self.interval)) - - def mute(self, qtile=None): - _run(['set', 'Master' if self.mute_master else self.mixer, 'mute']) - self.show('Muted') - - def unmute(self, qtile=None): - _run(['set', 'Master' if self.mute_master else self.mixer, 'unmute']) - volume = _get_volume(_run(['get', self.mixer])) - self.show(self.interval * round(volume / self.interval)) - - -def _get_mute(stdout): - if len(stdout) == 5: - if stdout[4].decode().split()[5][1:-1] == 'on': - muted = False - else: - muted = True - else: - muted = False - logger.warning('Output from amixer needs decoding') - return muted - -def _get_volume(stdout): - if (stdlen:=len(stdout)) == 5: - vol = int(stdout[4].decode().split()[3][1:-2]) - elif stdlen == 7: - vol = int(stdout[5].decode().split()[4][1:-2]) - else: - logger.warning('Output from amixer needs decoding') - vol = 0 - return vol - -def _run(args): - cmd = ['amixer'] - cmd.extend(args) - try: - output = subprocess.run(cmd, stdout=subprocess.PIPE, check=False) - except subprocess.CalledProcessError as err: - logger.error(err.output.decode()) - return '' - return output.stdout.splitlines() diff --git a/qtools/backlight/__init__.py b/qtools/backlight/__init__.py @@ -1,2 +0,0 @@ -from .backlight import Backlight -__all__ = ('Backlight',) diff --git a/qtools/backlight/backlight.py b/qtools/backlight/backlight.py @@ -1,88 +0,0 @@ -""" -Qtile plugin to control the screen backlight. - -Example usage: - - import qtools.backlight - backlight = qtools.backlight.Backlight() - keys.extend([EzKey(k, v) for k, v in { - '<XF86MonBrightnessUp>': backlight.lazy_inc_brightness, - '<XF86MonBrightnessDown>': backlight.lazy_dec_brightness, - }.items()]) - -""" - -import os -import time - -from libqtile.log_utils import logger -from qtools import Notifier - - -class Backlight(Notifier): - """ - This class controls screen backlight by directly reading and writing to the - backlight device file in /sys. - """ - defaults = [ - ('summary', 'Backlight', 'Notification summary.'), - ('interval', 10, 'Percentage interval by which to change backlight'), - ('name', '/sys/class/backlight/nv_backlight', 'Full path to backlight device.'), - ('smooth', True, 'Whether to smoothly change brightness level.'), - ('transition', 0.04, 'Step size in seconds when smoothly transitioning'), - ] - - def __init__(self, **config): - Notifier.__init__(self, **config) - self.add_defaults(Backlight.defaults) - - if os.path.isdir(self.name): - self.file = os.path.join(self.name, 'brightness') - with open(os.path.join(self.name, 'max_brightness'), 'r') as f: - self.max = int(f.read()) - - else: - logger.error('Path passed to Backlight plugin is invalid') - self.name = '/dev/null' - self.max = 100 - - self.interval = self.max * self.interval /100 - self.smooth_step = int(self.max / 100) - - def inc_brightness(self, qtile=None): - self.change(1) - - def dec_brightness(self, qtile=None): - self.change(-1) - - def change(self, direction): - start = self.get_brightness() - end = self.check_value(start + self.interval * direction) - self.show(int(100 * end / self.max)) - - if self.smooth: - for i in range( - start + direction, - end + direction, - direction * self.smooth_step, - ): - with open(self.file, 'w') as f: - f.write(str(i)) - time.sleep(self.transition) - logger.warning('brightness') - else: - with open(self.file, 'w') as f: - f.write(str(end)) - - def get_brightness(self): - with open(self.file, 'r') as f: - return int(f.read()) - - def check_value(self, value): - if value > self.max: - value = self.max - elif value < 0: - value = 0 - elif value % self.interval: - value = self.interval * round(value / self.interval) - return int(value)