Browse Source

Deployment target 10.14!

master
Abhishek Banthia 6 months ago
parent
commit
5ae6671208
  1. 21
      Clocker/AppDelegate.swift
  2. 10
      Clocker/ClockerUnitTests/AppDelegateTests.swift
  3. 6
      Clocker/Overall App/Foundation + Additions.swift
  4. 6
      Clocker/Panel/PanelController.swift
  5. 4
      Clocker/Preferences/General/PreferencesDataSource.swift
  6. 2
      Clocker/Preferences/General/PreferencesViewController.swift
  7. 22
      Clocker/Preferences/Menu Bar/StatusItemHandler.swift
  8. 11
      Clocker/Preferences/Menu Bar/StatusItemView.swift
  9. 9
      Clocker/Preferences/Menu Bar/UpcomingEventStatusItemView.swift

21
Clocker/AppDelegate.swift

@ -10,13 +10,8 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
private lazy var floatingWindow = FloatingWindowController.shared() private lazy var floatingWindow = FloatingWindowController.shared()
internal lazy var panelController = PanelController(windowNibName: .panel) internal lazy var panelController = PanelController(windowNibName: .panel)
private var statusBarHandler: StatusItemHandler! private var statusBarHandler: StatusItemHandler!
private var panelObserver: NSKeyValueObservation?
private let store: VersionUpdateHandler = VersionUpdateHandler(with: DataStore.shared()) private let store: VersionUpdateHandler = VersionUpdateHandler(with: DataStore.shared())
deinit {
panelObserver?.invalidate()
}
override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) { override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) {
if let path = keyPath, path == PreferencesConstants.hotKeyPathIdentifier { if let path = keyPath, path == PreferencesConstants.hotKeyPathIdentifier {
let hotKeyCenter = PTHotKeyCenter.shared() let hotKeyCenter = PTHotKeyCenter.shared()
@ -178,7 +173,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
alert.runModal() alert.runModal()
} }
@IBAction func ping(_ sender: Any) { @IBAction func ping(_ sender: NSButton) {
togglePanel(sender) togglePanel(sender)
} }
@ -234,16 +229,16 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
NSApp.terminate(nil) NSApp.terminate(nil)
} }
@IBAction open func togglePanel(_: Any) { @IBAction open func togglePanel(_ sender: NSButton) {
Logger.info("Toggle Panel called with sender state \(sender.state.rawValue)")
let displayMode = UserDefaults.standard.integer(forKey: CLShowAppInForeground) let displayMode = UserDefaults.standard.integer(forKey: CLShowAppInForeground)
if displayMode == 1 { if displayMode == 1 {
// No need to call NSApp.activate here since `showFloatingWindow` takes care of this // No need to call NSApp.activate here since `showFloatingWindow` takes care of this
showFloatingWindow() showFloatingWindow()
} else { } else {
setupPanelObserverIfNeeeded()
panelController.showWindow(nil) panelController.showWindow(nil)
panelController.setActivePanel(newValue: !panelController.hasActivePanelGetter()) panelController.setActivePanel(newValue: sender.state == .on)
NSApp.activate(ignoringOtherApps: true) NSApp.activate(ignoringOtherApps: true)
} }
} }
@ -263,12 +258,4 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
open func invalidateMenubarTimer(_ showIcon: Bool) { open func invalidateMenubarTimer(_ showIcon: Bool) {
statusBarHandler.invalidateTimer(showIcon: showIcon, isSyncing: true) statusBarHandler.invalidateTimer(showIcon: showIcon, isSyncing: true)
} }
private func setupPanelObserverIfNeeeded() {
if panelObserver == nil {
panelObserver = panelController.observe(\.hasActivePanel, options: [.new]) { obj, _ in
self.statusBarHandler.setHasActiveIcon(obj.hasActivePanelGetter())
}
}
}
} }

10
Clocker/ClockerUnitTests/AppDelegateTests.swift

