1 Commits

Author SHA1 Message Date
7aa759990b playerctl: remove backward/forward/music-note icons
these aren't worth the space cost on narrow devices (moby)
2024-06-19 19:13:07 +00:00
13 changed files with 140 additions and 256 deletions

View File

@@ -215,8 +215,7 @@
<property name="halign">start</property> <property name="halign">start</property>
<property name="label" translatable="yes">&lt;span size="small"&gt;&lt;b&gt;CSS IDs&lt;/b&gt;: <property name="label" translatable="yes">&lt;span size="small"&gt;&lt;b&gt;CSS IDs&lt;/b&gt;:
#hyprland-workspaces, #hyprland-workspaces-item, #hyprland-workspaces, #hyprland-workspaces-item,
#hyprland-workspaces-icon, #hyprland-workspaces-name #hyprland-workspaces-icon, #hyprland-workspaces-name&lt;/span&gt;</property>
#workspace-occupied&lt;/span&gt;</property>
<property name="use-markup">True</property> <property name="use-markup">True</property>
<property name="wrap">True</property> <property name="wrap">True</property>
</object> </object>

View File

@@ -266,8 +266,7 @@
<property name="halign">start</property> <property name="halign">start</property>
<property name="label" translatable="yes">&lt;span size="small"&gt;&lt;b&gt;CSS IDs&lt;/b&gt;: <property name="label" translatable="yes">&lt;span size="small"&gt;&lt;b&gt;CSS IDs&lt;/b&gt;:
#sway-workspaces, #sway-workspaces-item, #sway-workspaces, #sway-workspaces-item,
#sway-workspaces-icon, #sway-workspaces-name #sway-workspaces-icon, #sway-workspaces-name&lt;/span&gt;</property>
#workspace-occupied&lt;/span&gt;</property>
<property name="use-markup">True</property> <property name="use-markup">True</property>
<property name="wrap">True</property> <property name="wrap">True</property>
</object> </object>

View File

