refactor(services): convert weather + gamemode to Fabric services

Weather: move networking, caching and scheduling out of the Weather widget
into a WeatherService singleton. Reuse one httpx.Client for the app lifetime,
drop the 4-worker pool and the multi-entry dict caches (single-value fields),
query Nominatim only on location change, remove debounce and the /tmp-style
polling. Widget now observes the `updated` signal and never hits the network.

GameMode: turn the standalone CLI script into a GameModeService (Service
singleton) exposing an `enabled` Property and `changed` signal. Drive Hyprland
via `hyprctl eval hl.config(...)` instead of the deprecated `hyprctl keyword`
batch (rejected under the Lua config in Hyprland 0.55+), read state via
`hl.get_config`, and keep `hyprctl reload` for disable. Fix game-mode state
parsing so unrecognized `hl.get_config` output no longer falsely reports
active. BatteryWidget's GameModeButton now subscribes to the service.

Remove now-unused LOCATION_CACHE_TIMEOUT.
This commit is contained in:
sankalp committed 2026-07-14 00:37:52 +05:45
1 parent f3f17bb5fc
commit 112f4b1039
4 files changed
+280 -321

No files matched your search

+9 -23
View File
@@ -1,4 +1,4 @@
from fabric.utils import GLib, logger
from fabric.utils import GLib
from fabric.widgets.box import Box
from fabric.widgets.button import Button
from fabric.widgets.centerbox import CenterBox
@@ -7,7 +7,7 @@ from fabric.widgets.label import Label
from fabric.widgets.separator import Separator
from services.battery import Battery
from services.gamemode import check_gamemode, toggle_gamemode
from services.gamemode import GameModeService
from utils.functions import clear_children, format_duration
from utils.utils import svg_file
@@ -88,6 +88,8 @@ class GameModeButton(Box):
def __init__(self, parent, **kwargs):
super().__init__(name="energy-mode-button", h_expand=True, **kwargs)
self.parent = parent
self.gamemode_service = GameModeService.get_initial()
self.gamemode_service.connect("changed", self.update_state)
self.game_icon = Image(
icon_name="applications-games-symbolic",
@@ -121,30 +123,14 @@ class GameModeButton(Box):
self.update_state()
def on_clicked(self, *args):
try:
toggle_gamemode()
GLib.timeout_add(500, lambda: self.update_state())
except Exception as e:
logger.error(f"Failed to toggle game mode: {e}")
self.gamemode_service.toggle()
GLib.timeout_add(300, lambda: self._reset_icon_state())
def _reset_icon_state(self):
return False # Remove timeout
def update_state(self):
try:
is_active = check_gamemode() == "t"
if is_active:
self.game_icon.add_style_class("connected")
else:
self.game_icon.remove_style_class("connected")
except Exception as e:
logger.error(f"Failed to check game mode status: {e}")
def update_state(self, *_):
if self.gamemode_service.enabled:
self.game_icon.add_style_class("connected")
else:
self.game_icon.remove_style_class("connected")
return False # Remove timeout if called from GLib.timeout_add
class BatteryControl(Box):
def __init__(self, parent, **kwargs):