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