An (outdated) collection of plugins for Qtile.
git clone https://github.com/m-col/qtools
Files | Refs | Readme

Commit 5d094c147d5ee0203b5c8a439f896956406d1647
Parent: 8dbf615a323b1de2242c2a6405f3209c4d7bcf5a
Author: mcol <mcol@posteo.net>
Date: 2020-01-11 13:23:26 +0000
Committer: mcol <mcol@posteo.net>
Committed: 2020-01-11 13:23:26 +0000

move package into subfolder within repo

xresources/xresources.py Deleted

@@ -1,54 +0,0 @@
-"""
-Qtile helper to get X resources from the root window.
-"""
-
-
-import xcffib
-import xcffib.xproto
-
-
-def get(DISPLAY, defaults={}):
-    """
-    Get the X resources in an X servers resource manager.
-
-    Parameters
-    ==========
-    DISPLAY : str
-        DISPLAY name to query.
-    
-    defaults : dict (optional)
-        Default values to act as a fallback for missing values or in the event of a
-        failed connection.
-
-    Returns
-    =======
-    resources: dict
-        Dictionary containing all (available) X resources. Resources that are specified
-        in an Xresources/Xdefaults file as wildcards e.g. '*.color1' have the leading
-        '*.' stripped.
-
-    """
-    try:
-        conn = xcffib.connect(display=DISPLAY)
-    except xcffib.ConnectionException:
-        return defaults
-
-    root = conn.get_setup().roots[0].root
-    atom = conn.core.InternAtom(False, 16, 'RESOURCE_MANAGER').reply().atom
-
-    reply = conn.core.GetProperty(
-        False, root, atom,
-        xcffib.xproto.Atom.STRING,
-        0, (2 ** 32) - 1
-    ).reply()
-    conn.disconnect()
-
-    resource_string = reply.value.buf().decode("utf-8")
-    resource_list = filter(None, resource_string.split('\n'))
-    resources = {}
-
-    for resource in resource_list:
-        key, value = resource.split(':\t')
-        resources[key.strip('*.')] = value
-
-    return resources

xresources/__init__.py Deleted

@@ -1 +0,0 @@
-from .xresources import get

qtools/xresources/xresources.py Added

@@ -0,0 +1,54 @@
+"""
+Qtile helper to get X resources from the root window.
+"""
+
+
+import xcffib
+import xcffib.xproto
+
+
+def get(DISPLAY, defaults={}):
+    """
+    Get the X resources in an X servers resource manager.
+
+    Parameters
+    ==========
+    DISPLAY : str
+        DISPLAY name to query.
+    
+    defaults : dict (optional)
+        Default values to act as a fallback for missing values or in the event of a
+        failed connection.
+
+    Returns
+    =======
+    resources: dict
+        Dictionary containing all (available) X resources. Resources that are specified
+        in an Xresources/Xdefaults file as wildcards e.g. '*.color1' have the leading
+        '*.' stripped.
+
+    """
+    try:
+        conn = xcffib.connect(display=DISPLAY)
+    except xcffib.ConnectionException:
+        return defaults
+
+    root = conn.get_setup().roots[0].root
+    atom = conn.core.InternAtom(False, 16, 'RESOURCE_MANAGER').reply().atom
+
+    reply = conn.core.GetProperty(
+        False, root, atom,
+        xcffib.xproto.Atom.STRING,
+        0, (2 ** 32) - 1
+    ).reply()
+    conn.disconnect()
+
+    resource_string = reply.value.buf().decode("utf-8")
+    resource_list = filter(None, resource_string.split('\n'))
+    resources = {}
+
+    for resource in resource_list:
+        key, value = resource.split(':\t')
+        resources[key.strip('*.')] = value
+
+    return resources

qtools/xresources/__init__.py Added

@@ -0,0 +1 @@
+from .xresources import get

qtools/mpc/mpc.py Added

