Home | History | Annotate | Download | only in plugin
      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