How to get other application to paste from my global hotkey

十年热恋 提交于 2019-12-20 06:26:47

问题


I have written a small productivity tool that does a few string manipulations via the clipboard.

It is currently registering a hot key, where it pulls in the clipboard text, processes it, and dumps the result back on the clipboard.

I have this installed on CMD+SHIFT+V

currently what you need to do from another apppiclation is copy (CMD+C) and then activate my hothandler (CMD+SHIFT+V), and then you have to paste it back into the orginal app with (CMD+V).

I'd like to eliminate the third step if possible, so my hothandler somehow tells whatever is the active application to paste.

Any suggestions how to do this?

My code (minus the actual boring text replacement stuff) is this:

Please note this needs carbon framework for hotkey handlers

[EDIT:] I borrowed code from this answer on stack overflow for the hotkey handler code.

AppDelegate.h

#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import <Carbon/Carbon.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>  {

    EventHotKeyRef  hotKeyRef;
}

@property (assign) IBOutlet NSWindow *window;
-(IBAction) checkClipboard:(id) sender ;

@end

AppDelegate.m

#import "AppDelegate.h"
//#import "NSString+cppMacros.h" // not relevant to question




OSStatus _AppDelegateHotKeyHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData) {
    AppDelegate *appDel = [[NSApplication sharedApplication] delegate];
    [appDel checkClipboard:nil];
    return noErr;
}

@implementation AppDelegate



- (void)installHotkey {

    if (!hotKeyRef) {
        EventHotKeyID   hotKeyId;
        EventTypeSpec   eventType;

        eventType.eventClass    = kEventClassKeyboard;
        eventType.eventKind     = kEventHotKeyPressed;

        InstallApplicationEventHandler(&_AppDelegateHotKeyHandler, 1, &eventType, NULL, NULL);

        hotKeyId.signature  = 'hotk';
        hotKeyId.id         = 1337;

        RegisterEventHotKey(kVK_ANSI_V, cmdKey + shiftKey, hotKeyId, GetApplicationEventTarget(), 0, &hotKeyRef);
        NSLog(@"_AppDelegateHotKeyHandler installed");

    }
}

-(void) uninstallHotkey {
    if (hotKeyRef) {
        UnregisterEventHotKey(hotKeyRef);
        hotKeyRef = nil;
        NSLog(@"_AppDelegateHotKeyHandler uninstalled");
    }

}



-(IBAction) checkClipboard:(id) sender {

    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];


    NSArray *types = [NSArray arrayWithObjects:NSStringPboardType, nil];



    NSString *text = [pasteboard  stringForType:NSPasteboardTypeString];

    NSLog(@"clipboard input:%@",text);

    /* actual code is this: (not relevant to question)
     NSString *newText = [text isMacroEncoded] ? [text macroDecodedString] : [text macroEncodedString];
     */
    // demo code for question

    NSString *newText = [@"Pasted:" stringByAppendingString:text];


    [pasteboard declareTypes:types owner:self];

    [pasteboard setString:newText forType:NSStringPboardType];

    NSLog(@"clipboard output:%@",newText);

}


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    hotKeyRef = nil;
    [self installHotkey];
}

-(void) applicationWillTerminate:(NSNotification *)notification {
    [self uninstallHotkey];
}



@end

回答1:


You don't want to use a global hot key for this. You want to write your application so that it provides a "service". See the Services Implementation Guide.

Your service can be activated by a keyboard shortcut, either the default configured in your app's Info.plist or one configured by the user in System Preferences.

Cocoa takes care of both copying from the active app and pasting into it after you've done the transformation, so this will take care of the first and third steps.

Services use a separate pasteboard for transferring data, so this also doesn't interfere with the contents of the general (copy and paste) pasteboard.

It's a superior approach on every level.


Edited to add other benefits:

A service won't steal a keyboard shortcut from the active app.

A service is also available via the application menu and context menu. That makes it discoverable.




回答2:


It turns out there is a way to do what I want.

void pasteCurrent() {

    CGEventRef commandDown = CGEventCreateKeyboardEvent(NULL, kVK_Command, YES);
    CGEventRef VDown = CGEventCreateKeyboardEvent(NULL, kVK_ANSI_V, YES);

    CGEventRef VUp = CGEventCreateKeyboardEvent(NULL, kVK_ANSI_V, NO);
    CGEventRef commandUp = CGEventCreateKeyboardEvent(NULL, kVK_Command, NO);

    CGEventSetFlags(VDown,kCGEventFlagMaskCommand);
    CGEventSetFlags(VUp,kCGEventFlagMaskCommand);

    CGEventPost(kCGHIDEventTap, commandDown);
    CGEventPost(kCGHIDEventTap, VDown);
    CGEventPost(kCGHIDEventTap, VUp);
    CGEventPost(kCGHIDEventTap, commandUp);

    CFRelease(commandDown);
    CFRelease(VDown);
    CFRelease(VUp);
    CFRelease(commandUp);

}


来源:https://stackoverflow.com/questions/20169242/how-to-get-other-application-to-paste-from-my-global-hotkey

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!