@@ -30,19 +30,60 @@ extension TableViewCoordinator {
3030 guard !isSyncingSelection else { return }
3131 guard let tableView = notification. object as? NSTableView else { return }
3232
33+ let previousSelection = selectedRowIndices
3334 let newSelection = Set ( tableView. selectedRowIndexes. map { $0 } )
34- if newSelection != selectedRowIndices {
35+ if newSelection != previousSelection {
3536 selectedRowIndices = newSelection
3637 }
3738
38- if let keyTableView = tableView as? KeyHandlingTableView {
39- if newSelection. isEmpty {
40- keyTableView. focusedRow = - 1
41- keyTableView. focusedColumn = - 1
42- } else if keyTableView. focusedRow < 0 , let firstRow = newSelection. min ( ) {
43- keyTableView. focusedRow = firstRow
44- keyTableView. focusedColumn = 1
45- }
39+ guard let keyTableView = tableView as? KeyHandlingTableView else { return }
40+
41+ let newFocus = resolvedFocus (
42+ previous: previousSelection,
43+ current: newSelection,
44+ existingFocusedRow: keyTableView. focusedRow,
45+ existingFocusedColumn: keyTableView. focusedColumn,
46+ tableView: tableView
47+ )
48+
49+ if keyTableView. focusedRow != newFocus. row {
50+ keyTableView. focusedRow = newFocus. row
51+ }
52+ if keyTableView. focusedColumn != newFocus. column {
53+ keyTableView. focusedColumn = newFocus. column
54+ }
55+ }
56+
57+ private func resolvedFocus(
58+ previous: Set < Int > ,
59+ current: Set < Int > ,
60+ existingFocusedRow: Int ,
61+ existingFocusedColumn: Int ,
62+ tableView: NSTableView
63+ ) -> ( row: Int , column: Int ) {
64+ if current. isEmpty {
65+ return ( - 1 , - 1 )
66+ }
67+
68+ let column = existingFocusedColumn >= 1 ? existingFocusedColumn : 1
69+ let added = current. subtracting ( previous)
70+
71+ if let tip = added. max ( ) {
72+ return ( tip, column)
73+ }
74+
75+ let removed = previous. subtracting ( current)
76+ if let lostTip = removed. max ( ) ,
77+ let currentMax = current. max ( ) ,
78+ let currentMin = current. min ( ) {
79+ let row = lostTip > currentMax ? currentMax : currentMin
80+ return ( row, column)
4681 }
82+
83+ if existingFocusedRow >= 0 , current. contains ( existingFocusedRow) {
84+ return ( existingFocusedRow, column)
85+ }
86+
87+ return ( current. min ( ) ?? - 1 , column)
4788 }
4889}
0 commit comments