Index: remoting/client/plugin/normalizing_input_filter_mac.h |
diff --git a/remoting/client/plugin/normalizing_input_filter_mac.h b/remoting/client/plugin/normalizing_input_filter_mac.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ed1d0d3c4384a66b49e3f5fb997d5d509c5d0b52 |
--- /dev/null |
+++ b/remoting/client/plugin/normalizing_input_filter_mac.h |
@@ -0,0 +1,65 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <map> |
+ |
+#include "remoting/protocol/input_filter.h" |
+ |
+namespace remoting { |
+ |
+// NormalizingInputFilterMac is designed to solve the problem of missing keyup |
+// events on Mac. |
+// |
+// PROBLEM |
+// |
+// On Mac if user presses CMD and then C key there is no keyup event generated |
+// for C when user releases the C key before the CMD key. |
+// The cause is that CMD + C triggers a system action and Chrome injects only a |
+// keydown event for the C key. Safari shares the same behavior. |
+// |
+// SOLUTION |
+// |
+// When a keyup event for CMD key happens we will check all prior keydown |
+// events received and inject corresponding keyup events artificially, with |
+// the exception of: |
+// |
+// SHIFT, CONTROL, OPTION, LEFT CMD, RIGHT CMD and CAPS LOCK |
+// |
+// because they are reported by Chrome correctly. |
+// |
+// There are a couple cases that this solution doesn't work perfectly, one |
+// of them leads to duplicated keyup events. |
+// |
+// User performs this sequence of actions: |
+// |
+// CMD DOWN, C DOWN, CMD UP, C UP |
+// |
+// In this case the algorithm will generate: |
+// |
+// CMD DOWN, C DOWN, C UP, CMD UP, C UP |
+// |
+// Because we artificially generate keyup events the C UP event is duplicated |
+// as user releases the key after CMD key. This would not be a problem as the |
+// receiver end will drop this duplicated keyup event. |
+class NormalizingInputFilterMac : public protocol::InputFilter { |
+ public: |
+ explicit NormalizingInputFilterMac(protocol::InputStub* input_stub); |
+ virtual ~NormalizingInputFilterMac(); |
+ |
+ // InputFilter overrides. |
+ virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; |
+ |
+ private: |
+ typedef std::map<int, protocol::KeyEvent> KeyPressedMap; |
+ |
+ // Generate keyup events for any keys pressed with CMD. |
+ void GenerateKeyupEvents(); |
+ |
+ // A map that stores pressed keycodes and the corresponding key event. |
+ KeyPressedMap key_pressed_map_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(NormalizingInputFilterMac); |
+}; |
+ |
+} // namespace remoting |