mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 04:03:47 +00:00
Bug 993714 - [e10s] Cache native key bindings in tests (r=masayuki,sr=roc)
This commit is contained in:
parent
516d6336f0
commit
204c0f3633
@ -353,6 +353,9 @@ parent:
|
||||
|
||||
ReplyKeyEvent(WidgetKeyboardEvent event);
|
||||
|
||||
sync RequestNativeKeyBindings(WidgetKeyboardEvent event)
|
||||
returns (MaybeNativeKeyBinding bindings);
|
||||
|
||||
child:
|
||||
/**
|
||||
* Notify the remote browser that it has been Show()n on this
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* vim: set sw=2 sts=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@ -2027,19 +2027,40 @@ TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
|
||||
return RecvRealTouchEvent(aEvent, aGuid);
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::RequestNativeKeyBindings(AutoCacheNativeKeyCommands* aAutoCache,
|
||||
WidgetKeyboardEvent* aEvent)
|
||||
{
|
||||
MaybeNativeKeyBinding maybeBindings;
|
||||
if (!SendRequestNativeKeyBindings(*aEvent, &maybeBindings)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (maybeBindings.type() == MaybeNativeKeyBinding::TNativeKeyBinding) {
|
||||
const NativeKeyBinding& bindings = maybeBindings;
|
||||
aAutoCache->Cache(bindings.singleLineCommands(),
|
||||
bindings.multiLineCommands(),
|
||||
bindings.richTextCommands());
|
||||
} else {
|
||||
aAutoCache->CacheNoCommands();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event,
|
||||
const MaybeNativeKeyBinding& aBindings)
|
||||
{
|
||||
{
|
||||
PuppetWidget* widget = static_cast<PuppetWidget*>(mWidget.get());
|
||||
AutoCacheNativeKeyCommands autoCache(widget);
|
||||
|
||||
if (event.message == NS_KEY_PRESS) {
|
||||
PuppetWidget* widget = static_cast<PuppetWidget*>(mWidget.get());
|
||||
if (aBindings.type() == MaybeNativeKeyBinding::TNativeKeyBinding) {
|
||||
const NativeKeyBinding& bindings = aBindings;
|
||||
widget->CacheNativeKeyCommands(bindings.singleLineCommands(),
|
||||
bindings.multiLineCommands(),
|
||||
bindings.richTextCommands());
|
||||
autoCache.Cache(bindings.singleLineCommands(),
|
||||
bindings.multiLineCommands(),
|
||||
bindings.richTextCommands());
|
||||
} else {
|
||||
widget->ClearNativeKeyCommands();
|
||||
autoCache.CacheNoCommands();
|
||||
}
|
||||
}
|
||||
// If content code called preventDefault() on a keydown event, then we don't
|
||||
|
@ -46,6 +46,10 @@ namespace layers {
|
||||
class ActiveElementManager;
|
||||
}
|
||||
|
||||
namespace widget {
|
||||
struct AutoCacheNativeKeyCommands;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
|
||||
class TabChild;
|
||||
@ -393,6 +397,8 @@ public:
|
||||
|
||||
void NotifyPainted();
|
||||
|
||||
void RequestNativeKeyBindings(mozilla::widget::AutoCacheNativeKeyCommands* aAutoCache,
|
||||
WidgetKeyboardEvent* aEvent);
|
||||
|
||||
/** Return a boolean indicating if the page has called preventDefault on
|
||||
* the event.
|
||||
|
@ -791,6 +791,41 @@ DoCommandCallback(mozilla::Command aCommand, void* aData)
|
||||
static_cast<InfallibleTArray<mozilla::CommandInt>*>(aData)->AppendElement(aCommand);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvRequestNativeKeyBindings(const WidgetKeyboardEvent& aEvent,
|
||||
MaybeNativeKeyBinding* aBindings)
|
||||
{
|
||||
AutoInfallibleTArray<mozilla::CommandInt, 4> singleLine;
|
||||
AutoInfallibleTArray<mozilla::CommandInt, 4> multiLine;
|
||||
AutoInfallibleTArray<mozilla::CommandInt, 4> richText;
|
||||
|
||||
*aBindings = mozilla::void_t();
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget) {
|
||||
return true;
|
||||
}
|
||||
|
||||
WidgetKeyboardEvent localEvent(aEvent);
|
||||
|
||||
if (NS_FAILED(widget->AttachNativeKeyEvent(localEvent))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForSingleLineEditor,
|
||||
localEvent, DoCommandCallback, &singleLine);
|
||||
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForMultiLineEditor,
|
||||
localEvent, DoCommandCallback, &multiLine);
|
||||
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForRichTextEditor,
|
||||
localEvent, DoCommandCallback, &richText);
|
||||
|
||||
if (!singleLine.IsEmpty() || !multiLine.IsEmpty() || !richText.IsEmpty()) {
|
||||
*aBindings = NativeKeyBinding(singleLine, multiLine, richText);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TabParent::SendRealKeyEvent(WidgetKeyboardEvent& event)
|
||||
{
|
||||
if (mIsDestroyed) {
|
||||
|
@ -222,6 +222,9 @@ public:
|
||||
void MapEventCoordinatesForChildProcess(const LayoutDeviceIntPoint& aOffset,
|
||||
mozilla::WidgetEvent* aEvent);
|
||||
|
||||
virtual bool RecvRequestNativeKeyBindings(const mozilla::WidgetKeyboardEvent& aEvent,
|
||||
MaybeNativeKeyBinding* aBindings) MOZ_OVERRIDE;
|
||||
|
||||
void SendMouseEvent(const nsAString& aType, float aX, float aY,
|
||||
int32_t aButton, int32_t aClickCount,
|
||||
int32_t aModifiers, bool aIgnoreRootScrollFrame);
|
||||
|
@ -8905,6 +8905,7 @@ PresShell::DelayedKeyEvent::DelayedKeyEvent(WidgetKeyboardEvent* aEvent) :
|
||||
aEvent->message,
|
||||
aEvent->widget);
|
||||
keyEvent->AssignKeyEventData(*aEvent, false);
|
||||
keyEvent->mFlags.mIsSynthesizedForTests = aEvent->mFlags.mIsSynthesizedForTests;
|
||||
mEvent = keyEvent;
|
||||
}
|
||||
|
||||
|
@ -521,6 +521,7 @@ public:
|
||||
NS_IMETHOD_(void) SetInputContext(const InputContext& aContext,
|
||||
const InputContextAction& aAction);
|
||||
NS_IMETHOD_(InputContext) GetInputContext();
|
||||
NS_IMETHOD AttachNativeKeyEvent(mozilla::WidgetKeyboardEvent& aEvent);
|
||||
NS_IMETHOD_(bool) ExecuteNativeKeyBinding(
|
||||
NativeKeyBindingsType aType,
|
||||
const mozilla::WidgetKeyboardEvent& aEvent,
|
||||
|
@ -1942,6 +1942,13 @@ nsChildView::GetInputContext()
|
||||
return mInputContext;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsChildView::AttachNativeKeyEvent(mozilla::WidgetKeyboardEvent& aEvent)
|
||||
{
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE);
|
||||
return mTextInputHandler->AttachNativeKeyEvent(aEvent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
nsChildView::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
|
||||
const WidgetKeyboardEvent& aEvent,
|
||||
|
@ -100,8 +100,8 @@ typedef void* nsNativeWidget;
|
||||
#endif
|
||||
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0x8e081187, 0xf123, 0x4572, \
|
||||
{ 0x82, 0xc6, 0x4c, 0xcd, 0xc2, 0x0e, 0xbd, 0xf9 } }
|
||||
{ 0x87d80888, 0x9917, 0x4bfb, \
|
||||
{ 0x81, 0xa9, 0x1c, 0x5e, 0x30, 0x9c, 0x78, 0xb4 } }
|
||||
|
||||
/*
|
||||
* Window shadow styles
|
||||
@ -1811,6 +1811,14 @@ public:
|
||||
*/
|
||||
NS_IMETHOD_(InputContext) GetInputContext() = 0;
|
||||
|
||||
/*
|
||||
* Given a WidgetKeyboardEvent, this method synthesizes a corresponding
|
||||
* native (OS-level) event for it. This method allows tests to simulate
|
||||
* keystrokes that trigger native key bindings (which require a native
|
||||
* event).
|
||||
*/
|
||||
NS_IMETHOD AttachNativeKeyEvent(mozilla::WidgetKeyboardEvent& aEvent) = 0;
|
||||
|
||||
/*
|
||||
* Execute native key bindings for aType.
|
||||
*/
|
||||
|
@ -79,6 +79,7 @@ PuppetWidget::PuppetWidget(TabChild* aTabChild)
|
||||
: mTabChild(aTabChild)
|
||||
, mDPI(-1)
|
||||
, mDefaultScale(-1)
|
||||
, mNativeKeyCommandsValid(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PuppetWidget);
|
||||
|
||||
@ -275,6 +276,14 @@ PuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus)
|
||||
NS_ABORT_IF_FALSE(!mChild || mChild->mWindowType == eWindowType_popup,
|
||||
"Unexpected event dispatch!");
|
||||
|
||||
AutoCacheNativeKeyCommands autoCache(this);
|
||||
if (event->mFlags.mIsSynthesizedForTests && !mNativeKeyCommandsValid) {
|
||||
WidgetKeyboardEvent* keyEvent = event->AsKeyboardEvent();
|
||||
if (keyEvent) {
|
||||
mTabChild->RequestNativeKeyBindings(&autoCache, keyEvent);
|
||||
}
|
||||
}
|
||||
|
||||
aStatus = nsEventStatus_eIgnore;
|
||||
|
||||
if (event->message == NS_COMPOSITION_START) {
|
||||
@ -319,6 +328,12 @@ PuppetWidget::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
|
||||
DoCommandCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
// B2G doesn't have native key bindings.
|
||||
#ifdef MOZ_B2G
|
||||
return false;
|
||||
#else // #ifdef MOZ_B2G
|
||||
MOZ_ASSERT(mNativeKeyCommandsValid);
|
||||
|
||||
nsTArray<mozilla::CommandInt>& commands = mSingleLineCommands;
|
||||
switch (aType) {
|
||||
case nsIWidget::NativeKeyBindingsForSingleLineEditor:
|
||||
@ -340,6 +355,7 @@ PuppetWidget::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
|
||||
aCallback(static_cast<mozilla::Command>(commands[i]), aCallbackData);
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
LayerManager*
|
||||
|
@ -33,6 +33,8 @@ class TabChild;
|
||||
|
||||
namespace widget {
|
||||
|
||||
class AutoCacheNativeKeyCommands;
|
||||
|
||||
class PuppetWidget : public nsBaseWidget, public nsSupportsWeakReference
|
||||
{
|
||||
typedef mozilla::dom::TabChild TabChild;
|
||||
@ -136,21 +138,7 @@ public:
|
||||
DoCommandCallback aCallback,
|
||||
void* aCallbackData) MOZ_OVERRIDE;
|
||||
|
||||
void CacheNativeKeyCommands(const InfallibleTArray<mozilla::CommandInt>& aSingleLineCommands,
|
||||
const InfallibleTArray<mozilla::CommandInt>& aMultiLineCommands,
|
||||
const InfallibleTArray<mozilla::CommandInt>& aRichTextCommands)
|
||||
{
|
||||
mSingleLineCommands = aSingleLineCommands;
|
||||
mMultiLineCommands = aMultiLineCommands;
|
||||
mRichTextCommands = aRichTextCommands;
|
||||
}
|
||||
|
||||
void ClearNativeKeyCommands()
|
||||
{
|
||||
mSingleLineCommands.Clear();
|
||||
mMultiLineCommands.Clear();
|
||||
mRichTextCommands.Clear();
|
||||
}
|
||||
friend class AutoCacheNativeKeyCommands;
|
||||
|
||||
//
|
||||
// nsBaseWidget methods we override
|
||||
@ -250,11 +238,57 @@ private:
|
||||
double mDefaultScale;
|
||||
|
||||
// Precomputed answers for ExecuteNativeKeyBinding
|
||||
bool mNativeKeyCommandsValid;
|
||||
InfallibleTArray<mozilla::CommandInt> mSingleLineCommands;
|
||||
InfallibleTArray<mozilla::CommandInt> mMultiLineCommands;
|
||||
InfallibleTArray<mozilla::CommandInt> mRichTextCommands;
|
||||
};
|
||||
|
||||
struct AutoCacheNativeKeyCommands
|
||||
{
|
||||
AutoCacheNativeKeyCommands(PuppetWidget* aWidget)
|
||||
: mWidget(aWidget)
|
||||
{
|
||||
mSavedValid = mWidget->mNativeKeyCommandsValid;
|
||||
mSavedSingleLine = mWidget->mSingleLineCommands;
|
||||
mSavedMultiLine = mWidget->mMultiLineCommands;
|
||||
mSavedRichText = mWidget->mRichTextCommands;
|
||||
}
|
||||
|
||||
void Cache(const InfallibleTArray<mozilla::CommandInt>& aSingleLineCommands,
|
||||
const InfallibleTArray<mozilla::CommandInt>& aMultiLineCommands,
|
||||
const InfallibleTArray<mozilla::CommandInt>& aRichTextCommands)
|
||||
{
|
||||
mWidget->mNativeKeyCommandsValid = true;
|
||||
mWidget->mSingleLineCommands = aSingleLineCommands;
|
||||
mWidget->mMultiLineCommands = aMultiLineCommands;
|
||||
mWidget->mRichTextCommands = aRichTextCommands;
|
||||
}
|
||||
|
||||
void CacheNoCommands()
|
||||
{
|
||||
mWidget->mNativeKeyCommandsValid = true;
|
||||
mWidget->mSingleLineCommands.Clear();
|
||||
mWidget->mMultiLineCommands.Clear();
|
||||
mWidget->mRichTextCommands.Clear();
|
||||
}
|
||||
|
||||
~AutoCacheNativeKeyCommands()
|
||||
{
|
||||
mWidget->mNativeKeyCommandsValid = mSavedValid;
|
||||
mWidget->mSingleLineCommands = mSavedSingleLine;
|
||||
mWidget->mMultiLineCommands = mSavedMultiLine;
|
||||
mWidget->mRichTextCommands = mSavedRichText;
|
||||
}
|
||||
|
||||
private:
|
||||
PuppetWidget* mWidget;
|
||||
bool mSavedValid;
|
||||
InfallibleTArray<mozilla::CommandInt> mSavedSingleLine;
|
||||
InfallibleTArray<mozilla::CommandInt> mSavedMultiLine;
|
||||
InfallibleTArray<mozilla::CommandInt> mSavedRichText;
|
||||
};
|
||||
|
||||
class PuppetScreen : public nsBaseScreen
|
||||
{
|
||||
public:
|
||||
|
@ -181,6 +181,7 @@ public:
|
||||
virtual nsresult ActivateNativeMenuItemAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
virtual nsresult ForceUpdateNativeMenuAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD NotifyIME(const IMENotification& aIMENotification) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD AttachNativeKeyEvent(mozilla::WidgetKeyboardEvent& aEvent) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD_(bool) ExecuteNativeKeyBinding(
|
||||
NativeKeyBindingsType aType,
|
||||
const mozilla::WidgetKeyboardEvent& aEvent,
|
||||
|
Loading…
x
Reference in New Issue
Block a user