Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.cc

Issue 7015051: Re-land: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.h"
6
7 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
8 #include "chrome/browser/tab_contents/web_drag_dest_gtk.h"
9 #include "chrome/browser/ui/gtk/constrained_window_gtk.h"
10 #include "chrome/browser/ui/gtk/tab_contents_drag_source.h"
11 #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_delegate .h"
12 #include "content/browser/tab_contents/tab_contents.h"
13 #include "content/browser/tab_contents/tab_contents_view.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
16
17 using WebKit::WebDragOperation;
18 using WebKit::WebDragOperationsMask;
19 using WebKit::WebInputEvent;
20
21 namespace {
22
23 // Called when the content view gtk widget is tabbed to, or after the call to
24 // gtk_widget_child_focus() in TakeFocus(). We return true
25 // and grab focus if we don't have it. The call to
26 // FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to
27 // webkit.
28 gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus,
29 TabContents* tab_contents) {
30 // If we already have focus, let the next widget have a shot at it. We will
31 // reach this situation after the call to gtk_widget_child_focus() in
32 // TakeFocus().
33 if (gtk_widget_is_focus(widget))
34 return FALSE;
35
36 gtk_widget_grab_focus(widget);
37 bool reverse = focus == GTK_DIR_TAB_BACKWARD;
38 tab_contents->FocusThroughTabTraversal(reverse);
39 return TRUE;
40 }
41
42 // See tab_contents_view_gtk.cc for discussion of mouse scroll zooming.
43 gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
44 internal::NativeTabContentsViewDelegate* delegate) {
45 if ((event->state & gtk_accelerator_get_default_mod_mask()) ==
46 GDK_CONTROL_MASK) {
47 if (event->direction == GDK_SCROLL_DOWN) {
48 delegate->OnNativeTabContentsViewWheelZoom(false);
49 return TRUE;
50 }
51 if (event->direction == GDK_SCROLL_UP) {
52 delegate->OnNativeTabContentsViewWheelZoom(true);
53 return TRUE;
54 }
55 }
56
57 return FALSE;
58 }
59
60 gfx::NativeView GetHiddenTabHostWindow() {
61 static views::Widget* widget = NULL;
62
63 if (!widget) {
64 widget = new views::Widget;
65 // We don't want this widget to be closed automatically, this causes
66 // problems in tests that close the last non-secondary window.
67 widget->set_is_secondary_widget(false);
68 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
69 widget->Init(params);
70 }
71
72 return static_cast<views::WidgetGtk*>(widget->native_widget())->
73 window_contents();
74 }
75
76 } // namespace
77
78 ////////////////////////////////////////////////////////////////////////////////
79 // NativeTabContentsViewGtk, public:
80
81 NativeTabContentsViewGtk::NativeTabContentsViewGtk(
82 internal::NativeTabContentsViewDelegate* delegate)
83 : views::WidgetGtk(delegate->AsNativeWidgetDelegate()),
84 delegate_(delegate),
85 ignore_next_char_event_(false),
86 ALLOW_THIS_IN_INITIALIZER_LIST(drag_source_(
87 new TabContentsDragSource(delegate->GetTabContents()->view()))) {
88 }
89
90 NativeTabContentsViewGtk::~NativeTabContentsViewGtk() {
91 delegate_ = NULL;
92 CloseNow();
93 }
94
95 void NativeTabContentsViewGtk::AttachConstrainedWindow(
96 ConstrainedWindowGtk* constrained_window) {
97 DCHECK(find(constrained_windows_.begin(), constrained_windows_.end(),
98 constrained_window) == constrained_windows_.end());
99
100 constrained_windows_.push_back(constrained_window);
101 AddChild(constrained_window->widget());
102
103 gfx::Size requested_size;
104 views::WidgetGtk::GetRequestedSize(&requested_size);
105 PositionConstrainedWindows(requested_size);
106 }
107
108 void NativeTabContentsViewGtk::RemoveConstrainedWindow(
109 ConstrainedWindowGtk* constrained_window) {
110 std::vector<ConstrainedWindowGtk*>::iterator item =
111 find(constrained_windows_.begin(), constrained_windows_.end(),
112 constrained_window);
113 DCHECK(item != constrained_windows_.end());
114 RemoveChild((*item)->widget());
115 constrained_windows_.erase(item);
116 }
117
118 ////////////////////////////////////////////////////////////////////////////////
119 // NativeTabContentsViewGtk, NativeTabContentsView implementation:
120
121 void NativeTabContentsViewGtk::InitNativeTabContentsView() {
122 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
123 params.native_widget = this;
124 params.delete_on_destroy = false;
125 GetWidget()->Init(params);
126
127 // We need to own the widget in order to attach/detach the native view to a
128 // container.
129 gtk_object_ref(GTK_OBJECT(GetWidget()->GetNativeView()));
130 }
131
132 void NativeTabContentsViewGtk::Unparent() {
133 // Note that we do not DCHECK on focus_manager_ as it may be NULL when used
134 // with an external tab container.
135 NativeWidget::ReparentNativeView(GetNativeView(), GetHiddenTabHostWindow());
136 }
137
138 RenderWidgetHostView* NativeTabContentsViewGtk::CreateRenderWidgetHostView(
139 RenderWidgetHost* render_widget_host) {
140 RenderWidgetHostViewGtk* view =
141 new RenderWidgetHostViewGtk(render_widget_host);
142 view->InitAsChild();
143 g_signal_connect(view->native_view(), "focus",
144 G_CALLBACK(OnFocus), delegate_->GetTabContents());
145 g_signal_connect(view->native_view(), "scroll-event",
146 G_CALLBACK(OnMouseScroll), delegate_);
147
148 // Let widget know that the tab contents has been painted.
149 views::WidgetGtk::RegisterChildExposeHandler(view->native_view());
150
151 // Renderer target DnD.
152 if (delegate_->GetTabContents()->ShouldAcceptDragAndDrop())
153 drag_dest_.reset(new WebDragDestGtk(delegate_->GetTabContents(),
154 view->native_view()));
155
156 gtk_fixed_put(GTK_FIXED(GetWidget()->GetNativeView()), view->native_view(), 0,
157 0);
158 return view;
159 }
160
161 gfx::NativeWindow NativeTabContentsViewGtk::GetTopLevelNativeWindow() const {
162 GtkWidget* window = gtk_widget_get_ancestor(GetWidget()->GetNativeView(),
163 GTK_TYPE_WINDOW);
164 return window ? GTK_WINDOW(window) : NULL;
165 }
166
167 void NativeTabContentsViewGtk::SetPageTitle(const std::wstring& title) {
168 // Set the window name to include the page title so it's easier to spot
169 // when debugging (e.g. via xwininfo -tree).
170 if (GDK_IS_WINDOW(GetNativeView()->window))
171 gdk_window_set_title(GetNativeView()->window, WideToUTF8(title).c_str());
172 }
173
174 void NativeTabContentsViewGtk::StartDragging(const WebDropData& drop_data,
175 WebKit::WebDragOperationsMask ops,
176 const SkBitmap& image,
177 const gfx::Point& image_offset) {
178 drag_source_->StartDragging(drop_data, ops, &last_mouse_down_,
179 image, image_offset);
180 }
181
182 void NativeTabContentsViewGtk::CancelDrag() {
183 }
184
185 bool NativeTabContentsViewGtk::IsDoingDrag() const {
186 return false;
187 }
188
189 void NativeTabContentsViewGtk::SetDragCursor(
190 WebKit::WebDragOperation operation) {
191 if (drag_dest_.get())
192 drag_dest_->UpdateDragStatus(operation);
193 }
194
195 views::NativeWidget* NativeTabContentsViewGtk::AsNativeWidget() {
196 return this;
197 }
198
199 ////////////////////////////////////////////////////////////////////////////////
200 // NativeTabContentsViewGtk, views::WidgetGtk overrides:
201
202 // Called when the mouse moves within the widget. We notify SadTabView if it's
203 // not NULL, else our delegate.
204 gboolean NativeTabContentsViewGtk::OnMotionNotify(GtkWidget* widget,
205 GdkEventMotion* event) {
206 if (delegate_->IsShowingSadTab())
207 return views::WidgetGtk::OnMotionNotify(widget, event);
208
209 delegate_->OnNativeTabContentsViewMouseMove(true);
210 return FALSE;
211 }
212
213 gboolean NativeTabContentsViewGtk::OnLeaveNotify(GtkWidget* widget,
214 GdkEventCrossing* event) {
215 if (delegate_->IsShowingSadTab())
216 return views::WidgetGtk::OnLeaveNotify(widget, event);
217
218 delegate_->OnNativeTabContentsViewMouseMove(false);
219 return FALSE;
220 }
221
222 gboolean NativeTabContentsViewGtk::OnButtonPress(GtkWidget* widget,
223 GdkEventButton* event) {
224 if (delegate_->IsShowingSadTab())
225 return views::WidgetGtk::OnButtonPress(widget, event);
226 last_mouse_down_ = *event;
227 return views::WidgetGtk::OnButtonPress(widget, event);
228 }
229
230 void NativeTabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
231 GtkAllocation* allocation) {
232 gfx::Size size(allocation->width, allocation->height);
233 delegate_->OnNativeTabContentsViewSized(size);
234 if (size != size_)
235 PositionConstrainedWindows(size);
236 size_ = size;
237 views::WidgetGtk::OnSizeAllocate(widget, allocation);
238 }
239
240 void NativeTabContentsViewGtk::OnShow(GtkWidget* widget) {
241 delegate_->OnNativeTabContentsViewShown();
242 views::WidgetGtk::OnShow(widget);
243 }
244
245 void NativeTabContentsViewGtk::OnHide(GtkWidget* widget) {
246 // OnHide can be called during widget destruction (gtk_widget_dispose calls
247 // gtk_widget_hide) so we make sure we do not call back through to the
248 // delegate after it's already deleted.
249 if (delegate_)
250 delegate_->OnNativeTabContentsViewHidden();
251 views::WidgetGtk::OnHide(widget);
252 }
253
254 ////////////////////////////////////////////////////////////////////////////////
255 // NativeTabContentsViewGtk, private:
256
257 void NativeTabContentsViewGtk::PositionConstrainedWindows(
258 const gfx::Size& view_size) {
259 // Place each ConstrainedWindow in the center of the view.
260 int half_view_width = view_size.width() / 2;
261
262 typedef std::vector<ConstrainedWindowGtk*>::iterator iterator;
263
264 for (iterator f = constrained_windows_.begin(),
265 l = constrained_windows_.end(); f != l; ++f) {
266 GtkWidget* widget = (*f)->widget();
267
268 GtkRequisition requisition;
269 gtk_widget_size_request(widget, &requisition);
270
271 int child_x = std::max(half_view_width - (requisition.width / 2), 0);
272 PositionChild(widget, child_x, 0, 0, 0);
273 }
274 }
275
276 ////////////////////////////////////////////////////////////////////////////////
277 // NativeTabContentsView, public:
278
279 // static
280 NativeTabContentsView* NativeTabContentsView::CreateNativeTabContentsView(
281 internal::NativeTabContentsViewDelegate* delegate) {
282 return new NativeTabContentsViewGtk(delegate);
283 }
284
285 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
286 // Use of this source code is governed by a BSD-style license that can be
287 // found in the LICENSE file.
288
289 #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.h"
290
291 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
292 #include "chrome/browser/tab_contents/web_drag_dest_gtk.h"
293 #include "chrome/browser/ui/gtk/constrained_window_gtk.h"
294 #include "chrome/browser/ui/gtk/tab_contents_drag_source.h"
295 #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_delegate .h"
296 #include "content/browser/tab_contents/tab_contents.h"
297 #include "content/browser/tab_contents/tab_contents_view.h"
298 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
299 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
300
301 using WebKit::WebDragOperation;
302 using WebKit::WebDragOperationsMask;
303 using WebKit::WebInputEvent;
304
305 namespace {
306
307 // Called when the content view gtk widget is tabbed to, or after the call to
308 // gtk_widget_child_focus() in TakeFocus(). We return true
309 // and grab focus if we don't have it. The call to
310 // FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to
311 // webkit.
312 gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus,
313 TabContents* tab_contents) {
314 // If we already have focus, let the next widget have a shot at it. We will
315 // reach this situation after the call to gtk_widget_child_focus() in
316 // TakeFocus().
317 if (gtk_widget_is_focus(widget))
318 return FALSE;
319
320 gtk_widget_grab_focus(widget);
321 bool reverse = focus == GTK_DIR_TAB_BACKWARD;
322 tab_contents->FocusThroughTabTraversal(reverse);
323 return TRUE;
324 }
325
326 // See tab_contents_view_gtk.cc for discussion of mouse scroll zooming.
327 gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
328 internal::NativeTabContentsViewDelegate* delegate) {
329 if ((event->state & gtk_accelerator_get_default_mod_mask()) ==
330 GDK_CONTROL_MASK) {
331 if (event->direction == GDK_SCROLL_DOWN) {
332 delegate->OnNativeTabContentsViewWheelZoom(false);
333 return TRUE;
334 }
335 if (event->direction == GDK_SCROLL_UP) {
336 delegate->OnNativeTabContentsViewWheelZoom(true);
337 return TRUE;
338 }
339 }
340
341 return FALSE;
342 }
343
344 gfx::NativeView GetHiddenTabHostWindow() {
345 static views::Widget* widget = NULL;
346
347 if (!widget) {
348 widget = new views::Widget;
349 // We don't want this widget to be closed automatically, this causes
350 // problems in tests that close the last non-secondary window.
351 widget->set_is_secondary_widget(false);
352 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
353 widget->Init(params);
354 }
355
356 return static_cast<views::WidgetGtk*>(widget->native_widget())->
357 window_contents();
358 }
359
360 } // namespace
361
362 ////////////////////////////////////////////////////////////////////////////////
363 // NativeTabContentsViewGtk, public:
364
365 NativeTabContentsViewGtk::NativeTabContentsViewGtk(
366 internal::NativeTabContentsViewDelegate* delegate)
367 : views::WidgetGtk(delegate->AsNativeWidgetDelegate()),
368 delegate_(delegate),
369 ignore_next_char_event_(false),
370 ALLOW_THIS_IN_INITIALIZER_LIST(drag_source_(
371 new TabContentsDragSource(delegate->GetTabContents()->view()))) {
372 }
373
374 NativeTabContentsViewGtk::~NativeTabContentsViewGtk() {
375 delegate_ = NULL;
376 CloseNow();
377 }
378
379 void NativeTabContentsViewGtk::AttachConstrainedWindow(
380 ConstrainedWindowGtk* constrained_window) {
381 DCHECK(find(constrained_windows_.begin(), constrained_windows_.end(),
382 constrained_window) == constrained_windows_.end());
383
384 constrained_windows_.push_back(constrained_window);
385 AddChild(constrained_window->widget());
386
387 gfx::Size requested_size;
388 views::WidgetGtk::GetRequestedSize(&requested_size);
389 PositionConstrainedWindows(requested_size);
390 }
391
392 void NativeTabContentsViewGtk::RemoveConstrainedWindow(
393 ConstrainedWindowGtk* constrained_window) {
394 std::vector<ConstrainedWindowGtk*>::iterator item =
395 find(constrained_windows_.begin(), constrained_windows_.end(),
396 constrained_window);
397 DCHECK(item != constrained_windows_.end());
398 RemoveChild((*item)->widget());
399 constrained_windows_.erase(item);
400 }
401
402 ////////////////////////////////////////////////////////////////////////////////
403 // NativeTabContentsViewGtk, NativeTabContentsView implementation:
404
405 void NativeTabContentsViewGtk::InitNativeTabContentsView() {
406 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
407 params.native_widget = this;
408 params.delete_on_destroy = false;
409 GetWidget()->Init(params);
410
411 // We need to own the widget in order to attach/detach the native view to a
412 // container.
413 gtk_object_ref(GTK_OBJECT(GetWidget()->GetNativeView()));
414 }
415
416 void NativeTabContentsViewGtk::Unparent() {
417 // Note that we do not DCHECK on focus_manager_ as it may be NULL when used
418 // with an external tab container.
419 NativeWidget::ReparentNativeView(GetNativeView(), GetHiddenTabHostWindow());
420 }
421
422 RenderWidgetHostView* NativeTabContentsViewGtk::CreateRenderWidgetHostView(
423 RenderWidgetHost* render_widget_host) {
424 RenderWidgetHostViewGtk* view =
425 new RenderWidgetHostViewGtk(render_widget_host);
426 view->InitAsChild();
427 g_signal_connect(view->native_view(), "focus",
428 G_CALLBACK(OnFocus), delegate_->GetTabContents());
429 g_signal_connect(view->native_view(), "scroll-event",
430 G_CALLBACK(OnMouseScroll), delegate_);
431
432 // Let widget know that the tab contents has been painted.
433 views::WidgetGtk::RegisterChildExposeHandler(view->native_view());
434
435 // Renderer target DnD.
436 if (delegate_->GetTabContents()->ShouldAcceptDragAndDrop())
437 drag_dest_.reset(new WebDragDestGtk(delegate_->GetTabContents(),
438 view->native_view()));
439
440 gtk_fixed_put(GTK_FIXED(GetWidget()->GetNativeView()), view->native_view(), 0,
441 0);
442 return view;
443 }
444
445 gfx::NativeWindow NativeTabContentsViewGtk::GetTopLevelNativeWindow() const {
446 GtkWidget* window = gtk_widget_get_ancestor(GetWidget()->GetNativeView(),
447 GTK_TYPE_WINDOW);
448 return window ? GTK_WINDOW(window) : NULL;
449 }
450
451 void NativeTabContentsViewGtk::SetPageTitle(const std::wstring& title) {
452 // Set the window name to include the page title so it's easier to spot
453 // when debugging (e.g. via xwininfo -tree).
454 if (GDK_IS_WINDOW(GetNativeView()->window))
455 gdk_window_set_title(GetNativeView()->window, WideToUTF8(title).c_str());
456 }
457
458 void NativeTabContentsViewGtk::StartDragging(const WebDropData& drop_data,
459 WebKit::WebDragOperationsMask ops,
460 const SkBitmap& image,
461 const gfx::Point& image_offset) {
462 drag_source_->StartDragging(drop_data, ops, &last_mouse_down_,
463 image, image_offset);
464 }
465
466 void NativeTabContentsViewGtk::CancelDrag() {
467 }
468
469 bool NativeTabContentsViewGtk::IsDoingDrag() const {
470 return false;
471 }
472
473 void NativeTabContentsViewGtk::SetDragCursor(
474 WebKit::WebDragOperation operation) {
475 if (drag_dest_.get())
476 drag_dest_->UpdateDragStatus(operation);
477 }
478
479 views::NativeWidget* NativeTabContentsViewGtk::AsNativeWidget() {
480 return this;
481 }
482
483 ////////////////////////////////////////////////////////////////////////////////
484 // NativeTabContentsViewGtk, views::WidgetGtk overrides:
485
486 // Called when the mouse moves within the widget. We notify SadTabView if it's
487 // not NULL, else our delegate.
488 gboolean NativeTabContentsViewGtk::OnMotionNotify(GtkWidget* widget,
489 GdkEventMotion* event) {
490 if (delegate_->IsShowingSadTab())
491 return views::WidgetGtk::OnMotionNotify(widget, event);
492
493 delegate_->OnNativeTabContentsViewMouseMove(true);
494 return FALSE;
495 }
496
497 gboolean NativeTabContentsViewGtk::OnLeaveNotify(GtkWidget* widget,
498 GdkEventCrossing* event) {
499 if (delegate_->IsShowingSadTab())
500 return views::WidgetGtk::OnLeaveNotify(widget, event);
501
502 delegate_->OnNativeTabContentsViewMouseMove(false);
503 return FALSE;
504 }
505
506 gboolean NativeTabContentsViewGtk::OnButtonPress(GtkWidget* widget,
507 GdkEventButton* event) {
508 if (delegate_->IsShowingSadTab())
509 return views::WidgetGtk::OnButtonPress(widget, event);
510 last_mouse_down_ = *event;
511 return views::WidgetGtk::OnButtonPress(widget, event);
512 }
513
514 void NativeTabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
515 GtkAllocation* allocation) {
516 gfx::Size size(allocation->width, allocation->height);
517 delegate_->OnNativeTabContentsViewSized(size);
518 if (size != size_)
519 PositionConstrainedWindows(size);
520 size_ = size;
521 views::WidgetGtk::OnSizeAllocate(widget, allocation);
522 }
523
524 void NativeTabContentsViewGtk::OnShow(GtkWidget* widget) {
525 delegate_->OnNativeTabContentsViewShown();
526 views::WidgetGtk::OnShow(widget);
527 }
528
529 void NativeTabContentsViewGtk::OnHide(GtkWidget* widget) {
530 // OnHide can be called during widget destruction (gtk_widget_dispose calls
531 // gtk_widget_hide) so we make sure we do not call back through to the
532 // delegate after it's already deleted.
533 if (delegate_)
534 delegate_->OnNativeTabContentsViewHidden();
535 views::WidgetGtk::OnHide(widget);
536 }
537
538 ////////////////////////////////////////////////////////////////////////////////
539 // NativeTabContentsViewGtk, private:
540
541 void NativeTabContentsViewGtk::PositionConstrainedWindows(
542 const gfx::Size& view_size) {
543 // Place each ConstrainedWindow in the center of the view.
544 int half_view_width = view_size.width() / 2;
545
546 typedef std::vector<ConstrainedWindowGtk*>::iterator iterator;
547
548 for (iterator f = constrained_windows_.begin(),
549 l = constrained_windows_.end(); f != l; ++f) {
550 GtkWidget* widget = (*f)->widget();
551
552 GtkRequisition requisition;
553 gtk_widget_size_request(widget, &requisition);
554
555 int child_x = std::max(half_view_width - (requisition.width / 2), 0);
556 PositionChild(widget, child_x, 0, 0, 0);
557 }
558 }
559
560 ////////////////////////////////////////////////////////////////////////////////
561 // NativeTabContentsView, public:
562
563 // static
564 NativeTabContentsView* NativeTabContentsView::CreateNativeTabContentsView(
565 internal::NativeTabContentsViewDelegate* delegate) {
566 return new NativeTabContentsViewGtk(delegate);
567 }
568
569 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
570 // Use of this source code is governed by a BSD-style license that can be
571 // found in the LICENSE file.
572
573 #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.h"
574
575 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
576 #include "chrome/browser/tab_contents/web_drag_dest_gtk.h"
577 #include "chrome/browser/ui/gtk/constrained_window_gtk.h"
578 #include "chrome/browser/ui/gtk/tab_contents_drag_source.h"
579 #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_delegate .h"
580 #include "content/browser/tab_contents/tab_contents.h"
581 #include "content/browser/tab_contents/tab_contents_view.h"
582 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
583 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
584
585 using WebKit::WebDragOperation;
586 using WebKit::WebDragOperationsMask;
587 using WebKit::WebInputEvent;
588
589 namespace {
590
591 /*
592 // Called when the content view gtk widget is tabbed to, or after the call to
593 // gtk_widget_child_focus() in TakeFocus(). We return true
594 // and grab focus if we don't have it. The call to
595 // FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to
596 // webkit.
597 gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus,
598 TabContents* tab_contents) {
599 // If we already have focus, let the next widget have a shot at it. We will
600 // reach this situation after the call to gtk_widget_child_focus() in
601 // TakeFocus().
602 if (gtk_widget_is_focus(widget))
603 return FALSE;
604
605 gtk_widget_grab_focus(widget);
606 bool reverse = focus == GTK_DIR_TAB_BACKWARD;
607 tab_contents->FocusThroughTabTraversal(reverse);
608 return TRUE;
609 }
610
611 // Called when the mouse leaves the widget. We notify our delegate.
612 // WidgetGtk also defines OnLeaveNotify, so we use the name OnLeaveNotify2
613 // here.
614 gboolean OnLeaveNotify2(GtkWidget* widget, GdkEventCrossing* event,
615 TabContents* tab_contents) {
616 if (tab_contents->delegate())
617 tab_contents->delegate()->ContentsMouseEvent(
618 tab_contents, views::Screen::GetCursorScreenPoint(), false);
619 return FALSE;
620 }
621
622 // Called when the mouse moves within the widget.
623 gboolean CallMouseMove(GtkWidget* widget, GdkEventMotion* event,
624 TabContentsViewGtk* tab_contents_view) {
625 return tab_contents_view->OnMouseMove(widget, event);
626 }
627
628 // See tab_contents_view_gtk.cc for discussion of mouse scroll zooming.
629 gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
630 TabContents* tab_contents) {
631 if ((event->state & gtk_accelerator_get_default_mod_mask()) ==
632 GDK_CONTROL_MASK) {
633 if (tab_contents->delegate()) {
634 if (event->direction == GDK_SCROLL_DOWN) {
635 tab_contents->delegate()->ContentsZoomChange(false);
636 return TRUE;
637 } else if (event->direction == GDK_SCROLL_UP) {
638 tab_contents->delegate()->ContentsZoomChange(true);
639 return TRUE;
640 }
641 }
642 }
643
644 return FALSE;
645 }
646 */
647
648 } // namespace
649
650 ////////////////////////////////////////////////////////////////////////////////
651 // NativeTabContentsViewGtk, public:
652
653 NativeTabContentsViewGtk::NativeTabContentsViewGtk(
654 internal::NativeTabContentsViewDelegate* delegate)
655 : views::WidgetGtk(delegate->AsNativeWidgetDelegate()),
656 delegate_(delegate),
657 ignore_next_char_event_(false),
658 ALLOW_THIS_IN_INITIALIZER_LIST(drag_source_(
659 new TabContentsDragSource(delegate->GetTabContents()->view()))) {
660 }
661
662 NativeTabContentsViewGtk::~NativeTabContentsViewGtk() {
663 CloseNow();
664 }
665
666 void NativeTabContentsViewGtk::AttachConstrainedWindow(
667 ConstrainedWindowGtk* constrained_window) {
668 DCHECK(find(constrained_windows_.begin(), constrained_windows_.end(),
669 constrained_window) == constrained_windows_.end());
670
671 constrained_windows_.push_back(constrained_window);
672 AddChild(constrained_window->widget());
673
674 gfx::Size requested_size;
675 views::WidgetGtk::GetRequestedSize(&requested_size);
676 PositionConstrainedWindows(requested_size);
677 }
678
679 void NativeTabContentsViewGtk::RemoveConstrainedWindow(
680 ConstrainedWindowGtk* constrained_window) {
681 std::vector<ConstrainedWindowGtk*>::iterator item =
682 find(constrained_windows_.begin(), constrained_windows_.end(),
683 constrained_window);
684 DCHECK(item != constrained_windows_.end());
685 RemoveChild((*item)->widget());
686 constrained_windows_.erase(item);
687 }
688
689 ////////////////////////////////////////////////////////////////////////////////
690 // NativeTabContentsViewGtk, NativeTabContentsView implementation:
691
692 void NativeTabContentsViewGtk::InitNativeTabContentsView() {
693 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
694 params.native_widget = this;
695 params.delete_on_destroy = false;
696 GetWidget()->Init(params);
697
698 // We need to own the widget in order to attach/detach the native view to a
699 // container.
700 gtk_object_ref(GTK_OBJECT(GetWidget()->GetNativeView()));
701 }
702
703 void NativeTabContentsViewGtk::Unparent() {
704 }
705
706 RenderWidgetHostView* NativeTabContentsViewGtk::CreateRenderWidgetHostView(
707 RenderWidgetHost* render_widget_host) {
708 RenderWidgetHostViewGtk* view =
709 new RenderWidgetHostViewGtk(render_widget_host);
710 view->InitAsChild();
711 /*
712 g_signal_connect(view->native_view(), "focus",
713 G_CALLBACK(OnFocus), delegate_->GetTabContents());
714 g_signal_connect(view->native_view(), "leave-notify-event",
715 G_CALLBACK(OnLeaveNotify2), delegate_->GetTabContents());
716 g_signal_connect(view->native_view(), "motion-notify-event",
717 G_CALLBACK(CallMouseMove), this);
718 g_signal_connect(view->native_view(), "scroll-event",
719 G_CALLBACK(OnMouseScroll), delegate_->GetTabContents());
720 */
721 gtk_widget_add_events(view->native_view(), GDK_LEAVE_NOTIFY_MASK |
722 GDK_POINTER_MOTION_MASK);
723
724 // Let widget know that the tab contents has been painted.
725 views::WidgetGtk::RegisterChildExposeHandler(view->native_view());
726
727 // Renderer target DnD.
728 if (delegate_->GetTabContents()->ShouldAcceptDragAndDrop())
729 drag_dest_.reset(new WebDragDestGtk(delegate_->GetTabContents(),
730 view->native_view()));
731
732 gtk_fixed_put(GTK_FIXED(GetWidget()->GetNativeView()), view->native_view(), 0,
733 0);
734 return view;
735 }
736
737 gfx::NativeWindow NativeTabContentsViewGtk::GetTopLevelNativeWindow() const {
738 GtkWidget* window = gtk_widget_get_ancestor(GetWidget()->GetNativeView(),
739 GTK_TYPE_WINDOW);
740 return window ? GTK_WINDOW(window) : NULL;
741 }
742
743 void NativeTabContentsViewGtk::SetPageTitle(const std::wstring& title) {
744 // Set the window name to include the page title so it's easier to spot
745 // when debugging (e.g. via xwininfo -tree).
746 gdk_window_set_title(GetNativeView()->window, WideToUTF8(title).c_str());
747 }
748
749 void NativeTabContentsViewGtk::StartDragging(const WebDropData& drop_data,
750 WebKit::WebDragOperationsMask ops,
751 const SkBitmap& image,
752 const gfx::Point& image_offset) {
753 drag_source_->StartDragging(drop_data, ops, &last_mouse_down_,
754 image, image_offset);
755 }
756
757 void NativeTabContentsViewGtk::CancelDrag() {
758 }
759
760 bool NativeTabContentsViewGtk::IsDoingDrag() const {
761 return false;
762 }
763
764 void NativeTabContentsViewGtk::SetDragCursor(
765 WebKit::WebDragOperation operation) {
766 if (drag_dest_.get())
767 drag_dest_->UpdateDragStatus(operation);
768 }
769
770 views::NativeWidget* NativeTabContentsViewGtk::AsNativeWidget() {
771 return this;
772 }
773
774 ////////////////////////////////////////////////////////////////////////////////
775 // NativeTabContentsViewGtk, views::WidgetGtk overrides:
776
777 // Called when the mouse moves within the widget. We notify SadTabView if it's
778 // not NULL, else our delegate.
779 gboolean NativeTabContentsViewGtk::OnMotionNotify(GtkWidget* widget,
780 GdkEventMotion* event) {
781 if (delegate_->IsShowingSadTab())
782 return views::WidgetGtk::OnMotionNotify(widget, event);
783
784 delegate_->OnNativeTabContentsViewMouseMove();
785 return FALSE;
786 }
787
788 gboolean NativeTabContentsViewGtk::OnButtonPress(GtkWidget* widget,
789 GdkEventButton* event) {
790 if (delegate_->IsShowingSadTab())
791 return views::WidgetGtk::OnButtonPress(widget, event);
792 last_mouse_down_ = *event;
793 return views::WidgetGtk::OnButtonPress(widget, event);
794 }
795
796 void NativeTabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
797 GtkAllocation* allocation) {
798 gfx::Size size(allocation->width, allocation->height);
799 delegate_->OnNativeTabContentsViewSized(size);
800 if (size != size_)
801 PositionConstrainedWindows(size);
802 size_ = size;
803 views::WidgetGtk::OnSizeAllocate(widget, allocation);
804 }
805
806 void NativeTabContentsViewGtk::OnShow(GtkWidget* widget) {
807 delegate_->OnNativeTabContentsViewShown();
808 views::WidgetGtk::OnShow(widget);
809 }
810
811 void NativeTabContentsViewGtk::OnHide(GtkWidget* widget) {
812 delegate_->OnNativeTabContentsViewHidden();
813 views::WidgetGtk::OnHide(widget);
814 }
815
816 ////////////////////////////////////////////////////////////////////////////////
817 // NativeTabContentsViewGtk, private:
818
819 void NativeTabContentsViewGtk::PositionConstrainedWindows(
820 const gfx::Size& view_size) {
821 // Place each ConstrainedWindow in the center of the view.
822 int half_view_width = view_size.width() / 2;
823
824 typedef std::vector<ConstrainedWindowGtk*>::iterator iterator;
825
826 for (iterator f = constrained_windows_.begin(),
827 l = constrained_windows_.end(); f != l; ++f) {
828 GtkWidget* widget = (*f)->widget();
829
830 GtkRequisition requisition;
831 gtk_widget_size_request(widget, &requisition);
832
833 int child_x = std::max(half_view_width - (requisition.width / 2), 0);
834 PositionChild(widget, child_x, 0, 0, 0);
835 }
836 }
837
838 ////////////////////////////////////////////////////////////////////////////////
839 // NativeTabContentsView, public:
840
841 // static
842 NativeTabContentsView* NativeTabContentsView::CreateNativeTabContentsView(
843 internal::NativeTabContentsViewDelegate* delegate) {
844 return new NativeTabContentsViewGtk(delegate);
845 }
846
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698