#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('XApp', '1.0')
from gi.repository import Gio, GLib, GObject, Gtk, XApp
import os
import sys
DBUS_NAME = "org.x.StatusIcon"
DBUS_PATH = "/org/x/StatusIcon"
class StatusWidget(Gtk.Button):
def __init__(self, icon):
super(Gtk.Button, self).__init__()
self.proxy = icon
self.name = self.proxy.get_name()
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.image = Gtk.Image()
self.label = Gtk.Label()
box.pack_start(self.image, False, False, 6)
box.add(self.label)
self.add(box)
flags = GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE
self.image.props.icon_size = Gtk.IconSize.DIALOG
self.set_icon(self.proxy.props.icon_name)
self.proxy.bind_property("label", self.label, "label", flags)
self.proxy.bind_property("tooltip-text", self, "tooltip-text", flags)
self.proxy.bind_property("visible", self, "visible", flags)
self.proxy.connect("notify::icon-name", self.on_icon_name_changed)
self.connect("button-press-event", self.on_button_press)
self.connect("button-release-event", self.on_button_release)
def on_icon_name_changed(self, proxy, gparamspec, data=None):
string = self.proxy.props.icon_name
self.set_icon(string)
def set_icon(self, string):
if string:
if string and os.path.exists(string):
self.image.set_from_file(string)
else:
self.image.set_from_icon_name(string, Gtk.IconSize.DIALOG)
else:
self.image.set_from_icon_name("image-missing", Gtk.IconSize.DIALOG)
def on_button_press(self, widget, event):
# We're simulating a top panel here
alloc = widget.get_allocation()
ignore, x, y = widget.get_window().get_origin()
x += alloc.x
y += alloc.y + alloc.height
time = event.time
print ("Button press : %d:%d" % (x, y))
self.proxy.call_button_press_sync(x, y, event.button, event.time, Gtk.PositionType.TOP, None)
def on_button_release(self, widget, event):
# We're simulating a top panel here
alloc = widget.get_allocation()
ignore, x, y = widget.get_window().get_origin()
x += alloc.x
y += alloc.y + alloc.height
time = event.time
print ("Button release : %d:%d" % (x, y))
self.proxy.call_button_release_sync(x, y, event.button, event.time, Gtk.PositionType.TOP, None)
class StatusApplet(GObject.Object):
def __init__(self):
super(StatusApplet, self).__init__()
self.window = Gtk.Window()
self.window.set_accept_focus (False)
self.window.connect("destroy", self.on_window_destroy)
self.main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
margin=6,
spacing=6)
self.window.add(self.main_box)
self.disco_button = Gtk.Button()
self.main_box.pack_start(self.disco_button, False, False, 0)
self.disco_button.connect("clicked", self.on_disco_button_clicked)
self.indicator_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,
spacing=6)
self.main_box.pack_start(self.indicator_box, False, False, 0)
self.indicators = {}
self.monitor = None
self.setup_monitor()
self.window.show_all()
def on_window_destroy(self, widget, data=None):
self.destroy_monitor()
Gtk.main_quit()
def on_disco_button_clicked(self, widget, data=None):
if self.monitor == None:
self.setup_monitor ()
else:
self.destroy_monitor()
def setup_monitor (self):
self.monitor = XApp.StatusIconMonitor()
self.monitor.connect("icon-added", self.on_icon_added)
self.monitor.connect("icon-removed", self.on_icon_removed)
self.disco_button.set_label("Disconnect monitor")
def destroy_monitor (self):
for key in self.indicators.keys():
self.indicator_box.remove(self.indicators[key])
self.monitor = None
self.indicators = {}
self.disco_button.set_label("Connect monitor")
def on_icon_added(self, monitor, proxy):
name = proxy.get_name()
self.indicators[name] = StatusWidget(proxy)
self.indicator_box.add(self.indicators[name])
self.window.show_all()
self.sort_icons()
def on_icon_removed(self, monitor, proxy):
name = proxy.get_name()
self.indicator_box.remove(self.indicators[name])
del(self.indicators[name])
self.sort_icons()
def sort_icons(self, status_icon=None):
icon_list = list(self.indicators.values())
# for i in icon_list:
# print("before: ", i.proxy.props.icon_name, i.proxy.props.name.lower())
icon_list.sort(key=lambda icon: icon.proxy.props.name.lower())
icon_list.sort(key=lambda icon: icon.proxy.props.icon_name.lower().endswith("symbolic"))
# for i in icon_list:
# print("after: ", i.proxy.props.icon_name, i.proxy.props.name.lower())
icon_list.reverse()
for icon in icon_list:
self.indicator_box.reorder_child(icon, 0)
if __name__ == '__main__':
applet = StatusApplet()
Gtk.main()
sys.exit(0)