normalizing_input_filter_mac.h revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Copyright 2014 The Chromium Authors. All rights reserved. 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Use of this source code is governed by a BSD-style license that can be 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// found in the LICENSE file. 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <map> 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "remoting/protocol/input_filter.h" 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace remoting { 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// NormalizingInputFilterMac is designed to solve the problem of missing keyup 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// events on Mac. 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// PROBLEM 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// On Mac if user presses CMD and then C key there is no keyup event generated 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// for C when user releases the C key before the CMD key. 18bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org// The cause is that CMD + C triggers a system action and Chrome injects only a 19bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org// keydown event for the C key. Safari shares the same behavior. 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// SOLUTION 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// When a keyup event for CMD key happens we will check all prior keydown 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// events received and inject corresponding keyup events artificially, with 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// the exception of: 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// SHIFT, CONTROL, OPTION, LEFT CMD, RIGHT CMD and CAPS LOCK 2864a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org// 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// because they are reported by Chrome correctly. 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 3164a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org// There are a couple cases that this solution doesn't work perfectly, one 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// of them leads to duplicated keyup events. 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// User performs this sequence of actions: 3564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org// 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// CMD DOWN, C DOWN, CMD UP, C UP 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 383b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org// In this case the algorithm will generate: 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// CMD DOWN, C DOWN, C UP, CMD UP, C UP 41// 42// Because we artificially generate keyup events the C UP event is duplicated 43// as user releases the key after CMD key. This would not be a problem as the 44// receiver end will drop this duplicated keyup event. 45class NormalizingInputFilterMac : public protocol::InputFilter { 46 public: 47 explicit NormalizingInputFilterMac(protocol::InputStub* input_stub); 48 virtual ~NormalizingInputFilterMac(); 49 50 // InputFilter overrides. 51 virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; 52 53 private: 54 typedef std::map<int, protocol::KeyEvent> KeyPressedMap; 55 56 // Generate keyup events for any keys pressed with CMD. 57 void GenerateKeyupEvents(); 58 59 // A map that stores pressed keycodes and the corresponding key event. 60 KeyPressedMap key_pressed_map_; 61 62 DISALLOW_COPY_AND_ASSIGN(NormalizingInputFilterMac); 63}; 64 65} // namespace remoting 66