diff options
author | Roopesh Chander <roop@roopc.net> | 2019-04-01 22:36:16 +0530 |
---|---|---|
committer | Roopesh Chander <roop@roopc.net> | 2019-04-01 23:07:48 +0530 |
commit | 00432338725f9a2529a6c3f493010d5938f7a863 (patch) | |
tree | 86c109ec14f7ceb29693238f9c2202b72affc2cf | |
parent | macOS: Bring app to front before 'exiting with an active tunnel' alert (diff) | |
download | wireguard-apple-00432338725f9a2529a6c3f493010d5938f7a863.tar.xz wireguard-apple-00432338725f9a2529a6c3f493010d5938f7a863.zip |
macOS: Log view: Fix autoscroll to end of log
Looks like the tableview doesn't know how much to scroll to get to the
end when we use usesAutomaticRowHeights. So we wait for the tableview
to realize its frame has changed and then scroll to the bottom of the
frame explicitly.
Also, we keep track of whether the scroll view is scrolled to the end or
not every time scrolling happens, not just when we add log entries to
the table.
Signed-off-by: Roopesh Chander <roop@roopc.net>
-rw-r--r-- | WireGuard/WireGuard/UI/macOS/ViewController/LogViewController.swift | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/LogViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/LogViewController.swift index ddc8c31..3f3a14b 100644 --- a/WireGuard/WireGuard/UI/macOS/ViewController/LogViewController.swift +++ b/WireGuard/WireGuard/UI/macOS/ViewController/LogViewController.swift @@ -76,6 +76,7 @@ class LogViewController: NSViewController { let logViewHelper: LogViewHelper? var logEntries = [LogViewHelper.LogEntry]() var isFetchingLogEntries = false + var isInScrolledToEndMode = true private var updateLogEntriesTimer: Timer? @@ -103,6 +104,21 @@ class LogViewController: NSViewController { clipView.documentView = tableView scrollView.contentView = clipView + _ = NotificationCenter.default.addObserver(forName: NSView.boundsDidChangeNotification, object: clipView, queue: OperationQueue.main) { [weak self] _ in + guard let self = self else { return } + let lastVisibleRowIndex = self.tableView.row(at: NSPoint(x: 0, y: self.scrollView.contentView.documentVisibleRect.maxY - 1)) + self.isInScrolledToEndMode = lastVisibleRowIndex < 0 || lastVisibleRowIndex == self.logEntries.count - 1 + } + + _ = NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: tableView, queue: OperationQueue.main) { [weak self] _ in + guard let self = self else { return } + if self.isInScrolledToEndMode { + DispatchQueue.main.async { + self.tableView.scroll(NSPoint(x: 0, y: self.tableView.frame.maxY - clipView.documentVisibleRect.height)) + } + } + } + let margin: CGFloat = 20 let internalSpacing: CGFloat = 10 @@ -155,14 +171,9 @@ class LogViewController: NSViewController { self.saveButton.isEnabled = true } guard !fetchedLogEntries.isEmpty else { return } - let numOfEntries = self.logEntries.count - let lastVisibleRowIndex = self.tableView.row(at: NSPoint(x: 0, y: self.scrollView.contentView.documentVisibleRect.maxY - 1)) - let isScrolledToEnd = lastVisibleRowIndex == numOfEntries - 1 + let oldCount = self.logEntries.count self.logEntries.append(contentsOf: fetchedLogEntries) - self.tableView.insertRows(at: IndexSet(integersIn: numOfEntries ..< numOfEntries + fetchedLogEntries.count), withAnimation: .slideDown) - if isScrolledToEnd { - self.tableView.scrollRowToVisible(self.logEntries.count - 1) - } + self.tableView.insertRows(at: IndexSet(integersIn: oldCount ..< oldCount + fetchedLogEntries.count), withAnimation: .slideDown) } } |