refactor(src/window/notification): simplify hover handling and close‑button styling for notifications

This commit is contained in:
sankalp committed 2026-07-14 22:46:18 +05:45
1 parent 5dd3abb3b4
commit e7c49d7dda
2 files changed
+82 -43

No files matched your search

+76 -31
View File
@@ -13,6 +13,7 @@ from fabric.widgets.centerbox import CenterBox
from fabric.widgets.eventbox import EventBox
from fabric.widgets.image import Image
from fabric.widgets.label import Label
from fabric.widgets.revealer import Revealer
from fabric.widgets.wayland import WaylandWindow as Window
import shared.data as data
@@ -21,6 +22,7 @@ from services.modus import notification_service
from shared.widgets.clipping_box import ClippingBox
from shared.widgets.custom_image import CustomImage
from shared.widgets.customrevealer import SlideRevealer
from utils.gtk_utils import setup_cursor_hover
from utils.functions import escape_markup_text
from utils.roam import modus_service
from utils.icon_resolver import IconResolver
@@ -448,27 +450,36 @@ class NotificationWidget(Box):
) # Track app icon source for cleanup
self._should_cleanup_cache = False # Only cleanup cache on manual dismissal
super().__init__(
size=(NOTIFICATION_WIDTH, -1),
name=name,
content_box = Box(
name=f"{name}-inner-content",
orientation="v",
h_align="fill",
h_expand=True,
children=[
self.create_content(notification),
self.create_action_buttons(notification),
],
)
self.hover_event_box = EventBox(
events=["enter-notify-event", "leave-notify-event"], child=content_box
)
self.hover_event_box.connect("enter-notify-event", self._on_enter_notify)
self.hover_event_box.connect("leave-notify-event", self._on_leave_notify)
super().__init__(
size=(NOTIFICATION_WIDTH, -1),
name=name,
orientation="v",
h_align="fill",
h_expand=True,
children=[self.hover_event_box],
)
self.notification = notification
self.timeout_ms = timeout_ms
self._timeout_id = None
# Add hover events to the main notification widget
self.connect("enter-notify-event", self._on_enter_notify)
self.connect("leave-notify-event", self._on_leave_notify)
self.start_timeout()
self.show_all()
def create_header(self, notification):
"""Create notification header with optimized cached app icon - SINGLE CACHE SIZE"""
@@ -522,12 +533,21 @@ class NotificationWidget(Box):
],
)
],
end_children=[
self.create_close_button() if self.show_close_button else Box()
],
end_children=[Box()],
)
def create_content(self, notification):
if self.show_close_button:
self.close_button = Button(
name="notification-close-button",
image=CustomImage(icon_name="close-symbolic", icon_size=18),
on_clicked=lambda *_: self._manual_close(),
)
self.close_button.get_style_context().add_class("mac-close-button")
setup_cursor_hover(self.close_button)
else:
self.close_button = None
return Box(
name="notification-content",
spacing=8,
@@ -554,12 +574,6 @@ class NotificationWidget(Box):
max_chars_width=40,
ellipsization="end",
),
# Label(
# name="notification-app-name",
# markup=" | " + notification.app_name,
# h_align="start",
# ellipsization="end",
# ),
],
),
(
@@ -584,29 +598,28 @@ class NotificationWidget(Box):
Box(
orientation="v",
children=[
Button(
name="notification-close-button",
image=CustomImage(icon_name="close-symbolic", icon_size=18),
visible=True, # Initially hidden
on_clicked=lambda *_: self._manual_close(),
),
self.close_button,
Box(v_expand=True),
],
),
)
if self.show_close_button
else Box(h_expand=True),
],
)
def _on_enter_notify(self, widget, event):
if hasattr(event, "detail") and event.detail == Gdk.NotifyType.INFERIOR:
return False
self._is_hovered = True
if self.close_button:
self.close_button.set_visible(True)
self.pause_timeout()
return False
def _on_leave_notify(self, widget, event):
if hasattr(event, "detail") and event.detail == Gdk.NotifyType.INFERIOR:
return False
self._is_hovered = False
if self.close_button:
self.close_button.set_visible(False)
self.resume_timeout()
return False
@@ -712,7 +725,10 @@ class NotificationWidget(Box):
return pixbuf
def create_action_buttons(self, notification):
return Box(
if not notification.actions:
return Box(name="notification-action-buttons", visible=False)
action_box = Box(
name="notification-action-buttons",
spacing=4,
h_expand=True,
@@ -722,6 +738,35 @@ class NotificationWidget(Box):
],
)
revealer = Revealer(
transition_type="slide-up",
transition_duration=250,
child=action_box,
reveal_child=False,
)
# Wrap in EventBox to catch hover events specifically for the bottom area
event_box = EventBox(
name="notification-action-buttons-container",
events=["enter-notify-event", "leave-notify-event"],
child=revealer,
)
# Give it a tiny minimum height so there's an invisible hit-zone to trigger the reveal
event_box.set_size_request(-1, 12)
def _on_enter(*_):
revealer.set_reveal_child(True)
return False
def _on_leave(*_):
revealer.set_reveal_child(False)
return False
event_box.connect("enter-notify-event", _on_enter)
event_box.connect("leave-notify-event", _on_leave)
return event_box
def start_timeout(self):
self.stop_timeout()
self._timeout_id = GLib.timeout_add(self.timeout_ms, self.close_notification)
@@ -799,7 +844,7 @@ class NotificationRevealer(SlideRevealer):
parent_window=None,
**kwargs,
):
self.notif_box = NotificationWidget(notification, show_close_button=False)
self.notif_box = NotificationWidget(notification, show_close_button=True)
self.notification = notification
self.on_transition_end = on_transition_end
# Reference to NotificationCenter window for queue clearing
+6 -12
View File
@@ -512,19 +512,17 @@ class NotificationCenterWidget(NotificationWidget):
# Create our custom close button for notification center
self.close_button = Button(
name="notif-close-button",
name="notification-close-button",
image=CustomImage(
icon_name="close-symbolic", name="notification-close", icon_size=18
),
visible=True, # Always visible in notification center
on_clicked=self._on_close_clicked,
)
self.close_button.connect(
"enter-notify-event", lambda *_: self.hover_button(self.close_button)
)
self.close_button.connect(
"leave-notify-event", lambda *_: self.unhover_button(self.close_button)
)
self.close_button.get_style_context().add_class("mac-close-button")
from utils.gtk_utils import setup_cursor_hover
setup_cursor_hover(self.close_button)
# Create the content box manually with our custom close button
return Box(
@@ -584,10 +582,6 @@ class NotificationCenterWidget(NotificationWidget):
],
)
# Override to disable the action buttons
def create_action_buttons(self, notification):
return Box(name="notification-action-buttons")
def _on_close_clicked(self, *args):
try:
# Use instance cache metadata instead of notification attribute