From cdc310ed94654218e2d94a637e1acca28d7c1ed9 Mon Sep 17 00:00:00 2001 From: "trop[bot]" Date: Mon, 14 Jan 2019 11:48:41 -0800 Subject: [PATCH] fix: don't register some shortcuts without accessibility (#16378) --- atom/browser/api/atom_api_global_shortcut.cc | 37 ++++++++++++++++++- .../browser/api/atom_api_system_preferences.h | 2 + .../api/atom_api_system_preferences_mac.mm | 6 +++ atom/common/platform_util.h | 1 + atom/common/platform_util_mac.mm | 7 ++++ docs/api/global-shortcut.md | 8 ++++ 6 files changed, 60 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_global_shortcut.cc b/atom/browser/api/atom_api_global_shortcut.cc index 4fc7532d9e34..aee7ea151685 100644 --- a/atom/browser/api/atom_api_global_shortcut.cc +++ b/atom/browser/api/atom_api_global_shortcut.cc @@ -6,15 +6,45 @@ #include +#include "atom/browser/api/atom_api_system_preferences.h" #include "atom/common/native_mate_converters/accelerator_converter.h" #include "atom/common/native_mate_converters/callback.h" #include "base/stl_util.h" +#include "base/strings/utf_string_conversions.h" #include "native_mate/dictionary.h" #include "atom/common/node_includes.h" +#include "atom/common/platform_util.h" + +#if defined(OS_MACOSX) +#include "base/mac/mac_util.h" +#endif using extensions::GlobalShortcutListener; +namespace { + +#if defined(OS_MACOSX) +bool RegisteringMediaKeyForUntrustedClient(const ui::Accelerator& accelerator) { + if (platform_util::IsAtLeastOS10_14()) { + constexpr ui::KeyboardCode mediaKeys[] = { + ui::VKEY_MEDIA_PLAY_PAUSE, ui::VKEY_MEDIA_NEXT_TRACK, + ui::VKEY_MEDIA_PREV_TRACK, ui::VKEY_MEDIA_STOP}; + + if (std::find(std::begin(mediaKeys), std::end(mediaKeys), + accelerator.key_code()) != std::end(mediaKeys)) { + bool trusted = + atom::api::SystemPreferences::IsTrustedAccessibilityClient(false); + if (!trusted) + return true; + } + } + return false; +} +#endif + +} // namespace + namespace atom { namespace api { @@ -31,7 +61,7 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) { if (accelerator_callback_map_.find(accelerator) == accelerator_callback_map_.end()) { // This should never occur, because if it does, GlobalGlobalShortcutListener - // notifes us with wrong accelerator. + // notifies us with wrong accelerator. NOTREACHED(); return; } @@ -40,6 +70,11 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) { bool GlobalShortcut::Register(const ui::Accelerator& accelerator, const base::Closure& callback) { +#if defined(OS_MACOSX) + if (RegisteringMediaKeyForUntrustedClient(accelerator)) + return false; +#endif + if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator, this)) { return false; diff --git a/atom/browser/api/atom_api_system_preferences.h b/atom/browser/api/atom_api_system_preferences.h index bfd64e80159d..37671a8e221c 100644 --- a/atom/browser/api/atom_api_system_preferences.h +++ b/atom/browser/api/atom_api_system_preferences.h @@ -93,6 +93,8 @@ class SystemPreferences : public mate::EventEmitter mate::Arguments* args); void RemoveUserDefault(const std::string& name); bool IsSwipeTrackingFromScrollEventsEnabled(); + + static bool IsTrustedAccessibilityClient(bool prompt); #endif bool IsDarkMode(); bool IsInvertedColorScheme(); diff --git a/atom/browser/api/atom_api_system_preferences_mac.mm b/atom/browser/api/atom_api_system_preferences_mac.mm index 99fb216f5c48..f26212968647 100644 --- a/atom/browser/api/atom_api_system_preferences_mac.mm +++ b/atom/browser/api/atom_api_system_preferences_mac.mm @@ -308,6 +308,12 @@ void SystemPreferences::SetUserDefault(const std::string& name, } } +// static +bool SystemPreferences::IsTrustedAccessibilityClient(bool prompt) { + NSDictionary* options = @{(id)kAXTrustedCheckOptionPrompt : @(prompt)}; + return AXIsProcessTrustedWithOptions((CFDictionaryRef)options); +} + void SystemPreferences::RemoveUserDefault(const std::string& name) { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; [defaults removeObjectForKey:base::SysUTF8ToNSString(name)]; diff --git a/atom/common/platform_util.h b/atom/common/platform_util.h index 6fd84056a06a..e2549598198e 100644 --- a/atom/common/platform_util.h +++ b/atom/common/platform_util.h @@ -60,6 +60,7 @@ void Beep(); #if defined(OS_MACOSX) bool GetLoginItemEnabled(); void SetLoginItemEnabled(bool enabled); +bool IsAtLeastOS10_14(); #endif } // namespace platform_util diff --git a/atom/common/platform_util_mac.mm b/atom/common/platform_util_mac.mm index b83b1e11d891..7150531c5cb6 100644 --- a/atom/common/platform_util_mac.mm +++ b/atom/common/platform_util_mac.mm @@ -8,6 +8,8 @@ #import #import +#include "atom/common/platform_util.h" + #include "base/callback.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -18,6 +20,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "net/base/mac/url_conversions.h" +#include "third_party/WebKit/Source/platform/mac/VersionUtilMac.h" #include "url/gurl.h" namespace { @@ -166,6 +169,10 @@ void OpenExternal(const GURL& url, }); } +bool IsAtLeastOS10_14() { + return blink::internal::MacOSXMinorVersion() >= 14; +} + bool MoveItemToTrash(const base::FilePath& full_path) { NSString* path_string = base::SysUTF8ToNSString(full_path.value()); BOOL status = [[NSFileManager defaultManager] diff --git a/docs/api/global-shortcut.md b/docs/api/global-shortcut.md index d0f48a6f8055..802ef14a2ecb 100644 --- a/docs/api/global-shortcut.md +++ b/docs/api/global-shortcut.md @@ -54,6 +54,14 @@ When the accelerator is already taken by other applications, this call will silently fail. This behavior is intended by operating systems, since they don't want applications to fight for global shortcuts. +The following accelerators will not be registered successfully on macOS 10.14 Mojave unless +the app has been authorized as a [trusted accessibility client](https://developer.apple.com/library/archive/documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXTestingApps.html): + +* "Media Play/Pause" +* "Media Next Track" +* "Media Previous Track" +* "Media Stop" + ### `globalShortcut.isRegistered(accelerator)` * `accelerator` [Accelerator](accelerator.md)