Upgrade to Swift 5.1

This commit is contained in:
Sindre Sorhus 2019-09-11 21:34:41 +07:00
parent 0bd6ad734f
commit 250284d86c
9 changed files with 151 additions and 126 deletions

View file

@ -13,6 +13,8 @@ whitelist_rules:
- comma - comma
- compiler_protocol_init - compiler_protocol_init
- conditional_returns_on_newline - conditional_returns_on_newline
- contains_over_filter_count
- contains_over_filter_is_empty
- contains_over_first_not_nil - contains_over_first_not_nil
- control_statement - control_statement
- deployment_target - deployment_target
@ -21,8 +23,10 @@ whitelist_rules:
- discouraged_object_literal - discouraged_object_literal
- discouraged_optional_boolean - discouraged_optional_boolean
- discouraged_optional_collection - discouraged_optional_collection
- duplicate_enum_cases
- duplicate_imports - duplicate_imports
- dynamic_inline - dynamic_inline
- empty_collection_literal
- empty_count - empty_count
- empty_enum_arguments - empty_enum_arguments
- empty_parameters - empty_parameters
@ -48,6 +52,7 @@ whitelist_rules:
- legacy_constant - legacy_constant
- legacy_constructor - legacy_constructor
- legacy_hashing - legacy_hashing
- legacy_multiple
- legacy_nsgeometry_functions - legacy_nsgeometry_functions
- legacy_random - legacy_random
- literal_expression_end_indentation - literal_expression_end_indentation
@ -63,7 +68,9 @@ whitelist_rules:
- nimble_operator - nimble_operator
- no_extension_access_modifier - no_extension_access_modifier
- no_fallthrough_only - no_fallthrough_only
- no_space_in_method_call
- notification_center_detachment - notification_center_detachment
- nsobject_prefer_isequal
- number_separator - number_separator
- object_literal - object_literal
- opening_brace - opening_brace
@ -76,6 +83,8 @@ whitelist_rules:
- private_unit_test - private_unit_test
- prohibited_super_call - prohibited_super_call
- protocol_property_accessors_order - protocol_property_accessors_order
- reduce_boolean
- reduce_into
- redundant_discardable_let - redundant_discardable_let
- redundant_nil_coalescing - redundant_nil_coalescing
- redundant_objc_attribute - redundant_objc_attribute
@ -95,6 +104,7 @@ whitelist_rules:
- switch_case_alignment - switch_case_alignment
- switch_case_on_newline - switch_case_on_newline
- syntactic_sugar - syntactic_sugar
- todo
- toggle_bool - toggle_bool
- trailing_closure - trailing_closure
- trailing_comma - trailing_comma
@ -105,7 +115,9 @@ whitelist_rules:
- unavailable_function - unavailable_function
- unneeded_break_in_switch - unneeded_break_in_switch
- unneeded_parentheses_in_closure_argument - unneeded_parentheses_in_closure_argument
- unowned_variable_capture
- untyped_error_in_catch - untyped_error_in_catch
- unused_capture_list
- unused_closure_parameter - unused_closure_parameter
- unused_control_flow_label - unused_control_flow_label
- unused_enumerated - unused_enumerated
@ -117,15 +129,13 @@ whitelist_rules:
- vertical_whitespace_closing_braces - vertical_whitespace_closing_braces
- vertical_whitespace_opening_braces - vertical_whitespace_opening_braces
- void_return - void_return
- weak_computed_property
- weak_delegate - weak_delegate
- xct_specific_matcher - xct_specific_matcher
- xctfail_message - xctfail_message
- yoda_condition - yoda_condition
- todo
analyzer_rules: analyzer_rules:
- unused_declaration
- unused_import - unused_import
- unused_private_declaration
force_cast: warning force_cast: warning
force_unwrapping: warning force_unwrapping: warning
number_separator: number_separator:
@ -134,6 +144,18 @@ object_literal:
image_literal: false image_literal: false
discouraged_object_literal: discouraged_object_literal:
color_literal: false color_literal: false
type_contents_order:
order:
- case
- [type_alias, associated_type, subtype]
- type_property
- type_method
- ib_outlet
- [ib_inspectable, instance_property]
- initializer
- subscript
- view_life_cycle_method
- [ib_action, other_method]
identifier_name: identifier_name:
max_length: max_length:
warning: 100 warning: 100

