1 Commits

Author SHA1 Message Date
a714e4100c playerctl: add settings to control which elements are displayed
the defaults are to keep existing behavior, and display all fields.

new boolean options are added for:
- show-previous     shows "<<" icon to rewind the player
- show-play-pause   shows "||" or "|>" icon to play/pause the player
- show-next         shows ">>" icon to advance the player
- show-name         shows the media name (e.g. the artist + title) and
                    the number of players

these are especially useful for narrow screens, like mobile phones,
where a user may wish to disable all but "show-play-pause" in order to
fit size limitations of the panel.
2024-06-19 20:45:27 +00:00
13 changed files with 156 additions and 241 deletions

View File

@@ -215,8 +215,7 @@
<property name="halign">start</property>
<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-icon, #hyprland-workspaces-name
#workspace-occupied&lt;/span&gt;</property>
#hyprland-workspaces-icon, #hyprland-workspaces-name&lt;/span&gt;</property>
<property name="use-markup">True</property>
<property name="wrap">True</property>
</object>

View File

@@ -266,8 +266,7 @@
<property name="halign">start</property>
<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-icon, #sway-workspaces-name
#workspace-occupied&lt;/span&gt;</property>
#sway-workspaces-icon, #sway-workspaces-name&lt;/span&gt;</property>
<property name="use-markup">True</property>
<property name="wrap">True</property>
</object>

View File

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

View File

@@ -837,8 +837,6 @@ class SinkBox(Gtk.Box):
desc = sink["desc"]
if len(desc) > 26:
desc = "{}\u2026".format(desc[:26])
if sink["running"]:
desc = f"{desc}"
label = Gtk.Label(desc)
hbox.pack_start(label, True, True, 0)
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):
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)
self.settings = settings
self.num_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0)
@@ -22,7 +22,7 @@ class HyprlandWorkspaces(Gtk.Box):
self.ws_nums = []
self.build_box()
self.refresh(monitors, workspaces, clients, activewindow, activeworkspace)
self.refresh(monitors, workspaces, clients, activewindow)
def build_box(self):
check_key(self.settings, "num-ws", 10)
@@ -79,8 +79,6 @@ class HyprlandWorkspaces(Gtk.Box):
name = "{} {}".format(num, self.ws_id2name[num])
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)
if self.settings["angle"] != 0.0:
lbl.set_angle(self.settings["angle"])
@@ -90,7 +88,7 @@ class HyprlandWorkspaces(Gtk.Box):
return eb, lbl
def refresh(self, monitors, workspaces, clients, activewindow, activeworkspace):
def refresh(self, monitors, workspaces, clients, activewindow):
occupied_workspaces = []
self.ws_id2name = {}
@@ -113,22 +111,21 @@ class HyprlandWorkspaces(Gtk.Box):
client_title = "X|{}".format(client_title)
floating = activewindow["floating"]
pinned = activewindow["pinned"]
active_ws = activewindow["workspace"]["id"]
else:
client_class = ""
client_title = ""
floating = False
pinned = False
# fix #310
active_ws = activeworkspace["id"]
for m in monitors:
if m["focused"]:
active_ws = m["activeWorkspace"]["id"]
break
for num in self.ws_nums:
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"]
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.show_all()

View File

@@ -45,57 +45,54 @@ class KeyboardLayout(Gtk.EventBox):
if self.compositor:
self.keyboards = self.list_keyboards()
if self.keyboards:
self.keyboard_names = []
for k in self.keyboards:
if self.compositor == "Hyprland":
self.keyboard_names.append(k["name"])
# On sway some devices may be listed twice, let's add them just once
elif k.identifier not in self.keyboard_names:
self.keyboard_names.append(k.identifier)
self.keyboard_names = []
for k in self.keyboards:
if self.compositor == "Hyprland":
self.keyboard_names.append(k["name"])
# On sway some devices may be listed twice, let's add them just once
elif k.identifier not in self.keyboard_names:
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-hyprland", "")
self.device_name = settings["keyboard-device-sway"] if self.compositor == "sway" else settings[
"keyboard-device-hyprland"]
check_key(settings, "keyboard-device-sway", "")
check_key(settings, "keyboard-device-hyprland", "")
self.device_name = settings["keyboard-device-sway"] if self.compositor == "sway" else settings[
"keyboard-device-hyprland"]
check_key(settings, "root-css-name", "root-executor")
check_key(settings, "css-name", "")
check_key(settings, "icon-placement", "left")
check_key(settings, "icon-size", 16)
check_key(settings, "show-icon", True)
check_key(settings, "tooltip-text", "LMB: Next layout, RMB: Menu")
check_key(settings, "angle", 0.0)
check_key(settings, "root-css-name", "root-executor")
check_key(settings, "css-name", "")
check_key(settings, "icon-placement", "left")
check_key(settings, "icon-size", 16)
check_key(settings, "show-icon", True)
check_key(settings, "tooltip-text", "LMB: Next layout, RMB: Menu")
check_key(settings, "angle", 0.0)
self.label.set_angle(settings["angle"])
self.label.set_angle(settings["angle"])
if settings["angle"] != 0.0:
self.box.set_orientation(Gtk.Orientation.VERTICAL)
if settings["angle"] != 0.0:
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"])
if 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()
self.set_property("name", settings["root-css-name"])
if settings["css-name"]:
self.label.set_property("name", settings["css-name"])
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):
if self.compositor == "Hyprland":

