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 3 // found in the LICENSE file. 4 5 // MacKeyEventProcessor is designed to solve the problem of missing keyup 6 // events on Mac. 7 // 8 // PROBLEM 9 // 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. 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. 14 // 15 // SOLUTION 16 // 17 // When a keyup event for CMD key happens we will check all prior keydown 18 // events received and inject corresponding keyup events artificially, with 19 // the exception of: 20 // 21 // SHIFT, CONTROL, OPTION, LEFT CMD, RIGHT CMD and CAPS LOCK 22 // 23 // because they are reported by Chrome correctly. 24 // 25 // There are a couple cases that this solution doesn't work perfectly, one 26 // of them leads to duplicated keyup events. 27 // 28 // User performs this sequence of actions: 29 // 30 // CMD DOWN, C DOWN, CMD UP, C UP 31 // 32 // In this case the algorithm will generate: 33 // 34 // CMD DOWN, C DOWN, C UP, CMD UP, C UP 35 // 36 // Because we artificially generate keyup events the C UP event is duplicated 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. 39 40 #ifndef REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_ 41 #define REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_ 42 43 #include <map> 44 45 #include "base/basictypes.h" 46 #include "remoting/proto/event.pb.h" 47 #include "remoting/protocol/input_filter.h" 48 49 namespace remoting { 50 51 namespace protocol { 52 class InputStub; 53 } // namespace protocol 54 55 class MacKeyEventProcessor : public protocol::InputFilter { 56 public: 57 explicit MacKeyEventProcessor(protocol::InputStub* input_stub); 58 virtual ~MacKeyEventProcessor(); 59 60 // InputFilter overrides. 61 virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; 62 63 private: 64 // Generate keyup events for any keys pressed with CMD. 65 void GenerateKeyupEvents(); 66 67 // A map that stores pressed keycodes and the corresponding key event. 68 typedef std::map<int, protocol::KeyEvent> KeyPressedMap; 69 KeyPressedMap key_pressed_map_; 70 71 DISALLOW_COPY_AND_ASSIGN(MacKeyEventProcessor); 72 }; 73 74 } // namespace remoting 75 76 #endif // REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_ 77