app_list_linux.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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/linux/app_list_linux.h" 6 7#include "base/command_line.h" 8#include "base/location.h" 9#include "base/single_thread_task_runner.h" 10#include "base/thread_task_runner_handle.h" 11#include "chrome/browser/profiles/profile.h" 12#include "chrome/browser/ui/app_list/app_list_positioner.h" 13#include "ui/app_list/app_list_switches.h" 14#include "ui/app_list/views/app_list_view.h" 15#include "ui/gfx/screen.h" 16#include "ui/views/widget/widget.h" 17 18AppListLinux::AppListLinux(app_list::AppListView* view, 19 const base::Closure& on_should_dismiss) 20 : view_(view), 21 window_icon_updated_(false), 22 on_should_dismiss_(on_should_dismiss) { 23 view_->AddObserver(this); 24} 25 26AppListLinux::~AppListLinux() { 27 view_->RemoveObserver(this); 28} 29 30// static 31gfx::Point AppListLinux::FindAnchorPoint(const gfx::Size& view_size, 32 const gfx::Display& display, 33 const gfx::Point& cursor, 34 AppListPositioner::ScreenEdge edge) { 35 AppListPositioner positioner(display, view_size, 0); 36 37 // The experimental app list is placed in the center of the screen. 38 if (app_list::switches::IsExperimentalAppListPositionEnabled()) 39 return positioner.GetAnchorPointForScreenCenter(); 40 41 gfx::Point anchor; 42 // Snap to the shelf edge. If the cursor is greater than the window 43 // width/height away, anchor to the corner. Otherwise, anchor to the cursor 44 // position. 45 if (edge == AppListPositioner::SCREEN_EDGE_UNKNOWN) { 46 // If we can't find the shelf, snap to the top left. 47 return positioner.GetAnchorPointForScreenCorner( 48 AppListPositioner::SCREEN_CORNER_TOP_LEFT); 49 } 50 51 int snap_distance = edge == AppListPositioner::SCREEN_EDGE_BOTTOM || 52 edge == AppListPositioner::SCREEN_EDGE_TOP 53 ? view_size.height() 54 : view_size.width(); 55 if (positioner.GetCursorDistanceFromShelf(edge, cursor) > snap_distance) 56 return positioner.GetAnchorPointForShelfCorner(edge); 57 58 return positioner.GetAnchorPointForShelfCursor(edge, cursor); 59} 60 61void AppListLinux::Show() { 62 view_->GetWidget()->Show(); 63 if (!window_icon_updated_) { 64 view_->GetWidget()->GetTopLevelWidget()->UpdateWindowIcon(); 65 window_icon_updated_ = true; 66 } 67 view_->GetWidget()->Activate(); 68} 69 70void AppListLinux::Hide() { 71 view_->GetWidget()->Hide(); 72} 73 74void AppListLinux::MoveNearCursor() { 75 gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(); 76 gfx::Screen* screen = 77 gfx::Screen::GetScreenFor(view_->GetWidget()->GetNativeView()); 78 gfx::Display display = screen->GetDisplayNearestPoint(cursor); 79 80 view_->SetBubbleArrow(views::BubbleBorder::FLOAT); 81 // Find which edge of the screen the shelf is attached to. For now, just 82 // assume Ubuntu Unity (fixed to left edge). 83 // TODO(mgiuca): Support other window manager configurations, and multiple 84 // monitors (where the current display may not have an edge). 85 AppListPositioner::ScreenEdge edge = AppListPositioner::SCREEN_EDGE_LEFT; 86 view_->SetAnchorPoint(FindAnchorPoint(view_->GetPreferredSize(), display, 87 cursor, edge)); 88} 89 90bool AppListLinux::IsVisible() { 91 return view_->GetWidget()->IsVisible(); 92} 93 94void AppListLinux::Prerender() { 95 view_->Prerender(); 96} 97 98void AppListLinux::ReactivateOnNextFocusLoss() { 99 // This is only used on Windows 8, so we ignore it on Linux. 100} 101 102gfx::NativeWindow AppListLinux::GetWindow() { 103 return view_->GetWidget()->GetNativeWindow(); 104} 105 106void AppListLinux::SetProfile(Profile* profile) { 107 view_->SetProfileByPath(profile->GetPath()); 108} 109 110void AppListLinux::OnActivationChanged( 111 views::Widget* /*widget*/, bool active) { 112 if (active) 113 return; 114 115 // Call |on_should_dismiss_| asynchronously. This must be done asynchronously 116 // or our caller will crash, as it expects the app list to remain alive. 117 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, on_should_dismiss_); 118} 119