Index: chrome/browser/ui/views/app_list/win/activation_tracker_win.cc |
diff --git a/chrome/browser/ui/views/app_list/win/activation_tracker_win.cc b/chrome/browser/ui/views/app_list/win/activation_tracker_win.cc |
index b1d5a52c85fe8c41da296360c09110d4f2568242..4574703202e9fd65c0d0973a2a2587a5963e26b9 100644 |
--- a/chrome/browser/ui/views/app_list/win/activation_tracker_win.cc |
+++ b/chrome/browser/ui/views/app_list/win/activation_tracker_win.cc |
@@ -8,7 +8,9 @@ |
namespace { |
+static const wchar_t kJumpListClassName[] = L"DV2ControlHost"; |
static const wchar_t kTrayClassName[] = L"Shell_TrayWnd"; |
+static const int kFocusCheckIntervalMS = 250; |
} // namespace |
@@ -17,8 +19,8 @@ ActivationTrackerWin::ActivationTrackerWin( |
const base::Closure& on_should_dismiss) |
: view_(view), |
on_should_dismiss_(on_should_dismiss), |
- regain_next_lost_focus_(false), |
- preserving_focus_for_taskbar_menu_(false) { |
+ reactivate_on_next_focus_loss_(false), |
+ taskbar_has_focus_(false) { |
view_->AddObserver(this); |
} |
@@ -28,37 +30,55 @@ ActivationTrackerWin::~ActivationTrackerWin() { |
} |
void ActivationTrackerWin::OnActivationChanged( |
- views::Widget* widget, bool active) { |
- const int kFocusCheckIntervalMS = 250; |
+ views::Widget* /*widget*/, bool active) { |
if (active) { |
timer_.Stop(); |
return; |
} |
- preserving_focus_for_taskbar_menu_ = false; |
+ taskbar_has_focus_ = false; |
timer_.Start(FROM_HERE, |
base::TimeDelta::FromMilliseconds(kFocusCheckIntervalMS), this, |
- &ActivationTrackerWin::CheckTaskbarOrViewHasFocus); |
+ &ActivationTrackerWin::MaybeDismissAppList); |
} |
void ActivationTrackerWin::OnViewHidden() { |
timer_.Stop(); |
} |
-void ActivationTrackerWin::CheckTaskbarOrViewHasFocus() { |
+void ActivationTrackerWin::MaybeDismissAppList() { |
+ if (!ShouldDismissAppList()) |
+ return; |
+ |
+ if (reactivate_on_next_focus_loss_) { |
+ // Instead of dismissing the app launcher, re-activate it. |
+ reactivate_on_next_focus_loss_ = false; |
+ view_->GetWidget()->Activate(); |
+ return; |
+ } |
+ |
+ on_should_dismiss_.Run(); |
+} |
+ |
+bool ActivationTrackerWin::ShouldDismissAppList() { |
+ // The app launcher should be hidden when it loses focus, except for the cases |
+ // necessary to allow the launcher to be pinned or closed via the taskbar |
+ // context menu. This will return true to dismiss the app launcher unless one |
+ // of the following conditions are met: |
+ // - the app launcher is focused, or |
+ // - the taskbar's jump list is focused, or |
+ // - the taskbar is focused with the right mouse button pressed. |
+ |
// Remember if the taskbar had focus without the right mouse button being |
// down. |
- bool was_preserving_focus = preserving_focus_for_taskbar_menu_; |
- preserving_focus_for_taskbar_menu_ = false; |
+ bool taskbar_had_focus = taskbar_has_focus_; |
+ taskbar_has_focus_ = false; |
// First get the taskbar and jump lists windows (the jump list is the |
// context menu which the taskbar uses). |
- HWND jump_list_hwnd = FindWindow(L"DV2ControlHost", NULL); |
+ HWND jump_list_hwnd = FindWindow(kJumpListClassName, NULL); |
HWND taskbar_hwnd = FindWindow(kTrayClassName, NULL); |
- // This code is designed to hide the app launcher when it loses focus, |
- // except for the cases necessary to allow the launcher to be pinned or |
- // closed via the taskbar context menu. |
// First work out if the left or right button is currently down. |
int swapped = GetSystemMetrics(SM_SWAPBUTTON); |
int left_button = swapped ? VK_RBUTTON : VK_LBUTTON; |
@@ -70,52 +90,38 @@ void ActivationTrackerWin::CheckTaskbarOrViewHasFocus() { |
HWND focused_hwnd = GetForegroundWindow(); |
if (!focused_hwnd) { |
// Sometimes the focused window is NULL. This can happen when the focus is |
- // changing due to a mouse button press. If the button is still being |
- // pressed the launcher should not be hidden. |
- if (right_button_down || left_button_down) |
- return; |
- |
- // If the focused window is NULL, and the mouse button is not being |
- // pressed, then the launcher no longer has focus. |
- on_should_dismiss_.Run(); |
- return; |
+ // changing due to a mouse button press. Dismiss the launcher if and only if |
+ // no button is being pressed. |
+ return !right_button_down && !left_button_down; |
} |
while (focused_hwnd) { |
// If the focused window is the right click menu (called a jump list) or |
// the app list, don't hide the launcher. |
- if (focused_hwnd == jump_list_hwnd || |
- focused_hwnd == view_->GetHWND()) { |
- return; |
- } |
+ if (focused_hwnd == jump_list_hwnd || focused_hwnd == view_->GetHWND()) |
+ return false; |
if (focused_hwnd == taskbar_hwnd) { |
// If the focused window is the taskbar, and the right button is down, |
// don't hide the launcher as the user might be bringing up the menu. |
if (right_button_down) |
- return; |
+ return false; |
// There is a short period between the right mouse button being down |
// and the menu gaining focus, where the taskbar has focus and no button |
- // is down. If the taskbar is observed in this state once the launcher |
- // is not dismissed. If it happens twice in a row it is dismissed. |
- if (!was_preserving_focus) { |
- preserving_focus_for_taskbar_menu_ = true; |
- return; |
+ // is down. If the taskbar is observed in this state one time, the |
+ // launcher is not dismissed. If it happens for two consecutive timer |
+ // ticks, it is dismissed. |
+ if (!taskbar_had_focus) { |
+ taskbar_has_focus_ = true; |
+ return false; |
} |
- |
- break; |
+ return true; |
} |
focused_hwnd = GetParent(focused_hwnd); |
} |
- if (regain_next_lost_focus_) { |
- regain_next_lost_focus_ = false; |
- view_->GetWidget()->Activate(); |
- return; |
- } |
- |
- // If we get here, the focused window is not the taskbar, it's context menu, |
- // or the app list. |
- on_should_dismiss_.Run(); |
+ // If we get here, the focused window is not the taskbar, its context menu, or |
+ // the app list. |
+ return true; |
} |