♻️ refactor(launcher): improve code structure and plugin functionality
This commit is contained in:
1 parent
4822693298
commit
5495233667
31 files changed
+536
-618
No files matched your search
@@ -52,10 +52,10 @@ def patched_do_update_properties(self, *_):
|
||||
def _try_load_icon_from_path(self, icon_path):
|
||||
try:
|
||||
# Check if it's a file path and handle it directly
|
||||
if os.path.isabs(icon_path) or '/' in icon_path:
|
||||
if os.path.isabs(icon_path) or "/" in icon_path:
|
||||
# Try to load as SVG from the original path if it exists
|
||||
if os.path.exists(icon_path):
|
||||
if icon_path.lower().endswith('.svg'):
|
||||
if icon_path.lower().endswith(".svg"):
|
||||
# Load SVG directly
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
|
||||
icon_path, self._icon_size, self._icon_size
|
||||
@@ -80,11 +80,13 @@ def _try_load_icon_from_path(self, icon_path):
|
||||
# Remove extension for theme lookup
|
||||
name_without_ext = os.path.splitext(filename)[0]
|
||||
default_theme = Gtk.IconTheme.get_default()
|
||||
|
||||
|
||||
# Try filename without extension
|
||||
if default_theme.has_icon(name_without_ext):
|
||||
pixbuf = default_theme.load_icon(
|
||||
name_without_ext, self._icon_size, Gtk.IconLookupFlags.FORCE_SIZE
|
||||
name_without_ext,
|
||||
self._icon_size,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE,
|
||||
)
|
||||
if pixbuf:
|
||||
self._image.set_from_pixbuf(pixbuf)
|
||||
@@ -109,9 +111,9 @@ def _try_load_icon_from_path(self, icon_path):
|
||||
"/usr/local/share/icons",
|
||||
"/usr/local/share/pixmaps",
|
||||
os.path.expanduser("~/.local/share/icons"),
|
||||
os.path.expanduser("~/.icons")
|
||||
os.path.expanduser("~/.icons"),
|
||||
]
|
||||
|
||||
|
||||
filename = os.path.basename(icon_path)
|
||||
for icon_dir in common_icon_dirs:
|
||||
potential_path = os.path.join(icon_dir, filename)
|
||||
@@ -129,7 +131,7 @@ def _try_load_icon_from_path(self, icon_path):
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@@ -146,11 +148,11 @@ def apply_enhanced_system_tray():
|
||||
# Store original method
|
||||
global original_do_update_properties
|
||||
original_do_update_properties = SystemTrayItem.do_update_properties
|
||||
|
||||
|
||||
# Attach helper methods to SystemTrayItem class
|
||||
SystemTrayItem._try_load_icon_from_path = _try_load_icon_from_path
|
||||
SystemTrayItem._set_tooltip = _set_tooltip
|
||||
|
||||
|
||||
# Replace the do_update_properties method
|
||||
SystemTrayItem.do_update_properties = patched_do_update_properties
|
||||
|
||||
|
||||
@@ -54,26 +54,36 @@ class WifiIndicator(Button):
|
||||
self.network.ethernet_device
|
||||
and self.network.ethernet_device.state == "activated"
|
||||
):
|
||||
self.wifi_icon.set_from_file(get_relative_path("../../../config/assets/icons/wifi.svg"))
|
||||
self.wifi_icon.set_from_file(
|
||||
get_relative_path("../../../config/assets/icons/wifi.svg")
|
||||
)
|
||||
tooltip = f"Connected to Ethernet ({self.network.ethernet_device.speed})"
|
||||
self.set_tooltip_text(tooltip)
|
||||
return
|
||||
|
||||
if not self.network.wifi_device:
|
||||
self.wifi_icon.set_from_file(get_relative_path("../../../config/assets/icons/wifi-off.svg"))
|
||||
self.wifi_icon.set_from_file(
|
||||
get_relative_path("../../../config/assets/icons/wifi-off.svg")
|
||||
)
|
||||
tooltip = "No WiFi device found"
|
||||
elif not self.network.wifi_device.wireless_enabled:
|
||||
self.wifi_icon.set_from_file(get_relative_path("../../../config/assets/icons/wifi-off.svg"))
|
||||
self.wifi_icon.set_from_file(
|
||||
get_relative_path("../../../config/assets/icons/wifi-off.svg")
|
||||
)
|
||||
tooltip = "WiFi disabled"
|
||||
else:
|
||||
active_ap = self.network.wifi_device.active_access_point
|
||||
if active_ap:
|
||||
strength = active_ap.strength
|
||||
# Use wifi.svg for all connected states since we don't have signal strength icons
|
||||
self.wifi_icon.set_from_file(get_relative_path("../../../config/assets/icons/wifi.svg"))
|
||||
self.wifi_icon.set_from_file(
|
||||
get_relative_path("../../../config/assets/icons/wifi.svg")
|
||||
)
|
||||
tooltip = f"Connected to {active_ap.ssid} ({strength}%)"
|
||||
else:
|
||||
self.wifi_icon.set_from_file(get_relative_path("../../../config/assets/icons/wifi-off.svg"))
|
||||
self.wifi_icon.set_from_file(
|
||||
get_relative_path("../../../config/assets/icons/wifi-off.svg")
|
||||
)
|
||||
tooltip = "Not connected"
|
||||
|
||||
self.set_tooltip_text(tooltip)
|
||||
@@ -127,12 +137,16 @@ class BluetoothIndicator(Button):
|
||||
|
||||
def update_state(self):
|
||||
if not self.bluetooth.enabled:
|
||||
self.bt_icon.set_from_file(get_relative_path("../../../config/assets/icons/bluetooth-off.svg"))
|
||||
self.bt_icon.set_from_file(
|
||||
get_relative_path("../../../config/assets/icons/bluetooth-off.svg")
|
||||
)
|
||||
tooltip = "Bluetooth disabled"
|
||||
else:
|
||||
connected_devices = self.bluetooth.connected_devices
|
||||
if connected_devices:
|
||||
self.bt_icon.set_from_file(get_relative_path("../../../config/assets/icons/bluetooth.svg"))
|
||||
self.bt_icon.set_from_file(
|
||||
get_relative_path("../../../config/assets/icons/bluetooth.svg")
|
||||
)
|
||||
if len(connected_devices) == 1:
|
||||
device = connected_devices[0]
|
||||
tooltip = f"Connected to {device.alias}"
|
||||
@@ -141,7 +155,9 @@ class BluetoothIndicator(Button):
|
||||
else:
|
||||
tooltip = f"Connected to {len(connected_devices)} devices"
|
||||
else:
|
||||
self.bt_icon.set_from_file(get_relative_path("../../../config/assets/icons/bluetooth.svg"))
|
||||
self.bt_icon.set_from_file(
|
||||
get_relative_path("../../../config/assets/icons/bluetooth.svg")
|
||||
)
|
||||
tooltip = "No devices connected"
|
||||
|
||||
self.set_tooltip_text(tooltip)
|
||||
@@ -155,11 +171,10 @@ class BluetoothIndicator(Button):
|
||||
def on_device_removed(self, _, address):
|
||||
self.update_state()
|
||||
|
||||
|
||||
class Battery(Box):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(
|
||||
orientation="v", visible=True, **kwargs
|
||||
)
|
||||
super().__init__(orientation="v", visible=True, **kwargs)
|
||||
|
||||
self._battery = BatteryService()
|
||||
self._battery.changed.connect(self.update_battery)
|
||||
@@ -167,7 +182,9 @@ class Battery(Box):
|
||||
self.icon = Svg(
|
||||
name="indicators-icon",
|
||||
size=24,
|
||||
svg_file=get_relative_path("../../../config/assets/icons/battery/battery-100.svg"),
|
||||
svg_file=get_relative_path(
|
||||
"../../../config/assets/icons/battery/battery-100.svg"
|
||||
),
|
||||
)
|
||||
self.battery_button = Button(
|
||||
child=self.icon,
|
||||
@@ -259,21 +276,29 @@ class Battery(Box):
|
||||
self.icon.remove_style_class("alert")
|
||||
|
||||
if state == "FULLY_CHARGED" or (percentage >= 100 and state == "CHARGING"):
|
||||
self.icon.set_from_file(get_relative_path("../../../config/assets/icons/battery/battery-100-charging.svg"))
|
||||
self.icon.set_from_file(
|
||||
get_relative_path(
|
||||
"../../../config/assets/icons/battery/battery-100-charging.svg"
|
||||
)
|
||||
)
|
||||
elif state == "CHARGING":
|
||||
# Calculate battery level and use corresponding charging icon
|
||||
level = min(100, max(0, int(percentage // 10) * 10))
|
||||
if level == 0 and percentage > 0:
|
||||
level = 10
|
||||
icon_name = f"battery-{level:03d}-charging.svg"
|
||||
self.icon.set_from_file(get_relative_path(f"../../../config/assets/icons/battery/{icon_name}"))
|
||||
self.icon.set_from_file(
|
||||
get_relative_path(f"../../../config/assets/icons/battery/{icon_name}")
|
||||
)
|
||||
else:
|
||||
# Calculate battery level and use corresponding icon
|
||||
level = min(100, max(0, int(percentage // 10) * 10))
|
||||
if level == 0 and percentage > 0:
|
||||
level = 10
|
||||
icon_name = f"battery-{level:03d}.svg"
|
||||
self.icon.set_from_file(get_relative_path(f"../../../config/assets/icons/battery/{icon_name}"))
|
||||
self.icon.set_from_file(
|
||||
get_relative_path(f"../../../config/assets/icons/battery/{icon_name}")
|
||||
)
|
||||
|
||||
self.set_visible(True)
|
||||
return True
|
||||
|
||||
@@ -8,10 +8,10 @@ from fabric.utils import exec_shell_command
|
||||
|
||||
|
||||
class MenuActionHandler:
|
||||
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
def execute_action(self, action):
|
||||
try:
|
||||
# Window menu actions
|
||||
@@ -34,16 +34,13 @@ class MenuActionHandler:
|
||||
elif action == "Quit":
|
||||
Hyprland.send_command("dispatch killactive")
|
||||
|
||||
|
||||
# Go menu actions
|
||||
elif action == "Back":
|
||||
Hyprland.send_command("dispatch workspace e-1")
|
||||
elif action == "Forward":
|
||||
Hyprland.send_command("dispatch workspace e+1")
|
||||
|
||||
|
||||
# Edit menu actions
|
||||
|
||||
|
||||
# View menu actions
|
||||
elif action == "Full Screen":
|
||||
@@ -63,7 +60,7 @@ class MenuActionHandler:
|
||||
elif action == "Report a Bug...":
|
||||
exec_shell_command("xdg-open https://github.com/S4NKALP/Modus/issues")
|
||||
|
||||
# System menu actions
|
||||
# System menu actions
|
||||
elif action == "About This PC":
|
||||
exec_shell_command("gnome-system-monitor")
|
||||
elif action == "Force Quit":
|
||||
@@ -77,13 +74,14 @@ class MenuActionHandler:
|
||||
elif action == "Lock":
|
||||
exec_shell_command("hyprlock")
|
||||
|
||||
|
||||
# App menu actions (for hiding apps)
|
||||
elif action.startswith("Hide ") and not action == "Hide Others":
|
||||
action.replace("Hide ", "")
|
||||
Hyprland.send_command("dispatch movetoworkspacesilent special:hidden")
|
||||
elif action == "Hide Others":
|
||||
Hyprland.send_command("dispatch movetoworkspacesilent special:hidden,^(activewindow)")
|
||||
Hyprland.send_command(
|
||||
"dispatch movetoworkspacesilent special:hidden,^(activewindow)"
|
||||
)
|
||||
elif action == "Show All":
|
||||
Hyprland.send_command("dispatch movetoworkspace e+0,special:hidden")
|
||||
elif action.startswith("Quit "):
|
||||
|
||||
@@ -6,19 +6,10 @@ This file contains all the menu items and their organization.
|
||||
|
||||
def get_default_menu_contents():
|
||||
return {
|
||||
"Hyprland": [
|
||||
],
|
||||
"File": [
|
||||
],
|
||||
"Edit": [
|
||||
],
|
||||
"View": [
|
||||
"Full Screen",
|
||||
"---",
|
||||
"Zoom In",
|
||||
"Zoom Out",
|
||||
"Actual Size"
|
||||
],
|
||||
"Hyprland": [],
|
||||
"File": [],
|
||||
"Edit": [],
|
||||
"View": ["Full Screen", "---", "Zoom In", "Zoom Out", "Actual Size"],
|
||||
"Go": [
|
||||
"Back",
|
||||
"Forward",
|
||||
@@ -33,7 +24,7 @@ def get_default_menu_contents():
|
||||
"Center",
|
||||
"Group",
|
||||
"Pin",
|
||||
"Quit"
|
||||
"Quit",
|
||||
],
|
||||
"Help": [
|
||||
"---",
|
||||
@@ -41,33 +32,30 @@ def get_default_menu_contents():
|
||||
"Arch Wiki",
|
||||
"Keyboard Shortcuts",
|
||||
"---",
|
||||
"Report a Bug..."
|
||||
]
|
||||
"Report a Bug...",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def get_app_menu_template():
|
||||
return [
|
||||
"About {app_name}",
|
||||
"---",
|
||||
"Hide {app_name}",
|
||||
"---",
|
||||
"Quit {app_name}"
|
||||
]
|
||||
return ["About {app_name}", "---", "Hide {app_name}", "---", "Quit {app_name}"]
|
||||
|
||||
|
||||
def create_app_menu(app_name):
|
||||
template = get_app_menu_template()
|
||||
return [item.format(app_name=app_name) if "{app_name}" in item else item for item in template]
|
||||
return [
|
||||
item.format(app_name=app_name) if "{app_name}" in item else item
|
||||
for item in template
|
||||
]
|
||||
|
||||
|
||||
def get_menu_contents_for_app(app_name):
|
||||
contents = get_default_menu_contents().copy()
|
||||
|
||||
|
||||
if app_name and app_name != "Hyprland":
|
||||
# Replace the Hyprland menu with app-specific menu
|
||||
contents["Hyprland"] = create_app_menu(app_name)
|
||||
|
||||
|
||||
return contents
|
||||
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@ class DropdownWindow(WaylandWindow):
|
||||
super().__init__(
|
||||
name="dropdown-window",
|
||||
title="Menu Dropdown",
|
||||
layer="overlay",
|
||||
anchor="top left",
|
||||
exclusivity="none",
|
||||
margin=f"{y}px 0px 0px {x}px",
|
||||
visible=False,
|
||||
all_visible=True,
|
||||
**kwargs
|
||||
layer="overlay",
|
||||
anchor="top left",
|
||||
exclusivity="none",
|
||||
margin=f"{y}px 0px 0px {x}px",
|
||||
visible=False,
|
||||
all_visible=True,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
# Store reference to parent menubar for closing dropdown
|
||||
@@ -51,14 +51,16 @@ class DropdownWindow(WaylandWindow):
|
||||
if event.detail != 2: # 2 = Gdk.NotifyType.INFERIOR (child widget)
|
||||
# Start auto-close timer when mouse leaves
|
||||
if not self.auto_close_timer:
|
||||
self.auto_close_timer = GLib.timeout_add(300, self.auto_close_callback) # 300ms delay
|
||||
self.auto_close_timer = GLib.timeout_add(
|
||||
300, self.auto_close_callback
|
||||
) # 300ms delay
|
||||
return False
|
||||
|
||||
def auto_close_callback(self):
|
||||
if self.parent_menubar:
|
||||
self.parent_menubar.hide_dropdown()
|
||||
self.auto_close_timer = None
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
class MenuBar(Box):
|
||||
@@ -82,38 +84,32 @@ class MenuBar(Box):
|
||||
self.action_handler = MenuActionHandler()
|
||||
|
||||
# Menu items in macOS style order (excluding the first item which will be dynamic)
|
||||
self.static_menu_items = [
|
||||
"File",
|
||||
"Edit",
|
||||
"View",
|
||||
"Go",
|
||||
"Window",
|
||||
"Help"
|
||||
]
|
||||
self.static_menu_items = ["File", "Edit", "View", "Go", "Window", "Help"]
|
||||
|
||||
self.menu_contents = get_default_menu_contents()
|
||||
|
||||
self.app_button = Button(
|
||||
name="menubar-button",
|
||||
child=Label(
|
||||
name="activewindow-label",
|
||||
label="Hyprland"
|
||||
),
|
||||
child=Label(name="activewindow-label", label="Hyprland"),
|
||||
)
|
||||
self.app_button.connect(
|
||||
"clicked", lambda widget: self.toggle_dropdown("Hyprland", widget)
|
||||
)
|
||||
self.app_button.connect("clicked", lambda widget: self.toggle_dropdown("Hyprland", widget))
|
||||
self.add(self.app_button)
|
||||
|
||||
self.menu_buttons = []
|
||||
for item in self.static_menu_items:
|
||||
button = Button(
|
||||
name="menubar-button",
|
||||
child=Label(
|
||||
name="menubar-label",
|
||||
label=item
|
||||
),
|
||||
child=Label(name="menubar-label", label=item),
|
||||
)
|
||||
|
||||
button.connect("clicked", lambda widget, menu_item=item: self.on_menu_button_clicked(menu_item, widget))
|
||||
button.connect(
|
||||
"clicked",
|
||||
lambda widget, menu_item=item: self.on_menu_button_clicked(
|
||||
menu_item, widget
|
||||
),
|
||||
)
|
||||
self.menu_buttons.append(button)
|
||||
self.add(button)
|
||||
|
||||
@@ -145,9 +141,9 @@ class MenuBar(Box):
|
||||
if menu_item in context_dependent_menus:
|
||||
# Only allow if there's an active window (not just showing "Hyprland")
|
||||
has_active_window = (
|
||||
self.current_window_title and
|
||||
self.current_window_title.strip() and
|
||||
self.app_button.get_child().get_label() != "Hyprland"
|
||||
self.current_window_title
|
||||
and self.current_window_title.strip()
|
||||
and self.app_button.get_child().get_label() != "Hyprland"
|
||||
)
|
||||
return has_active_window
|
||||
|
||||
@@ -171,9 +167,11 @@ class MenuBar(Box):
|
||||
|
||||
def toggle_dropdown(self, menu_item, button):
|
||||
# If same menu is clicked and dropdown is visible, hide it
|
||||
if (self.current_dropdown == menu_item and
|
||||
self.dropdown_window and
|
||||
self.dropdown_window.get_visible()):
|
||||
if (
|
||||
self.current_dropdown == menu_item
|
||||
and self.dropdown_window
|
||||
and self.dropdown_window.get_visible()
|
||||
):
|
||||
self.hide_dropdown()
|
||||
return
|
||||
|
||||
@@ -209,7 +207,7 @@ class MenuBar(Box):
|
||||
separator = Box(
|
||||
name="menu-separator",
|
||||
size=(150, 1),
|
||||
style="background-color: #444; margin: 2px 0;"
|
||||
style="background-color: #444; margin: 2px 0;",
|
||||
)
|
||||
self.dropdown_window.content_box.add(separator)
|
||||
else:
|
||||
@@ -219,9 +217,9 @@ class MenuBar(Box):
|
||||
child=Label(
|
||||
name="dropdown-label",
|
||||
label=item,
|
||||
h_align="start" # Align text to the left
|
||||
h_align="start", # Align text to the left
|
||||
),
|
||||
on_clicked=lambda *_, action=item: self.on_menu_action(action)
|
||||
on_clicked=lambda *_, action=item: self.on_menu_action(action),
|
||||
)
|
||||
self.dropdown_window.content_box.add(menu_button)
|
||||
|
||||
@@ -236,7 +234,9 @@ class MenuBar(Box):
|
||||
# Get button allocation
|
||||
allocation = button.get_allocation()
|
||||
|
||||
print(f"Button allocation: x={allocation.x}, y={allocation.y}, width={allocation.width}, height={allocation.height}")
|
||||
print(
|
||||
f"Button allocation: x={allocation.x}, y={allocation.y}, width={allocation.width}, height={allocation.height}"
|
||||
)
|
||||
|
||||
# Use the exact button position for perfect alignment
|
||||
dropdown_x = allocation.x
|
||||
@@ -291,9 +291,11 @@ class MenuBar(Box):
|
||||
|
||||
def show_system_dropdown(self, button):
|
||||
# If same system dropdown is open, hide it (toggle behavior)
|
||||
if (self.current_dropdown == "System" and
|
||||
self.dropdown_window and
|
||||
self.dropdown_window.get_visible()):
|
||||
if (
|
||||
self.current_dropdown == "System"
|
||||
and self.dropdown_window
|
||||
and self.dropdown_window.get_visible()
|
||||
):
|
||||
self.hide_dropdown()
|
||||
return
|
||||
|
||||
@@ -324,7 +326,7 @@ class MenuBar(Box):
|
||||
"Shutdown",
|
||||
"Restart",
|
||||
"Sleep",
|
||||
"Lock"
|
||||
"Lock",
|
||||
]
|
||||
|
||||
# Add menu items to dropdown
|
||||
@@ -334,7 +336,7 @@ class MenuBar(Box):
|
||||
separator = Box(
|
||||
name="menu-separator",
|
||||
size=(150, 1),
|
||||
style="background-color: #444; margin: 2px 0;"
|
||||
style="background-color: #444; margin: 2px 0;",
|
||||
)
|
||||
self.dropdown_window.content_box.add(separator)
|
||||
else:
|
||||
@@ -344,9 +346,9 @@ class MenuBar(Box):
|
||||
child=Label(
|
||||
name="dropdown-label",
|
||||
label=item,
|
||||
h_align="start" # Align text to the left
|
||||
h_align="start", # Align text to the left
|
||||
),
|
||||
on_clicked=lambda *_, action=item: self.on_menu_action(action)
|
||||
on_clicked=lambda *_, action=item: self.on_menu_action(action),
|
||||
)
|
||||
self.dropdown_window.content_box.add(menu_button)
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
from fabric.widgets.button import Button
|
||||
from fabric.widgets.label import Label
|
||||
import time
|
||||
import subprocess
|
||||
from fabric.widgets.box import Box
|
||||
from gi.repository import GLib
|
||||
from fabric.utils import get_relative_path
|
||||
from fabric.widgets.svg import Svg
|
||||
|
||||
|
||||
class RecordingIndicator(Button):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(name="panel-button", visible=False, **kwargs)
|
||||
|
||||
self.script_path = get_relative_path("../../../scripts/screen-capture.sh")
|
||||
self.recording_start_time = None
|
||||
|
||||
self.recording_icon = Svg(
|
||||
name="indicators-icon",
|
||||
size=24,
|
||||
svg_file=get_relative_path("../../../config/assets/icons/media-record.svg"),
|
||||
)
|
||||
self.time_label = Label(name="recording-time-label", markup="00:00")
|
||||
|
||||
self.recording_box = Box(
|
||||
orientation="h",
|
||||
spacing=2,
|
||||
children=self.recording_icon,
|
||||
)
|
||||
|
||||
self.add(self.recording_box)
|
||||
|
||||
self.connect("clicked", self.on_stop_recording)
|
||||
self.hide()
|
||||
|
||||
GLib.timeout_add(1, self._delayed_init)
|
||||
|
||||
def check_recording_status(self):
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[self.script_path, "status"], capture_output=True, text=True, timeout=2
|
||||
)
|
||||
is_recording = result.stdout.strip() == "true"
|
||||
|
||||
if is_recording:
|
||||
if not self.get_visible():
|
||||
self.show()
|
||||
|
||||
# Get the recording start time if we don't have it
|
||||
if self.recording_start_time is None:
|
||||
self.recording_start_time = self.get_recording_start_time()
|
||||
|
||||
# Update the recording time display
|
||||
if self.recording_start_time:
|
||||
elapsed_seconds = int(time.time() - self.recording_start_time)
|
||||
minutes = elapsed_seconds // 60
|
||||
seconds = elapsed_seconds % 60
|
||||
time_text = f"{minutes:02d}:{seconds:02d}"
|
||||
self.time_label.set_markup(time_text)
|
||||
self.set_tooltip_text(
|
||||
f"Recording in progress ({minutes:02d}:{
|
||||
seconds:02d}) - Click to stop"
|
||||
)
|
||||
else:
|
||||
self.set_tooltip_text("Recording in progress - Click to stop")
|
||||
else:
|
||||
if self.get_visible():
|
||||
self.hide()
|
||||
self.recording_start_time = None
|
||||
|
||||
except Exception:
|
||||
# If we can't check status, hide the indicator
|
||||
if self.get_visible():
|
||||
self.hide()
|
||||
self.recording_start_time = None
|
||||
|
||||
return True # Continue the timeout
|
||||
@@ -7,10 +7,13 @@ from fabric.widgets.datetime import DateTime
|
||||
from fabric.widgets.label import Label
|
||||
from fabric.widgets.revealer import Revealer
|
||||
from fabric.widgets.svg import Svg
|
||||
from utils.wayland import WaylandWindow as Window
|
||||
|
||||
from modules.panel.components.enhanced_system_tray import (
|
||||
apply_enhanced_system_tray,
|
||||
) # ignore
|
||||
from modules.panel.components.indicators import Indicators
|
||||
from modules.panel.components.menubar import MenuBar
|
||||
from modules.panel.components.enhanced_system_tray import apply_enhanced_system_tray
|
||||
from utils.wayland import WaylandWindow as Window
|
||||
|
||||
# Apply enhanced system tray icon handling
|
||||
apply_enhanced_system_tray()
|
||||
@@ -131,4 +134,4 @@ class Panel(Window):
|
||||
else:
|
||||
self.chevron_button.get_child().set_from_file(
|
||||
get_relative_path("../../config/assets/icons/chevron-right.svg")
|
||||
)
|
||||
)
|
||||
Reference in new issue
Block a user