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

__init__.py (2963B)


      1 """
      2 Simple base classes that can be used for multiple plugins.
      3 """
      4 
      5 
      6 import os
      7 from random import randint
      8 
      9 import gi
     10 gi.require_version('Gst', '1.0')
     11 from gi.repository import Gst
     12 gi.require_version('Notify', '0.7')
     13 from gi.repository import Notify
     14 
     15 from xcffib.xproto import StackMode
     16 from libqtile.drawer import Drawer
     17 from libqtile.lazy import lazy
     18 from libqtile.log_utils import logger
     19 from libqtile import configurable, pangocffi, window
     20 
     21 
     22 class Notifier(configurable.Configurable):
     23     """
     24     This is a base class for classes with methods that are to be executed upon key
     25     presses and that generate pop-up notifications.
     26     """
     27     _is_initted = False
     28 
     29     defaults = [
     30         ('summary', 'Notifier', 'Notification summary.'),
     31         ('timeout', -1, 'Timeout for notifications.'),
     32         ('sound', None, 'Sound to make when sending notification'),
     33     ]
     34 
     35     def __init__(self, **config):
     36         if not Notifier._is_initted:
     37             Notifier._is_initted = True
     38             Notify.init('Qtile')
     39 
     40         configurable.Configurable.__init__(self, **config)
     41         self.add_defaults(Notifier.defaults)
     42         self.notifier = Notify.Notification.new(
     43             config.get('summary', 'Notifier'), ''
     44         )
     45         self.timeout = config.get('timeout', -1)
     46         self.id = randint(10, 1000)
     47 
     48         if self.sound is not None:
     49             self.sound = os.path.expanduser(self.sound)
     50 
     51     def __getattr__(self, name):
     52         """
     53         Using this, we can get e.g. Mpc.lazy_toggle which is the equivalent of
     54         lazy.function(Mpc.toggle), which is more convenient for setting keybindings.
     55         """
     56         if name.startswith('lazy_'):
     57             return lazy.function(getattr(self, name[5:]))
     58         return configurable.Configurable.__getattr__(self, name)
     59 
     60     @property
     61     def timeout(self):
     62         return self._timeout
     63 
     64     @timeout.setter
     65     def timeout(self, value):
     66         self.notifier.set_timeout(value)
     67         self._timeout = value
     68 
     69     def show(self, body):
     70         if not isinstance(body, str):
     71             body = str(body)
     72         self.notifier.update(self.summary, body)
     73         if hasattr(self, 'id'):
     74             self.notifier.set_property('id', self.id)
     75         self.notifier.show()
     76         if self.sound is not None:
     77             play_sound(self.sound)
     78 
     79     def hide(self):
     80         self.notifier.hide()
     81 
     82 
     83 Gst.init(None)
     84 
     85 def play_sound(path):
     86     """
     87     Play an audio file. This accepts a full path to an audio file. This is mostly a
     88     snippet from the playsound library.
     89     """
     90     playbin = Gst.ElementFactory.make('playbin', 'playbin')
     91     playbin.props.uri = 'file://' + path
     92 
     93     set_result = playbin.set_state(Gst.State.PLAYING)
     94     if set_result == Gst.StateChangeReturn.ASYNC:
     95         bus = playbin.get_bus()
     96         bus.poll(Gst.MessageType.EOS, Gst.CLOCK_TIME_NONE)
     97         playbin.set_state(Gst.State.NULL)
     98     else:
     99         logger.exception("qtools.play_sound failed with file: {0}".format(path))