From 288f203beab47f85d40a2766b08d2443ee13fb83 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 22 Dec 2017 11:13:20 -0800 Subject: [PATCH] Add setPointAndSizeAdjustingForScreen for placing windows without (usually) going offscreen. Use it for positioning the Keyboard Shortcuts window. Fix #263. --- Evergreen/AppDelegate.swift | 12 ++++---- .../RSCore/RSCore/NSWindow-Extensions.swift | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/Evergreen/AppDelegate.swift b/Evergreen/AppDelegate.swift index 5fe91725b..9f954befd 100644 --- a/Evergreen/AppDelegate.swift +++ b/Evergreen/AppDelegate.swift @@ -308,13 +308,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, let htmlFile = Bundle(for: type(of: self)).path(forResource: "KeyboardShortcuts", ofType: "html")! keyboardShortcutsWindowController?.displayContents(of: htmlFile) - if let window = keyboardShortcutsWindowController?.window, let screen = window.screen { - let width: CGFloat = 620.0 - let height: CGFloat = 1024.0 - let insetX: CGFloat = 128.0 - let insetY: CGFloat = 64.0 - window.setContentSize(NSSize(width: width, height: height)) - window.setFrameTopLeftPoint(NSPoint(x: insetX, y: screen.visibleFrame.maxY - insetY)) + if let window = keyboardShortcutsWindowController?.window { + let point = NSPoint(x: 128, y: 64) + let size = NSSize(width: 620, height: 1000) + let minSize = NSSize(width: 400, height: 400) + window.setPointAndSizeAdjustingForScreen(point: point, size: size, minimumSize: minSize) } } diff --git a/Frameworks/RSCore/RSCore/NSWindow-Extensions.swift b/Frameworks/RSCore/RSCore/NSWindow-Extensions.swift index edd5d01ce..400f00ddf 100755 --- a/Frameworks/RSCore/RSCore/NSWindow-Extensions.swift +++ b/Frameworks/RSCore/RSCore/NSWindow-Extensions.swift @@ -17,4 +17,32 @@ public extension NSWindow { } makeFirstResponder(responder) } + + public func setPointAndSizeAdjustingForScreen(point: NSPoint, size: NSSize, minimumSize: NSSize) { + + // point.y specifices from the *top* of the screen, even though screen coordinates work from the bottom up. This is for convenience. + // The eventual size may be smaller than requested, since the screen may be small, but not smaller than minimumSize. + + guard let screenFrame = screen?.visibleFrame else { + return + } + + let paddingFromScreenEdge: CGFloat = 8.0 + let x = point.x + let y = screenFrame.maxY - point.y + + var width = size.width + var height = size.height + + if x + width > screenFrame.maxX { + width = max((screenFrame.maxX - x) - paddingFromScreenEdge, minimumSize.width) + } + if y - height < 0.0 { + height = max((screenFrame.maxY - point.y) - paddingFromScreenEdge, minimumSize.height) + } + + let frame = NSRect(x: x, y: y, width: width, height: height) + setFrame(frame, display: true) + setFrameTopLeftPoint(frame.origin) + } }