2

I'm trying to bring an iPadOS app to macOS with catalyst. The app supports pointer (mouse/trackpad) interactions released with iPadOS 13.4. There are gestures in the app that work via secondary pointer click, but in the catalyst version they don't seem to work. No gesture recognizer or view seems to receive events that are initiated with a secondary click. I have also tried with a clean app and the results were the same.

While investigating this I overrode UIApplication with my custom implementation to catch all events via sendEvent(_:) and while debugging I confirmed that the events are delivered, to that point at least, but then no subsequent UIGestureRestureRecognizers or UIViews receive those events.

HangarRash
  • 7,314
  • 5
  • 5
  • 32
vicissim
  • 21
  • 1
  • This looks like a bug. I cannot get it working in Catalyst on Big Sur. However, I found a clue. If you hold down the primary and secondary mouse buttons, `UIEvent`'s `buttonMask` will contain `.secondary`. There is something wonky going on behind the scenes. – Timothy Davison Dec 11 '20 at 00:10

1 Answers1

0

Secondary click events can be intercepted in UIApplication's sendEvent:. The default implementation seems to be filtering them out. Here is an example implementation that forwards them to the ViewController:


- (void)sendEvent:(UIEvent *)event
{
    if (@available(macCatalyst 13.4, iOS 13.4, *)) {
        if (event.type == UIEventTypeTouches) {
            ViewController *vc = (ViewController *)self.delegate.window.rootViewController;
            NSSet<UITouch *> *touches = [event touchesForView:vc.view];
                
            NSMutableSet<UITouch *> *began = [NSMutableSet new];
            NSMutableSet<UITouch *> *moved = [NSMutableSet new];
            NSMutableSet<UITouch *> *ended = [NSMutableSet new];
            NSMutableSet<UITouch *> *cancelled = [NSMutableSet new];
            
            for (UITouch *touch in touches) {
                if (event.buttonMask == 2 && touch.phase == UITouchPhaseBegan) {
                    [began addObject:touch];
                    [secondaryTouches addObject:touch];
                }
                
                if (event.buttonMask == 2 && touch.phase == UITouchPhaseMoved) {
                    [moved addObject:touch];
                }
                
                if (touch.phase == UITouchPhaseEnded && [secondaryTouches containsObject:touch]) {
                    [ended addObject:touch];
                    [secondaryTouches removeObject:touch];
                }
                
                if (touch.phase == UITouchPhaseCancelled && [secondaryTouches containsObject:touch]) {
                    [cancelled addObject:touch];
                    [secondaryTouches removeObject:touch];
                }
            }
            
            if ([began count])
                [vc touchesBegan:began withEvent:event];
            if ([moved count])
                [vc touchesMoved:moved withEvent:event];
            if ([ended count])
                [vc touchesEnded:ended withEvent:event];
            if ([cancelled count])
                [vc touchesCancelled:cancelled withEvent:event];
        }
    }
    [super sendEvent:event];
}
Max Klint
  • 716
  • 5
  • 8