OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/chromeos/views/domui_menu_widget.h" | 5 #include "chrome/browser/chromeos/views/webui_menu_widget.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
10 #include "base/singleton.h" | 10 #include "base/singleton.h" |
11 #include "base/task.h" | 11 #include "base/task.h" |
12 #include "chrome/browser/chromeos/views/menu_locator.h" | 12 #include "chrome/browser/chromeos/views/menu_locator.h" |
13 #include "chrome/browser/chromeos/views/native_menu_domui.h" | 13 #include "chrome/browser/chromeos/views/native_menu_domui.h" |
14 #include "chrome/browser/chromeos/wm_ipc.h" | 14 #include "chrome/browser/chromeos/wm_ipc.h" |
15 #include "chrome/browser/renderer_host/render_view_host.h" | 15 #include "chrome/browser/renderer_host/render_view_host.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
97 gfx::Insets insets = host->GetInsets(); | 97 gfx::Insets insets = host->GetInsets(); |
98 gfx::Size size = host->GetChildViewAt(0)->GetPreferredSize(); | 98 gfx::Size size = host->GetChildViewAt(0)->GetPreferredSize(); |
99 return gfx::Size(size.width() + insets.width(), | 99 return gfx::Size(size.width() + insets.width(), |
100 size.height() + insets.height()); | 100 size.height() + insets.height()); |
101 } | 101 } |
102 | 102 |
103 DISALLOW_COPY_AND_ASSIGN(InsetsLayout); | 103 DISALLOW_COPY_AND_ASSIGN(InsetsLayout); |
104 }; | 104 }; |
105 | 105 |
106 // A gtk widget key used to test if a given WidgetGtk instance is | 106 // A gtk widget key used to test if a given WidgetGtk instance is |
107 // DOMUIMenuWidgetKey. | 107 // WebUIMenuWidgetKey. |
Avi (use Gerrit)
2011/02/03 15:09:05
Does the comment mean "if a given WidgetGtk instan
tfarina
2011/02/03 16:37:49
I don't know. Oshima wrote this code.
| |
108 const char* kDOMUIMenuWidgetKey = "__DOMUI_MENU_WIDGET__"; | 108 const char* kWebUIMenuWidgetKey = "__WEBUI_MENU_WIDGET__"; |
109 | 109 |
110 } // namespace | 110 } // namespace |
111 | 111 |
112 namespace chromeos { | 112 namespace chromeos { |
113 | 113 |
114 // static | 114 // static |
115 DOMUIMenuWidget* DOMUIMenuWidget::FindDOMUIMenuWidget(gfx::NativeView native) { | 115 WebUIMenuWidget* WebUIMenuWidget::FindWebUIMenuWidget(gfx::NativeView native) { |
116 DCHECK(native); | 116 DCHECK(native); |
117 native = gtk_widget_get_toplevel(native); | 117 native = gtk_widget_get_toplevel(native); |
118 if (!native) | 118 if (!native) |
119 return NULL; | 119 return NULL; |
120 return static_cast<chromeos::DOMUIMenuWidget*>( | 120 return static_cast<chromeos::WebUIMenuWidget*>( |
121 g_object_get_data(G_OBJECT(native), kDOMUIMenuWidgetKey)); | 121 g_object_get_data(G_OBJECT(native), kWebUIMenuWidgetKey)); |
122 } | 122 } |
123 | 123 |
124 /////////////////////////////////////////////////////////////////////////////// | 124 /////////////////////////////////////////////////////////////////////////////// |
125 // DOMUIMenuWidget public: | 125 // WebUIMenuWidget public: |
126 | 126 |
127 DOMUIMenuWidget::DOMUIMenuWidget(chromeos::NativeMenuDOMUI* domui_menu, | 127 WebUIMenuWidget::WebUIMenuWidget(chromeos::NativeMenuDOMUI* domui_menu, |
128 bool root) | 128 bool root) |
129 : views::WidgetGtk(views::WidgetGtk::TYPE_POPUP), | 129 : views::WidgetGtk(views::WidgetGtk::TYPE_POPUP), |
130 domui_menu_(domui_menu), | 130 domui_menu_(domui_menu), |
131 dom_view_(NULL), | 131 dom_view_(NULL), |
132 did_input_grab_(false), | 132 did_input_grab_(false), |
133 is_root_(root) { | 133 is_root_(root) { |
134 DCHECK(domui_menu_); | 134 DCHECK(domui_menu_); |
135 // TODO(oshima): Disabling transparent until we migrate bookmark | 135 // TODO(oshima): Disabling transparent until we migrate bookmark |
136 // menus to DOMUI. See crosbug.com/7718. | 136 // menus to DOMUI. See crosbug.com/7718. |
137 // MakeTransparent(); | 137 // MakeTransparent(); |
138 } | 138 } |
139 | 139 |
140 DOMUIMenuWidget::~DOMUIMenuWidget() { | 140 WebUIMenuWidget::~WebUIMenuWidget() { |
141 } | 141 } |
142 | 142 |
143 void DOMUIMenuWidget::Init(gfx::NativeView parent, const gfx::Rect& bounds) { | 143 void WebUIMenuWidget::Init(gfx::NativeView parent, const gfx::Rect& bounds) { |
144 WidgetGtk::Init(parent, bounds); | 144 WidgetGtk::Init(parent, bounds); |
145 gtk_window_set_destroy_with_parent(GTK_WINDOW(GetNativeView()), TRUE); | 145 gtk_window_set_destroy_with_parent(GTK_WINDOW(GetNativeView()), TRUE); |
146 gtk_window_set_type_hint(GTK_WINDOW(GetNativeView()), | 146 gtk_window_set_type_hint(GTK_WINDOW(GetNativeView()), |
147 GDK_WINDOW_TYPE_HINT_MENU); | 147 GDK_WINDOW_TYPE_HINT_MENU); |
148 g_object_set_data(G_OBJECT(GetNativeView()), kDOMUIMenuWidgetKey, this); | 148 g_object_set_data(G_OBJECT(GetNativeView()), kWebUIMenuWidgetKey, this); |
149 } | 149 } |
150 | 150 |
151 void DOMUIMenuWidget::Hide() { | 151 void WebUIMenuWidget::Hide() { |
152 ReleaseGrab(); | 152 ReleaseGrab(); |
153 WidgetGtk::Hide(); | 153 WidgetGtk::Hide(); |
154 // Clears the content. | 154 // Clears the content. |
155 ExecuteJavascript(L"updateModel({'items':[]})"); | 155 ExecuteJavascript(L"updateModel({'items':[]})"); |
156 } | 156 } |
157 | 157 |
158 void DOMUIMenuWidget::Close() { | 158 void WebUIMenuWidget::Close() { |
159 if (dom_view_ != NULL) { | 159 if (dom_view_ != NULL) { |
160 dom_view_->GetParent()->RemoveChildView(dom_view_); | 160 dom_view_->GetParent()->RemoveChildView(dom_view_); |
161 delete dom_view_; | 161 delete dom_view_; |
162 dom_view_ = NULL; | 162 dom_view_ = NULL; |
163 } | 163 } |
164 | 164 |
165 // Detach the domui_menu_ which is being deleted. | 165 // Detach the domui_menu_ which is being deleted. |
166 domui_menu_ = NULL; | 166 domui_menu_ = NULL; |
167 views::WidgetGtk::Close(); | 167 views::WidgetGtk::Close(); |
168 } | 168 } |
169 | 169 |
170 void DOMUIMenuWidget::ReleaseGrab() { | 170 void WebUIMenuWidget::ReleaseGrab() { |
171 WidgetGtk::ReleaseGrab(); | 171 WidgetGtk::ReleaseGrab(); |
172 if (did_input_grab_) { | 172 if (did_input_grab_) { |
173 did_input_grab_ = false; | 173 did_input_grab_ = false; |
174 gdk_pointer_ungrab(GDK_CURRENT_TIME); | 174 gdk_pointer_ungrab(GDK_CURRENT_TIME); |
175 gdk_keyboard_ungrab(GDK_CURRENT_TIME); | 175 gdk_keyboard_ungrab(GDK_CURRENT_TIME); |
176 | 176 |
177 ClearGrabWidget(); | 177 ClearGrabWidget(); |
178 } | 178 } |
179 } | 179 } |
180 | 180 |
181 gboolean DOMUIMenuWidget::OnGrabBrokeEvent(GtkWidget* widget, | 181 gboolean WebUIMenuWidget::OnGrabBrokeEvent(GtkWidget* widget, |
182 GdkEvent* event) { | 182 GdkEvent* event) { |
183 did_input_grab_ = false; | 183 did_input_grab_ = false; |
184 Hide(); | 184 Hide(); |
185 return WidgetGtk::OnGrabBrokeEvent(widget, event); | 185 return WidgetGtk::OnGrabBrokeEvent(widget, event); |
186 } | 186 } |
187 | 187 |
188 void DOMUIMenuWidget::OnSizeAllocate(GtkWidget* widget, | 188 void WebUIMenuWidget::OnSizeAllocate(GtkWidget* widget, |
189 GtkAllocation* allocation) { | 189 GtkAllocation* allocation) { |
190 views::WidgetGtk::OnSizeAllocate(widget, allocation); | 190 views::WidgetGtk::OnSizeAllocate(widget, allocation); |
191 // Adjust location when menu gets resized. | 191 // Adjust location when menu gets resized. |
192 gfx::Rect bounds; | 192 gfx::Rect bounds; |
193 GetBounds(&bounds, false); | 193 GetBounds(&bounds, false); |
194 // Don't move until the menu gets contents. | 194 // Don't move until the menu gets contents. |
195 if (bounds.height() > 1) { | 195 if (bounds.height() > 1) { |
196 menu_locator_->Move(this); | 196 menu_locator_->Move(this); |
197 domui_menu_->InputIsReady(); | 197 domui_menu_->InputIsReady(); |
198 } | 198 } |
199 } | 199 } |
200 | 200 |
201 gboolean MapToFocus(GtkWidget* widget, GdkEvent* event, gpointer data) { | 201 gboolean MapToFocus(GtkWidget* widget, GdkEvent* event, gpointer data) { |
202 DOMUIMenuWidget* menu_widget = DOMUIMenuWidget::FindDOMUIMenuWidget(widget); | 202 WebUIMenuWidget* menu_widget = WebUIMenuWidget::FindWebUIMenuWidget(widget); |
203 if (menu_widget) { | 203 if (menu_widget) { |
204 // See EnableInput for the meaning of data. | 204 // See EnableInput for the meaning of data. |
205 bool select_item = data != NULL; | 205 bool select_item = data != NULL; |
206 menu_widget->EnableInput(select_item); | 206 menu_widget->EnableInput(select_item); |
207 } | 207 } |
208 return true; | 208 return true; |
209 } | 209 } |
210 | 210 |
211 void DOMUIMenuWidget::EnableScroll(bool enable) { | 211 void WebUIMenuWidget::EnableScroll(bool enable) { |
212 ExecuteJavascript(StringPrintf( | 212 ExecuteJavascript(StringPrintf( |
213 L"enableScroll(%ls)", enable ? L"true" : L"false")); | 213 L"enableScroll(%ls)", enable ? L"true" : L"false")); |
214 } | 214 } |
215 | 215 |
216 void DOMUIMenuWidget::EnableInput(bool select_item) { | 216 void WebUIMenuWidget::EnableInput(bool select_item) { |
217 if (!dom_view_) | 217 if (!dom_view_) |
218 return; | 218 return; |
219 DCHECK(dom_view_->tab_contents()->render_view_host()); | 219 DCHECK(dom_view_->tab_contents()->render_view_host()); |
220 DCHECK(dom_view_->tab_contents()->render_view_host()->view()); | 220 DCHECK(dom_view_->tab_contents()->render_view_host()->view()); |
221 GtkWidget* target = | 221 GtkWidget* target = |
222 dom_view_->tab_contents()->render_view_host()->view()->GetNativeView(); | 222 dom_view_->tab_contents()->render_view_host()->view()->GetNativeView(); |
223 DCHECK(target); | 223 DCHECK(target); |
224 // Skip if the widget already own the input. | 224 // Skip if the widget already own the input. |
225 if (gtk_grab_get_current() == target) | 225 if (gtk_grab_get_current() == target) |
226 return; | 226 return; |
(...skipping 10 matching lines...) Expand all Loading... | |
237 return; | 237 return; |
238 } | 238 } |
239 | 239 |
240 gtk_grab_add(target); | 240 gtk_grab_add(target); |
241 dom_view_->tab_contents()->Focus(); | 241 dom_view_->tab_contents()->Focus(); |
242 if (select_item) { | 242 if (select_item) { |
243 ExecuteJavascript(L"selectItem()"); | 243 ExecuteJavascript(L"selectItem()"); |
244 } | 244 } |
245 } | 245 } |
246 | 246 |
247 void DOMUIMenuWidget::ExecuteJavascript(const std::wstring& script) { | 247 void WebUIMenuWidget::ExecuteJavascript(const std::wstring& script) { |
248 // Don't exeute there is no DOMView associated. This is fine because | 248 // Don't exeute there is no DOMView associated. This is fine because |
Avi (use Gerrit)
2011/02/03 15:09:05
Fix grammar and spelling: "Don't execute if there
tfarina
2011/02/03 16:37:49
Done.
| |
249 // 1) selectItem make sense only when DOMView is associated. | 249 // 1) selectItem make sense only when DOMView is associated. |
250 // 2) updateModel will be called again when a DOMView is created/assigned. | 250 // 2) updateModel will be called again when a DOMView is created/assigned. |
251 if (!dom_view_) | 251 if (!dom_view_) |
252 return; | 252 return; |
253 | 253 |
254 DCHECK(dom_view_->tab_contents()->render_view_host()); | 254 DCHECK(dom_view_->tab_contents()->render_view_host()); |
255 dom_view_->tab_contents()->render_view_host()-> | 255 dom_view_->tab_contents()->render_view_host()-> |
256 ExecuteJavascriptInWebFrame(std::wstring(), script); | 256 ExecuteJavascriptInWebFrame(std::wstring(), script); |
257 } | 257 } |
258 | 258 |
259 void DOMUIMenuWidget::ShowAt(chromeos::MenuLocator* locator) { | 259 void WebUIMenuWidget::ShowAt(chromeos::MenuLocator* locator) { |
260 DCHECK(domui_menu_); | 260 DCHECK(domui_menu_); |
261 menu_locator_.reset(locator); | 261 menu_locator_.reset(locator); |
262 if (!dom_view_) { | 262 if (!dom_view_) { |
263 // TODO(oshima): Replace DOMView with direct use of RVH for beta. | 263 // TODO(oshima): Replace DOMView with direct use of RVH for beta. |
264 // DOMView should be refactored to use RVH directly, but | 264 // DOMView should be refactored to use RVH directly, but |
265 // it'll require a lot of change and will take time. | 265 // it'll require a lot of change and will take time. |
266 dom_view_ = new DOMView(); | 266 dom_view_ = new DOMView(); |
267 dom_view_->Init(domui_menu_->GetProfile(), NULL); | 267 dom_view_->Init(domui_menu_->GetProfile(), NULL); |
268 // TODO(oshima): remove extra view to draw rounded corner. | 268 // TODO(oshima): remove extra view to draw rounded corner. |
269 views::View* container = new views::View(); | 269 views::View* container = new views::View(); |
270 container->AddChildView(dom_view_); | 270 container->AddChildView(dom_view_); |
271 container->set_border(new RoundedBorder(locator)); | 271 container->set_border(new RoundedBorder(locator)); |
272 container->SetLayoutManager(new InsetsLayout()); | 272 container->SetLayoutManager(new InsetsLayout()); |
273 SetContentsView(container); | 273 SetContentsView(container); |
274 dom_view_->LoadURL(domui_menu_->menu_url()); | 274 dom_view_->LoadURL(domui_menu_->menu_url()); |
275 } else { | 275 } else { |
276 domui_menu_->UpdateStates(); | 276 domui_menu_->UpdateStates(); |
277 dom_view_->GetParent()->set_border(new RoundedBorder(locator)); | 277 dom_view_->GetParent()->set_border(new RoundedBorder(locator)); |
278 menu_locator_->Move(this); | 278 menu_locator_->Move(this); |
279 } | 279 } |
280 Show(); | 280 Show(); |
281 | 281 |
282 // The pointer grab is captured only on the top level menu, | 282 // The pointer grab is captured only on the top level menu, |
283 // all mouse event events are delivered to submenu using gtk_add_grab. | 283 // all mouse event events are delivered to submenu using gtk_add_grab. |
284 if (is_root_) { | 284 if (is_root_) { |
285 CaptureGrab(); | 285 CaptureGrab(); |
286 } | 286 } |
287 } | 287 } |
288 | 288 |
289 void DOMUIMenuWidget::SetSize(const gfx::Size& new_size) { | 289 void WebUIMenuWidget::SetSize(const gfx::Size& new_size) { |
290 DCHECK(domui_menu_); | 290 DCHECK(domui_menu_); |
291 // Ignore the empty new_size request which is called when | 291 // Ignore the empty new_size request which is called when |
292 // menu.html is loaded. | 292 // menu.html is loaded. |
293 if (new_size.IsEmpty()) | 293 if (new_size.IsEmpty()) |
294 return; | 294 return; |
295 int width, height; | 295 int width, height; |
296 gtk_widget_get_size_request(GetNativeView(), &width, &height); | 296 gtk_widget_get_size_request(GetNativeView(), &width, &height); |
297 gfx::Size real_size(std::max(new_size.width(), width), | 297 gfx::Size real_size(std::max(new_size.width(), width), |
298 new_size.height()); | 298 new_size.height()); |
299 // Ignore the size request with the same size. | 299 // Ignore the size request with the same size. |
300 gfx::Rect bounds; | 300 gfx::Rect bounds; |
301 GetBounds(&bounds, false); | 301 GetBounds(&bounds, false); |
302 if (bounds.size() == real_size) | 302 if (bounds.size() == real_size) |
303 return; | 303 return; |
304 menu_locator_->SetBounds(this, real_size); | 304 menu_locator_->SetBounds(this, real_size); |
305 } | 305 } |
306 | 306 |
307 /////////////////////////////////////////////////////////////////////////////// | 307 /////////////////////////////////////////////////////////////////////////////// |
308 // DOMUIMenuWidget private: | 308 // WebUIMenuWidget private: |
309 | 309 |
310 void DOMUIMenuWidget::CaptureGrab() { | 310 void WebUIMenuWidget::CaptureGrab() { |
311 // Release the current grab. | 311 // Release the current grab. |
312 ClearGrabWidget(); | 312 ClearGrabWidget(); |
313 | 313 |
314 // NOTE: we do this to ensure we get mouse/keyboard events from | 314 // NOTE: we do this to ensure we get mouse/keyboard events from |
315 // other apps, a grab done with gtk_grab_add doesn't get events from | 315 // other apps, a grab done with gtk_grab_add doesn't get events from |
316 // other apps. | 316 // other apps. |
317 GdkGrabStatus pointer_grab_status = | 317 GdkGrabStatus pointer_grab_status = |
318 gdk_pointer_grab(window_contents()->window, FALSE, | 318 gdk_pointer_grab(window_contents()->window, FALSE, |
319 static_cast<GdkEventMask>( | 319 static_cast<GdkEventMask>( |
320 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | | 320 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | |
321 GDK_POINTER_MOTION_MASK), | 321 GDK_POINTER_MOTION_MASK), |
322 NULL, NULL, GDK_CURRENT_TIME); | 322 NULL, NULL, GDK_CURRENT_TIME); |
323 GdkGrabStatus keyboard_grab_status = | 323 GdkGrabStatus keyboard_grab_status = |
324 gdk_keyboard_grab(window_contents()->window, FALSE, | 324 gdk_keyboard_grab(window_contents()->window, FALSE, |
325 GDK_CURRENT_TIME); | 325 GDK_CURRENT_TIME); |
326 | 326 |
327 did_input_grab_ = pointer_grab_status == GDK_GRAB_SUCCESS && | 327 did_input_grab_ = pointer_grab_status == GDK_GRAB_SUCCESS && |
328 keyboard_grab_status == GDK_GRAB_SUCCESS; | 328 keyboard_grab_status == GDK_GRAB_SUCCESS; |
329 DCHECK(did_input_grab_); | 329 DCHECK(did_input_grab_); |
330 | 330 |
331 EnableInput(false /* no selection */); | 331 EnableInput(false /* no selection */); |
332 } | 332 } |
333 | 333 |
334 void DOMUIMenuWidget::ClearGrabWidget() { | 334 void WebUIMenuWidget::ClearGrabWidget() { |
335 GtkWidget* grab_widget; | 335 GtkWidget* grab_widget; |
336 while ((grab_widget = gtk_grab_get_current())) | 336 while ((grab_widget = gtk_grab_get_current())) |
337 gtk_grab_remove(grab_widget); | 337 gtk_grab_remove(grab_widget); |
338 } | 338 } |
339 | 339 |
340 } // namespace chromeos | 340 } // namespace chromeos |
OLD | NEW |