summaryrefslogtreecommitdiffstats
path: root/remoting/client/normalizing_input_filter_win.cc
diff options
context:
space:
mode:
authorwez <wez@chromium.org>2015-10-23 14:07:06 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-23 21:08:16 +0000
commitae3b75a1cd6d47607a789b5d0adba80f8fc3ebe4 (patch)
tree28e2d50e2d13bbd1ceef85355b37d4d2c7312b4d /remoting/client/normalizing_input_filter_win.cc
parent033bbbcb63cab781552dfb435c035131c423de30 (diff)
downloadchromium_src-ae3b75a1cd6d47607a789b5d0adba80f8fc3ebe4.zip
chromium_src-ae3b75a1cd6d47607a789b5d0adba80f8fc3ebe4.tar.gz
chromium_src-ae3b75a1cd6d47607a789b5d0adba80f8fc3ebe4.tar.bz2
Add NormalizingInputFilterWin to un-pick AltGr sequences.
Windows treats international keyboard layouts' AltGr modifier as a combination of left-Control and right-Alt modifiers, whereas the Chromoting protocol, and other platforms, treat AltGr as equivalent to right-Alt and handle the Alt/AltGr as part of the layout-specific meaning of the key. NormalizingInputFilterWin holds each keydown event for the left-Control key until the next input event (e.g. left-Control repeat, another key event, mouse event, etc) so that it can suppress it if the next event is a keydown for right-Alt, on the assumption that that indicates an AltGr sequence. BUG=470571 Review URL: https://codereview.chromium.org/1416233002 Cr-Commit-Position: refs/heads/master@{#355881}
Diffstat (limited to 'remoting/client/normalizing_input_filter_win.cc')
-rw-r--r--remoting/client/normalizing_input_filter_win.cc106
1 files changed, 106 insertions, 0 deletions
diff --git a/remoting/client/normalizing_input_filter_win.cc b/remoting/client/normalizing_input_filter_win.cc
new file mode 100644
index 0000000..20950da
--- /dev/null
+++ b/remoting/client/normalizing_input_filter_win.cc
@@ -0,0 +1,106 @@
+// Copyright 2015 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.
+
+#include "remoting/client/normalizing_input_filter_win.h"
+
+#include "base/logging.h"
+#include "ui/events/keycodes/dom/dom_code.h"
+
+namespace remoting {
+
+static bool IsLeftControl(uint32_t code) {
+ return code == static_cast<uint32_t>(ui::DomCode::CONTROL_LEFT);
+}
+
+static bool IsRightAlt(uint32_t code) {
+ return code == static_cast<uint32_t>(ui::DomCode::ALT_RIGHT);
+}
+
+NormalizingInputFilterWin::NormalizingInputFilterWin(
+ protocol::InputStub* input_stub)
+ : protocol::InputFilter(input_stub) {}
+
+NormalizingInputFilterWin::~NormalizingInputFilterWin() {}
+
+void NormalizingInputFilterWin::InjectKeyEvent(
+ const protocol::KeyEvent& event) {
+ DCHECK(event.has_usb_keycode());
+ DCHECK(event.has_pressed());
+
+ if (event.pressed()) {
+ ProcessKeyDown(event);
+ } else {
+ ProcessKeyUp(event);
+ }
+}
+
+void NormalizingInputFilterWin::InjectMouseEvent(
+ const protocol::MouseEvent& event) {
+ FlushDeferredKeydownEvent();
+ InputFilter::InjectMouseEvent(event);
+}
+
+void NormalizingInputFilterWin::ProcessKeyDown(
+ const protocol::KeyEvent& event) {
+ if (IsRightAlt(event.usb_keycode())) {
+ // If there's a deferred LeftControl event then treat it as part of an
+ // AltGr press, so swallow it.
+ if (deferred_control_keydown_.has_usb_keycode()) {
+ altgr_is_pressed_ = true;
+ deferred_control_keydown_ = protocol::KeyEvent();
+ }
+ }
+
+ // If a keydown for something other than RightAlt is received while there
+ // is a deferred LeftControl event then treat it as an actual LeftControl
+ // event, and flush it.
+ FlushDeferredKeydownEvent();
+
+ if (IsLeftControl(event.usb_keycode())) {
+ // If AltGr is pressed then ignore the LeftControl keydown repeat.
+ if (altgr_is_pressed_)
+ return;
+
+ // If LeftControl is not already pressed then defer the event.
+ if (!left_control_is_pressed_) {
+ deferred_control_keydown_ = event;
+ return;
+ }
+ }
+
+ InputFilter::InjectKeyEvent(event);
+}
+
+void NormalizingInputFilterWin::ProcessKeyUp(const protocol::KeyEvent& event) {
+ if (IsLeftControl(event.usb_keycode())) {
+ // If we treated the LeftControl as part of AltGr, and never sent the
+ // keydown, then ignore the keyup as well.
+ if (altgr_is_pressed_) {
+ altgr_is_pressed_ = false;
+ return;
+ }
+
+ // If there is still a deferred event then flush it, so that LeftControl
+ // press-and-release works.
+ FlushDeferredKeydownEvent();
+
+ left_control_is_pressed_ = false;
+ }
+
+ InputFilter::InjectKeyEvent(event);
+}
+
+void NormalizingInputFilterWin::FlushDeferredKeydownEvent() {
+ if (!deferred_control_keydown_.has_usb_keycode())
+ return;
+
+ DCHECK_EQ(static_cast<uint32_t>(ui::DomCode::CONTROL_LEFT),
+ deferred_control_keydown_.usb_keycode());
+
+ left_control_is_pressed_ = true;
+ InputFilter::InjectKeyEvent(deferred_control_keydown_);
+ deferred_control_keydown_ = protocol::KeyEvent();
+}
+
+} // namespace remoting