diff --git a/profiles/desktop/.config/i3/config b/profiles/desktop/.config/i3/config index ec8c9f0..aadb3a9 100644 --- a/profiles/desktop/.config/i3/config +++ b/profiles/desktop/.config/i3/config @@ -187,6 +187,7 @@ workspace $workspace8 output DP-0 workspace $workspace9 output DP-0 for_window [window_role="pop-up"] floating enable +for_window [class="Chromium" window_role="pop-up"] floating disable for_window [class="Tk"] floating enable for_window [title="PyMOL Viewer"] floating enable for_window [class="Toplevel"] floating enable diff --git a/profiles/desktop/.config/polybar/spotify/launchlistener.sh b/profiles/desktop/.config/polybar/spotify/launchlistener.sh new file mode 100755 index 0000000..253f2c8 --- /dev/null +++ b/profiles/desktop/.config/polybar/spotify/launchlistener.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +/usr/bin/env python3 ~/scripts/spotify/py_spotify_listener.py diff --git a/profiles/desktop/.config/polybar/spotify/py_spotify_listener.py b/profiles/desktop/.config/polybar/spotify/py_spotify_listener.py new file mode 100755 index 0000000..cbd4ceb --- /dev/null +++ b/profiles/desktop/.config/polybar/spotify/py_spotify_listener.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +# Unwrap function: (C)2011-2015 Dennis Kaarsemaker +# License: GPL3+ +"""Receiver related functionality.""" +import dbus.service +import dbus.glib +from gi.repository import GObject +import dbus + + +class Test(dbus.service.Object): + """Reciever test class.""" + + loop = None + + def __init__(self, bus_name, object_path, loop): + """Initialize the DBUS service object.""" + dbus.service.Object.__init__(self, bus_name, object_path) + self.loop = loop + + @dbus.service.method('tld.domain.sub.TestInterface') + def foo(self): + """Return a string.""" + return 'Foo' + + # Stop the main loop + @dbus.service.method('tld.domain.sub.TestInterface') + def stop(self): + """Stop the receiver.""" + self.loop.quit() + return 'Quit loop' + + # Pass an exception through dbus + @dbus.service.method('tld.domain.sub.TestInterface') + def fail(self): + """Trigger an exception.""" + raise Exception('FAIL!') + + +def catchall_handler(*args, **kwargs): + """Catch all handler. + Catch and print information about all singals. + """ + print('---- Caught signal ----') + print('%s:%s\n' % (kwargs['dbus_interface'], kwargs['member'])) + + print("\n") + +def quit_handler(): + """Signal handler for quitting the receiver.""" + print('Quitting....') + loop.quit() + +def event_handler(*args, **kwargs): + """event handler for the receiver.""" + """arg[1] contains metadata""" + """arg[1][1] contains PlaybackStatus""" + data = unwrap(args) + if data[1]['PlaybackStatus'] == "Playing": + print("Music is playing") + """ Send IPC hook 2 to the bottom bar pid for module playpause """ + with open("/tmp/ipc-bottom", "w") as text_file: + print("hook:module/playpause2", file=text_file) + if data[1]['PlaybackStatus'] == "Paused": + print("Music is paused.") + """ Send IPC hook 3 to the bottom bar pid for module playpause """ + with open("/tmp/ipc-bottom", "w") as text_file: + print("hook:module/playpause3", file=text_file) + """ Send IPC hook 2 to the bottom bar pid for module spotify """ + with open("/tmp/ipc-bottom", "w") as text_file: + print("hook:module/spotify2", file=text_file) + +def unwrap(val): + if isinstance(val, dbus.ByteArray): + return "".join([str(x) for x in val]) + if isinstance(val, (dbus.Array, list, tuple)): + return [unwrap(x) for x in val] + if isinstance(val, (dbus.Dictionary, dict)): + return dict([(unwrap(x), unwrap(y)) for x, y in val.items()]) + if isinstance(val, (dbus.Signature, dbus.String)): + return str(val) + if isinstance(val, dbus.Boolean): + return bool(val) + if isinstance(val, (dbus.Int16, dbus.UInt16, dbus.Int32, dbus.UInt32, dbus.Int64, dbus.UInt64)): + return int(val) + if isinstance(val, dbus.Byte): + return bytes([int(val)]) + return val + +loop = GObject.MainLoop() + +""" +First we get the bus to attach to. This may be either the session bus, of the +system bus. For system bus root permission is required. +We claim a bus name on the chosen bus. The name should be in form of a +domain name. +""" +bus = dbus.SessionBus() +# bus = dbus.SystemBus() +bus_name = dbus.service.BusName('sub.domain.tld', bus=bus) + +""" +We initialize our service object with our name and object path. Object +path should be in form of a reverse domain dame, delimited by / instead of . +and the Class name as last part. +The object path we set here is of importance for our invoker, since it will to +call it exactly as defined here. +""" +obj = Test(bus_name, '/tld/domain/sub/Test', loop) + + +""" +Attach signal handler. +Signal handlers may be attached in different ways, either by interface keyword +or DBUS interface and a signal name or member keyword. +You can easily gather all information by running the DBUS monitor. +""" +bus.add_signal_receiver(quit_handler, + dbus_interface='tld.domain.sub.event', + signal_name='quit_signal') +bus.add_signal_receiver(event_handler, + dbus_interface='org.freedesktop.DBus.Properties', + member_keyword='PropertiesChanged') + +loop.run() diff --git a/profiles/desktop/.config/polybar/spotify/spotify_status.py b/profiles/desktop/.config/polybar/spotify/spotify_status.py new file mode 100644 index 0000000..4476987 --- /dev/null +++ b/profiles/desktop/.config/polybar/spotify/spotify_status.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +import sys +import dbus +import argparse + + +parser = argparse.ArgumentParser() +parser.add_argument( + '-t', + '--trunclen', + type=int, + metavar='trunclen' +) +parser.add_argument( + '-f', + '--format', + type=str, + metavar='custom format', + dest='custom_format' +) +args = parser.parse_args() + +# Default parameters +output = '{artist}: {song}' +trunclen = 25 + +# parameters can be overwritten by args +if args.trunclen is not None: + trunclen = args.trunclen +if args.custom_format is not None: + output = args.custom_format + +try: + session_bus = dbus.SessionBus() + spotify_bus = session_bus.get_object( + 'org.mpris.MediaPlayer2.spotify', + '/org/mpris/MediaPlayer2' + ) + + spotify_properties = dbus.Interface( + spotify_bus, + 'org.freedesktop.DBus.Properties' + ) + + metadata = spotify_properties.Get('org.mpris.MediaPlayer2.Player', 'Metadata') + + artist = metadata['xesam:artist'][0] + song = metadata['xesam:title'] + + if len(song) > trunclen: + song = song[0:trunclen] + song += '...' + if ('(' in song) and (')' not in song): + song += ')' + + # Python3 uses UTF-8 by default. + if sys.version_info.major == 3: + print(output.format(artist=artist, song=song)) + else: + print(output.format(artist=artist, song=song).encode('UTF-8')) +except Exception as e: + if isinstance(e, dbus.exceptions.DBusException): + print('') + else: + print(e) +