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
48 changes: 47 additions & 1 deletion BLEUnlock/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ func t(_ key: String) -> String {
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSMenuItemValidation, NSUserNotificationCenterDelegate, BLEDelegate {
let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
// Stores whether the menu bar icon is hidden.
let hideStatusItemPreferenceKey = "hideStatusItemFromMenuBar"
let ble = BLE()
let mainMenu = NSMenu()
let deviceMenu = NSMenu()
Expand Down Expand Up @@ -117,6 +119,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSMenuItemVa
}

func updateRSSI(rssi: Int?, active: Bool) {
// Keep updating the status item even when it is hidden.
if let r = rssi {
lastRSSI = r
monitorMenuItem?.title = String(format:"%ddBm", r) + (active ? " (Active)" : "")
Expand Down Expand Up @@ -552,6 +555,15 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSMenuItemVa
menuItem.state = wakeWithoutUnlocking ? .on : .off
}

@objc func toggleHideMenuBarIcon(_ menuItem: NSMenuItem) {
let hideMenuBarIcon = !prefs.bool(forKey: hideStatusItemPreferenceKey)
prefs.set(hideMenuBarIcon, forKey: hideStatusItemPreferenceKey)
menuItem.state = hideMenuBarIcon ? .on : .off

// Apply the visibility change immediately.
statusItem.isVisible = !hideMenuBarIcon
}

@objc func lockNow() {
guard !isScreenLocked() else { return }
manualLock = true
Expand Down Expand Up @@ -650,6 +662,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSMenuItemVa

item = mainMenu.addItem(withTitle: t("launch_at_login"), action: #selector(toggleLaunchAtLogin), keyEquivalent: "")
item.state = prefs.bool(forKey: "launchAtLogin") ? .on : .off

item = mainMenu.addItem(withTitle: t("hide_menu_bar_icon"), action: #selector(toggleHideMenuBarIcon), keyEquivalent: "")
item.state = prefs.bool(forKey: hideStatusItemPreferenceKey) ? .on : .off

mainMenu.addItem(withTitle: t("set_rssi_threshold"), action: #selector(setRSSIThreshold),
keyEquivalent: "")
Expand All @@ -658,6 +673,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSMenuItemVa
mainMenu.addItem(withTitle: t("about"), action: #selector(showAboutBox), keyEquivalent: "")
mainMenu.addItem(NSMenuItem.separator())
mainMenu.addItem(withTitle: t("quit"), action: #selector(NSApplication.terminate(_:)), keyEquivalent: "")
// Keep the menu attached to the status item.
statusItem.menu = mainMenu
}

Expand All @@ -673,11 +689,29 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSMenuItemVa
}
}

func resetHiddenMenuBarIconState() {
guard prefs.bool(forKey: hideStatusItemPreferenceKey) else { return }

// Show the icon again when the app is reopened.
prefs.set(false, forKey: hideStatusItemPreferenceKey)
statusItem.isVisible = true

if let item = mainMenu.items.first(where: { $0.action == #selector(toggleHideMenuBarIcon) }) {
item.state = .off
}
}

func applicationDidFinishLaunching(_ aNotification: Notification) {
if let button = statusItem.button {
button.image = NSImage(named: "StatusBarDisconnected")
constructMenu()
}
constructMenu()

let hideMenuBarIcon = prefs.bool(forKey: hideStatusItemPreferenceKey)

// Restore the saved visibility state on launch.
statusItem.isVisible = !hideMenuBarIcon

ble.delegate = self
if let str = prefs.string(forKey: "device") {
if let uuid = UUID(uuidString: str) {
Expand Down Expand Up @@ -730,7 +764,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSMenuItemVa
// otherwise CBCentralManager.scanForPeripherals won't work.
NSApp.setActivationPolicy(.accessory)
}


func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
// Restore the icon when the running app is reopened.
resetHiddenMenuBarIconState()
return false
}

func applicationDidBecomeActive(_ notification: Notification) {
// Also restore the icon when the app becomes active again.
resetHiddenMenuBarIconState()
}

func applicationWillTerminate(_ aNotification: Notification) {
}
}
1 change: 1 addition & 0 deletions BLEUnlock/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"enter_rssi_threshold_info" = "Device whose RSSI is less than this value will be ignored while scanning.";
"farther" = "⬇Farther";
"launch_at_login" = "Launch at Login";
"hide_menu_bar_icon" = "Hide Menu Bar Icon";
"lock_delay" = "Delay to Lock";
"lock_now" = "Lock Screen Now";
"lock_rssi" = "Lock RSSI";
Expand Down
2 changes: 1 addition & 1 deletion BLEUnlock/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.12.2</string>
<key>CFBundleVersion</key>
<string>796</string>
<string>805</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
Expand Down
1 change: 1 addition & 0 deletions BLEUnlock/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"enter_rssi_threshold_info" = "この値よりRSSIが小さいデバイスはスキャンに表示されません。";
"farther" = "⬇遠い";
"launch_at_login" = "ログイン時に起動";
"hide_menu_bar_icon" = "メニューバーアイコンを非表示";
"lock_delay" = "ロックするまでの遅延";
"lock_now" = "今すぐロック";
"lock_rssi" = "ロック信号強度";
Expand Down
1 change: 1 addition & 0 deletions BLEUnlock/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"enter_rssi_threshold_info" = "扫描设备时会忽略RSSI值低于该值的设备。";
"farther" = "⬇远离";
"launch_at_login" = "开机启动";
"hide_menu_bar_icon" = "隐藏菜单栏图标";
"lock_delay" = "延迟锁定";
"lock_now" = "立刻锁定屏幕";
"lock_rssi" = "锁定 RSSI";
Expand Down