diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-19 17:58:51 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-19 17:58:51 +0000 |
commit | 0bb0c5a32a4348037c515372c5aa4b4bd5c0893f (patch) | |
tree | 09dd59ad4214ad83818d7ac2587d8530fdc131fd /ash/sticky_keys/sticky_keys_controller.cc | |
parent | bfcaff5da257f13f967c50162958b2a7be7cf2d6 (diff) | |
download | chromium_src-0bb0c5a32a4348037c515372c5aa4b4bd5c0893f.zip chromium_src-0bb0c5a32a4348037c515372c5aa4b4bd5c0893f.tar.gz chromium_src-0bb0c5a32a4348037c515372c5aa4b4bd5c0893f.tar.bz2 |
Revert 278342 "Convert sticky keys to a chromeos::EventRewriter ..."
> Convert sticky keys to a chromeos::EventRewriter phase.
>
> BUG=354035
> TEST=unit_tests,ash_unittests,manual
> R=sadrul@chromium.org,derat@chromium.org
>
> Review URL: https://codereview.chromium.org/255033003
TBR=kpschoedel@chromium.org
Review URL: https://codereview.chromium.org/341923006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278419 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/sticky_keys/sticky_keys_controller.cc')
-rw-r--r-- | ash/sticky_keys/sticky_keys_controller.cc | 515 |
1 files changed, 321 insertions, 194 deletions
diff --git a/ash/sticky_keys/sticky_keys_controller.cc b/ash/sticky_keys/sticky_keys_controller.cc index 6237004..53be1fc 100644 --- a/ash/sticky_keys/sticky_keys_controller.cc +++ b/ash/sticky_keys/sticky_keys_controller.cc @@ -4,6 +4,12 @@ #include "ash/sticky_keys/sticky_keys_controller.h" +#if defined(USE_X11) +#include <X11/extensions/XInput2.h> +#include <X11/Xlib.h> +#undef RootWindow +#endif + #include "ash/sticky_keys/sticky_keys_overlay.h" #include "base/basictypes.h" #include "base/debug/stack_trace.h" @@ -19,26 +25,79 @@ namespace ash { namespace { // Returns true if the type of mouse event should be modified by sticky keys. -bool ShouldModifyMouseEvent(const ui::MouseEvent& event) { - ui::EventType type = event.type(); +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; } -// Handle the common tail of event rewriting. -ui::EventRewriteStatus RewriteUpdate(bool consumed, - bool released, - int mod_down_flags, - int* flags) { - int changed_down_flags = mod_down_flags & ~*flags; - *flags |= mod_down_flags; - if (consumed) - return ui::EVENT_REWRITE_DISCARD; - if (released) - return ui::EVENT_REWRITE_DISPATCH_ANOTHER; - if (changed_down_flags) - return ui::EVENT_REWRITE_REWRITTEN; - return ui::EVENT_REWRITE_CONTINUE; +// 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: + void DispatchEvent(ui::Event* event, aura::Window* target); + + DISALLOW_COPY_AND_ASSIGN(StickyKeysHandlerDelegateImpl); +}; + +StickyKeysHandlerDelegateImpl::StickyKeysHandlerDelegateImpl() { +} + +StickyKeysHandlerDelegateImpl::~StickyKeysHandlerDelegateImpl() { +} + +void StickyKeysHandlerDelegateImpl::DispatchKeyEvent(ui::KeyEvent* event, + aura::Window* target) { + DispatchEvent(event, target); +} + +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()) { + aura::Window* source = static_cast<aura::Window*>(event->target()); + ui::MouseWheelEvent new_event(*static_cast<ui::MouseWheelEvent*>(event), + source, + source->GetRootWindow()); + // Transform the location back to host coordinates before dispatching. + new_event.UpdateForRootTransform(source->GetHost()->GetRootTransform()); + DispatchEvent(&new_event, target); + } else { + aura::Window* source = static_cast<aura::Window*>(event->target()); + ui::MouseEvent new_event(*event, source, source->GetRootWindow()); + // Transform the location back to host coordinates before dispatching. + new_event.UpdateForRootTransform(source->GetHost()->GetRootTransform()); + DispatchEvent(&new_event, target); + } +} + +void StickyKeysHandlerDelegateImpl::DispatchScrollEvent( + ui::ScrollEvent* event, + aura::Window* target) { + DispatchEvent(event, target); +} + +void StickyKeysHandlerDelegateImpl::DispatchEvent(ui::Event* event, + aura::Window* target) { + DCHECK(target); + ui::EventDispatchDetails details = + target->GetHost()->event_processor()->OnEventFromSource(event); + if (details.dispatcher_destroyed) + return; } } // namespace @@ -61,11 +120,21 @@ void StickyKeysController::Enable(bool 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)); - alt_sticky_key_.reset(new StickyKeysHandler(ui::EF_ALT_DOWN)); - altgr_sticky_key_.reset(new StickyKeysHandler(ui::EF_ALTGR_DOWN)); - ctrl_sticky_key_.reset(new StickyKeysHandler(ui::EF_CONTROL_DOWN)); - mod3_sticky_key_.reset(new StickyKeysHandler(ui::EF_MOD3_DOWN)); + shift_sticky_key_.reset( + new StickyKeysHandler(ui::EF_SHIFT_DOWN, + new StickyKeysHandlerDelegateImpl())); + alt_sticky_key_.reset( + new StickyKeysHandler(ui::EF_ALT_DOWN, + new StickyKeysHandlerDelegateImpl())); + altgr_sticky_key_.reset( + new StickyKeysHandler(ui::EF_ALTGR_DOWN, + new StickyKeysHandlerDelegateImpl())); + ctrl_sticky_key_.reset( + new StickyKeysHandler(ui::EF_CONTROL_DOWN, + new StickyKeysHandlerDelegateImpl())); + mod3_sticky_key_.reset( + new StickyKeysHandler(ui::EF_MOD3_DOWN, + new StickyKeysHandlerDelegateImpl())); overlay_.reset(new StickyKeysOverlay()); overlay_->SetModifierVisible(ui::EF_ALTGR_DOWN, altgr_enabled_); @@ -86,103 +155,56 @@ void StickyKeysController::SetModifiersEnabled(bool mod3_enabled, } } -bool StickyKeysController::HandleKeyEvent(const ui::KeyEvent& event, - ui::KeyboardCode key_code, - int* mod_down_flags, - bool* released) { - return shift_sticky_key_->HandleKeyEvent( - event, key_code, mod_down_flags, released) || - alt_sticky_key_->HandleKeyEvent( - event, key_code, mod_down_flags, released) || - altgr_sticky_key_->HandleKeyEvent( - event, key_code, mod_down_flags, released) || - ctrl_sticky_key_->HandleKeyEvent( - event, key_code, mod_down_flags, released) || - mod3_sticky_key_->HandleKeyEvent( - event, key_code, mod_down_flags, released); -} - -bool StickyKeysController::HandleMouseEvent(const ui::MouseEvent& event, - int* mod_down_flags, - bool* released) { - return shift_sticky_key_->HandleMouseEvent( - event, mod_down_flags, released) || - alt_sticky_key_->HandleMouseEvent( - event, mod_down_flags, released) || - altgr_sticky_key_->HandleMouseEvent( - event, mod_down_flags, released) || - ctrl_sticky_key_->HandleMouseEvent( - event, mod_down_flags, released) || - mod3_sticky_key_->HandleMouseEvent( - event, mod_down_flags, released); -} - -bool StickyKeysController::HandleScrollEvent(const ui::ScrollEvent& event, - int* mod_down_flags, - bool* released) { - return shift_sticky_key_->HandleScrollEvent( - event, mod_down_flags, released) || - alt_sticky_key_->HandleScrollEvent( - event, mod_down_flags, released) || - altgr_sticky_key_->HandleScrollEvent( - event, mod_down_flags, released) || - ctrl_sticky_key_->HandleScrollEvent( - event, mod_down_flags, released) || - mod3_sticky_key_->HandleScrollEvent( - event, mod_down_flags, released); -} - -ui::EventRewriteStatus StickyKeysController::RewriteKeyEvent( - const ui::KeyEvent& event, - ui::KeyboardCode key_code, - int* flags) { - if (!enabled_) - return ui::EVENT_REWRITE_CONTINUE; - int mod_down_flags = 0; - bool released = false; - bool consumed = HandleKeyEvent(event, key_code, &mod_down_flags, &released); - UpdateOverlay(); - return RewriteUpdate(consumed, released, mod_down_flags, flags); -} - -ui::EventRewriteStatus StickyKeysController::RewriteMouseEvent( - const ui::MouseEvent& event, - int* flags) { - if (!enabled_) - return ui::EVENT_REWRITE_CONTINUE; - int mod_down_flags = 0; - bool released = false; - bool consumed = HandleMouseEvent(event, &mod_down_flags, &released); - UpdateOverlay(); - return RewriteUpdate(consumed, released, mod_down_flags, flags); -} - -ui::EventRewriteStatus StickyKeysController::RewriteScrollEvent( - const ui::ScrollEvent& event, - int* flags) { - if (!enabled_) - return ui::EVENT_REWRITE_CONTINUE; - int mod_down_flags = 0; - bool released = false; - bool consumed = HandleScrollEvent(event, &mod_down_flags, &released); - UpdateOverlay(); - return RewriteUpdate(consumed, released, mod_down_flags, flags); -} - -ui::EventRewriteStatus StickyKeysController::NextDispatchEvent( - scoped_ptr<ui::Event>* new_event) { - DCHECK(new_event); - new_event->reset(); - int remaining = shift_sticky_key_->GetModifierUpEvent(new_event) + - alt_sticky_key_->GetModifierUpEvent(new_event) + - altgr_sticky_key_->GetModifierUpEvent(new_event) + - ctrl_sticky_key_->GetModifierUpEvent(new_event) + - mod3_sticky_key_->GetModifierUpEvent(new_event); - if (!new_event) - return ui::EVENT_REWRITE_CONTINUE; - if (remaining) - return ui::EVENT_REWRITE_DISPATCH_ANOTHER; - return ui::EVENT_REWRITE_REWRITTEN; +bool StickyKeysController::HandleKeyEvent(ui::KeyEvent* event) { + return shift_sticky_key_->HandleKeyEvent(event) || + alt_sticky_key_->HandleKeyEvent(event) || + altgr_sticky_key_->HandleKeyEvent(event) || + ctrl_sticky_key_->HandleKeyEvent(event) || + mod3_sticky_key_->HandleKeyEvent(event); +} + +bool StickyKeysController::HandleMouseEvent(ui::MouseEvent* event) { + return shift_sticky_key_->HandleMouseEvent(event) || + alt_sticky_key_->HandleMouseEvent(event) || + altgr_sticky_key_->HandleMouseEvent(event) || + ctrl_sticky_key_->HandleMouseEvent(event) || + mod3_sticky_key_->HandleMouseEvent(event); +} + +bool StickyKeysController::HandleScrollEvent(ui::ScrollEvent* event) { + return shift_sticky_key_->HandleScrollEvent(event) || + alt_sticky_key_->HandleScrollEvent(event) || + altgr_sticky_key_->HandleScrollEvent(event) || + ctrl_sticky_key_->HandleScrollEvent(event) || + mod3_sticky_key_->HandleScrollEvent(event); +} + +void StickyKeysController::OnKeyEvent(ui::KeyEvent* event) { + // Do not consume a translated key event which is generated by an IME. + if (event->IsTranslated()) + return; + + if (enabled_) { + if (HandleKeyEvent(event)) + event->StopPropagation(); + UpdateOverlay(); + } +} + +void StickyKeysController::OnMouseEvent(ui::MouseEvent* event) { + if (enabled_) { + if (HandleMouseEvent(event)) + event->StopPropagation(); + UpdateOverlay(); + } +} + +void StickyKeysController::OnScrollEvent(ui::ScrollEvent* event) { + if (enabled_) { + if (HandleScrollEvent(event)) + event->StopPropagation(); + UpdateOverlay(); + } } void StickyKeysController::UpdateOverlay() { @@ -213,64 +235,66 @@ StickyKeysOverlay* StickyKeysController::GetOverlayForTest() { /////////////////////////////////////////////////////////////////////////////// // StickyKeysHandler -StickyKeysHandler::StickyKeysHandler(ui::EventFlags modifier_flag) +StickyKeysHandler::StickyKeysHandler(ui::EventFlags modifier_flag, + StickyKeysHandlerDelegate* delegate) : modifier_flag_(modifier_flag), current_state_(STICKY_KEY_STATE_DISABLED), + event_from_myself_(false), preparing_to_enable_(false), - scroll_delta_(0) { + scroll_delta_(0), + delegate_(delegate) { } StickyKeysHandler::~StickyKeysHandler() { } -bool StickyKeysHandler::HandleKeyEvent(const ui::KeyEvent& event, - ui::KeyboardCode key_code, - int* mod_down_flags, - bool* released) { +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 STICKY_KEY_STATE_DISABLED: - return HandleDisabledState(event, key_code); + return HandleDisabledState(event); case STICKY_KEY_STATE_ENABLED: - return HandleEnabledState(event, key_code, mod_down_flags, released); + return HandleEnabledState(event); case STICKY_KEY_STATE_LOCKED: - return HandleLockedState(event, key_code, mod_down_flags, released); + return HandleLockedState(event); } NOTREACHED(); return false; } -bool StickyKeysHandler::HandleMouseEvent( - const ui::MouseEvent& event, - int* mod_down_flags, - bool* released) { +bool StickyKeysHandler::HandleMouseEvent(ui::MouseEvent* event) { if (ShouldModifyMouseEvent(event)) preparing_to_enable_ = false; - if (current_state_ == STICKY_KEY_STATE_DISABLED || - !ShouldModifyMouseEvent(event)) { + if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED + || !ShouldModifyMouseEvent(event)) { return false; } DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || current_state_ == STICKY_KEY_STATE_LOCKED); - *mod_down_flags |= modifier_flag_; + AppendModifier(event); // Only disable on the mouse released event in normal, non-locked mode. if (current_state_ == STICKY_KEY_STATE_ENABLED && - event.type() != ui::ET_MOUSE_PRESSED) { + event->type() != ui::ET_MOUSE_PRESSED) { current_state_ = STICKY_KEY_STATE_DISABLED; - *released = true; - return false; + DispatchEventAndReleaseModifier(event); + return true; } return false; } -bool StickyKeysHandler::HandleScrollEvent( - const ui::ScrollEvent& event, - int* mod_down_flags, - bool* released) { +bool StickyKeysHandler::HandleScrollEvent(ui::ScrollEvent* event) { preparing_to_enable_ = false; - if (current_state_ == STICKY_KEY_STATE_DISABLED) + if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED) return false; DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || current_state_ == STICKY_KEY_STATE_LOCKED); @@ -279,82 +303,70 @@ bool StickyKeysHandler::HandleScrollEvent( // and the offset of the current scroll event has the opposing sign. bool direction_changed = false; if (current_state_ == STICKY_KEY_STATE_ENABLED && - event.type() == ui::ET_SCROLL) { - int offset = event.y_offset(); + 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) - *mod_down_flags |= modifier_flag_; + 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_ == STICKY_KEY_STATE_ENABLED && - (event.type() == ui::ET_SCROLL_FLING_START || direction_changed)) { + (event->type() == ui::ET_SCROLL_FLING_START || direction_changed)) { current_state_ = STICKY_KEY_STATE_DISABLED; scroll_delta_ = 0; - *released = true; - return false; + DispatchEventAndReleaseModifier(event); + return true; } return false; } -int StickyKeysHandler::GetModifierUpEvent(scoped_ptr<ui::Event>* new_event) { - if (current_state_ != STICKY_KEY_STATE_DISABLED || !modifier_up_event_) - return 0; - DCHECK(new_event); - if (*new_event) - return 1; - new_event->reset(modifier_up_event_.release()); - return 0; -} - -StickyKeysHandler::KeyEventType StickyKeysHandler::TranslateKeyEvent( - ui::EventType type, - ui::KeyboardCode key_code) { +StickyKeysHandler::KeyEventType + StickyKeysHandler::TranslateKeyEvent(ui::KeyEvent* event) { bool is_target_key = false; - if (key_code == ui::VKEY_SHIFT || - key_code == ui::VKEY_LSHIFT || - key_code == ui::VKEY_RSHIFT) { + 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 (key_code == ui::VKEY_CONTROL || - key_code == ui::VKEY_LCONTROL || - key_code == ui::VKEY_RCONTROL) { + } 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 (key_code == ui::VKEY_MENU || - key_code == ui::VKEY_LMENU || - key_code == ui::VKEY_RMENU) { + } 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 if (key_code == ui::VKEY_ALTGR) { + } else if (event->key_code() == ui::VKEY_ALTGR) { is_target_key = (modifier_flag_ == ui::EF_ALTGR_DOWN); - } else if (key_code == ui::VKEY_OEM_8) { + } else if (event->key_code() == ui::VKEY_OEM_8) { is_target_key = (modifier_flag_ == ui::EF_MOD3_DOWN); } else { - return type == ui::ET_KEY_PRESSED ? + return event->type() == ui::ET_KEY_PRESSED ? NORMAL_KEY_DOWN : NORMAL_KEY_UP; } if (is_target_key) { - return type == ui::ET_KEY_PRESSED ? + return event->type() == ui::ET_KEY_PRESSED ? TARGET_MODIFIER_DOWN : TARGET_MODIFIER_UP; } - return type == ui::ET_KEY_PRESSED ? + return event->type() == ui::ET_KEY_PRESSED ? OTHER_MODIFIER_DOWN : OTHER_MODIFIER_UP; } -bool StickyKeysHandler::HandleDisabledState(const ui::KeyEvent& event, - ui::KeyboardCode key_code) { - switch (TranslateKeyEvent(event.type(), key_code)) { +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_ = STICKY_KEY_STATE_ENABLED; - modifier_up_event_.reset(new ui::KeyEvent(event)); + modifier_up_event_.reset(new ui::KeyEvent(*event)); return true; } return false; @@ -373,23 +385,20 @@ bool StickyKeysHandler::HandleDisabledState(const ui::KeyEvent& event, return false; } -bool StickyKeysHandler::HandleEnabledState(const ui::KeyEvent& event, - ui::KeyboardCode key_code, - int* mod_down_flags, - bool* released) { - switch (TranslateKeyEvent(event.type(), key_code)) { +bool StickyKeysHandler::HandleEnabledState(ui::KeyEvent* event) { + switch (TranslateKeyEvent(event)) { case NORMAL_KEY_UP: case TARGET_MODIFIER_DOWN: - return false; + return true; case TARGET_MODIFIER_UP: current_state_ = STICKY_KEY_STATE_LOCKED; modifier_up_event_.reset(); return true; case NORMAL_KEY_DOWN: { current_state_ = STICKY_KEY_STATE_DISABLED; - *mod_down_flags |= modifier_flag_; - *released = true; - return false; + AppendModifier(event); + DispatchEventAndReleaseModifier(event); + return true; } case OTHER_MODIFIER_DOWN: case OTHER_MODIFIER_UP: @@ -399,11 +408,8 @@ bool StickyKeysHandler::HandleEnabledState(const ui::KeyEvent& event, return false; } -bool StickyKeysHandler::HandleLockedState(const ui::KeyEvent& event, - ui::KeyboardCode key_code, - int* mod_down_flags, - bool* released) { - switch (TranslateKeyEvent(event.type(), key_code)) { +bool StickyKeysHandler::HandleLockedState(ui::KeyEvent* event) { + switch (TranslateKeyEvent(event)) { case TARGET_MODIFIER_DOWN: return true; case TARGET_MODIFIER_UP: @@ -411,7 +417,7 @@ bool StickyKeysHandler::HandleLockedState(const ui::KeyEvent& event, return false; case NORMAL_KEY_DOWN: case NORMAL_KEY_UP: - *mod_down_flags |= modifier_flag_; + AppendModifier(event); return false; case OTHER_MODIFIER_DOWN: case OTHER_MODIFIER_UP: @@ -421,4 +427,125 @@ bool StickyKeysHandler::HandleLockedState(const ui::KeyEvent& event, 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) { +#if defined(USE_X11) + 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_ALTGR_DOWN: + state_ref |= Mod5Mask; + break; + case ui::EF_SHIFT_DOWN: + state_ref |= ShiftMask; + break; + case ui::EF_MOD3_DOWN: + state_ref |= Mod3Mask; + break; + default: + NOTREACHED(); + } +#endif +} + +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) + // The native mouse event can either be a classic X button event or an + // XInput2 button event. + XEvent* xev = event->native_event(); + if (xev) { + switch (xev->type) { + case ButtonPress: + case ButtonRelease: { + XButtonEvent* xkey = &(xev->xbutton); + AppendNativeEventMask(&xkey->state); + break; + } + case GenericEvent: { + XIDeviceEvent* xievent = + static_cast<XIDeviceEvent*>(xev->xcookie.data); + CHECK(xievent->evtype == XI_ButtonPress || + xievent->evtype == XI_ButtonRelease); + AppendNativeEventMask( + reinterpret_cast<unsigned int*>(&xievent->mods.effective)); + break; + } + default: + NOTREACHED(); + } + } +#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 |