app_list_win.cc revision f2477e01787aa58f445919b809d89e252beef54f
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/views/app_list/win/app_list_win.h" 6 7#include "chrome/browser/profiles/profile.h" 8#include "chrome/browser/ui/app_list/app_list_positioner.h" 9#include "ui/app_list/views/app_list_view.h" 10#include "ui/gfx/screen.h" 11#include "ui/views/widget/widget.h" 12 13namespace { 14 15static const wchar_t kTrayClassName[] = L"Shell_TrayWnd"; 16 17// If the mouse cursor is less than this distance, in pixels, away from the 18// taskbar, it is considered to be in the taskbar for the purpose of anchoring. 19static const int kSnapDistance = 50; 20 21// The minimum distance, in pixels, to position the app list from the taskbar or 22// edge of screen. 23static const int kMinDistanceFromEdge = 3; 24 25// Utility methods for showing the app list. 26// Attempts to find the bounds of the Windows taskbar. Returns true on success. 27// |rect| is in screen coordinates. If the taskbar is in autohide mode and is 28// not visible, |rect| will be outside the current monitor's bounds, except for 29// one pixel of overlap where the edge of the taskbar is shown. 30bool GetTaskbarRect(gfx::Rect* rect) { 31 HWND taskbar_hwnd = FindWindow(kTrayClassName, NULL); 32 if (!taskbar_hwnd) 33 return false; 34 35 RECT win_rect; 36 if (!GetWindowRect(taskbar_hwnd, &win_rect)) 37 return false; 38 39 *rect = gfx::Rect(win_rect); 40 return true; 41} 42 43} // namespace 44 45AppListWin::AppListWin(app_list::AppListView* view, 46 const base::Closure& on_should_dismiss) 47 : view_(view), 48 activation_tracker_(view, on_should_dismiss), 49 window_icon_updated_(false) {} 50 51AppListWin::~AppListWin() {} 52 53gfx::Point AppListWin::FindAnchorPoint(const gfx::Size view_size, 54 const gfx::Display& display, 55 const gfx::Point& cursor, 56 const gfx::Rect& taskbar_rect) { 57 AppListPositioner positioner(display, view_size, kMinDistanceFromEdge); 58 59 // Subtract the taskbar area since the display's default work_area will not 60 // subtract it if the taskbar is set to auto-hide, and the app list should 61 // never overlap the taskbar. 62 positioner.WorkAreaSubtract(taskbar_rect); 63 64 // Find which edge of the screen the taskbar is attached to. 65 AppListPositioner::ScreenEdge edge = positioner.GetShelfEdge(taskbar_rect); 66 67 // Snap to the taskbar edge. If the cursor is greater than kSnapDistance away, 68 // anchor to the corner. Otherwise, anchor to the cursor position. 69 gfx::Point anchor; 70 if (edge == AppListPositioner::SCREEN_EDGE_UNKNOWN) { 71 // If we can't find the taskbar, snap to the bottom left. 72 return positioner.GetAnchorPointForScreenCorner( 73 AppListPositioner::SCREEN_CORNER_BOTTOM_LEFT); 74 } else if (positioner.GetCursorDistanceFromShelf(edge, cursor) > 75 kSnapDistance) { 76 return positioner.GetAnchorPointForShelfCorner(edge); 77 } else { 78 return positioner.GetAnchorPointForShelfCursor(edge, cursor); 79 } 80} 81 82void AppListWin::Show() { 83 view_->GetWidget()->Show(); 84 if (!window_icon_updated_) { 85 view_->GetWidget()->GetTopLevelWidget()->UpdateWindowIcon(); 86 window_icon_updated_ = true; 87 } 88 view_->GetWidget()->Activate(); 89} 90 91void AppListWin::Hide() { 92 view_->GetWidget()->Hide(); 93 activation_tracker_.OnViewHidden(); 94} 95 96void AppListWin::MoveNearCursor() { 97 gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(); 98 gfx::Screen* screen = 99 gfx::Screen::GetScreenFor(view_->GetWidget()->GetNativeView()); 100 gfx::Display display = screen->GetDisplayNearestPoint(cursor); 101 102 view_->SetBubbleArrow(views::BubbleBorder::FLOAT); 103 gfx::Rect taskbar_rect; 104 GetTaskbarRect(&taskbar_rect); 105 view_->SetAnchorPoint(FindAnchorPoint(view_->GetPreferredSize(), display, 106 cursor, taskbar_rect)); 107} 108 109bool AppListWin::IsVisible() { 110 return view_->GetWidget()->IsVisible(); 111} 112 113void AppListWin::Prerender() { 114 view_->Prerender(); 115} 116 117void AppListWin::ReactivateOnNextFocusLoss() { 118 activation_tracker_.ReactivateOnNextFocusLoss(); 119} 120 121gfx::NativeWindow AppListWin::GetWindow() { 122 return view_->GetWidget()->GetNativeWindow(); 123} 124 125void AppListWin::SetProfile(Profile* profile) { 126 view_->SetProfileByPath(profile->GetPath()); 127} 128