通过代码使 SHIFT+3 在 OSX 上生成 `#` 而不是 `£`
Posted
技术标签:
【中文标题】通过代码使 SHIFT+3 在 OSX 上生成 `#` 而不是 `£`【英文标题】:Make SHIFT+3 produce `#` not `£` on OSX by code 【发布时间】:2015-07-31 21:34:06 【问题描述】:在我的英国 MacBook Air 上,#
可以使用 OPT+3 键入。 SHIFT+3 当前生成£
。如何重新连线以便 SHIFT+3 产生#
?
这个问题的动机是https://apple.stackexchange.com/questions/156154/use-option-as-meta-key-with-ability-to-type-the-symbol
我认为 OSX 终端应用程序的默认设置没有注册 OPT(例如 nano 编辑器中的键盘快捷键需要)是一个失败,并且如果您切换设置以启用它,您现在无法输入#
,一般通过OPT+3完成。
在使用 nano 的终端会话中编辑远程服务器上的配置文件时,我经常需要 #
。
我相信可以使用Ukelele,但我更喜欢代码级解决方案。
如果我可以通过代码完成此操作,我将学到一些东西!
我试过询问a more generic question,但 OSX 有一个复杂的机制来处理击键。这个问题属于第一!如果我能理解这一点,它将阐明更一般情况的一个组成部分。
【问题讨论】:
【参考方案1】:这个答案直接来自Modify keyDown output,做了非常小的改编:
// compile and run from the commandline with:
// clang -fobjc-arc -framework Cocoa ./foo.m -o foo
// sudo ./foo
#import <Foundation/Foundation.h>
#import <AppKit/NSEvent.h>
typedef CFMachPortRef EventTap;
// - - - - - - - - - - - - - - - - - - - - -
@interface KeyChanger : NSObject
@private
EventTap _eventTap;
CFRunLoopSourceRef _runLoopSource;
CGEventRef _lastEvent;
@end
// - - - - - - - - - - - - - - - - - - - - -
CGEventRef _tapCallback(
CGEventTapProxy proxy,
CGEventType type,
CGEventRef event,
KeyChanger* listener
);
// - - - - - - - - - - - - - - - - - - - - -
@implementation KeyChanger
- (BOOL)tapEvents
if (!_eventTap)
NSLog(@"Initializing an event tap.");
_eventTap = CGEventTapCreate(kCGSessionEventTap,
kCGTailAppendEventTap,
kCGEventTapOptionDefault,
CGEventMaskBit( kCGEventKeyDown ),
(CGEventTapCallBack)_tapCallback,
(__bridge void *)(self));
if (!_eventTap)
NSLog(@"unable to create event tap. must run as root or "
"add privlidges for assistive devices to this app.");
return NO;
CGEventTapEnable(_eventTap, TRUE);
return [self isTapActive];
- (BOOL)isTapActive
return CGEventTapIsEnabled(_eventTap);
- (void)listen
if( ! _runLoopSource )
if( _eventTap ) //dont use [self tapActive]
_runLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault,
_eventTap, 0);
// Add to the current run loop.
CFRunLoopAddSource( CFRunLoopGetCurrent(), _runLoopSource,
kCFRunLoopCommonModes);
NSLog(@"Registering event tap as run loop source.");
CFRunLoopRun();
else
NSLog(@"No Event tap in place! You will need to call "
"listen after tapEvents to get events.");
- (CGEventRef)processEvent:(CGEventRef)cgEvent
NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
NSUInteger modifiers = [event modifierFlags] &
(NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask);
enum
kVK_ANSI_3 = 0x14,
;
// TODO: add other cases and do proper handling of case
if (
//[event.characters caseInsensitiveCompare:@"3"] == NSOrderedSame
event.keyCode == kVK_ANSI_3
&& modifiers == NSShiftKeyMask
)
NSLog(@"Got SHIFT+3");
event = [NSEvent keyEventWithType: event.type
location: NSZeroPoint
modifierFlags: event.modifierFlags & ! NSShiftKeyMask
timestamp: event.timestamp
windowNumber: event.windowNumber
context: event.context
characters: @"#"
charactersIgnoringModifiers: @"#"
isARepeat: event.isARepeat
keyCode: event.keyCode];
_lastEvent = [event CGEvent];
CFRetain(_lastEvent); // must retain the event. will be released by the system
return _lastEvent;
- (void)dealloc
if( _runLoopSource )
CFRunLoopRemoveSource( CFRunLoopGetCurrent(), _runLoopSource, kCFRunLoopCommonModes );
CFRelease( _runLoopSource );
if( _eventTap )
//kill the event tap
CGEventTapEnable( _eventTap, FALSE );
CFRelease( _eventTap );
@end
// - - - - - - - - - - - - - - - - - - - - -
CGEventRef _tapCallback(
CGEventTapProxy proxy,
CGEventType type,
CGEventRef event,
KeyChanger* listener
)
//Do not make the NSEvent here.
//NSEvent will throw an exception if we try to make an event from the tap timout type
@autoreleasepool
if( type == kCGEventTapDisabledByTimeout )
NSLog(@"event tap has timed out, re-enabling tap");
[listener tapEvents];
return nil;
if( type != kCGEventTapDisabledByUserInput )
return [listener processEvent:event];
return event;
// - - - - - - - - - - - - - - - - - - - - -
int main(int argc, const char * argv[])
@autoreleasepool
KeyChanger* keyChanger = [KeyChanger new];
[keyChanger tapEvents];
[keyChanger listen];//blocking call.
return 0;
【讨论】:
以上是关于通过代码使 SHIFT+3 在 OSX 上生成 `#` 而不是 `£`的主要内容,如果未能解决你的问题,请参考以下文章
Beanstalk:如何将服务器上生成的文件同步回 beanstalk 存储库?
如何在 Swift 3 中的 mapview 上生成不同的图钉?