@ -86,11 +86,11 @@ class AppDelegateTests: XCTestCase {
let subject = NSApplication.shared.delegate as? AppDelegate let subject = NSApplication.shared.delegate as? AppDelegate
subject?.invalidateMenubarTimer(true) subject?.invalidateMenubarTimer(true)
let statusItemHandler = subject?.statusItemForPanel() let statusItemHandler = subject?.statusItemForPanel()
XCTAssertNil(statusItemHandler?.statusItem.view) XCTAssertEqual(statusItemHandler?.statusItem.button?.subviews, [])
XCTAssertEqual(statusItemHandler?.statusItem.title, CLEmptyString) XCTAssertEqual(statusItemHandler?.statusItem.button?.title, CLEmptyString)
XCTAssertEqual(statusItemHandler?.statusItem.button?.image?.name(), "LightModeIcon") XCTAssertEqual(statusItemHandler?.statusItem.button?.image?.name(), "LightModeIcon")
XCTAssertEqual(statusItemHandler?.statusItem.button?.imagePosition, .imageOnly) XCTAssertEqual(statusItemHandler?.statusItem.button?.imagePosition, .imageOnly)
XCTAssertEqual(statusItemHandler?.statusItem.toolTip, "Clocker") XCTAssertEqual(statusItemHandler?.statusItem.button?.toolTip, "Clocker")
} }
func testCompactModeMenubarSetup() { func testCompactModeMenubarSetup() {
@ -109,7 +109,7 @@ class AppDelegateTests: XCTestCase {
subject?.setupMenubarTimer() subject?.setupMenubarTimer()
let statusItemHandler = subject?.statusItemForPanel() let statusItemHandler = subject?.statusItemForPanel()
XCTAssertNotNil(statusItemHandler?.statusItem.view) // This won't be nil for compact mode XCTAssertNotNil(statusItemHandler?.statusItem.button) // This won't be nil for compact mode
DataStore.shared().setTimezones(olderTimezones) DataStore.shared().setTimezones(olderTimezones)
} }
@ -140,7 +140,7 @@ class AppDelegateTests: XCTestCase {
subject?.setupMenubarTimer() subject?.setupMenubarTimer()
XCTAssertNil(subject?.statusItemForPanel().statusItem.view) // This will be nil for standard mode XCTAssertEqual(subject?.statusItemForPanel().statusItem.button?.subviews.isEmpty, true) // This will be nil for standard mode
UserDefaults.standard.set(0, forKey: CLMenubarCompactMode) // Set the menubar mode back to compact UserDefaults.standard.set(0, forKey: CLMenubarCompactMode) // Set the menubar mode back to compact
} }

6
Clocker/Overall App/Foundation + Additions.swift

@ -61,11 +61,7 @@ extension NSKeyedArchiver {
static func clocker_archive(with object: Any) -> Data? { static func clocker_archive(with object: Any) -> Data? {
if #available(macOS 10.14, *) { if #available(macOS 10.14, *) {
return try! NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: true) return try? NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: true)
}
if #available(macOS 10.13, *) {
return NSKeyedArchiver.archivedData(withRootObject: object)
} }
return nil return nil

6
Clocker/Panel/PanelController.swift

@ -143,8 +143,8 @@ class PanelController: ParentPanelController {
return return
} }
var statusBackgroundWindow = appDelegate.statusItemForPanel().statusItem.view?.window var statusBackgroundWindow = appDelegate.statusItemForPanel().statusItem.button?.window
var statusView = appDelegate.statusItemForPanel().statusItem.view var statusView = appDelegate.statusItemForPanel().statusItem.button
// This below is a better way than actually checking if the menubar compact mode is set. // This below is a better way than actually checking if the menubar compact mode is set.
if statusBackgroundWindow == nil || statusView == nil { if statusBackgroundWindow == nil || statusView == nil {
@ -407,7 +407,7 @@ extension PanelController: NSWindowDelegate {
setActivePanel(newValue: false) setActivePanel(newValue: false)
} }
if let appDelegate = NSApplication.shared.delegate as? AppDelegate { if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
appDelegate.statusItemForPanel().hasActiveIcon = false appDelegate.statusItemForPanel().statusItem.button?.state = .off
} }
} }
} }

4
Clocker/Preferences/General/PreferencesDataSource.swift

@ -66,11 +66,13 @@ extension PreferencesDataSource: NSTableViewDelegate {
return false return false
} }
guard let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: data) as? IndexSet, let first = rowIndexes.first else { guard let rowIndexes = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSIndexSet.self, from: data) else {
assertionFailure("Row was unexpectedly nil") assertionFailure("Row was unexpectedly nil")
return false return false
} }
let first = rowIndexes.firstIndex
let currentObject = newOrder[first] let currentObject = newOrder[first]
newOrder.remove(at: first) newOrder.remove(at: first)

2
Clocker/Preferences/General/PreferencesViewController.swift

