Skip to content

Commit

Permalink
Close menu when pressing hotkey again
Browse files Browse the repository at this point in the history
The tricky part here is that `menu.popUp()` blocks the main thread until
the menu is actually closed, which is why the only way to close the menu
is to actually add another hotkey listener and close menu manually.

Fixes #32.
  • Loading branch information
p0deje committed Oct 18, 2019
1 parent 8889f55 commit 2d4385e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 13 deletions.
23 changes: 12 additions & 11 deletions Maccy/FilterMenuItemView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class FilterMenuItemView: NSView, NSTextFieldDelegate {
guard let key = Key(carbonKeyCode: UInt32(event.keyCode)) else {
return false
}
let modifierFlags = event.modifierFlags
let modifierFlags = event.modifierFlags.intersection(.deviceIndependentFlagsMask)

if Keys.shouldPassThrough(key) {
return false
Expand All @@ -180,11 +180,12 @@ class FilterMenuItemView: NSView, NSTextFieldDelegate {
}

if key == Key.return || key == Key.keypadEnter || key == Key.upArrow || key == Key.downArrow {
if let menu = customMenu {
processSelectionKey(menu: menu, key: key, modifierFlags: modifierFlags)
return true
}
processSelectionKey(menu: customMenu, key: key, modifierFlags: modifierFlags)
return true
}

if key == GlobalHotKey.key && modifierFlags == GlobalHotKey.modifierFlags {
customMenu?.cancelTracking()
return false
}

Expand All @@ -208,21 +209,21 @@ class FilterMenuItemView: NSView, NSTextFieldDelegate {
}
}

private func processSelectionKey(menu: Menu, key: Key, modifierFlags: NSEvent.ModifierFlags) {
private func processSelectionKey(menu: Menu?, key: Key, modifierFlags: NSEvent.ModifierFlags) {
switch key {
case .return, .keypadEnter:
menu.select()
menu?.select()
case .upArrow:
if modifierFlags.contains(.command) {
menu.selectFirst()
menu?.selectFirst()
} else {
menu.selectPrevious(alt: modifierFlags.contains(.option))
menu?.selectPrevious(alt: modifierFlags.contains(.option))
}
case .downArrow:
if modifierFlags.contains(.command) {
menu.selectLast()
menu?.selectLast()
} else {
menu.selectNext(alt: modifierFlags.contains(.option))
menu?.selectNext(alt: modifierFlags.contains(.option))
}
default: ()
}
Expand Down
14 changes: 12 additions & 2 deletions Maccy/GlobalHotKey.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import HotKey

class GlobalHotKey {
private var hotKey: HotKey?
static public var key: Key?
static public var modifierFlags: NSEvent.ModifierFlags?

private var hotKey: HotKey!
private var handler: HotKey.Handler
private var hotKeyPrefObserver: NSKeyValueObservation?

Expand All @@ -12,7 +15,11 @@ class GlobalHotKey {
hotKeyPrefObserver = UserDefaults.standard.observe(\.hotKey, options: [.initial, .new], changeHandler: { _, _ in
if let (key, modifiers) = self.parseHotKey() {
self.hotKey = HotKey(key: key, modifiers: modifiers)
self.hotKey?.keyDownHandler = self.handler
self.hotKey.keyDownHandler = {
self.hotKey.isPaused = true
self.handler()
self.hotKey.isPaused = false
}
}
})
}
Expand Down Expand Up @@ -46,6 +53,9 @@ class GlobalHotKey {
}
}

GlobalHotKey.key = key
GlobalHotKey.modifierFlags = modifiers

return (key, modifiers)
}
}
11 changes: 11 additions & 0 deletions MaccyUITests/MaccyUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ class MaccyUITests: XCTestCase {
XCTAssertTrue(app.menuItems[copy2].exists)
}

func testCloseWithHotkey() {
popUpWithHotkey()
let historyItem = app.menuItems[copy1]
expectation(for: NSPredicate(format: "exists = 0"), evaluatedWith: historyItem)

for event in popUpEvents {
event.post(tap: .cghidEventTap)
}
waitForExpectations(timeout: 3)
}

func testPopupWithMenubar() {
popUpWithMouse()
XCTAssertTrue(app.menuItems[copy1].exists)
Expand Down

0 comments on commit 2d4385e

Please sign in to comment.