| 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 "app/gfx/native_widget_types.h" | 7 #include "app/gfx/native_widget_types.h" |
| 8 #include "app/l10n_util.h" | 8 #include "app/l10n_util.h" |
| 9 #include "chrome/browser/gtk/gtk_expanded_container.h" |
| 9 #include "chrome/browser/gtk/gtk_floating_container.h" | 10 #include "chrome/browser/gtk/gtk_floating_container.h" |
| 10 #include "chrome/browser/gtk/status_bubble_gtk.h" | 11 #include "chrome/browser/gtk/status_bubble_gtk.h" |
| 11 #include "chrome/browser/tab_contents/tab_contents.h" | 12 #include "chrome/browser/tab_contents/tab_contents.h" |
| 12 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" | 13 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
| 13 #include "chrome/common/notification_service.h" | 14 #include "chrome/common/notification_service.h" |
| 14 | 15 |
| 15 namespace { | |
| 16 | |
| 17 // Allocates all normal tab contents views to the size of the passed in | |
| 18 // |allocation|. | |
| 19 void ResizeChildren(GtkWidget* widget, void* param) { | |
| 20 GtkAllocation* allocation = reinterpret_cast<GtkAllocation*>(param); | |
| 21 if (!GTK_WIDGET_VISIBLE(widget)) | |
| 22 return; | |
| 23 | |
| 24 if (widget->allocation.width != allocation->width || | |
| 25 widget->allocation.height != allocation->height) { | |
| 26 gtk_widget_set_size_request(widget, allocation->width, | |
| 27 allocation->height); | |
| 28 } | |
| 29 } | |
| 30 | |
| 31 } // namespace | |
| 32 | |
| 33 TabContentsContainerGtk::TabContentsContainerGtk(StatusBubbleGtk* status_bubble) | 16 TabContentsContainerGtk::TabContentsContainerGtk(StatusBubbleGtk* status_bubble) |
| 34 : tab_contents_(NULL), | 17 : tab_contents_(NULL), |
| 35 status_bubble_(status_bubble) { | 18 status_bubble_(status_bubble) { |
| 36 Init(); | 19 Init(); |
| 37 } | 20 } |
| 38 | 21 |
| 39 TabContentsContainerGtk::~TabContentsContainerGtk() { | 22 TabContentsContainerGtk::~TabContentsContainerGtk() { |
| 40 floating_.Destroy(); | 23 floating_.Destroy(); |
| 41 } | 24 } |
| 42 | 25 |
| 43 void TabContentsContainerGtk::Init() { | 26 void TabContentsContainerGtk::Init() { |
| 44 // A high level overview of the TabContentsContainer: | 27 // A high level overview of the TabContentsContainer: |
| 45 // | 28 // |
| 46 // +- GtkFloatingContainer |floating_| -------------------------------+ | 29 // +- GtkFloatingContainer |floating_| -------------------------------+ |
| 47 // |+- GtkFixedContainer |fixed_| -----------------------------------+| | 30 // |+- GtkExpandedContainer |expanded_| -----------------------------+| |
| 48 // || || | 31 // || || |
| 49 // || || | 32 // || || |
| 50 // || || | 33 // || || |
| 51 // || || | 34 // || || |
| 52 // |+- (StatusBubble) ------+ || | 35 // |+- (StatusBubble) ------+ || |
| 53 // |+ + || | 36 // |+ + || |
| 54 // |+-----------------------+----------------------------------------+| | 37 // |+-----------------------+----------------------------------------+| |
| 55 // +------------------------------------------------------------------+ | 38 // +------------------------------------------------------------------+ |
| 56 | 39 |
| 57 floating_.Own(gtk_floating_container_new()); | 40 floating_.Own(gtk_floating_container_new()); |
| 58 gtk_widget_set_name(floating_.get(), "chrome-tab-contents-container"); | 41 gtk_widget_set_name(floating_.get(), "chrome-tab-contents-container"); |
| 59 | 42 |
| 60 fixed_ = gtk_fixed_new(); | 43 expanded_ = gtk_expanded_container_new(); |
| 61 g_signal_connect(fixed_, "size-allocate", | 44 gtk_container_add(GTK_CONTAINER(floating_.get()), expanded_); |
| 62 G_CALLBACK(OnFixedSizeAllocate), this); | |
| 63 gtk_container_add(GTK_CONTAINER(floating_.get()), fixed_); | |
| 64 | 45 |
| 65 if (status_bubble_) { | 46 if (status_bubble_) { |
| 66 gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()), | 47 gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()), |
| 67 status_bubble_->widget()); | 48 status_bubble_->widget()); |
| 68 g_signal_connect(floating_.get(), "set-floating-position", | 49 g_signal_connect(floating_.get(), "set-floating-position", |
| 69 G_CALLBACK(OnSetFloatingPosition), this); | 50 G_CALLBACK(OnSetFloatingPosition), this); |
| 70 } | 51 } |
| 71 | 52 |
| 72 gtk_widget_show(fixed_); | 53 gtk_widget_show(expanded_); |
| 73 gtk_widget_show(floating_.get()); | 54 gtk_widget_show(floating_.get()); |
| 74 | 55 |
| 75 ViewIDUtil::SetDelegateForWidget(widget(), this); | 56 ViewIDUtil::SetDelegateForWidget(widget(), this); |
| 76 } | 57 } |
| 77 | 58 |
| 78 void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) { | 59 void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) { |
| 79 if (tab_contents_) { | 60 if (tab_contents_) { |
| 80 gfx::NativeView widget = tab_contents_->GetNativeView(); | 61 gfx::NativeView widget = tab_contents_->GetNativeView(); |
| 81 if (widget) | 62 if (widget) |
| 82 gtk_widget_hide(widget); | 63 gtk_widget_hide(widget); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 98 // is shown. I'm not entirely sure that we need to observe this event under | 79 // is shown. I'm not entirely sure that we need to observe this event under |
| 99 // GTK, but am putting a stub implementation and a comment saying that if | 80 // GTK, but am putting a stub implementation and a comment saying that if |
| 100 // we crash after that NOTIMPLEMENTED(), we'll need it. | 81 // we crash after that NOTIMPLEMENTED(), we'll need it. |
| 101 registrar_.Add(this, NotificationType::RENDER_VIEW_HOST_CHANGED, | 82 registrar_.Add(this, NotificationType::RENDER_VIEW_HOST_CHANGED, |
| 102 Source<NavigationController>(&tab_contents_->controller())); | 83 Source<NavigationController>(&tab_contents_->controller())); |
| 103 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, | 84 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, |
| 104 Source<TabContents>(tab_contents_)); | 85 Source<TabContents>(tab_contents_)); |
| 105 | 86 |
| 106 gfx::NativeView widget = tab_contents_->GetNativeView(); | 87 gfx::NativeView widget = tab_contents_->GetNativeView(); |
| 107 if (widget) { | 88 if (widget) { |
| 108 if (widget->parent != fixed_) | 89 if (widget->parent != expanded_) |
| 109 gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0); | 90 gtk_container_add(GTK_CONTAINER(expanded_), widget); |
| 110 gtk_widget_show(widget); | 91 gtk_widget_show(widget); |
| 111 } | 92 } |
| 112 | 93 |
| 113 // We need to make sure that we are below the findbar. | 94 // We need to make sure that we are below the findbar. |
| 114 // Sometimes the content native view will be null. | 95 // Sometimes the content native view will be null. |
| 115 // TODO(estade): will this case ever cause findbar occlusion problems? | 96 // TODO(estade): will this case ever cause findbar occlusion problems? |
| 116 if (tab_contents_->GetContentNativeView()) { | 97 if (tab_contents_->GetContentNativeView()) { |
| 117 GdkWindow* content_gdk_window = | 98 GdkWindow* content_gdk_window = |
| 118 tab_contents_->GetContentNativeView()->window; | 99 tab_contents_->GetContentNativeView()->window; |
| 119 if (content_gdk_window) | 100 if (content_gdk_window) |
| 120 gdk_window_lower(content_gdk_window); | 101 gdk_window_lower(content_gdk_window); |
| 121 } | 102 } |
| 122 } | 103 } |
| 123 } | 104 } |
| 124 | 105 |
| 125 void TabContentsContainerGtk::DetachTabContents(TabContents* tab_contents) { | 106 void TabContentsContainerGtk::DetachTabContents(TabContents* tab_contents) { |
| 126 gfx::NativeView widget = tab_contents->GetNativeView(); | 107 gfx::NativeView widget = tab_contents->GetNativeView(); |
| 127 // It is possible to detach an unrealized, unparented TabContents if you | 108 // It is possible to detach an unrealized, unparented TabContents if you |
| 128 // slow things down enough in valgrind. Might happen in the real world, too. | 109 // slow things down enough in valgrind. Might happen in the real world, too. |
| 129 if (widget && widget->parent) { | 110 if (widget && widget->parent) { |
| 130 DCHECK_EQ(widget->parent, fixed_); | 111 DCHECK_EQ(widget->parent, expanded_); |
| 131 gtk_container_remove(GTK_CONTAINER(fixed_), widget); | 112 gtk_container_remove(GTK_CONTAINER(expanded_), widget); |
| 132 } | 113 } |
| 133 } | 114 } |
| 134 | 115 |
| 135 void TabContentsContainerGtk::Observe(NotificationType type, | 116 void TabContentsContainerGtk::Observe(NotificationType type, |
| 136 const NotificationSource& source, | 117 const NotificationSource& source, |
| 137 const NotificationDetails& details) { | 118 const NotificationDetails& details) { |
| 138 if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) { | 119 if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) { |
| 139 RenderViewHostSwitchedDetails* switched_details = | 120 RenderViewHostSwitchedDetails* switched_details = |
| 140 Details<RenderViewHostSwitchedDetails>(details).ptr(); | 121 Details<RenderViewHostSwitchedDetails>(details).ptr(); |
| 141 RenderViewHostChanged(switched_details->old_host, | 122 RenderViewHostChanged(switched_details->old_host, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 169 view_id == VIEW_ID_TAB_CONTAINER_FOCUS_VIEW) { | 150 view_id == VIEW_ID_TAB_CONTAINER_FOCUS_VIEW) { |
| 170 return widget(); | 151 return widget(); |
| 171 } | 152 } |
| 172 | 153 |
| 173 return NULL; | 154 return NULL; |
| 174 } | 155 } |
| 175 | 156 |
| 176 // ----------------------------------------------------------------------------- | 157 // ----------------------------------------------------------------------------- |
| 177 | 158 |
| 178 // static | 159 // static |
| 179 void TabContentsContainerGtk::OnFixedSizeAllocate( | |
| 180 GtkWidget* fixed, | |
| 181 GtkAllocation* allocation, | |
| 182 TabContentsContainerGtk* container) { | |
| 183 // Set all the tab contents GtkWidgets to the size of the allocation. | |
| 184 gtk_container_foreach(GTK_CONTAINER(fixed), ResizeChildren, allocation); | |
| 185 } | |
| 186 | |
| 187 // static | |
| 188 void TabContentsContainerGtk::OnSetFloatingPosition( | 160 void TabContentsContainerGtk::OnSetFloatingPosition( |
| 189 GtkFloatingContainer* floating_container, GtkAllocation* allocation, | 161 GtkFloatingContainer* floating_container, GtkAllocation* allocation, |
| 190 TabContentsContainerGtk* tab_contents_container) { | 162 TabContentsContainerGtk* tab_contents_container) { |
| 191 StatusBubbleGtk* status = tab_contents_container->status_bubble_; | 163 StatusBubbleGtk* status = tab_contents_container->status_bubble_; |
| 192 | 164 |
| 193 // Look at the size request of the status bubble and tell the | 165 // Look at the size request of the status bubble and tell the |
| 194 // GtkFloatingContainer where we want it positioned. | 166 // GtkFloatingContainer where we want it positioned. |
| 195 GtkRequisition requisition; | 167 GtkRequisition requisition; |
| 196 gtk_widget_size_request(status->widget(), &requisition); | 168 gtk_widget_size_request(status->widget(), &requisition); |
| 197 | 169 |
| 198 bool ltr = (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT); | 170 bool ltr = (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT); |
| 199 | 171 |
| 200 GValue value = { 0, }; | 172 GValue value = { 0, }; |
| 201 g_value_init(&value, G_TYPE_INT); | 173 g_value_init(&value, G_TYPE_INT); |
| 202 if (ltr ^ status->flip_horizontally()) // Is it on the left? | 174 if (ltr ^ status->flip_horizontally()) // Is it on the left? |
| 203 g_value_set_int(&value, 0); | 175 g_value_set_int(&value, 0); |
| 204 else | 176 else |
| 205 g_value_set_int(&value, allocation->width - requisition.width); | 177 g_value_set_int(&value, allocation->width - requisition.width); |
| 206 gtk_container_child_set_property(GTK_CONTAINER(floating_container), | 178 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 207 status->widget(), "x", &value); | 179 status->widget(), "x", &value); |
| 208 | 180 |
| 209 int child_y = std::max( | 181 int child_y = std::max( |
| 210 allocation->y + allocation->height - requisition.height, 0); | 182 allocation->y + allocation->height - requisition.height, 0); |
| 211 g_value_set_int(&value, child_y + status->y_offset()); | 183 g_value_set_int(&value, child_y + status->y_offset()); |
| 212 gtk_container_child_set_property(GTK_CONTAINER(floating_container), | 184 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 213 status->widget(), "y", &value); | 185 status->widget(), "y", &value); |
| 214 g_value_unset(&value); | 186 g_value_unset(&value); |
| 215 } | 187 } |
| OLD | NEW |