From 1f53891ed3083c3447a8d755fab4b0103f04e580 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Tue, 2 Feb 2016 17:05:56 +0900 Subject: [PATCH] Bug 1243268 - Support ImmSetCandidateWindow(CFS_EXCLUDE) on plugin process. r=masayuki --- dom/ipc/PBrowser.ipdl | 3 ++- dom/ipc/TabParent.cpp | 6 +++--- dom/ipc/TabParent.h | 4 ++-- dom/plugins/base/nsPluginInstanceOwner.cpp | 5 +++-- dom/plugins/base/nsPluginInstanceOwner.h | 3 ++- dom/plugins/ipc/PPluginInstance.ipdl | 6 +++--- dom/plugins/ipc/PluginInstanceChild.cpp | 18 +++++++++++++----- dom/plugins/ipc/PluginInstanceParent.cpp | 6 +++--- dom/plugins/ipc/PluginInstanceParent.h | 3 ++- widget/IMEData.h | 12 ++++++++++++ widget/PuppetWidget.cpp | 5 +++-- widget/PuppetWidget.h | 3 ++- widget/nsBaseWidget.h | 5 +++-- widget/nsGUIEventIPC.h | 20 ++++++++++++++++++++ widget/nsIWidget.h | 3 ++- widget/windows/nsWindow.cpp | 16 ++++++++++++---- widget/windows/nsWindow.h | 5 +++-- 17 files changed, 90 insertions(+), 33 deletions(-) diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 5563adb6962..db35c241ba4 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -70,6 +70,7 @@ using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h"; using mozilla::EventMessage from "mozilla/EventForwards.h"; using nsEventStatus from "mozilla/EventForwards.h"; using nsSizeMode from "nsIWidgetListener.h"; +using mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h"; namespace mozilla { namespace dom { @@ -284,7 +285,7 @@ parent: /** * Set IME candidate window by windowless plugin if plugin has focus. */ - async SetCandidateWindowForPlugin(int32_t aX, int32_t aY); + async SetCandidateWindowForPlugin(CandidateWindowPosition aPosition); /** * When plugin event isn't consumed, call this diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 95de646b84c..6ea222e7c73 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -2392,15 +2392,15 @@ TabParent::RecvSetPluginFocused(const bool& aFocused) } bool -TabParent::RecvSetCandidateWindowForPlugin(const int32_t& aX, - const int32_t& aY) +TabParent::RecvSetCandidateWindowForPlugin( + const CandidateWindowPosition& aPosition) { nsCOMPtr widget = GetWidget(); if (!widget) { return true; } - widget->SetCandidateWindowForPlugin(aX, aY); + widget->SetCandidateWindowForPlugin(aPosition); return true; } diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index ae221996501..080ff547c29 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -238,8 +238,8 @@ public: virtual bool RecvSetPluginFocused(const bool& aFocused) override; - virtual bool RecvSetCandidateWindowForPlugin(const int32_t& aX, - const int32_t& aY) override; + virtual bool RecvSetCandidateWindowForPlugin( + const widget::CandidateWindowPosition& aPosition) override; virtual bool RecvDefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) override; diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 0df46218d34..d52d352831f 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -941,7 +941,8 @@ nsPluginInstanceOwner::GetCompositionString(uint32_t aType, } bool -nsPluginInstanceOwner::SetCandidateWindow(int32_t aX, int32_t aY) +nsPluginInstanceOwner::SetCandidateWindow( + const widget::CandidateWindowPosition& aPosition) { if (NS_WARN_IF(!mPluginFrame)) { return false; @@ -955,7 +956,7 @@ nsPluginInstanceOwner::SetCandidateWindow(int32_t aX, int32_t aY) } } - widget->SetCandidateWindowForPlugin(aX, aY); + widget->SetCandidateWindowForPlugin(aPosition); return true; } diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index 556a9414a6f..69bb08da94f 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -269,7 +269,8 @@ public: bool GetCompositionString(uint32_t aIndex, nsTArray* aString, int32_t* aLength); - bool SetCandidateWindow(int32_t aX, int32_t aY); + bool SetCandidateWindow( + const mozilla::widget::CandidateWindowPosition& aPosition); bool RequestCommitOrCancel(bool aCommitted); private: diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index 0067a0dd266..ff09c7f8822 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -31,6 +31,7 @@ using mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h"; using nsIntRect from "nsRect.h"; using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h"; using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h"; +using struct mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h"; namespace mozilla { namespace plugins { @@ -264,9 +265,8 @@ parent: returns (uint8_t[] aDist, int32_t aLength); // Set candidate window position. // - // @param aX x position of candidate window - // @param aY y position of candidate window - async SetCandidateWindow(int32_t aX, int32_t aY); + // @param aPosition position information of candidate window + async SetCandidateWindow(CandidateWindowPosition aPosition); async RequestCommitOrCancel(bool aCommitted); both: diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index 7f0144eea60..e276f293942 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -2065,14 +2065,22 @@ PluginInstanceChild::ImmSetCandidateWindowProc(HIMC aIMC, LPCANDIDATEFORM aForm) } if (!sCurrentPluginInstance || - aForm->dwIndex != 0 || - !(aForm->dwStyle & CFS_CANDIDATEPOS)) { - // Flash only uses CFS_CANDIDATEPOS with index == 0. + aForm->dwIndex != 0) { return FALSE; } - sCurrentPluginInstance->SendSetCandidateWindow( - aForm->ptCurrentPos.x, aForm->ptCurrentPos.y); + CandidateWindowPosition position; + position.mPoint.x = aForm->ptCurrentPos.x; + position.mPoint.y = aForm->ptCurrentPos.y; + position.mExcludeRect = !!(aForm->dwStyle & CFS_EXCLUDE); + if (position.mExcludeRect) { + position.mRect.x = aForm->rcArea.left; + position.mRect.y = aForm->rcArea.top; + position.mRect.width = aForm->rcArea.right - aForm->rcArea.left; + position.mRect.height = aForm->rcArea.bottom - aForm->rcArea.top; + } + + sCurrentPluginInstance->SendSetCandidateWindow(position); return TRUE; } diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 8dcbd99c464..ea755c042e3 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -2396,13 +2396,13 @@ PluginInstanceParent::RecvGetCompositionString(const uint32_t& aIndex, } bool -PluginInstanceParent::RecvSetCandidateWindow(const int32_t& aX, - const int32_t& aY) +PluginInstanceParent::RecvSetCandidateWindow( + const mozilla::widget::CandidateWindowPosition& aPosition) { #if defined(OS_WIN) nsPluginInstanceOwner* owner = GetOwner(); if (owner) { - owner->SetCandidateWindow(aX, aY); + owner->SetCandidateWindow(aPosition); } #endif return true; diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index 2e211824c0f..751cc72574d 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -359,7 +359,8 @@ public: nsTArray* aBuffer, int32_t* aLength) override; virtual bool - RecvSetCandidateWindow(const int32_t& aX, const int32_t& aY) override; + RecvSetCandidateWindow( + const mozilla::widget::CandidateWindowPosition& aPosition) override; virtual bool RecvRequestCommitOrCancel(const bool& aCommitted) override; diff --git a/widget/IMEData.h b/widget/IMEData.h index 4e2adb55cd7..8c022331942 100644 --- a/widget/IMEData.h +++ b/widget/IMEData.h @@ -859,6 +859,18 @@ struct IMENotification final } }; +struct CandidateWindowPosition +{ + // Upper left corner of the candidate window if mExcludeRect is false. + // Otherwise, the position currently interested. E.g., caret position. + LayoutDeviceIntPoint mPoint; + // Rect which shouldn't be overlapped with the candidate window. + // This is valid only when mExcludeRect is true. + LayoutDeviceIntRect mRect; + // See explanation of mPoint and mRect. + bool mExcludeRect; +}; + } // namespace widget } // namespace mozilla diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index 5f27f6e4dbb..74dd4a31aa8 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -1414,13 +1414,14 @@ PuppetWidget::GetCurrentWidgetListener() } void -PuppetWidget::SetCandidateWindowForPlugin(int32_t aX, int32_t aY) +PuppetWidget::SetCandidateWindowForPlugin( + const CandidateWindowPosition& aPosition) { if (!mTabChild) { return; } - mTabChild->SendSetCandidateWindowForPlugin(aX, aY); + mTabChild->SendSetCandidateWindowForPlugin(aPosition); } void diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index a9ea5c03626..bca266879c3 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -253,7 +253,8 @@ public: virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override; - virtual void SetCandidateWindowForPlugin(int32_t aX, int32_t aY) override; + virtual void SetCandidateWindowForPlugin( + const CandidateWindowPosition& aPosition) override; virtual void ZoomToRect(const uint32_t& aPresShellId, const FrameMetrics::ViewID& aViewId, diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index 34729aaa3fd..d3a74b35f57 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -223,8 +223,9 @@ public: { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHOD SetPluginFocused(bool& aFocused) override { return NS_ERROR_NOT_IMPLEMENTED; } - virtual void SetCandidateWindowForPlugin(int32_t aX, - int32_t aY) override + virtual void SetCandidateWindowForPlugin( + const mozilla::widget::CandidateWindowPosition& + aPosition) override { } virtual void DefaultProcOfPluginEvent( const mozilla::WidgetPluginEvent& aEvent) override diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index a9d75142b94..964625feabd 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -950,6 +950,26 @@ struct ParamTraits } }; +template<> +struct ParamTraits +{ + typedef mozilla::widget::CandidateWindowPosition paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mPoint); + WriteParam(aMsg, aParam.mRect); + WriteParam(aMsg, aParam.mExcludeRect); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, &aResult->mPoint) && + ReadParam(aMsg, aIter, &aResult->mRect) && + ReadParam(aMsg, aIter, &aResult->mExcludeRect); + } +}; + } // namespace IPC #endif // nsGUIEventIPC_h__ diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 02b31c0b386..7c99fc42bc2 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -1835,7 +1835,8 @@ public: /** * Set IME candidate window position by windowless plugin. */ - virtual void SetCandidateWindowForPlugin(int32_t aX, int32_t aY) = 0; + virtual void SetCandidateWindowForPlugin( + const mozilla::widget::CandidateWindowPosition& aPosition) = 0; /** * Handle default action when PluginEvent isn't handled diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 1dd17237cae..4cdb114238b 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -7843,13 +7843,21 @@ nsWindow::ComputeShouldAccelerate() } void -nsWindow::SetCandidateWindowForPlugin(int32_t aX, int32_t aY) +nsWindow::SetCandidateWindowForPlugin(const CandidateWindowPosition& aPosition) { CANDIDATEFORM form; form.dwIndex = 0; - form.dwStyle = CFS_CANDIDATEPOS; - form.ptCurrentPos.x = aX; - form.ptCurrentPos.y = aY; + if (aPosition.mExcludeRect) { + form.dwStyle = CFS_EXCLUDE; + form.rcArea.left = aPosition.mRect.x; + form.rcArea.top = aPosition.mRect.y; + form.rcArea.right = aPosition.mRect.x + aPosition.mRect.width; + form.rcArea.bottom = aPosition.mRect.y + aPosition.mRect.height; + } else { + form.dwStyle = CFS_CANDIDATEPOS; + } + form.ptCurrentPos.x = aPosition.mPoint.x; + form.ptCurrentPos.y = aPosition.mPoint.y; IMEHandler::SetCandidateWindow(this, &form); } diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 95faa6ca2f9..505558b95f6 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -305,8 +305,9 @@ public: const IMEContext& DefaultIMC() const { return mDefaultIMC; } - virtual void SetCandidateWindowForPlugin(int32_t aX, - int32_t aY) override; + virtual void SetCandidateWindowForPlugin( + const mozilla::widget::CandidateWindowPosition& + aPosition) override; virtual void DefaultProcOfPluginEvent( const mozilla::WidgetPluginEvent& aEvent) override;