diff --git a/bec_widgets/widgets/containers/main_window/addons/notification_center/notification_banner.py b/bec_widgets/widgets/containers/main_window/addons/notification_center/notification_banner.py index 0fa0f764..057a2cfa 100644 --- a/bec_widgets/widgets/containers/main_window/addons/notification_center/notification_banner.py +++ b/bec_widgets/widgets/containers/main_window/addons/notification_center/notification_banner.py @@ -62,6 +62,21 @@ LIGHT_PALETTE = { } +def _connect_theme_change(slot) -> None: + """Connect *slot* to the available application theme-change signals.""" + qapp = QApplication.instance() + if qapp is None: + return + + theme = getattr(qapp, "theme", None) + if hasattr(theme, "theme_changed"): + theme.theme_changed.connect(slot) + + legacy_signal = getattr(qapp, "theme_signal", None) + if hasattr(legacy_signal, "theme_updated"): + legacy_signal.theme_updated.connect(slot) + + class NotificationToast(QFrame): """ Notification toast widget with title, body, optional traceback, @@ -257,9 +272,7 @@ class NotificationToast(QFrame): # ------------------------------------------------------------------ def _connect_to_theme_change(self): """Connect this toast to the global theme‑updated signal.""" - qapp = QApplication.instance() - if hasattr(qapp, "theme_signal"): - qapp.theme_signal.theme_updated.connect(self.apply_theme) + _connect_theme_change(self.apply_theme) # helper methods ----------------------------------------------------- def _current_inner_width(self) -> int: @@ -403,11 +416,18 @@ class NotificationToast(QFrame): #NotificationToast QPushButton:hover {{ color: {btn_hover}; }} """) # traceback panel colours - trace_bg = "#1e1e1e" if theme == "dark" else "#f0f0f0" + if theme == "dark": + trace_bg = "#1e1e1e" + trace_fg = palette["body"] + trace_border = "rgba(255,255,255,48)" + else: + trace_bg = "#ffffff" + trace_fg = palette["body"] + trace_border = "rgba(15,23,42,54)" self.trace_view.setStyleSheet(f""" background:{trace_bg}; - color:{palette['body']}; - border:none; + color:{trace_fg}; + border: 1px solid {trace_border}; border-radius:8px; """) @@ -438,7 +458,7 @@ class NotificationToast(QFrame): }} """) - self._accent_alpha = 28 if theme == "light" else 60 + self._accent_alpha = 6 if theme == "light" else 60 self._gradient_width_factor = 1.0 if theme == "light" else 0.70 self.update() @@ -674,9 +694,7 @@ class NotificationCentre(QScrollArea): def _connect_to_theme_change(self): """Connect to the theme change signal.""" - qapp = QApplication.instance() - if hasattr(qapp, "theme_signal"): - qapp.theme_signal.theme_updated.connect(self.apply_theme) + _connect_theme_change(self.apply_theme) # public API def add_notification( diff --git a/tests/unit_tests/test_notifications.py b/tests/unit_tests/test_notifications.py index 2561e18f..2707b29f 100644 --- a/tests/unit_tests/test_notifications.py +++ b/tests/unit_tests/test_notifications.py @@ -40,8 +40,10 @@ def test_apply_theme_updates_colours(qtbot, toast): """apply_theme("light") should inject LIGHT palette colours into stylesheets.""" toast.apply_theme("light") assert LIGHT_PALETTE["title"] in toast._title_lbl.styleSheet() - assert toast._accent_alpha == 28 + assert toast._accent_alpha == 6 assert toast._gradient_width_factor == 1.0 + assert "border: 1px solid" in toast.trace_view.styleSheet() + assert "border:none" not in toast.trace_view.styleSheet() toast.apply_theme("dark") assert DARK_PALETTE["title"] in toast._title_lbl.styleSheet() @@ -49,6 +51,16 @@ def test_apply_theme_updates_colours(qtbot, toast): assert toast._gradient_width_factor == 0.70 +def test_toast_updates_from_qapp_theme_changed_signal(qtbot, toast): + app = QtWidgets.QApplication.instance() + assert hasattr(app, "theme") + + app.theme.theme_changed.emit("light") + qtbot.wait(10) + + assert LIGHT_PALETTE["title"] in toast._title_lbl.styleSheet() + + def test_expired_signal(qtbot, toast): """Toast must emit expired once its lifetime finishes.""" with qtbot.waitSignal(toast.expired, timeout=1000): @@ -255,6 +267,20 @@ def test_theme_propagation(qtbot, centre): assert LIGHT_PALETTE["title"] in toast._title_lbl.styleSheet() +def test_centre_updates_from_qapp_theme_changed_signal(qtbot, centre): + toast = _post(centre, SeverityKind.INFO) + centre.apply_theme("dark") + + app = QtWidgets.QApplication.instance() + assert hasattr(app, "theme") + + app.theme.theme_changed.emit("light") + qtbot.wait(10) + + assert centre._theme == "light" + assert LIGHT_PALETTE["title"] in toast._title_lbl.styleSheet() + + # ------------------------------------------------------------------------ # NotificationIndicator tests # ------------------------------------------------------------------------