238 lines
7.0 KiB
Python
238 lines
7.0 KiB
Python
from loguru import logger
|
|
|
|
# Configure logging based on dev flag
|
|
from .config import DEV, LOG_LEVEL
|
|
if DEV:
|
|
# In dev mode, disable fabric logs but keep stylix and bar logs
|
|
logger.disable("fabric")
|
|
else:
|
|
# In production, disable fabric logs but keep bar logs with configurable level
|
|
import sys
|
|
logger.disable("fabric")
|
|
logger.configure(handlers=[{"sink": sys.stderr, "level": LOG_LEVEL, "format": "{time} | {level} | {name}:{function}:{line} - {message}"}])
|
|
|
|
from fabric import Application
|
|
from sims.services.i3 import I3, I3MessageType
|
|
from fabric.system_tray.widgets import SystemTray
|
|
from fabric.widgets.wayland import WaylandWindow as Window
|
|
from fabric.utils import (
|
|
get_relative_path,
|
|
)
|
|
from .modules.bar import StatusBar
|
|
from .modules.window_fuzzy import FuzzyWindowFinder
|
|
from .modules.launcher.apps import AppLauncher
|
|
from .modules.launcher.clipboard import ClipboardMenu
|
|
from .modules.launcher.power import PowerMenu
|
|
from .modules.launcher.screenrec import ScreenrecMenu
|
|
from .modules.launcher.screenshot import ScreenshotMenu
|
|
from .modules.calendar import CalendarService
|
|
from .modules.control_center import ControlCenter
|
|
from .modules.notifications import NotificationToasts
|
|
from .modules.stylix import get_stylix_css_path
|
|
from .modules.vinyl import VinylButton
|
|
from .config import CALENDAR, NOTIFICATIONS, POWER, SCREENREC, STYLIX, VINYL
|
|
from .services.fenster import get_i3_connection
|
|
from .services.notification_history import NotificationHistoryService
|
|
from .services.screenrec import ScreenrecService
|
|
|
|
from fabric.notifications import Notifications
|
|
|
|
|
|
tray = SystemTray(name="system-tray", spacing=4)
|
|
get_i3_connection()
|
|
|
|
dummy = Window(visible=False)
|
|
finder = FuzzyWindowFinder()
|
|
app_launcher = AppLauncher()
|
|
clipboard_menu = ClipboardMenu()
|
|
power_menu = PowerMenu(lock_command=POWER.get("lock_command", ["waylock"]))
|
|
screenshot_menu = ScreenshotMenu()
|
|
|
|
screenrec_service: ScreenrecService | None = None
|
|
screenrec_menu = None
|
|
if SCREENREC.get("enable", False):
|
|
screenrec_service = ScreenrecService(
|
|
output_dir=SCREENREC.get("output_dir", "~/Videos/wl-screenrec")
|
|
)
|
|
screenrec_menu = ScreenrecMenu(screenrec_service)
|
|
|
|
notifications_service: Notifications | None = None
|
|
notification_history: NotificationHistoryService | None = None
|
|
notification_toasts: NotificationToasts | None = None
|
|
if NOTIFICATIONS.get("enable", False):
|
|
notifications_service = Notifications()
|
|
notification_history = NotificationHistoryService(
|
|
notifications_service,
|
|
history_size=NOTIFICATIONS.get("history_size", 50),
|
|
image_max_px=NOTIFICATIONS.get("image_max_px", 128),
|
|
)
|
|
notification_toasts = NotificationToasts(
|
|
notifications_service,
|
|
monitor=0,
|
|
anchor=NOTIFICATIONS.get("anchor", "top center"),
|
|
margin=NOTIFICATIONS.get("margin", "8px"),
|
|
width=NOTIFICATIONS.get("width", 360),
|
|
timeout_ms=NOTIFICATIONS.get("timeout_ms", 10_000),
|
|
)
|
|
|
|
vinyl_button: VinylButton | None = VinylButton() if VINYL.get("enable", False) else None
|
|
calendar_service: CalendarService | None = (
|
|
CalendarService(update_interval=120000) if CALENDAR.get("enable", True) else None
|
|
)
|
|
|
|
control_center: ControlCenter | None = None
|
|
if notification_history is not None:
|
|
control_center = ControlCenter(
|
|
history=notification_history,
|
|
calendar_service=calendar_service,
|
|
vinyl_button=vinyl_button,
|
|
monitor=0,
|
|
width=NOTIFICATIONS.get("center_width", 380),
|
|
)
|
|
|
|
bar_windows = []
|
|
notmuch_widget = None
|
|
|
|
_app_windows = [dummy, finder, app_launcher, clipboard_menu, power_menu, screenshot_menu]
|
|
if screenrec_menu is not None:
|
|
_app_windows.append(screenrec_menu)
|
|
if notification_toasts is not None:
|
|
_app_windows.append(notification_toasts)
|
|
if control_center is not None:
|
|
_app_windows.append(control_center)
|
|
app = Application("sims", *_app_windows)
|
|
|
|
|
|
@Application.action()
|
|
def open_finder():
|
|
finder.show()
|
|
|
|
|
|
@Application.action()
|
|
def open_app_launcher():
|
|
app_launcher.show()
|
|
|
|
|
|
@Application.action()
|
|
def open_clipboard_menu():
|
|
clipboard_menu.show()
|
|
|
|
|
|
@Application.action()
|
|
def open_power_menu():
|
|
power_menu.show()
|
|
|
|
|
|
@Application.action()
|
|
def open_screenshot_menu():
|
|
screenshot_menu.show()
|
|
|
|
|
|
@Application.action()
|
|
def refresh_notmuch():
|
|
if notmuch_widget is not None:
|
|
notmuch_widget.service.update_counts()
|
|
|
|
|
|
@Application.action()
|
|
def open_screenrec_menu():
|
|
if screenrec_menu is not None:
|
|
screenrec_menu.show()
|
|
|
|
|
|
@Application.action()
|
|
def screenrec_start_monitor():
|
|
if screenrec_service is not None:
|
|
screenrec_service.start_monitor("videos")
|
|
|
|
|
|
@Application.action()
|
|
def screenrec_start_region():
|
|
if screenrec_service is not None:
|
|
screenrec_service.start_region("videos")
|
|
|
|
|
|
@Application.action()
|
|
def screenrec_stop():
|
|
if screenrec_service is not None:
|
|
screenrec_service.stop()
|
|
|
|
|
|
@Application.action()
|
|
def toggle_control_center():
|
|
if control_center is not None:
|
|
control_center.toggle()
|
|
|
|
|
|
def _set_all_bars_rounded(rounded: bool):
|
|
for bar in bar_windows:
|
|
bar.set_corners_rounded(rounded)
|
|
|
|
|
|
@Application.action()
|
|
def set_bar_corners_rounded():
|
|
_set_all_bars_rounded(True)
|
|
|
|
|
|
@Application.action()
|
|
def set_bar_corners_flat():
|
|
_set_all_bars_rounded(False)
|
|
|
|
|
|
@Application.action()
|
|
def toggle_bar_corners():
|
|
new_state = not any(bar.corners_rounded for bar in bar_windows)
|
|
_set_all_bars_rounded(new_state)
|
|
|
|
# Load CSS - use Stylix if enabled, otherwise use default
|
|
if STYLIX.get("enable", False):
|
|
stylix_css_path = get_stylix_css_path()
|
|
if stylix_css_path:
|
|
logger.info("[Bar] Using Stylix CSS")
|
|
app.set_stylesheet_from_file(get_relative_path("styles/main.css"))
|
|
app.set_stylesheet_from_file(stylix_css_path, append=True)
|
|
else:
|
|
logger.warning("[Bar] Stylix enabled but CSS generation failed, falling back to default")
|
|
app.set_stylesheet_from_file(get_relative_path("styles/main.css"))
|
|
else:
|
|
logger.info("[Bar] Using default CSS")
|
|
app.set_stylesheet_from_file(get_relative_path("styles/main.css"))
|
|
|
|
|
|
def spawn_bars():
|
|
global notmuch_widget
|
|
logger.info("[Bar] Spawning bars")
|
|
outputs_reply = I3.send_command("", I3MessageType.GET_OUTPUTS)
|
|
|
|
if not (outputs_reply.is_ok and isinstance(outputs_reply.reply, list)):
|
|
logger.warning("[Bar] Failed to get outputs — skipping bar spawn")
|
|
return
|
|
|
|
outputs = [o for o in outputs_reply.reply if o.get("active")]
|
|
|
|
if not outputs:
|
|
logger.warning("[Bar] No active outputs found — skipping bar spawn")
|
|
return
|
|
|
|
for i, output in enumerate(outputs):
|
|
output_name = output.get("name", f"Unknown-{i}")
|
|
bar = StatusBar(
|
|
display=output_name,
|
|
tray=tray if i == 0 else None,
|
|
monitor=i,
|
|
screenrec_service=screenrec_service if i == 0 else None,
|
|
control_center=control_center if i == 0 else None,
|
|
)
|
|
bar_windows.append(bar)
|
|
if i == 0 and bar.notmuch:
|
|
notmuch_widget = bar.notmuch
|
|
|
|
|
|
def main():
|
|
spawn_bars()
|
|
app.run()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|