@@ -87,6 +87,8 @@ his = os.getenv('HYPRLAND_INSTANCE_SIGNATURE')
if his: if his:
from nwg_panel.modules.hyprland_taskbar import HyprlandTaskbar from nwg_panel.modules.hyprland_taskbar import HyprlandTaskbar
from nwg_panel.modules.hyprland_workspaces import HyprlandWorkspaces from nwg_panel.modules.hyprland_workspaces import HyprlandWorkspaces
last_client_addr = ""
last_client_title = ""
common_settings = {} common_settings = {}
restart_cmd = "" restart_cmd = ""
@@ -152,6 +154,7 @@ def restart():
subprocess.Popen(restart_cmd, shell=True) subprocess.Popen(restart_cmd, shell=True)
# read from Hyprland socket2 on async thread
def hypr_watcher(): def hypr_watcher():
import socket import socket
@@ -162,48 +165,74 @@ def hypr_watcher():
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
client.connect(f"{hypr_dir}/{his}/.socket2.sock") client.connect(f"{hypr_dir}/{his}/.socket2.sock")
just_refreshed = False
global last_client_addr, last_client_title
client_addr, client_title = None, None
while True: while True:
datagram = client.recv(2048) datagram = client.recv(2048)
e_full_string = datagram.decode('utf-8').strip() e_full_string = datagram.decode('utf-8').strip()
lines = e_full_string.splitlines() # eprint("Event: {}".format(e_full_string))
event_names = [] # remember client address & title (string) for further event filtering
for line in lines: if e_full_string.startswith("activewindow"):
event_names.append(line.split(">>")[0]) lines = e_full_string.splitlines()
# print(f"events: {event_names}") for line in lines:
if line.startswith("activewindowv2"):
client_addr = e_full_string.split(">>")[1].strip()
elif line.startswith("activewindow>>"):
client_title = line.split(">>")[1].strip()
for event_name in event_names: event_name = e_full_string.split(">>")[0]
if event_name in ["activespecial",
"activewindow",
"activewindowv2",
"changefloatingmode",
"closewindow",
"createworkspace",
"destroyworkspace",
"focusedmon",
"monitoradded",
"movewindow",
"openwindow",
"windowtitle",
"workspace"]:
if "activewindow" in event_name and just_refreshed: if event_name in ["monitoradded", "openwindow", "movewindow"]:
just_refreshed = False monitors, workspaces, clients, activewindow = h_modules_get_all()
break for item in common.h_taskbars_list:
GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow)
last_client_title = client_title
last_client_addr = client_addr
continue
# print(f">>> refreshing on {event_name}") if event_name == "focusedmon":
monitors, workspaces, clients, activewindow, activeworkspace = h_modules_get_all() monitors, workspaces, clients, activewindow = h_modules_get_all()
for item in common.h_taskbars_list: for item in common.h_workspaces_list:
GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow) GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow)
last_client_title = client_title
last_client_addr = client_addr
continue
for item in common.h_workspaces_list: if event_name == "activewindow" and client_title != last_client_title:
GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow, activeworkspace) monitors, workspaces, clients, activewindow = h_modules_get_all()
for item in common.h_taskbars_list:
GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow)
if event_name in ["createworkspace", "destroyworkspace", "focusedmon", "workspace"]: for item in common.h_workspaces_list:
just_refreshed = True GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow)
break
last_client_title = client_title
continue
if event_name == "activewindowv2" and client_addr != last_client_addr:
monitors, workspaces, clients, activewindow = h_modules_get_all()
for item in common.h_taskbars_list:
GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow)
for item in common.h_workspaces_list:
GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow)
last_client_addr = client_addr
continue
if event_name in ["changefloatingmode", "closewindow"]:
monitors, workspaces, clients, activewindow = h_modules_get_all()
for item in common.h_taskbars_list:
GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow)
for item in common.h_workspaces_list:
GLib.timeout_add(0, item.refresh, monitors, workspaces, clients, activewindow)
last_client_addr = ""
last_client_title = ""
def on_i3ipc_event(i3conn, event): def on_i3ipc_event(i3conn, event):
@@ -238,14 +267,14 @@ def instantiate_content(panel, container, content_list, icons_path=""):
check_key(panel, "position", "top") check_key(panel, "position", "top")
check_key(panel, "items-padding", 0) check_key(panel, "items-padding", 0)
for item in content_list: # list initial data for Hyprland modules
# list initial data for Hyprland modules if his:
if his: if "hyprland-workspaces" in content_list or "hyprland-taskbar" in content_list:
if "hyprland-workspaces" in content_list or "hyprland-taskbar" in content_list: monitors, workspaces, clients, activewindow = h_modules_get_all()
monitors, workspaces, clients, activewindow, activeworkspace = h_modules_get_all() else:
else: monitors, workspaces, clients, activewindow = {}, {}, {}, {}
monitors, workspaces, clients, activewindow, activeworkspace = {}, {}, {}, {}, {}
for item in content_list:
if item == "sway-taskbar": if item == "sway-taskbar":
if "sway-taskbar" in panel: if "sway-taskbar" in panel:
if sway: if sway:
@@ -319,7 +348,7 @@ def instantiate_content(panel, container, content_list, icons_path=""):
if his: if his:
if "hyprland-workspaces" in panel: if "hyprland-workspaces" in panel:
workspaces = HyprlandWorkspaces(panel["hyprland-workspaces"], monitors, workspaces, clients, workspaces = HyprlandWorkspaces(panel["hyprland-workspaces"], monitors, workspaces, clients,
activewindow, activeworkspace, icons_path=icons_path) activewindow, icons_path=icons_path)
container.pack_start(workspaces, False, False, panel["items-padding"]) container.pack_start(workspaces, False, False, panel["items-padding"])
common.h_workspaces_list.append(workspaces) common.h_workspaces_list.append(workspaces)
else: else:
@@ -732,14 +761,12 @@ def main():
left_box.pack_start(ms, False, False, 0) left_box.pack_start(ms, False, False, 0)
instantiate_content(panel, left_box, panel["modules-left"], icons_path=icons_path) instantiate_content(panel, left_box, panel["modules-left"], icons_path=icons_path)
print("left box created")
center_box = Gtk.Box(orientation=o, spacing=panel["spacing"]) center_box = Gtk.Box(orientation=o, spacing=panel["spacing"])
center_box.set_property("name", "center-box") center_box.set_property("name", "center-box")
inner_box.pack_start(center_box, True, False, 0) inner_box.pack_start(center_box, True, False, 0)
check_key(panel, "modules-center", []) check_key(panel, "modules-center", [])
instantiate_content(panel, center_box, panel["modules-center"], icons_path=icons_path) instantiate_content(panel, center_box, panel["modules-center"], icons_path=icons_path)
print("center box created")
right_box = Gtk.Box(orientation=o, spacing=panel["spacing"]) right_box = Gtk.Box(orientation=o, spacing=panel["spacing"])
right_box.set_property("name", "right-box") right_box.set_property("name", "right-box")
@@ -749,7 +776,6 @@ def main():
inner_box.pack_start(helper_box, False, True, 0) inner_box.pack_start(helper_box, False, True, 0)
check_key(panel, "modules-right", []) check_key(panel, "modules-right", [])
instantiate_content(panel, right_box, panel["modules-right"], icons_path=icons_path) instantiate_content(panel, right_box, panel["modules-right"], icons_path=icons_path)
print("right box created")
if panel["menu-start"] == "right": if panel["menu-start"] == "right":
ms = MenuStart(panel["menu-start-settings"], icons_path=icons_path) ms = MenuStart(panel["menu-start-settings"], icons_path=icons_path)
@@ -777,7 +803,6 @@ def main():
window.add(vbox) window.add(vbox)
GtkLayerShell.init_for_window(window) GtkLayerShell.init_for_window(window)
GtkLayerShell.set_namespace(window, f"nwg-panel")
monitor = None monitor = None
try: try:
@@ -853,7 +878,6 @@ def main():
if his: if his:
if len(common.h_taskbars_list) > 0 or len(common.h_workspaces_list) > 0: if len(common.h_taskbars_list) > 0 or len(common.h_workspaces_list) > 0:
print("his: '{}', starting hypr_watcher".format(his)) print("his: '{}', starting hypr_watcher".format(his))
# read from Hyprland socket2 on another thread
thread = threading.Thread(target=hypr_watcher) thread = threading.Thread(target=hypr_watcher)
thread.daemon = True thread.daemon = True
thread.start() thread.start()

