如果某个修饰键被按下但没有其他键被按下,则检查NSEvent的modifierFlags。

22

我刚尝试使用NSEvent中的addLocalMonitorForEventsMatchingMask:handler:方法,并遇到以下问题:如何找出是否按下了某些修饰键?

以下是一个简短的示例,以将此问题设置为上下文:我想监听快捷键“⌘+W”。因此我编写了以下代码:

[NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *theEvent) {
    if ([theEvent modifierFlags] & NSCommandKeyMask && [theEvent keyCode] == 13) {
        [self.window performClose:self];
    }
    return theEvent;
}];

这个方法很有效,但快捷键会在按下更多修改键时触发,比如 "⌃+⌘+W" 或 "⇧+⌃+⌥+⌘+W"。有没有什么方法可以规避这个问题?

一个简单的解决方案是检查所有其他修改键并确保它们未被按下。这似乎很繁琐且容易出错 - 再加上现在已经够丑陋了,只用一元运算符"&"。此外,如果(由于某种原因)键盘布局添加了另一个修饰键,则可能会遇到麻烦。

像往常一样,我感谢任何建议。

4个回答

34

5
哇,太棒了!现在我只需要使用一次一元运算符"&",终于明白NSDeviceIndependentModifierFlagsMask的用途了:modifierFlags通常默认设置为256,然后添加其他标志位,这样就可以清除未按下的键,只留下已按下的键所对应的modifierFlags值。这样可以像Carbon一样编写组合的修改键,例如 flags == NSCommandKeyMask + NSControlKeyMas,表示需要同时按下 ⌘ ⌃而不是写成 flags & NSCommandKeyMask && flags & NSControlKeyMask。非常感谢! - Florian Pilz
学究模式指导我们应该只使用(按位)OR(“|”)掩码。否则,进位位将会让你后悔不已。 - geowar
[theEvent modifierFlags] & (NSControlKeyMask|NSCommandKeyMask) 可用于多个。 - Yunus Nedim Mehel
1
不幸的是,由于苹果的原因,NSDeviceIndependentModifierFlagsMask已被弃用。回到绘图板。 - Duck

14

Swift 5 版本

if event.modifierFlags.intersection(.deviceIndependentFlagsMask) == .command {
    // Got it!
}

6

@JoshCaswell的回答已经过时,因为自10.12以来NSDeviceIndependentModifierFlagsMask已被弃用。

他的回答更新为新语法如下:

// Mask out everything but the key flags
NSUInteger flags = [theEvent modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
if( flags == NSCommandKeyMask ){
  // Got it!
}

NSDeviceIndependentModifierFlagsMask已被替换为NSEventModifierFlagDeviceIndependentFlagsMask,因为这样做有很大的区别...


2
也许更好的是...
if event.modifierFlags.contains(.shift){
    // do it
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接