Bug 977904 - [e10s] Get native key bindings working. r=masayuki

This commit is contained in:
Tom Schuster 2014-03-20 16:46:29 +01:00
Родитель b09a3efb7b
Коммит 4731546af6
6 изменённых файлов: 123 добавлений и 5 удалений

Просмотреть файл

@ -49,10 +49,24 @@ using mozilla::dom::ScreenOrientation from "mozilla/dom/ScreenOrientation.h";
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h"; using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
using mozilla::CSSPoint from "Units.h"; using mozilla::CSSPoint from "Units.h";
using mozilla::CSSToScreenScale from "Units.h"; using mozilla::CSSToScreenScale from "Units.h";
using mozilla::CommandInt from "mozilla/EventForwards.h";
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
struct NativeKeyBinding
{
CommandInt[] singleLineCommands;
CommandInt[] multiLineCommands;
CommandInt[] richTextCommands;
};
union MaybeNativeKeyBinding
{
NativeKeyBinding;
void_t;
};
intr protocol PBrowser intr protocol PBrowser
{ {
manager PContent; manager PContent;
@ -419,7 +433,7 @@ child:
bool aIgnoreRootScrollFrame); bool aIgnoreRootScrollFrame);
RealMouseEvent(WidgetMouseEvent event); RealMouseEvent(WidgetMouseEvent event);
RealKeyEvent(WidgetKeyboardEvent event); RealKeyEvent(WidgetKeyboardEvent event, MaybeNativeKeyBinding keyBinding);
MouseWheelEvent(WidgetWheelEvent event); MouseWheelEvent(WidgetWheelEvent event);
RealTouchEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid); RealTouchEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid);
// We use a separate message for touchmove events only to apply // We use a separate message for touchmove events only to apply

Просмотреть файл

@ -1917,8 +1917,20 @@ TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
} }
bool bool
TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event) TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event,
{ const MaybeNativeKeyBinding& aBindings)
{
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());
} else {
widget->ClearNativeKeyCommands();
}
}
// If content code called preventDefault() on a keydown event, then we don't // If content code called preventDefault() on a keydown event, then we don't
// want to process any following keypress events. // want to process any following keypress events.
if (event.message == NS_KEY_PRESS && mIgnoreKeyPressEvent) { if (event.message == NS_KEY_PRESS && mIgnoreKeyPressEvent) {

Просмотреть файл

@ -238,7 +238,8 @@ public:
const int32_t& aModifiers, const int32_t& aModifiers,
const bool& aIgnoreRootScrollFrame) MOZ_OVERRIDE; const bool& aIgnoreRootScrollFrame) MOZ_OVERRIDE;
virtual bool RecvRealMouseEvent(const mozilla::WidgetMouseEvent& event) MOZ_OVERRIDE; virtual bool RecvRealMouseEvent(const mozilla::WidgetMouseEvent& event) MOZ_OVERRIDE;
virtual bool RecvRealKeyEvent(const mozilla::WidgetKeyboardEvent& event) MOZ_OVERRIDE; virtual bool RecvRealKeyEvent(const mozilla::WidgetKeyboardEvent& event,
const MaybeNativeKeyBinding& aBindings) MOZ_OVERRIDE;
virtual bool RecvMouseWheelEvent(const mozilla::WidgetWheelEvent& event) MOZ_OVERRIDE; virtual bool RecvMouseWheelEvent(const mozilla::WidgetWheelEvent& event) MOZ_OVERRIDE;
virtual bool RecvRealTouchEvent(const WidgetTouchEvent& aEvent, virtual bool RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid) MOZ_OVERRIDE; const ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;

Просмотреть файл

