11

On Mac OS X, doing a 3-finger tap on a word pops up a window with a definition of the word.

Image showing a pop up window showing a word definition.

This idiom is also used in Xcode, where doing a 3-finger tap over a symbol shows its documentation, much like if it had been alt+clicked.

Image showing a pop up window showing symbol documentation.

I would like to do something similar to that and display definitions when users of my application do a 3-finger tap on certain tokens in a NSTextView. However, I can't find how to detect that a tap has been done with 3 fingers. Could someone help me with that?

EDIT If this reminds anything to anyone, three events (caught by overriding [NSApplication sendEvent:]) are triggered when you do this kind of tap:

NSEvent: type=SysDefined loc=(270.918,250.488) time=417954.6 flags=0x100 win=0x0 winNum=28293 ctxt=0x0 subtype=6 data1=1818981744 data2=1818981744
NSEvent: type=SysDefined loc=(270.918,250.488) time=417954.6 flags=0x100 win=0x0 winNum=28293 ctxt=0x0 subtype=9 data1=1818981744 data2=1818981744
NSEvent: type=Kitdefined loc=(0,263) time=417954.8 flags=0x100 win=0x0 winNum=28306 ctxt=0x0 subtype=4 data1=1135411200 data2=1132691456
MPelletier
  • 16,256
  • 15
  • 86
  • 137
zneak
  • 134,922
  • 42
  • 253
  • 328

2 Answers2

8

Reacting on a triple tap in a NSTextView can most easily be done by overriding quickLookWithEvent:.

-(void)quickLookWithEvent:(NSEvent *)event
{
    NSLog(@"Look at me! %@", event);
}

It also taught me that you can triple tap anything to invoke Quick Look on it.

zneak
  • 134,922
  • 42
  • 253
  • 328
  • a few months late @zneak, but `quickLookWithEvent:` is documented as [being in `NSResponder` as of 10.8](https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/NSResponder/quickLookWithEvent:) – andlabs Apr 24 '14 at 16:01
  • Oh, sweet. I guess I just missed it then. – zneak Apr 24 '14 at 16:08
1

Subclass NSTextView and override mouse down event (this is where the view usually handle the click/tap events):

-(void)mouseDown:(NSEvent*)event
{
  if (event.clickCount == 3)
  {
    //Do your thing
  }
}

Hope this helps.

If the triple click does not work for you (I am not currently in from of my mac to check), you could try something else. I know it works in iOS, I don't know about the trackpad gestures.

You could try adding a UITapGestureRecognizer to your view:

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTapped:)];
tapGesture.numberOfTouchesRequired = 3;

//....

-(void)viewTapped:(UITapGestureRecognizer*)tap
{
  if(tap.state == UIGestureRecognizerStateRecognized)
  {
    //you detected a three finger tap, do work
  } 
}

LATER EDIT:

I found this article in the apple documentation. Based on a sample from this article, here is some code which should be useful (from listing 8-5):

- (void)touchesBeganWithEvent:(NSEvent *)event {
    if (!self.isEnabled) return;

    NSSet *touches = [event touchesMatchingPhase:NSTouchPhaseTouching inView:self.view];

    if (touches.count == 3) 
    {
       //Three finger touch detected
    }

    [super touchesBeganWithEvent:event];
}
nestedloop
  • 2,596
  • 23
  • 34
  • Your `mouseDown:` example works for doing 3 successive taps but does not catch taps made with 3 fingers. – zneak Dec 16 '13 at 18:32
  • @zneak I realized that pretty fast, so I added the second part. I really think that can lead to a solution to your problem, if it would be available for the trackpad, which in the mean time I found it is not. However, I found something in the apple documentation which I am editing into my answer. – nestedloop Dec 16 '13 at 20:40