♻️ refactor(notification): improve notification animation and limit count

This commit is contained in:
sankalp committed 2025-08-01 09:57:52 +05:45
1 parent f18183aebd
commit 2e7207c4ac
5 files changed
+61 -14

No files matched your search

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8"
version="1.1"
width="24"
height="24">
<metadata
id="metadata14">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs12" />
<path
id="path4"
d="M 6.3515625 4.7363281 L 5.4121094 5.6777344 L 18.955078 19.220703 L 19.894531 18.279297 L 18.488281 16.873047 A 1 1 0 0 0 18.828125 16.560547 L 21.765625 12.642578 A 1 1 0 0 0 21.794922 12.605469 A 1 1 0 0 0 22 11.998047 A 1 1 0 0 0 21.746094 11.335938 L 18.851562 7.4746094 A 1 1 0 0 0 17.998047 7 A 1 1 0 0 0 17 8.0019531 A 1 1 0 0 0 17.199219 8.5976562 L 17.195312 8.5996094 L 19.746094 12.001953 L 17.195312 15.404297 L 17.197266 15.40625 A 1 1 0 0 0 17.128906 15.513672 L 14.447266 12.832031 A 1 1 0 0 0 15 13 A 1 1 0 0 0 15 11 A 1 1 0 0 0 14.169922 12.554688 L 6.3515625 4.7363281 z M 5.5234375 7.1191406 A 1 1 0 0 0 5.1484375 7.4746094 L 2.2539062 11.335938 A 1 1 0 0 0 2 11.998047 A 1 1 0 0 0 2.2050781 12.605469 A 1 1 0 0 0 2.234375 12.642578 L 5.171875 16.560547 A 1 1 0 0 0 5.9980469 17 A 1 1 0 0 0 7 16.001953 A 1 1 0 0 0 6.8027344 15.40625 L 6.8046875 15.404297 L 4.2539062 12.001953 L 6.8046875 8.5996094 L 6.8007812 8.5976562 A 1 1 0 0 0 6.8789062 8.4746094 L 5.5234375 7.1191406 z M 9 11 A 1 1 0 0 0 9 13 A 1 1 0 0 0 9.7773438 11.373047 L 9.6269531 11.222656 A 1 1 0 0 0 9 11 z "
style="opacity:0.5;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;font-variant-east_asian:normal;marker:none" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -0,0 +1,4 @@
<svg width="24" height="24" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="m6.002 7c-0.34766-9.221e-4 -0.67086 0.17879-0.85352 0.47461l-2.8945 3.8613c-0.16267 0.18228-0.25299 0.4178-0.25391 0.66211-1.558e-4 0.21949 0.071909 0.43294 0.20508 0.60742 0.00947 0.0126 0.01924 0.02497 0.029297 0.03711l2.9375 3.918c0.18564 0.27425 0.495 0.43881 0.82617 0.43945 0.55229 0.0011 1.0009-0.44576 1.002-0.99805-1.36e-4 -0.21459-0.069298-0.42344-0.19727-0.5957l0.00195-2e-3 -2.5508-3.4023 2.5508-3.4023-0.00391-0.00195c0.12866-0.172 0.19851-0.38086 0.19923-0.59566 0.00108-0.55229-0.44576-1.0009-0.99805-1.002zm11.996 0c-0.55228 0.00108-0.99913 0.44967-0.99805 1.002 7.01e-4 0.21481 0.07055 0.42369 0.19922 0.5957l-0.0039 0.00195 2.5508 3.4023-2.5508 3.4023 2e-3 2e-3c-0.12798 0.17224-0.19716 0.38108-0.19732 0.59566 0.0011 0.55229 0.44967 0.99913 1.002 0.99805 0.33117-6.47e-4 0.64054-0.1652 0.82617-0.43945l2.9375-3.918c0.01006-0.01214 0.01983-0.02451 0.0293-0.03711 0.13317-0.17448 0.20523-0.38793 0.20508-0.60742-9.14e-4 -0.24431-0.09123-0.47983-0.25391-0.66211l-2.8945-3.8613c-0.18266-0.29582-0.50585-0.47553-0.85352-0.47461z" fill="#f2f2f2"/>
<path d="m9 11c-1.3333 0-1.3333 2 0 2s1.3333-2 0-2zm3 0c-1.3333 0-1.3333 2 0 2s1.3333-2 0-2zm3 0c-1.3333 0-1.3333 2 0 2s1.3333-2 0-2z" fill="#f2f2f2"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+13 -3
View File
@@ -28,7 +28,7 @@ NOTIFICATION_IMAGE_SIZE = 48
# Improved animation smoothness and consistent behavior for rapid notifications.
def smooth_revealer_animation(revealer: SlideRevealer, duration: int = 250):
def smooth_revealer_animation(revealer: SlideRevealer, duration: int = 600):
revealer.duration = duration
@@ -207,7 +207,7 @@ class NotificationRevealer(SlideRevealer):
super().__init__(
child=self.event_box,
direction="right",
duration=250,
duration=600,
)
smooth_revealer_animation(self)
@@ -283,6 +283,7 @@ class ModusNoti(Window):
self.notifications = Box(
v_expand=True,
h_expand=True,
title="Notification Center",
style="margin: 1px 0px 1px 1px;",
orientation="v",
spacing=5,
@@ -317,8 +318,17 @@ class ModusNoti(Window):
current_children.insert(0, new_box)
self.notifications.children = current_children
# This ensures each notification's container is fully laid out before animation
if len(current_children) >= 4:
# Animate close for the oldest notification if we exceed the limit
oldest_notification = current_children[-1]
if hasattr(oldest_notification, 'notification'):
# Trigger the close animation by closing the underlying notification
# This will use the same slide animation as auto-dismiss (left-to-right)
oldest_notification.notification.close("expired")
current_children.pop()
def start_animation():
if new_box.get_parent(): # Only animate if still in the tree
new_box.reveal()
+4 -4
View File
@@ -15,7 +15,7 @@ class BluetoothIndicator(Box):
self.bluetooth = BluetoothClient()
self.bt_icon = Svg(
name="bt-icon",
size=20,
size=25,
svg_file=get_relative_path(
"../../../config/assets/icons/applets/bluetooth-clear.svg"
),
@@ -211,15 +211,15 @@ class NetworkIndicator(Box):
elif primary_device == "wired" and self.network_service.ethernet_device:
ethernet = self.network_service.ethernet_device
if ethernet.internet == "activated":
icon_file = "ethernet.svg"
icon_file = "network-wired.svg"
tooltip = "Ethernet connected"
if hasattr(ethernet, "speed") and ethernet.speed > 0:
tooltip += f" ({ethernet.speed} Mbps)"
elif ethernet.internet == "activating":
icon_file = "wifi-clear.svg"
icon_file = "network-wired.svg"
tooltip = "Ethernet connecting..."
else:
icon_file = "wifi-off-clear.svg"
icon_file = "network-wired-offline.svg"
tooltip = "Ethernet disconnected"
self.network_icon.set_from_file(
+10 -7
View File
@@ -63,13 +63,15 @@ class AnimationManager:
"""Calculate optimal frame interval based on widget count"""
widget_count = len(self._animating_widgets)
if widget_count <= 1:
return 22 # 45 FPS for single widget
elif widget_count <= 3:
return 33 # 30 FPS for 2-3 widgets
return 16 # 60 FPS
elif widget_count <= 2:
return 16 # 60 FPS
elif widget_count <= 4:
return 22 # 45 FPS
elif widget_count <= 6:
return 50 # 20 FPS for 4-6 widgets
return 33 # 30 FPS
else:
return 67 # 15 FPS for 7+ widgets
return 50 # 20 FPS
def _start_timer(self):
interval = self._get_optimal_interval()
@@ -166,9 +168,10 @@ class SlideRevealer(Gtk.Overlay):
t = min(elapsed / self.duration, 1.0)
if self._show_animation:
eased = 1 - (1 - t) ** 3 # Inline ease_out_cubic
# Ease out quadratic (no bounce/overshoot)
eased = 1 - (1 - t) ** 2
else:
eased = t**3 # Ease in cubic for hide animation
eased = t**2 # Ease in quadratic for hide animation
self._pending_position = self._get_position_at_progress_cached(eased)