diff --git a/patches/chromium/.patches b/patches/chromium/.patches index 7395c7bba966b..55f533e97296b 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -104,3 +104,4 @@ hack_to_allow_gclient_sync_with_host_os_mac_on_linux_in_ci.patch add_gin_wrappable_crash_key.patch revert_roll_clang_llvmorg-13-init-14732-g8a7b5ebf-2.patch logging_win32_only_create_a_console_if_logging_to_stderr.patch +fix_media_key_usage_with_globalshortcuts.patch diff --git a/patches/chromium/fix_media_key_usage_with_globalshortcuts.patch b/patches/chromium/fix_media_key_usage_with_globalshortcuts.patch new file mode 100644 index 0000000000000..1072fb48d3014 --- /dev/null +++ b/patches/chromium/fix_media_key_usage_with_globalshortcuts.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Shelley Vohr +Date: Mon, 16 Aug 2021 17:55:32 +0200 +Subject: fix: media key usage with globalShortcuts + +This patch enables media keys to work properly with Electron's globalShortcut +module. Chromium's default usage of RemoteCommandCenterDelegate on macOS falls +down into MPRemoteCommandCenter, which makes it such that an app will not +receive remote control events until it begins playing audio. This runs +counter to the design of globalShortcuts, and so we need to instead +use `ui::MediaKeysListener`. + +diff --git a/content/browser/media/media_keys_listener_manager_impl.cc b/content/browser/media/media_keys_listener_manager_impl.cc +index 5938f75742b793868638e693a9a8c8dc686dfc46..bf8782c23095a09dec62c68d7d902df24abcb13e 100644 +--- a/content/browser/media/media_keys_listener_manager_impl.cc ++++ b/content/browser/media/media_keys_listener_manager_impl.cc +@@ -231,7 +231,7 @@ void MediaKeysListenerManagerImpl::StartListeningForMediaKeysIfNecessary() { + media::AudioManager::GetGlobalAppName()); + #endif + +- if (system_media_controls_) { ++ if (/* DISABLES CODE */ (0)) { + system_media_controls_->AddObserver(this); + system_media_controls_notifier_ = + std::make_unique( +@@ -239,8 +239,13 @@ void MediaKeysListenerManagerImpl::StartListeningForMediaKeysIfNecessary() { + } else { + // If we can't access system media controls, then directly listen for media + // key keypresses instead. ++#if defined(OS_MAC) ++ media_keys_listener_ = ui::MediaKeysListener::Create( ++ this, ui::MediaKeysListener::Scope::kGlobalRequiresAccessibility); ++#else + media_keys_listener_ = ui::MediaKeysListener::Create( + this, ui::MediaKeysListener::Scope::kGlobal); ++#endif + DCHECK(media_keys_listener_); + } + +diff --git a/ui/base/accelerators/media_keys_listener.h b/ui/base/accelerators/media_keys_listener.h +index c2b03328c0e508995bdc135031500783f500ceba..1b6b14dc2999c99445cef6ffc04d49a7c1728a54 100644 +--- a/ui/base/accelerators/media_keys_listener.h ++++ b/ui/base/accelerators/media_keys_listener.h +@@ -20,6 +20,7 @@ class Accelerator; + class COMPONENT_EXPORT(UI_BASE) MediaKeysListener { + public: + enum class Scope { ++ kGlobalRequiresAccessibility, // Listener works whenever application in focus or not but requires accessibility permissions on macOS + kGlobal, // Listener works whenever application in focus or not. + kFocused, // Listener only works whan application has focus. + }; +diff --git a/ui/base/accelerators/media_keys_listener_win.cc b/ui/base/accelerators/media_keys_listener_win.cc +index 6c63a88cbb13cfcc9a8ba652554839275ae1ee04..1643eafc094dce77e4ba8752cd02e1ae6c488b56 100644 +--- a/ui/base/accelerators/media_keys_listener_win.cc ++++ b/ui/base/accelerators/media_keys_listener_win.cc +@@ -13,7 +13,7 @@ std::unique_ptr MediaKeysListener::Create( + MediaKeysListener::Scope scope) { + DCHECK(delegate); + +- if (scope == Scope::kGlobal) { ++ if (scope == Scope::kGlobal || scope == Scope::kGlobalRequiresAccessibility) { + // We should never have more than one global media keys listener. + if (!GlobalMediaKeysListenerWin::has_instance()) + return std::make_unique(delegate); diff --git a/spec-main/api-global-shortcut-spec.ts b/spec-main/api-global-shortcut-spec.ts index 36d5191e5642f..689ea56bbb363 100644 --- a/spec-main/api-global-shortcut-spec.ts +++ b/spec-main/api-global-shortcut-spec.ts @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { globalShortcut } from 'electron/main'; +import { globalShortcut, BrowserWindow } from 'electron/main'; import { ifdescribe } from './spec-helpers'; ifdescribe(process.platform !== 'win32')('globalShortcut module', () => { @@ -55,4 +55,20 @@ ifdescribe(process.platform !== 'win32')('globalShortcut module', () => { globalShortcut.unregisterAll(); }); + + it('successfully registers and calls the callback for media keys', function (done) { + let robotjs; + try { + robotjs = require('robotjs'); + } catch (err) { + this.skip(); + } + + globalShortcut.register('MediaPlayPause', () => done()); + + const w = new BrowserWindow({ show: false }); + w.loadURL('about:blank'); + + robotjs.keyTap('audio_play'); + }); });