summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-01 21:06:29 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-01 21:06:29 +0000
commit4dab725746e1cea9430833de820d27999b5f0c43 (patch)
tree1a5e815ee568f4c5ca1db6116ca01ed55142ec20
parent59470077c6e1b77fdb11aec535958b1fdd8e623a (diff)
downloadchromium_src-4dab725746e1cea9430833de820d27999b5f0c43.zip
chromium_src-4dab725746e1cea9430833de820d27999b5f0c43.tar.gz
chromium_src-4dab725746e1cea9430833de820d27999b5f0c43.tar.bz2
Improves tab overview.
BUG=none TEST=none Review URL: http://codereview.chromium.org/151169 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19761 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/views/tabs/dragged_tab_controller.h6
-rw-r--r--chrome/browser/views/tabs/tab_overview_controller.cc33
-rw-r--r--chrome/browser/views/tabs/tab_overview_controller.h6
-rw-r--r--chrome/browser/views/tabs/tab_overview_drag_controller.cc62
-rw-r--r--chrome/browser/views/tabs/tab_overview_drag_controller.h30
-rw-r--r--chrome/browser/views/tabs/tab_overview_grid.cc6
-rw-r--r--chrome/browser/views/tabs/tab_overview_grid.h4
-rw-r--r--chrome/browser/views/tabs/tab_overview_message_listener.cc31
8 files changed, 153 insertions, 25 deletions
diff --git a/chrome/browser/views/tabs/dragged_tab_controller.h b/chrome/browser/views/tabs/dragged_tab_controller.h
index 5330b8a..11c88a6 100644
--- a/chrome/browser/views/tabs/dragged_tab_controller.h
+++ b/chrome/browser/views/tabs/dragged_tab_controller.h
@@ -68,6 +68,12 @@ class DraggedTabController : public TabContentsDelegate,
// Returns true if the specified Tab matches the Tab being dragged.
bool IsDragSourceTab(Tab* tab) const;
+
+
+ TabContents* dragged_contents() { return dragged_contents_; }
+
+
+
private:
class DockDisplayer;
friend class DockDisplayer;
diff --git a/chrome/browser/views/tabs/tab_overview_controller.cc b/chrome/browser/views/tabs/tab_overview_controller.cc
index eeb8347..c2f245b 100644
--- a/chrome/browser/views/tabs/tab_overview_controller.cc
+++ b/chrome/browser/views/tabs/tab_overview_controller.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/tab_contents/thumbnail_generator.h"
#include "chrome/browser/views/tabs/tab_overview_cell.h"
#include "chrome/browser/views/tabs/tab_overview_container.h"
+#include "chrome/browser/views/tabs/tab_overview_drag_controller.h"
#include "chrome/browser/views/tabs/tab_overview_grid.h"
#include "chrome/browser/views/tabs/tab_overview_types.h"
#include "chrome/browser/window_sizer.h"
@@ -85,21 +86,38 @@ void TabOverviewController::SetBrowser(Browser* browser,
browser_ = browser;
if (browser_)
model()->AddObserver(this);
+
+ show_thumbnails_ = false;
+ StartDelayTimer();
+
gfx::Rect host_bounds = CalculateHostBounds();
if (moved_offscreen_ && model() && model()->count()) {
// Need to reset the bounds if we were offscreen.
host_->SetBounds(host_bounds);
moved_offscreen_ = false;
+ } else if (!model() && shown_) {
+ MoveOffscreen();
}
+ if (!moved_offscreen_)
+ container_->SchedulePaint();
+
RecreateCells();
container_->set_arrow_center(horizontal_center_ - host_bounds.x());
+
+ if (!moved_offscreen_)
+ container_->SchedulePaint();
}
TabStripModel* TabOverviewController::model() const {
return browser_ ? browser_->tabstrip_model() : NULL;
}
+void TabOverviewController::SetMouseOverMiniWindow(bool over_mini_window) {
+ if (grid_->drag_controller())
+ grid_->drag_controller()->set_mouse_over_mini_window(over_mini_window);
+}
+
void TabOverviewController::Show() {
if (host_->IsVisible())
return;
@@ -107,9 +125,9 @@ void TabOverviewController::Show() {
shown_ = true;
DCHECK(model()); // The model needs to be set before showing.
host_->Show();
- delay_timer_.Start(
- base::TimeDelta::FromMilliseconds(350), this,
- &TabOverviewController::StartConfiguring);
+
+ show_thumbnails_ = false;
+ StartDelayTimer();
}
void TabOverviewController::ConfigureCell(TabOverviewCell* cell,
@@ -321,6 +339,7 @@ gfx::Rect TabOverviewController::CalculateHostBounds() {
void TabOverviewController::StartConfiguring() {
show_thumbnails_ = true;
+ configure_timer_.Stop();
configure_timer_.Start(
base::TimeDelta::FromMilliseconds(10), this,
&TabOverviewController::ConfigureNextUnconfiguredCell);
@@ -336,3 +355,11 @@ void TabOverviewController::ConfigureNextUnconfiguredCell() {
}
configure_timer_.Stop();
}
+
+void TabOverviewController::StartDelayTimer() {
+ configure_timer_.Stop();
+ delay_timer_.Stop();
+ delay_timer_.Start(
+ base::TimeDelta::FromMilliseconds(350), this,
+ &TabOverviewController::StartConfiguring);
+}
diff --git a/chrome/browser/views/tabs/tab_overview_controller.h b/chrome/browser/views/tabs/tab_overview_controller.h
index 15b13f5..ce5f0f7 100644
--- a/chrome/browser/views/tabs/tab_overview_controller.h
+++ b/chrome/browser/views/tabs/tab_overview_controller.h
@@ -54,6 +54,9 @@ class TabOverviewController : public TabStripModelObserver {
// offscren if the user detaches the last tab in the tab strip.
bool moved_offscreen() const { return moved_offscreen_; }
+ // Sets whether the mouse is over a mini-window.
+ void SetMouseOverMiniWindow(bool over_mini_window);
+
// Shows the grid.
void Show();
@@ -126,6 +129,9 @@ class TabOverviewController : public TabStripModelObserver {
// it. If all the thumnbails have been set configure_timer_ is stopped.
void ConfigureNextUnconfiguredCell();
+ // Starts the delay timer.
+ void StartDelayTimer();
+
// The widget showing the view.
views::Widget* host_;
diff --git a/chrome/browser/views/tabs/tab_overview_drag_controller.cc b/chrome/browser/views/tabs/tab_overview_drag_controller.cc
index b6740cc..da2df5c 100644
--- a/chrome/browser/views/tabs/tab_overview_drag_controller.cc
+++ b/chrome/browser/views/tabs/tab_overview_drag_controller.cc
@@ -7,6 +7,7 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/dock_info.h"
+#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -32,14 +33,16 @@ TabOverviewDragController::TabOverviewDragController(
y_offset_(0),
dragging_(false),
modifying_model_(false),
- detached_window_(NULL) {
+ detached_window_(NULL),
+ hidden_browser_(NULL),
+ mouse_over_mini_window_(false) {
}
TabOverviewDragController::~TabOverviewDragController() {
if (dragging_)
controller_->DragEnded();
if (original_index_ != -1)
- RevertDrag();
+ RevertDrag(false);
}
bool TabOverviewDragController::Configure(const gfx::Point& location) {
@@ -70,6 +73,12 @@ bool TabOverviewDragController::Configure(const gfx::Point& location) {
// Ask the controller to select the cell.
controller_->SelectTab(index);
+
+ if (controller_->browser()) {
+ browser_window_size_ =
+ controller_->browser()->window()->GetNormalBounds().size();
+ }
+
return true;
}
@@ -95,7 +104,12 @@ void TabOverviewDragController::CommitDrag(const gfx::Point& location) {
Drag(location);
if (detached_tab_) {
- DropTab(location);
+ if (mouse_over_mini_window_) {
+ // Dragged over a mini window, add as the last tab to the browser.
+ Attach(model()->count());
+ } else {
+ DropTab(location);
+ }
} else if (!dragging_ ) {
// We haven't started dragging. Tell the controller to focus the browser.
controller_->FocusBrowser();
@@ -109,25 +123,32 @@ void TabOverviewDragController::CommitDrag(const gfx::Point& location) {
original_index_ = -1;
}
-void TabOverviewDragController::RevertDrag() {
+void TabOverviewDragController::RevertDrag(bool tab_destroyed) {
if (original_index_ == -1)
return;
modifying_model_ = true;
if (detached_tab_) {
// Tab is currently detached, add it back to the original tab strip.
- original_model_->InsertTabContentsAt(original_index_,
- detached_tab_, true, false);
+ if (!tab_destroyed) {
+ original_model_->InsertTabContentsAt(original_index_,
+ detached_tab_, true, false);
+ }
SetDetachedContents(NULL);
detached_window_->Close();
detached_window_ = NULL;
- } else if (original_model_ != model()) {
+
+ if (hidden_browser_) {
+ gtk_widget_show(GTK_WIDGET(static_cast<BrowserWindowGtk*>(
+ hidden_browser_->window())->GetNativeHandle()));
+ }
+ } else if (original_model_ != model() && !tab_destroyed) {
// The tab was added to a different tab strip. Move it back to the
// original.
TabContents* contents = model()->DetachTabContentsAt(current_index_);
original_model_->InsertTabContentsAt(original_index_, contents, true,
false);
- } else if (current_index_ != original_index_) {
+ } else if (current_index_ != original_index_ && !tab_destroyed) {
original_model_->MoveTabContentsAt(current_index_, original_index_, true);
}
modifying_model_ = false;
@@ -149,7 +170,7 @@ void TabOverviewDragController::Observe(NotificationType type,
const NotificationDetails& details) {
DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
DCHECK(Source<TabContents>(source).ptr() == detached_tab_);
- RevertDrag();
+ RevertDrag(true);
}
void TabOverviewDragController::OpenURLFromTab(
@@ -326,6 +347,9 @@ void TabOverviewDragController::Detach(const gfx::Point& location) {
// to empty out the tabstrip as otherwise they may trigger Chrome to
// exit.
controller_->MoveOffscreen();
+ hidden_browser_ = controller_->browser();
+ gtk_widget_hide(GTK_WIDGET(static_cast<BrowserWindowGtk*>(
+ hidden_browser_->window())->GetNativeHandle()));
}
modifying_model_ = true;
model()->DetachTabContentsAt(current_index_);
@@ -336,13 +360,12 @@ void TabOverviewDragController::DropTab(const gfx::Point& location) {
TabContents* contents = detached_tab_;
SetDetachedContents(NULL);
- gfx::Rect browser_rect = controller_->browser()->window()->GetNormalBounds();
gfx::Point screen_loc(location);
grid()->ConvertPointToScreen(grid(), &screen_loc);
- gfx::Rect window_bounds(
- screen_loc, gfx::Size(browser_rect.width(), browser_rect.height()));
- Browser* new_browser = model()->delegate()->CreateNewStripWithContents(
- contents, window_bounds, DockInfo());
+ gfx::Rect window_bounds(screen_loc, browser_window_size_);
+ Browser* new_browser =
+ original_model_->delegate()->CreateNewStripWithContents(
+ contents, window_bounds, DockInfo());
new_browser->window()->Show();
detached_window_->Close();
@@ -357,6 +380,15 @@ void TabOverviewDragController::MoveDetachedWindow(
detached_window_->SetBounds(
gfx::Rect(screen_loc,
detached_window_->GetRootView()->GetPreferredSize()));
+
+ // Notify the wm of the move.
+ TabOverviewTypes::Message message;
+ message.set_type(TabOverviewTypes::Message::WM_MOVE_FLOATING_TAB);
+ message.set_param(0, x11_util::GetX11WindowFromGtkWidget(
+ detached_window_->GetNativeView()));
+ message.set_param(1, screen_loc.x() + x_offset_);
+ message.set_param(2, screen_loc.y() + y_offset_);
+ TabOverviewTypes::instance()->SendMessage(message);
}
views::Widget* TabOverviewDragController::CreateDetachedWindow(
@@ -364,7 +396,7 @@ views::Widget* TabOverviewDragController::CreateDetachedWindow(
TabContents* tab_contents) {
// TODO: wrap the cell in another view that provides a background.
views::WidgetGtk* widget =
- new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
+ new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
widget->MakeTransparent();
gfx::Point screen_loc = location;
screen_loc.Offset(-x_offset_, -y_offset_);
diff --git a/chrome/browser/views/tabs/tab_overview_drag_controller.h b/chrome/browser/views/tabs/tab_overview_drag_controller.h
index 7bf5298..4a8a2a0 100644
--- a/chrome/browser/views/tabs/tab_overview_drag_controller.h
+++ b/chrome/browser/views/tabs/tab_overview_drag_controller.h
@@ -10,6 +10,7 @@
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/common/notification_registrar.h"
+class Browser;
class TabOverviewController;
class TabOverviewGrid;
class TabStripModel;
@@ -40,18 +41,24 @@ class TabOverviewDragController : public TabContentsDelegate,
explicit TabOverviewDragController(TabOverviewController* controller);
~TabOverviewDragController();
- // Invoked to prepare the TabOverviewDragController for a drag. Returns true
- // if over a cell, false if the mouse isn't over a valid location.
+ // Sets whether the mouse is over a mini-window.
+ void set_mouse_over_mini_window(bool over_mini_window) {
+ mouse_over_mini_window_ = over_mini_window;
+ }
+
+ // Prepares the TabOverviewDragController for a drag. Returns true if over a
+ // cell, false if the mouse isn't over a valid location.
bool Configure(const gfx::Point& location);
// Invoked as the user drags the mouse.
void Drag(const gfx::Point& location);
- // Invoked to commit the drag, typically when the user pressed enter.
+ // Commits the drag, typically when the user releases the mouse.
void CommitDrag(const gfx::Point& location);
- // Invoked to rever the drag.
- void RevertDrag();
+ // Reverts the drag. Use true if the revert is the result of the tab being
+ // destroyed.
+ void RevertDrag(bool tab_destroyed);
bool modifying_model() const { return modifying_model_; }
TabOverviewGrid* grid() const;
@@ -151,6 +158,19 @@ class TabOverviewDragController : public TabContentsDelegate,
// around; this is that window.
views::Widget* detached_window_;
+ // When a tab is detached from a browser with a single tab we hide the
+ // browser. If this is non-null it means a single tab has been detached
+ // and this is the browser it was detached from.
+ Browser* hidden_browser_;
+
+ // Whether the mouse is over a mini window.
+ bool mouse_over_mini_window_;
+
+ // Size of the browser window. Cached in case browser() becomes NULL (as
+ // happens when the user drags over a region that shouldn't show the tab
+ // overview).
+ gfx::Size browser_window_size_;
+
DISALLOW_COPY_AND_ASSIGN(TabOverviewDragController);
};
diff --git a/chrome/browser/views/tabs/tab_overview_grid.cc b/chrome/browser/views/tabs/tab_overview_grid.cc
index faa151b..35bd116 100644
--- a/chrome/browser/views/tabs/tab_overview_grid.cc
+++ b/chrome/browser/views/tabs/tab_overview_grid.cc
@@ -24,6 +24,10 @@ TabOverviewCell* TabOverviewGrid::GetTabOverviewCellAt(int index) {
return static_cast<TabOverviewCell*>(GetChildViewAt(index));
}
+TabOverviewDragController* TabOverviewGrid::drag_controller() const {
+ return drag_controller_.get();
+}
+
void TabOverviewGrid::CancelDrag() {
drag_controller_.reset(NULL);
}
@@ -65,7 +69,7 @@ void TabOverviewGrid::OnMouseReleased(const views::MouseEvent& event,
return;
if (canceled)
- drag_controller_->RevertDrag();
+ drag_controller_->RevertDrag(false);
else
drag_controller_->CommitDrag(event.location());
drag_controller_.reset(NULL);
diff --git a/chrome/browser/views/tabs/tab_overview_grid.h b/chrome/browser/views/tabs/tab_overview_grid.h
index afb4aba..52cf27f 100644
--- a/chrome/browser/views/tabs/tab_overview_grid.h
+++ b/chrome/browser/views/tabs/tab_overview_grid.h
@@ -27,6 +27,10 @@ class TabOverviewGrid : public Grid {
// Returns the TabOverviewCell at the specified index.
TabOverviewCell* GetTabOverviewCellAt(int index);
+ // Returns the TabOverviewDragController. This is NULL if a drag is not
+ // underway.
+ TabOverviewDragController* drag_controller() const;
+
// Cancels the drag. Does nothing if a drag is not underway.
void CancelDrag();
diff --git a/chrome/browser/views/tabs/tab_overview_message_listener.cc b/chrome/browser/views/tabs/tab_overview_message_listener.cc
index 1014574..85d6607 100644
--- a/chrome/browser/views/tabs/tab_overview_message_listener.cc
+++ b/chrome/browser/views/tabs/tab_overview_message_listener.cc
@@ -62,14 +62,43 @@ void TabOverviewMessageListener::ProcessMessage(
case TabOverviewTypes::Message::CHROME_NOTIFY_LAYOUT_MODE: {
if (message.param(0) == 0) {
new_browser_window_.reset(NULL);
+ controller_.reset(NULL);
} else if (BrowserList::size() > 0) {
Browser* browser = *BrowserList::begin();
+ controller_.reset(new TabOverviewController(
+ browser->window()->GetNormalBounds().origin()));
new_browser_window_.reset(
new NewBrowserWindowWidget(browser->profile()));
}
break;
}
+ case TabOverviewTypes::Message::CHROME_NOTIFY_FLOATING_TAB_OVER_TOPLEVEL: {
+ if (!controller_.get())
+ return;
+
+ bool over_mini_window = message.param(1) == 1;
+ controller_->SetMouseOverMiniWindow(over_mini_window);
+ if (!over_mini_window)
+ return;
+
+ // Not over a mini-window, make sure the controller is showing the
+ // contents of the browser the mouse is over.
+ BrowserWindowGtk* browser_window =
+ BrowserWindowGtk::GetBrowserWindowForNativeWindow(
+ BrowserWindowGtk::GetBrowserWindowForXID(message.param(0)));
+ if (!browser_window)
+ return;
+
+ if (controller_->browser()->window() == browser_window)
+ return;
+
+ TabOverviewTypes::Message select_message;
+ select_message.set_type(TabOverviewTypes::Message::WM_MOVE_FLOATING_TAB);
+ select_message.set_param(0, message.param(1));
+ TabOverviewTypes::instance()->SendMessage(select_message);
+ }
+
default:
break;
}
@@ -86,5 +115,5 @@ void TabOverviewMessageListener::ShowOverview(Browser* browser,
}
void TabOverviewMessageListener::HideOverview() {
- controller_.reset(NULL);
+ controller_->SetBrowser(NULL, -1);
}