summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views.cc626
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views.h161
-rw-r--r--chrome/browser/views/extensions/extension_view.cc7
-rw-r--r--chrome/browser/views/notifications/balloon_view_host.cc11
-rw-r--r--chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc4
-rw-r--r--chrome/browser/views/tab_contents/tab_contents_view_gtk.cc40
-rw-r--r--chrome/chrome_browser.gypi19
7 files changed, 859 insertions, 9 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.cc b/chrome/browser/renderer_host/render_widget_host_view_views.cc
new file mode 100644
index 0000000..76f6cd6
--- /dev/null
+++ b/chrome/browser/renderer_host/render_widget_host_view_views.cc
@@ -0,0 +1,626 @@
+// Copyright (c) 2010 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/renderer_host/render_widget_host_view_views.h"
+
+#include <algorithm>
+#include <string>
+
+#include "app/keyboard_code_conversion_gtk.h"
+#include "app/l10n_util.h"
+#include "app/x11_util.h"
+#include "base/command_line.h"
+#include "base/histogram.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/string_number_conversions.h"
+#include "base/task.h"
+#include "base/time.h"
+#include "chrome/browser/renderer_host/backing_store_x.h"
+#include "chrome/browser/renderer_host/gpu_view_host.h"
+#include "chrome/browser/renderer_host/render_widget_host.h"
+#include "chrome/browser/renderer_host/video_layer_x.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/native_web_keyboard_event.h"
+#include "chrome/common/render_messages.h"
+#include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
+#include "views/event.h"
+#include "views/widget/widget.h"
+
+static const int kMaxWindowWidth = 4000;
+static const int kMaxWindowHeight = 4000;
+static const char* kRenderWidgetHostViewKey = "__RENDER_WIDGET_HOST_VIEW__";
+
+using WebKit::WebInputEventFactory;
+using WebKit::WebMouseWheelEvent;
+
+// static
+RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
+ RenderWidgetHost* widget) {
+ return new RenderWidgetHostViewViews(widget);
+}
+
+RenderWidgetHostViewViews::RenderWidgetHostViewViews(RenderWidgetHost* host)
+ : host_(host),
+ enable_gpu_rendering_(false),
+ about_to_validate_and_paint_(false),
+ is_hidden_(false),
+ is_loading_(false),
+ is_showing_context_menu_(false),
+ visually_deemphasized_(false) {
+ SetFocusable(true);
+ host_->set_view(this);
+
+ // Enable experimental out-of-process GPU rendering.
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ enable_gpu_rendering_ =
+ command_line->HasSwitch(switches::kEnableGPURendering);
+}
+
+RenderWidgetHostViewViews::~RenderWidgetHostViewViews() {
+}
+
+void RenderWidgetHostViewViews::InitAsChild() {
+ Show();
+}
+
+RenderWidgetHost* RenderWidgetHostViewViews::GetRenderWidgetHost() const {
+ return host_;
+}
+
+void RenderWidgetHostViewViews::InitAsPopup(
+ RenderWidgetHostView* parent_host_view,
+ const gfx::Rect& pos) {
+ // TODO(anicolao): figure out cases where popups occur and implement
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewViews::InitAsFullscreen(
+ RenderWidgetHostView* parent_host_view) {
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewViews::DidBecomeSelected() {
+ if (!is_hidden_)
+ return;
+
+ if (tab_switch_paint_time_.is_null())
+ tab_switch_paint_time_ = base::TimeTicks::Now();
+ is_hidden_ = false;
+ host_->WasRestored();
+}
+
+void RenderWidgetHostViewViews::WasHidden() {
+ if (is_hidden_)
+ return;
+
+ // If we receive any more paint messages while we are hidden, we want to
+ // ignore them so we don't re-allocate the backing store. We will paint
+ // everything again when we become selected again.
+ is_hidden_ = true;
+
+ // If we have a renderer, then inform it that we are being hidden so it can
+ // reduce its resource utilization.
+ GetRenderWidgetHost()->WasHidden();
+}
+
+void RenderWidgetHostViewViews::SetSize(const gfx::Size& size) {
+ // This is called when webkit has sent us a Move message.
+ int width = std::min(size.width(), kMaxWindowWidth);
+ int height = std::min(size.height(), kMaxWindowHeight);
+ if (requested_size_.width() != width ||
+ requested_size_.height() != height) {
+ requested_size_ = gfx::Size(width, height);
+ SetBounds(GetViewBounds());
+ host_->WasResized();
+ }
+}
+
+void RenderWidgetHostViewViews::MovePluginWindows(
+ const std::vector<webkit_glue::WebPluginGeometry>& moves) {
+ // TODO(anicolao): NIY
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewViews::Focus() {
+ RequestFocus();
+}
+
+bool RenderWidgetHostViewViews::HasFocus() {
+ return View::HasFocus();
+}
+
+void RenderWidgetHostViewViews::Show() {
+ SetVisible(true);
+}
+
+void RenderWidgetHostViewViews::Hide() {
+ SetVisible(false);
+}
+
+void RenderWidgetHostViewViews::Blur() {
+ // TODO(estade): We should be clearing native focus as well, but I know of no
+ // way to do that without focusing another widget.
+ host_->Blur();
+}
+
+
+bool RenderWidgetHostViewViews::IsShowing() {
+ return IsVisible();
+}
+
+gfx::Rect RenderWidgetHostViewViews::GetViewBounds() const {
+ return bounds();
+}
+
+void RenderWidgetHostViewViews::UpdateCursor(const WebCursor& cursor) {
+ // Optimize the common case, where the cursor hasn't changed.
+ // However, we can switch between different pixmaps, so only on the
+ // non-pixmap branch.
+ if (current_cursor_.GetCursorType() != GDK_CURSOR_IS_PIXMAP &&
+ current_cursor_.GetCursorType() == cursor.GetCursorType()) {
+ return;
+ }
+
+ current_cursor_ = cursor;
+ ShowCurrentCursor();
+}
+
+void RenderWidgetHostViewViews::SetIsLoading(bool is_loading) {
+ is_loading_ = is_loading;
+ // Only call ShowCurrentCursor() when it will actually change the cursor.
+ if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR)
+ ShowCurrentCursor();
+}
+
+void RenderWidgetHostViewViews::ImeUpdateTextInputState(
+ WebKit::WebTextInputType type,
+ const gfx::Rect& caret_rect) {
+ // TODO(bryeung): im_context_->UpdateInputMethodState(type, caret_rect);
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewViews::ImeCancelComposition() {
+ // TODO(bryeung): im_context_->CancelComposition();
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewViews::DidUpdateBackingStore(
+ const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy,
+ const std::vector<gfx::Rect>& copy_rects) {
+ if (is_hidden_)
+ return;
+
+ // TODO(darin): Implement the equivalent of Win32's ScrollWindowEX. Can that
+ // be done using XCopyArea? Perhaps similar to
+ // BackingStore::ScrollBackingStore?
+ if (about_to_validate_and_paint_)
+ invalid_rect_ = invalid_rect_.Union(scroll_rect);
+ else
+ SchedulePaint(scroll_rect, false);
+
+ for (size_t i = 0; i < copy_rects.size(); ++i) {
+ // Avoid double painting. NOTE: This is only relevant given the call to
+ // Paint(scroll_rect) above.
+ gfx::Rect rect = copy_rects[i].Subtract(scroll_rect);
+ if (rect.IsEmpty())
+ continue;
+
+ if (about_to_validate_and_paint_)
+ invalid_rect_ = invalid_rect_.Union(rect);
+ else
+ SchedulePaint(rect, false);
+ }
+}
+
+void RenderWidgetHostViewViews::RenderViewGone() {
+ Destroy();
+}
+
+void RenderWidgetHostViewViews::Destroy() {
+ // TODO(anicolao): deal with any special popup cleanup
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewViews::SetTooltipText(const std::wstring& tip) {
+ // TODO(anicolao): decide if we want tooltips for touch (none specified
+ // right now/might want a press-and-hold display)
+ // NOTIMPLEMENTED(); ... too annoying, it triggers for every mousemove
+}
+
+void RenderWidgetHostViewViews::SelectionChanged(const std::string& text) {
+ // TODO(anicolao): deal with the clipboard without GTK
+ NOTIMPLEMENTED();
+}
+
+void RenderWidgetHostViewViews::ShowingContextMenu(bool showing) {
+ is_showing_context_menu_ = showing;
+}
+
+bool RenderWidgetHostViewViews::NeedsInputGrab() {
+ return popup_type_ == WebKit::WebPopupTypeSelect;
+}
+
+bool RenderWidgetHostViewViews::IsPopup() {
+ return popup_type_ != WebKit::WebPopupTypeNone;
+}
+
+BackingStore* RenderWidgetHostViewViews::AllocBackingStore(
+ const gfx::Size& size) {
+ if (enable_gpu_rendering_) {
+ // Use a special GPU accelerated backing store.
+ if (!gpu_view_host_.get()) {
+ // Here we lazily make the GpuViewHost. This must be allocated when we
+ // have a native view realized, which happens sometime after creation
+ // when our owner puts us in the parent window.
+ DCHECK(GetNativeView());
+ XID window_xid = x11_util::GetX11WindowFromGtkWidget(GetNativeView());
+ gpu_view_host_.reset(new GpuViewHost(host_, window_xid));
+ }
+ return gpu_view_host_->CreateBackingStore(size);
+ }
+
+ return new BackingStoreX(host_, size,
+ x11_util::GetVisualFromGtkWidget(native_view()),
+ gtk_widget_get_visual(native_view())->depth);
+}
+
+gfx::NativeView RenderWidgetHostViewViews::native_view() const {
+ return GetWidget()->GetNativeView();
+}
+
+VideoLayer* RenderWidgetHostViewViews::AllocVideoLayer(const gfx::Size& size) {
+ if (enable_gpu_rendering_) {
+ // TODO(scherkus): is it possible for a video layer to be allocated before a
+ // backing store?
+ DCHECK(gpu_view_host_.get())
+ << "AllocVideoLayer() called before AllocBackingStore()";
+ return gpu_view_host_->CreateVideoLayer(size);
+ }
+
+ return new VideoLayerX(host_, size,
+ x11_util::GetVisualFromGtkWidget(native_view()),
+ gtk_widget_get_visual(native_view())->depth);
+}
+
+void RenderWidgetHostViewViews::SetBackground(const SkBitmap& background) {
+ RenderWidgetHostView::SetBackground(background);
+ host_->Send(new ViewMsg_SetBackground(host_->routing_id(), background));
+}
+
+void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) {
+ if (enable_gpu_rendering_) {
+ // When we're proxying painting, we don't actually display the web page
+ // ourselves.
+ if (gpu_view_host_.get())
+ gpu_view_host_->OnWindowPainted();
+
+ // Erase the background. This will prevent a flash of black when resizing
+ // or exposing the window. White is usually better than black.
+ return;
+ }
+
+ // Don't do any painting if the GPU process is rendering directly
+ // into the View.
+ RenderWidgetHost* render_widget_host = GetRenderWidgetHost();
+ if (render_widget_host->is_gpu_rendering_active()) {
+ return;
+ }
+
+ GdkWindow* window = native_view()->window;
+ DCHECK(!about_to_validate_and_paint_);
+
+ // TODO(anicolao): get the damage somehow
+ //invalid_rect_ = damage_rect;
+ invalid_rect_ = bounds();
+ about_to_validate_and_paint_ = true;
+ BackingStoreX* backing_store = static_cast<BackingStoreX*>(
+ host_->GetBackingStore(true));
+ // Calling GetBackingStore maybe have changed |invalid_rect_|...
+ about_to_validate_and_paint_ = false;
+
+ gfx::Rect paint_rect = gfx::Rect(0, 0, kMaxWindowWidth, kMaxWindowHeight);
+ paint_rect = paint_rect.Intersect(invalid_rect_);
+
+ if (backing_store) {
+ // Only render the widget if it is attached to a window; there's a short
+ // period where this object isn't attached to a window but hasn't been
+ // Destroy()ed yet and it receives paint messages...
+ if (window) {
+ if (!visually_deemphasized_) {
+ // In the common case, use XCopyArea. We don't draw more than once, so
+ // we don't need to double buffer.
+ backing_store->XShowRect(
+ paint_rect, x11_util::GetX11WindowFromGtkWidget(native_view()));
+
+ // Paint the video layer using XCopyArea.
+ // TODO(scherkus): implement VideoLayerX::CairoShow() for grey
+ // blending.
+ VideoLayerX* video_layer = static_cast<VideoLayerX*>(
+ host_->video_layer());
+ if (video_layer)
+ video_layer->XShow(
+ x11_util::GetX11WindowFromGtkWidget(native_view()));
+ } else {
+ // If the grey blend is showing, we make two drawing calls. Use double
+ // buffering to prevent flicker. Use CairoShowRect because XShowRect
+ // shortcuts GDK's double buffering.
+ GdkRectangle rect = { paint_rect.x(), paint_rect.y(),
+ paint_rect.width(), paint_rect.height() };
+ gdk_window_begin_paint_rect(window, &rect);
+
+ backing_store->CairoShowRect(paint_rect, GDK_DRAWABLE(window));
+
+ cairo_t* cr = gdk_cairo_create(window);
+ gdk_cairo_rectangle(cr, &rect);
+ cairo_set_source_rgba(cr, 0, 0, 0, 0.7);
+ cairo_fill(cr);
+ cairo_destroy(cr);
+
+ gdk_window_end_paint(window);
+ }
+ }
+ if (!whiteout_start_time_.is_null()) {
+ base::TimeDelta whiteout_duration = base::TimeTicks::Now() -
+ whiteout_start_time_;
+ UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration);
+
+ // Reset the start time to 0 so that we start recording again the next
+ // time the backing store is NULL...
+ whiteout_start_time_ = base::TimeTicks();
+ }
+ if (!tab_switch_paint_time_.is_null()) {
+ base::TimeDelta tab_switch_paint_duration = base::TimeTicks::Now() -
+ tab_switch_paint_time_;
+ UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration",
+ tab_switch_paint_duration);
+ // Reset tab_switch_paint_time_ to 0 so future tab selections are
+ // recorded.
+ tab_switch_paint_time_ = base::TimeTicks();
+ }
+ } else {
+ if (window)
+ gdk_window_clear(window);
+ if (whiteout_start_time_.is_null())
+ whiteout_start_time_ = base::TimeTicks::Now();
+ }
+}
+
+bool RenderWidgetHostViewViews::OnMousePressed(const views::MouseEvent& event) {
+ RequestFocus();
+
+ // TODO(anicolao): validate event generation.
+ WebKit::WebMouseEvent e;
+ e.timeStampSeconds = base::Time::Now().ToDoubleT();
+ e.modifiers = 0;
+ if (event.IsMiddleMouseButton()) {
+ e.modifiers |= WebKit::WebInputEvent::MiddleButtonDown;
+ e.button = WebKit::WebMouseEvent::ButtonMiddle;
+ }
+ if (event.IsRightMouseButton()) {
+ e.modifiers |= WebKit::WebInputEvent::RightButtonDown;
+ e.button = WebKit::WebMouseEvent::ButtonRight;
+ }
+ if (event.IsLeftMouseButton()) {
+ e.modifiers |= WebKit::WebInputEvent::LeftButtonDown;
+ e.button = WebKit::WebMouseEvent::ButtonLeft;
+ }
+ e.windowX = e.x = event.x();
+ e.windowY = e.y = event.y();
+ int x, y;
+ gdk_window_get_origin(GetNativeView()->window, &x, &y);
+ e.globalX = e.x + x;
+ e.globalY = e.y + y;
+ e.clickCount = 1;
+ // TODO(anicolao): deal with double clicks
+ e.type = WebKit::WebInputEvent::MouseDown;
+
+ GetRenderWidgetHost()->ForwardMouseEvent(e);
+ return true;
+}
+
+void RenderWidgetHostViewViews::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+ WebKit::WebMouseEvent e;
+ e.timeStampSeconds = base::Time::Now().ToDoubleT();
+ e.windowX = e.x = event.x();
+ e.windowY = e.y = event.y();
+ int x, y;
+ gdk_window_get_origin(GetNativeView()->window, &x, &y);
+ e.globalX = e.x + x;
+ e.globalY = e.y + y;
+ e.clickCount = 1;
+ e.type = WebKit::WebInputEvent::MouseUp;
+ if (event.IsMiddleMouseButton()) {
+ e.modifiers |= WebKit::WebInputEvent::MiddleButtonDown;
+ e.button = WebKit::WebMouseEvent::ButtonMiddle;
+ }
+ if (event.IsRightMouseButton()) {
+ e.modifiers |= WebKit::WebInputEvent::RightButtonDown;
+ e.button = WebKit::WebMouseEvent::ButtonRight;
+ }
+ if (event.IsLeftMouseButton()) {
+ e.modifiers |= WebKit::WebInputEvent::LeftButtonDown;
+ e.button = WebKit::WebMouseEvent::ButtonLeft;
+ }
+ GetRenderWidgetHost()->ForwardMouseEvent(e);
+}
+
+bool RenderWidgetHostViewViews::OnMouseDragged(const views::MouseEvent& event) {
+ OnMouseMoved(event);
+ return true;
+}
+
+void RenderWidgetHostViewViews::OnMouseMoved(const views::MouseEvent& event) {
+ WebKit::WebMouseEvent e;
+ e.timeStampSeconds = base::Time::Now().ToDoubleT();
+ e.windowX = e.x = event.x();
+ e.windowY = e.y = event.y();
+ int x, y;
+ gdk_window_get_origin(GetNativeView()->window, &x, &y);
+ e.globalX = e.x + x;
+ e.globalY = e.y + y;
+ e.type = WebKit::WebInputEvent::MouseMove;
+ if (event.IsMiddleMouseButton()) {
+ e.modifiers |= WebKit::WebInputEvent::MiddleButtonDown;
+ }
+ if (event.IsRightMouseButton()) {
+ e.modifiers |= WebKit::WebInputEvent::RightButtonDown;
+ }
+ if (event.IsLeftMouseButton()) {
+ e.modifiers |= WebKit::WebInputEvent::LeftButtonDown;
+ }
+ GetRenderWidgetHost()->ForwardMouseEvent(e);
+}
+
+void RenderWidgetHostViewViews::OnMouseEntered(const views::MouseEvent& event) {
+ // Already generated synthetically by webkit.
+}
+
+void RenderWidgetHostViewViews::OnMouseExited(const views::MouseEvent& event) {
+ // Already generated synthetically by webkit.
+}
+
+bool RenderWidgetHostViewViews::OnMouseWheel(const views::MouseWheelEvent& e) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+bool RenderWidgetHostViewViews::OnKeyPressed(const views::KeyEvent &e) {
+ // Send key event to input method.
+ // TODO host_view->im_context_->ProcessKeyEvent(event);
+ NativeWebKeyboardEvent wke;
+
+ wke.type = WebKit::WebInputEvent::KeyDown;
+ wke.windowsKeyCode = e.GetKeyCode();
+ wke.setKeyIdentifierFromWindowsKeyCode();
+
+ wke.text[0] = wke.unmodifiedText[0] =
+ static_cast<unsigned short>(gdk_keyval_to_unicode(
+ app::GdkKeyCodeForWindowsKeyCode(e.GetKeyCode(), false /*shift*/)));
+
+ // If ctrl key is pressed down, then control character shall be input.
+ // TODO(anicolao): deal with modifiers
+
+ ForwardKeyboardEvent(wke);
+
+ // send the keypress event
+ wke.type = WebKit::WebInputEvent::Char;
+
+ // TODO(anicolao): fear this comment from GTK land
+ // We return TRUE because we did handle the event. If it turns out webkit
+ // can't handle the event, we'll deal with it in
+ // RenderView::UnhandledKeyboardEvent().
+
+ return TRUE;
+}
+
+bool RenderWidgetHostViewViews::OnKeyReleased(const views::KeyEvent &e) {
+ // TODO(bryeung): deal with input methods
+ NativeWebKeyboardEvent wke;
+
+ wke.type = WebKit::WebInputEvent::KeyUp;
+ wke.windowsKeyCode = e.GetKeyCode();
+ wke.setKeyIdentifierFromWindowsKeyCode();
+
+ ForwardKeyboardEvent(wke);
+
+ return TRUE;
+}
+
+void RenderWidgetHostViewViews::DidGainFocus() {
+#if 0
+ // TODO(anicolao): - is this needed/replicable?
+ // Comes from the GTK equivalent.
+
+ int x, y;
+ gtk_widget_get_pointer(native_view(), &x, &y);
+ // http://crbug.com/13389
+ // If the cursor is in the render view, fake a mouse move event so that
+ // webkit updates its state. Otherwise webkit might think the cursor is
+ // somewhere it's not.
+ if (x >= 0 && y >= 0 && x < native_view()->allocation.width &&
+ y < native_view()->allocation.height) {
+ WebKit::WebMouseEvent fake_event;
+ fake_event.timeStampSeconds = base::Time::Now().ToDoubleT();
+ fake_event.modifiers = 0;
+ fake_event.windowX = fake_event.x = x;
+ fake_event.windowY = fake_event.y = y;
+ gdk_window_get_origin(native_view()->window, &x, &y);
+ fake_event.globalX = fake_event.x + x;
+ fake_event.globalY = fake_event.y + y;
+ fake_event.type = WebKit::WebInputEvent::MouseMove;
+ fake_event.button = WebKit::WebMouseEvent::ButtonNone;
+ GetRenderWidgetHost()->ForwardMouseEvent(fake_event);
+ }
+#endif
+
+ ShowCurrentCursor();
+ GetRenderWidgetHost()->GotFocus();
+}
+
+void RenderWidgetHostViewViews::WillLoseFocus() {
+ // If we are showing a context menu, maintain the illusion that webkit has
+ // focus.
+ if (!is_showing_context_menu_)
+ GetRenderWidgetHost()->Blur();
+}
+
+
+void RenderWidgetHostViewViews::ShowCurrentCursor() {
+ // The widget may not have a window. If that's the case, abort mission. This
+ // is the same issue as that explained above in Paint().
+ if (!native_view()->window)
+ return;
+
+ // TODO(anicolao): change to set cursors without GTK
+}
+
+void RenderWidgetHostViewViews::CreatePluginContainer(
+ gfx::PluginWindowHandle id) {
+ // TODO(anicolao): plugin_container_manager_.CreatePluginContainer(id);
+}
+
+void RenderWidgetHostViewViews::DestroyPluginContainer(
+ gfx::PluginWindowHandle id) {
+ // TODO(anicolao): plugin_container_manager_.DestroyPluginContainer(id);
+}
+
+void RenderWidgetHostViewViews::SetVisuallyDeemphasized(bool deemphasized) {
+ // TODO(anicolao)
+}
+
+bool RenderWidgetHostViewViews::ContainsNativeView(
+ gfx::NativeView native_view) const {
+ // TODO(port)
+ NOTREACHED() <<
+ "RenderWidgetHostViewViews::ContainsNativeView not implemented.";
+ return false;
+}
+
+void RenderWidgetHostViewViews::ForwardKeyboardEvent(
+ const NativeWebKeyboardEvent& event) {
+ if (!host_)
+ return;
+
+ EditCommands edit_commands;
+#if 0
+TODO(bryeung): key bindings
+ if (!event.skip_in_browser &&
+ key_bindings_handler_->Match(event, &edit_commands)) {
+ host_->ForwardEditCommandsForNextKeyEvent(edit_commands);
+ }
+#endif
+ host_->ForwardKeyboardEvent(event);
+}
+
+// static
+RenderWidgetHostView*
+ RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView(
+ gfx::NativeView widget) {
+ gpointer user_data = g_object_get_data(G_OBJECT(widget),
+ kRenderWidgetHostViewKey);
+ return reinterpret_cast<RenderWidgetHostView*>(user_data);
+}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.h b/chrome/browser/renderer_host/render_widget_host_view_views.h
new file mode 100644
index 0000000..331c1cd
--- /dev/null
+++ b/chrome/browser/renderer_host/render_widget_host_view_views.h
@@ -0,0 +1,161 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_VIEWS_H_
+#define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_VIEWS_H_
+#pragma once
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/scoped_ptr.h"
+#include "base/time.h"
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
+#include "gfx/native_widget_types.h"
+#include "views/controls/native/native_view_host.h"
+#include "views/event.h"
+#include "views/view.h"
+#include "webkit/glue/webcursor.h"
+
+class RenderWidgetHost;
+class GpuViewHost;
+struct NativeWebKeyboardEvent;
+
+// -----------------------------------------------------------------------------
+// See comments in render_widget_host_view.h about this class and its members.
+// -----------------------------------------------------------------------------
+class RenderWidgetHostViewViews : public RenderWidgetHostView,
+ public views::View {
+ public:
+ explicit RenderWidgetHostViewViews(RenderWidgetHost* widget);
+ virtual ~RenderWidgetHostViewViews();
+
+ // Initialize this object for use as a drawing area.
+ void InitAsChild();
+
+ // RenderWidgetHostView implementation.
+ virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
+ const gfx::Rect& pos);
+ virtual void InitAsFullscreen(RenderWidgetHostView* parent_host_view);
+ virtual RenderWidgetHost* GetRenderWidgetHost() const;
+ virtual void DidBecomeSelected();
+ virtual void WasHidden();
+ virtual void SetSize(const gfx::Size& size);
+ virtual void MovePluginWindows(
+ const std::vector<webkit_glue::WebPluginGeometry>& moves);
+ virtual void Focus();
+ virtual void Blur();
+ virtual bool HasFocus();
+ virtual void Show();
+ virtual void Hide();
+ virtual bool IsShowing();
+ virtual gfx::Rect GetViewBounds() const;
+ virtual void UpdateCursor(const WebCursor& cursor);
+ virtual void SetIsLoading(bool is_loading);
+ virtual void ImeUpdateTextInputState(WebKit::WebTextInputType type,
+ const gfx::Rect& caret_rect);
+ virtual void ImeCancelComposition();
+ virtual void DidUpdateBackingStore(
+ const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy,
+ const std::vector<gfx::Rect>& copy_rects);
+ virtual void RenderViewGone();
+ virtual void Destroy();
+ virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {}
+ virtual void SetTooltipText(const std::wstring& tooltip_text);
+ virtual void SelectionChanged(const std::string& text);
+ virtual void ShowingContextMenu(bool showing);
+ virtual BackingStore* AllocBackingStore(const gfx::Size& size);
+ virtual VideoLayer* AllocVideoLayer(const gfx::Size& size);
+ virtual void SetBackground(const SkBitmap& background);
+ virtual void CreatePluginContainer(gfx::PluginWindowHandle id);
+ virtual void DestroyPluginContainer(gfx::PluginWindowHandle id);
+ virtual void SetVisuallyDeemphasized(bool deemphasized);
+ virtual bool ContainsNativeView(gfx::NativeView native_view) const;
+
+ gfx::NativeView native_view() const;
+ virtual gfx::NativeView GetNativeView() { return native_view(); }
+
+ virtual void Paint(gfx::Canvas* canvas);
+
+ // Views mouse events
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual bool OnMouseDragged(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+ virtual void OnMouseMoved(const views::MouseEvent& e);
+ virtual void OnMouseEntered(const views::MouseEvent& event);
+ virtual void OnMouseExited(const views::MouseEvent& event);
+ virtual bool OnMouseWheel(const views::MouseWheelEvent& e);
+
+ // Views keyboard events
+ virtual bool OnKeyPressed(const views::KeyEvent &e);
+ virtual bool OnKeyReleased(const views::KeyEvent &e);
+
+ virtual void DidGainFocus();
+ virtual void WillLoseFocus();
+
+ // Forwards a keyboard event to renderer.
+ void ForwardKeyboardEvent(const NativeWebKeyboardEvent& event);
+
+ private:
+ friend class RenderWidgetHostViewViewsWidget;
+
+ // Returns whether the widget needs an input grab to work
+ // properly.
+ bool NeedsInputGrab();
+
+ // Returns whether this render view is a popup (<select> dropdown or
+ // autocomplete window).
+ bool IsPopup();
+
+ // Update the display cursor for the render view.
+ void ShowCurrentCursor();
+
+ // The model object.
+ RenderWidgetHost* host_;
+
+ // Cached value of --enable-gpu-rendering for out-of-process painting.
+ bool enable_gpu_rendering_;
+
+ // Non-NULL when we're doing out-of-process painting.
+ scoped_ptr<GpuViewHost> gpu_view_host_;
+
+ // This is true when we are currently painting and thus should handle extra
+ // paint requests by expanding the invalid rect rather than actually
+ // painting.
+ bool about_to_validate_and_paint_;
+
+ // This is the rectangle which we'll paint.
+ gfx::Rect invalid_rect_;
+
+ // Whether or not this widget is hidden.
+ bool is_hidden_;
+
+ // Whether we are currently loading.
+ bool is_loading_;
+
+ // The cursor for the page. This is passed up from the renderer.
+ WebCursor current_cursor_;
+
+ // Whether we are showing a context menu.
+ bool is_showing_context_menu_;
+
+ // The time at which this view started displaying white pixels as a result of
+ // not having anything to paint (empty backing store from renderer). This
+ // value returns true for is_null() if we are not recording whiteout times.
+ base::TimeTicks whiteout_start_time_;
+
+ // The time it took after this view was selected for it to be fully painted.
+ base::TimeTicks tab_switch_paint_time_;
+
+ // If true, fade the render widget when painting it.
+ bool visually_deemphasized_;
+
+ // The size that we want the renderer to be.
+ gfx::Size requested_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewViews);
+};
+
+#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_VIEWS_H_
diff --git a/chrome/browser/views/extensions/extension_view.cc b/chrome/browser/views/extensions/extension_view.cc
index 062bc00..4ba38ca 100644
--- a/chrome/browser/views/extensions/extension_view.cc
+++ b/chrome/browser/views/extensions/extension_view.cc
@@ -12,6 +12,8 @@
#if defined(OS_WIN)
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
+#elif defined(TOUCH_UI)
+#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
#elif defined(OS_LINUX)
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#endif
@@ -100,6 +102,11 @@ void ExtensionView::CreateWidgetHostView() {
HWND hwnd = view_win->Create(GetWidget()->GetNativeView());
view_win->ShowWindow(SW_SHOW);
Attach(hwnd);
+#elif defined(TOUCH_UI)
+ RenderWidgetHostViewViews* view_views =
+ static_cast<RenderWidgetHostViewViews*>(view);
+ view_views->InitAsChild();
+ Attach(view_views->GetNativeView());
#elif defined(OS_LINUX)
RenderWidgetHostViewGtk* view_gtk =
static_cast<RenderWidgetHostViewGtk*>(view);
diff --git a/chrome/browser/views/notifications/balloon_view_host.cc b/chrome/browser/views/notifications/balloon_view_host.cc
index b2c2a5c..24a7fe2 100644
--- a/chrome/browser/views/notifications/balloon_view_host.cc
+++ b/chrome/browser/views/notifications/balloon_view_host.cc
@@ -11,8 +11,12 @@
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#endif
#if defined(OS_LINUX)
+#if defined(TOUCH_UI)
+#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
+#else
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#endif
+#endif
#include "views/widget/widget.h"
#if defined(OS_WIN)
#include "views/widget/widget_win.h"
@@ -71,10 +75,17 @@ void BalloonViewHost::InitRenderWidgetHostView() {
view_win->ShowWindow(SW_SHOW);
native_host_->Attach(hwnd);
#elif defined(OS_LINUX)
+#if defined(TOUCH_UI)
+ RenderWidgetHostViewViews* view_views =
+ static_cast<RenderWidgetHostViewViews*>(render_widget_host_view_);
+ view_views->InitAsChild();
+ native_host_->Attach(view_views->native_view());
+#else
RenderWidgetHostViewGtk* view_gtk =
static_cast<RenderWidgetHostViewGtk*>(render_widget_host_view_);
view_gtk->InitAsChild();
native_host_->Attach(view_gtk->native_view());
+#endif
#else
NOTIMPLEMENTED();
#endif
diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc
index d9c26c5..0c07fa7 100644
--- a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc
+++ b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc
@@ -59,6 +59,7 @@ views::View* NativeTabContentsContainerGtk::GetView() {
void NativeTabContentsContainerGtk::TabContentsFocused(
TabContents* tab_contents) {
+#if !defined(TOUCH_UI)
// Called when the tab contents native view gets focused (typically through a
// user click). We make ourself the focused view, so the focus is restored
// properly when the browser window is deactivated/reactivated.
@@ -68,6 +69,9 @@ void NativeTabContentsContainerGtk::TabContentsFocused(
return;
}
focus_manager->SetFocusedView(this);
+#else
+ // no native views in TOUCH_UI, so don't steal the focus
+#endif
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc
index c261600..e13d441 100644
--- a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc
@@ -14,7 +14,11 @@
#include "chrome/browser/gtk/tab_contents_drag_source.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_factory.h"
+#if defined(TOUCH_UI)
+#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
+#else
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
+#endif
#include "chrome/browser/tab_contents/interstitial_page.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
@@ -174,6 +178,30 @@ RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget(
sad_tab_ = NULL;
}
+#if defined(TOUCH_UI)
+ RenderWidgetHostViewViews* view =
+ new RenderWidgetHostViewViews(render_widget_host);
+ SetContentsView(view);
+ view->Show();
+ view->InitAsChild();
+
+ g_signal_connect(view->native_view(), "focus",
+ G_CALLBACK(OnFocus), tab_contents());
+ g_signal_connect(view->native_view(), "leave-notify-event",
+ G_CALLBACK(OnLeaveNotify2), tab_contents());
+ g_signal_connect(view->native_view(), "motion-notify-event",
+ G_CALLBACK(CallMouseMove), this);
+ g_signal_connect(view->native_view(), "scroll-event",
+ G_CALLBACK(OnMouseScroll), tab_contents());
+ gtk_widget_add_events(view->native_view(), GDK_LEAVE_NOTIFY_MASK |
+ GDK_POINTER_MOTION_MASK);
+
+ // Renderer target DnD.
+ if (tab_contents()->ShouldAcceptDragAndDrop())
+ drag_dest_.reset(new WebDragDestGtk(tab_contents(), view->native_view()));
+
+ return view;
+#else
RenderWidgetHostViewGtk* view =
new RenderWidgetHostViewGtk(render_widget_host);
view->InitAsChild();
@@ -194,6 +222,7 @@ RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget(
gtk_fixed_put(GTK_FIXED(GetNativeView()), view->native_view(), 0, 0);
return view;
+#endif
}
gfx::NativeView TabContentsViewGtk::GetNativeView() const {
@@ -391,6 +420,17 @@ gboolean TabContentsViewGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) {
sad_tab_->SetBounds(gfx::Rect(0, 0, bounds.width(), bounds.height()));
gfx::CanvasSkiaPaint canvas(event);
sad_tab_->ProcessPaint(&canvas);
+ } else {
+#if defined(TOUCH_UI)
+ // there's no native view, so just like sad tabs
+ // we need to pass on the message to paint the page
+ gfx::Rect bounds;
+ GetBounds(&bounds, true);
+ views::View *view = reinterpret_cast<RenderWidgetHostViewViews *>(tab_contents()->render_view_host()->view());
+ view->SetBounds(gfx::Rect(0, 0, bounds.width(), bounds.height()));
+ gfx::CanvasSkiaPaint canvas(event);
+ view->ProcessPaint(&canvas);
+#endif
}
return false; // False indicates other widgets should get the event as well.
}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 90bef1d..f1b93e1 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2429,6 +2429,8 @@
'browser/renderer_host/render_widget_host_view_mac.mm',
'browser/renderer_host/render_widget_host_view_win.cc',
'browser/renderer_host/render_widget_host_view_win.h',
+ 'browser/renderer_host/render_widget_host_view_views.cc',
+ 'browser/renderer_host/render_widget_host_view_views.h',
'browser/renderer_host/resource_dispatcher_host.cc',
'browser/renderer_host/resource_dispatcher_host.h',
'browser/renderer_host/resource_dispatcher_host_request_info.cc',
@@ -3251,6 +3253,12 @@
'browser/dom_ui/keyboard_ui.h',
],
}],
+ ['touchui==1', {
+ 'sources/': [
+ ['exclude', '^browser/renderer_host/render_widget_host_view_gtk.cc'],
+ ['exclude', '^browser/renderer_host/render_widget_host_view_gtk.h'],
+ ],
+ }],
['OS=="linux"', {
'dependencies': [
'../build/linux/system.gyp:dbus-glib',
@@ -3516,6 +3524,8 @@
'browser/importer/nss_decryptor_system_nss.cc',
'browser/importer/nss_decryptor_system_nss.h',
'browser/power_save_blocker_stub.cc',
+ 'browser/renderer_host/render_widget_host_view_views.cc',
+ 'browser/renderer_host/render_widget_host_view_views.h',
'browser/views/select_file_dialog.cc',
],
'conditions': [
@@ -3552,7 +3562,6 @@
'sources/': [
['include', '^browser/back_forward_menu_model_views.cc'],
['include', '^browser/back_forward_menu_model_views.h'],
- ['include', '^browser/dock_info_gtk.cc'],
['include', '^browser/dock_info.cc'],
['include', '^browser/dock_info.h'],
['include', '^browser/extensions/'],
@@ -3781,8 +3790,6 @@
['include', '^browser/gtk/accessibility_event_router_gtk.h'],
['include', '^browser/gtk/accessible_widget_helper_gtk.cc'],
['include', '^browser/gtk/accessible_widget_helper_gtk.h'],
- ['include', '^browser/gtk/bookmark_context_menu_gtk.cc'],
- ['include', '^browser/gtk/bookmark_context_menu_gtk.h'],
['include', '^browser/gtk/bookmark_editor_gtk.cc'],
['include', '^browser/gtk/bookmark_editor_gtk.h'],
['include', '^browser/gtk/bookmark_tree_model.cc'],
@@ -3808,14 +3815,10 @@
['include', '^browser/gtk/edit_search_engine_dialog.h'],
['include', '^browser/gtk/first_run_dialog.cc'],
['include', '^browser/gtk/first_run_dialog.h'],
- ['include', '^browser/gtk/focus_store_gtk.cc'],
- ['include', '^browser/gtk/focus_store_gtk.h'],
['include', '^browser/gtk/gtk_chrome_button.cc'],
['include', '^browser/gtk/gtk_chrome_button.h'],
['include', '^browser/gtk/gtk_chrome_link_button.cc'],
['include', '^browser/gtk/gtk_chrome_link_button.h'],
- ['include', '^browser/gtk/gtk_custom_menu.cc'],
- ['include', '^browser/gtk/gtk_custom_menu.h'],
['include', '^browser/gtk/gtk_custom_menu_item.cc'],
['include', '^browser/gtk/gtk_floating_container.cc'],
['include', '^browser/gtk/gtk_floating_container.h'],
@@ -3836,8 +3839,6 @@
['include', '^browser/gtk/import_lock_dialog_gtk.h'],
['include', '^browser/gtk/keyword_editor_view.cc'],
['include', '^browser/gtk/keyword_editor_view.h'],
- ['include', '^browser/gtk/list_store_favicon_loader.cc'],
- ['include', '^browser/gtk/list_store_favicon_loader.h'],
['include', '^browser/gtk/meta_frames.cc'],
['include', '^browser/gtk/meta_frames.h'],
['include', '^browser/gtk/nine_box.cc'],