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