diff options
Diffstat (limited to 'chrome')
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'], |