diff options
-rw-r--r-- | remoting/host/event_executor_linux.cc | 33 | ||||
-rwxr-xr-x | remoting/tools/me2me_virtual_host.py | 16 |
2 files changed, 31 insertions, 18 deletions
diff --git a/remoting/host/event_executor_linux.cc b/remoting/host/event_executor_linux.cc index 794fa71..f2e68b8 100644 --- a/remoting/host/event_executor_linux.cc +++ b/remoting/host/event_executor_linux.cc @@ -29,7 +29,7 @@ namespace { class EventExecutorLinux : public EventExecutor { public: EventExecutorLinux(MessageLoop* message_loop, Capturer* capturer); - virtual ~EventExecutorLinux() {}; + virtual ~EventExecutorLinux(); bool Init(); @@ -37,6 +37,10 @@ class EventExecutorLinux : public EventExecutor { virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; private: + // |mode| is one of the AutoRepeatModeOn, AutoRepeatModeOff, + // AutoRepeatModeDefault constants defined by the XChangeKeyboardControl() + // API. + void SetAutoRepeatForKey(int keycode, int mode); void InjectScrollWheelClicks(int button, int count); MessageLoop* message_loop_; @@ -259,6 +263,10 @@ EventExecutorLinux::EventExecutorLinux(MessageLoop* message_loop, height_(0) { } +EventExecutorLinux::~EventExecutorLinux() { + CHECK(pressed_keys_.empty()); +} + bool EventExecutorLinux::Init() { CHECK(display_); @@ -321,17 +329,38 @@ void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) { << " to keycode: " << keycode; if (event.pressed()) { - if (pressed_keys_.find(keycode) != pressed_keys_.end()) + if (pressed_keys_.find(keycode) != pressed_keys_.end()) { + // Key is already held down, so lift the key up to ensure this repeated + // press takes effect. XTestFakeKeyEvent(display_, keycode, False, CurrentTime); + } else { + // Key is not currently held down, so disable auto-repeat for this + // key to avoid repeated presses in case network congestion delays the + // key-released event from the client. + SetAutoRepeatForKey(keycode, AutoRepeatModeOff); + } pressed_keys_.insert(keycode); } else { pressed_keys_.erase(keycode); + + // Reset the AutoRepeatMode for the key that has been lifted. In the IT2Me + // case, this ensures that key-repeating will continue to work normally + // for the local user of the host machine. "ModeDefault" is used instead + // of "ModeOn", since some keys (such as Shift) should not auto-repeat. + SetAutoRepeatForKey(keycode, AutoRepeatModeDefault); } XTestFakeKeyEvent(display_, keycode, event.pressed(), CurrentTime); XFlush(display_); } +void EventExecutorLinux::SetAutoRepeatForKey(int keycode, int mode) { + XKeyboardControl control; + control.key = keycode; + control.auto_repeat_mode = mode; + XChangeKeyboardControl(display_, KBKey | KBAutoRepeatMode, &control); +} + void EventExecutorLinux::InjectScrollWheelClicks(int button, int count) { for (int i = 0; i < count; i++) { // Generate a button-down and a button-up to simulate a wheel click. diff --git a/remoting/tools/me2me_virtual_host.py b/remoting/tools/me2me_virtual_host.py index e6fa6bb..b0eb122 100755 --- a/remoting/tools/me2me_virtual_host.py +++ b/remoting/tools/me2me_virtual_host.py @@ -25,7 +25,6 @@ import socket import subprocess import sys import tempfile -import threading import time import urllib2 import uuid @@ -332,14 +331,6 @@ class Desktop: if not self.session_proc.pid: raise Exception("Could not start X session") - # Allow some time for the desktop session to launch before disabling - # key-repeat, since the desktop environment may enable key-repeat during - # initialization. - - # TODO(lambroslambrou): A more robust solution would be for the host - # process to disable key-repeat in its (per-platform) event-injection code. - threading.Timer(30, self.disable_key_repeat).start() - def launch_host(self, host): # Start remoting host args = [locate_executable(REMOTING_COMMAND), @@ -348,13 +339,6 @@ class Desktop: if not self.host_proc.pid: raise Exception("Could not start remoting host") - def disable_key_repeat(self): - logging.info("Disabling keyboard auto-repeat") - try: - subprocess.call(["xset", "r", "off"], env=self.child_env) - except OSError, e: - logging.error("Failed to disable keyboard auto-repeat: " + str(e)) - class PidFile: """Class to allow creating and deleting a file which holds the PID of the |