@@ -0,0 +1,83 @@
+"""
+Qtile plugin to control Music Player Daemon using musicpd or mpd2 library
+
+Example usage:
+
+    import qtools.mpc
+    mpc = qtools.mpc.Client()
+    keys.extend([EzKey(k, v) for k, v in {
+        '<XF86AudioPlay>':  mpc.lazy_toggle,
+        '<XF86AudioNext>':  mpc.lazy_next,
+        '<XF86AudioPrev>':  mpc.lazy_previous,
+        '<XF86AudioPlay>':  mpc.lazy_stop,
+    }.items()])
+
+"""
+
+from functools import wraps
+
+try:
+    from musicpd import ConnectionError, MPDClient
+except ImportError:
+    from mpd import ConnectionError, MPDClient
+from qtools import Notifier
+
+
+def _client_func(func):
+    @wraps(func)
+    def _inner(self, qtile):
+        try:
+            self.client.connect()
+        except ConnectionError:
+            pass
+        self.show(func(self))
+        self.client.disconnect()
+    return _inner
+
+
+class Client(Notifier):
+    """
+    The host and port are 127.0.0.1 and 6600 by default but can be set by passing these
+    when initiating the client.
+
+    The notification timeout can be changed by setting Client.timeout to milliseconds
+    (int) or -1, which then uses the notification server's default timeout.
+    """
+    defaults = [
+        ('summary', 'Music', 'Notification summary.'),
+        ('host', '127.0.0.1', 'IP address of MPD server.'),
+        ('port', '6600', 'Port of MPD server.'),
+    ]
+    def __init__(self, **config):
+        Notifier.__init__(self, **config)
+        self.add_defaults(Client.defaults)
+
+        self.client = MPDClient()
+        self.client.host = self.host
+        self.client.port = self.port
+
+    @_client_func
+    def toggle(self):
+        if self.client.status()['state'] == 'play':
+            self.client.pause()
+            return 'Paused'
+        else:
+            self.client.play()
+            return 'Playing'
+
+    @_client_func
+    def next(self):
+        self.client.next()
+        current = self.client.currentsong()
+        return f"{current['artist']} - {current['title']}"
+
+    @_client_func
+    def previous(self):
+        self.client.previous()
+        current = self.client.currentsong()
+        return f"{current['artist']} - {current['title']}"
+
+    @_client_func
+    def stop(self):
+        self.client.stop()
+        return 'Stopped'

qtools/mpc/__init__.py Added

@@ -0,0 +1 @@
+from .mpc import Client

qtools/backlight/backlight.py Added

@@ -0,0 +1,63 @@
+"""
+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
+
+from libqtile.log_utils import logger
+from qtools import Notifier
+
+
+class Backlight(Notifier):
+
+    defaults = [
+        ('summary', 'Backlight', 'Notification summary.'),
+        ('interval', 10, 'Percentage interval by which to change backlight'),
+        (
+            'path',
+            '/sys/class/backlight/nv_backlight/brightness',
+            'Full path to backlight device.'
+        ),
+    ]
+
+    def __init__(self, **config):
+        Notifier.__init__(self, **config)
+        self.add_defaults(Backlight.defaults)
+
+        if not os.path.isfile(self.path):
+            logger.error('Path passed to Backlight plugin is invalid')
+            self.path = '/dev/null'
+
+    @property
+    def brightness(self):
+        with open(self.path, 'r') as f:
+            return int(f.read())
+
+    @brightness.setter
+    def brightness(self, value):
+        if value > 100:
+            value = 100
+        elif value < 0:
+            value = 0
+        elif value % self.interval:
+            value = self.interval * round(value / self.interval)
+
+        with open(self.path, 'w') as f:
+            f.write(str(value))
+        self.show(value)
+
+    def inc_brightness(self, qtile=None):
+        self.brightness += self.interval
+
+    def dec_brightness(self, qtile=None):
+        self.brightness -= self.interval

qtools/backlight/__init__.py Added

@@ -0,0 +1 @@
+from .backlight import Backlight

qtools/amixer/amixer.py Added

@@ -0,0 +1,70 @@
+"""
+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):
+    defaults = [
+        ('summary', 'Volume', 'Notification summary.'),
+        ('mixer', 'Master', 'ALSA mixer to control.'),
+        ('interval', 5, 'Percentage interval to change volume by.'),
+    ]
+    def __init__(self, **config):
+        Notifier.__init__(self, **config)
+        self.add_defaults(Volume.defaults)
+
+    def increase(self, qtile=None):
+        volume = self._run(f'{self.interval}%+')
+        self.show(self.interval * round(volume/self.interval))
+
+    def decrease(self, qtile=None):
+        volume = self._run(f'{self.interval}%-')
+        self.show(self.interval * round(volume/self.interval))
+
+    def toggle(self, qtile=None):
+        volume = self._run('toggle')
+        self.show(self.interval * round(volume/self.interval))
+
+    def mute(self, qtile=None):
+        self._run('mute')
+        self.show('Muted')
+
+    def unmute(self, qtile=None):
+        volume = self._run('unmute')
+        self.show(volume)
+
+    def _run(self, setting):
+        try:
+            output = subprocess.run(
+                ['amixer', 'set', self.mixer, setting],
+                stdout=subprocess.PIPE,
+            )
+            stdout = output.stdout.splitlines()
+        except subprocess.CalledProcessError as err:
+            logger.error(err.output.decode())
+            return
+
+        if len(stdout) == 5:
+            volume = int(stdout[4].decode().split()[3][1:-2])
+        elif len(stdout) == 7:
+            volume = int(stdout[5].decode().split()[4][1:-2])
+        else:
+            logger.warning('Output from amixer needs decoding')
+        return volume

