diff options
-rw-r--r-- | ash/accelerators/accelerator_controller.cc | 3 | ||||
-rw-r--r-- | ash/accelerators/accelerator_controller.h | 5 | ||||
-rw-r--r-- | ash/accelerators/accelerator_controller_unittest.cc | 70 | ||||
-rw-r--r-- | ash/accelerators/exit_warning_handler.cc | 88 | ||||
-rw-r--r-- | ash/accelerators/exit_warning_handler.h | 78 | ||||
-rw-r--r-- | ash/ash_strings.grd | 2 |
6 files changed, 70 insertions, 176 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index dfd4acb..b849802 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc @@ -369,8 +369,7 @@ void AcceleratorControllerContext::UpdateContext( // AcceleratorController, public: AcceleratorController::AcceleratorController() - : accelerator_manager_(new ui::AcceleratorManager), - exit_warning_handler_(&context_) { + : accelerator_manager_(new ui::AcceleratorManager) { Init(); } diff --git a/ash/accelerators/accelerator_controller.h b/ash/accelerators/accelerator_controller.h index 61076e6..cacba0e 100644 --- a/ash/accelerators/accelerator_controller.h +++ b/ash/accelerators/accelerator_controller.h @@ -41,9 +41,6 @@ class ASH_EXPORT AcceleratorControllerContext { // event type of the previous accelerator. void UpdateContext(const ui::Accelerator& accelerator); - const ui::Accelerator& current_accelerator() const { - return current_accelerator_; - } const ui::Accelerator& previous_accelerator() const { return previous_accelerator_; } @@ -152,7 +149,7 @@ class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget { // Contextual information, eg. if the current accelerator is repeated. AcceleratorControllerContext context_; - // Handles the exit accelerator which requires a long hold to exit and + // Handles the exit accelerator which requires a double press to exit and // shows a popup with an explanation. ExitWarningHandler exit_warning_handler_; diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index 216dbb5..a1a7f2c 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc @@ -323,16 +323,13 @@ class AcceleratorControllerTest : public test::AshTestBase { // Several functions to access ExitWarningHandler (as friend). static void StubForTest(ExitWarningHandler* ewh) { - ewh->stub_timers_for_test_ = true; + ewh->stub_timer_for_test_ = true; } static void Reset(ExitWarningHandler* ewh) { ewh->state_ = ExitWarningHandler::IDLE; } - static void SimulateTimer1Expired(ExitWarningHandler* ewh) { - ewh->Timer1Action(); - } - static void SimulateTimer2Expired(ExitWarningHandler* ewh) { - ewh->Timer2Action(); + static void SimulateTimerExpired(ExitWarningHandler* ewh) { + ewh->TimerAction(); } static bool is_ui_shown(ExitWarningHandler* ewh) { return !!ewh->widget_; @@ -360,7 +357,7 @@ bool AcceleratorControllerTest::ProcessWithContext( } #if !defined(OS_WIN) -// Quick double press of exit shortcut => exiting +// Double press of exit shortcut => exiting TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) { ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); ui::Accelerator release(press); @@ -372,55 +369,18 @@ TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) { EXPECT_FALSE(is_ui_shown(ewh)); EXPECT_TRUE(ProcessWithContext(press)); EXPECT_FALSE(ProcessWithContext(release)); + EXPECT_FALSE(is_idle(ewh)); EXPECT_TRUE(is_ui_shown(ewh)); - EXPECT_TRUE(ProcessWithContext(press)); // double press + EXPECT_TRUE(ProcessWithContext(press)); // second press before timer. EXPECT_FALSE(ProcessWithContext(release)); - SimulateTimer1Expired(ewh); // simulate double press timer expired - SimulateTimer2Expired(ewh); // simulate long hold timer expired - EXPECT_FALSE(is_ui_shown(ewh)); - EXPECT_TRUE(is_exiting(ewh)); - Reset(ewh); -} - -// Long hold of exit shortcut => exiting -TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestLongHold) { - ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); - ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); - ASSERT_TRUE(!!ewh); - StubForTest(ewh); - EXPECT_TRUE(is_idle(ewh)); - EXPECT_FALSE(is_ui_shown(ewh)); - EXPECT_TRUE(ProcessWithContext(press)); // hold - EXPECT_TRUE(is_ui_shown(ewh)); - SimulateTimer1Expired(ewh); // simulate double press timer expired - SimulateTimer2Expired(ewh); // simulate long hold timer expired - EXPECT_FALSE(is_ui_shown(ewh)); + SimulateTimerExpired(ewh); EXPECT_TRUE(is_exiting(ewh)); - Reset(ewh); -} - -// Release of exit shortcut before hold time limit => cancel -TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestEarlyRelease) { - ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); - ui::Accelerator release(press); - release.set_type(ui::ET_KEY_RELEASED); - ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest(); - ASSERT_TRUE(!!ewh); - StubForTest(ewh); - EXPECT_TRUE(is_idle(ewh)); - EXPECT_FALSE(is_ui_shown(ewh)); - EXPECT_TRUE(ProcessWithContext(press)); - EXPECT_TRUE(is_ui_shown(ewh)); - SimulateTimer1Expired(ewh); // simulate double press timer expired - EXPECT_FALSE(ProcessWithContext(release)); - SimulateTimer2Expired(ewh); // simulate long hold timer expired EXPECT_FALSE(is_ui_shown(ewh)); - EXPECT_TRUE(is_idle(ewh)); Reset(ewh); } -// Second Press after double press time limit => cancel -TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestQuickRelease) { +// Single press of exit shortcut before timer => idle +TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) { ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); ui::Accelerator release(press); release.set_type(ui::ET_KEY_RELEASED); @@ -431,12 +391,11 @@ TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestQuickRelease) { EXPECT_FALSE(is_ui_shown(ewh)); EXPECT_TRUE(ProcessWithContext(press)); EXPECT_FALSE(ProcessWithContext(release)); + EXPECT_FALSE(is_idle(ewh)); EXPECT_TRUE(is_ui_shown(ewh)); - SimulateTimer1Expired(ewh); // simulate double press timer expired - EXPECT_TRUE(ProcessWithContext(press)); - SimulateTimer2Expired(ewh); // simulate long hold timer expired - EXPECT_FALSE(is_ui_shown(ewh)); + SimulateTimerExpired(ewh); EXPECT_TRUE(is_idle(ewh)); + EXPECT_FALSE(is_ui_shown(ewh)); Reset(ewh); } #endif // !defined(OS_WIN) @@ -974,10 +933,9 @@ TEST_F(AcceleratorControllerTest, GlobalAccelerators) { ui::Accelerator(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN))); EXPECT_FALSE(is_idle(ewh)); EXPECT_TRUE(is_ui_shown(ewh)); - SimulateTimer1Expired(ewh); - SimulateTimer2Expired(ewh); + SimulateTimerExpired(ewh); + EXPECT_TRUE(is_idle(ewh)); EXPECT_FALSE(is_ui_shown(ewh)); - EXPECT_TRUE(is_exiting(ewh)); Reset(ewh); #endif diff --git a/ash/accelerators/exit_warning_handler.cc b/ash/accelerators/exit_warning_handler.cc index aa26683..07d87af 100644 --- a/ash/accelerators/exit_warning_handler.cc +++ b/ash/accelerators/exit_warning_handler.cc @@ -4,7 +4,6 @@ #include "ash/accelerators/exit_warning_handler.h" -#include "ash/accelerators/accelerator_controller.h" #include "ash/shell.h" #include "ash/shell_delegate.h" #include "ash/shell_window_ids.h" @@ -26,13 +25,33 @@ namespace ash { namespace { -const int64 kDoublePressTimeOutMilliseconds = 300; -const int64 kHoldTimeOutMilliseconds = 1000; +const int64 kTimeOutMilliseconds = 1000; const SkColor kForegroundColor = 0xFFFFFFFF; const SkColor kBackgroundColor = 0xE0808080; const int kHorizontalMarginAroundText = 100; const int kVerticalMarginAroundText = 100; +class ExitWarningLabel : public views::Label { + public: + ExitWarningLabel() {} + + virtual ~ExitWarningLabel() {} + + private: + virtual void PaintText(gfx::Canvas* canvas, + const string16& text, + const gfx::Rect& text_bounds, + int flags) OVERRIDE { + // Turn off subpixel rendering. + views::Label::PaintText(canvas, + text, + text_bounds, + flags | gfx::Canvas::NO_SUBPIXEL_RENDERING); + } + + DISALLOW_COPY_AND_ASSIGN(ExitWarningLabel); +}; + class ExitWarningWidgetDelegateView : public views::WidgetDelegateView { public: ExitWarningWidgetDelegateView() : text_width_(0), width_(0), height_(0) { @@ -42,7 +61,7 @@ class ExitWarningWidgetDelegateView : public views::WidgetDelegateView { text_width_ = font_.GetStringWidth(text_); width_ = text_width_ + kHorizontalMarginAroundText; height_ = font_.GetHeight() + kVerticalMarginAroundText; - views::Label* label = new views::Label; + views::Label* label = new ExitWarningLabel; label->SetText(text_); label->SetHorizontalAlignment(gfx::ALIGN_CENTER); label->SetFont(font_); @@ -74,11 +93,10 @@ class ExitWarningWidgetDelegateView : public views::WidgetDelegateView { } // namespace -ExitWarningHandler::ExitWarningHandler(AcceleratorControllerContext* context) - : context_(context), - state_(IDLE), +ExitWarningHandler::ExitWarningHandler() + : state_(IDLE), widget_(NULL), - stub_timers_for_test_(false) { + stub_timer_for_test_(false) { } ExitWarningHandler::~ExitWarningHandler() { @@ -87,25 +105,18 @@ ExitWarningHandler::~ExitWarningHandler() { } void ExitWarningHandler::HandleAccelerator() { - if (!context_) - return; switch (state_) { case IDLE: state_ = WAIT_FOR_DOUBLE_PRESS; - accelerator_ = context_->current_accelerator(); Show(); - StartTimers(); + StartTimer(); break; case WAIT_FOR_DOUBLE_PRESS: state_ = EXITING; - CancelTimers(); + CancelTimer(); Hide(); Shell::GetInstance()->delegate()->Exit(); break; - case WAIT_FOR_LONG_HOLD: - state_ = CANCELED; - break; - case CANCELED: case EXITING: break; default: @@ -114,46 +125,23 @@ void ExitWarningHandler::HandleAccelerator() { } } -void ExitWarningHandler::Timer1Action() { - if (state_ == WAIT_FOR_DOUBLE_PRESS) - state_ = WAIT_FOR_LONG_HOLD; -} - -void ExitWarningHandler::Timer2Action() { +void ExitWarningHandler::TimerAction() { Hide(); - if (state_ == CANCELED) { + if (state_ == WAIT_FOR_DOUBLE_PRESS) state_ = IDLE; - } else if (state_ == WAIT_FOR_LONG_HOLD) { - if (accelerator_ == context_->current_accelerator()) { - // We detect if the user has released any one of the keys that - // make up the shortcut by comparing "our" accelerator to the one - // from the current context and do not exit in that case. - state_ = EXITING; - Shell::GetInstance()->delegate()->Exit(); - } - else { - state_ = IDLE; - } - } } -void ExitWarningHandler::StartTimers() { - if (stub_timers_for_test_) +void ExitWarningHandler::StartTimer() { + if (stub_timer_for_test_) return; - timer1_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds( - kDoublePressTimeOutMilliseconds), - this, - &ExitWarningHandler::Timer1Action); - timer2_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kHoldTimeOutMilliseconds), - this, - &ExitWarningHandler::Timer2Action); + timer_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds(kTimeOutMilliseconds), + this, + &ExitWarningHandler::TimerAction); } -void ExitWarningHandler::CancelTimers() { - timer1_.Stop(); - timer2_.Stop(); +void ExitWarningHandler::CancelTimer() { + timer_.Stop(); } void ExitWarningHandler::Show() { diff --git a/ash/accelerators/exit_warning_handler.h b/ash/accelerators/exit_warning_handler.h index 3cb96f2..832a3ed 100644 --- a/ash/accelerators/exit_warning_handler.h +++ b/ash/accelerators/exit_warning_handler.h @@ -16,14 +16,9 @@ class Widget; namespace ash { // In order to avoid accidental exits when the user presses the exit -// shortcut by mistake, we require the user to hold the shortcut for -// a period of time. During that time we show a popup informing the -// user of this. We exit only if the user holds the shortcut longer -// than this time limit. -// An expert user may double press the shortcut for immediate exit. -// The double press must happen within the double press time limit. -// Unless the user performs a double press, we show the ui until the -// hold time limit has expired to avoid a short popup flash. +// shortcut by mistake, we require the user press it twice within a +// period of time. During that time we show a popup informing the +// user of this. // // Notes: // @@ -33,50 +28,24 @@ namespace ash { // // State Transition Diagrams: // -// T1 - double press time limit (short) -// T2 - hold to exit time limit (long) -// // IDLE // | Press // WAIT_FOR_DOUBLE_PRESS action: show ui & start timers -// | Press (DT < T1) -// EXITING action: hide ui, stop timers, exit +// | Press (before time limit ) +// EXITING action: hide ui, stop timer, exit // // IDLE // | Press // WAIT_FOR_DOUBLE_PRESS action: show ui & start timers -// | T1 timer expires -// WAIT_FOR_LONG_HOLD -// | T2 Timer exipres and -// | accelerator was held (matches current accelerator from context) -// EXITING action: hide ui, exit -// -// IDLE -// | Press -// WAIT_FOR_DOUBLE_PRESS action: show ui & start timers -// | T1 timer expires -// WAIT_FOR_LONG_HOLD -// | T2 Timer exipres and -// | accelerator was not held -// IDLE action: hide ui -// -// IDLE -// | Press -// WAIT_FOR_DOUBLE_PRESS action: show ui & start timers -// | T1 timer expires -// WAIT_FOR_LONG_HOLD -// | Press -// CANCELED -// | T2 timer expires +// | T timer expires // IDLE action: hide ui // -class AcceleratorControllerContext; class AcceleratorControllerTest; class ASH_EXPORT ExitWarningHandler { public: - explicit ExitWarningHandler(AcceleratorControllerContext* context); + ExitWarningHandler(); ~ExitWarningHandler(); @@ -89,41 +58,25 @@ class ASH_EXPORT ExitWarningHandler { enum State { IDLE, WAIT_FOR_DOUBLE_PRESS, - WAIT_FOR_LONG_HOLD, - CANCELED, EXITING }; - // Performs actions (see state diagram above) when the "double key - // press" time limit is exceeded. This is the shorter of the two - // time limits. - void Timer1Action(); - - // Performs actions (see state diagram above) when the hold time - // limit is exceeded. See state diagram above. This is the longer - // of the two time limits. - void Timer2Action(); + // Performs actions when the time limit is exceeded. + void TimerAction(); - void StartTimers(); - void CancelTimers(); + void StartTimer(); + void CancelTimer(); void Show(); void Hide(); - // AcceleratorControllerContext is used when a timer expires to test - // whether the user has held the accelerator key combination or has - // released (at least) one of the keys. - AcceleratorControllerContext* context_; - ui::Accelerator accelerator_; State state_; views::Widget* widget_; // owned by |this|. - base::OneShotTimer<ExitWarningHandler> timer1_; // short; double press - base::OneShotTimer<ExitWarningHandler> timer2_; // long; hold to exit + base::OneShotTimer<ExitWarningHandler> timer_; - // Flag to suppress starting the timers for testing. For test we - // call TimerAction1() and TimerAction2() directly to simulate the - // expiration of the timers. - bool stub_timers_for_test_; + // Flag to suppress starting the timer for testing. For test we call + // TimerAction() directly to simulate the expiration of the timer. + bool stub_timer_for_test_; DISALLOW_COPY_AND_ASSIGN(ExitWarningHandler); }; @@ -131,4 +84,3 @@ class ASH_EXPORT ExitWarningHandler { } // namespace ash #endif // ASH_ACCELERATORS_EXIT_WARNING_HANDLER_H_ - diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 5da716d..ca15ef7 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd @@ -510,7 +510,7 @@ Press Shift + Alt to switch. Failed to save screenshot </message> <message name="IDS_ASH_EXIT_WARNING_POPUP_TEXT" desc="The text of the popup when the user preses the exit shortcut."> - Hold Ctrl+Shift+Q to quit. + Press Ctrl+Shift+Q twice to quit. </message> <!-- ChromeOS-specific strings --> |