summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host/render_widget_host_view_views.cc
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-05-31 20:30:28 +0100
committerKristian Monsen <kristianm@google.com>2011-06-14 20:31:41 -0700
commit72a454cd3513ac24fbdd0e0cb9ad70b86a99b801 (patch)
tree382278a54ce7a744d62fa510a9a80688cc12434b /chrome/browser/renderer_host/render_widget_host_view_views.cc
parentc4becdd46e31d261b930e4b5a539cbc1d45c23a6 (diff)
downloadexternal_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.zip
external_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.tar.gz
external_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.tar.bz2
Merge Chromium.org at r11.0.672.0: Initial merge by git.
Change-Id: I8b4aaf611a2a405fe3fe10e8a94ea7658645c192
Diffstat (limited to 'chrome/browser/renderer_host/render_widget_host_view_views.cc')
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views.cc454
1 files changed, 342 insertions, 112 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
index a8049cf..cd38138 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_views.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_views.cc
@@ -7,9 +7,6 @@
#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/logging.h"
#include "base/message_loop.h"
@@ -17,29 +14,64 @@
#include "base/string_number_conversions.h"
#include "base/task.h"
#include "base/time.h"
+#include "chrome/browser/renderer_host/backing_store_skia.h"
#include "chrome/browser/renderer_host/backing_store_x.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
-#include "chrome/common/chrome_switches.h"
#include "chrome/common/native_web_keyboard_event.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/result_codes.h"
-#include "gfx/canvas.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 "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
+#include "ui/base/keycodes/keyboard_code_conversion_gtk.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/x/x11_util.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/canvas_skia.h"
+#include "views/events/event.h"
+#include "views/ime/ime_context.h"
#include "views/widget/widget.h"
#include "views/widget/widget_gtk.h"
static const int kMaxWindowWidth = 4000;
static const int kMaxWindowHeight = 4000;
-static const char* kRenderWidgetHostViewKey = "__RENDER_WIDGET_HOST_VIEW__";
+static const char kRenderWidgetHostViewKey[] = "__RENDER_WIDGET_HOST_VIEW__";
+static const char kBackingStoreSkiaSwitch[] = "use-backing-store-skia";
+
+// Copied from third_party/WebKit/Source/WebCore/page/EventHandler.cpp
+//
+// Match key code of composition keydown event on windows.
+// IE sends VK_PROCESSKEY which has value 229;
+//
+// Please refer to following documents for detals:
+// - Virtual-Key Codes
+// http://msdn.microsoft.com/en-us/library/ms645540(VS.85).aspx
+// - How the IME System Works
+// http://msdn.microsoft.com/en-us/library/cc194848.aspx
+// - ImmGetVirtualKey Function
+// http://msdn.microsoft.com/en-us/library/dd318570(VS.85).aspx
+static const int kCompositionEventKeyCode = 229;
using WebKit::WebInputEventFactory;
using WebKit::WebMouseWheelEvent;
using WebKit::WebTouchEvent;
+const char RenderWidgetHostViewViews::kViewClassName[] =
+ "browser/renderer_host/RenderWidgetHostViewViews";
+
namespace {
+bool UsingBackingStoreSkia() {
+ static bool decided = false;
+ static bool use_skia = false;
+ if (!decided) {
+ CommandLine* cmdline = CommandLine::ForCurrentProcess();
+ use_skia = (cmdline && cmdline->HasSwitch(kBackingStoreSkiaSwitch));
+ decided = true;
+ }
+
+ return use_skia;
+}
+
int WebInputEventFlagsFromViewsEvent(const views::Event& event) {
int modifiers = 0;
@@ -57,14 +89,14 @@ int WebInputEventFlagsFromViewsEvent(const views::Event& event) {
WebKit::WebTouchPoint::State TouchPointStateFromEvent(
const views::TouchEvent* event) {
- switch (event->GetType()) {
- case views::Event::ET_TOUCH_PRESSED:
+ switch (event->type()) {
+ case ui::ET_TOUCH_PRESSED:
return WebKit::WebTouchPoint::StatePressed;
- case views::Event::ET_TOUCH_RELEASED:
+ case ui::ET_TOUCH_RELEASED:
return WebKit::WebTouchPoint::StateReleased;
- case views::Event::ET_TOUCH_MOVED:
+ case ui::ET_TOUCH_MOVED:
return WebKit::WebTouchPoint::StateMoved;
- case views::Event::ET_TOUCH_CANCELLED:
+ case ui::ET_TOUCH_CANCELLED:
return WebKit::WebTouchPoint::StateCancelled;
default:
return WebKit::WebTouchPoint::StateUndefined;
@@ -73,14 +105,14 @@ WebKit::WebTouchPoint::State TouchPointStateFromEvent(
WebKit::WebInputEvent::Type TouchEventTypeFromEvent(
const views::TouchEvent* event) {
- switch (event->GetType()) {
- case views::Event::ET_TOUCH_PRESSED:
+ switch (event->type()) {
+ case ui::ET_TOUCH_PRESSED:
return WebKit::WebInputEvent::TouchStart;
- case views::Event::ET_TOUCH_RELEASED:
+ case ui::ET_TOUCH_RELEASED:
return WebKit::WebInputEvent::TouchEnd;
- case views::Event::ET_TOUCH_MOVED:
+ case ui::ET_TOUCH_MOVED:
return WebKit::WebInputEvent::TouchMove;
- case views::Event::ET_TOUCH_CANCELLED:
+ case ui::ET_TOUCH_CANCELLED:
return WebKit::WebInputEvent::TouchCancel;
default:
return WebKit::WebInputEvent::Undefined;
@@ -111,6 +143,149 @@ void InitializeWebMouseEventFromViewsEvent(const views::LocatedEvent& e,
} // namespace
+class IMEContextHandler : public views::CommitTextListener,
+ public views::CompositionListener,
+ public views::ForwardKeyEventListener {
+ public:
+ explicit IMEContextHandler(
+ RenderWidgetHostViewViews* host_view)
+ : host_view_(host_view),
+ is_enabled_(false),
+ is_focused_(false),
+ ime_context_(views::IMEContext::Create(host_view_)) {
+ ime_context_->set_commit_text_listener(this);
+ ime_context_->set_composition_listener(this);
+ ime_context_->set_forward_key_event_listener(this);
+ }
+
+ // IMEContext Listeners implementation
+ virtual void OnCommitText(views::IMEContext* sender,
+ const string16& text) {
+ DCHECK(ime_context_ == sender);
+
+ RenderWidgetHost* host = host_view_->GetRenderWidgetHost();
+ if (host) {
+ SendFakeCompositionWebKeyboardEvent(WebKit::WebInputEvent::RawKeyDown);
+ host->ImeConfirmComposition(text);
+ SendFakeCompositionWebKeyboardEvent(WebKit::WebInputEvent::KeyUp);
+ }
+ }
+
+ virtual void OnStartComposition(views::IMEContext* sender) {
+ DCHECK(ime_context_ == sender);
+ }
+
+ virtual void OnEndComposition(views::IMEContext* sender) {
+ DCHECK(ime_context_ == sender);
+
+ RenderWidgetHost* host = host_view_->GetRenderWidgetHost();
+ if (host)
+ host->ImeCancelComposition();
+ }
+
+ virtual void OnSetComposition(views::IMEContext* sender,
+ const string16& text,
+ const views::CompositionAttributeList& attributes,
+ uint32 cursor_pos) {
+ DCHECK(ime_context_ == sender);
+
+ RenderWidgetHost* host = host_view_->GetRenderWidgetHost();
+ if (host) {
+ SendFakeCompositionWebKeyboardEvent(WebKit::WebInputEvent::RawKeyDown);
+
+ // Cast CompositonAttribute to WebKit::WebCompositionUnderline directly,
+ // becasue CompositionAttribute is duplicated from
+ // WebKit::WebCompositionUnderline.
+ const std::vector<WebKit::WebCompositionUnderline>& underlines =
+ reinterpret_cast<const std::vector<WebKit::WebCompositionUnderline>&>(
+ attributes);
+ host->ImeSetComposition(text, underlines, cursor_pos, cursor_pos);
+ SendFakeCompositionWebKeyboardEvent(WebKit::WebInputEvent::KeyUp);
+ }
+ }
+
+ virtual void OnForwardKeyEvent(views::IMEContext* sender,
+ const views::KeyEvent& event) {
+ DCHECK(ime_context_ == sender);
+
+ host_view_->ForwardKeyEvent(event);
+ }
+
+ bool FilterKeyEvent(const views::KeyEvent& event) {
+ return is_enabled_ && ime_context_->FilterKeyEvent(event);
+ }
+
+ void Focus() {
+ if (!is_focused_) {
+ ime_context_->Focus();
+ is_focused_ = true;
+ }
+
+ // Enables RenderWidget's IME related events, so that we can be notified
+ // when WebKit wants to enable or disable IME.
+ RenderWidgetHost* host = host_view_->GetRenderWidgetHost();
+ if (host)
+ host->SetInputMethodActive(true);
+ }
+
+ void Blur() {
+ if (is_focused_) {
+ ime_context_->Blur();
+ is_focused_ = false;
+ }
+
+ // Disable RenderWidget's IME related events to save bandwidth.
+ RenderWidgetHost* host = host_view_->GetRenderWidgetHost();
+ if (host)
+ host->SetInputMethodActive(false);
+ }
+
+ void ImeUpdateTextInputState(WebKit::WebTextInputType type,
+ const gfx::Rect& caret_rect) {
+ bool enable =
+ (type != WebKit::WebTextInputTypeNone) &&
+ (type != WebKit::WebTextInputTypePassword);
+
+ if (is_enabled_ != enable) {
+ is_enabled_ = enable;
+ if (is_focused_) {
+ if (is_enabled_)
+ ime_context_->Focus();
+ else
+ ime_context_->Blur();
+ }
+ }
+
+ if (is_enabled_) {
+ gfx::Point p(caret_rect.origin());
+ views::View::ConvertPointToScreen(host_view_, &p);
+
+ ime_context_->SetCursorLocation(gfx::Rect(p, caret_rect.size()));
+ }
+ }
+
+ void Reset() {
+ ime_context_->Reset();
+ }
+
+ private:
+ void SendFakeCompositionWebKeyboardEvent(WebKit::WebInputEvent::Type type) {
+ NativeWebKeyboardEvent fake_event;
+ fake_event.windowsKeyCode = kCompositionEventKeyCode;
+ fake_event.skip_in_browser = true;
+ fake_event.type = type;
+ host_view_->ForwardWebKeyboardEvent(fake_event);
+ }
+
+ private:
+ RenderWidgetHostViewViews* host_view_;
+ bool is_enabled_;
+ bool is_focused_;
+ scoped_ptr<views::IMEContext> ime_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(IMEContextHandler);
+};
+
// static
RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
RenderWidgetHost* widget) {
@@ -125,19 +300,17 @@ RenderWidgetHostViewViews::RenderWidgetHostViewViews(RenderWidgetHost* host)
native_cursor_(NULL),
is_showing_context_menu_(false),
visually_deemphasized_(false),
- touch_event_()
- {
+ touch_event_() {
SetFocusable(true);
host_->set_view(this);
}
RenderWidgetHostViewViews::~RenderWidgetHostViewViews() {
- RenderViewGone(base::TERMINATION_STATUS_NORMAL_TERMINATION,
- ResultCodes::NORMAL_EXIT);
}
void RenderWidgetHostViewViews::InitAsChild() {
Show();
+ ime_context_.reset(new IMEContextHandler(this));
}
RenderWidgetHost* RenderWidgetHostViewViews::GetRenderWidgetHost() const {
@@ -151,8 +324,7 @@ void RenderWidgetHostViewViews::InitAsPopup(
NOTIMPLEMENTED();
}
-void RenderWidgetHostViewViews::InitAsFullscreen(
- RenderWidgetHostView* parent_host_view) {
+void RenderWidgetHostViewViews::InitAsFullscreen() {
NOTIMPLEMENTED();
}
@@ -187,7 +359,7 @@ void RenderWidgetHostViewViews::SetSize(const gfx::Size& size) {
if (requested_size_.width() != width ||
requested_size_.height() != height) {
requested_size_ = gfx::Size(width, height);
- SetBounds(gfx::Rect(x(), y(), width, height));
+ SetBounds(x(), y(), width, height);
host_->WasResized();
}
}
@@ -251,13 +423,11 @@ void RenderWidgetHostViewViews::SetIsLoading(bool is_loading) {
void RenderWidgetHostViewViews::ImeUpdateTextInputState(
WebKit::WebTextInputType type,
const gfx::Rect& caret_rect) {
- // TODO(bryeung): im_context_->UpdateInputMethodState(type, caret_rect);
- NOTIMPLEMENTED();
+ ime_context_->ImeUpdateTextInputState(type, caret_rect);
}
void RenderWidgetHostViewViews::ImeCancelComposition() {
- // TODO(bryeung): im_context_->CancelComposition();
- NOTIMPLEMENTED();
+ ime_context_->Reset();
}
void RenderWidgetHostViewViews::DidUpdateBackingStore(
@@ -286,6 +456,7 @@ void RenderWidgetHostViewViews::DidUpdateBackingStore(
else
SchedulePaint(rect, false);
}
+ invalid_rect_ = invalid_rect_.Intersect(bounds());
}
void RenderWidgetHostViewViews::RenderViewGone(base::TerminationStatus status,
@@ -295,8 +466,12 @@ void RenderWidgetHostViewViews::RenderViewGone(base::TerminationStatus status,
}
void RenderWidgetHostViewViews::Destroy() {
- // TODO(anicolao): deal with any special popup cleanup
- NOTIMPLEMENTED();
+ // host_'s destruction brought us here, null it out so we don't use it
+ host_ = NULL;
+
+ if (parent())
+ parent()->RemoveChildView(this);
+ MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
void RenderWidgetHostViewViews::SetTooltipText(const std::wstring& tip) {
@@ -324,15 +499,24 @@ bool RenderWidgetHostViewViews::IsPopup() {
BackingStore* RenderWidgetHostViewViews::AllocBackingStore(
const gfx::Size& size) {
- return new BackingStoreX(host_, size,
- x11_util::GetVisualFromGtkWidget(native_view()),
- gtk_widget_get_visual(native_view())->depth);
+ gfx::NativeView nview = GetInnerNativeView();
+ if (!nview)
+ return NULL;
+
+ if (UsingBackingStoreSkia()) {
+ return new BackingStoreSkia(host_, size);
+ } else {
+ return new BackingStoreX(host_, size,
+ ui::GetVisualFromGtkWidget(nview),
+ gtk_widget_get_visual(nview)->depth);
+ }
}
-gfx::NativeView RenderWidgetHostViewViews::native_view() const {
+gfx::NativeView RenderWidgetHostViewViews::GetInnerNativeView() const {
// TODO(sad): Ideally this function should be equivalent to GetNativeView, and
// WidgetGtk-specific function call should not be necessary.
- views::WidgetGtk* widget = static_cast<views::WidgetGtk*>(GetWidget());
+ const views::WidgetGtk* widget =
+ static_cast<const views::WidgetGtk*>(GetWidget());
return widget ? widget->window_contents() : NULL;
}
@@ -355,7 +539,8 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) {
// Paint a "hole" in the canvas so that the render of the web page is on
// top of whatever else has already been painted in the views hierarchy.
// Later views might still get to paint on top.
- canvas->FillRectInt(SK_ColorBLACK, 0, 0, kMaxWindowWidth, kMaxWindowHeight,
+ canvas->FillRectInt(SK_ColorBLACK, 0, 0,
+ bounds().width(), bounds().height(),
SkXfermode::kClear_Mode);
// Don't do any painting if the GPU process is rendering directly
@@ -365,7 +550,7 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) {
return;
}
- GdkWindow* window = native_view()->window;
+ GdkWindow* window = GetInnerNativeView()->window;
DCHECK(!about_to_validate_and_paint_);
// TODO(anicolao): get the damage somehow
@@ -375,8 +560,7 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) {
ConvertPointToWidget(this, &origin);
about_to_validate_and_paint_ = true;
- BackingStoreX* backing_store = static_cast<BackingStoreX*>(
- host_->GetBackingStore(true));
+ BackingStore* backing_store = host_->GetBackingStore(true);
// Calling GetBackingStore maybe have changed |invalid_rect_|...
about_to_validate_and_paint_ = false;
@@ -391,9 +575,15 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) {
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(origin,
- paint_rect, x11_util::GetX11WindowFromGdkWindow(window));
- } else {
+
+ if (UsingBackingStoreSkia()) {
+ static_cast<BackingStoreSkia*>(backing_store)->SkiaShowRect(
+ gfx::Point(paint_rect.x(), paint_rect.y()), canvas);
+ } else {
+ static_cast<BackingStoreX*>(backing_store)->XShowRect(origin,
+ paint_rect, ui::GetX11WindowFromGdkWindow(window));
+ }
+ } else if (!UsingBackingStoreSkia()) {
// 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.
@@ -401,7 +591,8 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) {
paint_rect.width(), paint_rect.height() };
gdk_window_begin_paint_rect(window, &rect);
- backing_store->CairoShowRect(paint_rect, GDK_DRAWABLE(window));
+ static_cast<BackingStoreX*>(backing_store)->CairoShowRect(
+ paint_rect, GDK_DRAWABLE(window));
cairo_t* cr = gdk_cairo_create(window);
gdk_cairo_rectangle(cr, &rect);
@@ -410,6 +601,9 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) {
cairo_destroy(cr);
gdk_window_end_paint(window);
+ } else {
+ // TODO(sad)
+ NOTIMPLEMENTED();
}
}
if (!whiteout_start_time_.is_null()) {
@@ -437,7 +631,7 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) {
}
gfx::NativeCursor RenderWidgetHostViewViews::GetCursorForPoint(
- views::Event::EventType type, const gfx::Point& point) {
+ ui::EventType type, const gfx::Point& point) {
return native_cursor_;
}
@@ -488,66 +682,28 @@ void RenderWidgetHostViewViews::OnMouseExited(const views::MouseEvent& event) {
bool RenderWidgetHostViewViews::OnMouseWheel(const views::MouseWheelEvent& e) {
WebMouseWheelEvent wmwe;
- InitializeWebMouseEventFromViewsEvent(e, GetPosition(), &wmwe);
+ InitializeWebMouseEventFromViewsEvent(e, GetMirroredPosition(), &wmwe);
wmwe.type = WebKit::WebInputEvent::MouseWheel;
wmwe.button = WebKit::WebMouseEvent::ButtonNone;
// TODO(sadrul): How do we determine if it's a horizontal scroll?
- wmwe.deltaY = e.GetOffset();
+ wmwe.deltaY = e.offset();
wmwe.wheelTicksY = wmwe.deltaY > 0 ? 1 : -1;
GetRenderWidgetHost()->ForwardWheelEvent(wmwe);
return true;
}
-bool RenderWidgetHostViewViews::OnKeyPressed(const views::KeyEvent &e) {
- // Send key event to input method.
- // TODO host_view->im_context_->ProcessKeyEvent(event);
-
- // This is how it works:
- // (1) If a RawKeyDown event is an accelerator for a reserved command (see
- // Browser::IsReservedCommand), then the command is executed. Otherwise,
- // the event is first sent off to the renderer. The renderer is also
- // notified whether the event would trigger an accelerator in the browser.
- // (2) A Char event is then sent to the renderer.
- // (3) If the renderer does not process the event in step (1), and the event
- // triggers an accelerator, then it will ignore the event in step (2). The
- // renderer also sends back notification to the browser for both steps (1)
- // and (2) about whether the events were processed or not. If the event
- // for (1) is not processed by the renderer, then it is processed by the
- // browser, and (2) is ignored.
-
- NativeWebKeyboardEvent wke;
- wke.type = WebKit::WebInputEvent::RawKeyDown;
- wke.windowsKeyCode = e.GetKeyCode();
- wke.setKeyIdentifierFromWindowsKeyCode();
-
- wke.text[0] = wke.unmodifiedText[0] =
- static_cast<unsigned short>(gdk_keyval_to_unicode(
- app::GdkKeyCodeForWindowsKeyCode(e.GetKeyCode(),
- e.IsShiftDown() ^ e.IsCapsLockDown())));
-
- wke.modifiers = WebInputEventFlagsFromViewsEvent(e);
- ForwardKeyboardEvent(wke);
-
- // send the keypress event
- wke.type = WebKit::WebInputEvent::Char;
- ForwardKeyboardEvent(wke);
-
+bool RenderWidgetHostViewViews::OnKeyPressed(const views::KeyEvent& e) {
+ if (!ime_context_->FilterKeyEvent(e))
+ ForwardKeyEvent(e);
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);
-
+bool RenderWidgetHostViewViews::OnKeyReleased(const views::KeyEvent& e) {
+ if (!ime_context_->FilterKeyEvent(e))
+ ForwardKeyEvent(e);
return TRUE;
}
@@ -577,7 +733,7 @@ void RenderWidgetHostViewViews::DidGainFocus() {
GetRenderWidgetHost()->ForwardMouseEvent(fake_event);
}
#endif
-
+ ime_context_->Focus();
ShowCurrentCursor();
GetRenderWidgetHost()->GotFocus();
}
@@ -585,15 +741,16 @@ void RenderWidgetHostViewViews::DidGainFocus() {
void RenderWidgetHostViewViews::WillLoseFocus() {
// If we are showing a context menu, maintain the illusion that webkit has
// focus.
- if (!is_showing_context_menu_ && !is_hidden_)
- GetRenderWidgetHost()->Blur();
+ if (!is_showing_context_menu_ && !is_hidden_ && host_)
+ host_->Blur();
+ ime_context_->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() || !native_view()->window)
+ if (!GetInnerNativeView() || !GetInnerNativeView()->window)
return;
native_cursor_ = current_cursor_.GetNativeCursor();
@@ -632,7 +789,7 @@ void RenderWidgetHostViewViews::AcceleratedCompositingActivated(
WebKit::WebMouseEvent RenderWidgetHostViewViews::WebMouseEventFromViewsEvent(
const views::MouseEvent& event) {
WebKit::WebMouseEvent wmevent;
- InitializeWebMouseEventFromViewsEvent(event, GetPosition(), &wmevent);
+ InitializeWebMouseEventFromViewsEvent(event, GetMirroredPosition(), &wmevent);
// Setting |wmevent.button| is not necessary for -move events, but it is
// necessary for -clicks and -drags.
@@ -652,63 +809,127 @@ WebKit::WebMouseEvent RenderWidgetHostViewViews::WebMouseEventFromViewsEvent(
return wmevent;
}
-void RenderWidgetHostViewViews::ForwardKeyboardEvent(
+void RenderWidgetHostViewViews::ForwardKeyEvent(
+ const views::KeyEvent& event) {
+ // This is how it works:
+ // (1) If a RawKeyDown event is an accelerator for a reserved command (see
+ // Browser::IsReservedCommand), then the command is executed. Otherwise,
+ // the event is first sent off to the renderer. The renderer is also
+ // notified whether the event would trigger an accelerator in the browser.
+ // (2) A Char event is then sent to the renderer.
+ // (3) If the renderer does not process the event in step (1), and the event
+ // triggers an accelerator, then it will ignore the event in step (2). The
+ // renderer also sends back notification to the browser for both steps (1)
+ // and (2) about whether the events were processed or not. If the event
+ // for (1) is not processed by the renderer, then it is processed by the
+ // browser, and (2) is ignored.
+ if (event.type() == ui::ET_KEY_PRESSED) {
+ NativeWebKeyboardEvent wke;
+
+ wke.type = WebKit::WebInputEvent::RawKeyDown;
+ wke.windowsKeyCode = event.key_code();
+ wke.setKeyIdentifierFromWindowsKeyCode();
+
+ int keyval = ui::GdkKeyCodeForWindowsKeyCode(event.key_code(),
+ event.IsShiftDown() ^ event.IsCapsLockDown());
+
+ wke.text[0] = wke.unmodifiedText[0] =
+ static_cast<unsigned short>(gdk_keyval_to_unicode(keyval));
+
+ wke.modifiers = WebInputEventFlagsFromViewsEvent(event);
+
+ ForwardWebKeyboardEvent(wke);
+
+ wke.type = WebKit::WebInputEvent::Char;
+ ForwardWebKeyboardEvent(wke);
+ } else {
+ NativeWebKeyboardEvent wke;
+
+ wke.type = WebKit::WebInputEvent::KeyUp;
+ wke.windowsKeyCode = event.key_code();
+ wke.setKeyIdentifierFromWindowsKeyCode();
+ ForwardWebKeyboardEvent(wke);
+ }
+}
+
+void RenderWidgetHostViewViews::ForwardWebKeyboardEvent(
const NativeWebKeyboardEvent& event) {
if (!host_)
return;
EditCommands edit_commands;
#if 0
-TODO(bryeung): key bindings
+ // TODO(bryeung): key bindings
if (!event.skip_in_browser &&
key_bindings_handler_->Match(event, &edit_commands)) {
host_->ForwardEditCommandsForNextKeyEvent(edit_commands);
}
#endif
+
host_->ForwardKeyboardEvent(event);
}
-bool RenderWidgetHostViewViews::OnTouchEvent(const views::TouchEvent& e) {
+views::View::TouchStatus RenderWidgetHostViewViews::OnTouchEvent(
+ const views::TouchEvent& e) {
// Update the list of touch points first.
WebKit::WebTouchPoint* point = NULL;
+ TouchStatus status = TOUCH_STATUS_UNKNOWN;
- switch (e.GetType()) {
- case views::Event::ET_TOUCH_PRESSED:
+ switch (e.type()) {
+ case ui::ET_TOUCH_PRESSED:
// Add a new touch point.
if (touch_event_.touchPointsLength <
WebTouchEvent::touchPointsLengthCap) {
point = &touch_event_.touchPoints[touch_event_.touchPointsLength++];
point->id = e.identity();
+
+ if (touch_event_.touchPointsLength == 1) {
+ // A new touch sequence has started.
+ status = TOUCH_STATUS_START;
+
+ // We also want the focus.
+ RequestFocus();
+ }
}
break;
- case views::Event::ET_TOUCH_RELEASED:
- case views::Event::ET_TOUCH_CANCELLED:
- case views::Event::ET_TOUCH_MOVED: {
+ case ui::ET_TOUCH_RELEASED:
+ case ui::ET_TOUCH_CANCELLED:
+ case ui::ET_TOUCH_MOVED: {
// The touch point should have been added to the event from an earlier
// _PRESSED event. So find that.
// At the moment, only a maximum of 4 touch-points are allowed. So a
// simple loop should be sufficient.
- for (int i = 0; i < WebTouchEvent::touchPointsLengthCap; ++i) {
+ for (int i = 0; i < touch_event_.touchPointsLength; ++i) {
point = touch_event_.touchPoints + i;
if (point->id == e.identity()) {
break;
}
point = NULL;
}
- DCHECK(point != NULL) << "Touchpoint not found for event " << e.GetType();
break;
}
default:
- DLOG(WARNING) << "Unknown touch event " << e.GetType();
+ DLOG(WARNING) << "Unknown touch event " << e.type();
break;
}
if (!point)
- return false;
+ return TOUCH_STATUS_UNKNOWN;
+
+ if (status != TOUCH_STATUS_START)
+ status = TOUCH_STATUS_CONTINUE;
// Update the location and state of the point.
- UpdateTouchPointPosition(&e, GetPosition(), point);
point->state = TouchPointStateFromEvent(&e);
+ if (point->state == WebKit::WebTouchPoint::StateMoved) {
+ // It is possible for badly written touch drivers to emit Move events even
+ // when the touch location hasn't changed. In such cases, consume the event
+ // and pretend nothing happened.
+ if (point->position.x == e.x() && point->position.y == e.y()) {
+ return status;
+ }
+ }
+ UpdateTouchPointPosition(&e, GetMirroredPosition(), point);
// Mark the rest of the points as stationary.
for (int i = 0; i < touch_event_.touchPointsLength; ++i) {
@@ -720,21 +941,30 @@ bool RenderWidgetHostViewViews::OnTouchEvent(const views::TouchEvent& e) {
// Update the type of the touch event.
touch_event_.type = TouchEventTypeFromEvent(&e);
+ touch_event_.timeStampSeconds = base::Time::Now().ToDoubleT();
// The event and all the touches have been updated. Dispatch.
host_->ForwardTouchEvent(touch_event_);
// If the touch was released, then remove it from the list of touch points.
- if (e.GetType() == views::Event::ET_TOUCH_RELEASED) {
+ if (e.type() == ui::ET_TOUCH_RELEASED) {
--touch_event_.touchPointsLength;
for (int i = point - touch_event_.touchPoints;
i < touch_event_.touchPointsLength;
++i) {
touch_event_.touchPoints[i] = touch_event_.touchPoints[i + 1];
}
+ if (touch_event_.touchPointsLength == 0)
+ status = TOUCH_STATUS_END;
+ } else if (e.type() == ui::ET_TOUCH_CANCELLED) {
+ status = TOUCH_STATUS_CANCEL;
}
- return true;
+ return status;
+}
+
+std::string RenderWidgetHostViewViews::GetClassName() const {
+ return kViewClassName;
}
// static