summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-19 22:01:26 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-19 22:01:26 +0000
commitfa5c9a0393065b41c2b81fc20e12ff232cafb17b (patch)
treee23686f952a7e2e16c5954f05b5028ffde30970b /chrome/browser/gtk
parent12b5d06ea959032da7288b8b2b435adfc2c2cea3 (diff)
downloadchromium_src-fa5c9a0393065b41c2b81fc20e12ff232cafb17b.zip
chromium_src-fa5c9a0393065b41c2b81fc20e12ff232cafb17b.tar.gz
chromium_src-fa5c9a0393065b41c2b81fc20e12ff232cafb17b.tar.bz2
Add a TabContentsContainerGtk to remove the current hack that inserts the
RenderViewHostGtk native_view() into the widget heiarchy. (Now we're crashing on cross site instance navigation because it looks like we aren't updating some internal reference to the new renderer.) Review URL: http://codereview.chromium.org/21517 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10045 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc61
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h26
-rw-r--r--chrome/browser/gtk/tab_contents_container_gtk.cc112
-rw-r--r--chrome/browser/gtk/tab_contents_container_gtk.h59
4 files changed, 238 insertions, 20 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index a1fa41e..86bbfa4 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/gtk/nine_box.h"
#include "chrome/browser/gtk/browser_toolbar_view_gtk.h"
#include "chrome/browser/gtk/status_bubble_gtk.h"
+#include "chrome/browser/gtk/tab_contents_container_gtk.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/tab_contents/web_contents.h"
@@ -57,14 +58,16 @@ gfx::Rect GetInitialWindowBounds(GtkWindow* window) {
} // namespace
BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
- : content_area_(NULL),
- browser_(browser),
- custom_frame_(false) // TODO(port): make this a pref.
-{
+ : browser_(browser),
+ // TODO(port): make this a pref.
+ custom_frame_(false) {
Init();
+ browser_->tabstrip_model()->AddObserver(this);
}
BrowserWindowGtk::~BrowserWindowGtk() {
+ browser_->tabstrip_model()->RemoveObserver(this);
+
Close();
}
@@ -81,8 +84,8 @@ gboolean BrowserWindowGtk::OnContentAreaExpose(GtkWidget* widget,
const int kFramePixels = 2;
GdkPixbuf* pixbuf =
- gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, // alpha
- 8, // bit depth
+ gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, // alpha
+ 8, // bit depth
widget->allocation.width,
BrowserToolbarGtk::kToolbarHeight + kFramePixels);
@@ -141,6 +144,9 @@ void BrowserWindowGtk::Init() {
toolbar_->Init(browser_->profile());
toolbar_->AddToolbarToBox(vbox_);
+ contents_container_.reset(new TabContentsContainerGtk());
+ contents_container_->AddContainerToBox(vbox_);
+
// Note that calling this the first time is necessary to get the
// proper control layout.
// TODO(port): make this a pref.
@@ -152,15 +158,6 @@ void BrowserWindowGtk::Init() {
}
void BrowserWindowGtk::Show() {
- // TODO(estade): fix this block. As it stands, it is a temporary hack to get
- // the browser displaying something.
- if (content_area_ == NULL) {
- WebContents* contents = (WebContents*)(browser_->GetTabContentsAt(0));
- content_area_ = ((RenderWidgetHostViewGtk*)contents->
- render_view_host()->view())->native_view();
- gtk_box_pack_start(GTK_BOX(vbox_), content_area_, TRUE, TRUE, 0);
- }
-
gtk_widget_show_all(GTK_WIDGET(window_));
}
@@ -318,6 +315,40 @@ void BrowserWindowGtk::ShowHTMLDialog(HtmlDialogContentsDelegate* delegate,
NOTIMPLEMENTED();
}
+void BrowserWindowGtk::TabDetachedAt(TabContents* contents, int index) {
+ // We use index here rather than comparing |contents| because by this time
+ // the model has already removed |contents| from its list, so
+ // browser_->GetSelectedTabContents() will return NULL or something else.
+ if (index == browser_->tabstrip_model()->selected_index()) {
+ // TODO(port): Uncoment this line when we get infobars.
+ // infobar_container_->ChangeTabContents(NULL);
+ contents_container_->SetTabContents(NULL);
+ }
+}
+
+void BrowserWindowGtk::TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture) {
+ DCHECK(old_contents != new_contents);
+
+ // Update various elements that are interested in knowing the current
+ // TabContents.
+ // TOOD(port): Un-comment this line when we get infobars.
+ // infobar_container_->ChangeTabContents(new_contents);
+ contents_container_->SetTabContents(new_contents);
+
+ new_contents->DidBecomeSelected();
+
+ // Update all the UI bits.
+ UpdateTitleBar();
+ toolbar_->SetProfile(new_contents->profile());
+ UpdateToolbar(new_contents, true);
+}
+
+void BrowserWindowGtk::TabStripEmpty() {
+}
+
void BrowserWindowGtk::DestroyBrowser() {
browser_.reset();
}
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index 6ff3ce0..70ed990 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -2,24 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_WINDOW_GTK_H_
-#define CHROME_BROWSER_WINDOW_GTK_H_
+#ifndef CHROME_BROWSER_GTK_BROWSER_WINDOW_GTK_H_
+#define CHROME_BROWSER_GTK_BROWSER_WINDOW_GTK_H_
#include <gtk/gtk.h>
#include "base/gfx/rect.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/browser_window.h"
+#include "chrome/browser/tabs/tab_strip_model.h"
class BrowserToolbarGtk;
class NineBox;
class StatusBubbleGtk;
+class TabContentsContainerGtk;
// An implementation of BrowserWindow for GTK.
// Cross-platform code will interact with this object when
// it needs to manipulate the window.
-class BrowserWindowGtk : public BrowserWindow {
+class BrowserWindowGtk : public BrowserWindow,
+ public TabStripModelObserver {
public:
explicit BrowserWindowGtk(Browser* browser);
virtual ~BrowserWindowGtk();
@@ -64,6 +67,14 @@ class BrowserWindowGtk : public BrowserWindow {
virtual void ShowHTMLDialog(HtmlDialogContentsDelegate* delegate,
void* parent_window);
+ // Overridden from TabStripModelObserver:
+ virtual void TabDetachedAt(TabContents* contents, int index);
+ virtual void TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture);
+ virtual void TabStripEmpty();
+
void OnBoundsChanged(const gfx::Rect& bounds);
void OnStateChanged(GdkWindowState state);
@@ -71,7 +82,6 @@ class BrowserWindowGtk : public BrowserWindow {
virtual void DestroyBrowser();
GtkWindow* window_;
GtkWidget* vbox_;
- GtkWidget* content_area_;
scoped_ptr<Browser> browser_;
@@ -96,11 +106,17 @@ class BrowserWindowGtk : public BrowserWindow {
// Whether we're drawing the custom Chrome frame (including title bar).
bool custom_frame_;
+ // The object that manages all of the widgets in the toolbar.
scoped_ptr<BrowserToolbarGtk> toolbar_;
// The status bubble manager. Always non-NULL.
scoped_ptr<StatusBubbleGtk> status_bubble_;
+
+ // A container that manages the GtkWidget*s that are the webpage display
+ // (along with associated infobars, shelves, and other things that are part
+ // of the content area).
+ scoped_ptr<TabContentsContainerGtk> contents_container_;
};
-#endif // CHROME_BROWSER_WINDOW_GTK_H_
+#endif // CHROME_BROWSER_GTK_BROWSER_WINDOW_GTK_H_
diff --git a/chrome/browser/gtk/tab_contents_container_gtk.cc b/chrome/browser/gtk/tab_contents_container_gtk.cc
new file mode 100644
index 0000000..9f07b66
--- /dev/null
+++ b/chrome/browser/gtk/tab_contents_container_gtk.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/gtk/tab_contents_container_gtk.h"
+
+#include "base/gfx/native_widget_types.h"
+#include "chrome/browser/tab_contents/web_contents.h"
+#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
+#include "chrome/common/notification_service.h"
+
+
+TabContentsContainerGtk::TabContentsContainerGtk()
+ : tab_contents_(NULL),
+ vbox_(gtk_vbox_new(FALSE, 0)) {
+}
+
+TabContentsContainerGtk::~TabContentsContainerGtk() {
+ if (tab_contents_)
+ RemoveObservers();
+}
+
+void TabContentsContainerGtk::AddContainerToBox(GtkWidget* box) {
+ gtk_box_pack_start(GTK_BOX(box), vbox_, TRUE, TRUE, 0);
+}
+
+void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) {
+ if (tab_contents_) {
+ gfx::NativeView widget = tab_contents_->GetNativeView();
+ if (widget) {
+ gtk_container_remove(GTK_CONTAINER(vbox_), widget);
+ }
+
+ tab_contents_->WasHidden();
+
+ RemoveObservers();
+ }
+
+ tab_contents_ = tab_contents;
+
+ // When detaching the last tab of the browser SetTabContents is invoked
+ // with NULL. Don't attempt to do anything in that case.
+ if (tab_contents_) {
+ AddObservers();
+
+ gfx::NativeView widget = tab_contents_->GetNativeView();
+ if (widget) {
+ gtk_box_pack_start(GTK_BOX(vbox_), widget, TRUE, TRUE, 0);
+ }
+ }
+}
+
+void TabContentsContainerGtk::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) {
+ RenderViewHostSwitchedDetails* switched_details =
+ Details<RenderViewHostSwitchedDetails>(details).ptr();
+ RenderViewHostChanged(switched_details->old_host,
+ switched_details->new_host);
+ } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
+ TabContentsDestroyed(Source<TabContents>(source).ptr());
+ } else {
+ NOTREACHED();
+ }
+}
+
+void TabContentsContainerGtk::AddObservers() {
+ DCHECK(tab_contents_);
+ if (tab_contents_->AsWebContents()) {
+ // WebContents can change their RenderViewHost and hence the GtkWidget that
+ // is shown. I'm not entirely sure that we need to observe this event under
+ // GTK, but am putting a stub implementation and a comment saying that if
+ // we crash after that NOTIMPLEMENTED(), we'll need it.
+ NotificationService::current()->AddObserver(
+ this, NotificationType::RENDER_VIEW_HOST_CHANGED,
+ Source<NavigationController>(tab_contents_->controller()));
+ }
+ NotificationService::current()->AddObserver(
+ this,
+ NotificationType::TAB_CONTENTS_DESTROYED,
+ Source<TabContents>(tab_contents_));
+}
+
+void TabContentsContainerGtk::RemoveObservers() {
+ DCHECK(tab_contents_);
+ if (tab_contents_->AsWebContents()) {
+ NotificationService::current()->RemoveObserver(
+ this,
+ NotificationType::RENDER_VIEW_HOST_CHANGED,
+ Source<NavigationController>(tab_contents_->controller()));
+ }
+ NotificationService::current()->RemoveObserver(
+ this,
+ NotificationType::TAB_CONTENTS_DESTROYED,
+ Source<TabContents>(tab_contents_));
+}
+
+void TabContentsContainerGtk::RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) {
+ // If you find a crash right after this NOTIMPLEMENTED(), we'll need to
+ // switch out some widgets like in SetTabContents().
+ NOTIMPLEMENTED();
+}
+
+void TabContentsContainerGtk::TabContentsDestroyed(TabContents* contents) {
+ // Sometimes, a TabContents is destroyed before we know about it. This allows
+ // us to clean up our state in case this happens.
+ DCHECK(contents == tab_contents_);
+ SetTabContents(NULL);
+}
+
diff --git a/chrome/browser/gtk/tab_contents_container_gtk.h b/chrome/browser/gtk/tab_contents_container_gtk.h
new file mode 100644
index 0000000..927f1f6
--- /dev/null
+++ b/chrome/browser/gtk/tab_contents_container_gtk.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_GTK_TAB_CONTENTS_CONTAINER_GTK_H__
+#define CHROME_BROWSER_GTK_TAB_CONTENTS_CONTAINER_GTK_H__
+
+#include <gtk/gtk.h>
+
+#include "base/basictypes.h"
+#include "chrome/common/notification_observer.h"
+
+class RenderViewHost;
+class TabContents;
+
+class TabContentsContainerGtk : public NotificationObserver {
+ public:
+ TabContentsContainerGtk();
+ ~TabContentsContainerGtk();
+
+ // Inserts our GtkWidget* hierarchy into a GtkBox managed by our owner.
+ void AddContainerToBox(GtkWidget* widget);
+
+ // Make the specified tab visible.
+ void SetTabContents(TabContents* tab_contents);
+ TabContents* GetTabContents() const { return tab_contents_; }
+
+ // NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ // Add or remove observers for events that we care about.
+ void AddObservers();
+ void RemoveObservers();
+
+ // Called when the RenderViewHost of the hosted TabContents has changed, e.g.
+ // to show an interstitial page.
+ void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host);
+
+ // Called when a TabContents is destroyed. This gives us a chance to clean
+ // up our internal state if the TabContents is somehow destroyed before we
+ // get notified.
+ void TabContentsDestroyed(TabContents* contents);
+
+ // The currently visible TabContents.
+ TabContents* tab_contents_;
+
+ // We keep a GtkVBox which is inserted into this object's owner's GtkWidget
+ // hierarchy. We then insert and remove WebContents GtkWidgets into this
+ // vbox_.
+ GtkWidget* vbox_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(TabContentsContainerGtk);
+};
+
+#endif // CHROME_BROWSER_GTK_TAB_CONTENTS_CONTAINER_GTK_H__