https://bugs.webkit.org/show_bug.cgi?id=129812
Reviewed by Darin Adler.
Source/WebCore:
No significant behavior changes expected, except for Esc key processing, which now
dispatches a keypress before executing its default action.
* platform/KeypressCommand.h: Added.
(WebCore::KeypressCommand::KeypressCommand):
* GNUmakefile.list.am:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
Moved KeypressCommand from dom/KeyboardEvent.h to its own header, as it needed
in platform/ directory now.
* dom/KeyboardEvent.cpp:
(WebCore::KeyboardEvent::KeyboardEvent):
* dom/KeyboardEvent.h:
(WebCore::KeyboardEvent::handledByInputMethod):
(WebCore::KeyboardEvent::keypressCommands):
* platform/PlatformKeyboardEvent.h:
(WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent):
(WebCore::PlatformKeyboardEvent::handledByInputMethod):
(WebCore::PlatformKeyboardEvent::commands):
PlatformKeyboardEvent now carries results of interpreting the event by AppKit. This
is logically not much different from carrying charcode, and is similar to what Gtk
does for input methods.
KeyboardEvent already had keypress commands, which were added to it after construction.
It's still possible for WebKit1, while with WebKit2, they are provided at construction
time. The event now also has a boolean for whether IM handled it already.
Source/WebKit/mac:
* WebCoreSupport/WebEditorClient.mm: (WebEditorClient::handleInputMethodKeydown):
Added a FIXME. WebKit1/mac is the only port that uses this roundabout way to
interpret events, so it would simplify code if we switched it to WebKit2/mac model.
Source/WebKit2:
* Shared/NativeWebKeyboardEvent.h:
* Shared/WebEvent.h:
(WebKit::WebKeyboardEvent::handledByInputMethod):
(WebKit::WebKeyboardEvent::commands):
* Shared/WebEventConversion.cpp:
(WebKit::WebKit2PlatformKeyboardEvent::WebKit2PlatformKeyboardEvent):
* Shared/WebKeyboardEvent.cpp:
(WebKit::WebKeyboardEvent::WebKeyboardEvent):
(WebKit::WebKeyboardEvent::~WebKeyboardEvent):
(WebKit::WebKeyboardEvent::encode):
(WebKit::WebKeyboardEvent::decode):
* Shared/mac/NativeWebKeyboardEventMac.mm:
(WebKit::NativeWebKeyboardEvent::NativeWebKeyboardEvent):
* Shared/mac/WebEventFactory.h:
* Shared/mac/WebEventFactory.mm:
(WebKit::WebEventFactory::createWebKeyboardEvent):
Keyboard events now carry results of interpretation with them.
Ideally, mouse events should also have a handledByInputMethod member, because IMs
can handle events, but that can wait until we have actual bugs caused by not diabling
default processing for these.
* UIProcess/API/mac/WKView.mm:
(-[WKView becomeFirstResponder]): Updated for new NativeWebKeyboardEvent contructor
signature. We don't interpret the event in this code path.
(-[WKView doCommandBySelector:]): Added logging.
(-[WKView performKeyEquivalent:]): Reimplemented Esc and Cmd+period handling to avoid
infinite loops and re-entrancy. These two work in a unique way in AppKit.
Interpret key event before sending it down to WebProcess.
(-[WKView keyUp:]): Interpret key event before sending it down to WebProcess.
We need to tell IMs about the event, but key binding processing is moot, all commands
are executed on keydown.
(-[WKView keyDown:]): Interpret the event.
(-[WKView flagsChanged:]): Ditto.
(-[WKView _interpretKeyEvent:savingCommandsTo:WebCore::]): Added an assertion in
consumedByIM code path.
(-[WKView _executeSavedCommandBySelector:]): Added logging.
* UIProcess/PageClient.h:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/WebPageProxyIOS.mm:
* UIProcess/mac/WebPageProxyMac.mm:
Removed interpretQueuedKeyEvent/interpretKeyEvent, WebProcess no longer asks UIProcess to do this.
* WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:
(WebKit::WebEditorClient::handleKeyboardEvent):
* WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm:
(WebKit::WebEditorClient::handleKeyboardEvent):
(WebKit::WebEditorClient::handleInputMethodKeydown):
WebPage::handleEditingKeyboardEvent is now one function instead of two with a boolean
switch between two behaviors.
* WebProcess/WebPage/WebPage.cpp:(WebKit::WebPage::WebPage):
* WebProcess/WebPage/WebPage.h:
Removed m_keyboardEventBeingInterpreted, as we no longer send the event for interpretation.
This means that we sometimes have to pass a null event down to WebCore, but I wasn't
able to find any behavior differences from us doing so.
* WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::handleEditingKeyboardEvent):
Added a FIXME.
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::executeKeypressCommandsInternal): When we don't have an event,
use current frame as a target, just like input method messages do.
(WebKit::WebPage::handleEditingKeyboardEvent): This function no longer saves commands,
it only interprets them.
Added a check for Esc, as we don't want to handle it in keydown event handler.
(WebKit::WebPage::insertText): Pass 0 instead of m_keyboardEventBeingInterpreted.
(WebKit::WebPage::insertDictatedText): Ditto.
(WebKit::WebPage::executeKeypressCommands): Ditto.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@165356
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2014-03-06 Alexey Proskuryakov <ap@apple.com>
+
+ [Mac] Don't perform a round-trip through WebProcess before interpreting key events
+ https://bugs.webkit.org/show_bug.cgi?id=129812
+
+ Reviewed by Darin Adler.
+
+ No significant behavior changes expected, except for Esc key processing, which now
+ dispatches a keypress before executing its default action.
+
+ * platform/KeypressCommand.h: Added.
+ (WebCore::KeypressCommand::KeypressCommand):
+ * GNUmakefile.list.am:
+ * WebCore.vcxproj/WebCore.vcxproj:
+ * WebCore.vcxproj/WebCore.vcxproj.filters:
+ * WebCore.xcodeproj/project.pbxproj:
+ Moved KeypressCommand from dom/KeyboardEvent.h to its own header, as it needed
+ in platform/ directory now.
+
+ * dom/KeyboardEvent.cpp:
+ (WebCore::KeyboardEvent::KeyboardEvent):
+ * dom/KeyboardEvent.h:
+ (WebCore::KeyboardEvent::handledByInputMethod):
+ (WebCore::KeyboardEvent::keypressCommands):
+ * platform/PlatformKeyboardEvent.h:
+ (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent):
+ (WebCore::PlatformKeyboardEvent::handledByInputMethod):
+ (WebCore::PlatformKeyboardEvent::commands):
+ PlatformKeyboardEvent now carries results of interpreting the event by AppKit. This
+ is logically not much different from carrying charcode, and is similar to what Gtk
+ does for input methods.
+ KeyboardEvent already had keypress commands, which were added to it after construction.
+ It's still possible for WebKit1, while with WebKit2, they are provided at construction
+ time. The event now also has a boolean for whether IM handled it already.
+
2014-03-09 Zalan Bujtas <zalan@apple.com>
Subpixel rendering: Pass FloatSize boxsize to transform animations to support device pixel sizing.
Source/WebCore/platform/URL.h \
Source/WebCore/platform/URLHash.h \
Source/WebCore/platform/KeyedCoding.h \
+ Source/WebCore/platform/KeypressCommand.h \
Source/WebCore/platform/KillRing.h \
Source/WebCore/platform/KillRingNone.cpp \
Source/WebCore/platform/Language.cpp \
<ClInclude Include="..\platform\graphics\win\SharedGDIObject.h" />
<ClInclude Include="..\platform\HistogramSupport.h" />
<ClInclude Include="..\platform\HostWindow.h" />
+ <ClInclude Include="..\platform\KeypressCommand.h" />
<ClInclude Include="..\platform\KillRing.h" />
<ClInclude Include="..\platform\URL.h" />
<ClInclude Include="..\platform\URLHash.h" />
<ClInclude Include="..\platform\URLHash.h">
<Filter>platform</Filter>
</ClInclude>
+ <ClInclude Include="..\platform\KeypressCommand.h">
+ <Filter>platform</Filter>
+ </ClInclude>
<ClInclude Include="..\platform\Language.h">
<Filter>platform</Filter>
</ClInclude>
E157A8F118185425009F821D /* JSCryptoAlgorithmBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = E157A8EF18185425009F821D /* JSCryptoAlgorithmBuilder.h */; };
E15A36D71104572000B7B639 /* XMLNSNames.h in Headers */ = {isa = PBXBuildFile; fileRef = E15A36D61104572000B7B639 /* XMLNSNames.h */; };
E15A36D91104572700B7B639 /* XMLNSNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E15A36D81104572700B7B639 /* XMLNSNames.cpp */; };
+ E15FF7D518C9553800FE4C87 /* KeypressCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = E15FF7D418C9553800FE4C87 /* KeypressCommand.h */; settings = {ATTRIBUTES = (Private, ); }; };
E164FAA318315BF400DB4E61 /* CryptoKeyRSA.h in Headers */ = {isa = PBXBuildFile; fileRef = E164FAA218315BF400DB4E61 /* CryptoKeyRSA.h */; };
E164FAA518315E1A00DB4E61 /* CryptoKeyRSAMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E164FAA418315E1A00DB4E61 /* CryptoKeyRSAMac.cpp */; };
E169803D1133542D00894115 /* CRuntimeObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E169803C1133542D00894115 /* CRuntimeObject.h */; };
E157A8EF18185425009F821D /* JSCryptoAlgorithmBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCryptoAlgorithmBuilder.h; sourceTree = "<group>"; };
E15A36D61104572000B7B639 /* XMLNSNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLNSNames.h; sourceTree = "<group>"; };
E15A36D81104572700B7B639 /* XMLNSNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XMLNSNames.cpp; sourceTree = "<group>"; };
+ E15FF7D418C9553800FE4C87 /* KeypressCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeypressCommand.h; sourceTree = "<group>"; };
E164FAA218315BF400DB4E61 /* CryptoKeyRSA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CryptoKeyRSA.h; path = keys/CryptoKeyRSA.h; sourceTree = "<group>"; };
E164FAA418315E1A00DB4E61 /* CryptoKeyRSAMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CryptoKeyRSAMac.cpp; path = mac/CryptoKeyRSAMac.cpp; sourceTree = "<group>"; };
E169803C1133542D00894115 /* CRuntimeObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CRuntimeObject.h; sourceTree = "<group>"; };
D630E2AB149BF344005B2F93 /* HistogramSupport.h */,
BC3BC29B0E91AB0F00835588 /* HostWindow.h */,
862F129F18C1DCE4005C54AF /* HysteresisActivity.h */,
+ E15FF7D418C9553800FE4C87 /* KeypressCommand.h */,
1AE00D57182DAC8D00087DD7 /* KeyedCoding.h */,
521D46F711AEC9B100514613 /* KillRing.h */,
4306E4E514955543007F17AC /* KillRingNone.cpp */,
85E711930AC5D5350053270F /* DOMCSSStyleDeclarationInternal.h in Headers */,
85032DE70AA8C9BE007D3B7D /* DOMCSSStyleRule.h in Headers */,
85909CE20ACC7A7E00DF01F1 /* DOMCSSStyleRuleInternal.h in Headers */,
+ E15FF7D518C9553800FE4C87 /* KeypressCommand.h in Headers */,
858C39280AA8FF9D00B187A4 /* DOMCSSStyleSheet.h in Headers */,
85909CE30ACC7A7E00DF01F1 /* DOMCSSStyleSheetInternal.h in Headers */,
FCD8832A16A49F8200962227 /* DOMCSSSupportsRule.h in Headers */,
KeyboardEvent::KeyboardEvent()
: m_location(DOM_KEY_LOCATION_STANDARD)
, m_altGraphKey(false)
+#if PLATFORM(COCOA)
+ , m_handledByInputMethod(false)
+#endif
{
}
, m_keyIdentifier(key.keyIdentifier())
, m_location(keyLocationCode(key))
, m_altGraphKey(false)
+#if PLATFORM(COCOA)
+ , m_handledByInputMethod(key.handledByInputMethod())
+ , m_keypressCommands(key.commands())
+#endif
{
}
, m_keyIdentifier(initializer.keyIdentifier)
, m_location(initializer.location)
, m_altGraphKey(false)
+#if PLATFORM(COCOA)
+ , m_handledByInputMethod(false)
+#endif
{
}
#ifndef KeyboardEvent_h
#define KeyboardEvent_h
+#include "KeypressCommand.h"
#include "UIEventWithKeyState.h"
#include <memory>
#include <wtf/Vector.h>
class Node;
class PlatformKeyboardEvent;
-#if PLATFORM(COCOA)
-struct KeypressCommand {
- KeypressCommand() { }
- explicit KeypressCommand(const String& commandName) : commandName(commandName) { ASSERT(isASCIILower(commandName[0U])); }
- KeypressCommand(const String& commandName, const String& text) : commandName(commandName), text(text) { ASSERT(commandName == "insertText:"); }
-
- String commandName; // Actually, a selector name - it may have a trailing colon, and a name that can be different from an editor command name.
- String text;
-};
-#endif
-
struct KeyboardEventInit : public UIEventInit {
KeyboardEventInit();
virtual int which() const override;
#if PLATFORM(COCOA)
- // We only have this need to store keypress command info on the Mac.
+ bool handledByInputMethod() const { return m_handledByInputMethod; }
+ const Vector<KeypressCommand>& keypressCommands() const { return m_keypressCommands; }
+
+ // The non-const version is still needed for WebKit1, which doesn't construct a complete KeyboardEvent with interpreted commands yet.
Vector<KeypressCommand>& keypressCommands() { return m_keypressCommands; }
#endif
#if PLATFORM(COCOA)
// Commands that were sent by AppKit when interpreting the event. Doesn't include input method commands.
+ bool m_handledByInputMethod;
Vector<KeypressCommand> m_keypressCommands;
#endif
};
--- /dev/null
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef KeypressCommand_h
+#define KeypressCommand_h
+
+#include <wtf/Assertions.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(COCOA)
+
+namespace WebCore {
+
+struct KeypressCommand {
+ KeypressCommand() { }
+ explicit KeypressCommand(const String& commandName) : commandName(commandName) { ASSERT(isASCIILower(commandName[0U])); }
+ KeypressCommand(const String& commandName, const String& text) : commandName(commandName), text(text) { ASSERT(commandName == "insertText:"); }
+
+ String commandName; // Actually, a selector name - it may have a trailing colon, and a name that can be different from an editor command name.
+ String text;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // KeypressCommand_h
#ifndef PlatformKeyboardEvent_h
#define PlatformKeyboardEvent_h
+#include "KeypressCommand.h"
#include "PlatformEvent.h"
#include <wtf/WindowsExtras.h>
#include <wtf/text/WTFString.h>
, m_windowsVirtualKeyCode(0)
, m_nativeVirtualKeyCode(0)
, m_macCharCode(0)
+#if USE(APPKIT)
+ , m_handledByInputMethod(false)
+#endif
, m_autoRepeat(false)
, m_isKeypad(false)
, m_isSystemKey(false)
, m_windowsVirtualKeyCode(windowsVirtualKeyCode)
, m_nativeVirtualKeyCode(nativeVirtualKeyCode)
, m_macCharCode(macCharCode)
+#if USE(APPKIT)
+ , m_handledByInputMethod(false)
+#endif
, m_autoRepeat(isAutoRepeat)
, m_isKeypad(isKeypad)
, m_isSystemKey(isSystemKey)
int nativeVirtualKeyCode() const { return m_nativeVirtualKeyCode; }
int macCharCode() const { return m_macCharCode; }
+#if USE(APPKIT)
+ bool handledByInputMethod() const { return m_handledByInputMethod; }
+ const Vector<KeypressCommand>& commands() const { return m_commands; }
+#endif
+
bool isAutoRepeat() const { return m_autoRepeat; }
bool isKeypad() const { return m_isKeypad; }
bool isSystemKey() const { return m_isSystemKey; }
int m_windowsVirtualKeyCode;
int m_nativeVirtualKeyCode;
int m_macCharCode;
+#if USE(APPKIT)
+ bool m_handledByInputMethod;
+ Vector<KeypressCommand> m_commands;
+#endif
bool m_autoRepeat;
bool m_isKeypad;
bool m_isSystemKey;
+2014-03-06 Alexey Proskuryakov <ap@apple.com>
+
+ [Mac] Don't perform a round-trip through WebProcess before interpreting key events
+ https://bugs.webkit.org/show_bug.cgi?id=129812
+
+ Reviewed by Darin Adler.
+
+ * WebCoreSupport/WebEditorClient.mm: (WebEditorClient::handleInputMethodKeydown):
+ Added a FIXME. WebKit1/mac is the only port that uses this roundabout way to
+ interpret events, so it would simplify code if we switched it to WebKit2/mac model.
+
2014-03-08 Simon Fraser <simon.fraser@apple.com>
[iOS Wk2] Can't scroll after going back to page in page cache
void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* event)
{
#if !PLATFORM(IOS)
+ // FIXME: Switch to WebKit2 model, interpreting the event before it's sent down to WebCore.
Frame* frame = event->target()->toNode()->document().frame();
WebHTMLView *webHTMLView = [[kit(frame) frameView] documentView];
if ([webHTMLView _interpretKeyEvent:event savingCommands:YES])
+2014-03-06 Alexey Proskuryakov <ap@apple.com>
+
+ [Mac] Don't perform a round-trip through WebProcess before interpreting key events
+ https://bugs.webkit.org/show_bug.cgi?id=129812
+
+ Reviewed by Darin Adler.
+
+ * Shared/NativeWebKeyboardEvent.h:
+ * Shared/WebEvent.h:
+ (WebKit::WebKeyboardEvent::handledByInputMethod):
+ (WebKit::WebKeyboardEvent::commands):
+ * Shared/WebEventConversion.cpp:
+ (WebKit::WebKit2PlatformKeyboardEvent::WebKit2PlatformKeyboardEvent):
+ * Shared/WebKeyboardEvent.cpp:
+ (WebKit::WebKeyboardEvent::WebKeyboardEvent):
+ (WebKit::WebKeyboardEvent::~WebKeyboardEvent):
+ (WebKit::WebKeyboardEvent::encode):
+ (WebKit::WebKeyboardEvent::decode):
+ * Shared/mac/NativeWebKeyboardEventMac.mm:
+ (WebKit::NativeWebKeyboardEvent::NativeWebKeyboardEvent):
+ * Shared/mac/WebEventFactory.h:
+ * Shared/mac/WebEventFactory.mm:
+ (WebKit::WebEventFactory::createWebKeyboardEvent):
+ Keyboard events now carry results of interpretation with them.
+ Ideally, mouse events should also have a handledByInputMethod member, because IMs
+ can handle events, but that can wait until we have actual bugs caused by not diabling
+ default processing for these.
+
+ * UIProcess/API/mac/WKView.mm:
+ (-[WKView becomeFirstResponder]): Updated for new NativeWebKeyboardEvent contructor
+ signature. We don't interpret the event in this code path.
+ (-[WKView doCommandBySelector:]): Added logging.
+ (-[WKView performKeyEquivalent:]): Reimplemented Esc and Cmd+period handling to avoid
+ infinite loops and re-entrancy. These two work in a unique way in AppKit.
+ Interpret key event before sending it down to WebProcess.
+ (-[WKView keyUp:]): Interpret key event before sending it down to WebProcess.
+ We need to tell IMs about the event, but key binding processing is moot, all commands
+ are executed on keydown.
+ (-[WKView keyDown:]): Interpret the event.
+ (-[WKView flagsChanged:]): Ditto.
+ (-[WKView _interpretKeyEvent:savingCommandsTo:WebCore::]): Added an assertion in
+ consumedByIM code path.
+ (-[WKView _executeSavedCommandBySelector:]): Added logging.
+
+ * UIProcess/PageClient.h:
+ * UIProcess/ios/PageClientImplIOS.h:
+ * UIProcess/ios/PageClientImplIOS.mm:
+ * UIProcess/mac/PageClientImpl.h:
+ * UIProcess/mac/PageClientImpl.mm:
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ * UIProcess/mac/WebPageProxyMac.mm:
+ Removed interpretQueuedKeyEvent/interpretKeyEvent, WebProcess no longer asks UIProcess to do this.
+
+ * WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:
+ (WebKit::WebEditorClient::handleKeyboardEvent):
+ * WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm:
+ (WebKit::WebEditorClient::handleKeyboardEvent):
+ (WebKit::WebEditorClient::handleInputMethodKeydown):
+ WebPage::handleEditingKeyboardEvent is now one function instead of two with a boolean
+ switch between two behaviors.
+
+ * WebProcess/WebPage/WebPage.cpp:(WebKit::WebPage::WebPage):
+ * WebProcess/WebPage/WebPage.h:
+ Removed m_keyboardEventBeingInterpreted, as we no longer send the event for interpretation.
+ This means that we sometimes have to pass a null event down to WebCore, but I wasn't
+ able to find any behavior differences from us doing so.
+
+ * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::handleEditingKeyboardEvent):
+ Added a FIXME.
+
+ * WebProcess/WebPage/mac/WebPageMac.mm:
+ (WebKit::WebPage::executeKeypressCommandsInternal): When we don't have an event,
+ use current frame as a target, just like input method messages do.
+ (WebKit::WebPage::handleEditingKeyboardEvent): This function no longer saves commands,
+ it only interprets them.
+ Added a check for Esc, as we don't want to handle it in keydown event handler.
+ (WebKit::WebPage::insertText): Pass 0 instead of m_keyboardEventBeingInterpreted.
+ (WebKit::WebPage::insertDictatedText): Ditto.
+ (WebKit::WebPage::executeKeypressCommands): Ditto.
+
2014-03-09 Zalan Bujtas <zalan@apple.com>
Subpixel rendering: Pass FloatSize boxsize to transform animations to support device pixel sizing.
#if USE(APPKIT)
#include <wtf/RetainPtr.h>
OBJC_CLASS NSView;
+
+namespace WebCore {
+struct KeypressCommand;
+}
#endif
#if PLATFORM(EFL)
class NativeWebKeyboardEvent : public WebKeyboardEvent {
public:
#if USE(APPKIT)
- NativeWebKeyboardEvent(NSEvent *, NSView *);
+ NativeWebKeyboardEvent(NSEvent *, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>&);
#elif PLATFORM(GTK)
NativeWebKeyboardEvent(const NativeWebKeyboardEvent&);
NativeWebKeyboardEvent(GdkEvent*, const WebCore::CompositionResults&, WebCore::GtkInputMethodFilter::EventFakedForComposition);
class ArgumentEncoder;
}
+#if USE(APPKIT)
+namespace WebCore {
+struct KeypressCommand;
+}
+#endif
+
namespace WebKit {
class WebEvent {
// FIXME: Move this class to its own header file.
class WebKeyboardEvent : public WebEvent {
public:
- WebKeyboardEvent() { }
+ WebKeyboardEvent();
+ ~WebKeyboardEvent();
+#if USE(APPKIT)
+ WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>&, bool isAutoRepeat, bool isKeypad, bool isSystemKey, Modifiers, double timestamp);
+#else
WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, Modifiers, double timestamp);
+#endif
const String& text() const { return m_text; }
const String& unmodifiedText() const { return m_unmodifiedText; }
int32_t windowsVirtualKeyCode() const { return m_windowsVirtualKeyCode; }
int32_t nativeVirtualKeyCode() const { return m_nativeVirtualKeyCode; }
int32_t macCharCode() const { return m_macCharCode; }
+#if USE(APPKIT)
+ bool handledByInputMethod() const { return m_handledByInputMethod; }
+ const Vector<WebCore::KeypressCommand>& commands() const { return m_commands; }
+#endif
bool isAutoRepeat() const { return m_isAutoRepeat; }
bool isKeypad() const { return m_isKeypad; }
bool isSystemKey() const { return m_isSystemKey; }
int32_t m_windowsVirtualKeyCode;
int32_t m_nativeVirtualKeyCode;
int32_t m_macCharCode;
+#if USE(APPKIT)
+ bool m_handledByInputMethod;
+ Vector<WebCore::KeypressCommand> m_commands;
+#endif
bool m_isAutoRepeat;
bool m_isKeypad;
bool m_isSystemKey;
m_windowsVirtualKeyCode = webEvent.windowsVirtualKeyCode();
m_nativeVirtualKeyCode = webEvent.nativeVirtualKeyCode();
m_macCharCode = webEvent.macCharCode();
+#if USE(APPKIT)
+ m_handledByInputMethod = webEvent.handledByInputMethod();
+ m_commands = webEvent.commands();
+#endif
m_autoRepeat = webEvent.isAutoRepeat();
m_isKeypad = webEvent.isKeypad();
m_isSystemKey = webEvent.isSystemKey();
#include "WebEvent.h"
#include "WebCoreArgumentCoders.h"
+#include <WebCore/KeypressCommand.h>
namespace WebKit {
+WebKeyboardEvent::WebKeyboardEvent()
+{
+}
+
+#if USE(APPKIT)
+
+WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>& commands, bool isAutoRepeat, bool isKeypad, bool isSystemKey, Modifiers modifiers, double timestamp)
+ : WebEvent(type, modifiers, timestamp)
+ , m_text(text)
+ , m_unmodifiedText(unmodifiedText)
+ , m_keyIdentifier(keyIdentifier)
+ , m_windowsVirtualKeyCode(windowsVirtualKeyCode)
+ , m_nativeVirtualKeyCode(nativeVirtualKeyCode)
+ , m_macCharCode(macCharCode)
+ , m_handledByInputMethod(handledByInputMethod)
+ , m_commands(commands)
+ , m_isAutoRepeat(isAutoRepeat)
+ , m_isKeypad(isKeypad)
+ , m_isSystemKey(isSystemKey)
+{
+ ASSERT(isKeyboardEventType(type));
+}
+
+#else
+
WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, Modifiers modifiers, double timestamp)
: WebEvent(type, modifiers, timestamp)
, m_text(text)
ASSERT(isKeyboardEventType(type));
}
+#endif
+
+WebKeyboardEvent::~WebKeyboardEvent()
+{
+}
+
void WebKeyboardEvent::encode(IPC::ArgumentEncoder& encoder) const
{
WebEvent::encode(encoder);
encoder << m_windowsVirtualKeyCode;
encoder << m_nativeVirtualKeyCode;
encoder << m_macCharCode;
+#if USE(APPKIT)
+ encoder << m_handledByInputMethod;
+ encoder << m_commands;
+#endif
encoder << m_isAutoRepeat;
encoder << m_isKeypad;
encoder << m_isSystemKey;
return false;
if (!decoder.decode(result.m_macCharCode))
return false;
+#if USE(APPKIT)
+ if (!decoder.decode(result.m_handledByInputMethod))
+ return false;
+ if (!decoder.decode(result.m_commands))
+ return false;
+#endif
if (!decoder.decode(result.m_isAutoRepeat))
return false;
if (!decoder.decode(result.m_isKeypad))
#if USE(APPKIT)
#import "WebEventFactory.h"
+#import <WebCore/KeyboardEvent.h>
+
+using namespace WebCore;
namespace WebKit {
-NativeWebKeyboardEvent::NativeWebKeyboardEvent(NSEvent *event, NSView *view)
- : WebKeyboardEvent(WebEventFactory::createWebKeyboardEvent(event, view))
+NativeWebKeyboardEvent::NativeWebKeyboardEvent(NSEvent *event, bool handledByInputMethod, const Vector<KeypressCommand>& commands)
+ : WebKeyboardEvent(WebEventFactory::createWebKeyboardEvent(event, handledByInputMethod, commands))
, m_nativeEvent(event)
{
}
class WebEventFactory {
public:
#if USE(APPKIT)
- static WebMouseEvent createWebMouseEvent(NSEvent *event, NSView *windowView);
- static WebWheelEvent createWebWheelEvent(NSEvent *event, NSView *windowView);
- static WebKeyboardEvent createWebKeyboardEvent(NSEvent *event, NSView *windowView);
+ static WebMouseEvent createWebMouseEvent(NSEvent *, NSView *windowView);
+ static WebWheelEvent createWebWheelEvent(NSEvent *, NSView *windowView);
+ static WebKeyboardEvent createWebKeyboardEvent(NSEvent *, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>&);
#endif // USE(APPKIT)
};
#if USE(APPKIT)
#import "WebKitSystemInterface.h"
+#import <WebCore/KeyboardEvent.h>
#import <WebCore/PlatformEventFactoryMac.h>
#import <WebCore/Scrollbar.h>
#import <WebCore/WindowsKeyboardCodes.h>
return WebWheelEvent(WebEvent::Wheel, IntPoint(position), IntPoint(globalPosition), FloatSize(deltaX, deltaY), FloatSize(wheelTicksX, wheelTicksY), granularity, directionInvertedFromDevice, phase, momentumPhase, hasPreciseScrollingDeltas, scrollCount, unacceleratedScrollingDelta, modifiers, timestamp);
}
-WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(NSEvent *event, NSView *)
+WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(NSEvent *event, bool handledByInputMethod, const Vector<WebCore::KeypressCommand>& commands)
{
WebEvent::Type type = isKeyUpEvent(event) ? WebEvent::KeyUp : WebEvent::KeyDown;
String text = textFromEvent(event);
unmodifiedText = "\x9";
}
- return WebKeyboardEvent(type, text, unmodifiedText, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, macCharCode, autoRepeat, isKeypad, isSystemKey, modifiers, timestamp);
+ return WebKeyboardEvent(type, text, unmodifiedText, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, macCharCode, handledByInputMethod, commands, autoRepeat, isKeypad, isSystemKey, modifiers, timestamp);
}
} // namespace WebKit
NSEvent *keyboardEvent = nil;
if ([event type] == NSKeyDown || [event type] == NSKeyUp)
keyboardEvent = event;
- _data->_page->setInitialFocus(direction == NSSelectingNext, keyboardEvent != nil, NativeWebKeyboardEvent(keyboardEvent, self));
+ _data->_page->setInitialFocus(direction == NSSelectingNext, keyboardEvent != nil, NativeWebKeyboardEvent(keyboardEvent, false, Vector<KeypressCommand>()));
}
return YES;
}
if (parameters && !isFromInputMethod) {
KeypressCommand command(NSStringFromSelector(selector));
parameters->commands->append(command);
+ LOG(TextInput, "...stored");
_data->_page->registerKeypressCommandName(command.commandName);
} else {
// FIXME: Send the command to Editor synchronously and only send it along the
// fetching a new event might release the old one. Retaining and then autoreleasing
// the current event prevents that from causing a problem inside WebKit or AppKit code.
[[event retain] autorelease];
-
+
+ // We get Esc key here after processing either Esc or Cmd+period. The former starts as a keyDown, and the latter starts as a key equivalent,
+ // but both get transformed to a cancelOperation: command, executing which passes an Esc key event to -performKeyEquivalent:.
+ // Don't interpret this event again, avoiding re-entrancy and infinite loops.
+ if ([[event charactersIgnoringModifiers] isEqualToString:@"\e"] && !([event modifierFlags] & NSDeviceIndependentModifierFlagsMask))
+ return [super performKeyEquivalent:event];
+
+ // If we are already re-sending the event, then WebCore has already seen it, no need for custom processing.
BOOL eventWasSentToWebCore = (_data->_keyDownEventBeingResent == event);
+ if (eventWasSentToWebCore)
+ return [super performKeyEquivalent:event];
- if (!eventWasSentToWebCore)
- [self _disableComplexTextInputIfNecessary];
+ ASSERT(event == [NSApp currentEvent]);
+
+ [self _disableComplexTextInputIfNecessary];
// Pass key combos through WebCore if there is a key binding available for
// this event. This lets web pages have a crack at intercepting key-modified keypresses.
- // But don't do it if we have already handled the event.
- // Pressing Esc results in a fake event being sent - don't pass it to WebCore.
- if (!eventWasSentToWebCore && event == [NSApp currentEvent] && self == [[self window] firstResponder]) {
- _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(event, self));
+ // FIXME: Why is the firstResponder check needed?
+ if (self == [[self window] firstResponder]) {
+ Vector<KeypressCommand> commands;
+ BOOL handledByInputMethod = [self _interpretKeyEvent:event savingCommandsTo:commands];
+ _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(event, handledByInputMethod, commands));
return YES;
}
- (void)keyUp:(NSEvent *)theEvent
{
LOG(TextInput, "keyUp:%p %@", theEvent, theEvent);
- _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(theEvent, self));
+
+ Vector<KeypressCommand> commands;
+ BOOL handledByInputMethod = [self _interpretKeyEvent:theEvent savingCommandsTo:commands];
+
+ _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(theEvent, handledByInputMethod, commands));
}
- (void)_disableComplexTextInputIfNecessary
[super keyDown:theEvent];
return;
}
- _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(theEvent, self));
+
+ Vector<KeypressCommand> commands;
+ BOOL handledByInputMethod = [self _interpretKeyEvent:theEvent savingCommandsTo:commands];
+ if (!commands.isEmpty()) {
+ // An input method may make several actions per keypress. For example, pressing Return with Korean IM both confirms it and sends a newline.
+ // IM-like actions are handled immediately (so the return value from UI process is true), but there are saved commands that
+ // should be handled like normal text input after DOM event dispatch.
+ handledByInputMethod = NO;
+ }
+
+ _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(theEvent, handledByInputMethod, commands));
}
- (void)flagsChanged:(NSEvent *)theEvent
if (!keyCode || keyCode == 10 || keyCode == 63)
return;
- _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(theEvent, self));
+ Vector<KeypressCommand> commands;
+ BOOL handledByInputMethod = [self _interpretKeyEvent:theEvent savingCommandsTo:commands];
+
+ _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(theEvent, handledByInputMethod, commands));
}
- (void)_executeSavedKeypressCommands
LOG(TextInput, "-> interpretKeyEvents:%p %@", event, event);
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
- _data->_interpretKeyEventsParameters = 0;
+ _data->_interpretKeyEventsParameters = nullptr;
// An input method may consume an event and not tell us (e.g. when displaying a candidate window),
// in which case we should not bubble the event up the DOM.
if (parameters.consumedByIM) {
+ ASSERT(commands.isEmpty());
LOG(TextInput, "...event %p was consumed by an input method", event);
return YES;
}
- (bool)_executeSavedCommandBySelector:(SEL)selector
{
+ LOG(TextInput, "Executing previously saved command %s", sel_getName(selector));
// The sink does two things: 1) Tells us if the responder went unhandled, and
// 2) prevents any NSBeep; we don't ever want to beep here.
RetainPtr<WKResponderChainSink> sink = adoptNS([[WKResponderChainSink alloc] initWithResponderChain:self]);
virtual void executeUndoRedo(WebPageProxy::UndoOrRedo) = 0;
#if PLATFORM(COCOA)
virtual void accessibilityWebProcessTokenReceived(const IPC::DataReference&) = 0;
- virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, Vector<WebCore::KeypressCommand>&) = 0;
virtual bool executeSavedCommandBySelector(const String& selector) = 0;
virtual void setDragImage(const WebCore::IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag) = 0;
virtual void updateSecureInputState() = 0;
// Keyboard handling
#if PLATFORM(COCOA)
- void interpretQueuedKeyEvent(const EditorState&, bool& handled, Vector<WebCore::KeypressCommand>&);
void executeSavedCommandBySelector(const String& selector, bool& handled);
#endif
DidPerformDictionaryLookup(WebKit::AttributedString text, WebKit::DictionaryPopupInfo dictionaryPopupInfo)
# Keyboard input support messages
- InterpretQueuedKeyEvent(WebKit::EditorState state) -> (bool handled, Vector<WebCore::KeypressCommand> savedCommands)
ExecuteSavedCommandBySelector(String selector) -> (bool handled)
# Remote accessibility messages
virtual bool canUndoRedo(WebPageProxy::UndoOrRedo) override;
virtual void executeUndoRedo(WebPageProxy::UndoOrRedo) override;
virtual void accessibilityWebProcessTokenReceived(const IPC::DataReference&) override;
- virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, Vector<WebCore::KeypressCommand>&) override;
virtual bool executeSavedCommandBySelector(const String& selector) override;
virtual void setDragImage(const WebCore::IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag) override;
virtual void updateSecureInputState() override;
[m_contentView _setAccessibilityWebProcessToken:remoteToken];
}
-bool PageClientImpl::interpretKeyEvent(const NativeWebKeyboardEvent&, Vector<KeypressCommand>&)
-{
- notImplemented();
- return false;
-}
-
bool PageClientImpl::interpretKeyEvent(const NativeWebKeyboardEvent& event, bool isCharEvent)
{
return [m_contentView _interpretKeyEvent:event.nativeEvent() isCharEvent:isCharEvent];
m_process->send(Messages::WebPage::ExtendSelection(static_cast<uint32_t>(granularity)), m_pageID);
}
-void WebPageProxy::interpretQueuedKeyEvent(const EditorState&, bool&, Vector<WebCore::KeypressCommand>&)
-{
- notImplemented();
-}
-
void WebPageProxy::interpretKeyEvent(const EditorState& state, bool isCharEvent, bool& handled)
{
m_editorState = state;
virtual void clearAllEditCommands();
virtual bool canUndoRedo(WebPageProxy::UndoOrRedo);
virtual void executeUndoRedo(WebPageProxy::UndoOrRedo);
- virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, Vector<WebCore::KeypressCommand>&);
virtual bool executeSavedCommandBySelector(const String& selector);
virtual void setDragImage(const WebCore::IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag);
virtual void setPromisedData(const String& pasteboardName, PassRefPtr<WebCore::SharedBuffer> imageBuffer, const String& filename, const String& extension, const String& title,
return (undoOrRedo == WebPageProxy::Undo) ? [[m_wkView undoManager] undo] : [[m_wkView undoManager] redo];
}
-bool PageClientImpl::interpretKeyEvent(const NativeWebKeyboardEvent& event, Vector<WebCore::KeypressCommand>& commands)
-{
- return [m_wkView _interpretKeyEvent:event.nativeEvent() savingCommandsTo:commands];
-}
-
void PageClientImpl::setDragImage(const IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag)
{
RetainPtr<CGImageRef> dragCGImage = dragImage->makeCGImage();
process().send(Messages::WebPage::PerformDictionaryLookupAtLocation(point), m_pageID);
}
-void WebPageProxy::interpretQueuedKeyEvent(const EditorState& state, bool& handled, Vector<WebCore::KeypressCommand>& commands)
-{
- m_editorState = state;
- handled = m_pageClient.interpretKeyEvent(m_keyEventQueue.first(), commands);
-}
-
// Complex text input support for plug-ins.
void WebPageProxy::sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput)
{
void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event)
{
- if (m_page->handleEditingKeyboardEvent(event, false))
+ if (m_page->handleEditingKeyboardEvent(event))
event->setDefaultHandled();
}
void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event)
{
- if (m_page->handleEditingKeyboardEvent(event, false))
+ if (m_page->handleEditingKeyboardEvent(event))
event->setDefaultHandled();
}
void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* event)
{
- if (m_page->handleEditingKeyboardEvent(event, true))
+ if (event->handledByInputMethod())
event->setDefaultHandled();
}
#if PLATFORM(COCOA)
, m_pdfPluginEnabled(false)
, m_hasCachedWindowFrame(false)
- , m_keyboardEventBeingInterpreted(0)
, m_viewGestureGeometryCollector(*this)
#elif PLATFORM(GTK) && HAVE(ACCESSIBILITY)
, m_accessibilityObject(0)
void layoutIfNeeded();
// -- Called from WebCore clients.
-#if PLATFORM(COCOA)
- bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*, bool saveCommands);
-#elif !PLATFORM(GTK)
bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*);
-#endif
void didStartPageTransition();
void didCompletePageTransition();
RetainPtr<WKAccessibilityWebPageObject> m_mockAccessibilityElement;
- WebCore::KeyboardEvent* m_keyboardEventBeingInterpreted;
-
ViewGestureGeometryCollector m_viewGestureGeometryCollector;
#elif HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
return m_viewportConfiguration.allowsUserScaling();
}
-bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* event, bool)
+bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* event)
{
+ // FIXME: Interpret the event immediately upon receiving it in UI process, without sending to WebProcess first.
bool eventWasHandled = false;
bool sendResult = WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::InterpretKeyEvent(editorState(), event->keyEvent()->type() == PlatformKeyboardEvent::Char),
Messages::WebPageProxy::InterpretKeyEvent::Reply(eventWasHandled), m_pageID);
if (!frame.editor().hasComposition()) {
// An insertText: might be handled by other responders in the chain if we don't handle it.
// One example is space bar that results in scrolling down the page.
- frame.editor().insertText(text, 0);
+ frame.editor().insertText(text, nullptr);
} else
frame.editor().confirmComposition(text);
}
bool WebPage::executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>& commands, KeyboardEvent* event)
{
- Frame* frame = frameForEvent(event);
- ASSERT(frame->page() == corePage());
+ Frame& frame = event ? *frameForEvent(event) : m_page->focusController().focusedOrMainFrame();
+ ASSERT(frame.page() == corePage());
bool eventWasHandled = false;
for (size_t i = 0; i < commands.size(); ++i) {
if (commands[i].commandName == "insertText:") {
- ASSERT(!frame->editor().hasComposition());
-
- if (!frame->editor().canEdit())
- continue;
+ if (frame.editor().hasComposition()) {
+ eventWasHandled = true;
+ frame.editor().confirmComposition(commands[i].text);
+ } else {
+ if (!frame.editor().canEdit())
+ continue;
- // An insertText: might be handled by other responders in the chain if we don't handle it.
- // One example is space bar that results in scrolling down the page.
- eventWasHandled |= frame->editor().insertText(commands[i].text, event);
+ // An insertText: might be handled by other responders in the chain if we don't handle it.
+ // One example is space bar that results in scrolling down the page.
+ eventWasHandled |= frame.editor().insertText(commands[i].text, event);
+ }
} else {
- Editor::Command command = frame->editor().command(commandNameForSelectorName(commands[i].commandName));
+ Editor::Command command = frame.editor().command(commandNameForSelectorName(commands[i].commandName));
if (command.isSupported()) {
bool commandExecutedByEditor = command.execute(event);
eventWasHandled |= commandExecutedByEditor;
return eventWasHandled;
}
-bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* event, bool saveCommands)
+bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* event)
{
- ASSERT(!saveCommands || event->keypressCommands().isEmpty()); // Save commands once for each event.
-
Frame* frame = frameForEvent(event);
const PlatformKeyboardEvent* platformEvent = event->keyEvent();
if (!platformEvent)
return false;
- Vector<KeypressCommand>& commands = event->keypressCommands();
+ const Vector<KeypressCommand>& commands = event->keypressCommands();
+
+ ASSERT(!platformEvent->macEvent()); // Cannot have a native event in WebProcess.
- if ([platformEvent->macEvent() type] == NSFlagsChanged)
+ // Don't handle Esc while handling keydown event, we need to dispatch a keypress first.
+ if (platformEvent->type() != PlatformEvent::Char && platformEvent->windowsVirtualKeyCode() == VK_ESCAPE && commands.size() == 1 && commandNameForSelectorName(commands[0].commandName) == "cancelOperation")
return false;
bool eventWasHandled = false;
-
- if (saveCommands) {
- KeyboardEvent* oldEvent = m_keyboardEventBeingInterpreted;
- m_keyboardEventBeingInterpreted = event;
- bool sendResult = WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::InterpretQueuedKeyEvent(editorState()),
- Messages::WebPageProxy::InterpretQueuedKeyEvent::Reply(eventWasHandled, commands), m_pageID);
- m_keyboardEventBeingInterpreted = oldEvent;
- if (!sendResult)
- return false;
-
- // An input method may make several actions per keypress. For example, pressing Return with Korean IM both confirms it and sends a newline.
- // IM-like actions are handled immediately (so the return value from UI process is true), but there are saved commands that
- // should be handled like normal text input after DOM event dispatch.
- if (!event->keypressCommands().isEmpty())
- return false;
- } else {
- // Are there commands that could just cause text insertion if executed via Editor?
- // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore
- // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
- // (e.g. Tab that inserts a Tab character, or Enter).
- bool haveTextInsertionCommands = false;
- for (size_t i = 0; i < commands.size(); ++i) {
- if (frame->editor().command(commandNameForSelectorName(commands[i].commandName)).isTextInsertion())
- haveTextInsertionCommands = true;
- }
- // If there are no text insertion commands, default keydown handler is the right time to execute the commands.
- // Keypress (Char event) handler is the latest opportunity to execute.
- if (!haveTextInsertionCommands || platformEvent->type() == PlatformEvent::Char) {
- eventWasHandled = executeKeypressCommandsInternal(event->keypressCommands(), event);
- event->keypressCommands().clear();
- }
+
+ // Are there commands that could just cause text insertion if executed via Editor?
+ // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore
+ // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
+ // (e.g. Tab that inserts a Tab character, or Enter).
+ bool haveTextInsertionCommands = false;
+ for (auto& command : commands) {
+ if (frame->editor().command(commandNameForSelectorName(command.commandName)).isTextInsertion())
+ haveTextInsertionCommands = true;
+ }
+ // If there are no text insertion commands, default keydown handler is the right time to execute the commands.
+ // Keypress (Char event) handler is the latest opportunity to execute.
+ if (!haveTextInsertionCommands || platformEvent->type() == PlatformEvent::Char) {
+ eventWasHandled = executeKeypressCommandsInternal(event->keypressCommands(), event);
+ event->keypressCommands().clear();
}
+
return eventWasHandled;
}
if (!frame.editor().hasComposition()) {
// An insertText: might be handled by other responders in the chain if we don't handle it.
// One example is space bar that results in scrolling down the page.
- handled = frame.editor().insertText(text, m_keyboardEventBeingInterpreted);
+ handled = frame.editor().insertText(text, nullptr);
} else {
handled = true;
frame.editor().confirmComposition(text);
}
ASSERT(!frame.editor().hasComposition());
- handled = frame.editor().insertDictatedText(text, dictationAlternativeLocations, m_keyboardEventBeingInterpreted);
+ handled = frame.editor().insertDictatedText(text, dictationAlternativeLocations, nullptr);
newState = editorState();
}
void WebPage::executeKeypressCommands(const Vector<WebCore::KeypressCommand>& commands, bool& handled, EditorState& newState)
{
- handled = executeKeypressCommandsInternal(commands, m_keyboardEventBeingInterpreted);
+ handled = executeKeypressCommandsInternal(commands, nullptr);
newState = editorState();
}