From 0efcaec4d6ce71221160c96a26a366e9c5bff98a Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Mon, 24 Aug 2020 10:41:06 -0700 Subject: [PATCH] fix: global shortcut media keys working with accessibility (#24145) * fix: global shortcut media keys * update patches Co-authored-by: Electron Bot --- ...use_key_listener_for_internal_chrome.patch | 68 +++++++++++++++++++ .../api/electron_api_global_shortcut.cc | 26 ++++++- 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/patches/chromium/fix_use_the_new_mediaplaypause_key_listener_for_internal_chrome.patch b/patches/chromium/fix_use_the_new_mediaplaypause_key_listener_for_internal_chrome.patch index b711b3c08f7b..1a95d39b04b6 100644 --- a/patches/chromium/fix_use_the_new_mediaplaypause_key_listener_for_internal_chrome.patch +++ b/patches/chromium/fix_use_the_new_mediaplaypause_key_listener_for_internal_chrome.patch @@ -8,6 +8,54 @@ The new kGlobalRequiresAccessibility Scope type should be upstreamed and then we can use that and minimize this patch to just the change in global_shortcut_listener_mac.mm +diff --git a/chrome/browser/extensions/global_shortcut_listener.cc b/chrome/browser/extensions/global_shortcut_listener.cc +index bc009606d01469125052e68a9cdc82aaa697c764..ff18043cb07d748a49adea9874517fb29e3e7f9f 100644 +--- a/chrome/browser/extensions/global_shortcut_listener.cc ++++ b/chrome/browser/extensions/global_shortcut_listener.cc +@@ -7,6 +7,7 @@ + #include "base/check.h" + #include "base/notreached.h" + #include "content/public/browser/browser_thread.h" ++#include "content/public/browser/media_keys_listener_manager.h" + #include "ui/base/accelerators/accelerator.h" + + using content::BrowserThread; +@@ -66,6 +67,22 @@ void GlobalShortcutListener::UnregisterAccelerator( + StopListening(); + } + ++// static ++void GlobalShortcutListener::SetShouldUseInternalMediaKeyHandling(bool should_use) { ++ if (content::MediaKeysListenerManager:: ++ IsMediaKeysListenerManagerEnabled()) { ++ content::MediaKeysListenerManager* media_keys_listener_manager = ++ content::MediaKeysListenerManager::GetInstance(); ++ DCHECK(media_keys_listener_manager); ++ ++ if (should_use) { ++ media_keys_listener_manager->EnableInternalMediaKeyHandling(); ++ } else { ++ media_keys_listener_manager->DisableInternalMediaKeyHandling(); ++ } ++ } ++} ++ + void GlobalShortcutListener::UnregisterAccelerators(Observer* observer) { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (IsShortcutHandlingSuspended()) +diff --git a/chrome/browser/extensions/global_shortcut_listener.h b/chrome/browser/extensions/global_shortcut_listener.h +index 9aec54a3263d24491d24013a80b719dfc834ecd4..001a6cb2a5eb701351fa924109b43fab6f30748d 100644 +--- a/chrome/browser/extensions/global_shortcut_listener.h ++++ b/chrome/browser/extensions/global_shortcut_listener.h +@@ -31,6 +31,8 @@ class GlobalShortcutListener { + + static GlobalShortcutListener* GetInstance(); + ++ static void SetShouldUseInternalMediaKeyHandling(bool should_use); ++ + // Register an observer for when a certain |accelerator| is struck. Returns + // true if register successfully, or false if 1) the specificied |accelerator| + // has been registered by another caller or other native applications, or diff --git a/chrome/browser/extensions/global_shortcut_listener_mac.mm b/chrome/browser/extensions/global_shortcut_listener_mac.mm index befe726af9c10b1563a7fc0bb77cc55f65943d5c..bac51f33f35f96fe4ecc764cf5ca887176642f74 100644 --- a/chrome/browser/extensions/global_shortcut_listener_mac.mm @@ -21,6 +69,26 @@ index befe726af9c10b1563a7fc0bb77cc55f65943d5c..bac51f33f35f96fe4ecc764cf5ca8871 DCHECK(media_keys_listener_); } } +diff --git a/content/browser/media/media_keys_listener_manager_impl.cc b/content/browser/media/media_keys_listener_manager_impl.cc +index 28dc8c8451940b18e74384aad10d4d9e886b31a3..f9e1854ed72cc5a9f2431df066eb72f5242569f1 100644 +--- a/content/browser/media/media_keys_listener_manager_impl.cc ++++ b/content/browser/media/media_keys_listener_manager_impl.cc +@@ -177,8 +177,14 @@ void MediaKeysListenerManagerImpl::EnsureMediaKeysListener() { + + EnsureAuxiliaryServices(); + +- media_keys_listener_ = ui::MediaKeysListener::Create( ++ if (!media_key_handling_enabled_) { ++ media_keys_listener_ = ui::MediaKeysListener::Create( ++ this, ui::MediaKeysListener::Scope::kGlobalRequiresAccessibility); ++ } else { ++ media_keys_listener_ = ui::MediaKeysListener::Create( + this, ui::MediaKeysListener::Scope::kGlobal); ++ } ++ + DCHECK(media_keys_listener_); + + media_keys_listener_->SetIsMediaPlaying(is_media_playing_); diff --git a/ui/base/accelerators/media_keys_listener.h b/ui/base/accelerators/media_keys_listener.h index 6787fa39da18ec26c215e4cbe0b3f69093323f8c..ec10c46cde437a935edfdf79e5ba9622c6ba1d67 100644 --- a/ui/base/accelerators/media_keys_listener.h diff --git a/shell/browser/api/electron_api_global_shortcut.cc b/shell/browser/api/electron_api_global_shortcut.cc index 62abc1a60bd6..2ae8af1c811d 100644 --- a/shell/browser/api/electron_api_global_shortcut.cc +++ b/shell/browser/api/electron_api_global_shortcut.cc @@ -9,6 +9,7 @@ #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/common/extensions/command.h" #include "gin/dictionary.h" #include "gin/object_template_builder.h" #include "shell/browser/api/electron_api_system_preferences.h" @@ -20,6 +21,7 @@ #include "base/mac/mac_util.h" #endif +using extensions::Command; using extensions::GlobalShortcutListener; namespace { @@ -43,6 +45,15 @@ bool RegisteringMediaKeyForUntrustedClient(const ui::Accelerator& accelerator) { } return false; } + +bool MapHasMediaKeys( + const std::map& accelerator_map) { + auto media_key = std::find_if( + accelerator_map.begin(), accelerator_map.end(), + [](const auto& ac) { return Command::IsMediaKey(ac.first); }); + + return media_key != accelerator_map.end(); +} #endif } // namespace @@ -90,8 +101,12 @@ bool GlobalShortcut::RegisterAll( bool GlobalShortcut::Register(const ui::Accelerator& accelerator, const base::Closure& callback) { #if defined(OS_MAC) - if (RegisteringMediaKeyForUntrustedClient(accelerator)) - return false; + if (Command::IsMediaKey(accelerator)) { + if (RegisteringMediaKeyForUntrustedClient(accelerator)) + return false; + + GlobalShortcutListener::SetShouldUseInternalMediaKeyHandling(false); + } #endif if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator, @@ -107,6 +122,13 @@ void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) { if (accelerator_callback_map_.erase(accelerator) == 0) return; +#if defined(OS_MAC) + if (Command::IsMediaKey(accelerator) && + !MapHasMediaKeys(accelerator_callback_map_)) { + GlobalShortcutListener::SetShouldUseInternalMediaKeyHandling(true); + } +#endif + GlobalShortcutListener::GetInstance()->UnregisterAccelerator(accelerator, this); }