View File

@@ -837,8 +837,6 @@ class SinkBox(Gtk.Box):
desc = sink["desc"] desc = sink["desc"]
if len(desc) > 26: if len(desc) > 26:
desc = "{}\u2026".format(desc[:26]) desc = "{}\u2026".format(desc[:26])
if sink["running"]:
desc = f"{desc}"
label = Gtk.Label(desc) label = Gtk.Label(desc)
hbox.pack_start(label, True, True, 0) hbox.pack_start(label, True, True, 0)
eb.add(vbox) eb.add(vbox)

View File

@@ -6,7 +6,7 @@ from nwg_panel.tools import check_key, update_image_fallback_desktop, hyprctl
class HyprlandWorkspaces(Gtk.Box): class HyprlandWorkspaces(Gtk.Box):
def __init__(self, settings, monitors, workspaces, clients, activewindow, activeworkspace, icons_path): def __init__(self, settings, monitors, workspaces, clients, activewindow, icons_path):
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL, spacing=0) Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
self.settings = settings self.settings = settings
self.num_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0) self.num_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0)
@@ -22,7 +22,7 @@ class HyprlandWorkspaces(Gtk.Box):
self.ws_nums = [] self.ws_nums = []
self.build_box() self.build_box()
self.refresh(monitors, workspaces, clients, activewindow, activeworkspace) self.refresh(monitors, workspaces, clients, activewindow)
def build_box(self): def build_box(self):
check_key(self.settings, "num-ws", 10) check_key(self.settings, "num-ws", 10)
@@ -79,8 +79,6 @@ class HyprlandWorkspaces(Gtk.Box):
name = "{} {}".format(num, self.ws_id2name[num]) name = "{} {}".format(num, self.ws_id2name[num])
lbl = Gtk.Label.new("{}".format(name)) if not add_dot else Gtk.Label.new("{}.".format(name)) lbl = Gtk.Label.new("{}".format(name)) if not add_dot else Gtk.Label.new("{}.".format(name))
# if add_dot:
# lbl.set_property("name", "workspace-occupied")
lbl.set_use_markup(True) lbl.set_use_markup(True)
if self.settings["angle"] != 0.0: if self.settings["angle"] != 0.0:
lbl.set_angle(self.settings["angle"]) lbl.set_angle(self.settings["angle"])
@@ -90,7 +88,7 @@ class HyprlandWorkspaces(Gtk.Box):
return eb, lbl return eb, lbl
def refresh(self, monitors, workspaces, clients, activewindow, activeworkspace): def refresh(self, monitors, workspaces, clients, activewindow):
occupied_workspaces = [] occupied_workspaces = []
self.ws_id2name = {} self.ws_id2name = {}
@@ -113,22 +111,21 @@ class HyprlandWorkspaces(Gtk.Box):
client_title = "X|{}".format(client_title) client_title = "X|{}".format(client_title)
floating = activewindow["floating"] floating = activewindow["floating"]
pinned = activewindow["pinned"] pinned = activewindow["pinned"]
active_ws = activewindow["workspace"]["id"]
else: else:
client_class = "" client_class = ""
client_title = "" client_title = ""
floating = False floating = False
pinned = False pinned = False
for m in monitors:
# fix #310 if m["focused"]:
active_ws = activeworkspace["id"] active_ws = m["activeWorkspace"]["id"]
break
for num in self.ws_nums: for num in self.ws_nums:
if num in occupied_workspaces or self.settings["show-empty"]: if num in occupied_workspaces or self.settings["show-empty"]:
occ = num in occupied_workspaces
dot = num in occupied_workspaces and self.settings["show-empty"] and self.settings["mark-content"] dot = num in occupied_workspaces and self.settings["show-empty"] and self.settings["mark-content"]
eb, lbl = self.build_number(num, add_dot=dot, active_win_ws=active_ws) eb, lbl = self.build_number(num, add_dot=dot, active_win_ws=active_ws)
if occ:
lbl.set_property("name", "workspace-occupied")
self.num_box.pack_start(eb, False, False, 0) self.num_box.pack_start(eb, False, False, 0)
self.num_box.show_all() self.num_box.show_all()

