@@ -195,7 +195,7 @@ def __init__(self, monitor_id: int = 0, **kwargs):
195195 self .ws_container .attach (self .ws_rail , 0 , 0 , 1 , 1 )
196196 self .ws_container .attach (workspaces_widget , 0 , 0 , 1 , 1 )
197197 self .ws_container .set_name ("workspaces-container" )
198-
198+ self . _animation_source_ids = []
199199
200200 self .button_tools = Button (
201201 name = "button-bar" ,
@@ -536,7 +536,9 @@ def setup_workspaces(self):
536536 logger .error (f"Error initializing workspace rail: { e } " )
537537
538538 def _on_workspace_changed (self , _ , event ):
539- """Handle workspace change events directly"""
539+ """Handle workspace change events directly.
540+
541+ This will cancel any ongoing animation and start a new one when workspace changes."""
540542 if event is not None and isinstance (event , HyprlandEvent ) and event .data :
541543 try :
542544 workspace_id = int (event .data [0 ])
@@ -547,12 +549,14 @@ def _on_workspace_changed(self, _, event):
547549 else :
548550 logger .warning (f"Invalid workspace event received: { event } " )
549551
550- def update_rail (self , workspace_id , initial_setup = False ):
551- """Update the workspace rail position based on the workspace button"""
552- if self .is_animating_rail and not initial_setup :
553- return
552+ def _cancel_animations (self ):
553+ # Cancel any pending animation timeouts
554+ for source_id in self ._animation_source_ids :
555+ GLib .source_remove (source_id )
556+ self ._animation_source_ids .clear ()
554557
555558 logger .info (f"Updating rail for workspace { workspace_id } " )
559+ self ._cancel_animations ()
556560 workspaces = self .children_workspaces
557561 active_button = next (
558562 (
@@ -662,13 +666,14 @@ def _update_rail_with_animation(self, active_button):
662666 """
663667 self .ws_rail_provider .load_from_data (stretch_css .encode ())
664668
665- GLib .timeout_add (
669+ source_id = GLib .timeout_add (
666670 int (stretch_duration * 1000 ),
667671 self ._shrink_rail ,
668672 target_pos ,
669673 diameter ,
670674 shrink_duration ,
671675 )
676+ self ._animation_source_ids .append (source_id )
672677 return False
673678
674679 def _shrink_rail (self , target_pos , target_size , duration ):
@@ -692,19 +697,20 @@ def _shrink_rail(self, target_pos, target_size, duration):
692697 """
693698 self .ws_rail_provider .load_from_data (shrink_css .encode ())
694699
695- GLib .timeout_add (
700+ source_id = GLib .timeout_add (
696701 int (duration * 1000 ),
697702 self ._finalize_rail_animation ,
698703 target_pos ,
699704 target_size ,
700705 )
701- return False
706+ self . _animation_source_ids . append ( source_id )
702707
703708 def _finalize_rail_animation (self , final_pos , final_size ):
704709 """Finalize animation and update state."""
705710 self .current_rail_pos = final_pos
706711 self .current_rail_size = final_size
707712 self .is_animating_rail = False
713+ self ._animation_source_ids .clear ()
708714 logger .info (
709715 f"Rail animation finished at pos={ self .current_rail_pos } , size={ self .current_rail_size } "
710716 )
0 commit comments