Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ build/
Releases/
Dozer.xcodeproj/
Credentials/
Carthage/

# Fastlane
fastlane/
Expand Down
2 changes: 1 addition & 1 deletion .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ identifier_name:
min_length:
warning: 2
error: 2
validates_start_with_lowercase: false
validates_start_with_lowercase: off
allowed_symbols:
- '_'
excluded:
Expand Down
1 change: 0 additions & 1 deletion Brewfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ brew "swiftformat"
brew "swiftgen"
brew "swiftlint"
brew "xcodegen"
brew "carthage"
107 changes: 0 additions & 107 deletions Brewfile.lock.json

This file was deleted.

2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Refresh the Dozer icons or logo. [Design resources for logo and status bar icon]
You can submit your own code. This can be bug fixes or new features. Please ask me (@Mortennn) before implementing a new feature. Check out [Issues](https://github.com/Mortennn/Dozer/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).

### Getting started
Make sure you have at least Xcode 10 installed.
Make sure you have Xcode 15 or later installed (Dozer targets macOS 11+). Dependencies are managed with Swift Package Manager and resolved automatically by Xcode — no Carthage step is required.

Run the following command:
```shell
Expand Down
5 changes: 0 additions & 5 deletions Cartfile

This file was deleted.

5 changes: 0 additions & 5 deletions Cartfile.resolved

This file was deleted.

69 changes: 62 additions & 7 deletions Dozer/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,32 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

import Cocoa
import MASShortcut
import KeyboardShortcuts
import Sparkle
import Defaults
import Preferences
import Settings


final class AppDelegate: NSObject, NSApplicationDelegate {
// Sparkle 2 updater. Shared so the settings panes can read/write its state.
let updaterController = SPUStandardUpdaterController(
startingUpdater: true,
updaterDelegate: nil,
userDriverDelegate: nil
)

func applicationDidFinishLaunching(_: Notification) {
MASShortcutBinder.shared()?.bindShortcut(withDefaultsKey: UserDefaultKeys.Shortcuts.ToggleMenuItems) { () in
// Carry over a shortcut saved by the old MASShortcut integration.
migrateLegacyShortcutIfNeeded()

// Trigger on key-down to match MASShortcut's original behavior.
KeyboardShortcuts.onKeyDown(for: .toggleMenuItems) {
DozerIcons.shared.toggle()
}

// Initalize Dozer Icons
_ = DozerIcons.shared

// If enabled hide menu bar icons at launch
DozerIcons.shared.hideAtLaunch()

Expand All @@ -30,15 +41,59 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
return true
}

lazy var preferences: [PreferencePane] = [
/// Import a shortcut saved by the previous MASShortcut integration so
/// existing users keep their toggle hotkey after upgrading.
///
/// MASShortcut (via `MASShortcutBinder`) stored the shortcut under the
/// `"toggleMenuItems"` UserDefaults key as a `{keyCode, modifierFlags}`
/// dictionary, where `modifierFlags` are Cocoa `NSEvent.ModifierFlags`.
/// KeyboardShortcuts uses its own `"KeyboardShortcuts_"`-prefixed storage,
/// so without this the saved shortcut would silently disappear.
@MainActor
private func migrateLegacyShortcutIfNeeded() {
let legacyKey = "toggleMenuItems"
let defaults = UserDefaults.standard

guard let legacy = defaults.dictionary(forKey: legacyKey) else {
return
}

// Only import if the user has not already recorded one with the new API.
if KeyboardShortcuts.getShortcut(for: .toggleMenuItems) == nil,
let keyCode = (legacy["keyCode"] as? NSNumber)?.intValue,
let modifierFlags = (legacy["modifierFlags"] as? NSNumber)?.uintValue {
let shortcut = KeyboardShortcuts.Shortcut(
KeyboardShortcuts.Key(rawValue: keyCode),
modifiers: NSEvent.ModifierFlags(rawValue: modifierFlags)
)
KeyboardShortcuts.setShortcut(shortcut, for: .toggleMenuItems)
Defaults[.isShortcutSet] = true
}

// Drop the obsolete key so this only runs once.
defaults.removeObject(forKey: legacyKey)
}

lazy var preferences: [SettingsPane] = [
Dozer(),
General()
]

lazy var preferencesWindowController = PreferencesWindowController(
preferencePanes: preferences,
lazy var preferencesWindowController = SettingsWindowController(
panes: preferences,
style: .toolbarItems,
animated: true,
hidesToolbarForSingleItem: true
)

/// Open the settings window, reliably in front of other apps.
///
/// The Settings library relies on the cooperative `NSApp.activate()` on
/// macOS 14+, which does not reliably bring an accessory (menu-bar) app's
/// window forward, so the window can open behind the frontmost app.
/// `orderFrontRegardless()` forces it above other apps' windows.
func showPreferences() {
preferencesWindowController.show(pane: .general)
preferencesWindowController.window?.orderFrontRegardless()
}
}
11 changes: 5 additions & 6 deletions Dozer/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

import Cocoa
import Preferences
import Settings
import Defaults
import KeyboardShortcuts

extension Defaults.Keys {
static let hideOnLogin: Defaults.Key<Bool> = Key<Bool>("hideOnLogin", default: false)
Expand All @@ -20,17 +21,15 @@ extension Defaults.Keys {
static let isShortcutSet: Defaults.Key<Bool> = Key<Bool>("isShortcutSet", default: false)
}

struct UserDefaultKeys {
struct Shortcuts {
static let ToggleMenuItems: String = "toggleMenuItems"
}
extension KeyboardShortcuts.Name {
static let toggleMenuItems = Self("toggleMenuItems")
}

extension NSStoryboard.Name {
static let preferences: NSStoryboard.Name = NSStoryboard.Name("Preferences")
}

extension Preferences.PaneIdentifier {
extension Settings.PaneIdentifier {
static let dozer = Self("dozer")
static let general = Self("general")
}
Expand Down
2 changes: 1 addition & 1 deletion Dozer/DozerIcons.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public final class DozerIcons {
Defaults[.showIconAndMenuEnabled] = self.enableIconAndMenu
if self.enableIconAndMenu == false {
_ = DozerIcons.toggleDockIcon(showIcon: false)
appDelegate.preferencesWindowController.show(preferencePane: .general)
appDelegate.showPreferences()
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Dozer/Other/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
<string>11.0</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
Expand Down
1 change: 0 additions & 1 deletion Dozer/Other/bridging-header.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@
#define bridging_header_h

#import <Cocoa/Cocoa.h>
#import <MASShortcut/Shortcut.h>

#endif
2 changes: 1 addition & 1 deletion Dozer/StatusIconClasses/NormalStatusIcon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class NormalStatusIcon: HelperstatusIcon {
case .leftMouseDown:
DozerIcons.shared.toggle()
case .rightMouseDown:
appDelegate.preferencesWindowController.show(preferencePane: .general)
appDelegate.showPreferences()
default:
break
}
Expand Down
2 changes: 1 addition & 1 deletion Dozer/StatusIconClasses/RemoveStatusIcon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class RemoveStatusIcon: HelperstatusIcon {
case .leftMouseDown:
DozerIcons.shared.toggleRemove()
case .rightMouseDown:
appDelegate.preferencesWindowController.show(preferencePane: .general)
appDelegate.showPreferences()
default:
break
}
Expand Down
14 changes: 8 additions & 6 deletions Dozer/ViewControllers/DozerVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

import Cocoa
import Sparkle
import Preferences
import Settings

final class Dozer: NSViewController, PreferencePane {
let preferencePaneIdentifier = Preferences.PaneIdentifier.dozer
let preferencePaneTitle: String = "Dozer"
final class Dozer: NSViewController, SettingsPane {
let paneIdentifier = Settings.PaneIdentifier.dozer
let paneTitle: String = "Dozer"
let toolbarItemIcon = NSImage(named: "AppIcon")!

override var nibName: NSNib.Name? { "Dozer" }
Expand All @@ -25,8 +25,10 @@ final class Dozer: NSViewController, PreferencePane {
versionLabel.stringValue = "\(releaseVersionNumber) (\(buildVersionNumber))"
}

checkForUpdates.target = SUUpdater.shared()!
checkForUpdates.action = #selector(SUUpdater.shared()!.checkForUpdates(_:))
if let appDelegate = NSApp.delegate as? AppDelegate {
checkForUpdates.target = appDelegate.updaterController
checkForUpdates.action = #selector(SPUStandardUpdaterController.checkForUpdates(_:))
}

quit.action = #selector(NSApp.terminate(_:))
}
Expand Down
Loading