View File

@@ -45,57 +45,54 @@ class KeyboardLayout(Gtk.EventBox):
if self.compositor: if self.compositor:
self.keyboards = self.list_keyboards() self.keyboards = self.list_keyboards()
if self.keyboards: self.keyboard_names = []
self.keyboard_names = [] for k in self.keyboards:
for k in self.keyboards: if self.compositor == "Hyprland":
if self.compositor == "Hyprland": self.keyboard_names.append(k["name"])
self.keyboard_names.append(k["name"]) # On sway some devices may be listed twice, let's add them just once
# On sway some devices may be listed twice, let's add them just once elif k.identifier not in self.keyboard_names:
elif k.identifier not in self.keyboard_names: self.keyboard_names.append(k.identifier)
self.keyboard_names.append(k.identifier) # print(f"keyboard_names = {self.keyboard_names}")
self.kb_layouts = self.get_kb_layouts() self.kb_layouts = self.get_kb_layouts()
# print(f"kb_layouts = {self.kb_layouts}")
check_key(settings, "keyboard-device-sway", "") check_key(settings, "keyboard-device-sway", "")
check_key(settings, "keyboard-device-hyprland", "") check_key(settings, "keyboard-device-hyprland", "")
self.device_name = settings["keyboard-device-sway"] if self.compositor == "sway" else settings[ self.device_name = settings["keyboard-device-sway"] if self.compositor == "sway" else settings[
"keyboard-device-hyprland"] "keyboard-device-hyprland"]
check_key(settings, "root-css-name", "root-executor") check_key(settings, "root-css-name", "root-executor")
check_key(settings, "css-name", "") check_key(settings, "css-name", "")
check_key(settings, "icon-placement", "left") check_key(settings, "icon-placement", "left")
check_key(settings, "icon-size", 16) check_key(settings, "icon-size", 16)
check_key(settings, "show-icon", True) check_key(settings, "show-icon", True)
check_key(settings, "tooltip-text", "LMB: Next layout, RMB: Menu") check_key(settings, "tooltip-text", "LMB: Next layout, RMB: Menu")
check_key(settings, "angle", 0.0) check_key(settings, "angle", 0.0)
self.label.set_angle(settings["angle"]) self.label.set_angle(settings["angle"])
if settings["angle"] != 0.0: if settings["angle"] != 0.0:
self.box.set_orientation(Gtk.Orientation.VERTICAL) self.box.set_orientation(Gtk.Orientation.VERTICAL)
update_image(self.image, "input-keyboard", self.settings["icon-size"], self.icons_path) update_image(self.image, "input-keyboard", self.settings["icon-size"], self.icons_path)
self.set_property("name", settings["root-css-name"]) self.set_property("name", settings["root-css-name"])
if settings["css-name"]: if settings["css-name"]:
self.label.set_property("name", settings["css-name"]) self.label.set_property("name", settings["css-name"])
else:
self.label.set_property("name", "executor-label")
if settings["tooltip-text"]:
self.set_tooltip_text(settings["tooltip-text"])
self.connect('button-release-event', self.on_button_release)
self.connect('enter-notify-event', on_enter_notify_event)
self.connect('leave-notify-event', on_leave_notify_event)
self.build_box()
label = self.get_current_layout()
if label:
self.label.set_text(label)
self.show_all()
else: else:
print("KeyboardLayout module: failed listing devices, won't create UI, sorry.") self.label.set_property("name", "executor-label")
if settings["tooltip-text"]:
self.set_tooltip_text(settings["tooltip-text"])
self.connect('button-release-event', self.on_button_release)
self.connect('enter-notify-event', on_enter_notify_event)
self.connect('leave-notify-event', on_leave_notify_event)
self.build_box()
self.refresh()
self.show_all()
def list_keyboards(self): def list_keyboards(self):
if self.compositor == "Hyprland": if self.compositor == "Hyprland":

