Bug 1243268 - Support ImmSetCandidateWindow(CFS_EXCLUDE) on plugin process. r=masayuki

This commit is contained in:
Makoto Kato 2016-02-02 17:05:56 +09:00
parent f54117c214
commit 1f53891ed3
17 changed files with 90 additions and 33 deletions

View File

@ -70,6 +70,7 @@ using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h";
using mozilla::EventMessage from "mozilla/EventForwards.h"; using mozilla::EventMessage from "mozilla/EventForwards.h";
using nsEventStatus from "mozilla/EventForwards.h"; using nsEventStatus from "mozilla/EventForwards.h";
using nsSizeMode from "nsIWidgetListener.h"; using nsSizeMode from "nsIWidgetListener.h";
using mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h";
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -284,7 +285,7 @@ parent:
/** /**
* Set IME candidate window by windowless plugin if plugin has focus. * 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 * When plugin event isn't consumed, call this

View File

@ -2392,15 +2392,15 @@ TabParent::RecvSetPluginFocused(const bool& aFocused)
} }
bool bool
TabParent::RecvSetCandidateWindowForPlugin(const int32_t& aX, TabParent::RecvSetCandidateWindowForPlugin(
const int32_t& aY) const CandidateWindowPosition& aPosition)
{ {
nsCOMPtr<nsIWidget> widget = GetWidget(); nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) { if (!widget) {
return true; return true;
} }
widget->SetCandidateWindowForPlugin(aX, aY); widget->SetCandidateWindowForPlugin(aPosition);
return true; return true;
} }

View File

@ -238,8 +238,8 @@ public:
virtual bool RecvSetPluginFocused(const bool& aFocused) override; virtual bool RecvSetPluginFocused(const bool& aFocused) override;
virtual bool RecvSetCandidateWindowForPlugin(const int32_t& aX, virtual bool RecvSetCandidateWindowForPlugin(
const int32_t& aY) override; const widget::CandidateWindowPosition& aPosition) override;
virtual bool virtual bool
RecvDefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) override; RecvDefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) override;

View File

@ -941,7 +941,8 @@ nsPluginInstanceOwner::GetCompositionString(uint32_t aType,
} }
bool bool
nsPluginInstanceOwner::SetCandidateWindow(int32_t aX, int32_t aY) nsPluginInstanceOwner::SetCandidateWindow(
const widget::CandidateWindowPosition& aPosition)
{ {
if (NS_WARN_IF(!mPluginFrame)) { if (NS_WARN_IF(!mPluginFrame)) {
return false; return false;
@ -955,7 +956,7 @@ nsPluginInstanceOwner::SetCandidateWindow(int32_t aX, int32_t aY)
} }
} }
widget->SetCandidateWindowForPlugin(aX, aY); widget->SetCandidateWindowForPlugin(aPosition);
return true; return true;
} }

View File

@ -269,7 +269,8 @@ public:
bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString, bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString,
int32_t* aLength); int32_t* aLength);
bool SetCandidateWindow(int32_t aX, int32_t aY); bool SetCandidateWindow(
const mozilla::widget::CandidateWindowPosition& aPosition);
bool RequestCommitOrCancel(bool aCommitted); bool RequestCommitOrCancel(bool aCommitted);
private: private:

View File

@ -31,6 +31,7 @@ using mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h";
using nsIntRect from "nsRect.h"; using nsIntRect from "nsRect.h";
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h"; using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h"; using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h";
using struct mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h";
namespace mozilla { namespace mozilla {
namespace plugins { namespace plugins {
@ -264,9 +265,8 @@ parent:
returns (uint8_t[] aDist, int32_t aLength); returns (uint8_t[] aDist, int32_t aLength);
// Set candidate window position. // Set candidate window position.
// //
// @param aX x position of candidate window // @param aPosition position information of candidate window
// @param aY y position of candidate window async SetCandidateWindow(CandidateWindowPosition aPosition);
async SetCandidateWindow(int32_t aX, int32_t aY);
async RequestCommitOrCancel(bool aCommitted); async RequestCommitOrCancel(bool aCommitted);
both: both:

View File

@ -2065,14 +2065,22 @@ PluginInstanceChild::ImmSetCandidateWindowProc(HIMC aIMC, LPCANDIDATEFORM aForm)
} }
if (!sCurrentPluginInstance || if (!sCurrentPluginInstance ||
aForm->dwIndex != 0 || aForm->dwIndex != 0) {
!(aForm->dwStyle & CFS_CANDIDATEPOS)) {
// Flash only uses CFS_CANDIDATEPOS with index == 0.
return FALSE; return FALSE;
} }
sCurrentPluginInstance->SendSetCandidateWindow( CandidateWindowPosition position;
aForm->ptCurrentPos.x, aForm->ptCurrentPos.y); 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; return TRUE;
} }

View File

@ -2396,13 +2396,13 @@ PluginInstanceParent::RecvGetCompositionString(const uint32_t& aIndex,
} }
bool bool
PluginInstanceParent::RecvSetCandidateWindow(const int32_t& aX, PluginInstanceParent::RecvSetCandidateWindow(
const int32_t& aY) const mozilla::widget::CandidateWindowPosition& aPosition)
{ {
#if defined(OS_WIN) #if defined(OS_WIN)
nsPluginInstanceOwner* owner = GetOwner(); nsPluginInstanceOwner* owner = GetOwner();
if (owner) { if (owner) {
owner->SetCandidateWindow(aX, aY); owner->SetCandidateWindow(aPosition);
} }
#endif #endif
return true; return true;

View File

@ -359,7 +359,8 @@ public:
nsTArray<uint8_t>* aBuffer, nsTArray<uint8_t>* aBuffer,
int32_t* aLength) override; int32_t* aLength) override;
virtual bool virtual bool
RecvSetCandidateWindow(const int32_t& aX, const int32_t& aY) override; RecvSetCandidateWindow(
const mozilla::widget::CandidateWindowPosition& aPosition) override;
virtual bool virtual bool
RecvRequestCommitOrCancel(const bool& aCommitted) override; RecvRequestCommitOrCancel(const bool& aCommitted) override;

View File

@ -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 widget
} // namespace mozilla } // namespace mozilla

View File

@ -1414,13 +1414,14 @@ PuppetWidget::GetCurrentWidgetListener()
} }
void void
PuppetWidget::SetCandidateWindowForPlugin(int32_t aX, int32_t aY) PuppetWidget::SetCandidateWindowForPlugin(
const CandidateWindowPosition& aPosition)
{ {
if (!mTabChild) { if (!mTabChild) {
return; return;
} }
mTabChild->SendSetCandidateWindowForPlugin(aX, aY); mTabChild->SendSetCandidateWindowForPlugin(aPosition);
} }
void void

View File

@ -253,7 +253,8 @@ public:
virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override; 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, virtual void ZoomToRect(const uint32_t& aPresShellId,
const FrameMetrics::ViewID& aViewId, const FrameMetrics::ViewID& aViewId,

View File

@ -223,8 +223,9 @@ public:
{ return NS_ERROR_NOT_IMPLEMENTED; } { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD SetPluginFocused(bool& aFocused) override NS_IMETHOD SetPluginFocused(bool& aFocused) override
{ return NS_ERROR_NOT_IMPLEMENTED; } { return NS_ERROR_NOT_IMPLEMENTED; }
virtual void SetCandidateWindowForPlugin(int32_t aX, virtual void SetCandidateWindowForPlugin(
int32_t aY) override const mozilla::widget::CandidateWindowPosition&
aPosition) override
{ } { }
virtual void DefaultProcOfPluginEvent( virtual void DefaultProcOfPluginEvent(
const mozilla::WidgetPluginEvent& aEvent) override const mozilla::WidgetPluginEvent& aEvent) override

View File

@ -950,6 +950,26 @@ struct ParamTraits<mozilla::ContentCache>
} }
}; };
template<>
struct ParamTraits<mozilla::widget::CandidateWindowPosition>
{
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 } // namespace IPC
#endif // nsGUIEventIPC_h__ #endif // nsGUIEventIPC_h__

View File

@ -1835,7 +1835,8 @@ public:
/** /**
* Set IME candidate window position by windowless plugin. * 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 * Handle default action when PluginEvent isn't handled

View File

@ -7843,13 +7843,21 @@ nsWindow::ComputeShouldAccelerate()
} }
void void
nsWindow::SetCandidateWindowForPlugin(int32_t aX, int32_t aY) nsWindow::SetCandidateWindowForPlugin(const CandidateWindowPosition& aPosition)
{ {
CANDIDATEFORM form; CANDIDATEFORM form;
form.dwIndex = 0; form.dwIndex = 0;
form.dwStyle = CFS_CANDIDATEPOS; if (aPosition.mExcludeRect) {
form.ptCurrentPos.x = aX; form.dwStyle = CFS_EXCLUDE;
form.ptCurrentPos.y = aY; 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); IMEHandler::SetCandidateWindow(this, &form);
} }

View File

@ -305,8 +305,9 @@ public:
const IMEContext& DefaultIMC() const { return mDefaultIMC; } const IMEContext& DefaultIMC() const { return mDefaultIMC; }
virtual void SetCandidateWindowForPlugin(int32_t aX, virtual void SetCandidateWindowForPlugin(
int32_t aY) override; const mozilla::widget::CandidateWindowPosition&
aPosition) override;
virtual void DefaultProcOfPluginEvent( virtual void DefaultProcOfPluginEvent(
const mozilla::WidgetPluginEvent& aEvent) override; const mozilla::WidgetPluginEvent& aEvent) override;