0

Right to the point, then:

First snippet (AppDelegate):

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    //...code taken out...

    [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *incomingEvent) {
        if ([incomingEvent type] == NSKeyDown) {
            NSUInteger flags = [incomingEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
            if (flags==NSCommandKeyMask && ([incomingEvent keyCode] == 8)) {
                [ClipboardUtilities logger:@"cmd+c recognized"];
                [self determineAndAddToHistory];
            }
        }
    }];
}

Second snippet (AppDelegate):

-(void) determineAndAddToHistory {
    id clipDat = [ClipboardUtilities getClipboardDataNatively];
    if ([clipDat isKindOfClass:[NSAttributedString class]])
        NSLog(@"clipDat.string = %@",((NSAttributedString*)clipDat).string);
}

Third snippet (ClipboardUtilities class):

+(id) getClipboardDataNatively {
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    NSArray *classArray = @[[NSAttributedString class], [NSImage class]];
    NSDictionary *options = [NSDictionary dictionary];

    NSArray *objectsToPaste = nil;
    BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options];
    if (ok) {
        objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options];
    }
        NSLog(@"objectsToPaste count = %li",[objectsToPaste count]);
    return [objectsToPaste objectAtIndex:0];
}

I've noticed some strange behaviour that I will try to explain with an example:

Input

  1. Cmd+C the string "A"
  2. Cmd+C the string "B"
  3. Cmd+C the string "C"
  4. Cmd+C the string "D"

Output from determineAndAddToHistory

  1. A
  2. A
  3. B
  4. C

So I'm noticing that it retains that first item for some reason...then returns me the second most recent item each time. I've tried outputting the objectsToPaste array in the getClipboardDataNatively method, and this still is the case. Could someone please let me know how I would approach this problem, or how they've solved it?

P.S. my ClipboardUtilities class does not implement any Delegates, or inherit from anything but NSObject.

  • I read somewhere that my clipboard (OS level) might be messed up, so I'm testing on another operating system. I'm actually new to Mac development, is there a way to spread builds without the mac developer certificate? Please let me know if it is illegal to do this. I also apologize if I sound like I'm asking people to spoon feed me. – MartinMystery Nov 13 '12 at 02:27

1 Answers1

0

Well I guess since nobody likes long questions (I'll have to figure out how to shorten this), I figured something out. For some reason, I get the hotkey call really quickly (the clipboard gets updated AFTER the key is called in fact). As a result, I just have a small delay, and my model is now updated properly:

NSTimer* briefDelay = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(determineAndAddToHistory) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:briefDelay forMode:NSRunLoopCommonModes];

I do not invalidate the timer manually, as per the documentation:

repeats
    If YES, the timer will repeatedly reschedule itself until invalidated. If NO, the timer will be invalidated after it fires.
  • I do not feel that this is the correct answer, as manually setting a delay for this kind of issue is not reliable (dependant on the CPU). I feel like I may have to lock it some how, but I need to be waiting for the clipboard to update...which will be tricky, since I may end up polling. I'll sleep on this. – MartinMystery Nov 14 '12 at 04:35