View File

@@ -211,15 +211,6 @@ class Playerctl(Gtk.EventBox):
if self.settings["angle"] != 0.0: if self.settings["angle"] != 0.0:
button_box.set_orientation(Gtk.Orientation.VERTICAL) button_box.set_orientation(Gtk.Orientation.VERTICAL)
img = Gtk.Image()
update_image(img, "media-skip-backward-symbolic", self.settings["icon-size"], icons_path=self.icons_path)
btn = Gtk.Button()
btn.set_image(img)
if self.settings["button-css-name"]:
btn.set_property("name", self.settings["button-css-name"])
btn.connect("clicked", self.launch, self.PlayerOps.PREVIOUS)
button_box.pack_start(btn, False, False, 1)
self.play_pause_btn = Gtk.Button() self.play_pause_btn = Gtk.Button()
if self.settings["button-css-name"]: if self.settings["button-css-name"]:
self.play_pause_btn.set_property("name", self.settings["button-css-name"]) self.play_pause_btn.set_property("name", self.settings["button-css-name"])
@@ -229,15 +220,6 @@ class Playerctl(Gtk.EventBox):
self.play_pause_btn.connect("clicked", self.launch, self.PlayerOps.PLAY_PAUSE) self.play_pause_btn.connect("clicked", self.launch, self.PlayerOps.PLAY_PAUSE)
button_box.pack_start(self.play_pause_btn, False, False, 1) button_box.pack_start(self.play_pause_btn, False, False, 1)
img = Gtk.Image()
update_image(img, "media-skip-forward-symbolic", self.settings["icon-size"], icons_path=self.icons_path)
btn = Gtk.Button()
btn.set_image(img)
if self.settings["button-css-name"]:
btn.set_property("name", self.settings["button-css-name"])
btn.connect("clicked", self.launch, self.PlayerOps.NEXT)
button_box.pack_start(btn, False, False, 1)
self.num_players_lbl = Gtk.Label.new("") self.num_players_lbl = Gtk.Label.new("")
if self.settings["label-css-name"]: if self.settings["label-css-name"]:
self.num_players_lbl.set_property("name", self.settings["label-css-name"]) self.num_players_lbl.set_property("name", self.settings["label-css-name"])
@@ -257,13 +239,9 @@ class Playerctl(Gtk.EventBox):
self.box.pack_start(button_box, False, False, 2) self.box.pack_start(button_box, False, False, 2)
if self.settings["show-cover"]: if self.settings["show-cover"]:
self.box.pack_start(self.cover_img, False, False, 0) self.box.pack_start(self.cover_img, False, False, 0)
self.box.pack_start(self.num_players_lbl, False, False, 0)
self.box.pack_start(self.label, False, False, 5)
else: else:
if self.settings["show-cover"]: if self.settings["show-cover"]:
self.box.pack_start(self.cover_img, False, False, 2) self.box.pack_start(self.cover_img, False, False, 2)
self.box.pack_start(self.num_players_lbl, False, False, 0)
self.box.pack_start(self.label, False, False, 2)
self.box.pack_start(button_box, False, False, 10) self.box.pack_start(button_box, False, False, 10)
def launch(self, button, op): def launch(self, button, op):