View file

@ -1,2 +1,2 @@
github "sindresorhus/Defaults" "v2.0.0" github "sindresorhus/Defaults" "v3.0.0"
github "sparkle-project/Sparkle" "1.21.3" github "sparkle-project/Sparkle" "1.21.3"

View file

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 51; objectVersion = 52;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
@ -163,7 +163,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0820; LastSwiftUpdateCheck = 0820;
LastUpgradeCheck = 0930; LastUpgradeCheck = 1100;
ORGANIZATIONNAME = "Sindre Sorhus"; ORGANIZATIONNAME = "Sindre Sorhus";
TargetAttributes = { TargetAttributes = {
E3FE2CBE1E726CE800C6713A = { E3FE2CBE1E726CE800C6713A = {
@ -180,10 +180,11 @@
}; };
}; };
buildConfigurationList = E3FE2CBA1E726CE800C6713A /* Build configuration list for PBXProject "Touch Bar Simulator" */; buildConfigurationList = E3FE2CBA1E726CE800C6713A /* Build configuration list for PBXProject "Touch Bar Simulator" */;
compatibilityVersion = "Xcode 10.0"; compatibilityVersion = "Xcode 11.0";
developmentRegion = en; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
en,
Base, Base,
); );
mainGroup = E3FE2CB61E726CE800C6713A; mainGroup = E3FE2CB61E726CE800C6713A;
@ -296,13 +297,14 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14; MACOSX_DEPLOYMENT_TARGET = 10.14.4;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_COMPILATION_MODE = singlefile; SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VALID_ARCHS = x86_64; VALID_ARCHS = x86_64;
}; };
name = Debug; name = Debug;
@ -349,11 +351,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14; MACOSX_DEPLOYMENT_TARGET = 10.14.4;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
VALID_ARCHS = x86_64; VALID_ARCHS = x86_64;
}; };
name = Release; name = Release;
@ -366,6 +369,7 @@
CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = YG56YK5RN5; DEVELOPMENT_TEAM = YG56YK5RN5;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)", "$(PROJECT_DIR)",
@ -404,6 +408,7 @@
CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = YG56YK5RN5; DEVELOPMENT_TEAM = YG56YK5RN5;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)", "$(PROJECT_DIR)",

View file

