diff options
author | wez <wez@chromium.org> | 2015-10-23 14:07:06 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-23 21:08:16 +0000 |
commit | ae3b75a1cd6d47607a789b5d0adba80f8fc3ebe4 (patch) | |
tree | 28e2d50e2d13bbd1ceef85355b37d4d2c7312b4d /remoting/client/normalizing_input_filter_win.cc | |
parent | 033bbbcb63cab781552dfb435c035131c423de30 (diff) | |
download | chromium_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.cc | 106 |
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 |