summaryrefslogtreecommitdiffstats
path: root/remoting/host/input_injector_mac.cc
diff options
context:
space:
mode:
authorjamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-02 19:39:59 +0000
committerjamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-02 19:39:59 +0000
commit2bdedb610afd975b4b1cf1f2a15c07a9e26f18cf (patch)
tree9cb96efd750bfc62c29e598f86890a833974f2dc /remoting/host/input_injector_mac.cc
parent0482bda02545c9a94c4129bb12e6d88b4e44caab (diff)
downloadchromium_src-2bdedb610afd975b4b1cf1f2a15c07a9e26f18cf.zip
chromium_src-2bdedb610afd975b4b1cf1f2a15c07a9e26f18cf.tar.gz
chromium_src-2bdedb610afd975b4b1cf1f2a15c07a9e26f18cf.tar.bz2
Fix modifier keys on Mac.
CGEvents have an explicit set of modifier flags that can be set when they are injected, but the previous code was not doing this. It seems that the OS will usually generate them automatically by virtue of the fact the modifier key events were injected previously, but it seems that this behaviour is not reliable (nor is it documented). This CL sets the appropriate flags explicitly. BUG=331542 Review URL: https://codereview.chromium.org/141523012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@248425 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host/input_injector_mac.cc')
-rw-r--r--remoting/host/input_injector_mac.cc43
1 files changed, 39 insertions, 4 deletions
diff --git a/remoting/host/input_injector_mac.cc b/remoting/host/input_injector_mac.cc
index f3d158e..51fb09c 100644
--- a/remoting/host/input_injector_mac.cc
+++ b/remoting/host/input_injector_mac.cc
@@ -26,6 +26,15 @@ namespace remoting {
namespace {
+void SetOrClearBit(uint64_t &value, uint64_t bit, bool set_bit) {
+ value = set_bit ? (value | bit) : (value & ~bit);
+}
+
+// This value is not defined. Give it the obvious name so that if it is ever
+// added there will be a handy compilation error to remind us to remove this
+// definition.
+const int kVK_RightCommand = 0x36;
+
using protocol::ClipboardEvent;
using protocol::KeyEvent;
using protocol::MouseEvent;
@@ -74,6 +83,8 @@ class InputInjectorMac : public InputInjector {
webrtc::DesktopVector mouse_pos_;
uint32 mouse_button_state_;
scoped_ptr<Clipboard> clipboard_;
+ CGEventFlags left_modifiers_;
+ CGEventFlags right_modifiers_;
DISALLOW_COPY_AND_ASSIGN(Core);
};
@@ -113,7 +124,9 @@ InputInjectorMac::Core::Core(
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: task_runner_(task_runner),
mouse_button_state_(0),
- clipboard_(Clipboard::Create()) {
+ clipboard_(Clipboard::Create()),
+ left_modifiers_(0),
+ right_modifiers_(0) {
// Ensure that local hardware events are not suppressed after injecting
// input events. This allows LocalInputMonitor to detect if the local mouse
// is being moved whilst a remote user is connected.
@@ -154,14 +167,36 @@ void InputInjectorMac::Core::InjectKeyEvent(const KeyEvent& event) {
if (keycode == key_converter->InvalidNativeKeycode())
return;
+ // If this is a modifier key, remember its new state so that it can be
+ // correctly applied to subsequent events.
+ if (keycode == kVK_Command) {
+ SetOrClearBit(left_modifiers_, kCGEventFlagMaskCommand, event.pressed());
+ } else if (keycode == kVK_Shift) {
+ SetOrClearBit(left_modifiers_, kCGEventFlagMaskShift, event.pressed());
+ } else if (keycode == kVK_Control) {
+ SetOrClearBit(left_modifiers_, kCGEventFlagMaskControl, event.pressed());
+ } else if (keycode == kVK_Option) {
+ SetOrClearBit(left_modifiers_, kCGEventFlagMaskAlternate, event.pressed());
+ } else if (keycode == kVK_RightCommand) {
+ SetOrClearBit(right_modifiers_, kCGEventFlagMaskCommand, event.pressed());
+ } else if (keycode == kVK_RightShift) {
+ SetOrClearBit(right_modifiers_, kCGEventFlagMaskShift, event.pressed());
+ } else if (keycode == kVK_RightControl) {
+ SetOrClearBit(right_modifiers_, kCGEventFlagMaskControl, event.pressed());
+ } else if (keycode == kVK_RightOption) {
+ SetOrClearBit(right_modifiers_, kCGEventFlagMaskAlternate, event.pressed());
+ }
+
base::ScopedCFTypeRef<CGEventRef> eventRef(
CGEventCreateKeyboardEvent(NULL, keycode, event.pressed()));
if (eventRef) {
- // We only need to manually set CapsLock: Mac ignores NumLock.
- // Modifier keys work correctly already via press/release event injection.
+ // In addition to the modifier keys pressed right now, we also need to set
+ // AlphaShift if caps lock was active at the client (Mac ignores NumLock).
+ uint64_t flags = left_modifiers_ | right_modifiers_;
if (event.lock_states() & protocol::KeyEvent::LOCK_STATES_CAPSLOCK)
- CGEventSetFlags(eventRef, kCGEventFlagMaskAlphaShift);
+ flags |= kCGEventFlagMaskAlphaShift;
+ CGEventSetFlags(eventRef, flags);
// Post the event to the current session.
CGEventPost(kCGSessionEventTap, eventRef);