Merge pull request #317 from progandy/fix/sni-without-introspection

fix tray icons for electron (#224)
This commit is contained in:
Piotr Miller
2024-08-25 16:19:23 +02:00
committed by GitHub
4 changed files with 87 additions and 4 deletions

View File

@@ -1,10 +1,13 @@
from gi.repository import Gdk
from dasbus.connection import SessionMessageBus
from dasbus.specification import DBusSpecificationParser
from dasbus.client.observer import DBusObserver
from dasbus.client.proxy import disconnect_proxy
from dasbus.error import DBusError
from nwg_panel.tools import load_resource
PROPERTIES = [
"Id",
"Category",
@@ -57,6 +60,13 @@ class StatusNotifierItem(object):
def item_available_handler(self, _observer):
self.item_proxy = self.session_bus.get_proxy(self.service_name, self.object_path)
try:
spec = self.item_proxy._handler.specification
if spec is not None:
if not any("StatusNotifierItem" in ifname for ifname in spec.interfaces):
DBusSpecificationParser._parse_xml(spec, load_resource(__package__,"org.kde.StatusNotifierItem.xml"))
except:
pass
if hasattr(self.item_proxy, "PropertiesChanged"):
self.item_proxy.PropertiesChanged.connect(
lambda _if, changed, invalid: self.change_handler(list(changed), invalid)

View File

@@ -0,0 +1,49 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name='org.kde.StatusNotifierItem'>
<annotation name="org.gtk.GDBus.C.Name" value="Item" />
<method name='ContextMenu'>
<arg type='i' direction='in' name='x'/>
<arg type='i' direction='in' name='y'/>
</method>
<method name='Activate'>
<arg type='i' direction='in' name='x'/>
<arg type='i' direction='in' name='y'/>
</method>
<method name='SecondaryActivate'>
<arg type='i' direction='in' name='x'/>
<arg type='i' direction='in' name='y'/>
</method>
<method name='Scroll'>
<arg type='i' direction='in' name='delta'/>
<arg type='s' direction='in' name='orientation'/>
</method>
<signal name='NewTitle'/>
<signal name='NewIcon'/>
<signal name='NewAttentionIcon'/>
<signal name='NewOverlayIcon'/>
<signal name='NewToolTip'/>
<signal name='NewStatus'>
<arg type='s' name='status'/>
</signal>
<property name='Category' type='s' access='read'/>
<property name='Id' type='s' access='read'/>
<property name='Title' type='s' access='read'/>
<property name='Status' type='s' access='read'/>
<!-- See discussion on pull #536
<property name='WindowId' type='u' access='read'/>
-->
<property name='IconThemePath' type='s' access='read'/>
<property name='IconName' type='s' access='read'/>
<property name='IconPixmap' type='a(iiay)' access='read'/>
<property name='OverlayIconName' type='s' access='read'/>
<property name='OverlayIconPixmap' type='a(iiay)' access='read'/>
<property name='AttentionIconName' type='s' access='read'/>
<property name='AttentionIconPixmap' type='a(iiay)' access='read'/>
<property name='AttentionMovieName' type='s' access='read'/>
<property name='ToolTip' type='(sa(iiay)ss)' access='read'/>
<property name='Menu' type='o' access='read'/>
<property name='ItemIsMenu' type='b' access='read'/>
</interface>
</node>

View File

@@ -76,7 +76,7 @@ def update_icon_from_pixmap(image, item, icon_size):
def update_tooltip(image, item):
icon_name, icon_data, title, description = item.properties["Tooltip"]
icon_name, icon_data, title, description = item.properties["ToolTip"] if "ToolTip" in item.properties else item.properties["Tooltip"]
tooltip = title
if description:
tooltip = "<b>{}</b>\n{}".format(title, description)
@@ -131,7 +131,7 @@ class Tray(Gtk.EventBox):
elif "IconPixmap" in item.properties and len(item.properties["IconPixmap"]) != 0:
update_icon_from_pixmap(image, item, self.icon_size)
if "Tooltip" in item.properties:
if "Tooltip" in item.properties or "ToolTip" in item.properties:
update_tooltip(image, item)
elif "Title" in item.properties:
image.set_tooltip_markup(item.properties["Title"])
@@ -168,7 +168,7 @@ class Tray(Gtk.EventBox):
update_icon_from_pixmap(image, item, self.icon_size)
pass
if "Tooltip" in changed_properties:
if "Tooltip" in changed_properties or "ToolTip" in changed_properties:
update_tooltip(image, item)
elif "Title" in changed_properties:
image.set_tooltip_markup(item.properties["Title"])

View File

@@ -788,7 +788,6 @@ def get_cache_dir():
else:
return None
def file_age(path):
return time.time() - os.stat(path)[stat.ST_MTIME]
@@ -909,3 +908,28 @@ def cmd_through_compositor(cmd):
elif os.getenv("HYPRLAND_INSTANCE_SIGNATURE"):
cmd = f"hyprctl dispatch exec '{cmd}'"
return cmd
def load_resource(package, resource_name):
try:
import importlib.resources as resources
with resources.open_binary(package, resource_name) as resource_file:
return resource_file.read()
except:
pass
try:
import importlib.util
spec = importlib.util.find_spec(package)
if spec is not None and spec.loader is not None and hasattr(spec.loader, 'get_data'):
return spec.loader.get_data(resource_name)
except Exception:
pass
try:
import pkgutil
data = pkgutil.get_data(package, resource_name)
if data is None:
raise FileNotFoundError(f"Resource {resource_name} not found in package {package}.")
return data
except ImportError as e:
raise ImportError("Failed to load the resource using any available method.") from e