@ -297,7 +297,7 @@ class PreferencesViewController: ParentViewController {
} }
} }
@objc func ping(_ sender: Any) { @objc func ping(_ sender: NSButton) {
guard let delegate = NSApplication.shared.delegate as? AppDelegate else { guard let delegate = NSApplication.shared.delegate as? AppDelegate else {
return return
} }

22
Clocker/Preferences/Menu Bar/StatusItemHandler.swift

@ -17,8 +17,8 @@ class StatusItemHandler: NSObject {
var statusItem: NSStatusItem = { var statusItem: NSStatusItem = {
let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
statusItem.toolTip = "Clocker" statusItem.button?.toolTip = "Clocker"
statusItem.highlightMode = false (statusItem.button?.cell as? NSButtonCell)?.highlightsBy = NSCell.StyleMask(rawValue: 0)
return statusItem return statusItem
}() }()
@ -43,7 +43,7 @@ class StatusItemHandler: NSObject {
// Do some cleanup // Do some cleanup
switch oldValue { switch oldValue {
case .compactText: case .compactText:
statusItem.view = nil statusItem.button?.subviews = []
statusContainerView = nil statusContainerView = nil
case .standardText: case .standardText:
statusItem.button?.title = CLEmptyString statusItem.button?.title = CLEmptyString
@ -98,7 +98,7 @@ class StatusItemHandler: NSObject {
} }
} }
statusItem.target = self statusItem.button?.target = self
statusItem.autosaveName = NSStatusItem.AutosaveName("ClockerStatusItem") statusItem.autosaveName = NSStatusItem.AutosaveName("ClockerStatusItem")
setSelector() setSelector()
} }
@ -151,8 +151,10 @@ class StatusItemHandler: NSObject {
store: store, store: store,
showUpcomingEventView: upcomingEventView, showUpcomingEventView: upcomingEventView,
bufferContainerWidth: bufferCalculatedWidth()) bufferContainerWidth: bufferCalculatedWidth())
statusItem.view = statusContainerView statusContainerView?.wantsLayer = true
statusItem.view?.window?.backgroundColor = NSColor.clear statusItem.button?.addSubview(statusContainerView!)
statusItem.button?.frame = statusContainerView!.bounds
statusItem.button?.subviews.first?.window?.backgroundColor = NSColor.clear
} }
// This is called when the Apple interface style pre-Mojave is changed. // This is called when the Apple interface style pre-Mojave is changed.
@ -169,7 +171,7 @@ class StatusItemHandler: NSObject {
hasActiveIcon = value hasActiveIcon = value
} }
@objc func menubarIconClicked(_ sender: Any) { @objc func menubarIconClicked(_ sender: NSStatusBarButton) {
guard let mainDelegate = NSApplication.shared.delegate as? AppDelegate else { guard let mainDelegate = NSApplication.shared.delegate as? AppDelegate else {
return return
} }
@ -340,8 +342,8 @@ class StatusItemHandler: NSObject {
} }
private func setClockerIcon() { private func setClockerIcon() {
if statusItem.view != nil { if statusItem.button?.subviews.isEmpty == false {
statusItem.view = nil statusItem.button?.subviews = []
} }
if statusItem.button?.image?.name() == NSImage.Name.menubarIcon { if statusItem.button?.image?.name() == NSImage.Name.menubarIcon {
@ -351,7 +353,7 @@ class StatusItemHandler: NSObject {
statusItem.button?.title = CLEmptyString statusItem.button?.title = CLEmptyString
statusItem.button?.image = NSImage(named: .menubarIcon) statusItem.button?.image = NSImage(named: .menubarIcon)
statusItem.button?.imagePosition = .imageOnly statusItem.button?.imagePosition = .imageOnly
statusItem.toolTip = "Clocker" statusItem.button?.toolTip = "Clocker"
} }
private func setupForStandardText() { private func setupForStandardText() {

11
Clocker/Preferences/Menu Bar/StatusItemView.swift

@ -111,7 +111,7 @@ class StatusItemView: NSView {
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
locationView.leadingAnchor.constraint(equalTo: leadingAnchor), locationView.leadingAnchor.constraint(equalTo: leadingAnchor),
locationView.trailingAnchor.constraint(equalTo: trailingAnchor), locationView.trailingAnchor.constraint(equalTo: trailingAnchor),
locationView.topAnchor.constraint(equalTo: topAnchor, constant: 7), locationView.topAnchor.constraint(equalTo: topAnchor, constant: 0),
locationView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.35), locationView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.35),
]) ])
@ -138,15 +138,6 @@ class StatusItemView: NSView {
required init?(coder _: NSCoder) { required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
guard let mainDelegate = NSApplication.shared.delegate as? AppDelegate else {
return
}
mainDelegate.togglePanel(event)
}
} }
extension StatusItemView: StatusItemViewConforming { extension StatusItemView: StatusItemViewConforming {

9
Clocker/Preferences/Menu Bar/UpcomingEventStatusItemView.swift

@ -85,15 +85,6 @@ class UpcomingEventStatusItemView: NSView {
nextEventField.attributedStringValue = NSAttributedString(string: "Next Event", attributes: textFontAttributes) nextEventField.attributedStringValue = NSAttributedString(string: "Next Event", attributes: textFontAttributes)
etaField.attributedStringValue = NSAttributedString(string: metadata, attributes: timeAttributes) etaField.attributedStringValue = NSAttributedString(string: metadata, attributes: timeAttributes)
} }
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
guard let mainDelegate = NSApplication.shared.delegate as? AppDelegate else {
return
}
mainDelegate.togglePanel(event)
}
} }
extension UpcomingEventStatusItemView: StatusItemViewConforming { extension UpcomingEventStatusItemView: StatusItemViewConforming {

Loading…
Cancel
Save