@@ -8,15 +8,13 @@ namespace Spice86.Views.Behaviors;
88using Spice86 . Shared . Emulator . Memory ;
99using Spice86 . ViewModels ;
1010
11- using System . Timers ;
11+
1212
1313/// <summary>
1414/// Attached behavior for handling scrolling in the disassembly view.
1515/// This behavior encapsulates the UI-specific scrolling logic to improve separation of concerns.
1616/// </summary>
1717public class DisassemblyScrollBehavior {
18- private const int AnimationFramesPerSecond = 60 ;
19-
2018 // Attached property for enabling the behavior
2119 public static readonly AttachedProperty < bool > IsEnabledProperty = AvaloniaProperty . RegisterAttached < DisassemblyScrollBehavior , Control , bool > ( "IsEnabled" ) ;
2220
@@ -26,9 +24,6 @@ public class DisassemblyScrollBehavior {
2624 // Static field to track if we're currently processing a scroll operation
2725 private static bool _isScrollingInProgress ;
2826
29- // Configuration properties for smooth scrolling
30- private static readonly TimeSpan AnimationDuration = TimeSpan . FromMilliseconds ( 250 ) ;
31-
3227 // Static constructor to register property changed handlers
3328 static DisassemblyScrollBehavior ( ) {
3429 IsEnabledProperty . Changed . AddClassHandler < Control > ( OnIsEnabledChanged ) ;
@@ -141,7 +136,7 @@ public static void ScrollToAddress(ListBox listBox, uint targetAddress) {
141136 }
142137
143138 // Scroll to the target item
144- Dispatcher . UIThread . Post ( ( ) => ScrollToPosition ( listBox , scrollViewer , targetIndex ) , DispatcherPriority . Loaded ) ;
139+ Dispatcher . UIThread . Post ( ( ) => ScrollToPosition ( listBox , scrollViewer , targetIndex ) , DispatcherPriority . Normal ) ;
145140 }
146141 } finally {
147142 // Release the lock
@@ -188,55 +183,9 @@ private static void ScrollToPosition(ListBox listBox, ScrollViewer scrollViewer,
188183 double maxOffset = Math . Max ( 0 , scrollViewer . Extent . Height - viewportHeight ) ;
189184 double finalOffset = Math . Min ( targetOffset , maxOffset ) ;
190185
191- // Use smooth scrolling with configurable parameters
192- AnimateSmoothScroll ( scrollViewer , finalOffset ) ;
193- }
194-
195- private static void AnimateSmoothScroll ( ScrollViewer scrollViewer , double targetOffsetY ) {
196- // Get the current offset
197- double startOffsetY = scrollViewer . Offset . Y ;
198-
199- // If we're already at the target, no need to animate
200- if ( Math . Abs ( startOffsetY - targetOffsetY ) < 0.1 ) {
201- return ;
202- }
203-
204- // Ensure we're on the UI thread
205- if ( ! Dispatcher . UIThread . CheckAccess ( ) ) {
206- Dispatcher . UIThread . Post ( ( ) => AnimateSmoothScroll ( scrollViewer , targetOffsetY ) ) ;
207-
208- return ;
209- }
210-
211- // Use a timer to animate the scroll
212- var timer = new Timer ( 1000.0 / AnimationFramesPerSecond ) ;
213- int currentFrame = 0 ;
214- int totalFrames = ( int ) ( AnimationDuration . TotalMilliseconds / ( 1000.0 / AnimationFramesPerSecond ) ) ;
215-
216- timer . Elapsed += ( _ , _ ) => {
217- // Calculate progress (0.0 to 1.0)
218- currentFrame ++ ;
219- double progress = Math . Min ( 1.0 , currentFrame / ( double ) totalFrames ) ;
220-
221- // Apply easing function
222- double easedProgress = progress < 0.5 ? 4 * progress * progress * progress : 1 - Math . Pow ( - 2 * progress + 2 , 3 ) / 2 ;
223-
224- // Calculate new offset
225- double newOffsetY = startOffsetY + ( targetOffsetY - startOffsetY ) * easedProgress ;
226-
227- // Apply the new offset on the UI thread
228- Dispatcher . UIThread . Post ( ( ) => {
229- scrollViewer . Offset = new Vector ( scrollViewer . Offset . X , newOffsetY ) ;
230- } ) ;
231-
232- // Stop the timer when animation is complete
233- if ( progress >= 1.0 ) {
234- timer . Stop ( ) ;
235- timer . Dispose ( ) ;
236- }
237- } ;
238-
239- // Start the timer
240- timer . Start ( ) ;
186+ // Instant scroll: set the offset directly.
187+ // Smooth animation was removed because each render frame of SelectableTextBlock rows with
188+ // inline Runs is too expensive on Linux (Skia/FreeType), turning a 250ms animation into 20s.
189+ scrollViewer . Offset = new Vector ( scrollViewer . Offset . X , finalOffset ) ;
241190 }
242191}
0 commit comments