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