-rw-r--r-- qtools/__init__.py
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)) 100