Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/gtk/tab_contents_container_gtk.h" | 5 #include "chrome/browser/gtk/tab_contents_container_gtk.h" |
| 6 | 6 |
| 7 #include "base/gfx/native_widget_types.h" | 7 #include "base/gfx/native_widget_types.h" |
| 8 #include "chrome/browser/gtk/status_bubble_gtk.h" | |
| 8 #include "chrome/browser/tab_contents/tab_contents.h" | 9 #include "chrome/browser/tab_contents/tab_contents.h" |
| 9 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" | 10 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
| 10 #include "chrome/common/notification_service.h" | 11 #include "chrome/common/notification_service.h" |
| 11 | 12 |
| 12 TabContentsContainerGtk::TabContentsContainerGtk() | 13 namespace { |
| 14 | |
| 15 // Allocates all normal tab contents views to the size of the passed in | |
| 16 // |allocation|. Ignores StatusBubbles, which are handled separately. | |
| 17 void ChildrenSizeAllocate(GtkWidget* widget, void* param) { | |
| 18 GtkAllocation* allocation = reinterpret_cast<GtkAllocation*>(param); | |
| 19 | |
| 20 if (strcmp(gtk_widget_get_name(widget), "status-bubble") != 0) { | |
| 21 gtk_widget_size_allocate(widget, allocation); | |
| 22 } | |
| 23 } | |
| 24 | |
| 25 } // namespace | |
| 26 | |
| 27 TabContentsContainerGtk::TabContentsContainerGtk(StatusBubbleGtk* status_bubble) | |
| 13 : tab_contents_(NULL), | 28 : tab_contents_(NULL), |
| 14 vbox_(gtk_vbox_new(FALSE, 0)) { | 29 status_bubble_(status_bubble), |
| 15 gtk_widget_show_all(vbox_); | 30 fixed_(gtk_fixed_new()) { |
| 31 gtk_fixed_put(GTK_FIXED(fixed_), status_bubble->widget(), 0, 0); | |
| 32 | |
| 33 g_signal_connect(fixed_, "size-allocate", | |
| 34 G_CALLBACK(OnFixedSizeAllocate), this); | |
| 35 | |
| 36 gtk_widget_show(fixed_); | |
| 16 } | 37 } |
| 17 | 38 |
| 18 TabContentsContainerGtk::~TabContentsContainerGtk() { | 39 TabContentsContainerGtk::~TabContentsContainerGtk() { |
| 19 if (tab_contents_) | 40 if (tab_contents_) |
| 20 RemoveObservers(); | 41 RemoveObservers(); |
| 21 } | 42 } |
| 22 | 43 |
| 23 void TabContentsContainerGtk::AddContainerToBox(GtkWidget* box) { | 44 void TabContentsContainerGtk::AddContainerToBox(GtkWidget* box) { |
| 24 gtk_box_pack_start(GTK_BOX(box), vbox_, TRUE, TRUE, 0); | 45 gtk_box_pack_start(GTK_BOX(box), fixed_, TRUE, TRUE, 0); |
| 25 } | 46 } |
| 26 | 47 |
| 27 void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) { | 48 void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) { |
| 28 if (tab_contents_) { | 49 if (tab_contents_) { |
| 29 gfx::NativeView widget = tab_contents_->GetNativeView(); | 50 gfx::NativeView widget = tab_contents_->GetNativeView(); |
| 30 if (widget) | 51 if (widget) |
| 31 gtk_widget_hide(widget); | 52 gtk_widget_hide(widget); |
| 32 | 53 |
| 33 tab_contents_->WasHidden(); | 54 tab_contents_->WasHidden(); |
| 34 | 55 |
| 35 RemoveObservers(); | 56 RemoveObservers(); |
| 36 } | 57 } |
| 37 | 58 |
| 38 tab_contents_ = tab_contents; | 59 tab_contents_ = tab_contents; |
| 39 | 60 |
| 40 // When detaching the last tab of the browser SetTabContents is invoked | 61 // When detaching the last tab of the browser SetTabContents is invoked |
| 41 // with NULL. Don't attempt to do anything in that case. | 62 // with NULL. Don't attempt to do anything in that case. |
| 42 if (tab_contents_) { | 63 if (tab_contents_) { |
| 43 AddObservers(); | 64 AddObservers(); |
| 44 | 65 |
| 45 gfx::NativeView widget = tab_contents_->GetNativeView(); | 66 gfx::NativeView widget = tab_contents_->GetNativeView(); |
| 46 if (widget) { | 67 if (widget) { |
| 47 // Pack it into |vbox_| if it isn't already. | 68 if (widget->parent != fixed_) |
| 48 if (widget->parent != vbox_) | 69 gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0); |
| 49 gtk_box_pack_end(GTK_BOX(vbox_), widget, TRUE, TRUE, 0); | |
| 50 gtk_widget_show(widget); | 70 gtk_widget_show(widget); |
| 51 } | 71 } |
| 52 | 72 |
| 53 // We need to make sure that we are below the findbar. | 73 // We need to make sure that we are below the findbar. |
| 54 // Sometimes the content native view will be null. | 74 // Sometimes the content native view will be null. |
| 55 // TODO(estade): will this case ever cause findbar occlusion problems? | 75 // TODO(estade): will this case ever cause findbar occlusion problems? |
| 56 if (tab_contents_->GetContentNativeView()) { | 76 if (tab_contents_->GetContentNativeView()) { |
| 57 GdkWindow* content_gdk_window = | 77 GdkWindow* content_gdk_window = |
| 58 tab_contents_->GetContentNativeView()->window; | 78 tab_contents_->GetContentNativeView()->window; |
| 59 if (content_gdk_window) | 79 if (content_gdk_window) |
| 60 gdk_window_lower(content_gdk_window); | 80 gdk_window_lower(content_gdk_window); |
| 61 } | 81 } |
| 62 } | 82 } |
| 63 } | 83 } |
| 64 | 84 |
| 65 void TabContentsContainerGtk::DetachTabContents(TabContents* tab_contents) { | 85 void TabContentsContainerGtk::DetachTabContents(TabContents* tab_contents) { |
| 66 gfx::NativeView widget = tab_contents_->GetNativeView(); | 86 gfx::NativeView widget = tab_contents_->GetNativeView(); |
| 67 if (widget) { | 87 // It is possible to detach an unrealized, unparrented TabContents if you |
|
Evan Stade
2009/05/19 23:41:25
typo: unparented
| |
| 68 DCHECK_EQ(widget->parent, vbox_); | 88 // slow things down enough in valgrind. Might happen in the real world, too. |
| 69 gtk_container_remove(GTK_CONTAINER(vbox_), widget); | 89 if (widget && widget->parent) { |
| 90 DCHECK_EQ(widget->parent, fixed_); | |
| 91 gtk_container_remove(GTK_CONTAINER(fixed_), widget); | |
| 70 } | 92 } |
| 71 } | 93 } |
| 72 | 94 |
| 73 void TabContentsContainerGtk::Observe(NotificationType type, | 95 void TabContentsContainerGtk::Observe(NotificationType type, |
| 74 const NotificationSource& source, | 96 const NotificationSource& source, |
| 75 const NotificationDetails& details) { | 97 const NotificationDetails& details) { |
| 76 if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) { | 98 if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) { |
| 77 RenderViewHostSwitchedDetails* switched_details = | 99 RenderViewHostSwitchedDetails* switched_details = |
| 78 Details<RenderViewHostSwitchedDetails>(details).ptr(); | 100 Details<RenderViewHostSwitchedDetails>(details).ptr(); |
| 79 RenderViewHostChanged(switched_details->old_host, | 101 RenderViewHostChanged(switched_details->old_host, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 // RENDER_VIEW_HOST_CHANGED notification. This was used on Windows for focus | 144 // RENDER_VIEW_HOST_CHANGED notification. This was used on Windows for focus |
| 123 // issues, and I'm not entirely convinced that this isn't necessary. | 145 // issues, and I'm not entirely convinced that this isn't necessary. |
| 124 } | 146 } |
| 125 | 147 |
| 126 void TabContentsContainerGtk::TabContentsDestroyed(TabContents* contents) { | 148 void TabContentsContainerGtk::TabContentsDestroyed(TabContents* contents) { |
| 127 // Sometimes, a TabContents is destroyed before we know about it. This allows | 149 // Sometimes, a TabContents is destroyed before we know about it. This allows |
| 128 // us to clean up our state in case this happens. | 150 // us to clean up our state in case this happens. |
| 129 DCHECK(contents == tab_contents_); | 151 DCHECK(contents == tab_contents_); |
| 130 SetTabContents(NULL); | 152 SetTabContents(NULL); |
| 131 } | 153 } |
| 154 | |
| 155 // static | |
| 156 void TabContentsContainerGtk::OnFixedSizeAllocate( | |
| 157 GtkWidget* fixed, | |
| 158 GtkAllocation* allocation, | |
| 159 TabContentsContainerGtk* container) { | |
| 160 // Set all the tab contents GtkWidgets to the size of the allocation. | |
| 161 gtk_container_foreach(GTK_CONTAINER(fixed), ChildrenSizeAllocate, | |
| 162 allocation); | |
| 163 | |
| 164 // Tell the status bubble about how large it can be. | |
| 165 container->status_bubble_->SetParentAllocation(fixed, allocation); | |
| 166 } | |
| OLD | NEW |