Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
commit 9e1efdf0cbd9600c543fa8fe8e2ad60261353e36
Author: Kenneth Rohde Christiansen <kenneth@webkit.org>
Date: Fri Jan 6 16:32:31 2012 +0100
WIP
diff --git a/Source/WebCore/loader/EmptyClients.h b/Source/WebCore/loader/EmptyClients.h
index 8d1fe7d..23c86ba 100644
--- a/Source/WebCore/loader/EmptyClients.h
+++ b/Source/WebCore/loader/EmptyClients.h
@@ -524,7 +524,7 @@ public:
virtual bool spellingUIIsShowing() { return false; }
virtual void willSetInputMethodState() { }
- virtual void setInputMethodState(bool) { }
+ virtual void setInputMethodState(bool, FocusController::StateChangeReason) { }
private:
EmptyTextCheckerClient m_textCheckerClient;
diff --git a/Source/WebCore/page/EditorClient.h b/Source/WebCore/page/EditorClient.h
index 5a4be2c..0ff62ac 100644
--- a/Source/WebCore/page/EditorClient.h
+++ b/Source/WebCore/page/EditorClient.h
@@ -30,6 +30,7 @@
#include "SpellingCorrectionController.h"
#include "EditorInsertAction.h"
#include "FloatRect.h"
+#include "FocusController.h"
#include "TextAffinity.h"
#include "UndoStep.h"
#include <wtf/Forward.h>
@@ -167,7 +168,7 @@ public:
virtual void showSpellingUI(bool show) = 0;
virtual bool spellingUIIsShowing() = 0;
virtual void willSetInputMethodState() = 0;
- virtual void setInputMethodState(bool enabled) = 0;
+ virtual void setInputMethodState(bool, FocusController::StateChangeReason) = 0;
};
}
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index c21eb7e..e218386 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -38,6 +38,7 @@
#include "DragController.h"
#include "DragState.h"
#include "Editor.h"
+#include "EditorClient.h"
#include "EventNames.h"
#include "FloatPoint.h"
#include "FloatRect.h"
@@ -2244,8 +2245,27 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
PlatformMouseEvent fakeMouseDown(gestureEvent.position(), gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, /* clickCount */ 1, gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
PlatformMouseEvent fakeMouseUp(gestureEvent.position(), gestureEvent.globalPosition(), LeftButton, PlatformEvent::MouseReleased, /* clickCount */ 1, gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
mouseMoved(fakeMouseMove);
+
+ // Input methods which act as primary input device (AKA virtual keyboards) appear and
+ // disappear when something gains or looses focus. As this can happen multiple times
+ // during the fake mouse events, we have to postpone the state changes here.
+
+ // Elements can loose focus on mousedownEvent but get focused via for instance
+ // the DOM during clickEvent. To not hide and reshow the input method editor, we
+ // disable it until after all event processing.
+ m_frame->page()->editorClient()->willSetInputMethodState();
+ m_frame->page()->focusController()->setPostponeInputMethodStateChanges(true);
+
handleMousePressEvent(fakeMouseDown);
handleMouseReleaseEvent(fakeMouseUp);
+
+ // Reenable the input method, which will reset the state and show the input method iff:
+ // a) an editable element received mousedownEvent and got focused.
+ // b) an editable element received focus via JavaScript focus() as a result of a clickEvent.
+ // c) an editable element received focus as a result of a clickEvent on a <label for=name>.
+ m_frame->page()->focusController()->setPostponeInputMethodStateChanges(false);
+ m_frame->page()->focusController()->inputMethodStateDidChange(FocusController::TapStateChangeReason);
+
return true;
}
case PlatformEvent::GestureScrollUpdate: {
diff --git a/Source/WebCore/page/FocusController.cpp b/Source/WebCore/page/FocusController.cpp
index 4f58df3..6f5d03f 100644
--- a/Source/WebCore/page/FocusController.cpp
+++ b/Source/WebCore/page/FocusController.cpp
@@ -85,6 +85,7 @@ static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool
FocusController::FocusController(Page* page)
: m_page(page)
+ , m_postponeInputMethodStateChanges(false)
, m_isActive(false)
, m_isFocused(false)
, m_isChangingFocusedFrame(false)
@@ -511,11 +512,36 @@ static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFram
s->clear();
}
+void FocusController::inputMethodStateDidChange(FocusController::StateChangeReason reason)
+{
+ if (m_postponeInputMethodStateChanges)
+ return;
+
+ // We need to check the editor state, as we can be in edit mode even when focusing
+ // a non-editable node. This is due to content editable and design mode, where it
+ // is possible to click on links etc to change into to bold, etc.
+ bool mayEdit = focusedOrMainFrame()->editor()->canEdit();
+
+#if !PLATFORM(QT)
+ // Check whether to disallow editing using input methods (disabled for password fields).
+ Node* focusedNode = focusedOrMainFrame()->document()->focusedNode();
+ if (focusedNode && !focusedNode->shouldUseInputMethod())
+ mayEdit = false;
+#endif
+
+ m_page->editorClient()->setInputMethodState(mayEdit, reason);
+}
+
+void FocusController::setPostponeInputMethodStateChanges(bool enable)
+{
+ m_postponeInputMethodStateChanges = enable;
+}
+
bool FocusController::setFocusedNode(Node* node, PassRefPtr<Frame> newFocusedFrame)
{
RefPtr<Frame> oldFocusedFrame = focusedFrame();
RefPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : 0;
-
+
Node* oldFocusedNode = oldDocument ? oldDocument->focusedNode() : 0;
if (oldFocusedNode == node)
return true;
@@ -531,23 +557,23 @@ bool FocusController::setFocusedNode(Node* node, PassRefPtr<Frame> newFocusedFra
if (!node) {
if (oldDocument)
oldDocument->setFocusedNode(0);
- m_page->editorClient()->setInputMethodState(false);
+ inputMethodStateDidChange();
return true;
}
RefPtr<Document> newDocument = node->document();
if (newDocument && newDocument->focusedNode() == node) {
- m_page->editorClient()->setInputMethodState(node->shouldUseInputMethod());
+ inputMethodStateDidChange();
return true;
}
-
+
if (oldDocument && oldDocument != newDocument)
oldDocument->setFocusedNode(0);
-
+
setFocusedFrame(newFocusedFrame);
- // Setting the focused node can result in losing our last reft to node when JS event handlers fire.
+ // Setting the focused node can result in losing our last ref to node when JS event handlers fire.
RefPtr<Node> protect = node;
if (newDocument) {
bool successfullyFocused = newDocument->setFocusedNode(node);
@@ -556,7 +582,7 @@ bool FocusController::setFocusedNode(Node* node, PassRefPtr<Frame> newFocusedFra
}
if (newDocument->focusedNode() == node)
- m_page->editorClient()->setInputMethodState(node->shouldUseInputMethod());
+ inputMethodStateDidChange();
return true;
}
diff --git a/Source/WebCore/page/FocusController.h b/Source/WebCore/page/FocusController.h
index 6880a1c..59b0d00 100644
--- a/Source/WebCore/page/FocusController.h
+++ b/Source/WebCore/page/FocusController.h
@@ -54,7 +54,11 @@ public:
bool setInitialFocus(FocusDirection, KeyboardEvent*);
bool advanceFocus(FocusDirection, KeyboardEvent*, bool initialFocus = false);
-
+
+ void setPostponeInputMethodStateChanges(bool);
+ enum StateChangeReason { TapStateChangeReason, OtherStateChangeReason };
+ void inputMethodStateDidChange(StateChangeReason reason = OtherStateChangeReason);
+
bool setFocusedNode(Node*, PassRefPtr<Frame>);
void setActive(bool);
@@ -93,6 +97,7 @@ private:
Page* m_page;
RefPtr<Frame> m_focusedFrame;
+ bool m_postponeInputMethodStateChanges;
bool m_isActive;
bool m_isFocused;
bool m_isChangingFocusedFrame;
diff --git a/Source/WebKit/chromium/src/EditorClientImpl.cpp b/Source/WebKit/chromium/src/EditorClientImpl.cpp
index 5fa2378..4b93e12 100644
--- a/Source/WebKit/chromium/src/EditorClientImpl.cpp
+++ b/Source/WebKit/chromium/src/EditorClientImpl.cpp
@@ -807,4 +807,9 @@ void EditorClientImpl::setInputMethodState(bool)
{
}
-} // namesace WebKit
+bool EditorClientImpl::inputMethodIsPrimaryInputDevice()
+{
+ return false;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/chromium/src/EditorClientImpl.h b/Source/WebKit/chromium/src/EditorClientImpl.h
index 233695f..9985db6 100644
--- a/Source/WebKit/chromium/src/EditorClientImpl.h
+++ b/Source/WebKit/chromium/src/EditorClientImpl.h
@@ -107,6 +107,7 @@ public:
virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses);
virtual void willSetInputMethodState();
virtual void setInputMethodState(bool enabled);
+ virtual bool inputMethodIsPrimaryInputDevice();
virtual void requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&);
virtual WebCore::TextCheckerClient* textChecker() { return this; }
diff --git a/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp
index 78563ec..27e4836 100644
--- a/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp
+++ b/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp
@@ -50,6 +50,12 @@ void EditorClientEfl::setInputMethodState(bool active)
ewk_view_input_method_state_set(m_view, active);
}
+bool EditorClientEfl::inputMethodIsPrimaryInputDevice()
+{
+ notImplemented();
+ return false;
+}
+
bool EditorClientEfl::shouldDeleteRange(Range*)
{
notImplemented();
diff --git a/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.h b/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.h
index 7ff1813..846a2ed 100644
--- a/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.h
+++ b/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.h
@@ -120,6 +120,7 @@ public:
virtual void getGuessesForWord(const String& word, const String& context, WTF::Vector<String>& guesses);
virtual void willSetInputMethodState();
virtual void setInputMethodState(bool enabled);
+ virtual bool inputMethodIsPrimaryInputDevice();
virtual void requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&) { }
virtual TextCheckerClient* textChecker() { return this; }
diff --git a/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp b/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp
index 913b0df..5c0a4a1 100644
--- a/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp
+++ b/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp
@@ -133,6 +133,11 @@ void EditorClient::setInputMethodState(bool active)
#endif
}
+bool EditorClient::inputMethodIsPrimaryInputDevice()
+{
+ return false;
+}
+
bool EditorClient::shouldDeleteRange(Range* range)
{
gboolean accept = TRUE;
diff --git a/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.h b/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.h
index 2533c16..e304f36 100644
--- a/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.h
+++ b/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.h
@@ -136,6 +136,7 @@ class EditorClient : public WebCore::EditorClient {
virtual bool spellingUIIsShowing();
virtual void willSetInputMethodState();
virtual void setInputMethodState(bool enabled);
+ virtual bool inputMethodIsPrimaryInputDevice();
private:
#if ENABLE(SPELLCHECK)
diff --git a/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h b/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h
index c70d608..b0d5aca 100644
--- a/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h
+++ b/Source/WebKit/mac/WebCoreSupport/WebEditorClient.h
@@ -135,6 +135,7 @@ public:
virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses) OVERRIDE;
virtual void willSetInputMethodState() OVERRIDE;
virtual void setInputMethodState(bool enabled) OVERRIDE;
+ virtual bool inputMethodIsPrimaryInputDevice() OVERRIDE;
virtual void requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&) OVERRIDE;
#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
virtual void showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) OVERRIDE;
diff --git a/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm b/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm
index 8cb31f8..ed24f88 100644
--- a/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm
+++ b/Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm
@@ -937,6 +937,11 @@ void WebEditorClient::setInputMethodState(bool)
{
}
+bool WebEditorClient::inputMethodIsPrimaryInputDevice()
+{
+ return NO;
+}
+
#ifndef BUILDING_ON_LEOPARD
@interface WebEditorSpellCheckResponder : NSObject
{
diff --git a/Source/WebKit/qt/WebCoreSupport/EditorClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/EditorClientQt.cpp
index 1d80803..9fdbb93 100644
--- a/Source/WebKit/qt/WebCoreSupport/EditorClientQt.cpp
+++ b/Source/WebKit/qt/WebCoreSupport/EditorClientQt.cpp
@@ -632,6 +632,11 @@ void EditorClientQt::setInputMethodState(bool active)
emit m_page->microFocusChanged();
}
+bool EditorClientQt::inputMethodIsPrimaryInputDevice()
+{
+ return false;
+}
+
}
// vim: ts=4 sw=4 et
diff --git a/Source/WebKit/qt/WebCoreSupport/EditorClientQt.h b/Source/WebKit/qt/WebCoreSupport/EditorClientQt.h
index c20f975..574ecbe 100644
--- a/Source/WebKit/qt/WebCoreSupport/EditorClientQt.h
+++ b/Source/WebKit/qt/WebCoreSupport/EditorClientQt.h
@@ -102,6 +102,7 @@ public:
virtual bool spellingUIIsShowing();
virtual void willSetInputMethodState();
virtual void setInputMethodState(bool enabled);
+ virtual bool inputMethodIsPrimaryInputDevice() OVERRIDE;
virtual TextCheckerClient* textChecker() { return &m_textCheckerClient; }
bool isEditing() const;
diff --git a/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp b/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp
index 0b26530..749d479 100644
--- a/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp
+++ b/Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp
@@ -789,3 +789,9 @@ void WebEditorClient::setInputMethodState(bool enabled)
{
m_webView->setInputMethodState(enabled);
}
+
+bool WebEditorClient::inputMethodIsPrimaryInputDevice()
+{
+ return false;
+}
+
diff --git a/Source/WebKit/win/WebCoreSupport/WebEditorClient.h b/Source/WebKit/win/WebCoreSupport/WebEditorClient.h
index a40586c..d7aab91 100644
--- a/Source/WebKit/win/WebCoreSupport/WebEditorClient.h
+++ b/Source/WebKit/win/WebCoreSupport/WebEditorClient.h
@@ -110,6 +110,7 @@ public:
virtual void willSetInputMethodState();
virtual void setInputMethodState(bool);
+ virtual bool inputMethodIsPrimaryInputDevice();
virtual void requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&) {}
virtual WebCore::TextCheckerClient* textChecker() { return this; }
diff --git a/Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.cpp b/Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.cpp
index 4cd3aac..01f1c50 100644
--- a/Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.cpp
+++ b/Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.cpp
@@ -501,4 +501,10 @@ void EditorClientWinCE::willSetInputMethodState()
notImplemented();
}
+bool EditorClientWinCE::inputMethodIsPrimaryInputDevice()
+{
+ notImplemented();
+ return false;
+}
+
} // namespace WebKit
diff --git a/Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.h b/Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.h
index c29524e..ed177b8 100644
--- a/Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.h
+++ b/Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.h
@@ -101,6 +101,7 @@ public:
virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses);
virtual void willSetInputMethodState();
virtual void setInputMethodState(bool);
+ virtual bool inputMethodIsPrimaryInputDevice();
virtual void requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&) {}
virtual WebCore::TextCheckerClient* textChecker() { return this; }
diff --git a/Source/WebKit/wx/WebKitSupport/EditorClientWx.cpp b/Source/WebKit/wx/WebKitSupport/EditorClientWx.cpp
index e8cf31d..484a070 100644
--- a/Source/WebKit/wx/WebKitSupport/EditorClientWx.cpp
+++ b/Source/WebKit/wx/WebKitSupport/EditorClientWx.cpp
@@ -560,4 +560,10 @@ void EditorClientWx::setInputMethodState(bool enabled)
notImplemented();
}
+bool EditorClientWx::inputMethodIsPrimaryInputDevice()
+{
+ notImplemented();
+ return false;
+}
+
}
diff --git a/Source/WebKit/wx/WebKitSupport/EditorClientWx.h b/Source/WebKit/wx/WebKitSupport/EditorClientWx.h
index 1387fb8..85e3576 100644
--- a/Source/WebKit/wx/WebKitSupport/EditorClientWx.h
+++ b/Source/WebKit/wx/WebKitSupport/EditorClientWx.h
@@ -114,6 +114,8 @@ public:
virtual void willSetInputMethodState();
virtual void setInputMethodState(bool enabled);
+ virtual bool inputMethodIsPrimaryInputDevice();
+
virtual void requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&) {}
virtual TextCheckerClient* textChecker() { return this; }
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp
index 1e39864..3c1dd85 100644
--- a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp
+++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp
@@ -185,11 +185,6 @@ void WebEditorClient::respondToChangedSelection(Frame* frame)
EditorState state = m_page->editorState();
-#if PLATFORM(QT)
- if (Element* scope = frame->selection()->rootEditableElement())
- m_page->send(Messages::WebPageProxy::FocusEditableArea(state.microFocus, scope->getRect()));
-#endif
-
m_page->send(Messages::WebPageProxy::EditorStateChanged(state));
#if PLATFORM(WIN)
@@ -445,8 +440,19 @@ void WebEditorClient::willSetInputMethodState()
notImplemented();
}
-void WebEditorClient::setInputMethodState(bool)
+void WebEditorClient::setInputMethodState(bool active, FocusController::StateChangeReason reason)
{
+#if PLATFORM(QT)
+ if (reason != FocusController::TapStateChangeReason)
+ return;
+
+ Frame* frame = m_page->corePage()->focusController()->focusedOrMainFrame();
+ Element* scope = frame->selection()->rootEditableElement();
+ if (active && scope)
+ m_page->send(Messages::WebPageProxy::FocusEditableArea(m_page->editorState().microFocus, scope->getRect()));
+ return;
+#endif
+
notImplemented();
}
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h
index 6664275..69c6a83 100644
--- a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h
+++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h
@@ -139,7 +139,7 @@ private:
virtual bool spellingUIIsShowing() OVERRIDE;
virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) OVERRIDE;
virtual void willSetInputMethodState() OVERRIDE;
- virtual void setInputMethodState(bool enabled) OVERRIDE;
+ virtual void setInputMethodState(bool, WebCore::FocusController::StateChangeReason reason) OVERRIDE;
virtual void requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&) OVERRIDE;
#if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
virtual void showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) OVERRIDE;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment