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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.cc
===================================================================
--- chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.cc (revision 0)
+++ chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.cc (revision 0)
@@ -0,0 +1,846 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.h"
+
+#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
+#include "chrome/browser/tab_contents/web_drag_dest_gtk.h"
+#include "chrome/browser/ui/gtk/constrained_window_gtk.h"
+#include "chrome/browser/ui/gtk/tab_contents_drag_source.h"
+#include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_delegate.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/browser/tab_contents/tab_contents_view.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
+
+using WebKit::WebDragOperation;
+using WebKit::WebDragOperationsMask;
+using WebKit::WebInputEvent;
+
+namespace {
+
+// Called when the content view gtk widget is tabbed to, or after the call to
+// gtk_widget_child_focus() in TakeFocus(). We return true
+// and grab focus if we don't have it. The call to
+// FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to
+// webkit.
+gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus,
+ TabContents* tab_contents) {
+ // If we already have focus, let the next widget have a shot at it. We will
+ // reach this situation after the call to gtk_widget_child_focus() in
+ // TakeFocus().
+ if (gtk_widget_is_focus(widget))
+ return FALSE;
+
+ gtk_widget_grab_focus(widget);
+ bool reverse = focus == GTK_DIR_TAB_BACKWARD;
+ tab_contents->FocusThroughTabTraversal(reverse);
+ return TRUE;
+}
+
+// See tab_contents_view_gtk.cc for discussion of mouse scroll zooming.
+gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
+ internal::NativeTabContentsViewDelegate* delegate) {
+ if ((event->state & gtk_accelerator_get_default_mod_mask()) ==
+ GDK_CONTROL_MASK) {
+ if (event->direction == GDK_SCROLL_DOWN) {
+ delegate->OnNativeTabContentsViewWheelZoom(false);
+ return TRUE;
+ }
+ if (event->direction == GDK_SCROLL_UP) {
+ delegate->OnNativeTabContentsViewWheelZoom(true);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+gfx::NativeView GetHiddenTabHostWindow() {
+ static views::Widget* widget = NULL;
+
+ if (!widget) {
+ widget = new views::Widget;
+ // We don't want this widget to be closed automatically, this causes
+ // problems in tests that close the last non-secondary window.
+ widget->set_is_secondary_widget(false);
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
+ widget->Init(params);
+ }
+
+ return static_cast<views::WidgetGtk*>(widget->native_widget())->
+ window_contents();
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, public:
+
+NativeTabContentsViewGtk::NativeTabContentsViewGtk(
+ internal::NativeTabContentsViewDelegate* delegate)
+ : views::WidgetGtk(delegate->AsNativeWidgetDelegate()),
+ delegate_(delegate),
+ ignore_next_char_event_(false),
+ ALLOW_THIS_IN_INITIALIZER_LIST(drag_source_(
+ new TabContentsDragSource(delegate->GetTabContents()->view()))) {
+}
+
+NativeTabContentsViewGtk::~NativeTabContentsViewGtk() {
+ delegate_ = NULL;
+ CloseNow();
+}
+
+void NativeTabContentsViewGtk::AttachConstrainedWindow(
+ ConstrainedWindowGtk* constrained_window) {
+ DCHECK(find(constrained_windows_.begin(), constrained_windows_.end(),
+ constrained_window) == constrained_windows_.end());
+
+ constrained_windows_.push_back(constrained_window);
+ AddChild(constrained_window->widget());
+
+ gfx::Size requested_size;
+ views::WidgetGtk::GetRequestedSize(&requested_size);
+ PositionConstrainedWindows(requested_size);
+}
+
+void NativeTabContentsViewGtk::RemoveConstrainedWindow(
+ ConstrainedWindowGtk* constrained_window) {
+ std::vector<ConstrainedWindowGtk*>::iterator item =
+ find(constrained_windows_.begin(), constrained_windows_.end(),
+ constrained_window);
+ DCHECK(item != constrained_windows_.end());
+ RemoveChild((*item)->widget());
+ constrained_windows_.erase(item);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, NativeTabContentsView implementation:
+
+void NativeTabContentsViewGtk::InitNativeTabContentsView() {
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
+ params.native_widget = this;
+ params.delete_on_destroy = false;
+ GetWidget()->Init(params);
+
+ // We need to own the widget in order to attach/detach the native view to a
+ // container.
+ gtk_object_ref(GTK_OBJECT(GetWidget()->GetNativeView()));
+}
+
+void NativeTabContentsViewGtk::Unparent() {
+ // Note that we do not DCHECK on focus_manager_ as it may be NULL when used
+ // with an external tab container.
+ NativeWidget::ReparentNativeView(GetNativeView(), GetHiddenTabHostWindow());
+}
+
+RenderWidgetHostView* NativeTabContentsViewGtk::CreateRenderWidgetHostView(
+ RenderWidgetHost* render_widget_host) {
+ RenderWidgetHostViewGtk* view =
+ new RenderWidgetHostViewGtk(render_widget_host);
+ view->InitAsChild();
+ g_signal_connect(view->native_view(), "focus",
+ G_CALLBACK(OnFocus), delegate_->GetTabContents());
+ g_signal_connect(view->native_view(), "scroll-event",
+ G_CALLBACK(OnMouseScroll), delegate_);
+
+ // Let widget know that the tab contents has been painted.
+ views::WidgetGtk::RegisterChildExposeHandler(view->native_view());
+
+ // Renderer target DnD.
+ if (delegate_->GetTabContents()->ShouldAcceptDragAndDrop())
+ drag_dest_.reset(new WebDragDestGtk(delegate_->GetTabContents(),
+ view->native_view()));
+
+ gtk_fixed_put(GTK_FIXED(GetWidget()->GetNativeView()), view->native_view(), 0,
+ 0);
+ return view;
+}
+
+gfx::NativeWindow NativeTabContentsViewGtk::GetTopLevelNativeWindow() const {
+ GtkWidget* window = gtk_widget_get_ancestor(GetWidget()->GetNativeView(),
+ GTK_TYPE_WINDOW);
+ return window ? GTK_WINDOW(window) : NULL;
+}
+
+void NativeTabContentsViewGtk::SetPageTitle(const std::wstring& title) {
+ // Set the window name to include the page title so it's easier to spot
+ // when debugging (e.g. via xwininfo -tree).
+ if (GDK_IS_WINDOW(GetNativeView()->window))
+ gdk_window_set_title(GetNativeView()->window, WideToUTF8(title).c_str());
+}
+
+void NativeTabContentsViewGtk::StartDragging(const WebDropData& drop_data,
+ WebKit::WebDragOperationsMask ops,
+ const SkBitmap& image,
+ const gfx::Point& image_offset) {
+ drag_source_->StartDragging(drop_data, ops, &last_mouse_down_,
+ image, image_offset);
+}
+
+void NativeTabContentsViewGtk::CancelDrag() {
+}
+
+bool NativeTabContentsViewGtk::IsDoingDrag() const {
+ return false;
+}
+
+void NativeTabContentsViewGtk::SetDragCursor(
+ WebKit::WebDragOperation operation) {
+ if (drag_dest_.get())
+ drag_dest_->UpdateDragStatus(operation);
+}
+
+views::NativeWidget* NativeTabContentsViewGtk::AsNativeWidget() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, views::WidgetGtk overrides:
+
+// Called when the mouse moves within the widget. We notify SadTabView if it's
+// not NULL, else our delegate.
+gboolean NativeTabContentsViewGtk::OnMotionNotify(GtkWidget* widget,
+ GdkEventMotion* event) {
+ if (delegate_->IsShowingSadTab())
+ return views::WidgetGtk::OnMotionNotify(widget, event);
+
+ delegate_->OnNativeTabContentsViewMouseMove(true);
+ return FALSE;
+}
+
+gboolean NativeTabContentsViewGtk::OnLeaveNotify(GtkWidget* widget,
+ GdkEventCrossing* event) {
+ if (delegate_->IsShowingSadTab())
+ return views::WidgetGtk::OnLeaveNotify(widget, event);
+
+ delegate_->OnNativeTabContentsViewMouseMove(false);
+ return FALSE;
+}
+
+gboolean NativeTabContentsViewGtk::OnButtonPress(GtkWidget* widget,
+ GdkEventButton* event) {
+ if (delegate_->IsShowingSadTab())
+ return views::WidgetGtk::OnButtonPress(widget, event);
+ last_mouse_down_ = *event;
+ return views::WidgetGtk::OnButtonPress(widget, event);
+}
+
+void NativeTabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
+ GtkAllocation* allocation) {
+ gfx::Size size(allocation->width, allocation->height);
+ delegate_->OnNativeTabContentsViewSized(size);
+ if (size != size_)
+ PositionConstrainedWindows(size);
+ size_ = size;
+ views::WidgetGtk::OnSizeAllocate(widget, allocation);
+}
+
+void NativeTabContentsViewGtk::OnShow(GtkWidget* widget) {
+ delegate_->OnNativeTabContentsViewShown();
+ views::WidgetGtk::OnShow(widget);
+}
+
+void NativeTabContentsViewGtk::OnHide(GtkWidget* widget) {
+ // OnHide can be called during widget destruction (gtk_widget_dispose calls
+ // gtk_widget_hide) so we make sure we do not call back through to the
+ // delegate after it's already deleted.
+ if (delegate_)
+ delegate_->OnNativeTabContentsViewHidden();
+ views::WidgetGtk::OnHide(widget);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, private:
+
+void NativeTabContentsViewGtk::PositionConstrainedWindows(
+ const gfx::Size& view_size) {
+ // Place each ConstrainedWindow in the center of the view.
+ int half_view_width = view_size.width() / 2;
+
+ typedef std::vector<ConstrainedWindowGtk*>::iterator iterator;
+
+ for (iterator f = constrained_windows_.begin(),
+ l = constrained_windows_.end(); f != l; ++f) {
+ GtkWidget* widget = (*f)->widget();
+
+ GtkRequisition requisition;
+ gtk_widget_size_request(widget, &requisition);
+
+ int child_x = std::max(half_view_width - (requisition.width / 2), 0);
+ PositionChild(widget, child_x, 0, 0, 0);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsView, public:
+
+// static
+NativeTabContentsView* NativeTabContentsView::CreateNativeTabContentsView(
+ internal::NativeTabContentsViewDelegate* delegate) {
+ return new NativeTabContentsViewGtk(delegate);
+}
+
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.h"
+
+#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
+#include "chrome/browser/tab_contents/web_drag_dest_gtk.h"
+#include "chrome/browser/ui/gtk/constrained_window_gtk.h"
+#include "chrome/browser/ui/gtk/tab_contents_drag_source.h"
+#include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_delegate.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/browser/tab_contents/tab_contents_view.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
+
+using WebKit::WebDragOperation;
+using WebKit::WebDragOperationsMask;
+using WebKit::WebInputEvent;
+
+namespace {
+
+// Called when the content view gtk widget is tabbed to, or after the call to
+// gtk_widget_child_focus() in TakeFocus(). We return true
+// and grab focus if we don't have it. The call to
+// FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to
+// webkit.
+gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus,
+ TabContents* tab_contents) {
+ // If we already have focus, let the next widget have a shot at it. We will
+ // reach this situation after the call to gtk_widget_child_focus() in
+ // TakeFocus().
+ if (gtk_widget_is_focus(widget))
+ return FALSE;
+
+ gtk_widget_grab_focus(widget);
+ bool reverse = focus == GTK_DIR_TAB_BACKWARD;
+ tab_contents->FocusThroughTabTraversal(reverse);
+ return TRUE;
+}
+
+// See tab_contents_view_gtk.cc for discussion of mouse scroll zooming.
+gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
+ internal::NativeTabContentsViewDelegate* delegate) {
+ if ((event->state & gtk_accelerator_get_default_mod_mask()) ==
+ GDK_CONTROL_MASK) {
+ if (event->direction == GDK_SCROLL_DOWN) {
+ delegate->OnNativeTabContentsViewWheelZoom(false);
+ return TRUE;
+ }
+ if (event->direction == GDK_SCROLL_UP) {
+ delegate->OnNativeTabContentsViewWheelZoom(true);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+gfx::NativeView GetHiddenTabHostWindow() {
+ static views::Widget* widget = NULL;
+
+ if (!widget) {
+ widget = new views::Widget;
+ // We don't want this widget to be closed automatically, this causes
+ // problems in tests that close the last non-secondary window.
+ widget->set_is_secondary_widget(false);
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
+ widget->Init(params);
+ }
+
+ return static_cast<views::WidgetGtk*>(widget->native_widget())->
+ window_contents();
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, public:
+
+NativeTabContentsViewGtk::NativeTabContentsViewGtk(
+ internal::NativeTabContentsViewDelegate* delegate)
+ : views::WidgetGtk(delegate->AsNativeWidgetDelegate()),
+ delegate_(delegate),
+ ignore_next_char_event_(false),
+ ALLOW_THIS_IN_INITIALIZER_LIST(drag_source_(
+ new TabContentsDragSource(delegate->GetTabContents()->view()))) {
+}
+
+NativeTabContentsViewGtk::~NativeTabContentsViewGtk() {
+ delegate_ = NULL;
+ CloseNow();
+}
+
+void NativeTabContentsViewGtk::AttachConstrainedWindow(
+ ConstrainedWindowGtk* constrained_window) {
+ DCHECK(find(constrained_windows_.begin(), constrained_windows_.end(),
+ constrained_window) == constrained_windows_.end());
+
+ constrained_windows_.push_back(constrained_window);
+ AddChild(constrained_window->widget());
+
+ gfx::Size requested_size;
+ views::WidgetGtk::GetRequestedSize(&requested_size);
+ PositionConstrainedWindows(requested_size);
+}
+
+void NativeTabContentsViewGtk::RemoveConstrainedWindow(
+ ConstrainedWindowGtk* constrained_window) {
+ std::vector<ConstrainedWindowGtk*>::iterator item =
+ find(constrained_windows_.begin(), constrained_windows_.end(),
+ constrained_window);
+ DCHECK(item != constrained_windows_.end());
+ RemoveChild((*item)->widget());
+ constrained_windows_.erase(item);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, NativeTabContentsView implementation:
+
+void NativeTabContentsViewGtk::InitNativeTabContentsView() {
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
+ params.native_widget = this;
+ params.delete_on_destroy = false;
+ GetWidget()->Init(params);
+
+ // We need to own the widget in order to attach/detach the native view to a
+ // container.
+ gtk_object_ref(GTK_OBJECT(GetWidget()->GetNativeView()));
+}
+
+void NativeTabContentsViewGtk::Unparent() {
+ // Note that we do not DCHECK on focus_manager_ as it may be NULL when used
+ // with an external tab container.
+ NativeWidget::ReparentNativeView(GetNativeView(), GetHiddenTabHostWindow());
+}
+
+RenderWidgetHostView* NativeTabContentsViewGtk::CreateRenderWidgetHostView(
+ RenderWidgetHost* render_widget_host) {
+ RenderWidgetHostViewGtk* view =
+ new RenderWidgetHostViewGtk(render_widget_host);
+ view->InitAsChild();
+ g_signal_connect(view->native_view(), "focus",
+ G_CALLBACK(OnFocus), delegate_->GetTabContents());
+ g_signal_connect(view->native_view(), "scroll-event",
+ G_CALLBACK(OnMouseScroll), delegate_);
+
+ // Let widget know that the tab contents has been painted.
+ views::WidgetGtk::RegisterChildExposeHandler(view->native_view());
+
+ // Renderer target DnD.
+ if (delegate_->GetTabContents()->ShouldAcceptDragAndDrop())
+ drag_dest_.reset(new WebDragDestGtk(delegate_->GetTabContents(),
+ view->native_view()));
+
+ gtk_fixed_put(GTK_FIXED(GetWidget()->GetNativeView()), view->native_view(), 0,
+ 0);
+ return view;
+}
+
+gfx::NativeWindow NativeTabContentsViewGtk::GetTopLevelNativeWindow() const {
+ GtkWidget* window = gtk_widget_get_ancestor(GetWidget()->GetNativeView(),
+ GTK_TYPE_WINDOW);
+ return window ? GTK_WINDOW(window) : NULL;
+}
+
+void NativeTabContentsViewGtk::SetPageTitle(const std::wstring& title) {
+ // Set the window name to include the page title so it's easier to spot
+ // when debugging (e.g. via xwininfo -tree).
+ if (GDK_IS_WINDOW(GetNativeView()->window))
+ gdk_window_set_title(GetNativeView()->window, WideToUTF8(title).c_str());
+}
+
+void NativeTabContentsViewGtk::StartDragging(const WebDropData& drop_data,
+ WebKit::WebDragOperationsMask ops,
+ const SkBitmap& image,
+ const gfx::Point& image_offset) {
+ drag_source_->StartDragging(drop_data, ops, &last_mouse_down_,
+ image, image_offset);
+}
+
+void NativeTabContentsViewGtk::CancelDrag() {
+}
+
+bool NativeTabContentsViewGtk::IsDoingDrag() const {
+ return false;
+}
+
+void NativeTabContentsViewGtk::SetDragCursor(
+ WebKit::WebDragOperation operation) {
+ if (drag_dest_.get())
+ drag_dest_->UpdateDragStatus(operation);
+}
+
+views::NativeWidget* NativeTabContentsViewGtk::AsNativeWidget() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, views::WidgetGtk overrides:
+
+// Called when the mouse moves within the widget. We notify SadTabView if it's
+// not NULL, else our delegate.
+gboolean NativeTabContentsViewGtk::OnMotionNotify(GtkWidget* widget,
+ GdkEventMotion* event) {
+ if (delegate_->IsShowingSadTab())
+ return views::WidgetGtk::OnMotionNotify(widget, event);
+
+ delegate_->OnNativeTabContentsViewMouseMove(true);
+ return FALSE;
+}
+
+gboolean NativeTabContentsViewGtk::OnLeaveNotify(GtkWidget* widget,
+ GdkEventCrossing* event) {
+ if (delegate_->IsShowingSadTab())
+ return views::WidgetGtk::OnLeaveNotify(widget, event);
+
+ delegate_->OnNativeTabContentsViewMouseMove(false);
+ return FALSE;
+}
+
+gboolean NativeTabContentsViewGtk::OnButtonPress(GtkWidget* widget,
+ GdkEventButton* event) {
+ if (delegate_->IsShowingSadTab())
+ return views::WidgetGtk::OnButtonPress(widget, event);
+ last_mouse_down_ = *event;
+ return views::WidgetGtk::OnButtonPress(widget, event);
+}
+
+void NativeTabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
+ GtkAllocation* allocation) {
+ gfx::Size size(allocation->width, allocation->height);
+ delegate_->OnNativeTabContentsViewSized(size);
+ if (size != size_)
+ PositionConstrainedWindows(size);
+ size_ = size;
+ views::WidgetGtk::OnSizeAllocate(widget, allocation);
+}
+
+void NativeTabContentsViewGtk::OnShow(GtkWidget* widget) {
+ delegate_->OnNativeTabContentsViewShown();
+ views::WidgetGtk::OnShow(widget);
+}
+
+void NativeTabContentsViewGtk::OnHide(GtkWidget* widget) {
+ // OnHide can be called during widget destruction (gtk_widget_dispose calls
+ // gtk_widget_hide) so we make sure we do not call back through to the
+ // delegate after it's already deleted.
+ if (delegate_)
+ delegate_->OnNativeTabContentsViewHidden();
+ views::WidgetGtk::OnHide(widget);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, private:
+
+void NativeTabContentsViewGtk::PositionConstrainedWindows(
+ const gfx::Size& view_size) {
+ // Place each ConstrainedWindow in the center of the view.
+ int half_view_width = view_size.width() / 2;
+
+ typedef std::vector<ConstrainedWindowGtk*>::iterator iterator;
+
+ for (iterator f = constrained_windows_.begin(),
+ l = constrained_windows_.end(); f != l; ++f) {
+ GtkWidget* widget = (*f)->widget();
+
+ GtkRequisition requisition;
+ gtk_widget_size_request(widget, &requisition);
+
+ int child_x = std::max(half_view_width - (requisition.width / 2), 0);
+ PositionChild(widget, child_x, 0, 0, 0);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsView, public:
+
+// static
+NativeTabContentsView* NativeTabContentsView::CreateNativeTabContentsView(
+ internal::NativeTabContentsViewDelegate* delegate) {
+ return new NativeTabContentsViewGtk(delegate);
+}
+
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.h"
+
+#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
+#include "chrome/browser/tab_contents/web_drag_dest_gtk.h"
+#include "chrome/browser/ui/gtk/constrained_window_gtk.h"
+#include "chrome/browser/ui/gtk/tab_contents_drag_source.h"
+#include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_delegate.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/browser/tab_contents/tab_contents_view.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
+
+using WebKit::WebDragOperation;
+using WebKit::WebDragOperationsMask;
+using WebKit::WebInputEvent;
+
+namespace {
+
+/*
+// Called when the content view gtk widget is tabbed to, or after the call to
+// gtk_widget_child_focus() in TakeFocus(). We return true
+// and grab focus if we don't have it. The call to
+// FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to
+// webkit.
+gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus,
+ TabContents* tab_contents) {
+ // If we already have focus, let the next widget have a shot at it. We will
+ // reach this situation after the call to gtk_widget_child_focus() in
+ // TakeFocus().
+ if (gtk_widget_is_focus(widget))
+ return FALSE;
+
+ gtk_widget_grab_focus(widget);
+ bool reverse = focus == GTK_DIR_TAB_BACKWARD;
+ tab_contents->FocusThroughTabTraversal(reverse);
+ return TRUE;
+}
+
+// Called when the mouse leaves the widget. We notify our delegate.
+// WidgetGtk also defines OnLeaveNotify, so we use the name OnLeaveNotify2
+// here.
+gboolean OnLeaveNotify2(GtkWidget* widget, GdkEventCrossing* event,
+ TabContents* tab_contents) {
+ if (tab_contents->delegate())
+ tab_contents->delegate()->ContentsMouseEvent(
+ tab_contents, views::Screen::GetCursorScreenPoint(), false);
+ return FALSE;
+}
+
+// Called when the mouse moves within the widget.
+gboolean CallMouseMove(GtkWidget* widget, GdkEventMotion* event,
+ TabContentsViewGtk* tab_contents_view) {
+ return tab_contents_view->OnMouseMove(widget, event);
+}
+
+// See tab_contents_view_gtk.cc for discussion of mouse scroll zooming.
+gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
+ TabContents* tab_contents) {
+ if ((event->state & gtk_accelerator_get_default_mod_mask()) ==
+ GDK_CONTROL_MASK) {
+ if (tab_contents->delegate()) {
+ if (event->direction == GDK_SCROLL_DOWN) {
+ tab_contents->delegate()->ContentsZoomChange(false);
+ return TRUE;
+ } else if (event->direction == GDK_SCROLL_UP) {
+ tab_contents->delegate()->ContentsZoomChange(true);
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+*/
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, public:
+
+NativeTabContentsViewGtk::NativeTabContentsViewGtk(
+ internal::NativeTabContentsViewDelegate* delegate)
+ : views::WidgetGtk(delegate->AsNativeWidgetDelegate()),
+ delegate_(delegate),
+ ignore_next_char_event_(false),
+ ALLOW_THIS_IN_INITIALIZER_LIST(drag_source_(
+ new TabContentsDragSource(delegate->GetTabContents()->view()))) {
+}
+
+NativeTabContentsViewGtk::~NativeTabContentsViewGtk() {
+ CloseNow();
+}
+
+void NativeTabContentsViewGtk::AttachConstrainedWindow(
+ ConstrainedWindowGtk* constrained_window) {
+ DCHECK(find(constrained_windows_.begin(), constrained_windows_.end(),
+ constrained_window) == constrained_windows_.end());
+
+ constrained_windows_.push_back(constrained_window);
+ AddChild(constrained_window->widget());
+
+ gfx::Size requested_size;
+ views::WidgetGtk::GetRequestedSize(&requested_size);
+ PositionConstrainedWindows(requested_size);
+}
+
+void NativeTabContentsViewGtk::RemoveConstrainedWindow(
+ ConstrainedWindowGtk* constrained_window) {
+ std::vector<ConstrainedWindowGtk*>::iterator item =
+ find(constrained_windows_.begin(), constrained_windows_.end(),
+ constrained_window);
+ DCHECK(item != constrained_windows_.end());
+ RemoveChild((*item)->widget());
+ constrained_windows_.erase(item);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, NativeTabContentsView implementation:
+
+void NativeTabContentsViewGtk::InitNativeTabContentsView() {
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
+ params.native_widget = this;
+ params.delete_on_destroy = false;
+ GetWidget()->Init(params);
+
+ // We need to own the widget in order to attach/detach the native view to a
+ // container.
+ gtk_object_ref(GTK_OBJECT(GetWidget()->GetNativeView()));
+}
+
+void NativeTabContentsViewGtk::Unparent() {
+}
+
+RenderWidgetHostView* NativeTabContentsViewGtk::CreateRenderWidgetHostView(
+ RenderWidgetHost* render_widget_host) {
+ RenderWidgetHostViewGtk* view =
+ new RenderWidgetHostViewGtk(render_widget_host);
+ view->InitAsChild();
+ /*
+ g_signal_connect(view->native_view(), "focus",
+ G_CALLBACK(OnFocus), delegate_->GetTabContents());
+ g_signal_connect(view->native_view(), "leave-notify-event",
+ G_CALLBACK(OnLeaveNotify2), delegate_->GetTabContents());
+ g_signal_connect(view->native_view(), "motion-notify-event",
+ G_CALLBACK(CallMouseMove), this);
+ g_signal_connect(view->native_view(), "scroll-event",
+ G_CALLBACK(OnMouseScroll), delegate_->GetTabContents());
+ */
+ gtk_widget_add_events(view->native_view(), GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK);
+
+ // Let widget know that the tab contents has been painted.
+ views::WidgetGtk::RegisterChildExposeHandler(view->native_view());
+
+ // Renderer target DnD.
+ if (delegate_->GetTabContents()->ShouldAcceptDragAndDrop())
+ drag_dest_.reset(new WebDragDestGtk(delegate_->GetTabContents(),
+ view->native_view()));
+
+ gtk_fixed_put(GTK_FIXED(GetWidget()->GetNativeView()), view->native_view(), 0,
+ 0);
+ return view;
+}
+
+gfx::NativeWindow NativeTabContentsViewGtk::GetTopLevelNativeWindow() const {
+ GtkWidget* window = gtk_widget_get_ancestor(GetWidget()->GetNativeView(),
+ GTK_TYPE_WINDOW);
+ return window ? GTK_WINDOW(window) : NULL;
+}
+
+void NativeTabContentsViewGtk::SetPageTitle(const std::wstring& title) {
+ // Set the window name to include the page title so it's easier to spot
+ // when debugging (e.g. via xwininfo -tree).
+ gdk_window_set_title(GetNativeView()->window, WideToUTF8(title).c_str());
+}
+
+void NativeTabContentsViewGtk::StartDragging(const WebDropData& drop_data,
+ WebKit::WebDragOperationsMask ops,
+ const SkBitmap& image,
+ const gfx::Point& image_offset) {
+ drag_source_->StartDragging(drop_data, ops, &last_mouse_down_,
+ image, image_offset);
+}
+
+void NativeTabContentsViewGtk::CancelDrag() {
+}
+
+bool NativeTabContentsViewGtk::IsDoingDrag() const {
+ return false;
+}
+
+void NativeTabContentsViewGtk::SetDragCursor(
+ WebKit::WebDragOperation operation) {
+ if (drag_dest_.get())
+ drag_dest_->UpdateDragStatus(operation);
+}
+
+views::NativeWidget* NativeTabContentsViewGtk::AsNativeWidget() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, views::WidgetGtk overrides:
+
+// Called when the mouse moves within the widget. We notify SadTabView if it's
+// not NULL, else our delegate.
+gboolean NativeTabContentsViewGtk::OnMotionNotify(GtkWidget* widget,
+ GdkEventMotion* event) {
+ if (delegate_->IsShowingSadTab())
+ return views::WidgetGtk::OnMotionNotify(widget, event);
+
+ delegate_->OnNativeTabContentsViewMouseMove();
+ return FALSE;
+}
+
+gboolean NativeTabContentsViewGtk::OnButtonPress(GtkWidget* widget,
+ GdkEventButton* event) {
+ if (delegate_->IsShowingSadTab())
+ return views::WidgetGtk::OnButtonPress(widget, event);
+ last_mouse_down_ = *event;
+ return views::WidgetGtk::OnButtonPress(widget, event);
+}
+
+void NativeTabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
+ GtkAllocation* allocation) {
+ gfx::Size size(allocation->width, allocation->height);
+ delegate_->OnNativeTabContentsViewSized(size);
+ if (size != size_)
+ PositionConstrainedWindows(size);
+ size_ = size;
+ views::WidgetGtk::OnSizeAllocate(widget, allocation);
+}
+
+void NativeTabContentsViewGtk::OnShow(GtkWidget* widget) {
+ delegate_->OnNativeTabContentsViewShown();
+ views::WidgetGtk::OnShow(widget);
+}
+
+void NativeTabContentsViewGtk::OnHide(GtkWidget* widget) {
+ delegate_->OnNativeTabContentsViewHidden();
+ views::WidgetGtk::OnHide(widget);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsViewGtk, private:
+
+void NativeTabContentsViewGtk::PositionConstrainedWindows(
+ const gfx::Size& view_size) {
+ // Place each ConstrainedWindow in the center of the view.
+ int half_view_width = view_size.width() / 2;
+
+ typedef std::vector<ConstrainedWindowGtk*>::iterator iterator;
+
+ for (iterator f = constrained_windows_.begin(),
+ l = constrained_windows_.end(); f != l; ++f) {
+ GtkWidget* widget = (*f)->widget();
+
+ GtkRequisition requisition;
+ gtk_widget_size_request(widget, &requisition);
+
+ int child_x = std::max(half_view_width - (requisition.width / 2), 0);
+ PositionChild(widget, child_x, 0, 0, 0);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsView, public:
+
+// static
+NativeTabContentsView* NativeTabContentsView::CreateNativeTabContentsView(
+ internal::NativeTabContentsViewDelegate* delegate) {
+ return new NativeTabContentsViewGtk(delegate);
+}
+
Property changes on: chrome\browser\ui\views\tab_contents\native_tab_contents_view_gtk.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698