Home | History | Annotate | Download | only in win
      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 }
     96