View File

@@ -1,13 +1,10 @@
from gi.repository import Gdk from gi.repository import Gdk
from dasbus.connection import SessionMessageBus from dasbus.connection import SessionMessageBus
from dasbus.specification import DBusSpecificationParser
from dasbus.client.observer import DBusObserver from dasbus.client.observer import DBusObserver
from dasbus.client.proxy import disconnect_proxy from dasbus.client.proxy import disconnect_proxy
from dasbus.error import DBusError from dasbus.error import DBusError
from nwg_panel.tools import load_resource
PROPERTIES = [ PROPERTIES = [
"Id", "Id",
"Category", "Category",
@@ -60,13 +57,6 @@ class StatusNotifierItem(object):
def item_available_handler(self, _observer): def item_available_handler(self, _observer):
self.item_proxy = self.session_bus.get_proxy(self.service_name, self.object_path) 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"): if hasattr(self.item_proxy, "PropertiesChanged"):
self.item_proxy.PropertiesChanged.connect( self.item_proxy.PropertiesChanged.connect(
lambda _if, changed, invalid: self.change_handler(list(changed), invalid) lambda _if, changed, invalid: self.change_handler(list(changed), invalid)
@@ -75,10 +65,6 @@ class StatusNotifierItem(object):
self.item_proxy.NewTitle.connect( self.item_proxy.NewTitle.connect(
lambda: self.change_handler(["Title"]) lambda: self.change_handler(["Title"])
) )
if hasattr(self.item_proxy, 'NewToolTip'):
self.item_proxy.NewToolTip.connect(
lambda: self.change_handler(["ToolTip"])
)
if hasattr(self.item_proxy, 'NewIcon'): if hasattr(self.item_proxy, 'NewIcon'):
self.item_proxy.NewIcon.connect( self.item_proxy.NewIcon.connect(
lambda: self.change_handler(["IconName", "IconPixmap"]) lambda: self.change_handler(["IconName", "IconPixmap"])

View File

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

View File

@@ -171,10 +171,6 @@ class SwayWorkspaces(Gtk.Box):
else: else:
lbl.hide() lbl.hide()
# mark non-empty WS with CSS ID
if int_num in non_empty:
lbl.set_property("name", "workspace-occupied")
# mark non-empty WS with a dot # mark non-empty WS with a dot
if self.settings["mark-content"]: if self.settings["mark-content"]:
if int_num in non_empty: if int_num in non_empty:
@@ -266,13 +262,13 @@ class SwayWorkspaces(Gtk.Box):
for item in tree.descendants(): for item in tree.descendants():
if item.type == "workspace": if item.type == "workspace":
# find non-empty workspaces # find non-empty workspaces
# if self.settings["mark-content"] or self.settings["hide-empty"]: if self.settings["mark-content"] or self.settings["hide-empty"]:
tasks_num = 0 tasks_num = 0
for d in item.descendants(): for d in item.descendants():
if d.type == "con" and d.name: if d.type == "con" and d.name:
tasks_num += 1 tasks_num += 1
if tasks_num > 0: if tasks_num > 0:
non_empty.append(item.num) non_empty.append(item.num)
for node in item.floating_nodes: for node in item.floating_nodes:
if str(node.workspace().num) in self.settings["numbers"]: if str(node.workspace().num) in self.settings["numbers"]:

View File

@@ -358,10 +358,6 @@ def list_outputs(sway=False, tree=None, silent=False):
'transform': transform, 'transform': transform,
'scale': scale, 'scale': scale,
'monitor': None} 'monitor': None}
#Each monitor only have a single transform this avoid parsing multiple times the same monitor
#Disabled monitors don't have transforms.
# Gdk doesn't report disabled monitor, not filtering them would cause crashes
transform = None
else: else:
print("'wlr-randr' command not found, terminating") print("'wlr-randr' command not found, terminating")
sys.exit(1) sys.exit(1)
@@ -375,8 +371,10 @@ def list_outputs(sway=False, tree=None, silent=False):
monitor = display.get_monitor(i) monitor = display.get_monitor(i)
monitors.append(monitor) monitors.append(monitor)
for key, monitor in zip(outputs_dict.keys(), monitors): idx = 0
outputs_dict[key]["monitor"] = monitor for key in outputs_dict:
outputs_dict[key]["monitor"] = monitors[idx]
idx += 1
return outputs_dict return outputs_dict
@@ -536,14 +534,11 @@ def list_sinks():
for line in lines: for line in lines:
details = line.split() details = line.split()
name = details[1][1:-1] name = details[1][1:-1]
desc = " ".join(details[3:])[1:-1] desc = " ".join(details[2:])[1:-1]
sink = {"name": name, "desc": desc, "running": True if "Running" in line else False} sinks.append({"name": name, "desc": desc})
sinks.append(sink)
except Exception as e: except Exception as e:
eprint(e) eprint(e)
if nwg_panel.common.commands["pactl"]:
elif nwg_panel.common.commands["pactl"]:
try: try:
output = cmd2string("pactl list sinks") output = cmd2string("pactl list sinks")
if output: if output:
@@ -560,8 +555,6 @@ def list_sinks():
sink.update({"name": line.split(": ")[1]}) sink.update({"name": line.split(": ")[1]})
elif line.lower().startswith("description"): elif line.lower().startswith("description"):
sink.update({"desc": line.split(": ")[1]}) sink.update({"desc": line.split(": ")[1]})
elif line.lower().startswith("state"):
sink.update({"running": True if "RUNNING" in line else False})
if sink: if sink:
sinks.append(sink) sinks.append(sink)
except Exception as e: except Exception as e:
@@ -793,6 +786,7 @@ def get_cache_dir():
else: else:
return None return None
def file_age(path): def file_age(path):
return time.time() - os.stat(path)[stat.ST_MTIME] return time.time() - os.stat(path)[stat.ST_MTIME]
@@ -891,17 +885,8 @@ def h_get_activewindow():
return {} return {}
def h_get_active_workspace():
reply = hyprctl("j/activeworkspace")
try:
return json.loads(reply)
except Exception as e:
eprint(e)
return {}
def h_modules_get_all(): def h_modules_get_all():
return h_list_monitors(), h_list_workspaces(), h_list_clients(), h_get_activewindow(), h_get_active_workspace() return h_list_monitors(), h_list_workspaces(), h_list_clients(), h_get_activewindow()
def cmd_through_compositor(cmd): def cmd_through_compositor(cmd):
@@ -913,28 +898,3 @@ def cmd_through_compositor(cmd):
elif os.getenv("HYPRLAND_INSTANCE_SIGNATURE"): elif os.getenv("HYPRLAND_INSTANCE_SIGNATURE"):
cmd = f"hyprctl dispatch exec '{cmd}'" cmd = f"hyprctl dispatch exec '{cmd}'"
return 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

View File

@@ -8,13 +8,12 @@ def read(f_name):
setup( setup(
name='nwg-panel', name='nwg-panel',
version='0.9.41', version='0.9.34',
description='GTK3-based panel for sway and Hyprland Wayland compositors', description='GTK3-based panel for sway and Hyprland Wayland compositors',
packages=find_packages(), packages=find_packages(),
include_package_data=True, include_package_data=True,
package_data={ package_data={
"": ["config/*", "icons_dark/*", "icons_light/*", "icons_color/*", "langs/*", "executors/*", "local/*", "": ["config/*", "icons_dark/*", "icons_light/*", "icons_color/*", "langs/*", "executors/*", "local/*"]
"modules/sni_system_tray/org.kde.StatusNotifierItem.xml"]
}, },
url='https://github.com/nwg-piotr/nwg-panel', url='https://github.com/nwg-piotr/nwg-panel',
license='MIT', license='MIT',