diff options
author | garykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-26 01:55:52 +0000 |
---|---|---|
committer | garykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-26 01:55:52 +0000 |
commit | b67fb930ca28a39b12cb40c769321df52cd0ddae (patch) | |
tree | ae6122a7f0c3e5e10cd1bb58b73e0375ff9c833e /remoting | |
parent | 79e1409f81bf5ce29f69acfaae15f0ff057cb321 (diff) | |
download | chromium_src-b67fb930ca28a39b12cb40c769321df52cd0ddae.zip chromium_src-b67fb930ca28a39b12cb40c769321df52cd0ddae.tar.gz chromium_src-b67fb930ca28a39b12cb40c769321df52cd0ddae.tar.bz2 |
Chromoting: Undo any mouse-downs that haven't been mouse-upped.
BUG=97466
TEST=manual
Review URL: http://codereview.chromium.org/7973016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102687 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/host/client_session.cc | 48 | ||||
-rw-r--r-- | remoting/host/client_session.h | 21 | ||||
-rw-r--r-- | remoting/host/client_session_unittest.cc | 15 | ||||
-rw-r--r-- | remoting/host/event_executor_linux.cc | 4 | ||||
-rw-r--r-- | remoting/proto/event.proto | 3 |
5 files changed, 68 insertions, 23 deletions
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index 312e6c1..3416069 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc @@ -87,16 +87,7 @@ void ClientSession::InjectKeyEvent(const KeyEvent& event) { void ClientSession::InjectMouseEvent(const MouseEvent& event) { if (authenticated_ && !ShouldIgnoreRemoteMouseInput(event)) { - if (event.has_button() && event.has_button_down()) { - if (event.button() >= 1 && event.button() < 32) { - uint32 button_change = 1 << (event.button() - 1); - if (event.button_down()) { - remote_mouse_button_state_ |= button_change; - } else { - remote_mouse_button_state_ &= ~button_change; - } - } - } + RecordMouseButtonState(event); MouseEvent event_to_inject = event; if (event.has_x() && event.has_y()) { // In case the client sends events with off-screen coordinates, modify @@ -110,6 +101,11 @@ void ClientSession::InjectMouseEvent(const MouseEvent& event) { event_to_inject.set_x(pos.x()); event_to_inject.set_y(pos.y()); + // Record the mouse position so we can use it if we need to inject + // fake mouse button events. Note that we need to do this after we + // clamp the values to the screen area. + remote_mouse_pos_ = pos; + injected_mouse_positions_.push_back(pos); if (injected_mouse_positions_.size() > kNumRemoteMousePositions) { VLOG(1) << "Injected mouse positions queue full."; @@ -121,7 +117,7 @@ void ClientSession::InjectMouseEvent(const MouseEvent& event) { } void ClientSession::OnDisconnected() { - UnpressKeys(); + RestoreEventState(); authenticated_ = false; } @@ -187,7 +183,22 @@ void ClientSession::RecordKeyEvent(const KeyEvent& event) { } } -void ClientSession::UnpressKeys() { +void ClientSession::RecordMouseButtonState(const MouseEvent& event) { + if (event.has_button() && event.has_button_down()) { + // Button values are defined in remoting/proto/event.proto. + if (event.button() >= 1 && event.button() < MouseEvent::BUTTON_MAX) { + uint32 button_change = 1 << (event.button() - 1); + if (event.button_down()) { + remote_mouse_button_state_ |= button_change; + } else { + remote_mouse_button_state_ &= ~button_change; + } + } + } +} + +void ClientSession::RestoreEventState() { + // Undo any currently pressed keys. std::set<int>::iterator i; for (i = pressed_keys_.begin(); i != pressed_keys_.end(); ++i) { KeyEvent key; @@ -196,6 +207,19 @@ void ClientSession::UnpressKeys() { input_stub_->InjectKeyEvent(key); } pressed_keys_.clear(); + + // Undo any currently pressed mouse buttons. + for (int i = 1; i < MouseEvent::BUTTON_MAX; i++) { + if (remote_mouse_button_state_ & (1 << (i - 1))) { + MouseEvent mouse; + mouse.set_x(remote_mouse_pos_.x()); + mouse.set_y(remote_mouse_pos_.y()); + mouse.set_button((MouseEvent::MouseButton)i); + mouse.set_button_down(false); + input_stub_->InjectMouseEvent(mouse); + } + } + remote_mouse_button_state_ = 0; } } // namespace remoting diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h index 4cedefc..b387984 100644 --- a/remoting/host/client_session.h +++ b/remoting/host/client_session.h @@ -87,17 +87,17 @@ class ClientSession : public protocol::HostStub, private: friend class base::RefCountedThreadSafe<ClientSession>; - friend class ClientSessionTest_UnpressKeys_Test; + friend class ClientSessionTest_RestoreEventState_Test; virtual ~ClientSession(); - // Keep track of keydowns and keyups so that we can clean up the keyboard - // state when the user disconnects. + // Keep track of input state so that we can clean up the event queue when + // the user disconnects. void RecordKeyEvent(const protocol::KeyEvent& event); + void RecordMouseButtonState(const protocol::MouseEvent& event); - // Synthesize KeyUp events for keys that have been pressed but not released. - // This should be used when the client has disconnected to clear out any - // pending key events. - void UnpressKeys(); + // Synthesize KeyUp and MouseUp events so that we can undo these events + // when the user disconnects. + void RestoreEventState(); EventHandler* event_handler_; @@ -128,12 +128,19 @@ class ClientSession : public protocol::HostStub, // State to control remote input blocking while the local pointer is in use. uint32 remote_mouse_button_state_; + // Current location of the mouse pointer. This is used to provide appropriate + // coordinates when we release the mouse buttons after a user disconnects. + gfx::Point remote_mouse_pos_; + // Queue of recently-injected mouse positions. This is used to detect whether // mouse events from the local input monitor are echoes of injected positions, // or genuine mouse movements of a local input device. std::list<gfx::Point> injected_mouse_positions_; base::Time latest_local_input_time_; + + // Set of keys that are currently pressed down by the user. This is used so + // we can release them if the user disconnects. std::set<int> pressed_keys_; DISALLOW_COPY_AND_ASSIGN(ClientSession); diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc index 1734709..cd621e8 100644 --- a/remoting/host/client_session_unittest.cc +++ b/remoting/host/client_session_unittest.cc @@ -81,6 +81,10 @@ MATCHER_P2(EqualsMouseEvent, x, y, "") { return arg.x() == x && arg.y() == y; } +MATCHER_P(EqualsMouseUpEvent, button, "") { + return arg.button() == button && !arg.button_down(); +} + TEST_F(ClientSessionTest, InputStubFilter) { protocol::KeyEvent key_event1; key_event1.set_pressed(true); @@ -178,7 +182,7 @@ TEST_F(ClientSessionTest, LocalInputTest) { client_session_->OnDisconnected(); } -TEST_F(ClientSessionTest, UnpressKeys) { +TEST_F(ClientSessionTest, RestoreEventState) { protocol::KeyEvent key1; key1.set_pressed(true); key1.set_keycode(1); @@ -187,13 +191,20 @@ TEST_F(ClientSessionTest, UnpressKeys) { key2.set_pressed(true); key2.set_keycode(2); + protocol::MouseEvent mousedown; + mousedown.set_button(protocol::MouseEvent::BUTTON_LEFT); + mousedown.set_button_down(true); + client_session_->RecordKeyEvent(key1); client_session_->RecordKeyEvent(key2); + client_session_->RecordMouseButtonState(mousedown); EXPECT_CALL(input_stub_, InjectKeyEvent(EqualsKeyEvent(1, false))); EXPECT_CALL(input_stub_, InjectKeyEvent(EqualsKeyEvent(2, false))); + EXPECT_CALL(input_stub_, InjectMouseEvent(EqualsMouseUpEvent( + protocol::MouseEvent::BUTTON_LEFT))); - client_session_->UnpressKeys(); + client_session_->RestoreEventState(); } TEST_F(ClientSessionTest, ClampMouseEvents) { diff --git a/remoting/host/event_executor_linux.cc b/remoting/host/event_executor_linux.cc index 56ac3e4..2321c5c 100644 --- a/remoting/host/event_executor_linux.cc +++ b/remoting/host/event_executor_linux.cc @@ -345,7 +345,9 @@ void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) { } VLOG(3) << "Button " << event.button() - << " received, sending down " << button_number; + << " received, sending " + << (event.button_down() ? "down " : "up ") + << button_number; XTestFakeButtonEvent(display_, button_number, event.button_down(), CurrentTime); XFlush(display_); diff --git a/remoting/proto/event.proto b/remoting/proto/event.proto index 945d0b0..2098e70 100644 --- a/remoting/proto/event.proto +++ b/remoting/proto/event.proto @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -26,6 +26,7 @@ message MouseEvent { BUTTON_LEFT = 1; BUTTON_MIDDLE = 2; BUTTON_RIGHT = 3; + BUTTON_MAX = 4; } // Mouse position information. |