perf: faster arrow key navigation in torrent list (#8315) (#8323)

* perf: when selection changes, only update the rows whose selection changed

previously we were updating all rows

* perf: coalesce pending reloads in TorrentTableView

* refactor: return a copy rather thabn a mutable index

* refactor: move the assignment out of the if statement

* make symmetricDifference an NSIndexSet method
This commit is contained in:
Charles Kerr
2026-02-02 07:08:01 -06:00
committed by GitHub
parent 5f8755bd68
commit 1dd096e77f

View File

@@ -28,6 +28,29 @@ static CGFloat const kErrorImageSize = 20.0;
static NSTimeInterval const kToggleProgressSeconds = 0.175;
@interface NSIndexSet (Transmission)
- (NSIndexSet*)symmetricDifference:(NSIndexSet*)otherSet;
@end
@implementation NSIndexSet (Transmission)
- (NSIndexSet*)symmetricDifference:(NSIndexSet*)otherSet
{
NSMutableIndexSet* result = [self mutableCopy];
[result addIndexes:otherSet];
[self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL*) {
if ([otherSet containsIndex:idx])
{
[result removeIndex:idx];
}
}];
return [result copy];
}
@end
@interface TorrentTableView ()
@property(nonatomic) IBOutlet Controller* fController;
@@ -49,6 +72,8 @@ static NSTimeInterval const kToggleProgressSeconds = 0.175;
@property(nonatomic) NSDictionary* fHoverEventDict;
@property(nonatomic) NSMutableIndexSet* fPendingSelectionReloadRows;
@end
@implementation TorrentTableView
@@ -430,8 +455,32 @@ static NSTimeInterval const kToggleProgressSeconds = 0.175;
- (void)outlineViewSelectionDidChange:(NSNotification*)notification
{
self.fSelectedRowIndexes = self.selectedRowIndexes;
[self reloadVisibleRows];
NSIndexSet* oldSelection = self.fSelectedRowIndexes ?: [NSIndexSet indexSet];
NSIndexSet* newSelection = self.selectedRowIndexes;
self.fSelectedRowIndexes = newSelection;
NSIndexSet* changedRows = [oldSelection symmetricDifference:newSelection];
if (changedRows.count > 0)
{
if (!self.fPendingSelectionReloadRows)
{
self.fPendingSelectionReloadRows = [[NSMutableIndexSet alloc] init];
[self performSelector:@selector(flushSelectionReload) withObject:nil afterDelay:0 inModes:@[ NSRunLoopCommonModes ]];
}
[self.fPendingSelectionReloadRows addIndexes:changedRows];
}
}
- (void)flushSelectionReload
{
NSMutableIndexSet* rows = self.fPendingSelectionReloadRows;
self.fPendingSelectionReloadRows = nil;
if (rows.count > 0)
{
[self reloadDataForRowIndexes:rows columnIndexes:[NSIndexSet indexSetWithIndex:0]];
}
}
- (void)outlineViewItemDidExpand:(NSNotification*)notification