@ -4,12 +4,14 @@ import Defaults
final class AppDelegate: NSObject, NSApplicationDelegate { final class AppDelegate: NSObject, NSApplicationDelegate {
lazy var window = with(TouchBarWindow()) { lazy var window = with(TouchBarWindow()) {
$0.alphaValue = CGFloat(defaults[.windowTransparency]) $0.alphaValue = CGFloat(Defaults[.windowTransparency])
$0.setUp() $0.setUp()
} }
lazy var statusItem = with(NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)) { lazy var statusItem = with(NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)) {
$0.menu = with(NSMenu()) { $0.delegate = self } $0.menu = with(NSMenu()) {
$0.delegate = self
}
$0.button!.image = NSImage(named: "MenuBarIcon") $0.button!.image = NSImage(named: "MenuBarIcon")
$0.button!.toolTip = "Right-click or option-click for menu" $0.button!.toolTip = "Right-click or option-click for menu"
} }
@ -95,7 +97,7 @@ extension AppDelegate: NSMenuDelegate {
} }
private func statusItemShouldShowMenu() -> Bool { private func statusItemShouldShowMenu() -> Bool {
return !NSApp.isLeftMouseDown || NSApp.isOptionKeyDown !NSApp.isLeftMouseDown || NSApp.isOptionKeyDown
} }
func menuNeedsUpdate(_ menu: NSMenu) { func menuNeedsUpdate(_ menu: NSMenu) {
@ -111,7 +113,7 @@ extension AppDelegate: NSMenuDelegate {
private func statusItemButtonClicked() { private func statusItemButtonClicked() {
// When the user explicitly wants the Touch Bar to appear then `dockBahavior` should be disabled. // When the user explicitly wants the Touch Bar to appear then `dockBahavior` should be disabled.
// This is also how the macOS Dock behaves. // This is also how the macOS Dock behaves.
defaults[.dockBehavior] = false Defaults[.dockBehavior] = false
toggleView() toggleView()

View file

@ -5,7 +5,7 @@ import Defaults
extension Defaults { extension Defaults {
@discardableResult @discardableResult
func observe<T: Codable, Weak: AnyObject>( static func observe<T: Codable, Weak: AnyObject>(
_ key: Key<T>, _ key: Key<T>,
tiedToLifetimeOf weaklyHeldObject: Weak, tiedToLifetimeOf weaklyHeldObject: Weak,
options: NSKeyValueObservingOptions = [.initial, .new, .old], options: NSKeyValueObservingOptions = [.initial, .new, .old],
@ -40,17 +40,17 @@ extension NSMenuItem {
*/ */
func bindState(to key: Defaults.Key<Bool>) -> Self { func bindState(to key: Defaults.Key<Bool>) -> Self {
addAction { _ in addAction { _ in
defaults[key].toggle() Defaults[key].toggle()
} }
defaults.observe(key, tiedToLifetimeOf: self) { [unowned self] change in Defaults.observe(key, tiedToLifetimeOf: self) { [unowned self] change in
self.isChecked = change.newValue self.isChecked = change.newValue
} }
return self return self
} }
// TODO: The doc comments here are out of date // TODO: The doc comments here are out of date.
/** /**
Adds an action to this menu item that sets the value of `key` in the Adds an action to this menu item that sets the value of `key` in the
defaults system to `value`, and initializes this item's state based on defaults system to `value`, and initializes this item's state based on
@ -66,10 +66,10 @@ extension NSMenuItem {
*/ */
func bindChecked<Value: Equatable>(to key: Defaults.Key<Value>, value: Value) -> Self { func bindChecked<Value: Equatable>(to key: Defaults.Key<Value>, value: Value) -> Self {
addAction { _ in addAction { _ in
defaults[key] = value Defaults[key] = value
} }
defaults.observe(key, tiedToLifetimeOf: self) { [unowned self] change in Defaults.observe(key, tiedToLifetimeOf: self) { [unowned self] change in
self.isChecked = (change.newValue == value) self.isChecked = (change.newValue == value)
} }
@ -91,10 +91,10 @@ extension NSSlider {
*/ */
func bindDoubleValue(to key: Defaults.Key<Double>) -> Self { func bindDoubleValue(to key: Defaults.Key<Double>) -> Self {
addAction { sender in addAction { sender in
defaults[key] = sender.doubleValue Defaults[key] = sender.doubleValue
} }
defaults.observe(key, tiedToLifetimeOf: self) { [unowned self] change in Defaults.observe(key, tiedToLifetimeOf: self) { [unowned self] change in
self.doubleValue = change.newValue self.doubleValue = change.newValue
} }

View file

@ -22,12 +22,12 @@ private final class ToolbarSliderCell: NSSliderCell {
var frame = knobRect.insetBy(dx: 0, dy: 6.5) var frame = knobRect.insetBy(dx: 0, dy: 6.5)
if let shadow = self.shadow { if let shadow = self.shadow {
// Make room on either side of the view for the shadow to spill into, // Make room on either side of the view for the shadow to spill into,
// rather than clip on the edges // rather than clip on the edges.
frame.origin.x *= ((barRect.width - shadow.shadowBlurRadius * 2) / barRect.width) frame.origin.x *= ((barRect.width - shadow.shadowBlurRadius * 2) / barRect.width)
frame.origin.x += shadow.shadowBlurRadius frame.origin.x += shadow.shadowBlurRadius
} }
// Make the slider grey // Make the slider grey.
var greySliderFrame = barRect var greySliderFrame = barRect
greySliderFrame.origin.x -= 1 greySliderFrame.origin.x -= 1
greySliderFrame.origin.y = barRect.origin.y + 1 greySliderFrame.origin.y = barRect.origin.y + 1
@ -46,7 +46,7 @@ private final class ToolbarSliderCell: NSSliderCell {
fillColor.set() fillColor.set()
path.fill() path.fill()
// Border should not draw a shadow // Border should not draw a shadow.
NSShadow().set() NSShadow().set()
// Border // Border
@ -81,7 +81,7 @@ extension NSSlider {
// itself brighter for some reason. // itself brighter for some reason.
func alwaysRedisplayOnValueChanged() -> Self { func alwaysRedisplayOnValueChanged() -> Self {
addAction { sender in addAction { sender in
if (defaults[.windowTransparency] - sender.doubleValue) != 0 { if (Defaults[.windowTransparency] - sender.doubleValue) != 0 {
sender.needsDisplay = true sender.needsDisplay = true
} }
} }

View file

@ -20,9 +20,7 @@ final class TouchBarView: NSView {
stop() stop()
} }
override func acceptsFirstMouse(for event: NSEvent?) -> Bool { override func acceptsFirstMouse(for event: NSEvent?) -> Bool { true }
return true
}
func start() { func start() {
stream = SLSDFRDisplayStreamCreate(0, .main) { status, _, frameSurface, _ in stream = SLSDFRDisplayStreamCreate(0, .main) { status, _, frameSurface, _ in
@ -38,7 +36,7 @@ final class TouchBarView: NSView {
} }
func stop() { func stop() {
guard let stream = stream else { guard let stream = self.stream else {
return return
} }

View file

@ -21,7 +21,7 @@ final class TouchBarWindow: NSPanel {
func reposition(window: NSWindow) { func reposition(window: NSWindow) {
switch self { switch self {
case .floating: case .floating:
if let prevPosition = defaults[.lastFloatingPosition] { if let prevPosition = Defaults[.lastFloatingPosition] {
window.setFrameOrigin(prevPosition) window.setFrameOrigin(prevPosition)
} }
case .dockedToTop: case .dockedToTop:
@ -32,18 +32,22 @@ final class TouchBarWindow: NSPanel {
} }
} }
override var canBecomeMain: Bool { false }
override var canBecomeKey: Bool { false }
var docking: Docking = .floating { var docking: Docking = .floating {
didSet { didSet {
if oldValue == .floating && docking != .floating { if oldValue == .floating && docking != .floating {
defaults[.lastFloatingPosition] = frame.origin Defaults[.lastFloatingPosition] = frame.origin
} }
if self.docking == .floating { if docking == .floating {
dockBehavior = false dockBehavior = false
} }
// Prevent the Touch Bar from momentarily becoming visible. // Prevent the Touch Bar from momentarily becoming visible.
if self.docking == .floating || !dockBehavior { if docking == .floating || !dockBehavior {
stopDockBehaviorTimer() stopDockBehaviorTimer()
docking.dock(window: self) docking.dock(window: self)
setIsVisible(true) setIsVisible(true)
@ -51,7 +55,7 @@ final class TouchBarWindow: NSPanel {
return return
} }
// When docking is set to `dockedToTop` or `dockedToBottom` dockBehavior should start // When docking is set to `dockedToTop` or `dockedToBottom` dockBehavior should start.
if dockBehavior { if dockBehavior {
setIsVisible(false) setIsVisible(false)
docking.dock(window: self) docking.dock(window: self)
@ -80,7 +84,14 @@ final class TouchBarWindow: NSPanel {
func startDockBehaviorTimer() { func startDockBehaviorTimer() {
stopDockBehaviorTimer() stopDockBehaviorTimer()
dockBehaviorTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(handleDockBehavior), userInfo: nil, repeats: true)
dockBehaviorTimer = Timer.scheduledTimer(
timeInterval: 0.1,
target: self,
selector: #selector(handleDockBehavior),
userInfo: nil,
repeats: true
)
} }
func stopDockBehaviorTimer() { func stopDockBehaviorTimer() {
@ -88,23 +99,23 @@ final class TouchBarWindow: NSPanel {
dockBehaviorTimer = Timer() dockBehaviorTimer = Timer()
} }
var dockBehavior: Bool = defaults[.dockBehavior] { var dockBehavior: Bool = Defaults[.dockBehavior] {
didSet { didSet {
defaults[.dockBehavior] = self.dockBehavior Defaults[.dockBehavior] = dockBehavior
if self.docking == .dockedToBottom || self.docking == .dockedToTop { if docking == .dockedToBottom || docking == .dockedToTop {
defaults[.lastWindowDockingWithDockBehavior] = self.docking Defaults[.lastWindowDockingWithDockBehavior] = docking
} }
if dockBehavior { if dockBehavior {
if self.docking == .dockedToBottom || self.docking == .dockedToTop { if docking == .dockedToBottom || docking == .dockedToTop {
self.docking = defaults[.lastWindowDockingWithDockBehavior] docking = Defaults[.lastWindowDockingWithDockBehavior]
startDockBehaviorTimer() startDockBehaviorTimer()
} else if self.docking == .floating { } else if docking == .floating {
defaults[.windowDocking] = defaults[.lastWindowDockingWithDockBehavior] Defaults[.windowDocking] = Defaults[.lastWindowDockingWithDockBehavior]
} }
} else { } else {
stopDockBehaviorTimer() stopDockBehaviorTimer()
self.setIsVisible(true) setIsVisible(true)
} }
} }
} }
@ -119,25 +130,25 @@ final class TouchBarWindow: NSPanel {
} }
var detectionRect: NSRect = .zero var detectionRect: NSRect = .zero
if self.docking == .dockedToBottom { if docking == .dockedToBottom {
if self.isVisible { if isVisible {
detectionRect = CGRect( detectionRect = CGRect(
x: 0, x: 0,
y: 0, y: 0,
width: visibleFrame.width, width: visibleFrame.width,
height: self.frame.height + (screenFrame.height - visibleFrame.height - NSStatusBar.system.thickness) height: frame.height + (screenFrame.height - visibleFrame.height - NSStatusBar.system.thickness)
) )
} else { } else {
detectionRect = CGRect(x: 0, y: 0, width: visibleFrame.width, height: 1) detectionRect = CGRect(x: 0, y: 0, width: visibleFrame.width, height: 1)
} }
} else if self.docking == .dockedToTop { } else if docking == .dockedToTop {
if self.isVisible { if isVisible {
detectionRect = CGRect( detectionRect = CGRect(
x: 0, x: 0,
// Without `+ 1`, the Touch Bar would glitch (toggling rapidly). // Without `+ 1`, the Touch Bar would glitch (toggling rapidly).
y: screenFrame.height - self.frame.height - NSStatusBar.system.thickness + 1, y: screenFrame.height - frame.height - NSStatusBar.system.thickness + 1,
width: visibleFrame.width, width: visibleFrame.width,
height: self.frame.height + NSStatusBar.system.thickness) height: frame.height + NSStatusBar.system.thickness)
} else { } else {
detectionRect = CGRect( detectionRect = CGRect(
x: 0, x: 0,
@ -167,7 +178,7 @@ final class TouchBarWindow: NSPanel {
showTouchBarTimer = Timer() showTouchBarTimer = Timer()
showAnimationDidRun = false showAnimationDidRun = false
if self.isVisible && !dismissAnimationDidRun { if isVisible && !dismissAnimationDidRun {
performActionWithAnimation(action: .dismiss) performActionWithAnimation(action: .dismiss)
dismissAnimationDidRun = true dismissAnimationDidRun = true
} }
@ -175,10 +186,10 @@ final class TouchBarWindow: NSPanel {
} }
func moveToStartPoint() { func moveToStartPoint() {
if self.docking == .dockedToTop { if docking == .dockedToTop {
self.moveTo(x: .center, y: .top) moveTo(x: .center, y: .top)
} else if self.docking == .dockedToBottom { } else if docking == .dockedToBottom {
self.moveTo(x: .center, y: .bottom) moveTo(x: .center, y: .bottom)
} }
} }
@ -187,25 +198,25 @@ final class TouchBarWindow: NSPanel {
func showTouchBarWithAnimation() { func showTouchBarWithAnimation() {
guard guard
self.docking == .dockedToTop || docking == .dockedToTop ||
self.docking == .dockedToBottom docking == .dockedToBottom
else { else {
return return
} }
var startOrigin: CGPoint! var startOrigin: CGPoint!
let endFrame = self.frame let endFrame = frame
self.setIsVisible(true) setIsVisible(true)
if self.docking == .dockedToTop { if docking == .dockedToTop {
startOrigin = CGPoint(x: self.frame.origin.x, y: self.frame.origin.y + self.frame.height) startOrigin = CGPoint(x: frame.origin.x, y: frame.origin.y + frame.height)
} else if self.docking == .dockedToBottom { } else if docking == .dockedToBottom {
startOrigin = CGPoint(x: self.frame.origin.x, y: 0 - self.frame.height) startOrigin = CGPoint(x: frame.origin.x, y: 0 - frame.height)
} }
self.setFrameOrigin(startOrigin) setFrameOrigin(startOrigin)
NSAnimationContext.runAnimationGroup({ context in NSAnimationContext.runAnimationGroup({ context in
context.duration = TimeInterval(0.3) context.duration = TimeInterval(0.3)
self.animator().setFrame(endFrame, display: false, animate: true) animator().setFrame(endFrame, display: false, animate: true)
}, completionHandler: { }, completionHandler: {
self.moveToStartPoint() self.moveToStartPoint()
}) })
@ -213,22 +224,22 @@ final class TouchBarWindow: NSPanel {
func dismissTouchBarWithAnimation() { func dismissTouchBarWithAnimation() {
guard guard
self.docking == .dockedToTop || docking == .dockedToTop ||
self.docking == .dockedToBottom docking == .dockedToBottom
else { else {
return return
} }
var endFrame = self.frame var endFrame = frame
if self.docking == .dockedToTop { if docking == .dockedToTop {
endFrame.origin = NSPoint(x: self.frame.origin.x, y: self.frame.origin.y + self.frame.height + NSStatusBar.system.thickness) endFrame.origin = NSPoint(x: frame.origin.x, y: frame.origin.y + frame.height + NSStatusBar.system.thickness)
} else if self.docking == .dockedToBottom { } else if docking == .dockedToBottom {
endFrame.origin = NSPoint(x: self.frame.origin.x, y: 0 - self.frame.height) endFrame.origin = NSPoint(x: frame.origin.x, y: 0 - frame.height)
} }
NSAnimationContext.runAnimationGroup({ context in NSAnimationContext.runAnimationGroup({ context in
context.duration = TimeInterval(0.3) context.duration = TimeInterval(0.3)
self.animator().setFrame(endFrame, display: false, animate: true) animator().setFrame(endFrame, display: false, animate: true)
}, completionHandler: { }, completionHandler: {
self.setIsVisible(false) self.setIsVisible(false)
self.moveToStartPoint() self.moveToStartPoint()
@ -237,38 +248,41 @@ final class TouchBarWindow: NSPanel {
func performActionWithAnimation(action: TouchBarAction) { func performActionWithAnimation(action: TouchBarAction) {
guard guard
self.docking == .dockedToTop || docking == .dockedToTop ||
self.docking == .dockedToBottom docking == .dockedToBottom
else { else {
return return
} }
var startOrigin: CGPoint! var startOrigin: CGPoint!
var endFrame = self.frame var endFrame = frame
if action == .show { if action == .show {
self.setIsVisible(true) setIsVisible(true)
if self.docking == .dockedToTop {
startOrigin = CGPoint(x: self.frame.origin.x, y: self.frame.origin.y + self.frame.height) if docking == .dockedToTop {
} else if self.docking == .dockedToBottom { startOrigin = CGPoint(x: frame.origin.x, y: frame.origin.y + frame.height)
startOrigin = CGPoint(x: self.frame.origin.x, y: 0 - self.frame.height) } else if docking == .dockedToBottom {
startOrigin = CGPoint(x: frame.origin.x, y: 0 - frame.height)
} }
self.setFrameOrigin(startOrigin)
setFrameOrigin(startOrigin)
} else if action == .dismiss { } else if action == .dismiss {
if self.docking == .dockedToTop { if docking == .dockedToTop {
endFrame.origin = NSPoint(x: self.frame.origin.x, y: self.frame.origin.y + self.frame.height + NSStatusBar.system.thickness) endFrame.origin = NSPoint(x: frame.origin.x, y: frame.origin.y + frame.height + NSStatusBar.system.thickness)
} else if self.docking == .dockedToBottom { } else if docking == .dockedToBottom {
endFrame.origin = NSPoint(x: self.frame.origin.x, y: 0 - self.frame.height) endFrame.origin = NSPoint(x: frame.origin.x, y: 0 - frame.height)
} }
} }
NSAnimationContext.runAnimationGroup({ context in NSAnimationContext.runAnimationGroup({ context in
context.duration = TimeInterval(0.3) context.duration = TimeInterval(0.3)
self.animator().setFrame(endFrame, display: false, animate: true) animator().setFrame(endFrame, display: false, animate: true)
}, completionHandler: { }, completionHandler: {
if action == .dismiss { if action == .dismiss {
self.setIsVisible(false) self.setIsVisible(false)
} }
self.moveToStartPoint() self.moveToStartPoint()
}) })
} }
@ -316,14 +330,6 @@ final class TouchBarWindow: NSPanel {
return slider return slider
} }
override var canBecomeMain: Bool {
return false
}
override var canBecomeKey: Bool {
return false
}
private var defaultsObservations: [DefaultsObservation] = [] private var defaultsObservations: [DefaultsObservation] = []
func setUp() { func setUp() {
@ -337,21 +343,21 @@ final class TouchBarWindow: NSPanel {
view.addSubview(touchBarView) view.addSubview(touchBarView)
// TODO: These could use the `observe` method with `tiedToLifetimeOf` so we don't have to manually invalidate them. // TODO: These could use the `observe` method with `tiedToLifetimeOf` so we don't have to manually invalidate them.
defaultsObservations.append(defaults.observe(.windowTransparency) { change in defaultsObservations.append(Defaults.observe(.windowTransparency) { change in
self.alphaValue = CGFloat(change.newValue) self.alphaValue = CGFloat(change.newValue)
}) })
defaultsObservations.append(defaults.observe(.windowDocking) { change in defaultsObservations.append(Defaults.observe(.windowDocking) { change in
self.docking = change.newValue self.docking = change.newValue
}) })
// TODO: We could maybe simplify this by creating another `Default` extension to bind a default to a KeyPath: // TODO: We could maybe simplify this by creating another `Default` extension to bind a default to a KeyPath:
// `defaults.bind(.showOnAllDesktops, to: \.showOnAllDesktop)` // `defaults.bind(.showOnAllDesktops, to: \.showOnAllDesktop)`
defaultsObservations.append(defaults.observe(.showOnAllDesktops) { change in defaultsObservations.append(Defaults.observe(.showOnAllDesktops) { change in
self.showOnAllDesktops = change.newValue self.showOnAllDesktops = change.newValue
}) })
defaultsObservations.append(defaults.observe(.dockBehavior) { change in defaultsObservations.append(Defaults.observe(.dockBehavior) { change in
self.dockBehavior = change.newValue self.dockBehavior = change.newValue
}) })
@ -388,8 +394,8 @@ final class TouchBarWindow: NSPanel {
backing: .buffered, backing: .buffered,
defer: false defer: false
) )
self.level = .assistiveTechHigh
self.level = .assistiveTechHigh
self._setPreventsActivation(true) self._setPreventsActivation(true)
self.isRestorable = true self.isRestorable = true
self.hidesOnDeactivate = false self.hidesOnDeactivate = false

View file

@ -1,7 +1,7 @@
import Cocoa import Cocoa
/** /**
Convenience function for initializing an object and modifying its properties Convenience function for initializing an object and modifying its properties.
``` ```
let label = with(NSTextField()) { let label = with(NSTextField()) {
@ -19,8 +19,8 @@ func with<T>(_ item: T, update: (inout T) throws -> Void) rethrows -> T {
} }
extension CGRect { extension CGRect {
func adding(padding: Double) -> CGRect { func adding(padding: Double) -> Self {
return CGRect( Self(
x: origin.x - CGFloat(padding), x: origin.x - CGFloat(padding),
y: origin.y - CGFloat(padding), y: origin.y - CGFloat(padding),
width: width + CGFloat(padding * 2), width: width + CGFloat(padding * 2),
@ -29,10 +29,10 @@ extension CGRect {
} }
/** /**
Returns a CGRect where `self` is centered in `rect` Returns a `CGRect` where `self` is centered in `rect`.
*/ */
func centered(in rect: CGRect, xOffset: Double = 0, yOffset: Double = 0) -> CGRect { func centered(in rect: Self, xOffset: Double = 0, yOffset: Double = 0) -> Self {
return CGRect( Self(
x: ((rect.width - size.width) / 2) + CGFloat(xOffset), x: ((rect.width - size.width) / 2) + CGFloat(xOffset),
y: ((rect.height - size.height) / 2) + CGFloat(yOffset), y: ((rect.height - size.height) / 2) + CGFloat(yOffset),
width: size.width, width: size.width,
@ -42,9 +42,7 @@ extension CGRect {
} }
extension NSWindow { extension NSWindow {
var toolbarView: NSView? { var toolbarView: NSView? { standardWindowButton(.closeButton)?.superview }
return standardWindowButton(.closeButton)?.superview
}
} }
extension NSWindow { extension NSWindow {
@ -60,6 +58,7 @@ extension NSWindow {
guard let screen = NSScreen.main else { guard let screen = NSScreen.main else {
return return
} }
let visibleFrame = screen.visibleFrame let visibleFrame = screen.visibleFrame
let x: CGFloat, y: CGFloat let x: CGFloat, y: CGFloat
@ -73,7 +72,7 @@ extension NSWindow {
} }
switch yPositioning { switch yPositioning {
case .top: case .top:
// Defect fix: keep docked windows below menubar area // Defect fix: keep docked windows below menubar area.
// Previously, the window would obstruct menubar clicks when the menubar was set to auto-hide. // Previously, the window would obstruct menubar clicks when the menubar was set to auto-hide.
// Now, the window stays below that area. // Now, the window stays below that area.
let menubarThickness = NSStatusBar.system.thickness let menubarThickness = NSStatusBar.system.thickness
@ -96,9 +95,7 @@ extension NSView {
extension NSMenuItem { extension NSMenuItem {
var isChecked: Bool { var isChecked: Bool {
get { get { state == .on }
return state == .on
}
set { set {
state = newValue ? .on : .off state = newValue ? .on : .off
} }
@ -130,7 +127,7 @@ extension NSMenuItem {
final class AssociatedObject<T: Any> { final class AssociatedObject<T: Any> {
subscript(index: Any) -> T? { subscript(index: Any) -> T? {
get { get {
return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T? objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T?
} set { } set {
objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
} }
@ -179,7 +176,7 @@ extension TargetActionSender {
*/ */
var onAction: ((Self) -> Void)? { var onAction: ((Self) -> Void)? {
get { get {
return (TargetActionSenderAssociatedKeys.trampoline[self] as? ActionTrampoline<Self>)?.action (TargetActionSenderAssociatedKeys.trampoline[self] as? ActionTrampoline<Self>)?.action
} }
set { set {
guard let newValue = newValue else { guard let newValue = newValue else {
@ -207,13 +204,8 @@ extension TargetActionSender {
} }
extension NSApplication { extension NSApplication {
var isLeftMouseDown: Bool { var isLeftMouseDown: Bool { currentEvent?.type == .leftMouseDown }
return currentEvent?.type == .leftMouseDown var isOptionKeyDown: Bool { NSEvent.modifierFlags.contains(.option) }
}
var isOptionKeyDown: Bool {
return NSEvent.modifierFlags.contains(.option)
}
} }
// TODO: Find a namespace to put this onto. I don't like free-floating functions. // TODO: Find a namespace to put this onto. I don't like free-floating functions.
@ -228,7 +220,7 @@ func pressKey(keyCode: CGKeyCode, flags: CGEventFlags = []) {
extension NSWindow.Level { extension NSWindow.Level {
private static func level(for cgLevelKey: CGWindowLevelKey) -> NSWindow.Level { private static func level(for cgLevelKey: CGWindowLevelKey) -> NSWindow.Level {
return NSWindow.Level(rawValue: Int(CGWindowLevelForKey(cgLevelKey))) NSWindow.Level(rawValue: Int(CGWindowLevelForKey(cgLevelKey)))
} }
public static let desktop = level(for: .desktopWindow) public static let desktop = level(for: .desktopWindow)