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