summaryrefslogtreecommitdiffstats
path: root/chromium/ash/wm/sticky_keys.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ash/wm/sticky_keys.cc')
-rw-r--r--chromium/ash/wm/sticky_keys.cc445
1 files changed, 0 insertions, 445 deletions
diff --git a/chromium/ash/wm/sticky_keys.cc b/chromium/ash/wm/sticky_keys.cc
deleted file mode 100644
index 9e2cc2a92de..00000000000
--- a/chromium/ash/wm/sticky_keys.cc
+++ /dev/null
@@ -1,445 +0,0 @@
-// Copyright 2013 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 "ash/wm/sticky_keys.h"
-
-#if defined(USE_X11)
-#include <X11/extensions/XInput2.h>
-#include <X11/Xlib.h>
-#undef RootWindow
-#endif
-
-#include "base/basictypes.h"
-#include "base/debug/stack_trace.h"
-#include "ui/aura/root_window.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_tracker.h"
-#include "ui/events/event.h"
-#include "ui/events/keycodes/keyboard_code_conversion.h"
-
-namespace ash {
-
-namespace {
-
-// Returns true if the type of mouse event should be modified by sticky keys.
-bool ShouldModifyMouseEvent(ui::MouseEvent* event) {
- ui::EventType type = event->type();
- return type == ui::ET_MOUSE_PRESSED || type == ui::ET_MOUSE_RELEASED ||
- type == ui::ET_MOUSEWHEEL;
-}
-
-// An implementation of StickyKeysHandler::StickyKeysHandlerDelegate.
-class StickyKeysHandlerDelegateImpl :
- public StickyKeysHandler::StickyKeysHandlerDelegate {
- public:
- StickyKeysHandlerDelegateImpl();
- virtual ~StickyKeysHandlerDelegateImpl();
-
- // StickyKeysHandlerDelegate overrides.
- virtual void DispatchKeyEvent(ui::KeyEvent* event,
- aura::Window* target) OVERRIDE;
-
- virtual void DispatchMouseEvent(ui::MouseEvent* event,
- aura::Window* target) OVERRIDE;
-
- virtual void DispatchScrollEvent(ui::ScrollEvent* event,
- aura::Window* target) OVERRIDE;
- private:
- DISALLOW_COPY_AND_ASSIGN(StickyKeysHandlerDelegateImpl);
-};
-
-StickyKeysHandlerDelegateImpl::StickyKeysHandlerDelegateImpl() {
-}
-
-StickyKeysHandlerDelegateImpl::~StickyKeysHandlerDelegateImpl() {
-}
-
-void StickyKeysHandlerDelegateImpl::DispatchKeyEvent(ui::KeyEvent* event,
- aura::Window* target) {
- DCHECK(target);
- target->GetDispatcher()->AsRootWindowHostDelegate()->OnHostKeyEvent(event);
-}
-
-void StickyKeysHandlerDelegateImpl::DispatchMouseEvent(ui::MouseEvent* event,
- aura::Window* target) {
- DCHECK(target);
- // We need to send a new, untransformed mouse event to the host.
- if (event->IsMouseWheelEvent()) {
- ui::MouseWheelEvent new_event(*static_cast<ui::MouseWheelEvent*>(event));
- target->GetDispatcher()->AsRootWindowHostDelegate()
- ->OnHostMouseEvent(&new_event);
- } else {
- ui::MouseEvent new_event(*event, target, target->GetRootWindow());
- target->GetDispatcher()->AsRootWindowHostDelegate()
- ->OnHostMouseEvent(&new_event);
- }
-}
-
-void StickyKeysHandlerDelegateImpl::DispatchScrollEvent(
- ui::ScrollEvent* event,
- aura::Window* target) {
- DCHECK(target);
- target->GetDispatcher()->AsRootWindowHostDelegate()
- ->OnHostScrollEvent(event);
-}
-
-} // namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// StickyKeys
-StickyKeys::StickyKeys()
- : enabled_(false),
- shift_sticky_key_(
- new StickyKeysHandler(ui::EF_SHIFT_DOWN,
- new StickyKeysHandlerDelegateImpl())),
- alt_sticky_key_(
- new StickyKeysHandler(ui::EF_ALT_DOWN,
- new StickyKeysHandlerDelegateImpl())),
- ctrl_sticky_key_(
- new StickyKeysHandler(ui::EF_CONTROL_DOWN,
- new StickyKeysHandlerDelegateImpl())) {
-}
-
-StickyKeys::~StickyKeys() {
-}
-
-void StickyKeys::Enable(bool enabled) {
- if (enabled_ != enabled) {
- enabled_ = enabled;
-
- // Reset key handlers when activating sticky keys to ensure all
- // the handlers' states are reset.
- if (enabled_) {
- shift_sticky_key_.reset(
- new StickyKeysHandler(ui::EF_SHIFT_DOWN,
- new StickyKeysHandlerDelegateImpl()));
- alt_sticky_key_.reset(
- new StickyKeysHandler(ui::EF_ALT_DOWN,
- new StickyKeysHandlerDelegateImpl()));
- ctrl_sticky_key_.reset(
- new StickyKeysHandler(ui::EF_CONTROL_DOWN,
- new StickyKeysHandlerDelegateImpl()));
- }
- }
-}
-
-bool StickyKeys::HandleKeyEvent(ui::KeyEvent* event) {
- return shift_sticky_key_->HandleKeyEvent(event) ||
- alt_sticky_key_->HandleKeyEvent(event) ||
- ctrl_sticky_key_->HandleKeyEvent(event);
- return ctrl_sticky_key_->HandleKeyEvent(event);
-}
-
-bool StickyKeys::HandleMouseEvent(ui::MouseEvent* event) {
- return shift_sticky_key_->HandleMouseEvent(event) ||
- alt_sticky_key_->HandleMouseEvent(event) ||
- ctrl_sticky_key_->HandleMouseEvent(event);
-}
-
-bool StickyKeys::HandleScrollEvent(ui::ScrollEvent* event) {
- return shift_sticky_key_->HandleScrollEvent(event) ||
- alt_sticky_key_->HandleScrollEvent(event) ||
- ctrl_sticky_key_->HandleScrollEvent(event);
-}
-
-void StickyKeys::OnKeyEvent(ui::KeyEvent* event) {
- // Do not consume a translated key event which is generated by an IME.
- if (event->type() == ui::ET_TRANSLATED_KEY_PRESS ||
- event->type() == ui::ET_TRANSLATED_KEY_RELEASE) {
- return;
- }
-
- if (enabled_ && HandleKeyEvent(event))
- event->StopPropagation();
-}
-
-void StickyKeys::OnMouseEvent(ui::MouseEvent* event) {
- if (enabled_ && HandleMouseEvent(event))
- event->StopPropagation();
-}
-
-void StickyKeys::OnScrollEvent(ui::ScrollEvent* event) {
- if (enabled_ && HandleScrollEvent(event))
- event->StopPropagation();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// StickyKeysHandler
-StickyKeysHandler::StickyKeysHandler(ui::EventFlags target_modifier_flag,
- StickyKeysHandlerDelegate* delegate)
- : modifier_flag_(target_modifier_flag),
- current_state_(DISABLED),
- event_from_myself_(false),
- preparing_to_enable_(false),
- scroll_delta_(0),
- delegate_(delegate) {
-}
-
-StickyKeysHandler::~StickyKeysHandler() {
-}
-
-StickyKeysHandler::StickyKeysHandlerDelegate::StickyKeysHandlerDelegate() {
-}
-
-StickyKeysHandler::StickyKeysHandlerDelegate::~StickyKeysHandlerDelegate() {
-}
-
-bool StickyKeysHandler::HandleKeyEvent(ui::KeyEvent* event) {
- if (event_from_myself_)
- return false; // Do not handle self-generated key event.
- switch (current_state_) {
- case DISABLED:
- return HandleDisabledState(event);
- case ENABLED:
- return HandleEnabledState(event);
- case LOCKED:
- return HandleLockedState(event);
- }
- NOTREACHED();
- return false;
-}
-
-bool StickyKeysHandler::HandleMouseEvent(ui::MouseEvent* event) {
- preparing_to_enable_ = false;
- if (event_from_myself_ || current_state_ == DISABLED
- || !ShouldModifyMouseEvent(event)) {
- return false;
- }
- DCHECK(current_state_ == ENABLED || current_state_ == LOCKED);
-
- AppendModifier(event);
- // Only disable on the mouse released event in normal, non-locked mode.
- if (current_state_ == ENABLED && event->type() != ui::ET_MOUSE_PRESSED) {
- current_state_ = DISABLED;
- DispatchEventAndReleaseModifier(event);
- return true;
- }
-
- return false;
-}
-
-bool StickyKeysHandler::HandleScrollEvent(ui::ScrollEvent* event) {
- preparing_to_enable_ = false;
- if (event_from_myself_ || current_state_ == DISABLED)
- return false;
- DCHECK(current_state_ == ENABLED || current_state_ == LOCKED);
-
- // We detect a direction change if the current |scroll_delta_| is assigned
- // and the offset of the current scroll event has the opposing sign.
- bool direction_changed = false;
- if (current_state_ == ENABLED && event->type() == ui::ET_SCROLL) {
- int offset = event->y_offset();
- if (scroll_delta_)
- direction_changed = offset * scroll_delta_ <= 0;
- scroll_delta_ = offset;
- }
-
- if (!direction_changed)
- AppendModifier(event);
-
- // We want to modify all the scroll events in the scroll sequence, which ends
- // with a fling start event. We also stop when the scroll sequence changes
- // direction.
- if (current_state_ == ENABLED &&
- (event->type() == ui::ET_SCROLL_FLING_START || direction_changed)) {
- current_state_ = DISABLED;
- scroll_delta_ = 0;
- DispatchEventAndReleaseModifier(event);
- return true;
- }
-
- return false;
-}
-
-StickyKeysHandler::KeyEventType
- StickyKeysHandler::TranslateKeyEvent(ui::KeyEvent* event) {
- bool is_target_key = false;
- if (event->key_code() == ui::VKEY_SHIFT ||
- event->key_code() == ui::VKEY_LSHIFT ||
- event->key_code() == ui::VKEY_RSHIFT) {
- is_target_key = (modifier_flag_ == ui::EF_SHIFT_DOWN);
- } else if (event->key_code() == ui::VKEY_CONTROL ||
- event->key_code() == ui::VKEY_LCONTROL ||
- event->key_code() == ui::VKEY_RCONTROL) {
- is_target_key = (modifier_flag_ == ui::EF_CONTROL_DOWN);
- } else if (event->key_code() == ui::VKEY_MENU ||
- event->key_code() == ui::VKEY_LMENU ||
- event->key_code() == ui::VKEY_RMENU) {
- is_target_key = (modifier_flag_ == ui::EF_ALT_DOWN);
- } else {
- return event->type() == ui::ET_KEY_PRESSED ?
- NORMAL_KEY_DOWN : NORMAL_KEY_UP;
- }
-
- if (is_target_key) {
- return event->type() == ui::ET_KEY_PRESSED ?
- TARGET_MODIFIER_DOWN : TARGET_MODIFIER_UP;
- }
- return event->type() == ui::ET_KEY_PRESSED ?
- OTHER_MODIFIER_DOWN : OTHER_MODIFIER_UP;
-}
-
-bool StickyKeysHandler::HandleDisabledState(ui::KeyEvent* event) {
- switch (TranslateKeyEvent(event)) {
- case TARGET_MODIFIER_UP:
- if (preparing_to_enable_) {
- preparing_to_enable_ = false;
- scroll_delta_ = 0;
- current_state_ = ENABLED;
- modifier_up_event_.reset(new ui::KeyEvent(*event));
- return true;
- }
- return false;
- case TARGET_MODIFIER_DOWN:
- preparing_to_enable_ = true;
- return false;
- case NORMAL_KEY_DOWN:
- preparing_to_enable_ = false;
- return false;
- case NORMAL_KEY_UP:
- case OTHER_MODIFIER_DOWN:
- case OTHER_MODIFIER_UP:
- return false;
- }
- NOTREACHED();
- return false;
-}
-
-bool StickyKeysHandler::HandleEnabledState(ui::KeyEvent* event) {
- switch (TranslateKeyEvent(event)) {
- case NORMAL_KEY_UP:
- case TARGET_MODIFIER_DOWN:
- return true;
- case TARGET_MODIFIER_UP:
- current_state_ = LOCKED;
- modifier_up_event_.reset();
- return true;
- case NORMAL_KEY_DOWN: {
- current_state_ = DISABLED;
- AppendModifier(event);
- DispatchEventAndReleaseModifier(event);
- return true;
- }
- case OTHER_MODIFIER_DOWN:
- case OTHER_MODIFIER_UP:
- return false;
- }
- NOTREACHED();
- return false;
-}
-
-bool StickyKeysHandler::HandleLockedState(ui::KeyEvent* event) {
- switch (TranslateKeyEvent(event)) {
- case TARGET_MODIFIER_DOWN:
- return true;
- case TARGET_MODIFIER_UP:
- current_state_ = DISABLED;
- return false;
- case NORMAL_KEY_DOWN:
- case NORMAL_KEY_UP:
- AppendModifier(event);
- return false;
- case OTHER_MODIFIER_DOWN:
- case OTHER_MODIFIER_UP:
- return false;
- }
- NOTREACHED();
- return false;
-}
-
-void StickyKeysHandler::DispatchEventAndReleaseModifier(ui::Event* event) {
- DCHECK(event->IsKeyEvent() ||
- event->IsMouseEvent() ||
- event->IsScrollEvent());
- DCHECK(modifier_up_event_.get());
- aura::Window* target = static_cast<aura::Window*>(event->target());
- DCHECK(target);
- aura::Window* root_window = target->GetRootWindow();
- DCHECK(root_window);
-
- aura::WindowTracker window_tracker;
- window_tracker.Add(target);
-
- event_from_myself_ = true;
- if (event->IsKeyEvent()) {
- delegate_->DispatchKeyEvent(static_cast<ui::KeyEvent*>(event), target);
- } else if (event->IsMouseEvent()) {
- delegate_->DispatchMouseEvent(static_cast<ui::MouseEvent*>(event), target);
- } else {
- delegate_->DispatchScrollEvent(
- static_cast<ui::ScrollEvent*>(event), target);
- }
-
- // The action triggered above may have destroyed the event target, in which
- // case we will dispatch the modifier up event to the root window instead.
- aura::Window* modifier_up_target =
- window_tracker.Contains(target) ? target : root_window;
- delegate_->DispatchKeyEvent(modifier_up_event_.get(), modifier_up_target);
- event_from_myself_ = false;
-}
-
-void StickyKeysHandler::AppendNativeEventMask(unsigned int* state) {
- unsigned int& state_ref = *state;
- switch (modifier_flag_) {
- case ui::EF_CONTROL_DOWN:
- state_ref |= ControlMask;
- break;
- case ui::EF_ALT_DOWN:
- state_ref |= Mod1Mask;
- break;
- case ui::EF_SHIFT_DOWN:
- state_ref |= ShiftMask;
- break;
- default:
- NOTREACHED();
- }
-}
-
-void StickyKeysHandler::AppendModifier(ui::KeyEvent* event) {
-#if defined(USE_X11)
- XEvent* xev = event->native_event();
- if (xev) {
- XKeyEvent* xkey = &(xev->xkey);
- AppendNativeEventMask(&xkey->state);
- }
-#elif defined(USE_OZONE)
- NOTIMPLEMENTED() << "Modifier key is not handled";
-#endif
- event->set_flags(event->flags() | modifier_flag_);
- event->set_character(ui::GetCharacterFromKeyCode(event->key_code(),
- event->flags()));
- event->NormalizeFlags();
-}
-
-void StickyKeysHandler::AppendModifier(ui::MouseEvent* event) {
-#if defined(USE_X11)
- XEvent* xev = event->native_event();
- if (xev) {
- XButtonEvent* xkey = &(xev->xbutton);
- AppendNativeEventMask(&xkey->state);
- }
-#elif defined(USE_OZONE)
- NOTIMPLEMENTED() << "Modifier key is not handled";
-#endif
- event->set_flags(event->flags() | modifier_flag_);
-}
-
-void StickyKeysHandler::AppendModifier(ui::ScrollEvent* event) {
-#if defined(USE_X11)
- XEvent* xev = event->native_event();
- if (xev) {
- XIDeviceEvent* xievent =
- static_cast<XIDeviceEvent*>(xev->xcookie.data);
- if (xievent) {
- AppendNativeEventMask(reinterpret_cast<unsigned int*>(
- &xievent->mods.effective));
- }
- }
-#elif defined(USE_OZONE)
- NOTIMPLEMENTED() << "Modifier key is not handled";
-#endif
- event->set_flags(event->flags() | modifier_flag_);
-}
-
-} // namespace ash