qtools/amixer/__init__.py Added

@@ -0,0 +1 @@
+from .amixer import Volume

qtools/__init__.py Added

@@ -0,0 +1,63 @@
+"""
+Simple base classes that can be used for multiple plugins.
+"""
+
+
+import gi
+gi.require_version('Notify', '0.7')
+from gi.repository import Notify
+
+from libqtile.configurable import Configurable
+from libqtile.command import lazy
+
+
+class Notifier(Configurable):
+    """
+    This is a base class for classes with methods that are to be executed upon key
+    presses and that generate pop-up notifications.
+    """
+    _is_initted = False
+
+    defaults = [
+        ('summary', 'Notifier', 'Notification summary.'),
+        ('timeout', -1, 'Timeout for notifications.'),
+    ]
+
+    def __init__(self, **config):
+        if not Notifier._is_initted:
+            Notifier._is_initted = True
+            Notify.init('Qtile')
+
+        Configurable.__init__(self, **config)
+        self.add_defaults(Notifier.defaults)
+        self.notifier = Notify.Notification.new(
+            config.get('summary', 'Notifier'), ''
+        )
+        self.timeout = config.get('timeout', -1)
+
+    def __getattr__(self, name):
+        """
+        Using this, we can get e.g. Mpc.lazy_toggle which is the equivalent of
+        lazy.function(Mpc.toggle), which is more convenient for setting keybindings.
+        """
+        if name.startswith('lazy_'):
+            return lazy.function(getattr(self, name[5:]))
+        return Configurable.__getattr__(self, name)
+
+    @property
+    def timeout(self):
+        return self._timeout
+
+    @timeout.setter
+    def timeout(self, value):
+        self.notifier.set_timeout(value)
+        self._timeout = value
+
+    def show(self, body):
+        if not isinstance(body, str):
+            body = str(body)
+        self.notifier.update(self.summary, body)
+        self.notifier.show()
+
+    def hide(self):
+        self.notifier.hide()

mpc/mpc.py Deleted

@@ -1,83 +0,0 @@
-"""
-Qtile plugin to control Music Player Daemon using musicpd or mpd2 library
-
-Example usage:
-
-    import qtools.mpc
-    mpc = qtools.mpc.Client()
-    keys.extend([EzKey(k, v) for k, v in {
-        '<XF86AudioPlay>':  mpc.lazy_toggle,
-        '<XF86AudioNext>':  mpc.lazy_next,
-        '<XF86AudioPrev>':  mpc.lazy_previous,
-        '<XF86AudioPlay>':  mpc.lazy_stop,
-    }.items()])
-
-"""
-
-from functools import wraps
-
-try:
-    from musicpd import ConnectionError, MPDClient
-except ImportError:
-    from mpd import ConnectionError, MPDClient
-from qtools import Notifier
-
-
-def _client_func(func):
-    @wraps(func)
-    def _inner(self, qtile):
-        try:
-            self.client.connect()
-        except ConnectionError:
-            pass
-        self.show(func(self))
-        self.client.disconnect()
-    return _inner
-
-
-class Client(Notifier):
-    """
-    The host and port are 127.0.0.1 and 6600 by default but can be set by passing these
-    when initiating the client.
-
-    The notification timeout can be changed by setting Client.timeout to milliseconds
-    (int) or -1, which then uses the notification server's default timeout.
-    """
-    defaults = [
-        ('summary', 'Music', 'Notification summary.'),
-        ('host', '127.0.0.1', 'IP address of MPD server.'),
-        ('port', '6600', 'Port of MPD server.'),
-    ]
-    def __init__(self, **config):
-        Notifier.__init__(self, **config)
-        self.add_defaults(Client.defaults)
-
-        self.client = MPDClient()
-        self.client.host = self.host
-        self.client.port = self.port
-
-    @_client_func
-    def toggle(self):
-        if self.client.status()['state'] == 'play':
-            self.client.pause()
-            return 'Paused'
-        else:
-            self.client.play()
-            return 'Playing'
-
-    @_client_func
-    def next(self):
-        self.client.next()
-        current = self.client.currentsong()
-        return f"{current['artist']} - {current['title']}"
-
-    @_client_func
-    def previous(self):
-        self.client.previous()
-        current = self.client.currentsong()
-        return f"{current['artist']} - {current['title']}"
-
-    @_client_func
-    def stop(self):
-        self.client.stop()
-        return 'Stopped'

mpc/__init__.py Deleted

@@ -1 +0,0 @@
-from .mpc import Client

backlight/backlight.py Deleted

