使SHIFT + 3在OSX上通过代码产生`#`而不是`£` [英] Make SHIFT+3 produce `#` not `£` on OSX by code

查看:112
本文介绍了使SHIFT + 3在OSX上通过代码产生`#`而不是`£`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的英国MacBook Air上,可以使用OPT + 3键入#. SHIFT + 3当前产生£.如何重新布线,以便SHIFT + 3产生#?

On my UK MacBook Air, # can be typed using OPT+3. SHIFT+3 currently produces £. How can I rewire so that SHIFT+3 produces #?

该问题是由引起的. https://apple.stackexchange.com/questions/156154/use-option-as-meta-key-with-ability-to-type-the-symbol

我认为OSX的Terminal应用程序上的默认设置未注册OPT是失败的(例如,对于nano编辑器中的键盘快捷方式是必需的),并且如果您将设置切换为启用它,则现在无法键入#,通常由OPT + 3完成.

I think it's a failing that the default setting on OSX's Terminal app doesn't register OPT (which is needed e.g. for keyboard shortcuts in the nano editor), and that if you switch the setting to enable it, you are now unable to type #, which is generally done by OPT+3.

在使用nano的终端会话中编辑远程服务器上的配置文件时,我经常需要#.

I frequently need # while editing configuration files on my remote server in a Terminal session using nano.

我相信可以使用 Ukelele ,但我更希望使用代码级解决方案.

I believe it may be possible to use Ukelele but I would much prefer a code-level solution.

如果我可以通过代码完成此操作,那么我将学到一些东西!

If I can accomplish this by code, I will have learned something!

我尝试问>一个更通用的问题,但是OSX具有用于处理击键的复杂机制.这个问题首先属于!如果我能理解这一点,它将说明更一般情况的一部分.

I've tried asking a more generic question but OSX has a complex machinery for processing keystrokes. This question belongs first! If I can understand this, it will illuminate a component of the more general case.

推荐答案

此答案直接来自修改keyDown输出进行了很小的修改:

This answer come straight from Modify keyDown output with very minor adaptation:

// 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上通过代码产生`#`而不是`£`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