diff --git a/src/ui/main-window/TilesPanel.swift b/src/ui/main-window/TilesPanel.swift index dbf9b576..6a3dcf26 100644 --- a/src/ui/main-window/TilesPanel.swift +++ b/src/ui/main-window/TilesPanel.swift @@ -5,6 +5,9 @@ class TilesPanel: NSPanel { static var maxPossibleThumbnailSize = NSSize.zero static var maxPossibleAppIconSize = NSSize.zero static var shared: TilesPanel! + private var frozenTopCenter: NSPoint? + private var highWaterWidth: CGFloat = 0 + private var highWaterHeight: CGFloat = 0 convenience init() { self.init(contentRect: .zero, styleMask: .nonactivatingPanel, backing: .buffered, defer: false) @@ -40,12 +43,37 @@ class TilesPanel: NSPanel { guard App.appIsBeingUsed else { return } setContentSize(TilesView.contentView.frame.size) guard App.appIsBeingUsed else { return } - NSScreen.preferred.repositionPanel(self) + repositionOrFreeze() } // prevent further AppKit work TilesView.clearNeedsLayout() } + private func repositionOrFreeze() { + let size = frame.size + guard TilesView.isSearchModeOn else { + NSScreen.preferred.repositionPanel(self) + resetFrozenPosition() + return + } + if size.width > highWaterWidth || size.height > highWaterHeight { + NSScreen.preferred.repositionPanel(self) + highWaterWidth = size.width + highWaterHeight = size.height + frozenTopCenter = NSPoint(x: frame.midX, y: frame.maxY) + } else if let topCenter = frozenTopCenter { + let x = topCenter.x - size.width * 0.5 + let y = topCenter.y - size.height + setFrameOrigin(NSPoint(x: x, y: y)) + } + } + + func resetFrozenPosition() { + frozenTopCenter = nil + highWaterWidth = 0 + highWaterHeight = 0 + } + override func orderOut(_ sender: Any?) { TilesView.clearNeedsLayout() if Preferences.fadeOutAnimation { diff --git a/src/ui/main-window/TilesView.swift b/src/ui/main-window/TilesView.swift index 7a65dc11..51cecca4 100644 --- a/src/ui/main-window/TilesView.swift +++ b/src/ui/main-window/TilesView.swift @@ -53,6 +53,7 @@ class TilesView { static func endSearchSession() { searchField.stringValue = "" Windows.updateSearchQuery("") + TilesPanel.shared.resetFrozenPosition() searchMode = .off updateSearchFieldEditability() } @@ -69,6 +70,7 @@ class TilesView { static func disableSearchMode() { guard searchMode != .off else { return } + TilesPanel.shared.resetFrozenPosition() searchMode = .off updateSearchFieldEditability() searchField.stringValue = "" @@ -496,8 +498,10 @@ class TilesView { scrollView.contentView.frame.size = scrollView.frame.size searchField.isHidden = searchMode == .off if searchMode != .off { - searchField.frame.size = NSSize(width: TilesView.thumbnailsWidth, height: searchBarHeight) - searchField.frame.origin = CGPoint(x: originX, y: frameHeight - Appearance.windowPadding - searchBarHeight) + let searchWidth = minSearchWidth + searchField.frame.size = NSSize(width: searchWidth, height: searchBarHeight) + let searchX = originX + (TilesView.thumbnailsWidth - searchWidth) * 0.5 + searchField.frame.origin = CGPoint(x: searchX, y: frameHeight - Appearance.windowPadding - searchBarHeight) } if App.shared.userInterfaceLayoutDirection == .rightToLeft { let croppedWidth = max(0, TilesView.thumbnailsWidth - maxX)