Browse Source

fix: macOS tray button selection with VoiceOver (#39448)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <[email protected]>
trop[bot] 1 year ago
parent
commit
dfd80db886
1 changed files with 25 additions and 1 deletions
  1. 25 1
      shell/browser/ui/tray_icon_cocoa.mm

+ 25 - 1
shell/browser/ui/tray_icon_cocoa.mm

@@ -51,7 +51,12 @@
     NSStatusItem* item = [[NSStatusBar systemStatusBar]
         statusItemWithLength:NSVariableStatusItemLength];
     statusItem_.reset([item retain]);
-    [[statusItem_ button] addSubview:self];  // inject custom view
+    [[statusItem_ button] addSubview:self];
+
+    // We need to set the target and action on the button, otherwise
+    // VoiceOver doesn't know where to send the select action.
+    [[statusItem_ button] setTarget:self];
+    [[statusItem_ button] setAction:@selector(mouseDown:)];
     [self updateDimensions];
   }
   return self;
@@ -185,6 +190,25 @@
 }
 
 - (void)mouseDown:(NSEvent*)event {
+  // If |event| does not respond to locationInWindow, we've
+  // arrived here from VoiceOver, which does not pass an event.
+  // Create a synthetic event to pass to the click handler.
+  if (![event respondsToSelector:@selector(locationInWindow)]) {
+    event = [NSEvent mouseEventWithType:NSEventTypeRightMouseDown
+                               location:NSMakePoint(0, 0)
+                          modifierFlags:0
+                              timestamp:NSApp.currentEvent.timestamp
+                           windowNumber:0
+                                context:nil
+                            eventNumber:0
+                             clickCount:1
+                               pressure:1.0];
+
+    // We also need to explicitly call the click handler here, since
+    // VoiceOver won't trigger mouseUp.
+    [self handleClickNotifications:event];
+  }
+
   trayIcon_->NotifyMouseDown(
       gfx::ScreenPointFromNSPoint([event locationInWindow]),
       ui::EventFlagsFromModifiers([event modifierFlags]));