@ -788,6 +788,12 @@ bool TabParent::SendMouseWheelEvent(WidgetWheelEvent& event)
return PBrowserParent::SendMouseWheelEvent(event); return PBrowserParent::SendMouseWheelEvent(event);
} }
static void
DoCommandCallback(mozilla::Command aCommand, void* aData)
{
static_cast<InfallibleTArray<mozilla::CommandInt>*>(aData)->AppendElement(aCommand);
}
bool TabParent::SendRealKeyEvent(WidgetKeyboardEvent& event) bool TabParent::SendRealKeyEvent(WidgetKeyboardEvent& event)
{ {
if (mIsDestroyed) { if (mIsDestroyed) {
@ -797,7 +803,30 @@ bool TabParent::SendRealKeyEvent(WidgetKeyboardEvent& event)
if (!MapEventCoordinatesForChildProcess(&event)) { if (!MapEventCoordinatesForChildProcess(&event)) {
return false; return false;
} }
return PBrowserParent::SendRealKeyEvent(event);
MaybeNativeKeyBinding bindings;
bindings = void_t();
if (event.message == NS_KEY_PRESS) {
nsCOMPtr<nsIWidget> widget = GetWidget();
AutoInfallibleTArray<mozilla::CommandInt, 4> singleLine;
AutoInfallibleTArray<mozilla::CommandInt, 4> multiLine;
AutoInfallibleTArray<mozilla::CommandInt, 4> richText;
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForSingleLineEditor,
event, DoCommandCallback, &singleLine);
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForMultiLineEditor,
event, DoCommandCallback, &multiLine);
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForRichTextEditor,
event, DoCommandCallback, &richText);
if (!singleLine.IsEmpty() || !multiLine.IsEmpty() || !richText.IsEmpty()) {
bindings = NativeKeyBinding(singleLine, multiLine, richText);
}
}
return PBrowserParent::SendRealKeyEvent(event, bindings);
} }
bool TabParent::SendRealTouchEvent(WidgetTouchEvent& event) bool TabParent::SendRealTouchEvent(WidgetTouchEvent& event)

Просмотреть файл

@ -81,6 +81,10 @@ PuppetWidget::PuppetWidget(TabChild* aTabChild)
, mDefaultScale(-1) , mDefaultScale(-1)
{ {
MOZ_COUNT_CTOR(PuppetWidget); MOZ_COUNT_CTOR(PuppetWidget);
mSingleLineCommands.SetCapacity(4);
mMultiLineCommands.SetCapacity(4);
mRichTextCommands.SetCapacity(4);
} }
PuppetWidget::~PuppetWidget() PuppetWidget::~PuppetWidget()
@ -308,6 +312,36 @@ PuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP_(bool)
PuppetWidget::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
const mozilla::WidgetKeyboardEvent& aEvent,
DoCommandCallback aCallback,
void* aCallbackData)
{
nsTArray<mozilla::CommandInt>& commands = mSingleLineCommands;
switch (aType) {
case nsIWidget::NativeKeyBindingsForSingleLineEditor:
commands = mSingleLineCommands;
break;
case nsIWidget::NativeKeyBindingsForMultiLineEditor:
commands = mMultiLineCommands;
break;
case nsIWidget::NativeKeyBindingsForRichTextEditor:
commands = mRichTextCommands;
break;
}
if (commands.IsEmpty()) {
return false;
}
for (uint32_t i = 0; i < commands.Length(); i++) {
aCallback(static_cast<mozilla::Command>(commands[i]), aCallbackData);
}
return true;
}
LayerManager* LayerManager*
PuppetWidget::GetLayerManager(PLayerTransactionChild* aShadowManager, PuppetWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
LayersBackend aBackendHint, LayersBackend aBackendHint,

Просмотреть файл

@ -21,6 +21,7 @@
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsWeakReference.h" #include "nsWeakReference.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
class gfxASurface; class gfxASurface;
@ -129,6 +130,28 @@ public:
bool aDoCapture) bool aDoCapture)
{ return NS_ERROR_UNEXPECTED; } { return NS_ERROR_UNEXPECTED; }
NS_IMETHOD_(bool)
ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
const mozilla::WidgetKeyboardEvent& aEvent,
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();
}
// //
// nsBaseWidget methods we override // nsBaseWidget methods we override
// //
@ -225,6 +248,11 @@ private:
// The DPI of the screen corresponding to this widget // The DPI of the screen corresponding to this widget
float mDPI; float mDPI;
double mDefaultScale; double mDefaultScale;
// Precomputed answers for ExecuteNativeKeyBinding
InfallibleTArray<mozilla::CommandInt> mSingleLineCommands;
InfallibleTArray<mozilla::CommandInt> mMultiLineCommands;
InfallibleTArray<mozilla::CommandInt> mRichTextCommands;
}; };
class PuppetScreen : public nsBaseScreen class PuppetScreen : public nsBaseScreen