fix: don't register some shortcuts without accessibility (#16276)

This commit is contained in:
Shelley Vohr 2019-01-12 10:30:13 -08:00 committed by GitHub
parent ece0487228
commit 8f629a2f31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 1 deletions

View file

@ -6,15 +6,45 @@
#include <string> #include <string>
#include "atom/browser/api/atom_api_system_preferences.h"
#include "atom/common/native_mate_converters/accelerator_converter.h" #include "atom/common/native_mate_converters/accelerator_converter.h"
#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/callback.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "atom/common/node_includes.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; 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 atom {
namespace api { namespace api {
@ -31,7 +61,7 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator_callback_map_.find(accelerator) == if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) { accelerator_callback_map_.end()) {
// This should never occur, because if it does, GlobalGlobalShortcutListener // This should never occur, because if it does, GlobalGlobalShortcutListener
// notifes us with wrong accelerator. // notifies us with wrong accelerator.
NOTREACHED(); NOTREACHED();
return; return;
} }
@ -40,6 +70,11 @@ void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
bool GlobalShortcut::Register(const ui::Accelerator& accelerator, bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
const base::Closure& callback) { const base::Closure& callback) {
#if defined(OS_MACOSX)
if (RegisteringMediaKeyForUntrustedClient(accelerator))
return false;
#endif
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator, if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
this)) { this)) {
return false; return false;

View file

@ -93,6 +93,8 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
mate::Arguments* args); mate::Arguments* args);
void RemoveUserDefault(const std::string& name); void RemoveUserDefault(const std::string& name);
bool IsSwipeTrackingFromScrollEventsEnabled(); bool IsSwipeTrackingFromScrollEventsEnabled();
static bool IsTrustedAccessibilityClient(bool prompt);
#endif #endif
bool IsDarkMode(); bool IsDarkMode();
bool IsInvertedColorScheme(); bool IsInvertedColorScheme();

View file

@ -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) { void SystemPreferences::RemoveUserDefault(const std::string& name) {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:base::SysUTF8ToNSString(name)]; [defaults removeObjectForKey:base::SysUTF8ToNSString(name)];

View file

@ -60,6 +60,7 @@ void Beep();
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
bool GetLoginItemEnabled(); bool GetLoginItemEnabled();
void SetLoginItemEnabled(bool enabled); void SetLoginItemEnabled(bool enabled);
bool IsAtLeastOS10_14();
#endif #endif
} // namespace platform_util } // namespace platform_util

View file

@ -8,6 +8,8 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <ServiceManagement/ServiceManagement.h> #import <ServiceManagement/ServiceManagement.h>
#include "atom/common/platform_util.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
@ -18,6 +20,7 @@
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "net/base/mac/url_conversions.h" #include "net/base/mac/url_conversions.h"
#include "third_party/WebKit/Source/platform/mac/VersionUtilMac.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace { 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) { bool MoveItemToTrash(const base::FilePath& full_path) {
NSString* path_string = base::SysUTF8ToNSString(full_path.value()); NSString* path_string = base::SysUTF8ToNSString(full_path.value());
BOOL status = [[NSFileManager defaultManager] BOOL status = [[NSFileManager defaultManager]

View file

@ -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 silently fail. This behavior is intended by operating systems, since they don't
want applications to fight for global shortcuts. 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)` ### `globalShortcut.isRegistered(accelerator)`
* `accelerator` [Accelerator](accelerator.md) * `accelerator` [Accelerator](accelerator.md)