diff options
-rw-r--r-- | ash/ash.gyp | 5 | ||||
-rw-r--r-- | ash/ash_strings.grd | 12 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_controller.cc | 101 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_controller.h | 34 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_overlay.cc | 283 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_overlay.h | 71 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_overlay_unittest.cc | 206 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_state.h | 25 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_unittest.cc | 114 |
9 files changed, 740 insertions, 111 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index fb332ba..439d41d 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -251,8 +251,11 @@ 'shell_delegate.h', 'shell_factory.h', 'shell_window_ids.h', + 'sticky_keys/sticky_keys_state.h', 'sticky_keys/sticky_keys_controller.cc', 'sticky_keys/sticky_keys_controller.h', + 'sticky_keys/sticky_keys_overlay.cc', + 'sticky_keys/sticky_keys_overlay.h', 'system/bluetooth/bluetooth_observer.h', 'system/bluetooth/tray_bluetooth.cc', 'system/bluetooth/tray_bluetooth.h', @@ -875,6 +878,7 @@ 'shell/window_watcher_shelf_item_delegate.h', 'shell/window_watcher_unittest.cc', 'shell_unittest.cc', + 'sticky_keys/sticky_keys_overlay_unittest.cc', 'sticky_keys/sticky_keys_unittest.cc', 'system/chromeos/managed/tray_locally_managed_user_unittest.cc', 'system/chromeos/network/network_state_notifier_unittest.cc', @@ -951,6 +955,7 @@ ['exclude', 'ash_root_window_transformer_unittest.cc'], ['exclude', 'magnifier/magnification_controller_unittest.cc'], ['exclude', 'wm/workspace/workspace_window_resizer_unittest.cc'], + ['exclude', 'sticky_keys/sticky_keys_overlay_unittest.cc'], ['exclude', 'sticky_keys/sticky_keys_unittest.cc'], ['exclude', 'autoclick/autoclick_unittest.cc'], ], diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index c51d882..dfab164 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd @@ -598,6 +598,18 @@ Press Shift + Alt to switch. <message name="IDS_ASH_LOGOUT_CONFIRMATION_BUTTON" desc="The text for okay button of the logout confirmation dialog."> Sign out now </message> + <message name="IDS_ASH_CONTROL_KEY" desc="Name of [Ctrl] key name. Shouldn't be translated in many languages actually. This name should be lower case."> + ctrl + </message> + <message name="IDS_ASH_SHIFT_KEY" desc="Name of [Shift] key. Shouldn't be translated in many languages actually. This name should be lower case."> + shift + </message> + <message name="IDS_ASH_ALT_KEY" desc="Name of [Alt] key name. Shouldn't be translated in many languages actually. This name should be lower case."> + alt + </message> + <message name="IDS_ASH_SEARCH_KEY" desc="Name of [Search] key name. Shouldn't be translated in many languages actually. This name should be lower case."> + search + </message> <!-- ChromeOS-specific strings --> <if expr="pp_ifdef('chromeos')"> diff --git a/ash/sticky_keys/sticky_keys_controller.cc b/ash/sticky_keys/sticky_keys_controller.cc index aad1ee4..abb7906 100644 --- a/ash/sticky_keys/sticky_keys_controller.cc +++ b/ash/sticky_keys/sticky_keys_controller.cc @@ -10,6 +10,7 @@ #undef RootWindow #endif +#include "ash/sticky_keys/sticky_keys_overlay.h" #include "base/basictypes.h" #include "base/debug/stack_trace.h" #include "ui/aura/root_window.h" @@ -89,16 +90,7 @@ void StickyKeysHandlerDelegateImpl::DispatchScrollEvent( /////////////////////////////////////////////////////////////////////////////// // StickyKeys StickyKeysController::StickyKeysController() - : 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())) { + : enabled_(false) { } StickyKeysController::~StickyKeysController() { @@ -113,13 +105,17 @@ void StickyKeysController::Enable(bool enabled) { if (enabled_) { shift_sticky_key_.reset( new StickyKeysHandler(ui::EF_SHIFT_DOWN, - new StickyKeysHandlerDelegateImpl())); + 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())); + + overlay_.reset(new StickyKeysOverlay()); + } else if (overlay_.get()) { + overlay_->Show(false); } } } @@ -149,26 +145,55 @@ void StickyKeysController::OnKeyEvent(ui::KeyEvent* event) { return; } - if (enabled_ && HandleKeyEvent(event)) - event->StopPropagation(); + if (enabled_) { + if (HandleKeyEvent(event)) + event->StopPropagation(); + UpdateOverlay(); + } } void StickyKeysController::OnMouseEvent(ui::MouseEvent* event) { - if (enabled_ && HandleMouseEvent(event)) - event->StopPropagation(); + if (enabled_) { + if (HandleMouseEvent(event)) + event->StopPropagation(); + UpdateOverlay(); + } } void StickyKeysController::OnScrollEvent(ui::ScrollEvent* event) { - if (enabled_ && HandleScrollEvent(event)) - event->StopPropagation(); + if (enabled_) { + if (HandleScrollEvent(event)) + event->StopPropagation(); + UpdateOverlay(); + } +} + +void StickyKeysController::UpdateOverlay() { + overlay_->SetModifierKeyState( + ui::EF_SHIFT_DOWN, shift_sticky_key_->current_state()); + overlay_->SetModifierKeyState( + ui::EF_CONTROL_DOWN, ctrl_sticky_key_->current_state()); + overlay_->SetModifierKeyState( + ui::EF_ALT_DOWN, alt_sticky_key_->current_state()); + + bool key_in_use = + shift_sticky_key_->current_state() != STICKY_KEY_STATE_DISABLED || + alt_sticky_key_->current_state() != STICKY_KEY_STATE_DISABLED || + ctrl_sticky_key_->current_state() != STICKY_KEY_STATE_DISABLED; + + overlay_->Show(enabled_ && key_in_use); +} + +StickyKeysOverlay* StickyKeysController::GetOverlayForTest() { + return overlay_.get(); } /////////////////////////////////////////////////////////////////////////////// // StickyKeysHandler -StickyKeysHandler::StickyKeysHandler(ui::EventFlags target_modifier_flag, +StickyKeysHandler::StickyKeysHandler(ui::EventFlags modifier_flag, StickyKeysHandlerDelegate* delegate) - : modifier_flag_(target_modifier_flag), - current_state_(DISABLED), + : modifier_flag_(modifier_flag), + current_state_(STICKY_KEY_STATE_DISABLED), event_from_myself_(false), preparing_to_enable_(false), scroll_delta_(0), @@ -188,11 +213,11 @@ bool StickyKeysHandler::HandleKeyEvent(ui::KeyEvent* event) { if (event_from_myself_) return false; // Do not handle self-generated key event. switch (current_state_) { - case DISABLED: + case STICKY_KEY_STATE_DISABLED: return HandleDisabledState(event); - case ENABLED: + case STICKY_KEY_STATE_ENABLED: return HandleEnabledState(event); - case LOCKED: + case STICKY_KEY_STATE_LOCKED: return HandleLockedState(event); } NOTREACHED(); @@ -203,16 +228,18 @@ bool StickyKeysHandler::HandleMouseEvent(ui::MouseEvent* event) { if (ShouldModifyMouseEvent(event)) preparing_to_enable_ = false; - if (event_from_myself_ || current_state_ == DISABLED + if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED || !ShouldModifyMouseEvent(event)) { return false; } - DCHECK(current_state_ == ENABLED || current_state_ == LOCKED); + DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || + current_state_ == STICKY_KEY_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; + if (current_state_ == STICKY_KEY_STATE_ENABLED && + event->type() != ui::ET_MOUSE_PRESSED) { + current_state_ = STICKY_KEY_STATE_DISABLED; DispatchEventAndReleaseModifier(event); return true; } @@ -222,14 +249,16 @@ bool StickyKeysHandler::HandleMouseEvent(ui::MouseEvent* event) { bool StickyKeysHandler::HandleScrollEvent(ui::ScrollEvent* event) { preparing_to_enable_ = false; - if (event_from_myself_ || current_state_ == DISABLED) + if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED) return false; - DCHECK(current_state_ == ENABLED || current_state_ == LOCKED); + DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED || + current_state_ == STICKY_KEY_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) { + if (current_state_ == STICKY_KEY_STATE_ENABLED && + event->type() == ui::ET_SCROLL) { int offset = event->y_offset(); if (scroll_delta_) direction_changed = offset * scroll_delta_ <= 0; @@ -242,9 +271,9 @@ bool StickyKeysHandler::HandleScrollEvent(ui::ScrollEvent* 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 && + if (current_state_ == STICKY_KEY_STATE_ENABLED && (event->type() == ui::ET_SCROLL_FLING_START || direction_changed)) { - current_state_ = DISABLED; + current_state_ = STICKY_KEY_STATE_DISABLED; scroll_delta_ = 0; DispatchEventAndReleaseModifier(event); return true; @@ -287,7 +316,7 @@ bool StickyKeysHandler::HandleDisabledState(ui::KeyEvent* event) { if (preparing_to_enable_) { preparing_to_enable_ = false; scroll_delta_ = 0; - current_state_ = ENABLED; + current_state_ = STICKY_KEY_STATE_ENABLED; modifier_up_event_.reset(new ui::KeyEvent(*event)); return true; } @@ -313,11 +342,11 @@ bool StickyKeysHandler::HandleEnabledState(ui::KeyEvent* event) { case TARGET_MODIFIER_DOWN: return true; case TARGET_MODIFIER_UP: - current_state_ = LOCKED; + current_state_ = STICKY_KEY_STATE_LOCKED; modifier_up_event_.reset(); return true; case NORMAL_KEY_DOWN: { - current_state_ = DISABLED; + current_state_ = STICKY_KEY_STATE_DISABLED; AppendModifier(event); DispatchEventAndReleaseModifier(event); return true; @@ -335,7 +364,7 @@ bool StickyKeysHandler::HandleLockedState(ui::KeyEvent* event) { case TARGET_MODIFIER_DOWN: return true; case TARGET_MODIFIER_UP: - current_state_ = DISABLED; + current_state_ = STICKY_KEY_STATE_DISABLED; return false; case NORMAL_KEY_DOWN: case NORMAL_KEY_UP: diff --git a/ash/sticky_keys/sticky_keys_controller.h b/ash/sticky_keys/sticky_keys_controller.h index c31eebd..bb75770 100644 --- a/ash/sticky_keys/sticky_keys_controller.h +++ b/ash/sticky_keys/sticky_keys_controller.h @@ -6,6 +6,7 @@ #define ASH_STICKY_KEYS_STICKY_KEYS_CONTROLLER_H_ #include "ash/ash_export.h" +#include "ash/sticky_keys/sticky_keys_state.h" #include "base/memory/scoped_ptr.h" #include "ui/events/event_constants.h" #include "ui/events/event_handler.h" @@ -22,6 +23,7 @@ class Window; namespace ash { +class StickyKeysOverlay; class StickyKeysHandler; // StickyKeysController is an accessibility feature for users to be able to @@ -65,6 +67,15 @@ class ASH_EXPORT StickyKeysController : public ui::EventHandler { // Activate sticky keys to intercept and modify incoming events. void Enable(bool enabled); + // Overridden from ui::EventHandler: + virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE; + virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE; + virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE; + + // Returns the StickyKeyOverlay used by the controller. Ownership is not + // passed. + StickyKeysOverlay* GetOverlayForTest(); + private: // Handles keyboard event. Returns true if Sticky key consumes keyboard event. bool HandleKeyEvent(ui::KeyEvent* event); @@ -75,10 +86,8 @@ class ASH_EXPORT StickyKeysController : public ui::EventHandler { // Handles scroll event. Returns true if sticky key consumes scroll event. bool HandleScrollEvent(ui::ScrollEvent* event); - // Overridden from ui::EventHandler: - virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE; - virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE; - virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE; + // Updates the overlay UI with the current state of the sticky keys. + void UpdateOverlay(); // Whether sticky keys is activated and modifying events. bool enabled_; @@ -88,6 +97,8 @@ class ASH_EXPORT StickyKeysController : public ui::EventHandler { scoped_ptr<StickyKeysHandler> alt_sticky_key_; scoped_ptr<StickyKeysHandler> ctrl_sticky_key_; + scoped_ptr<StickyKeysOverlay> overlay_; + DISALLOW_COPY_AND_ASSIGN(StickyKeysController); }; @@ -139,19 +150,6 @@ class ASH_EXPORT StickyKeysHandler { virtual void DispatchScrollEvent(ui::ScrollEvent* event, aura::Window* target) = 0; }; - // Represents Sticky Key state. - enum StickyKeyState { - // The sticky key is disabled. Incomming non modifier key events are not - // affected. - DISABLED, - // The sticky key is enabled. Incomming non modifier key down events are - // modified with |modifier_flag_|. After that, sticky key state become - // DISABLED. - ENABLED, - // The sticky key is locked. Incomming non modifier key down events are - // modified with |modifier_flag_|. - LOCKED, - }; // This class takes an ownership of |delegate|. StickyKeysHandler(ui::EventFlags modifier_flag, @@ -207,7 +205,7 @@ class ASH_EXPORT StickyKeysHandler { void AppendModifier(ui::MouseEvent* event); void AppendModifier(ui::ScrollEvent* event); - // The modifier flag to be monitored and appended. + // The modifier flag to be monitored and appended to events. const ui::EventFlags modifier_flag_; // The current sticky key status. diff --git a/ash/sticky_keys/sticky_keys_overlay.cc b/ash/sticky_keys/sticky_keys_overlay.cc new file mode 100644 index 0000000..19e5acb --- /dev/null +++ b/ash/sticky_keys/sticky_keys_overlay.cc @@ -0,0 +1,283 @@ +// Copyright 2014 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/sticky_keys/sticky_keys_overlay.h" + +#include "ash/shell.h" +#include "ash/shell_window_ids.h" +#include "ash/sticky_keys/sticky_keys_controller.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "grit/ash_strings.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/font_list.h" +#include "ui/views/border.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" + +namespace ash { + +namespace { + +// Horizontal offset of the overlay from the top left of the screen. +const int kHorizontalOverlayOffset = 18; + +// Vertical offset of the overlay from the top left of the screen. +const int kVerticalOverlayOffset = 18; + +// Spacing between overlay contents and border. +const int kHorizontalBorderSpacing = 9; +const int kVerticalBorderSpacing = 4; + +// Spacing between modifier key labels. +const int kKeyLabelSpacing = 7; + +// Duration of slide animation when overlay is shown or hidden. +const int kSlideAnimationDurationMs = 100; + +} + +/////////////////////////////////////////////////////////////////////////////// +// StickyKeyOverlayLabel +class StickyKeyOverlayLabel : public views::Label { + public: + explicit StickyKeyOverlayLabel(const std::string& key_name); + + virtual ~StickyKeyOverlayLabel(); + + StickyKeyState state() const { return state_; } + + void SetKeyState(StickyKeyState state); + + private: + // views::Label overrides: + virtual void PaintText(gfx::Canvas* canvas, + const base::string16& text, + const gfx::Rect& text_bounds, + int flags) OVERRIDE; + + StickyKeyState state_; + + DISALLOW_COPY_AND_ASSIGN(StickyKeyOverlayLabel); +}; + +StickyKeyOverlayLabel::StickyKeyOverlayLabel(const std::string& key_name) + : state_(STICKY_KEY_STATE_DISABLED) { + SetText(base::UTF8ToUTF16(key_name)); + SetHorizontalAlignment(gfx::ALIGN_LEFT); + SetFontList( + font_list().DeriveFontListWithSize(18)); + SetAutoColorReadabilityEnabled(false); + SetFocusable(false); + SetEnabledColor(SkColorSetARGB(0x80, 0xFF, 0xFF, 0xFF)); + SetDisabledColor(SkColorSetARGB(0x80, 0xFF, 0xFF, 0xFF)); +} + +StickyKeyOverlayLabel::~StickyKeyOverlayLabel() { +} + +void StickyKeyOverlayLabel::SetKeyState(StickyKeyState state) { + state_ = state; + SkColor label_color; + int style; + switch (state) { + case STICKY_KEY_STATE_ENABLED: + style = gfx::Font::NORMAL; + label_color = SkColorSetA(enabled_color(), 0xFF); + break; + case STICKY_KEY_STATE_LOCKED: + style = gfx::Font::UNDERLINE; + label_color = SkColorSetA(enabled_color(), 0xFF); + break; + default: + style = gfx::Font::NORMAL; + label_color = SkColorSetA(enabled_color(), 0x80); + } + + SetEnabledColor(label_color); + SetDisabledColor(label_color); + SetFontList(font_list().DeriveFontListWithSizeDeltaAndStyle(0, style)); +} + +void StickyKeyOverlayLabel::PaintText(gfx::Canvas* canvas, + const base::string16& text, + const gfx::Rect& text_bounds, + int flags) { + views::Label::PaintText(canvas, + text, + text_bounds, + flags | gfx::Canvas::NO_SUBPIXEL_RENDERING); +} + + +/////////////////////////////////////////////////////////////////////////////// +// StickyKeyOverlayLabel +class StickyKeysOverlayView : public views::WidgetDelegateView { + public: + StickyKeysOverlayView(); + + virtual ~StickyKeysOverlayView(); + + // views::WidgetDelegateView overrides: + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + + void SetKeyState(ui::EventFlags modifier, StickyKeyState state); + + StickyKeyState GetKeyState(ui::EventFlags modifier); + + private: + void AddKeyLabel(ui::EventFlags modifier, const std::string& key_label); + + typedef std::map<ui::EventFlags, StickyKeyOverlayLabel*> ModifierLabelMap; + ModifierLabelMap modifier_label_map_; + + DISALLOW_COPY_AND_ASSIGN(StickyKeysOverlayView); +}; + +StickyKeysOverlayView::StickyKeysOverlayView() { + SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, + kHorizontalBorderSpacing, + kVerticalBorderSpacing, + kKeyLabelSpacing)); + AddKeyLabel(ui::EF_CONTROL_DOWN, + l10n_util::GetStringUTF8(IDS_ASH_CONTROL_KEY)); + AddKeyLabel(ui::EF_ALT_DOWN, + l10n_util::GetStringUTF8(IDS_ASH_ALT_KEY)); + AddKeyLabel(ui::EF_SHIFT_DOWN, + l10n_util::GetStringUTF8(IDS_ASH_SHIFT_KEY)); +} + +StickyKeysOverlayView::~StickyKeysOverlayView() {} + +void StickyKeysOverlayView::OnPaint(gfx::Canvas* canvas) { + SkPaint paint; + paint.setStyle(SkPaint::kFill_Style); + paint.setColor(SkColorSetARGB(0xB3, 0x55, 0x55, 0x55)); + canvas->DrawRoundRect(GetLocalBounds(), 2, paint); + views::WidgetDelegateView::OnPaint(canvas); +} + +void StickyKeysOverlayView::SetKeyState(ui::EventFlags modifier, + StickyKeyState state) { + ModifierLabelMap::iterator it = modifier_label_map_.find(modifier); + DCHECK(it != modifier_label_map_.end()); + if (it != modifier_label_map_.end()) { + StickyKeyOverlayLabel* label = it->second; + label->SetKeyState(state); + } +} + +StickyKeyState StickyKeysOverlayView::GetKeyState(ui::EventFlags modifier) { + ModifierLabelMap::iterator it = modifier_label_map_.find(modifier); + DCHECK(it != modifier_label_map_.end()); + return it->second->state(); +} + +void StickyKeysOverlayView::AddKeyLabel(ui::EventFlags modifier, + const std::string& key_label) { + StickyKeyOverlayLabel* label = new StickyKeyOverlayLabel(key_label); + AddChildView(label); + modifier_label_map_[modifier] = label; +} + +/////////////////////////////////////////////////////////////////////////////// +// StickyKeysOverlay +StickyKeysOverlay::StickyKeysOverlay() + : is_visible_(false), + overlay_view_(new StickyKeysOverlayView), + widget_size_(overlay_view_->GetPreferredSize()) { + views::Widget::InitParams params; + params.type = views::Widget::InitParams::TYPE_POPUP; + params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.accept_events = false; + params.can_activate = false; + params.keep_on_top = true; + params.remove_standard_frame = true; + params.delegate = overlay_view_; + params.bounds = CalculateOverlayBounds(); + params.parent = Shell::GetContainer( + Shell::GetTargetRootWindow(), + internal::kShellWindowId_OverlayContainer); + overlay_widget_.reset(new views::Widget); + overlay_widget_->Init(params); + overlay_widget_->SetVisibilityChangedAnimationsEnabled(false); + overlay_widget_->SetContentsView(overlay_view_); + overlay_widget_->GetNativeView()->SetName("StickyKeysOverlay"); +} + +StickyKeysOverlay::~StickyKeysOverlay() {} + +void StickyKeysOverlay::Show(bool visible) { + if (is_visible_ == visible) + return; + + is_visible_ = visible; + if (is_visible_) + overlay_widget_->Show(); + overlay_widget_->SetBounds(CalculateOverlayBounds()); + + ui::LayerAnimator* animator = overlay_widget_->GetLayer()->GetAnimator(); + animator->AddObserver(this); + + // Ensure transform is correct before beginning animation. + if (!animator->is_animating()) { + int sign = is_visible_ ? -1 : 1; + gfx::Transform transform; + transform.Translate( + sign * (widget_size_.width() + kHorizontalOverlayOffset), 0); + overlay_widget_->GetLayer()->SetTransform(transform); + } + + ui::ScopedLayerAnimationSettings settings(animator); + settings.SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); + settings.SetTweenType(visible ? gfx::Tween::EASE_OUT : gfx::Tween::EASE_IN); + settings.SetTransitionDuration( + base::TimeDelta::FromMilliseconds(kSlideAnimationDurationMs)); + + overlay_widget_->GetLayer()->SetTransform(gfx::Transform()); +} + +void StickyKeysOverlay::SetModifierKeyState(ui::EventFlags modifier, + StickyKeyState state) { + overlay_view_->SetKeyState(modifier, state); +} + +StickyKeyState StickyKeysOverlay::GetModifierKeyState( + ui::EventFlags modifier) { + return overlay_view_->GetKeyState(modifier); +} + +gfx::Rect StickyKeysOverlay::CalculateOverlayBounds() { + int x = is_visible_ ? kHorizontalOverlayOffset : -widget_size_.width(); + return gfx::Rect(gfx::Point(x, kVerticalOverlayOffset), widget_size_); +} + +void StickyKeysOverlay::OnLayerAnimationEnded( + ui::LayerAnimationSequence* sequence) { + ui::LayerAnimator* animator = overlay_widget_->GetLayer()->GetAnimator(); + if (animator) + animator->RemoveObserver(this); + if (!is_visible_) + overlay_widget_->Hide(); +} + +void StickyKeysOverlay::OnLayerAnimationAborted( + ui::LayerAnimationSequence* sequence) { + ui::LayerAnimator* animator = overlay_widget_->GetLayer()->GetAnimator(); + if (animator) + animator->RemoveObserver(this); +} + +void StickyKeysOverlay::OnLayerAnimationScheduled( + ui::LayerAnimationSequence* sequence) { +} + +} // namespace ash diff --git a/ash/sticky_keys/sticky_keys_overlay.h b/ash/sticky_keys/sticky_keys_overlay.h new file mode 100644 index 0000000..88d195a --- /dev/null +++ b/ash/sticky_keys/sticky_keys_overlay.h @@ -0,0 +1,71 @@ +// Copyright 2014 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. + +#ifndef ASH_STICKY_KEYS_STICKY_KEYS_OVERLAY_H_ +#define ASH_STICKY_KEYS_STICKY_KEYS_OVERLAY_H_ + +#include "ash/ash_export.h" +#include "ash/sticky_keys/sticky_keys_state.h" +#include "base/memory/scoped_ptr.h" +#include "ui/compositor/layer_animation_observer.h" +#include "ui/events/event_constants.h" +#include "ui/gfx/geometry/size.h" + +namespace gfx { +class Rect; +} + +namespace views { +class Widget; +} + +namespace ash { + +class StickyKeysOverlayView; + +// Controls the overlay UI for sticky keys, an accessibility feature allowing +// use of modifier keys without holding them down. This overlay will appear as +// a transparent window on the top left of the screen, showing the state of +// each sticky key modifier. +class ASH_EXPORT StickyKeysOverlay : public ui::LayerAnimationObserver { + public: + StickyKeysOverlay(); + virtual ~StickyKeysOverlay(); + + // Shows or hides the overlay. + void Show(bool visible); + + // Updates the overlay with the current state of a sticky key modifier. + void SetModifierKeyState(ui::EventFlags modifier, + StickyKeyState state); + + // Get the current state of the sticky key modifier in the overlay. + StickyKeyState GetModifierKeyState(ui::EventFlags modifier); + + // Returns true if the overlay is currently visible. If the overlay is + // animating, the returned value is the target of the animation. + bool is_visible() { return is_visible_; } + + private: + // Returns the current bounds of the overlay, which is based on visibility. + gfx::Rect CalculateOverlayBounds(); + + // gfx::LayerAnimationObserver overrides: + virtual void OnLayerAnimationEnded( + ui::LayerAnimationSequence* sequence) OVERRIDE; + virtual void OnLayerAnimationAborted( + ui::LayerAnimationSequence* sequence) OVERRIDE; + virtual void OnLayerAnimationScheduled( + ui::LayerAnimationSequence* sequence) OVERRIDE; + + bool is_visible_; + scoped_ptr<views::Widget> overlay_widget_; + // Ownership of |overlay_view_| is passed to the view heirarchy. + StickyKeysOverlayView* overlay_view_; + gfx::Size widget_size_; +}; + +} // namespace ash + +#endif // ASH_STICKY_KEYS_STICKY_KEYS_OVERLAY_H_ diff --git a/ash/sticky_keys/sticky_keys_overlay_unittest.cc b/ash/sticky_keys/sticky_keys_overlay_unittest.cc new file mode 100644 index 0000000..de2d980 --- /dev/null +++ b/ash/sticky_keys/sticky_keys_overlay_unittest.cc @@ -0,0 +1,206 @@ +// Copyright 2014 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/sticky_keys/sticky_keys_overlay.h" + +#include "ash/shell.h" +#include "ash/sticky_keys/sticky_keys_controller.h" +#include "ash/test/ash_test_base.h" +#include "base/memory/scoped_ptr.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window_tree_host_delegate.h" +#include "ui/events/event.h" + +namespace ash { + +class StickyKeysOverlayTest : public test::AshTestBase { + public: + StickyKeysOverlayTest() : + controller_(NULL), + overlay_(NULL) {} + + virtual ~StickyKeysOverlayTest() {} + + virtual void SetUp() OVERRIDE { + test::AshTestBase::SetUp(); + + controller_ = Shell::GetInstance()->sticky_keys_controller(); + controller_->Enable(true); + overlay_ = controller_->GetOverlayForTest(); + ASSERT_TRUE(overlay_); + } + + void PressAndReleaseKey(ui::KeyboardCode code) { + SendKeyEvent(ui::ET_KEY_PRESSED, code); + SendKeyEvent(ui::ET_KEY_RELEASED, code); + } + + void SendKeyEvent(ui::EventType type, ui::KeyboardCode code) { + ui::KeyEvent event(type, code, 0, false); + ui::Event::DispatcherApi dispatcher(&event); + dispatcher.set_target(Shell::GetInstance()->GetPrimaryRootWindow()); + + aura::WindowTreeHostDelegate* delegate = Shell::GetPrimaryRootWindow() + ->GetDispatcher()->AsWindowTreeHostDelegate(); + delegate->OnHostKeyEvent(&event); + } + + StickyKeysController* controller_; + StickyKeysOverlay* overlay_; +}; + +TEST_F(StickyKeysOverlayTest, OverlayVisibility) { + StickyKeysOverlay overlay; + EXPECT_FALSE(overlay.is_visible()); + overlay.Show(true); + EXPECT_TRUE(overlay.is_visible()); +} + +TEST_F(StickyKeysOverlayTest, ModifierKeyState) { + StickyKeysOverlay overlay; + overlay.SetModifierKeyState(ui::EF_SHIFT_DOWN, STICKY_KEY_STATE_DISABLED); + overlay.SetModifierKeyState(ui::EF_ALT_DOWN, STICKY_KEY_STATE_LOCKED); + overlay.SetModifierKeyState(ui::EF_CONTROL_DOWN, STICKY_KEY_STATE_ENABLED); + + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay.GetModifierKeyState(ui::EF_SHIFT_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, + overlay.GetModifierKeyState(ui::EF_ALT_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, + overlay.GetModifierKeyState(ui::EF_CONTROL_DOWN)); +} + +TEST_F(StickyKeysOverlayTest, OneModifierEnabled) { + EXPECT_FALSE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + + // Pressing modifier key should show overlay. + PressAndReleaseKey(ui::VKEY_CONTROL); + EXPECT_TRUE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + + // Pressing a normal key should hide overlay. + PressAndReleaseKey(ui::VKEY_T); + EXPECT_FALSE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); +} + +TEST_F(StickyKeysOverlayTest, TwoModifiersEnabled) { + EXPECT_FALSE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); + + // Pressing two modifiers should show overlay. + PressAndReleaseKey(ui::VKEY_SHIFT); + PressAndReleaseKey(ui::VKEY_CONTROL); + EXPECT_TRUE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, + overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + + // Pressing a normal key should hide overlay. + PressAndReleaseKey(ui::VKEY_N); + EXPECT_FALSE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); +} + +TEST_F(StickyKeysOverlayTest, LockedModifier) { + EXPECT_FALSE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); + + // Pressing a modifier key twice should lock modifier and show overlay. + PressAndReleaseKey(ui::VKEY_LMENU); + PressAndReleaseKey(ui::VKEY_LMENU); + EXPECT_TRUE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, + overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); + + // Pressing a normal key should not hide overlay. + PressAndReleaseKey(ui::VKEY_D); + EXPECT_TRUE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, + overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); +} + +TEST_F(StickyKeysOverlayTest, LockedAndNormalModifier) { + EXPECT_FALSE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); + + // Pressing a modifier key twice should lock modifier and show overlay. + PressAndReleaseKey(ui::VKEY_CONTROL); + PressAndReleaseKey(ui::VKEY_CONTROL); + EXPECT_TRUE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + + // Pressing another modifier key should still show overlay. + PressAndReleaseKey(ui::VKEY_SHIFT); + EXPECT_TRUE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, + overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); + + // Pressing a normal key should not hide overlay but disable normal modifier. + PressAndReleaseKey(ui::VKEY_D); + EXPECT_TRUE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); +} + +TEST_F(StickyKeysOverlayTest, ModifiersDisabled) { + EXPECT_FALSE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); + + // Enable modifiers. + PressAndReleaseKey(ui::VKEY_CONTROL); + PressAndReleaseKey(ui::VKEY_SHIFT); + PressAndReleaseKey(ui::VKEY_SHIFT); + PressAndReleaseKey(ui::VKEY_LMENU); + + EXPECT_TRUE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, + overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, + overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); + + // Disable modifiers and overlay should be hidden. + PressAndReleaseKey(ui::VKEY_CONTROL); + PressAndReleaseKey(ui::VKEY_CONTROL); + PressAndReleaseKey(ui::VKEY_SHIFT); + PressAndReleaseKey(ui::VKEY_LMENU); + PressAndReleaseKey(ui::VKEY_LMENU); + + EXPECT_FALSE(overlay_->is_visible()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, + overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); +} + +} // namespace ash diff --git a/ash/sticky_keys/sticky_keys_state.h b/ash/sticky_keys/sticky_keys_state.h new file mode 100644 index 0000000..97e99d8 --- /dev/null +++ b/ash/sticky_keys/sticky_keys_state.h @@ -0,0 +1,25 @@ +// Copyright 2014 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. + +#ifndef ASH_STICKY_KEYS_STICKY_KEYS_STATE_H_ +#define ASH_STICKY_KEYS_STICKY_KEYS_STATE_H_ + +namespace ash { + +// State of an individual modifier key. +enum StickyKeyState { + // The sticky key is disabled. Incoming non-modifier key events are not + // affected. + STICKY_KEY_STATE_DISABLED, + // The sticky key is enabled. Incoming non-modifier key down events are + // modified. After that, sticky key state becomes DISABLED. + STICKY_KEY_STATE_ENABLED, + // The sticky key is locked. All incoming non modifier key down events are + // modified. + STICKY_KEY_STATE_LOCKED, +}; + +} // namespace ash + +#endif // ASH_STICKY_KEYS_STICKY_KEYS_STATE_H_ diff --git a/ash/sticky_keys/sticky_keys_unittest.cc b/ash/sticky_keys/sticky_keys_unittest.cc index 9474247..c53035c 100644 --- a/ash/sticky_keys/sticky_keys_unittest.cc +++ b/ash/sticky_keys/sticky_keys_unittest.cc @@ -293,11 +293,11 @@ TEST_F(StickyKeysTest, BasicOneshotScenarioTest) { new MockStickyKeysHandlerDelegate(this); StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN, mock_delegate); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // By typing Shift key, internal state become ENABLED. SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); ev.reset(GenerateKey(true, ui::VKEY_A)); sticky_key.HandleKeyEvent(ev.get()); @@ -308,7 +308,7 @@ TEST_F(StickyKeysTest, BasicOneshotScenarioTest) { ev.reset(GenerateKey(false, ui::VKEY_A)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Making sure Shift up keyboard event is dispatched. ASSERT_EQ(2U, mock_delegate->GetEventCount()); EXPECT_EQ(ui::ET_KEY_PRESSED, mock_delegate->GetEvent(0)->type()); @@ -336,15 +336,15 @@ TEST_F(StickyKeysTest, BasicLockedScenarioTest) { new MockStickyKeysHandlerDelegate(this); StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN, mock_delegate); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // By typing shift key, internal state become ENABLED. SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); // By typing shift key again, internal state become LOCKED. SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); // All keyboard events including keyUp become shift modified. ev.reset(GenerateKey(true, ui::VKEY_A)); @@ -356,7 +356,7 @@ TEST_F(StickyKeysTest, BasicLockedScenarioTest) { EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN); // Locked state keeps after normal keyboard event. - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); ev.reset(GenerateKey(true, ui::VKEY_B)); sticky_key.HandleKeyEvent(ev.get()); @@ -366,11 +366,11 @@ TEST_F(StickyKeysTest, BasicLockedScenarioTest) { sticky_key.HandleKeyEvent(ev.get()); EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); // By typing shift key again, internal state become back to DISABLED. SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); } TEST_F(StickyKeysTest, NonTargetModifierTest) { @@ -379,40 +379,40 @@ TEST_F(StickyKeysTest, NonTargetModifierTest) { new MockStickyKeysHandlerDelegate(this); StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN, mock_delegate); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Non target modifier key does not affect internal state ev.reset(GenerateKey(true, ui::VKEY_MENU)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); ev.reset(GenerateKey(false, ui::VKEY_MENU)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); // Non target modifier key does not affect internal state ev.reset(GenerateKey(true, ui::VKEY_MENU)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); ev.reset(GenerateKey(false, ui::VKEY_MENU)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); // Non target modifier key does not affect internal state ev.reset(GenerateKey(true, ui::VKEY_MENU)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); ev.reset(GenerateKey(false, ui::VKEY_MENU)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); } TEST_F(StickyKeysTest, NormalShortcutTest) { @@ -422,7 +422,7 @@ TEST_F(StickyKeysTest, NormalShortcutTest) { new MockStickyKeysHandlerDelegate(this); StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Perform ctrl+n shortcut. ev.reset(GenerateKey(true, ui::VKEY_CONTROL)); @@ -431,12 +431,12 @@ TEST_F(StickyKeysTest, NormalShortcutTest) { sticky_key.HandleKeyEvent(ev.get()); ev.reset(GenerateKey(false, ui::VKEY_N)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Sticky keys should not be enabled afterwards. ev.reset(GenerateKey(false, ui::VKEY_CONTROL)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); } TEST_F(StickyKeysTest, NormalModifiedClickTest) { @@ -446,7 +446,7 @@ TEST_F(StickyKeysTest, NormalModifiedClickTest) { new MockStickyKeysHandlerDelegate(this); StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Perform ctrl+click. kev.reset(GenerateKey(true, ui::VKEY_CONTROL)); @@ -459,7 +459,7 @@ TEST_F(StickyKeysTest, NormalModifiedClickTest) { // Sticky keys should not be enabled afterwards. kev.reset(GenerateKey(false, ui::VKEY_CONTROL)); sticky_key.HandleKeyEvent(kev.get()); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); } TEST_F(StickyKeysTest, MouseMovedModifierTest) { @@ -469,7 +469,7 @@ TEST_F(StickyKeysTest, MouseMovedModifierTest) { new MockStickyKeysHandlerDelegate(this); StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Press ctrl and handle mouse move events. kev.reset(GenerateKey(true, ui::VKEY_CONTROL)); @@ -482,7 +482,7 @@ TEST_F(StickyKeysTest, MouseMovedModifierTest) { // Sticky keys should be enabled afterwards. kev.reset(GenerateKey(false, ui::VKEY_CONTROL)); sticky_key.HandleKeyEvent(kev.get()); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); } TEST_F(StickyKeysTest, NormalModifiedScrollTest) { @@ -494,7 +494,7 @@ TEST_F(StickyKeysTest, NormalModifiedScrollTest) { new MockStickyKeysHandlerDelegate(this); StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Perform ctrl+scroll. kev.reset(GenerateKey(true, ui::VKEY_CONTROL)); @@ -508,7 +508,7 @@ TEST_F(StickyKeysTest, NormalModifiedScrollTest) { // Sticky keys should not be enabled afterwards. kev.reset(GenerateKey(false, ui::VKEY_CONTROL)); sticky_key.HandleKeyEvent(kev.get()); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); } TEST_F(StickyKeysTest, MouseEventOneshot) { @@ -518,21 +518,21 @@ TEST_F(StickyKeysTest, MouseEventOneshot) { new MockStickyKeysHandlerDelegate(this); StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); // We should still be in the ENABLED state until we get the mouse // release event. ev.reset(GenerateMouseEvent(true)); sticky_key.HandleMouseEvent(ev.get()); EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); ev.reset(GenerateMouseEvent(false)); sticky_key.HandleMouseEvent(ev.get()); EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Making sure modifier key release event is dispatched in the right order. ASSERT_EQ(2u, mock_delegate->GetEventCount()); @@ -559,13 +559,13 @@ TEST_F(StickyKeysTest, MouseEventLocked) { new MockStickyKeysHandlerDelegate(this); StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Pressing modifier key twice should make us enter lock state. SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); // Mouse events should not disable locked mode. for (int i = 0; i < 3; ++i) { @@ -575,7 +575,7 @@ TEST_F(StickyKeysTest, MouseEventLocked) { ev.reset(GenerateMouseEvent(false)); sticky_key.HandleMouseEvent(ev.get()); EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); } // Test with mouse wheel. @@ -585,7 +585,7 @@ TEST_F(StickyKeysTest, MouseEventLocked) { ev.reset(GenerateMouseWheelEvent(-ui::MouseWheelEvent::kWheelDelta)); sticky_key.HandleMouseEvent(ev.get()); EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); } // Test mixed case with mouse events and key events. @@ -599,7 +599,7 @@ TEST_F(StickyKeysTest, MouseEventLocked) { sticky_key.HandleKeyEvent(kev.get()); EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); } TEST_F(StickyKeysTest, ScrollEventOneshot) { @@ -618,30 +618,30 @@ TEST_F(StickyKeysTest, ScrollEventOneshot) { mock_delegate->ClearEvents(); // Enable sticky keys. - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); // Test a scroll sequence. Sticky keys should only be disabled at the end // of the scroll sequence. Fling cancel event starts the scroll sequence. ev.reset(GenerateFlingScrollEvent(0, true)); sticky_key.HandleScrollEvent(ev.get()); EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); // Scrolls should all be modified but not disable sticky keys. for (int j = 0; j < 3; ++j) { ev.reset(GenerateScrollEvent(scroll_deltas[i])); sticky_key.HandleScrollEvent(ev.get()); EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); } // Fling start event ends scroll sequence. ev.reset(GenerateFlingScrollEvent(scroll_deltas[i], false)); sticky_key.HandleScrollEvent(ev.get()); EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); ASSERT_EQ(2U, mock_delegate->GetEventCount()); EXPECT_EQ(ui::ET_SCROLL_FLING_START, mock_delegate->GetEvent(0)->type()); @@ -670,12 +670,12 @@ TEST_F(StickyKeysTest, ScrollDirectionChanged) { const int direction_change_values[2] = {0, -10}; for (int i = 0; i < 2; ++i) { SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); // Fling cancel starts scroll sequence. ev.reset(GenerateFlingScrollEvent(0, true)); sticky_key.HandleScrollEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); // Test that changing directions in a scroll sequence will // return sticky keys to DISABLED state. @@ -683,13 +683,13 @@ TEST_F(StickyKeysTest, ScrollDirectionChanged) { ev.reset(GenerateScrollEvent(10)); sticky_key.HandleScrollEvent(ev.get()); EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); } ev.reset(GenerateScrollEvent(direction_change_values[i])); sticky_key.HandleScrollEvent(ev.get()); EXPECT_FALSE(ev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); } } @@ -707,7 +707,7 @@ TEST_F(StickyKeysTest, ScrollEventLocked) { // Lock sticky keys. SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); // Test scroll events are correctly modified in locked state. for (int i = 0; i < 5; ++i) { @@ -727,7 +727,7 @@ TEST_F(StickyKeysTest, ScrollEventLocked) { sticky_key.HandleScrollEvent(ev.get()); } - EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); } TEST_F(StickyKeysTest, EventTargetDestroyed) { @@ -739,14 +739,14 @@ TEST_F(StickyKeysTest, EventTargetDestroyed) { target()->Focus(); // Go into ENABLED state. - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); // CTRL+J is a special shortcut that will destroy the event target. ev.reset(GenerateKey(true, ui::VKEY_J)); sticky_key.HandleKeyEvent(ev.get()); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); EXPECT_FALSE(target()); } @@ -760,32 +760,32 @@ TEST_F(StickyKeysTest, SynthesizedEvents) { // Test non-native key events. scoped_ptr<ui::KeyEvent> kev; SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); kev.reset(GenerateSynthesizedKeyEvent(true, ui::VKEY_K)); sticky_key.HandleKeyEvent(kev.get()); EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); kev.reset(GenerateSynthesizedKeyEvent(false, ui::VKEY_K)); sticky_key.HandleKeyEvent(kev.get()); EXPECT_FALSE(kev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); // Test non-native mouse events. SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); scoped_ptr<ui::MouseEvent> mev; mev.reset(GenerateSynthesizedMouseEvent(true)); sticky_key.HandleMouseEvent(mev.get()); EXPECT_TRUE(mev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); mev.reset(GenerateSynthesizedMouseEvent(false)); sticky_key.HandleMouseEvent(mev.get()); EXPECT_TRUE(mev->flags() & ui::EF_CONTROL_DOWN); - EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); + EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); } TEST_F(StickyKeysTest, KeyEventDispatchImpl) { |