1// Copyright 2014 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#include <map> 6 7#include "remoting/protocol/input_filter.h" 8 9namespace remoting { 10 11// NormalizingInputFilterMac is designed to solve the problem of missing keyup 12// events on Mac. 13// 14// PROBLEM 15// 16// On Mac if user presses CMD and then C key there is no keyup event generated 17// for C when user releases the C key before the CMD key. 18// The cause is that CMD + C triggers a system action and Chrome injects only a 19// keydown event for the C key. Safari shares the same behavior. 20// 21// SOLUTION 22// 23// When a keyup event for CMD key happens we will check all prior keydown 24// events received and inject corresponding keyup events artificially, with 25// the exception of: 26// 27// SHIFT, CONTROL, OPTION, LEFT CMD, RIGHT CMD and CAPS LOCK 28// 29// because they are reported by Chrome correctly. 30// 31// There are a couple cases that this solution doesn't work perfectly, one 32// of them leads to duplicated keyup events. 33// 34// User performs this sequence of actions: 35// 36// CMD DOWN, C DOWN, CMD UP, C UP 37// 38// In this case the algorithm will generate: 39// 40// 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