View File

@@ -30,6 +30,10 @@ class Playerctl(Gtk.EventBox):
check_key(settings, "chars", 30)
check_key(settings, "scroll", True)
check_key(settings, "show-cover", True)
check_key(settings, "show-previous", True)
check_key(settings, "show-play-pause", True)
check_key(settings, "show-next", True)
check_key(settings, "show-name", True)
check_key(settings, "cover-size", 24)
check_key(settings, "angle", 0.0)
check_key(settings, "button-css-name", "")
@@ -218,7 +222,8 @@ class Playerctl(Gtk.EventBox):
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)
if self.settings["show-previous"]:
button_box.pack_start(btn, False, False, 1)
self.play_pause_btn = Gtk.Button()
if self.settings["button-css-name"]:
@@ -227,7 +232,8 @@ class Playerctl(Gtk.EventBox):
update_image(img, "media-playback-start-symbolic", self.settings["icon-size"], icons_path=self.icons_path)
self.play_pause_btn.set_image(img)
self.play_pause_btn.connect("clicked", self.launch, self.PlayerOps.PLAY_PAUSE)
button_box.pack_start(self.play_pause_btn, False, False, 1)
if self.settings["show-play-pause"]:
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)
@@ -236,7 +242,8 @@ class Playerctl(Gtk.EventBox):
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)
if self.settings["show-next"]:
button_box.pack_start(btn, False, False, 1)
self.num_players_lbl = Gtk.Label.new("")
if self.settings["label-css-name"]:
@@ -257,13 +264,15 @@ class Playerctl(Gtk.EventBox):
self.box.pack_start(button_box, False, False, 2)
if self.settings["show-cover"]:
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)
if self.settings["show-name"]:
self.box.pack_start(self.num_players_lbl, False, False, 0)
self.box.pack_start(self.label, False, False, 5)
else:
if self.settings["show-cover"]:
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)
if self.settings["show-name"]:
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)
def launch(self, button, op):

View File

@@ -1,13 +1,10 @@
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",
@@ -60,13 +57,6 @@ 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)
@@ -75,10 +65,6 @@ class StatusNotifierItem(object):
self.item_proxy.NewTitle.connect(
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'):
self.item_proxy.NewIcon.connect(
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):
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
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 or "ToolTip" in item.properties:
if "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 or "ToolTip" in changed_properties:
if "Tooltip" in changed_properties:
update_tooltip(image, item)
elif "Title" in changed_properties:
image.set_tooltip_markup(item.properties["Title"])

View File

@@ -171,10 +171,6 @@ class SwayWorkspaces(Gtk.Box):
else:
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
if self.settings["mark-content"]:
if int_num in non_empty:
@@ -266,13 +262,13 @@ class SwayWorkspaces(Gtk.Box):
for item in tree.descendants():
if item.type == "workspace":
# find non-empty workspaces
# if self.settings["mark-content"] or self.settings["hide-empty"]:
tasks_num = 0
for d in item.descendants():
if d.type == "con" and d.name:
tasks_num += 1
if tasks_num > 0:
non_empty.append(item.num)
if self.settings["mark-content"] or self.settings["hide-empty"]:
tasks_num = 0
for d in item.descendants():
if d.type == "con" and d.name:
tasks_num += 1
if tasks_num > 0:
non_empty.append(item.num)
for node in item.floating_nodes:
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,
'scale': scale,
'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:
print("'wlr-randr' command not found, terminating")
sys.exit(1)
@@ -375,8 +371,10 @@ def list_outputs(sway=False, tree=None, silent=False):
monitor = display.get_monitor(i)
monitors.append(monitor)
for key, monitor in zip(outputs_dict.keys(), monitors):
outputs_dict[key]["monitor"] = monitor
idx = 0
for key in outputs_dict:
outputs_dict[key]["monitor"] = monitors[idx]
idx += 1
return outputs_dict
@@ -536,14 +534,11 @@ def list_sinks():
for line in lines:
details = line.split()
name = details[1][1:-1]
desc = " ".join(details[3:])[1:-1]
sink = {"name": name, "desc": desc, "running": True if "Running" in line else False}
sinks.append(sink)
desc = " ".join(details[2:])[1:-1]
sinks.append({"name": name, "desc": desc})
except Exception as e:
eprint(e)
elif nwg_panel.common.commands["pactl"]:
if nwg_panel.common.commands["pactl"]:
try:
output = cmd2string("pactl list sinks")
if output:
@@ -560,8 +555,6 @@ def list_sinks():
sink.update({"name": line.split(": ")[1]})
elif line.lower().startswith("description"):
sink.update({"desc": line.split(": ")[1]})
elif line.lower().startswith("state"):
sink.update({"running": True if "RUNNING" in line else False})
if sink:
sinks.append(sink)
except Exception as e:
@@ -793,6 +786,7 @@ def get_cache_dir():
else:
return None
def file_age(path):
return time.time() - os.stat(path)[stat.ST_MTIME]
@@ -891,17 +885,8 @@ def h_get_activewindow():
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():
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):
@@ -913,28 +898,3 @@ 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

View File

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