@@ -1,63 +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
-
-from libqtile.log_utils import logger
-from qtools import Notifier
-
-
-class Backlight(Notifier):
-
-    defaults = [
-        ('summary', 'Backlight', 'Notification summary.'),
-        ('interval', 10, 'Percentage interval by which to change backlight'),
-        (
-            'path',
-            '/sys/class/backlight/nv_backlight/brightness',
-            'Full path to backlight device.'
-        ),
-    ]
-
-    def __init__(self, **config):
-        Notifier.__init__(self, **config)
-        self.add_defaults(Backlight.defaults)
-
-        if not os.path.isfile(self.path):
-            logger.error('Path passed to Backlight plugin is invalid')
-            self.path = '/dev/null'
-
-    @property
-    def brightness(self):
-        with open(self.path, 'r') as f:
-            return int(f.read())
-
-    @brightness.setter
-    def brightness(self, value):
-        if value > 100:
-            value = 100
-        elif value < 0:
-            value = 0
-        elif value % self.interval:
-            value = self.interval * round(value / self.interval)
-
-        with open(self.path, 'w') as f:
-            f.write(str(value))
-        self.show(value)
-
-    def inc_brightness(self, qtile=None):
-        self.brightness += self.interval
-
-    def dec_brightness(self, qtile=None):
-        self.brightness -= self.interval

backlight/__init__.py Deleted

@@ -1 +0,0 @@
-from .backlight import Backlight

amixer/amixer.py Deleted

@@ -1,70 +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):
-    defaults = [
-        ('summary', 'Volume', 'Notification summary.'),
-        ('mixer', 'Master', 'ALSA mixer to control.'),
-        ('interval', 5, 'Percentage interval to change volume by.'),
-    ]
-    def __init__(self, **config):
-        Notifier.__init__(self, **config)
-        self.add_defaults(Volume.defaults)
-
-    def increase(self, qtile=None):
-        volume = self._run(f'{self.interval}%+')
-        self.show(self.interval * round(volume/self.interval))
-
-    def decrease(self, qtile=None):
-        volume = self._run(f'{self.interval}%-')
-        self.show(self.interval * round(volume/self.interval))
-
-    def toggle(self, qtile=None):
-        volume = self._run('toggle')
-        self.show(self.interval * round(volume/self.interval))
-
-    def mute(self, qtile=None):
-        self._run('mute')
-        self.show('Muted')
-
-    def unmute(self, qtile=None):
-        volume = self._run('unmute')
-        self.show(volume)
-
-    def _run(self, setting):
-        try:
-            output = subprocess.run(
-                ['amixer', 'set', self.mixer, setting],
-                stdout=subprocess.PIPE,
-            )
-            stdout = output.stdout.splitlines()
-        except subprocess.CalledProcessError as err:
-            logger.error(err.output.decode())
-            return
-
-        if len(stdout) == 5:
-            volume = int(stdout[4].decode().split()[3][1:-2])
-        elif len(stdout) == 7:
-            volume = int(stdout[5].decode().split()[4][1:-2])
-        else:
-            logger.warning('Output from amixer needs decoding')
-        return volume

amixer/__init__.py Deleted

@@ -1 +0,0 @@
-from .amixer import Volume

__init__.py Deleted

@@ -1,63 +0,0 @@
-"""
-Simple base classes that can be used for multiple plugins.
-"""
-
-
-import gi
-gi.require_version('Notify', '0.7')
-from gi.repository import Notify
-
-from libqtile.configurable import Configurable
-from libqtile.command import lazy
-
-
-class Notifier(Configurable):
-    """
-    This is a base class for classes with methods that are to be executed upon key
-    presses and that generate pop-up notifications.
-    """
-    _is_initted = False
-
-    defaults = [
-        ('summary', 'Notifier', 'Notification summary.'),
-        ('timeout', -1, 'Timeout for notifications.'),
-    ]
-
-    def __init__(self, **config):
-        if not Notifier._is_initted:
-            Notifier._is_initted = True
-            Notify.init('Qtile')
-
-        Configurable.__init__(self, **config)
-        self.add_defaults(Notifier.defaults)
-        self.notifier = Notify.Notification.new(
-            config.get('summary', 'Notifier'), ''
-        )
-        self.timeout = config.get('timeout', -1)
-
-    def __getattr__(self, name):
-        """
-        Using this, we can get e.g. Mpc.lazy_toggle which is the equivalent of
-        lazy.function(Mpc.toggle), which is more convenient for setting keybindings.
-        """
-        if name.startswith('lazy_'):
-            return lazy.function(getattr(self, name[5:]))
-        return Configurable.__getattr__(self, name)
-
-    @property
-    def timeout(self):
-        return self._timeout
-
-    @timeout.setter
-    def timeout(self, value):
-        self.notifier.set_timeout(value)
-        self._timeout = value
-
-    def show(self, body):
-        if not isinstance(body, str):
-            body = str(body)
-        self.notifier.update(self.summary, body)
-        self.notifier.show()
-
-    def hide(self):
-        self.notifier.hide()