Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / app_list / win / app_list_win.cc
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
15 namespace {
16
17 static 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.
21 static const int kSnapDistance = 50;
22
23 // The minimum distance, in pixels, to position the app list from the taskbar or
24 // edge of screen.
25 static 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.
32 bool 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
47 AppListWin::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
53 AppListWin::~AppListWin() {}
54
55 gfx::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 (CommandLine::ForCurrentProcess()->HasSwitch(
68       app_list::switches::kEnableExperimentalAppList)) {
69     return positioner.GetAnchorPointForScreenCenter();
70   }
71
72   // Find which edge of the screen the taskbar is attached to.
73   AppListPositioner::ScreenEdge edge = positioner.GetShelfEdge(taskbar_rect);
74
75   // Snap to the taskbar edge. If the cursor is greater than kSnapDistance away,
76   // anchor to the corner. Otherwise, anchor to the cursor position.
77   gfx::Point anchor;
78   if (edge == AppListPositioner::SCREEN_EDGE_UNKNOWN) {
79     // If we can't find the taskbar, snap to the bottom left.
80     return positioner.GetAnchorPointForScreenCorner(
81         AppListPositioner::SCREEN_CORNER_BOTTOM_LEFT);
82   }
83
84   if (positioner.GetCursorDistanceFromShelf(edge, cursor) > kSnapDistance)
85     return positioner.GetAnchorPointForShelfCorner(edge);
86
87   return positioner.GetAnchorPointForShelfCursor(edge, cursor);
88 }
89
90 void AppListWin::Show() {
91   view_->GetWidget()->Show();
92   if (!window_icon_updated_) {
93     view_->GetWidget()->GetTopLevelWidget()->UpdateWindowIcon();
94     window_icon_updated_ = true;
95   }
96   view_->GetWidget()->Activate();
97 }
98
99 void AppListWin::Hide() {
100   view_->GetWidget()->Hide();
101   activation_tracker_.OnViewHidden();
102 }
103
104 void AppListWin::MoveNearCursor() {
105   gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
106   gfx::Screen* screen =
107       gfx::Screen::GetScreenFor(view_->GetWidget()->GetNativeView());
108   gfx::Display display = screen->GetDisplayNearestPoint(cursor);
109
110   view_->SetBubbleArrow(views::BubbleBorder::FLOAT);
111   gfx::Rect taskbar_rect;
112   GetTaskbarRect(&taskbar_rect);
113   view_->SetAnchorPoint(FindAnchorPoint(view_->GetPreferredSize(), display,
114                                         cursor, taskbar_rect));
115 }
116
117 bool AppListWin::IsVisible() {
118   return view_->GetWidget()->IsVisible();
119 }
120
121 void AppListWin::Prerender() {
122   view_->Prerender();
123 }
124
125 void AppListWin::ReactivateOnNextFocusLoss() {
126   activation_tracker_.ReactivateOnNextFocusLoss();
127 }
128
129 gfx::NativeWindow AppListWin::GetWindow() {
130   return view_->GetWidget()->GetNativeWindow();
131 }
132
133 void AppListWin::SetProfile(Profile* profile) {
134   view_->SetProfileByPath(profile->GetPath());
135 }