From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <jeremya@chromium.org>
Date: Wed, 10 Oct 2018 15:07:34 -0700
Subject: define Command::IsMediaKey on mac

Override MediaKeysListener::IsMediaKeycode to also listen for Volume Up, Volume Down,
and Mute. We also need to patch out Chromium's usage of RemoteCommandCenterDelegate, as
it uses MPRemoteCommandCenter. MPRemoteCommandCenter makes it such that GlobalShortcuts
in Electron will not work as intended, because by design an app does not receive remote
control events until it begins playing audio. This means that a media shortcut would not kick
into effect until you, for example, began playing a YouTube video which sort of defeats the
purpose of GlobalShortcuts.

At the moment there is no upstream possibility for this; but perhaps Chromium may
consider some kind of switch, enabled by default, which would conditionally choose to avoid usage of
RemoteCommandCenterDelegate on macOS.

Also apply electron/electron@0f67b1866a9f00b852370e721affa4efda623f3a
and electron/electron@d2368d2d3b3de9eec4cc32b6aaf035cc89921bf1 as
patches.

diff --git a/chrome/browser/extensions/global_shortcut_listener_win.cc b/chrome/browser/extensions/global_shortcut_listener_win.cc
index c5125495b4d178ffb18be4d2d9670f7556412cbd..cddb321abb938c667a4a2089f87eab999510e9b1 100644
--- a/chrome/browser/extensions/global_shortcut_listener_win.cc
+++ b/chrome/browser/extensions/global_shortcut_listener_win.cc
@@ -62,6 +62,8 @@ void GlobalShortcutListenerWin::OnWndProc(HWND hwnd,
   modifiers |= (LOWORD(lparam) & MOD_SHIFT) ? ui::EF_SHIFT_DOWN : 0;
   modifiers |= (LOWORD(lparam) & MOD_ALT) ? ui::EF_ALT_DOWN : 0;
   modifiers |= (LOWORD(lparam) & MOD_CONTROL) ? ui::EF_CONTROL_DOWN : 0;
+  modifiers |= (LOWORD(lparam) & MOD_WIN) ? ui::EF_COMMAND_DOWN : 0;
+
   ui::Accelerator accelerator(
       ui::KeyboardCodeForWindowsKeyCode(key_code), modifiers);
 
@@ -92,6 +94,7 @@ bool GlobalShortcutListenerWin::RegisterAcceleratorImpl(
   modifiers |= accelerator.IsShiftDown() ? MOD_SHIFT : 0;
   modifiers |= accelerator.IsCtrlDown() ? MOD_CONTROL : 0;
   modifiers |= accelerator.IsAltDown() ? MOD_ALT : 0;
+  modifiers |= accelerator.IsCmdDown() ? MOD_WIN : 0;
 
   // Create an observer that registers a hot key for |accelerator|.
   std::unique_ptr<gfx::SingletonHwndHotKeyObserver> observer =
diff --git a/chrome/browser/extensions/global_shortcut_listener_x11.cc b/chrome/browser/extensions/global_shortcut_listener_x11.cc
index 392cf3d58c64c088596e8d321a2ce37b0ec60b6e..43e30f47240dc10a3a9b950255d4e48792cc4159 100644
--- a/chrome/browser/extensions/global_shortcut_listener_x11.cc
+++ b/chrome/browser/extensions/global_shortcut_listener_x11.cc
@@ -38,6 +38,7 @@ int GetNativeModifiers(const ui::Accelerator& accelerator) {
   modifiers |= accelerator.IsShiftDown() ? ShiftMask : 0;
   modifiers |= accelerator.IsCtrlDown() ? ControlMask : 0;
   modifiers |= accelerator.IsAltDown() ? Mod1Mask : 0;
+  modifiers |= accelerator.IsCmdDown() ? Mod4Mask : 0;
 
   return modifiers;
 }
@@ -151,6 +152,8 @@ void GlobalShortcutListenerX11::OnXKeyPressEvent(::XEvent* x_event) {
   modifiers |= (x_event->xkey.state & ShiftMask) ? ui::EF_SHIFT_DOWN : 0;
   modifiers |= (x_event->xkey.state & ControlMask) ? ui::EF_CONTROL_DOWN : 0;
   modifiers |= (x_event->xkey.state & Mod1Mask) ? ui::EF_ALT_DOWN : 0;
+  // For Windows key
+  modifiers |= (x_event->xkey.state & Mod4Mask) ? ui::EF_COMMAND_DOWN: 0;
 
   ui::Accelerator accelerator(
       ui::KeyboardCodeFromXKeyEvent(x_event), modifiers);
diff --git a/ui/base/accelerators/media_keys_listener.cc b/ui/base/accelerators/media_keys_listener.cc
index 1145e1f3d79482b5bb468c3128431ac674310e5f..e9f595045e0c076e0735f27dfc38bfbc7951d372 100644
--- a/ui/base/accelerators/media_keys_listener.cc
+++ b/ui/base/accelerators/media_keys_listener.cc
@@ -13,7 +13,8 @@ MediaKeysListener::~MediaKeysListener() = default;
 // static
 bool MediaKeysListener::IsMediaKeycode(KeyboardCode key_code) {
   return key_code == VKEY_MEDIA_PLAY_PAUSE || key_code == VKEY_MEDIA_STOP ||
-         key_code == VKEY_MEDIA_PREV_TRACK || key_code == VKEY_MEDIA_NEXT_TRACK;
+         key_code == VKEY_MEDIA_PREV_TRACK || key_code == VKEY_MEDIA_NEXT_TRACK ||
+         key_code == VKEY_VOLUME_UP || key_code == VKEY_VOLUME_DOWN || key_code == VKEY_VOLUME_MUTE;
 }
 
 }  // namespace ui
diff --git a/ui/base/accelerators/media_keys_listener_mac.mm b/ui/base/accelerators/media_keys_listener_mac.mm
index f4e3126a4efd66f05c4f13e40ba23db10b8cca96..9232dda3fc82d9ad56fef96a2599312122d20cd4 100644
--- a/ui/base/accelerators/media_keys_listener_mac.mm
+++ b/ui/base/accelerators/media_keys_listener_mac.mm
@@ -11,6 +11,7 @@
 #include <IOKit/hidsystem/ev_keymap.h>
 
 #include "base/containers/flat_set.h"
+#include "electron/buildflags/buildflags.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/base/accelerators/remote_command_media_keys_listener_mac.h"
 #include "ui/base/now_playing/remote_command_center_delegate.h"
@@ -33,6 +34,12 @@ KeyboardCode MediaKeyCodeToKeyboardCode(int key_code) {
     case NX_KEYTYPE_NEXT:
     case NX_KEYTYPE_FAST:
       return VKEY_MEDIA_NEXT_TRACK;
+    case NX_KEYTYPE_SOUND_UP:
+      return VKEY_VOLUME_UP;
+    case NX_KEYTYPE_SOUND_DOWN:
+      return VKEY_VOLUME_DOWN;
+    case NX_KEYTYPE_MUTE:
+      return VKEY_VOLUME_MUTE;
   }
   return VKEY_UNKNOWN;
 }
@@ -193,7 +200,10 @@ CGEventRef MediaKeysListenerImpl::EventTapCallback(CGEventTapProxy proxy,
   int key_code = (data1 & 0xFFFF0000) >> 16;
   if (key_code != NX_KEYTYPE_PLAY && key_code != NX_KEYTYPE_NEXT &&
       key_code != NX_KEYTYPE_PREVIOUS && key_code != NX_KEYTYPE_FAST &&
-      key_code != NX_KEYTYPE_REWIND) {
+      key_code != NX_KEYTYPE_REWIND &&
+      key_code != NX_KEYTYPE_SOUND_UP &&
+      key_code != NX_KEYTYPE_SOUND_DOWN &&
+      key_code != NX_KEYTYPE_MUTE) {
     return event;
   }
 
@@ -224,6 +234,7 @@ std::unique_ptr<MediaKeysListener> MediaKeysListener::Create(
   // For Mac OS 10.12.2 or later, we want to use MPRemoteCommandCenter for
   // getting media keys globally if there is a RemoteCommandCenterDelegate
   // available.
+#if !BUILDFLAG(ENABLE_MEDIA_KEY_OVERRIDES)
   if (@available(macOS 10.12.2, *)) {
     if (scope == Scope::kGlobal &&
         now_playing::RemoteCommandCenterDelegate::GetInstance()) {
@@ -233,6 +244,7 @@ std::unique_ptr<MediaKeysListener> MediaKeysListener::Create(
       return std::move(listener);
     }
   }
+#endif
 
   return std::make_unique<MediaKeysListenerImpl>(delegate, scope);
 }
