防止事件监视器中的错误 "funk" 声音 OS X
Prevent error "funk" sound in event monitor OS X
我正在 swift 中编写一个位于屏幕顶部菜单栏中的应用程序。我需要一个全局和本地事件监视器来打开特定按键上的弹出窗口。本地事件监视器没有问题,但是当用户从 Finder 等应用程序中按下键盘命令 (cmd+shift+8) 时,弹出窗口打开但 mac 错误 "Funk" 声音是也玩过。有什么办法可以禁用它吗?也许应用程序可以通过某种方式吃掉声音,或者将其注册为有效的键盘快捷键以便永远不会播放声音?
代码如下:
NSEvent.addGlobalMonitorForEvents(matching: NSEventMask.keyDown, handler: {(event: NSEvent!) -> Void in
if (event.keyCode == 28 && event.modifierFlags.contains(NSEventModifierFlags.command) && event.modifierFlags.contains(NSEventModifierFlags.shift)){
self.togglePopover(sender: self)
}
});
NSEvent.addLocalMonitorForEvents(matching: NSEventMask.keyDown, handler: {(event: NSEvent!) -> NSEvent? in
if (event.keyCode == 28 && event.modifierFlags.contains(NSEventModifierFlags.command) && event.modifierFlags.contains(NSEventModifierFlags.shift)){
self.togglePopover(sender: self)
}
return event
});
我最终使用 MASShortcut 作为解决此问题的解决方案。
在您的 addGlobalMonitorForEventsMatchingMask
处理程序中,保存当前音量级别并调低两个频道的音量。您可以在调低音量之前或之后在处理程序中进行自己的事件处理。
在从处理程序返回之前,恢复原始音量,但包括延迟以给予 OS 处理事件的时间(它将发送 "funk," 但你听不到)。
一个副作用:如果您正在听某些东西(例如音乐),它也会被暂时静音。
我的活动代码:
[NSEvent addGlobalMonitorForEventsMatchingMask:NSEventMaskKeyDown
handler:^(NSEvent *event) {
if ( event.type == NSEventTypeKeyDown ) {
if ( event.keyCode == 106 ) { // F16
// process the event here
[self adjustVolume:@(NO)];
[self performSelector:@selector(adjustVolume:) withObject:@(YES) afterDelay:0.3];
// 0.2 seconds was too soon
}
}
}];
我的音量调节码:
- (void)adjustVolume:(NSNumber *)offOn
{
// get audio device...
AudioObjectPropertyAddress getDefaultOutputDevicePropertyAddress = {
kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
AudioDeviceID defaultOutputDeviceID;
UInt32 infoSize = sizeof(defaultOutputDeviceID);
AudioObjectGetPropertyData(kAudioObjectSystemObject,
&getDefaultOutputDevicePropertyAddress,
0, NULL,
&infoSize, &defaultOutputDeviceID);
// structurs to access the left/right volume setting
AudioObjectPropertyAddress volumePropertyAddress1 = {
kAudioDevicePropertyVolumeScalar,
kAudioDevicePropertyScopeOutput,
1 /* left */
};
AudioObjectPropertyAddress volumePropertyAddress2 = {
kAudioDevicePropertyVolumeScalar,
kAudioDevicePropertyScopeOutput,
2 /* right */
};
// save the original volume (assumes left/right are the same
static Float32 volumeOriginal; // could be an iVar
if ( offOn.boolValue == NO ) { // turn off
UInt32 volumedataSize = sizeof(volumeOriginal);
AudioObjectGetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress1,
0, NULL,
&volumedataSize, &volumeOriginal);
//NSLog(@"volumeOriginal %f",volumeOriginal);
// turn off both channels
Float32 volume = 0.0;
AudioObjectSetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress1,
0, NULL,
sizeof(volume), &volume);
AudioObjectSetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress2,
0, NULL,
sizeof(volume), &volume);
} else { // restore
//NSLog(@"restoring volume");
AudioObjectSetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress1,
0, NULL,
sizeof(volumeOriginal), &volumeOriginal);
AudioObjectSetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress2,
0, NULL,
sizeof(volumeOriginal), &volumeOriginal);
}
}
感谢 Thomas O'Dell 让我开始了这个 Change OS X system volume programmatically
我正在 swift 中编写一个位于屏幕顶部菜单栏中的应用程序。我需要一个全局和本地事件监视器来打开特定按键上的弹出窗口。本地事件监视器没有问题,但是当用户从 Finder 等应用程序中按下键盘命令 (cmd+shift+8) 时,弹出窗口打开但 mac 错误 "Funk" 声音是也玩过。有什么办法可以禁用它吗?也许应用程序可以通过某种方式吃掉声音,或者将其注册为有效的键盘快捷键以便永远不会播放声音?
代码如下:
NSEvent.addGlobalMonitorForEvents(matching: NSEventMask.keyDown, handler: {(event: NSEvent!) -> Void in
if (event.keyCode == 28 && event.modifierFlags.contains(NSEventModifierFlags.command) && event.modifierFlags.contains(NSEventModifierFlags.shift)){
self.togglePopover(sender: self)
}
});
NSEvent.addLocalMonitorForEvents(matching: NSEventMask.keyDown, handler: {(event: NSEvent!) -> NSEvent? in
if (event.keyCode == 28 && event.modifierFlags.contains(NSEventModifierFlags.command) && event.modifierFlags.contains(NSEventModifierFlags.shift)){
self.togglePopover(sender: self)
}
return event
});
我最终使用 MASShortcut 作为解决此问题的解决方案。
在您的
addGlobalMonitorForEventsMatchingMask
处理程序中,保存当前音量级别并调低两个频道的音量。您可以在调低音量之前或之后在处理程序中进行自己的事件处理。在从处理程序返回之前,恢复原始音量,但包括延迟以给予 OS 处理事件的时间(它将发送 "funk," 但你听不到)。
一个副作用:如果您正在听某些东西(例如音乐),它也会被暂时静音。
我的活动代码:
[NSEvent addGlobalMonitorForEventsMatchingMask:NSEventMaskKeyDown
handler:^(NSEvent *event) {
if ( event.type == NSEventTypeKeyDown ) {
if ( event.keyCode == 106 ) { // F16
// process the event here
[self adjustVolume:@(NO)];
[self performSelector:@selector(adjustVolume:) withObject:@(YES) afterDelay:0.3];
// 0.2 seconds was too soon
}
}
}];
我的音量调节码:
- (void)adjustVolume:(NSNumber *)offOn
{
// get audio device...
AudioObjectPropertyAddress getDefaultOutputDevicePropertyAddress = {
kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
AudioDeviceID defaultOutputDeviceID;
UInt32 infoSize = sizeof(defaultOutputDeviceID);
AudioObjectGetPropertyData(kAudioObjectSystemObject,
&getDefaultOutputDevicePropertyAddress,
0, NULL,
&infoSize, &defaultOutputDeviceID);
// structurs to access the left/right volume setting
AudioObjectPropertyAddress volumePropertyAddress1 = {
kAudioDevicePropertyVolumeScalar,
kAudioDevicePropertyScopeOutput,
1 /* left */
};
AudioObjectPropertyAddress volumePropertyAddress2 = {
kAudioDevicePropertyVolumeScalar,
kAudioDevicePropertyScopeOutput,
2 /* right */
};
// save the original volume (assumes left/right are the same
static Float32 volumeOriginal; // could be an iVar
if ( offOn.boolValue == NO ) { // turn off
UInt32 volumedataSize = sizeof(volumeOriginal);
AudioObjectGetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress1,
0, NULL,
&volumedataSize, &volumeOriginal);
//NSLog(@"volumeOriginal %f",volumeOriginal);
// turn off both channels
Float32 volume = 0.0;
AudioObjectSetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress1,
0, NULL,
sizeof(volume), &volume);
AudioObjectSetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress2,
0, NULL,
sizeof(volume), &volume);
} else { // restore
//NSLog(@"restoring volume");
AudioObjectSetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress1,
0, NULL,
sizeof(volumeOriginal), &volumeOriginal);
AudioObjectSetPropertyData(defaultOutputDeviceID,
&volumePropertyAddress2,
0, NULL,
sizeof(volumeOriginal), &volumeOriginal);
}
}
感谢 Thomas O'Dell 让我开始了这个 Change OS X system volume programmatically