172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/wm_overview_controller.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/linked_ptr.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/wm_ipc.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/chromeos/wm_overview_favicon.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/wm_overview_snapshot.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/wm_overview_title.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/thumbnail_generator.h" 173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/tabs/tab_strip_model.h" 184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h" 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h" 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_widget_host.h" 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_widget_host_view.h" 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_view.h" 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_service.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/root_view.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget_gtk.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing std::vector; 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_CHROMEOS) 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#error This file is only meant to be compiled for ChromeOS 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chromeos { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Use this timer to delay consecutive snapshots during the updating process. 40201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// We will start the timer upon successfully retrieving a new snapshot, or if 41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// for some reason the current snapshot is still pending (while Chrome is 42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// still loading the page.) 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kDelayTimeMs = 10; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is the size of the web page when we lay it out for a snapshot. 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kSnapshotWebPageWidth = 1024; 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kSnapshotWebPageHeight = 1280; 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const double kSnapshotWebPageRatio = 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<double>(kSnapshotWebPageWidth) / kSnapshotWebPageHeight; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is the maximum percentage of the original browser client area 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that a snapshot can take up. 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const double kSnapshotMaxSizeRatio = 0.77; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is the height of the title in pixels. 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kTitleHeight = 32; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The number of additional padding pixels to remove from the title width. 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const int kFaviconPadding = 5; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BrowserListener : public TabStripModelObserver { 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserListener(Browser* browser, WmOverviewController* parent); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~BrowserListener(); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Begin TabStripModelObserver methods 67201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void TabInsertedAt(TabContentsWrapper* contents, 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index, 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool foreground); 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void TabClosingAt(TabStripModel* tab_strip_model, 71201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsWrapper* contents, 72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int index) {} 73201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void TabDetachedAt(TabContentsWrapper* contents, int index); 74201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void TabMoved(TabContentsWrapper* contents, 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int from_index, 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int to_index); 77201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void TabChangedAt(TabContentsWrapper* contents, int index, 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabStripModelObserver::TabChangeType change_type); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void TabStripEmpty(); 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen virtual void TabDeselected(TabContentsWrapper* contents) {} 81201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch virtual void TabSelectedAt(TabContentsWrapper* old_contents, 82201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsWrapper* new_contents, 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index, 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool user_gesture); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // End TabStripModelObserver methods 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the number of tabs in this child. 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int count() const { return browser_->tabstrip_model()->count(); } 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the browser that this child gets its data from. 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser() const { return browser_; } 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Removes all the snapshots and re-populates them from the browser. 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RecreateSnapshots(); 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Mark the given snapshot as dirty, and start the delay timer. 97201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void MarkSnapshotAsDirty(int index); 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Updates the selected index and tab count on the toplevel window. 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void UpdateSelectedIndex(int index); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Update the first "dirty" snapshot, which is ordered after (excluding) 103201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // the snapshot whose index is given by |start_from|; When |start_from| is 104201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // -1, search start at the begining of the list. 105201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Return the index of the snapshot which is actually updated; -1 if there 106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // are no more tab contents (after |start_from|) to configure on this 107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // listener. 108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int ConfigureNextUnconfiguredSnapshot(int start_from); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Saves the currently selected tab. 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void SaveCurrentTab() { original_selected_tab_ = browser_->active_index(); } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reverts the selected browser tab to the tab that was selected 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // when This BrowserListener was created, or the last time 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SaveCurrentTab was called. 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RestoreOriginalSelectedTab(); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Selects the tab at the given index. 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void SelectTab(int index, uint32 timestamp); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shows any snapshots that are not visible. 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ShowSnapshots(); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Callback for |AskForSnapshot|, start delay timer for next round. 125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void OnSnapshotReady(const SkBitmap& sk_bitmap); 126201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the tab contents from the tab model for this child at index. 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* GetTabContentsAt(int index) const { 129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return browser_->tabstrip_model()->GetTabContentsAt(index)->tab_contents(); 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Calculate the size of a cell based on the browser window's size. 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size CalculateCellSize(); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Configures a cell from the tab contents. 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ConfigureCell(WmOverviewSnapshot* cell, TabContents* contents); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Configures a cell from the model. 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ConfigureCell(WmOverviewSnapshot* cell, int index) { 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConfigureCell(cell, GetTabContentsAt(index)); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Inserts a new snapshot, initialized from the model, at the given 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // index, and renumbers any following snapshots. 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void InsertSnapshot(int index); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Removes the snapshot at index. 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ClearSnapshot(int index); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Renumbers the index atom in the snapshots starting at the given 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // index. 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RenumberSnapshots(int start_index); 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser_; // Not owned 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WmOverviewController* controller_; // Not owned 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Which renderer host we are working on. 159201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RenderWidgetHost* current_renderer_host_; // Not owned 160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Widgets containing snapshot images for this browser. Note that 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // these are all subclasses of WidgetGtk, and they are all added to 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // parents, so they will be deleted by the parents when they are 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // closed. 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct SnapshotNode { 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WmOverviewSnapshot* snapshot; // Not owned 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WmOverviewTitle* title; // Not owned 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WmOverviewFavicon* favicon; // Not owned 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::vector<SnapshotNode> SnapshotVector; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SnapshotVector snapshots_; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Non-zero if we are currently setting the tab from within SelectTab. 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is used to make sure we use the right timestamp when sending 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // property changes that originated from the window manager. 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 select_tab_timestamp_; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The tab selected the last time SaveCurrentTab is called. 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int original_selected_tab_; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(BrowserListener); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserListener::BrowserListener(Browser* browser, 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WmOverviewController* controller) 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : browser_(browser), 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch controller_(controller), 188201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch current_renderer_host_(NULL), 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch select_tab_timestamp_(0), 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch original_selected_tab_(-1) { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(browser_); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(controller_); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->tabstrip_model()->AddObserver(this); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This browser didn't already exist, and so we haven't been 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // watching it for tab insertions, so we need to create the 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // snapshots associated with it. 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RecreateSnapshots(); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserListener::~BrowserListener() { 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->tabstrip_model()->RemoveObserver(this); 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserListener::TabInsertedAt(TabContentsWrapper* contents, 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index, 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool foreground) { 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InsertSnapshot(index); 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenumberSnapshots(index); 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateSelectedIndex(browser_->active_index()); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 214201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserListener::TabDetachedAt(TabContentsWrapper* contents, int index) { 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearSnapshot(index); 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateSelectedIndex(browser_->active_index()); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenumberSnapshots(index); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 220201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserListener::TabMoved(TabContentsWrapper* contents, 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int from_index, 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int to_index) { 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Need to reorder tab in the snapshots list, and reset the window 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // type atom on the affected snapshots (the one moved, and all the 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ones after it), so that their indices are correct. 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SnapshotNode node = snapshots_[from_index]; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_.erase(snapshots_.begin() + from_index); 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_.insert(snapshots_.begin() + to_index, node); 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenumberSnapshots(std::min(to_index, from_index)); 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateSelectedIndex(browser_->active_index()); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::TabChangedAt( 235201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsWrapper* contents, 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index, 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabStripModelObserver::TabChangeType change_type) { 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (change_type != TabStripModelObserver::LOADING_ONLY) { 239201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch snapshots_[index].title->SetTitle(contents->tab_contents()->GetTitle()); 240201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch snapshots_[index].title->SetUrl(contents->tab_contents()->GetURL()); 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen snapshots_[index].favicon->SetFavicon( 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen contents->tab_contents()->GetFavicon()); 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (change_type != TabStripModelObserver::TITLE_NOT_LOADING) 244201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MarkSnapshotAsDirty(index); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::TabStripEmpty() { 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_.clear(); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserListener::TabSelectedAt(TabContentsWrapper* old_contents, 253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsWrapper* new_contents, 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index, 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool user_gesture) { 256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (old_contents == new_contents) 257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateSelectedIndex(index); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 262201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserListener::MarkSnapshotAsDirty(int index) { 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_[index].snapshot->reload_snapshot(); 264201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch controller_->UpdateSnapshots(); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::RecreateSnapshots() { 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_.clear(); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < count(); ++i) 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InsertSnapshot(i); 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenumberSnapshots(0); 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::UpdateSelectedIndex(int index) { 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WmIpcWindowType type = WmIpc::instance()->GetWindowType( 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_WIDGET(browser_->window()->GetNativeHandle()), NULL); 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we only operate on toplevel windows. 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (type == WM_IPC_WINDOW_CHROME_TOPLEVEL) { 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<int> params; 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch params.push_back(browser_->tab_count()); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch params.push_back(index); 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch params.push_back(select_tab_timestamp_ ? select_tab_timestamp_ : 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_get_current_event_time()); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WmIpc::instance()->SetWindowType( 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_WIDGET(browser_->window()->GetNativeHandle()), 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WM_IPC_WINDOW_CHROME_TOPLEVEL, 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ¶ms); 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 293201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochint BrowserListener::ConfigureNextUnconfiguredSnapshot(int start_from) { 294201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (SnapshotVector::size_type i = start_from + 1; 295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch i < snapshots_.size(); ++i) { 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WmOverviewSnapshot* cell = snapshots_[i].snapshot; 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!cell->configured_snapshot()) { 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConfigureCell(cell, i); 299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return i; 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 302201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return -1; 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::RestoreOriginalSelectedTab() { 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (original_selected_tab_ >= 0) { 307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen browser_->ActivateTabAt(original_selected_tab_, false); 308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateSelectedIndex(browser_->active_index()); 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::ShowSnapshots() { 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (SnapshotVector::size_type i = 0; i < snapshots_.size(); ++i) { 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SnapshotNode& node = snapshots_[i]; 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!node.snapshot->IsVisible()) 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.snapshot->Show(); 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!snapshots_[i].title->IsVisible()) 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.title->Show(); 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!snapshots_[i].favicon->IsVisible()) 320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen node.favicon->Show(); 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::SelectTab(int index, uint32 timestamp) { 325513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Ignore requests to switch to non-existent tabs (the window manager gets 326513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // notified asynchronously about the number of tabs in each window, so there's 327513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // no guarantee that the messages that it sends us will make sense). 328513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (index < 0 || index >= browser_->tab_count()) 329513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 330513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 old_value = select_tab_timestamp_; 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch select_tab_timestamp_ = timestamp; 333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen browser_->ActivateTabAt(index, true); 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch select_tab_timestamp_ = old_value; 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Size BrowserListener::CalculateCellSize() { 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make the page size and the cell size a fixed size for overview 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // mode. The cell size is calculated based on the desired maximum 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // size on the screen, so it's related to the width and height of 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the browser client area. In this way, when this snapshot gets 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to the window manager, it will already have the correct size, 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and will be scaled by 1.0, meaning that it won't be resampled 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and will not be blurry. 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect bounds = static_cast<BrowserView*>(browser_->window())-> 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetClientAreaBounds(); 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Size max_size = gfx::Size( 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bounds.width() * kSnapshotMaxSizeRatio, 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bounds.height() * kSnapshotMaxSizeRatio); 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const double max_size_ratio = static_cast<double>(max_size.width()) / 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch max_size.height(); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size cell_size; 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (kSnapshotWebPageRatio > max_size_ratio) { 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const double scale_factor = 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<double>(max_size.width())/ kSnapshotWebPageWidth; 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cell_size = gfx::Size(max_size.width(), 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSnapshotWebPageHeight * scale_factor + 0.5); 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const double scale_factor = 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<double>(max_size.height())/ kSnapshotWebPageHeight; 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cell_size = gfx::Size(kSnapshotWebPageWidth * scale_factor + 0.5, 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch max_size.height()); 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return cell_size; 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 367201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserListener::OnSnapshotReady(const SkBitmap& sk_bitmap) { 368201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (int i = 0; i < count(); i++) { 369201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch RenderWidgetHostView* view = 370201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch GetTabContentsAt(i)->GetRenderWidgetHostView(); 371201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (view && view->GetRenderWidgetHost() == current_renderer_host_) { 372201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch snapshots_[i].snapshot->SetImage(sk_bitmap); 373201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch current_renderer_host_ = NULL; 374201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 375201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Start timer for next round of snapshot updating. 376201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch controller_->StartDelayTimer(); 377201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return; 378201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 379201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 380201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(current_renderer_host_ == NULL); 381201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 382201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::ConfigureCell(WmOverviewSnapshot* cell, 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* contents) { 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (contents) { 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ThumbnailGenerator* generator = 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_browser_process->GetThumbnailGenerator(); 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO: Make sure that if the cell gets deleted before the 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // callback is called that it sticks around until it gets 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // called. (some kind of "in flight" list that uses linked_ptr 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to make sure they don't actually get deleted?) Also, make 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // sure that any request for a thumbnail eventually returns 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (even if it has bogus data), so we don't leak orphaned cells, 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // which could happen if a tab is closed while it is being 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // rendered. 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ThumbnailGenerator::ThumbnailReadyCallback* callback = 397201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NewCallback(this, &BrowserListener::OnSnapshotReady); 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 399201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch current_renderer_host_ = contents->render_view_host(); 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch generator->AskForSnapshot(contents->render_view_host(), 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch callback, 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size(kSnapshotWebPageWidth, 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSnapshotWebPageHeight), 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CalculateCellSize()); 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This happens because the contents haven't been loaded yet. 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we set the snapshot image to something, otherwise 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // configured_snapshot remains false and 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ConfigureNextUnconfiguredSnapshot would get stuck. 412201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch current_renderer_host_ = NULL; 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cell->SetImage(SkBitmap()); 414201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch cell->reload_snapshot(); 415201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch controller_->StartDelayTimer(); 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::InsertSnapshot(int index) { 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SnapshotNode node; 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.snapshot = new WmOverviewSnapshot; 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size cell_size = CalculateCellSize(); 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.snapshot->Init(cell_size, browser_, index); 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen node.favicon = new WmOverviewFavicon; 426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen node.favicon->Init(node.snapshot); 427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen node.favicon->SetFavicon(browser_->GetTabContentsAt(index)->GetFavicon()); 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.title = new WmOverviewTitle; 430dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen node.title->Init(gfx::Size(std::max(0, cell_size.width() - 431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WmOverviewFavicon::kIconSize - 432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kFaviconPadding), 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kTitleHeight), node.snapshot); 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.title->SetTitle(browser_->GetTabContentsAt(index)->GetTitle()); 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_.insert(snapshots_.begin() + index, node); 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.snapshot->reload_snapshot(); 438201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch controller_->UpdateSnapshots(); 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Removes the snapshot at index. 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::ClearSnapshot(int index) { 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_[index].snapshot->CloseNow(); 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_[index].title->CloseNow(); 445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen snapshots_[index].favicon->CloseNow(); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_.erase(snapshots_.begin() + index); 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserListener::RenumberSnapshots(int start_index) { 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (SnapshotVector::size_type i = start_index; i < snapshots_.size(); ++i) { 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (snapshots_[i].snapshot->index() != static_cast<int>(i)) 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch snapshots_[i].snapshot->UpdateIndex(browser_, i); 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/////////////////////////////////// 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WmOverviewController methods 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 46021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenWmOverviewController* WmOverviewController::GetInstance() { 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static WmOverviewController* instance = NULL; 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!instance) { 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch instance = Singleton<WmOverviewController>::get(); 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return instance; 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWmOverviewController::WmOverviewController() 469201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch : layout_mode_(ACTIVE_MODE), 470201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch updating_snapshots_(false), 471201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch browser_listener_index_(0), 472201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab_contents_index_(-1) { 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddAllBrowsers(); 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (registrar_.IsEmpty()) { 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we get notifications for when the tab contents are 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // connected, so we know when a new browser has been created. 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::TAB_CONTENTS_CONNECTED, 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ask for notification when the snapshot source image has changed 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and needs to be refreshed. 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::THUMBNAIL_GENERATOR_SNAPSHOT_CHANGED, 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserList::AddObserver(this); 49021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WmMessageListener::GetInstance()->AddObserver(this); 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWmOverviewController::~WmOverviewController() { 49421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WmMessageListener::GetInstance()->RemoveObserver(this); 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserList::RemoveObserver(this); 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch listeners_.clear(); 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WmOverviewController::Observe(NotificationType type, 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details) { 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type.value) { 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now that the tab contents are ready, we create the listeners 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and snapshots for any new browsers out there. This actually 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // results in us traversing the list of browsers more often than 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // necessary (whenever a tab is connected, as opposed to only when 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a new browser is created), but other notifications aren't 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // sufficient to know when the first tab of a new browser has its 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // dimensions set. The implementation of AddAllBrowsers avoids 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // doing anything to already-existing browsers, so it's not a huge 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // problem, but still, it would be nice if there were a more 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // appropriate (browser-level) notification. 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::TAB_CONTENTS_CONNECTED: 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddAllBrowsers(); 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::THUMBNAIL_GENERATOR_SNAPSHOT_CHANGED: { 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It's OK to do this in active mode too -- nothing will happen 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // except invalidation of the snapshot, because the delay timer 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // won't start until we're in overview mode. 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenderWidgetHost* renderer = Details<RenderViewHost>(details).ptr(); 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SnapshotImageChanged(renderer); 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do nothing. 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WmOverviewController::SnapshotImageChanged(RenderWidgetHost* renderer) { 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Find out which TabContents this renderer is attached to, and then 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // invalidate the associated snapshot so it'll update. 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserListenerVector::iterator iter = listeners_.begin(); 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iter != listeners_.end()) { 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < (*iter)->count(); i++) { 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenderWidgetHostView* view = 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*iter)->GetTabContentsAt(i)->GetRenderWidgetHostView(); 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (view && view->GetRenderWidgetHost() == renderer) { 540201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch (*iter)->MarkSnapshotAsDirty(i); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++iter; 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 546201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DLOG(ERROR) << "SnapshotImageChanged, but we do not know which it is?"; 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 549731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid WmOverviewController::OnBrowserRemoved(const Browser* browser) { 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (BrowserListenerVector::iterator i = listeners_.begin(); 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != listeners_.end(); ++i) { 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((*i)->browser() == browser) { 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch listeners_.erase(i); 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserView* GetBrowserViewForGdkWindow(GdkWindow* gdk_window) { 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer data = NULL; 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_get_user_data(gdk_window, &data); 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* widget = reinterpret_cast<GtkWidget*>(data); 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (widget) { 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindow* gtk_window = GTK_WINDOW(widget); 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return BrowserView::GetBrowserViewForNativeWindow(gtk_window); 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WmOverviewController::ProcessWmMessage(const WmIpc::Message& message, 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkWindow* window) { 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (message.type()) { 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WM_IPC_MESSAGE_CHROME_NOTIFY_LAYOUT_MODE: { 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch layout_mode_ = message.param(0) == 0 ? ACTIVE_MODE : OVERVIEW_MODE; 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (layout_mode_ == ACTIVE_MODE || BrowserList::size() == 0) { 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Hide(message.param(1) != 0); 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Show(); 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case WM_IPC_MESSAGE_CHROME_NOTIFY_TAB_SELECT: { 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserView* browser_window = GetBrowserViewForGdkWindow(window); 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Find out which listener this goes to, and send it there. 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (BrowserListenerVector::iterator i = listeners_.begin(); 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != listeners_.end(); ++i) { 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((*i)->browser()->window() == browser_window) { 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // param(0): index of the tab to select. 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // param(1): timestamp of the event. 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*i)->SelectTab(message.param(0), message.param(1)); 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WmOverviewController::StartDelayTimer() { 603201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // We're rate limiting the number of times we can reconfigure the 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // snapshots. If we were to restart the delay timer, it could 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // result in a very long delay until they get configured if tabs 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // keep changing. 607201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch updating_snapshots_ = false; 608201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (layout_mode_ == OVERVIEW_MODE) { 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delay_timer_.Start( 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta::FromMilliseconds(kDelayTimeMs), this, 611201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch &WmOverviewController::UpdateSnapshots); 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WmOverviewController::RestoreTabSelections() { 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (BrowserListenerVector::iterator i = listeners_.begin(); 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != listeners_.end(); ++i) { 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*i)->RestoreOriginalSelectedTab(); 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WmOverviewController::SaveTabSelections() { 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (BrowserListenerVector::iterator i = listeners_.begin(); 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != listeners_.end(); ++i) { 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*i)->SaveCurrentTab(); 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WmOverviewController::Show() { 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SaveTabSelections(); 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (BrowserListenerVector::iterator i = listeners_.begin(); 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != listeners_.end(); ++i) { 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*i)->ShowSnapshots(); 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 636201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 637201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // TODO(jiesun): Make the focused tab as the start point. 638201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch browser_listener_index_ = 0; 639201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab_contents_index_ = -1; 640201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch UpdateSnapshots(); 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WmOverviewController::Hide(bool cancelled) { 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delay_timer_.Stop(); 645201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch updating_snapshots_ = false; 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cancelled) { 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RestoreTabSelections(); 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 651201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid WmOverviewController::UpdateSnapshots() { 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 653201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Only updating snapshots during overview mode. 654201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (layout_mode_ != OVERVIEW_MODE) 655201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return; 656201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 657201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Only reloading snapshots when not already started. 658201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (updating_snapshots_ || delay_timer_.IsRunning()) 659201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return; 660201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 661201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Only update one snapshot in round-robin mode. 662201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Start delay timer after each update unless all snapshots had been updated. 663201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!listeners_.size()) 664201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return; 665201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 666201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (int(listeners_.size()) <= browser_listener_index_) { 667201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DLOG(INFO) << "Browser listener(s) have disappeared since last update"; 668201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch browser_listener_index_ = 0; 669201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab_contents_index_ = -1; 670201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } else { 671201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BrowserListener* listener = listeners_[browser_listener_index_].get(); 672201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (listener->count() <= tab_contents_index_) { 673201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DLOG(INFO) << "Tab content(s) have disappeared since last update"; 674201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab_contents_index_ = -1; 675201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 676201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 677201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 678201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int browser_listener_index = browser_listener_index_; 679201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int tab_contents_index = tab_contents_index_; 680201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 681201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch bool loop_back = false; 682201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch while (1) { 683201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BrowserListener* listener = listeners_[browser_listener_index].get(); 684201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab_contents_index = 685201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch listener->ConfigureNextUnconfiguredSnapshot(tab_contents_index); 686201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (tab_contents_index >= 0) { 687201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch updating_snapshots_ = true; // Prevent future parallel updates. 688201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch browser_listener_index_ = browser_listener_index; 689201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab_contents_index_ = tab_contents_index; 690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 691201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 692201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 693201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Found next one; 69421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen browser_listener_index++; 695201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch browser_listener_index = browser_listener_index % listeners_.size(); 696201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch tab_contents_index = -1; 697201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 698201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (loop_back) 699201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch break; 700201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch loop_back = browser_listener_index == browser_listener_index_; 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 702201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 703201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // All snapshots have been fully updated. 704201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch updating_snapshots_ = false; 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WmOverviewController::AddAllBrowsers() { 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make a copy so the old ones aren't deleted yet. 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserListenerVector old_listeners; 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch listeners_.swap(old_listeners); 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Iterator through the browser list, adding all the browsers in the 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // new order. If they were in the old list of listeners, just copy 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that linked pointer, instead of making a new listener, so that we 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // can avoid lots of spurious destroy/create messages. 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserList::const_iterator iterator = BrowserList::begin(); 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (iterator != BrowserList::end()) { 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't add a browser to the list if that type of browser doesn't 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // have snapshots in overview mode. 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((*iterator)->type() != Browser::TYPE_NORMAL && 72221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen (*iterator)->type() != Browser::TYPE_APP) { 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++iterator; 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserListenerVector::value_type item( 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserListenerVector::value_type(NULL)); 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (BrowserListenerVector::iterator old_iter = old_listeners.begin(); 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch old_iter != old_listeners.end(); ++old_iter) { 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((*old_iter)->browser() == *iterator) { 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item = *old_iter; 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This browser isn't tracked by any listener, so create it. 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (item.get() == NULL) { 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item = BrowserListenerVector::value_type( 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new BrowserListener(*iterator, this)); 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch listeners_.push_back(item); 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++iterator; 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace chromeos 748