Upstream version 7.36.149.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 "chrome/browser/ui/app_list/app_list_positioner.h"
8 #include "ui/app_list/app_list_switches.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
13 namespace {
14
15 static 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.
19 static const int kSnapDistance = 50;
20
21 // The minimum distance, in pixels, to position the app list from the taskbar or
22 // edge of screen.
23 static 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.
30 bool 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
45 // static
46 gfx::Point AppListWin::FindAnchorPoint(const gfx::Size& view_size,
47                                        const gfx::Display& display,
48                                        const gfx::Point& cursor,
49                                        const gfx::Rect& taskbar_rect,
50                                        bool center_window) {
51   AppListPositioner positioner(display, view_size, kMinDistanceFromEdge);
52
53   // Subtract the taskbar area since the display's default work_area will not
54   // subtract it if the taskbar is set to auto-hide, and the app list should
55   // never overlap the taskbar.
56   positioner.WorkAreaSubtract(taskbar_rect);
57
58   // Special case for app list in the center of the screen.
59   if (center_window)
60     return positioner.GetAnchorPointForScreenCenter();
61
62   // Find which edge of the screen the taskbar is attached to.
63   AppListPositioner::ScreenEdge edge = positioner.GetShelfEdge(taskbar_rect);
64
65   // Snap to the taskbar edge. If the cursor is greater than kSnapDistance away,
66   // anchor to the corner. Otherwise, anchor to the cursor position.
67   gfx::Point anchor;
68   if (edge == AppListPositioner::SCREEN_EDGE_UNKNOWN) {
69     // If we can't find the taskbar, snap to the bottom left.
70     return positioner.GetAnchorPointForScreenCorner(
71         AppListPositioner::SCREEN_CORNER_BOTTOM_LEFT);
72   }
73
74   if (positioner.GetCursorDistanceFromShelf(edge, cursor) > kSnapDistance)
75     return positioner.GetAnchorPointForShelfCorner(edge);
76
77   return positioner.GetAnchorPointForShelfCursor(edge, cursor);
78 }
79
80 // static
81 void AppListWin::MoveNearCursor(app_list::AppListView* view) {
82   gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
83   gfx::Screen* screen =
84       gfx::Screen::GetScreenFor(view->GetWidget()->GetNativeView());
85   gfx::Display display = screen->GetDisplayNearestPoint(cursor);
86
87   view->SetBubbleArrow(views::BubbleBorder::FLOAT);
88   gfx::Rect taskbar_rect;
89   GetTaskbarRect(&taskbar_rect);
90   view->SetAnchorPoint(FindAnchorPoint(view->GetPreferredSize(),
91                                        display,
92                                        cursor,
93                                        taskbar_rect,
94                                        view->ShouldCenterWindow()));
95 }