From d442e6021b2328bc2475dfedfb1d3b622d5ca128 Mon Sep 17 00:00:00 2001 From: Tae Won Ha Date: Thu, 23 Dec 2021 14:16:37 +0100 Subject: [PATCH] Add NvimViewDelegate for menu item key equivalent handling --- NvimView/Sources/NvimView/NvimView+Key.swift | 20 ++++++++++++++++---- NvimView/Sources/NvimView/NvimView.swift | 6 ++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/NvimView/Sources/NvimView/NvimView+Key.swift b/NvimView/Sources/NvimView/NvimView+Key.swift index c11a606f..598ee890 100644 --- a/NvimView/Sources/NvimView/NvimView+Key.swift +++ b/NvimView/Sources/NvimView/NvimView+Key.swift @@ -78,8 +78,21 @@ public extension NvimView { override func performKeyEquivalent(with event: NSEvent) -> Bool { if event.type != .keyDown { return false } + + // Cocoa first calls this method to ask whether a subview implements the key equivalent + // in question. For example, if we have ⌘-. as shortcut for a menu item, which is the case + // for "Tools -> Focus Neovim View" by default, at some point in the event processing chain + // this method will be called. If we want to forward the event to Neovim because the user + // could have set it for some action, that menu item shortcut will not work. To work around + // this, we ask NvimViewDelegate whether the event is a shortcut of a menu item. The delegate + // has to be implemented by the user of NvimView. + if self.delegate?.isMenuItemKeyEquivalent(event) == true { return false } + let flags = event.modifierFlags.intersection(.deviceIndependentFlagsMask) + // Emoji menu: Cmd-Ctrl-Space + if flags.contains([.command, .control]), event.keyCode == spaceKeyChar { return false } + // & do not trigger keyDown events. // Catch the key event here and pass it to keyDown. // By rogual in NeoVim dot app: @@ -89,13 +102,10 @@ public extension NvimView { return true } - // Emoji menu: Cmd-Ctrl-Space - if flags.contains([.command, .control]), event.keyCode == 49 { return false } - // Space key (especially in combination with modifiers) can result in // unexpected chars (e.g. ctrl-space = \0), so catch the event early and // pass it to keyDown. - if event.keyCode == 49 { + if event.keyCode == spaceKeyChar { self.keyDown(with: event) return true } @@ -315,3 +325,5 @@ public extension NvimView { string.replacingOccurrences(of: "<", with: self.wrapNamedKeys("lt")) } } + +private let spaceKeyChar = 49 diff --git a/NvimView/Sources/NvimView/NvimView.swift b/NvimView/Sources/NvimView/NvimView.swift index bfd5d768..4e07b7af 100644 --- a/NvimView/Sources/NvimView/NvimView.swift +++ b/NvimView/Sources/NvimView/NvimView.swift @@ -11,6 +11,10 @@ import RxPack import RxSwift import Tabs +public protocol NvimViewDelegate { + func isMenuItemKeyEquivalent(_: NSEvent) -> Bool +} + public class NvimView: NSView, UiBridgeConsumer, NSUserInterfaceValidations, @@ -29,6 +33,8 @@ public class NvimView: NSView, public static let minLinespacing = 0.5.cgf public static let maxLinespacing = 8.cgf + public var delegate: NvimViewDelegate? + public let usesCustomTabBar: Bool public let tabBar: TabBar?