diff options
author | mazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-03 09:02:24 +0000 |
---|---|---|
committer | mazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-03 09:02:24 +0000 |
commit | 2d0f2e95d4a44967424a7bb735d5263da3dea581 (patch) | |
tree | 9b2868014f1f58f4d369e73b162c75ccecabda0f | |
parent | 219e07987f9ec4e40418b251b4960681af726d53 (diff) | |
download | chromium_src-2d0f2e95d4a44967424a7bb735d5263da3dea581.zip chromium_src-2d0f2e95d4a44967424a7bb735d5263da3dea581.tar.gz chromium_src-2d0f2e95d4a44967424a7bb735d5263da3dea581.tar.bz2 |
Show keyboard when the focused editable field is touched inside the web content area.
When an editable fieled is touched and the focus is moved to the element, NOTIFICATION_FOCUS_CHANGED_IN_PAGE is sent. However, if the field is already focused, no notification is sent. But keyboard should be shown in such a case.
This CL
- Adds NOTIFICATION_FOCUSED_EDITABLE_NODE_TOUCHED notification, which is sent when the focused editable field is touched,
- Adds ChromeViewHostMsg_FocusedEditableNodeTouched IPC message, which is sent from renderer to browser when a touch released on the focused editable field,
- Changes RenderWidget to handle touch events in OnHandleInputEvent, and
- Handles NOTIFICATION_FOCUSED_EDITABLE_NODE_TOUCHED in KeyboardWidget to show keyboard.
BUG=none
TEST=Manual
Review URL: http://codereview.chromium.org/7923005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103694 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/renderer_host/chrome_render_view_host_observer.cc | 9 | ||||
-rw-r--r-- | chrome/browser/renderer_host/chrome_render_view_host_observer.h | 1 | ||||
-rw-r--r-- | chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc | 32 | ||||
-rw-r--r-- | chrome/common/chrome_notification_types.h | 5 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 4 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_view_observer.cc | 31 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_view_observer.h | 1 | ||||
-rw-r--r-- | content/renderer/render_view.cc | 5 | ||||
-rw-r--r-- | content/renderer/render_view.h | 2 | ||||
-rw-r--r-- | content/renderer/render_view_observer.h | 2 | ||||
-rw-r--r-- | content/renderer/render_widget.cc | 3 | ||||
-rw-r--r-- | content/renderer/render_widget.h | 5 |
12 files changed, 100 insertions, 0 deletions
diff --git a/chrome/browser/renderer_host/chrome_render_view_host_observer.cc b/chrome/browser/renderer_host/chrome_render_view_host_observer.cc index 6b573b5..6d1a8e27 100644 --- a/chrome/browser/renderer_host/chrome_render_view_host_observer.cc +++ b/chrome/browser/renderer_host/chrome_render_view_host_observer.cc @@ -53,6 +53,8 @@ bool ChromeRenderViewHostObserver::OnMessageReceived( IPC_BEGIN_MESSAGE_MAP(ChromeRenderViewHostObserver, message) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DomOperationResponse, OnDomOperationResponse) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FocusedEditableNodeTouched, + OnFocusedEditableNodeTouched) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -152,3 +154,10 @@ void ChromeRenderViewHostObserver::OnDomOperationResponse( Source<RenderViewHost>(render_view_host()), Details<DomOperationNotificationDetails>(&details)); } + +void ChromeRenderViewHostObserver::OnFocusedEditableNodeTouched() { + NotificationService::current()->Notify( + chrome::NOTIFICATION_FOCUSED_EDITABLE_NODE_TOUCHED, + Source<RenderViewHost>(render_view_host()), + NotificationService::NoDetails()); +} diff --git a/chrome/browser/renderer_host/chrome_render_view_host_observer.h b/chrome/browser/renderer_host/chrome_render_view_host_observer.h index 5a5eaa8..e5e83dc 100644 --- a/chrome/browser/renderer_host/chrome_render_view_host_observer.h +++ b/chrome/browser/renderer_host/chrome_render_view_host_observer.h @@ -39,6 +39,7 @@ class ChromeRenderViewHostObserver : public RenderViewHostObserver { void OnDomOperationResponse(const std::string& json_string, int automation_id); + void OnFocusedEditableNodeTouched(); chrome_browser_net::Predictor* predictor_; diff --git a/chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc b/chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc index e8a35a9..31550cb 100644 --- a/chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc +++ b/chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc @@ -11,8 +11,11 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/tabs/tab_strip_model.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/views/dom_view.h" +#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/extension_messages.h" #include "chrome/common/url_constants.h" @@ -86,6 +89,10 @@ class KeyboardWidget // Sets the target widget, adds/removes Widget::Observer, reparents etc. void SetTarget(Widget* target); + // Returns the widget of the active browser, or NULL if there is no such + // widget. + views::Widget* GetBrowserWidget(); + // Overridden from views::Widget. virtual bool OnKeyEvent(const views::KeyEvent& event) OVERRIDE; @@ -180,6 +187,9 @@ KeyboardWidget::KeyboardWidget() views::TextInputTypeTracker::GetInstance()->AddTextInputTypeObserver(this); registrar_.Add(this, + chrome::NOTIFICATION_FOCUSED_EDITABLE_NODE_TOUCHED, + NotificationService::AllSources()); + registrar_.Add(this, chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED, NotificationService::AllSources()); registrar_.Add(this, @@ -210,6 +220,8 @@ KeyboardWidget::~KeyboardWidget() { } void KeyboardWidget::ShowKeyboardForWidget(views::Widget* widget) { + if (target_ == widget && IsVisible()) + return; SetTarget(widget); transform_.reset(new ui::InterpolatedTranslation( @@ -256,6 +268,16 @@ void KeyboardWidget::SetTarget(views::Widget* target) { } } +views::Widget* KeyboardWidget::GetBrowserWidget() { + Browser* browser = GetBrowser(); + if (!browser) + return NULL; + BrowserView* view = BrowserView::GetBrowserViewForBrowser(browser); + if (!view) + return NULL; + return view->GetWidget(); +} + bool KeyboardWidget::OnKeyEvent(const views::KeyEvent& event) { return target_ ? target_->OnKeyEvent(event) : false; } @@ -384,6 +406,16 @@ void KeyboardWidget::Observe(int type, const NotificationSource& source, const NotificationDetails& details) { switch (type) { + case chrome::NOTIFICATION_FOCUSED_EDITABLE_NODE_TOUCHED: { + // In case the keyboard hid itself and the focus is still in an editable + // field, and the user touches the field, then we want to show the + // keyboard again. + views::Widget* widget = GetBrowserWidget(); + if (widget) + ShowKeyboardForWidget(widget); + break; + } + case chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED: { Hide(); break; diff --git a/chrome/common/chrome_notification_types.h b/chrome/common/chrome_notification_types.h index 523d392..aeafa8e 100644 --- a/chrome/common/chrome_notification_types.h +++ b/chrome/common/chrome_notification_types.h @@ -121,6 +121,11 @@ enum NotificationType { // The source is the ExtensionTabHelper SetAppExtension was invoked on. NOTIFICATION_TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, + // Notification posted when the element that is focused and currently accepts + // keyboard input inside the webpage has been touched. The source is the + // RenderViewHost and the details are not used. + NOTIFICATION_FOCUSED_EDITABLE_NODE_TOUCHED, + // Stuff inside the tabs --------------------------------------------------- // Notification from TabContents that we have received a response from the diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 84d1cff..6bd830a 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -526,6 +526,10 @@ IPC_MESSAGE_ROUTED0(ChromeViewHostMsg_DidBlockDisplayingInsecureContent) // a secure origin by a security policy. The page may appear incomplete. IPC_MESSAGE_ROUTED0(ChromeViewHostMsg_DidBlockRunningInsecureContent) +// Message sent from renderer to the browser when the element that is focused +// and currently accepts keyboard input inside the webpage has been touched. +IPC_MESSAGE_ROUTED0(ChromeViewHostMsg_FocusedEditableNodeTouched) + // Suggest results ----------------------------------------------------------- IPC_MESSAGE_ROUTED3(ChromeViewHostMsg_SetSuggestions, diff --git a/chrome/renderer/chrome_render_view_observer.cc b/chrome/renderer/chrome_render_view_observer.cc index 4016919..444eb07 100644 --- a/chrome/renderer/chrome_render_view_observer.cc +++ b/chrome/renderer/chrome_render_view_observer.cc @@ -30,10 +30,12 @@ #include "net/base/data_url.h" #include "skia/ext/image_operations.h" #include "skia/ext/platform_canvas.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObject.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" @@ -48,6 +50,7 @@ #include "webkit/glue/webkit_glue.h" #include "v8/include/v8-testing.h" +using WebKit::WebAccessibilityObject; using WebKit::WebCString; using WebKit::WebDataSource; using WebKit::WebFrame; @@ -56,6 +59,7 @@ using WebKit::WebRect; using WebKit::WebSecurityOrigin; using WebKit::WebSize; using WebKit::WebString; +using WebKit::WebTouchEvent; using WebKit::WebURL; using WebKit::WebURLRequest; using WebKit::WebView; @@ -723,6 +727,33 @@ void ChromeRenderViewObserver::DidClearWindowObject(WebFrame* frame) { } } +void ChromeRenderViewObserver::DidHandleTouchEvent(const WebTouchEvent& event) { + // TODO(mazda): Consider using WebKit::WebInputEvent::GestureTap event when + // it's implemented. Only sends the message on touch end event + // for now. + if (event.type != WebKit::WebInputEvent::TouchEnd) + return; + // Ignore the case of multiple touches + if (event.touchesLength != 1) + return; + if (render_view()->webview()->textInputType() == WebKit::WebTextInputTypeNone) + return; + WebKit::WebNode node = render_view()->GetFocusedNode(); + if (node.isNull()) + return; + WebKit::WebAccessibilityObject accessibility = + render_view()->webview()->accessibilityObject(); + if (accessibility.isNull()) + return; + const WebKit::WebTouchPoint point = event.touches[0]; + accessibility = accessibility.hitTest(point.position); + if (accessibility.isNull()) + return; + if (accessibility.node() == node) + render_view()->Send(new ChromeViewHostMsg_FocusedEditableNodeTouched( + render_view()->routing_id())); +} + void ChromeRenderViewObserver::CapturePageInfo(int load_id, bool preliminary_capture) { if (load_id != render_view()->page_id()) diff --git a/chrome/renderer/chrome_render_view_observer.h b/chrome/renderer/chrome_render_view_observer.h index cf1497e..a52c311 100644 --- a/chrome/renderer/chrome_render_view_observer.h +++ b/chrome/renderer/chrome_render_view_observer.h @@ -68,6 +68,7 @@ class ChromeRenderViewObserver : public RenderViewObserver, virtual void DidCommitProvisionalLoad(WebKit::WebFrame* frame, bool is_new_navigation) OVERRIDE; virtual void DidClearWindowObject(WebKit::WebFrame* frame) OVERRIDE; + virtual void DidHandleTouchEvent(const WebKit::WebTouchEvent& event) OVERRIDE; // WebKit::WebPermissionClient implementation. virtual bool allowDatabase(WebKit::WebFrame* frame, diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc index 8d08fab..91d9c2d 100644 --- a/content/renderer/render_view.cc +++ b/content/renderer/render_view.cc @@ -223,6 +223,7 @@ using WebKit::WebStorageQuotaType; using WebKit::WebString; using WebKit::WebTextAffinity; using WebKit::WebTextDirection; +using WebKit::WebTouchEvent; using WebKit::WebURL; using WebKit::WebURLError; using WebKit::WebURLRequest; @@ -3948,6 +3949,10 @@ void RenderView::DidHandleMouseEvent(const WebKit::WebMouseEvent& event) { FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidHandleMouseEvent(event)); } +void RenderView::DidHandleTouchEvent(const WebTouchEvent& event) { + FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidHandleTouchEvent(event)); +} + void RenderView::OnWasHidden() { RenderWidget::OnWasHidden(); diff --git a/content/renderer/render_view.h b/content/renderer/render_view.h index 245e196..31a3141 100644 --- a/content/renderer/render_view.h +++ b/content/renderer/render_view.h @@ -134,6 +134,7 @@ class WebPlugin; class WebSpeechInputController; class WebSpeechInputListener; class WebStorageNamespace; +class WebTouchEvent; class WebURLLoader; class WebURLRequest; class WebView; @@ -649,6 +650,7 @@ class RenderView : public RenderWidget, virtual bool WillHandleMouseEvent( const WebKit::WebMouseEvent& event) OVERRIDE; virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event); + virtual void DidHandleTouchEvent(const WebKit::WebTouchEvent& event); virtual void OnSetFocus(bool enable); virtual void OnWasHidden(); virtual void OnWasRestored(bool needs_repainting); diff --git a/content/renderer/render_view_observer.h b/content/renderer/render_view_observer.h index de5dda5..6f42f86 100644 --- a/content/renderer/render_view_observer.h +++ b/content/renderer/render_view_observer.h @@ -21,6 +21,7 @@ class WebMediaPlayerClient; class WebMouseEvent; class WebNode; class WebString; +class WebTouchEvent; class WebURL; struct WebURLError; } @@ -67,6 +68,7 @@ class CONTENT_EXPORT RenderViewObserver : public IPC::Channel::Listener, // These match the RenderView methods. virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {} + virtual void DidHandleTouchEvent(const WebKit::WebTouchEvent& event) {} virtual void WillCreateMediaPlayer(WebKit::WebFrame* frame, WebKit::WebMediaPlayerClient* client) {} diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 2f0dfc2..b57c11c 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -58,6 +58,7 @@ using WebKit::WebRect; using WebKit::WebScreenInfo; using WebKit::WebSize; using WebKit::WebTextDirection; +using WebKit::WebTouchEvent; using WebKit::WebVector; using WebKit::WebWidget; @@ -493,6 +494,8 @@ void RenderWidget::OnHandleInputEvent(const IPC::Message& message) { DidHandleKeyEvent(); if (WebInputEvent::isMouseEventType(input_event->type)) DidHandleMouseEvent(*(static_cast<const WebMouseEvent*>(input_event))); + if (WebInputEvent::isTouchEventType(input_event->type)) + DidHandleTouchEvent(*(static_cast<const WebTouchEvent*>(input_event))); } } diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index f44f289..624888b 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h @@ -46,6 +46,7 @@ class PlatformCanvas; namespace WebKit { class WebInputEvent; class WebMouseEvent; +class WebTouchEvent; class WebWidget; struct WebPopupMenuInfo; } @@ -314,6 +315,10 @@ class CONTENT_EXPORT RenderWidget // just handled. virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {} + // Called by OnHandleInputEvent() to notify subclasses that a touch event was + // just handled. + virtual void DidHandleTouchEvent(const WebKit::WebTouchEvent& event) {} + // Routing ID that allows us to communicate to the parent browser process // RenderWidgetHost. When MSG_ROUTING_NONE, no messages may be sent. int32 routing_id_; |