fix_media_key_usage_with_globalshortcuts.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Shelley Vohr <[email protected]>
  3. Date: Mon, 16 Aug 2021 17:55:32 +0200
  4. Subject: fix: media key usage with globalShortcuts
  5. This patch enables media keys to work properly with Electron's globalShortcut
  6. module. Chromium's default usage of RemoteCommandCenterDelegate on macOS falls
  7. down into MPRemoteCommandCenter, which makes it such that an app will not
  8. receive remote control events until it begins playing audio. This runs
  9. counter to the design of globalShortcuts, and so we need to instead
  10. use `ui::MediaKeysListener`.
  11. diff --git a/content/browser/media/media_keys_listener_manager_impl.cc b/content/browser/media/media_keys_listener_manager_impl.cc
  12. index 42e37564e585987d367921568f0f1d2b7507f953..9baf89efbade01e8b60c579255f10799914e144f 100644
  13. --- a/content/browser/media/media_keys_listener_manager_impl.cc
  14. +++ b/content/browser/media/media_keys_listener_manager_impl.cc
  15. @@ -87,7 +87,11 @@ bool MediaKeysListenerManagerImpl::StartWatchingMediaKey(
  16. CanActiveMediaSessionControllerReceiveEvents();
  17. // Tell the underlying MediaKeysListener to listen for the key.
  18. - if (should_start_watching && media_keys_listener_ &&
  19. + if (
  20. +#if BUILDFLAG(IS_MAC)
  21. + !media_key_handling_enabled_ &&
  22. +#endif // BUILDFLAG(IS_MAC)
  23. + should_start_watching && media_keys_listener_ &&
  24. !media_keys_listener_->StartWatchingMediaKey(key_code)) {
  25. return false;
  26. }
  27. @@ -361,6 +365,20 @@ void MediaKeysListenerManagerImpl::StartListeningForMediaKeysIfNecessary() {
  28. this, ui::MediaKeysListener::Scope::kGlobal);
  29. DCHECK(media_keys_listener_);
  30. }
  31. +
  32. +#if BUILDFLAG(IS_MAC)
  33. + // Chromium's implementation of SystemMediaControls falls
  34. + // down into MPRemoteCommandCenter, which makes it such that an app will not
  35. + // will not receive remote control events until it begins playing audio.
  36. + // If there's not already a MediaKeysListener instance, create one so
  37. + // that globalShortcuts work correctly.
  38. + if (!media_keys_listener_) {
  39. + media_keys_listener_ = ui::MediaKeysListener::Create(
  40. + this, ui::MediaKeysListener::Scope::kGlobal);
  41. + DCHECK(media_keys_listener_);
  42. + }
  43. +#endif
  44. +
  45. EnsureAuxiliaryServices();
  46. }
  47. diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc
  48. index cdf35a5bcec7b30f1b75e77cc29a9b7bb591cfd6..b6dfeee587faa742beb4f1d871db4c4f76bf46ab 100644
  49. --- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc
  50. +++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc
  51. @@ -65,6 +65,22 @@ void GlobalAcceleratorListener::UnregisterAccelerator(
  52. }
  53. }
  54. +// static
  55. +void GlobalAcceleratorListener::SetShouldUseInternalMediaKeyHandling(bool should_use) {
  56. + if (content::MediaKeysListenerManager::
  57. + IsMediaKeysListenerManagerEnabled()) {
  58. + content::MediaKeysListenerManager* media_keys_listener_manager =
  59. + content::MediaKeysListenerManager::GetInstance();
  60. + DCHECK(media_keys_listener_manager);
  61. +
  62. + if (should_use) {
  63. + media_keys_listener_manager->EnableInternalMediaKeyHandling();
  64. + } else {
  65. + media_keys_listener_manager->DisableInternalMediaKeyHandling();
  66. + }
  67. + }
  68. +}
  69. +
  70. void GlobalAcceleratorListener::UnregisterAccelerators(Observer* observer) {
  71. if (IsShortcutHandlingSuspended()) {
  72. return;
  73. diff --git a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h
  74. index 701808699796b0ef1a87d4d12f79fb6cf580c617..bf6e38410cedd6dd6d339b6f2f456124770bbd96 100644
  75. --- a/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h
  76. +++ b/ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h
  77. @@ -8,6 +8,7 @@
  78. #include <map>
  79. #include "base/memory/raw_ptr.h"
  80. +#include "content/public/browser/media_keys_listener_manager.h"
  81. #include "ui/base/accelerators/command.h"
  82. namespace ui {
  83. @@ -38,6 +39,9 @@ class GlobalAcceleratorListener {
  84. // The instance may be nullptr.
  85. static GlobalAcceleratorListener* GetInstance();
  86. + // enables media keys to work with Electron's globalShortcut module.
  87. + static void SetShouldUseInternalMediaKeyHandling(bool should_use);
  88. +
  89. // Register an observer for when a certain `accelerator` is struck. Returns
  90. // true if register successfully, or false if the specified `accelerator`
  91. // has been registered by another caller or other native applications.