OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // MacKeyEventProcessor is designed to solve the problem of missing keyup | 5 // MacKeyEventProcessor is designed to solve the problem of missing keyup |
6 // events on Mac. | 6 // events on Mac. |
7 // | 7 // |
8 // PROBLEM | 8 // PROBLEM |
9 // | 9 // |
10 // On Mac if user presses CMD and then C key there is no keyup event generated | 10 // On Mac if user presses CMD and then C key there is no keyup event generated |
11 // for C when user releases the C key before the CMD key. | 11 // for C when user releases the C key before the CMD key. |
12 // The cause is that CMD + C triggers a system action and Chrome injects only a | 12 // The cause is that CMD + C triggers a system action and Chrome injects only a |
13 // keydown event for the C key. Safari shares the same behavior. | 13 // keydown event for the C key. Safari shares the same behavior. |
14 // | 14 // |
15 // This is a list of sample edge cases: | |
16 // | |
17 // CMD DOWN, C DOWN, C UP, CMD UP | |
18 // CMD DOWN, SHIFT DOWN, C DOWN, C UP, CMD UP, SHIFT UP | |
19 // CMD DOWN, CAPS LOCK DOWN, CMD DOWN, CAPS LOCK DOWN | |
20 // L CMD DOWN, C DOWN, R CMD DOWN, L CMD UP, C UP, R CMD UP | |
21 // | |
22 // SOLUTION | 15 // SOLUTION |
23 // | 16 // |
24 // When a keyup event for CMD key happens we will check all prior keydown | 17 // When a keyup event for CMD key happens we will check all prior keydown |
25 // events received and inject corresponding keyup events artificially, with | 18 // events received and inject corresponding keyup events artificially, with |
26 // the exception of: | 19 // the exception of: |
27 // | 20 // |
28 // SHIFT, CONTROL, OPTION, LEFT CMD, RIGHT CMD and CAPS LOCK | 21 // SHIFT, CONTROL, OPTION, LEFT CMD, RIGHT CMD and CAPS LOCK |
29 // | 22 // |
30 // because they are reported by Chrome correctly. | 23 // because they are reported by Chrome correctly. |
31 // | 24 // |
32 // There are a couple cases that this solution doesn't work perfectly, one | 25 // There are a couple cases that this solution doesn't work perfectly, one |
33 // of them leads to duplicated keyup events. | 26 // of them leads to duplicated keyup events. |
34 // | 27 // |
35 // User performs this sequence of actions: | 28 // User performs this sequence of actions: |
36 // | 29 // |
37 // CMD DOWN, C DOWN, CMD UP, C UP | 30 // CMD DOWN, C DOWN, CMD UP, C UP |
38 // | 31 // |
39 // In this case the algorithm will generate: | 32 // In this case the algorithm will generate: |
40 // | 33 // |
41 // CMD DOWN, C DOWN, C UP, CMD UP, C UP | 34 // CMD DOWN, C DOWN, C UP, CMD UP, C UP |
42 // | 35 // |
43 // Because we artificially generate keyup events the C UP event is duplicated | 36 // Because we artificially generate keyup events the C UP event is duplicated |
44 // as user releases the key after CMD key. | 37 // as user releases the key after CMD key. This would not be a problem as the |
| 38 // receiver end will drop this duplicated keyup event. |
45 | 39 |
46 #ifndef REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_ | 40 #ifndef REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_ |
47 #define REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_ | 41 #define REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_ |
48 | 42 |
49 #include <map> | 43 #include <map> |
50 | 44 |
51 #include "base/basictypes.h" | 45 #include "base/basictypes.h" |
52 #include "remoting/proto/event.pb.h" | 46 #include "remoting/proto/event.pb.h" |
53 #include "remoting/protocol/input_filter.h" | 47 #include "remoting/protocol/input_filter.h" |
54 | 48 |
55 namespace remoting { | 49 namespace remoting { |
56 | 50 |
57 namespace protocol { | 51 namespace protocol { |
58 class InputStub; | 52 class InputStub; |
59 } // namespace protocol | 53 } // namespace protocol |
60 | 54 |
61 class MacKeyEventProcessor : public protocol::InputFilter { | 55 class MacKeyEventProcessor : public protocol::InputFilter { |
62 public: | 56 public: |
63 explicit MacKeyEventProcessor(protocol::InputStub* input_stub); | 57 explicit MacKeyEventProcessor(protocol::InputStub* input_stub); |
64 virtual ~MacKeyEventProcessor(); | 58 virtual ~MacKeyEventProcessor(); |
65 | 59 |
66 // InputFilter overrides. | 60 // InputFilter overrides. |
67 virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; | 61 virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; |
68 | 62 |
69 // Return the number of keys pressed. This method is used by unit test to | |
70 // test correctness of this class. | |
71 int NumberOfPressedKeys() const; | |
72 | |
73 private: | 63 private: |
74 // Iterate the current pressed keys and generate keyup events. | 64 // Generate keyup events for any keys pressed with CMD. |
75 void GenerateKeyupEvents(); | 65 void GenerateKeyupEvents(); |
76 | 66 |
77 // A map that stores pressed keycodes and the corresponding key event. | 67 // A map that stores pressed keycodes and the corresponding key event. |
78 typedef std::map<int, protocol::KeyEvent> KeyPressedMap; | 68 typedef std::map<int, protocol::KeyEvent> KeyPressedMap; |
79 KeyPressedMap key_pressed_map_; | 69 KeyPressedMap key_pressed_map_; |
80 | 70 |
81 DISALLOW_COPY_AND_ASSIGN(MacKeyEventProcessor); | 71 DISALLOW_COPY_AND_ASSIGN(MacKeyEventProcessor); |
82 }; | 72 }; |
83 | 73 |
84 } // namespace remoting | 74 } // namespace remoting |
85 | 75 |
86 #endif // REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_ | 76 #endif // REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_ |
OLD | NEW |