15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/launcher/launcher.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/focus_cycler.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/launcher/launcher_delegate.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/launcher/launcher_model.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/launcher/launcher_navigator.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/launcher/launcher_view.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/root_window_controller.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/screen_ash.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_widget.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_delegate.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_window_ids.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/property_util.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_properties.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/activation_client.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window_observer.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/skbitmap_operations.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/accessible_pane_view.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget_delegate.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char Launcher::kNativeViewName[] = "LauncherView"; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Launcher::Launcher(LauncherModel* launcher_model, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LauncherDelegate* launcher_delegate, 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShelfWidget* shelf_widget) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : launcher_view_(NULL), 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) alignment_(shelf_widget->GetAlignment()), 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_(launcher_delegate), 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shelf_widget_(shelf_widget) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_view_ = new internal::LauncherView( 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_model, delegate_, shelf_widget_->shelf_layout_manager()); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_view_->Init(); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shelf_widget_->GetContentsView()->AddChildView(launcher_view_); 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shelf_widget_->GetNativeView()->SetName(kNativeViewName); 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate_->OnLauncherCreated(this); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Launcher::~Launcher() { 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate_->OnLauncherDestroyed(this); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Launcher* Launcher::ForPrimaryDisplay() { 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ShelfWidget* shelf_widget = internal::RootWindowController::ForLauncher( 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Shell::GetPrimaryRootWindow())->shelf(); 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return shelf_widget ? shelf_widget->launcher() : NULL; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Launcher* Launcher::ForWindow(aura::Window* window) { 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ShelfWidget* shelf_widget = 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) internal::RootWindowController::ForLauncher(window)->shelf(); 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return shelf_widget ? shelf_widget->launcher() : NULL; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Launcher::SetAlignment(ShelfAlignment alignment) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alignment_ = alignment; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_view_->OnShelfAlignmentChanged(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ShelfLayoutManager will resize the launcher. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect Launcher::GetScreenBoundsOfItemIconForWindow(aura::Window* window) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LauncherID id = delegate_->GetIDByWindow(window); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds(launcher_view_->GetIdealBoundsOfItemIcon(id)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point screen_origin; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View::ConvertPointToScreen(launcher_view_, &screen_origin); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Rect(screen_origin.x() + bounds.x(), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) screen_origin.y() + bounds.y(), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds.width(), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds.height()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Launcher::UpdateIconPositionForWindow(aura::Window* window) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_view_->UpdatePanelIconPosition( 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_->GetIDByWindow(window), 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ash::ScreenAsh::ConvertRectFromScreen( 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shelf_widget()->GetNativeView(), 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window->GetBoundsInScreen()).CenterPoint()); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Launcher::ActivateLauncherItem(int index) { 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We pass in a keyboard event which will then trigger a switch to the 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // next item if the current one is already active. 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::KeyEvent event(ui::ET_KEY_RELEASED, 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::VKEY_UNKNOWN, // The actual key gets ignored. 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::EF_NONE, 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ash::LauncherItems& items = 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_view_->model()->items(); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate_->ItemSelected(items[index], event); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Launcher::CycleWindowLinear(CycleDirection direction) { 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int item_index = GetNextActivatedItemIndex( 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *(launcher_view_->model()), direction); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item_index >= 0) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ActivateLauncherItem(item_index); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Launcher::AddIconObserver(LauncherIconObserver* observer) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_view_->AddIconObserver(observer); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Launcher::RemoveIconObserver(LauncherIconObserver* observer) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_view_->RemoveIconObserver(observer); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Launcher::IsShowingMenu() const { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return launcher_view_->IsShowingMenu(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Launcher::IsShowingOverflowBubble() const { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return launcher_view_->IsShowingOverflowBubble(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Launcher::SetVisible(bool visible) const { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_view_->SetVisible(visible); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Launcher::IsVisible() const { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return launcher_view_->visible(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1454311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdochvoid Launcher::SchedulePaint() { 1464311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch launcher_view_->SchedulePaintForAllButtons(); 1474311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch} 1484311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* Launcher::GetAppListButtonView() const { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return launcher_view_->GetAppListButtonView(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid Launcher::LaunchAppIndexAt(int item_index) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LauncherModel* launcher_model = launcher_view_->model(); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LauncherItems& items = launcher_model->items(); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int item_count = launcher_model->item_count(); 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int indexes_left = item_index >= 0 ? item_index : item_count; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int found_index = -1; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Iterating until we have hit the index we are interested in which 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is true once indexes_left becomes negative. 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < item_count && indexes_left >= 0; i++) { 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (items[i].type != TYPE_APP_LIST) { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found_index = i; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) indexes_left--; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There are two ways how found_index can be valid: a.) the nth item was 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // found (which is true when indexes_left is -1) or b.) the last item was 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // requested (which is true when index was passed in as a negative number). 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (found_index >= 0 && (indexes_left == -1 || item_index < 0) && 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (delegate_->IsPerAppLauncher() || 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (items[found_index].status == ash::STATUS_RUNNING || 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) items[found_index].status == ash::STATUS_CLOSED))) { 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Then set this one as active (or advance to the next item of its kind). 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ActivateLauncherItem(found_index); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)internal::LauncherView* Launcher::GetLauncherViewForTest() { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return launcher_view_; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Launcher::SetLauncherViewBounds(gfx::Rect bounds) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_view_->SetBoundsRect(bounds); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect Launcher::GetLauncherViewBounds() const { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return launcher_view_->bounds(); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 193bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochapp_list::ApplicationDragAndDropHost* Launcher::GetDragAndDropHostForAppList() { 194bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return launcher_view_; 195bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 196bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 198