mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1182411 Part 2: Change winless popup surrogate to have its parent set in the chrome process. r=jimm
The creation of the surrogate native window in the child NPAPI process was failing when then sandbox was at low integrity, because the parent is from the chrome process, so at medium integrity. Instead of making an IPC call to get the parent, we now create the window upfront and send it in an IPC message to be parented in the chrome process. This is done with asynchronous messaging.
This commit is contained in:
parent
4b8fd6e69b
commit
01f693c138
@ -144,6 +144,12 @@ parent:
|
|||||||
*/
|
*/
|
||||||
sync GetWidgetNativeData() returns (WindowsHandle value);
|
sync GetWidgetNativeData() returns (WindowsHandle value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW to be adopted by the
|
||||||
|
* widget's shareable window on the chrome side. Only used on Windows.
|
||||||
|
*/
|
||||||
|
async SetNativeChildOfShareableWindow(uintptr_t childWindow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When content moves focus from a native plugin window that's a child
|
* When content moves focus from a native plugin window that's a child
|
||||||
* of the native browser window we need to move native focus to the
|
* of the native browser window we need to move native focus to the
|
||||||
|
@ -2537,6 +2537,24 @@ TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TabParent::RecvSetNativeChildOfShareableWindow(const uintptr_t& aChildWindow)
|
||||||
|
{
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
|
||||||
|
if (widget) {
|
||||||
|
// Note that this call will probably cause a sync native message to the
|
||||||
|
// process that owns the child window.
|
||||||
|
widget->SetNativeData(NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW, aChildWindow);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
NS_NOTREACHED(
|
||||||
|
"TabParent::RecvSetNativeChildOfShareableWindow not implemented!");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabParent::RecvDispatchFocusToTopLevelWindow()
|
TabParent::RecvDispatchFocusToTopLevelWindow()
|
||||||
{
|
{
|
||||||
|
@ -221,6 +221,7 @@ public:
|
|||||||
virtual bool RecvGetDefaultScale(double* aValue) override;
|
virtual bool RecvGetDefaultScale(double* aValue) override;
|
||||||
virtual bool RecvGetMaxTouchPoints(uint32_t* aTouchPoints) override;
|
virtual bool RecvGetMaxTouchPoints(uint32_t* aTouchPoints) override;
|
||||||
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue) override;
|
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue) override;
|
||||||
|
virtual bool RecvSetNativeChildOfShareableWindow(const uintptr_t& childWindow) override;
|
||||||
virtual bool RecvDispatchFocusToTopLevelWindow() override;
|
virtual bool RecvDispatchFocusToTopLevelWindow() override;
|
||||||
virtual bool RecvZoomToRect(const uint32_t& aPresShellId,
|
virtual bool RecvZoomToRect(const uint32_t& aPresShellId,
|
||||||
const ViewID& aViewId,
|
const ViewID& aViewId,
|
||||||
|
@ -642,23 +642,17 @@ nsPluginInstanceOwner::RedrawPlugin()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
|
|
||||||
{
|
|
||||||
if (!mPluginFrame) {
|
|
||||||
NS_WARNING("plugin owner has no owner in getting doc's window handle");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
void** pvalue = (void**)value;
|
nsIWidget*
|
||||||
nsViewManager* vm = mPluginFrame->PresContext()->GetPresShell()->GetViewManager();
|
nsPluginInstanceOwner::GetContainingWidgetIfOffset()
|
||||||
if (!vm)
|
{
|
||||||
return NS_ERROR_FAILURE;
|
MOZ_ASSERT(mPluginFrame, "Caller should have checked for null mPluginFrame.");
|
||||||
|
|
||||||
// This property is provided to allow a "windowless" plugin to determine the window it is drawing
|
// This property is provided to allow a "windowless" plugin to determine the window it is drawing
|
||||||
// in, so it can translate mouse coordinates it receives directly from the operating system
|
// in, so it can translate mouse coordinates it receives directly from the operating system
|
||||||
// to coordinates relative to itself.
|
// to coordinates relative to itself.
|
||||||
|
|
||||||
// The original code (outside this #if) returns the document's window, which is OK if the window the "windowless" plugin
|
// The original code returns the document's window, which is OK if the window the "windowless" plugin
|
||||||
// is drawing into has the same origin as the document's window, but this is not the case for "windowless" plugins inside of scrolling DIVs etc
|
// is drawing into has the same origin as the document's window, but this is not the case for "windowless" plugins inside of scrolling DIVs etc
|
||||||
|
|
||||||
// To make sure "windowless" plugins always get the right origin for translating mouse coordinates, this code
|
// To make sure "windowless" plugins always get the right origin for translating mouse coordinates, this code
|
||||||
@ -692,17 +686,53 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
|
|||||||
if (offset.x || offset.y) {
|
if (offset.x || offset.y) {
|
||||||
// in the case the two windows are offset from eachother, we do go ahead and return the correct enclosing window
|
// in the case the two windows are offset from eachother, we do go ahead and return the correct enclosing window
|
||||||
// so that mouse co-ordinates are not messed up.
|
// so that mouse co-ordinates are not messed up.
|
||||||
*pvalue = (void*)win->GetNativeData(NS_NATIVE_WINDOW);
|
return win;
|
||||||
if (*pvalue)
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<nsIWidget>
|
||||||
|
GetRootWidgetForPluginFrame(const nsPluginFrame* aPluginFrame)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aPluginFrame);
|
||||||
|
|
||||||
|
nsViewManager* vm =
|
||||||
|
aPluginFrame->PresContext()->GetPresShell()->GetViewManager();
|
||||||
|
if (!vm) {
|
||||||
|
NS_WARNING("Could not find view manager for plugin frame.");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIWidget> rootWidget;
|
||||||
|
vm->GetRootWidget(getter_AddRefs(rootWidget));
|
||||||
|
return rootWidget.forget();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
|
||||||
|
{
|
||||||
|
if (!mPluginFrame) {
|
||||||
|
NS_WARNING("plugin owner has no owner in getting doc's window handle");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
void** pvalue = (void**)value;
|
||||||
|
nsIWidget* offsetContainingWidget = GetContainingWidgetIfOffset();
|
||||||
|
if (offsetContainingWidget) {
|
||||||
|
*pvalue = (void*)offsetContainingWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||||
|
if (*pvalue) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// simply return the topmost document window
|
// simply return the topmost document window
|
||||||
nsCOMPtr<nsIWidget> widget;
|
nsCOMPtr<nsIWidget> widget = GetRootWidgetForPluginFrame(mPluginFrame);
|
||||||
vm->GetRootWidget(getter_AddRefs(widget));
|
|
||||||
if (widget) {
|
if (widget) {
|
||||||
*pvalue = (void*)widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
|
*pvalue = widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
|
||||||
} else {
|
} else {
|
||||||
NS_ASSERTION(widget, "couldn't get doc's widget in getting doc's window handle");
|
NS_ASSERTION(widget, "couldn't get doc's widget in getting doc's window handle");
|
||||||
}
|
}
|
||||||
@ -720,6 +750,48 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
void
|
||||||
|
nsPluginInstanceOwner::SetWidgetWindowAsParent(HWND aWindowToAdopt)
|
||||||
|
{
|
||||||
|
if (!mWidget) {
|
||||||
|
NS_ERROR("mWidget should exist before this gets called.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mWidget->SetNativeData(NS_NATIVE_CHILD_WINDOW,
|
||||||
|
reinterpret_cast<uintptr_t>(aWindowToAdopt));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsPluginInstanceOwner::SetNetscapeWindowAsParent(HWND aWindowToAdopt)
|
||||||
|
{
|
||||||
|
if (!mPluginFrame) {
|
||||||
|
NS_WARNING("Plugin owner has no plugin frame.");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a containing window that is offset then ask that to adopt.
|
||||||
|
nsIWidget* offsetWidget = GetContainingWidgetIfOffset();
|
||||||
|
if (offsetWidget) {
|
||||||
|
offsetWidget->SetNativeData(NS_NATIVE_CHILD_WINDOW,
|
||||||
|
reinterpret_cast<uintptr_t>(aWindowToAdopt));
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise ask the topmost document window to adopt.
|
||||||
|
nsCOMPtr<nsIWidget> rootWidget = GetRootWidgetForPluginFrame(mPluginFrame);
|
||||||
|
if (!rootWidget) {
|
||||||
|
NS_ASSERTION(rootWidget, "Couldn't get topmost document's widget.");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rootWidget->SetNativeData(NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW,
|
||||||
|
reinterpret_cast<uintptr_t>(aWindowToAdopt));
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
NS_IMETHODIMP nsPluginInstanceOwner::SetEventModel(int32_t eventModel)
|
NS_IMETHODIMP nsPluginInstanceOwner::SetEventModel(int32_t eventModel)
|
||||||
{
|
{
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
|
@ -112,6 +112,11 @@ public:
|
|||||||
void ReleasePluginPort(void* pluginPort);
|
void ReleasePluginPort(void* pluginPort);
|
||||||
|
|
||||||
nsEventStatus ProcessEvent(const mozilla::WidgetGUIEvent& anEvent);
|
nsEventStatus ProcessEvent(const mozilla::WidgetGUIEvent& anEvent);
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
void SetWidgetWindowAsParent(HWND aWindowToAdopt);
|
||||||
|
nsresult SetNetscapeWindowAsParent(HWND aWindowToAdopt);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
enum { ePluginPaintEnable, ePluginPaintDisable };
|
enum { ePluginPaintEnable, ePluginPaintDisable };
|
||||||
@ -273,6 +278,10 @@ private:
|
|||||||
bool mFullScreen;
|
bool mFullScreen;
|
||||||
void* mJavaView;
|
void* mJavaView;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
nsIWidget* GetContainingWidgetIfOffset();
|
||||||
|
#endif
|
||||||
|
|
||||||
nsPluginNativeWindow *mPluginWindow;
|
nsPluginNativeWindow *mPluginWindow;
|
||||||
nsRefPtr<nsNPAPIPluginInstance> mInstance;
|
nsRefPtr<nsNPAPIPluginInstance> mInstance;
|
||||||
|
@ -70,8 +70,11 @@ child:
|
|||||||
|
|
||||||
// This is only used on Windows and, for windowed plugins, must be called
|
// This is only used on Windows and, for windowed plugins, must be called
|
||||||
// before the first call to NPP_SetWindow.
|
// before the first call to NPP_SetWindow.
|
||||||
intr CreateChildPluginWindow(NPRemoteWindow window)
|
intr CreateChildPluginWindow()
|
||||||
returns (NPRemoteWindow createdChild);
|
returns (NativeWindowHandle childPluginWindow);
|
||||||
|
|
||||||
|
// This is only used on Windows and, for windowless plugins.
|
||||||
|
async CreateChildPopupSurrogate(NativeWindowHandle netscapeWindow);
|
||||||
|
|
||||||
intr NPP_SetWindow(NPRemoteWindow window);
|
intr NPP_SetWindow(NPRemoteWindow window);
|
||||||
|
|
||||||
@ -219,6 +222,10 @@ parent:
|
|||||||
// Notifies the parent of its NPP_New result code.
|
// Notifies the parent of its NPP_New result code.
|
||||||
async AsyncNPP_NewResult(NPError aResult);
|
async AsyncNPP_NewResult(NPError aResult);
|
||||||
|
|
||||||
|
// Sends a native window to be adopted by the native window that would be
|
||||||
|
// returned by NPN_GetValue_NPNVnetscapeWindow. Only used on Windows.
|
||||||
|
async SetNetscapeWindowAsParent(NativeWindowHandle childWindow);
|
||||||
|
|
||||||
both:
|
both:
|
||||||
async PPluginScriptableObject();
|
async PPluginScriptableObject();
|
||||||
|
|
||||||
|
@ -1146,25 +1146,31 @@ void PluginInstanceChild::DeleteWindow()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PluginInstanceChild::AnswerCreateChildPluginWindow(const NPRemoteWindow& aWindow,
|
PluginInstanceChild::AnswerCreateChildPluginWindow(NativeWindowHandle* aChildPluginWindow)
|
||||||
NPRemoteWindow* aCreatedChild)
|
|
||||||
{
|
{
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
MOZ_ASSERT(aWindow.type == NPWindowTypeWindow);
|
|
||||||
MOZ_ASSERT(!mPluginWindowHWND);
|
MOZ_ASSERT(!mPluginWindowHWND);
|
||||||
|
|
||||||
if ((GetQuirks() & PluginModuleChild::QUIRK_QUICKTIME_AVOID_SETWINDOW) &&
|
|
||||||
aWindow.width == 0 && aWindow.height == 0) {
|
|
||||||
|
|
||||||
// Skip CreateChildPluginWindow call for hidden QuickTime plugins.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CreatePluginWindow()) {
|
if (!CreatePluginWindow()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
aCreatedChild->window = reinterpret_cast<uint64_t>(mPluginWindowHWND);
|
MOZ_ASSERT(mPluginWindowHWND);
|
||||||
|
|
||||||
|
*aChildPluginWindow = mPluginWindowHWND;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
NS_NOTREACHED("PluginInstanceChild::CreateChildPluginWindow not implemented!");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PluginInstanceChild::RecvCreateChildPopupSurrogate(const NativeWindowHandle& aNetscapeWindow)
|
||||||
|
{
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
mCachedWinlessPluginHWND = aNetscapeWindow;
|
||||||
|
CreateWinlessPopupSurrogate();
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
NS_NOTREACHED("PluginInstanceChild::CreateChildPluginWindow not implemented!");
|
NS_NOTREACHED("PluginInstanceChild::CreateChildPluginWindow not implemented!");
|
||||||
@ -1254,12 +1260,10 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
|||||||
switch (aWindow.type) {
|
switch (aWindow.type) {
|
||||||
case NPWindowTypeWindow:
|
case NPWindowTypeWindow:
|
||||||
{
|
{
|
||||||
if ((GetQuirks() & QUIRK_QUICKTIME_AVOID_SETWINDOW) &&
|
// This check is now done in PluginInstanceParent before this call, so
|
||||||
aWindow.width == 0 &&
|
// we should never see it here.
|
||||||
aWindow.height == 0) {
|
MOZ_ASSERT(!(GetQuirks() & QUIRK_QUICKTIME_AVOID_SETWINDOW) ||
|
||||||
// Skip SetWindow call for hidden QuickTime plugins
|
aWindow.width != 0 || aWindow.height != 0);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(mPluginWindowHWND,
|
MOZ_ASSERT(mPluginWindowHWND,
|
||||||
"Child plugin window must exist before call to SetWindow");
|
"Child plugin window must exist before call to SetWindow");
|
||||||
@ -1298,8 +1302,6 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
|||||||
|
|
||||||
case NPWindowTypeDrawable:
|
case NPWindowTypeDrawable:
|
||||||
mWindow.type = aWindow.type;
|
mWindow.type = aWindow.type;
|
||||||
if (GetQuirks() & QUIRK_WINLESS_TRACKPOPUP_HOOK)
|
|
||||||
CreateWinlessPopupSurrogate();
|
|
||||||
if (GetQuirks() & QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
|
if (GetQuirks() & QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
|
||||||
SetupFlashMsgThrottle();
|
SetupFlashMsgThrottle();
|
||||||
return SharedSurfaceSetWindow(aWindow);
|
return SharedSurfaceSetWindow(aWindow);
|
||||||
@ -1968,21 +1970,15 @@ PluginInstanceChild::CreateWinlessPopupSurrogate()
|
|||||||
if (mWinlessPopupSurrogateHWND)
|
if (mWinlessPopupSurrogateHWND)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
HWND hwnd = nullptr;
|
|
||||||
NPError result;
|
|
||||||
if (!CallNPN_GetValue_NPNVnetscapeWindow(&hwnd, &result)) {
|
|
||||||
NS_ERROR("CallNPN_GetValue_NPNVnetscapeWindow failed.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mWinlessPopupSurrogateHWND =
|
mWinlessPopupSurrogateHWND =
|
||||||
CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Static", nullptr, WS_CHILD,
|
CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Static", nullptr, WS_POPUP,
|
||||||
0, 0, 0, 0, hwnd, 0, GetModuleHandle(nullptr), 0);
|
0, 0, 0, 0, nullptr, 0, GetModuleHandle(nullptr), 0);
|
||||||
if (!mWinlessPopupSurrogateHWND) {
|
if (!mWinlessPopupSurrogateHWND) {
|
||||||
NS_ERROR("CreateWindowEx failed for winless placeholder!");
|
NS_ERROR("CreateWindowEx failed for winless placeholder!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
SendSetNetscapeWindowAsParent(mWinlessPopupSurrogateHWND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2833,8 +2829,6 @@ PluginInstanceChild::DoAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
|
|||||||
UpdateWindowAttributes(true);
|
UpdateWindowAttributes(true);
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
if (GetQuirks() & QUIRK_WINLESS_TRACKPOPUP_HOOK)
|
|
||||||
CreateWinlessPopupSurrogate();
|
|
||||||
if (GetQuirks() & QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
|
if (GetQuirks() & QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
|
||||||
SetupFlashMsgThrottle();
|
SetupFlashMsgThrottle();
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,10 +65,14 @@ class PluginInstanceChild : public PPluginInstanceChild
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool AnswerCreateChildPluginWindow(const NPRemoteWindow& window,
|
virtual bool
|
||||||
NPRemoteWindow* aCreatedChild) override;
|
AnswerCreateChildPluginWindow(NativeWindowHandle* aChildPluginWindow) override;
|
||||||
|
|
||||||
bool AnswerNPP_SetWindow(const NPRemoteWindow& window) override;
|
virtual bool
|
||||||
|
RecvCreateChildPopupSurrogate(const NativeWindowHandle& aNetscapeWindow) override;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
AnswerNPP_SetWindow(const NPRemoteWindow& window) override;
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
AnswerNPP_GetValue_NPPVpluginWantsAllNetworkStreams(bool* wantsAllStreams, NPError* rv) override;
|
AnswerNPP_GetValue_NPPVpluginWantsAllNetworkStreams(bool* wantsAllStreams, NPError* rv) override;
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsIWidget.h"
|
#include "nsIWidget.h"
|
||||||
#include "nsPluginNativeWindow.h"
|
#include "nsPluginNativeWindow.h"
|
||||||
|
#include "PluginQuirks.h"
|
||||||
extern const wchar_t* kFlashFullscreenClass;
|
extern const wchar_t* kFlashFullscreenClass;
|
||||||
#elif defined(MOZ_WIDGET_GTK)
|
#elif defined(MOZ_WIDGET_GTK)
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
@ -679,6 +680,11 @@ PluginInstanceParent::AsyncSetWindow(NPWindow* aWindow)
|
|||||||
mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
|
mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
|
||||||
window.contentsScaleFactor = scaleFactor;
|
window.contentsScaleFactor = scaleFactor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
MaybeCreateChildPopupSurrogate();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
|
if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
|
||||||
window))
|
window))
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
@ -967,16 +973,29 @@ PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
|
|||||||
if (!SharedSurfaceSetWindow(aWindow, window)) {
|
if (!SharedSurfaceSetWindow(aWindow, window)) {
|
||||||
return NPERR_OUT_OF_MEMORY_ERROR;
|
return NPERR_OUT_OF_MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
MaybeCreateChildPopupSurrogate();
|
||||||
|
} else {
|
||||||
SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
|
SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
|
||||||
|
|
||||||
|
// Skip SetWindow call for hidden QuickTime plugins.
|
||||||
|
if ((mParent->GetQuirks() & QUIRK_QUICKTIME_AVOID_SETWINDOW) &&
|
||||||
|
aWindow->width == 0 && aWindow->height == 0) {
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
window.window = reinterpret_cast<uint64_t>(aWindow->window);
|
window.window = reinterpret_cast<uint64_t>(aWindow->window);
|
||||||
window.x = aWindow->x;
|
window.x = aWindow->x;
|
||||||
window.y = aWindow->y;
|
window.y = aWindow->y;
|
||||||
window.width = aWindow->width;
|
window.width = aWindow->width;
|
||||||
window.height = aWindow->height;
|
window.height = aWindow->height;
|
||||||
window.type = aWindow->type;
|
window.type = aWindow->type;
|
||||||
|
|
||||||
|
// On Windows we need to create and set the parent before we set the
|
||||||
|
// window on the plugin, or keyboard interaction will not work.
|
||||||
|
if (!MaybeCreateAndParentChildPluginWindow()) {
|
||||||
|
return NPERR_GENERIC_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
window.window = reinterpret_cast<uint64_t>(aWindow->window);
|
window.window = reinterpret_cast<uint64_t>(aWindow->window);
|
||||||
@ -1027,33 +1046,6 @@ PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
|
|||||||
window.colormap = ws_info->colormap;
|
window.colormap = ws_info->colormap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
|
||||||
// On Windows we need to create and set the parent before we set the window
|
|
||||||
// on the plugin, or certain things like keyboard interaction will not work.
|
|
||||||
if (!mChildPluginHWND && mWindowType == NPWindowTypeWindow) {
|
|
||||||
NPRemoteWindow childWindow;
|
|
||||||
if (!CallCreateChildPluginWindow(window, &childWindow)) {
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
mChildPluginHWND = reinterpret_cast<HWND>(childWindow.window);
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's not clear if the parent window would ever change, but when this was
|
|
||||||
// done in the NPAPI child it used to allow for this.
|
|
||||||
if (mChildPluginHWND && mPluginHWND != mChildPluginsParentHWND) {
|
|
||||||
nsCOMPtr<nsIWidget> widget;
|
|
||||||
static_cast<const nsPluginNativeWindow*>(aWindow)->
|
|
||||||
GetPluginWidget(getter_AddRefs(widget));
|
|
||||||
if (widget) {
|
|
||||||
widget->SetNativeData(NS_NATIVE_CHILD_WINDOW,
|
|
||||||
reinterpret_cast<uintptr_t>(mChildPluginHWND));
|
|
||||||
}
|
|
||||||
|
|
||||||
mChildPluginsParentHWND = mPluginHWND;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!CallNPP_SetWindow(window)) {
|
if (!CallNPP_SetWindow(window)) {
|
||||||
return NPERR_GENERIC_ERROR;
|
return NPERR_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
@ -1806,6 +1798,22 @@ PluginInstanceParent::RecvAsyncNPP_NewResult(const NPError& aResult)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PluginInstanceParent::RecvSetNetscapeWindowAsParent(const NativeWindowHandle& childWindow)
|
||||||
|
{
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
nsPluginInstanceOwner* owner = GetOwner();
|
||||||
|
if (!owner || NS_FAILED(owner->SetNetscapeWindowAsParent(childWindow))) {
|
||||||
|
NS_WARNING("Failed to set Netscape window as parent.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
NS_NOTREACHED("PluginInstanceParent::RecvSetNetscapeWindowAsParent not implemented!");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2050,6 +2058,65 @@ PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
|
|||||||
SRCCOPY);
|
SRCCOPY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PluginInstanceParent::MaybeCreateAndParentChildPluginWindow()
|
||||||
|
{
|
||||||
|
// On Windows we need to create and set the parent before we set the
|
||||||
|
// window on the plugin, or keyboard interaction will not work.
|
||||||
|
if (!mChildPluginHWND) {
|
||||||
|
if (!CallCreateChildPluginWindow(&mChildPluginHWND) ||
|
||||||
|
!mChildPluginHWND) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's not clear if the parent window would ever change, but when this
|
||||||
|
// was done in the NPAPI child it used to allow for this.
|
||||||
|
if (mPluginHWND == mChildPluginsParentHWND) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPluginInstanceOwner* owner = GetOwner();
|
||||||
|
if (!owner) {
|
||||||
|
// We can't reparent without an owner, the plugin is probably shutting
|
||||||
|
// down, just return true to allow any calls to continue.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that this call will probably cause a sync native message to the
|
||||||
|
// process that owns the child window.
|
||||||
|
owner->SetWidgetWindowAsParent(mChildPluginHWND);
|
||||||
|
mChildPluginsParentHWND = mPluginHWND;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PluginInstanceParent::MaybeCreateChildPopupSurrogate()
|
||||||
|
{
|
||||||
|
// Already created or not required for this plugin.
|
||||||
|
if (mChildPluginHWND || mWindowType != NPWindowTypeDrawable ||
|
||||||
|
!(mParent->GetQuirks() & QUIRK_WINLESS_TRACKPOPUP_HOOK)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to pass the netscape window down to be cached as part of the call
|
||||||
|
// to create the surrogate, because the reparenting of the surrogate in the
|
||||||
|
// main process can cause sync Windows messages to the plugin process, which
|
||||||
|
// then cause sync messages from the plugin child for the netscape window
|
||||||
|
// which causes a deadlock.
|
||||||
|
NativeWindowHandle netscapeWindow;
|
||||||
|
NPError result = mNPNIface->getvalue(mNPP, NPNVnetscapeWindow,
|
||||||
|
&netscapeWindow);
|
||||||
|
if (NPERR_NO_ERROR != result) {
|
||||||
|
NS_WARNING("Can't get netscape window to pass to plugin child.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SendCreateChildPopupSurrogate(netscapeWindow)) {
|
||||||
|
NS_WARNING("Failed to create popup surrogate in child.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // defined(OS_WIN)
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -221,6 +221,9 @@ public:
|
|||||||
virtual bool
|
virtual bool
|
||||||
RecvAsyncNPP_NewResult(const NPError& aResult) override;
|
RecvAsyncNPP_NewResult(const NPError& aResult) override;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
RecvSetNetscapeWindowAsParent(const NativeWindowHandle& childWindow) override;
|
||||||
|
|
||||||
NPError NPP_SetWindow(const NPWindow* aWindow);
|
NPError NPP_SetWindow(const NPWindow* aWindow);
|
||||||
|
|
||||||
NPError NPP_GetValue(NPPVariable variable, void* retval);
|
NPError NPP_GetValue(NPPVariable variable, void* retval);
|
||||||
@ -361,11 +364,16 @@ private:
|
|||||||
void SubclassPluginWindow(HWND aWnd);
|
void SubclassPluginWindow(HWND aWnd);
|
||||||
void UnsubclassPluginWindow();
|
void UnsubclassPluginWindow();
|
||||||
|
|
||||||
|
bool MaybeCreateAndParentChildPluginWindow();
|
||||||
|
void MaybeCreateChildPopupSurrogate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gfx::SharedDIBWin mSharedSurfaceDib;
|
gfx::SharedDIBWin mSharedSurfaceDib;
|
||||||
nsIntRect mPluginPort;
|
nsIntRect mPluginPort;
|
||||||
nsIntRect mSharedSize;
|
nsIntRect mSharedSize;
|
||||||
HWND mPluginHWND;
|
HWND mPluginHWND;
|
||||||
|
// This is used for the normal child plugin HWND for windowed plugins and,
|
||||||
|
// if needed, also the child popup surrogate HWND for windowless plugins.
|
||||||
HWND mChildPluginHWND;
|
HWND mChildPluginHWND;
|
||||||
HWND mChildPluginsParentHWND;
|
HWND mChildPluginsParentHWND;
|
||||||
WNDPROC mPluginWndProc;
|
WNDPROC mPluginWndProc;
|
||||||
|
@ -1080,6 +1080,23 @@ PuppetWidget::GetNativeData(uint32_t aDataType)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
void
|
||||||
|
PuppetWidget::SetNativeData(uint32_t aDataType, uintptr_t aVal)
|
||||||
|
{
|
||||||
|
switch (aDataType) {
|
||||||
|
case NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW:
|
||||||
|
MOZ_ASSERT(mTabChild, "Need TabChild to send the message.");
|
||||||
|
if (mTabChild) {
|
||||||
|
mTabChild->SendSetNativeChildOfShareableWindow(aVal);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NS_WARNING("SetNativeData called with unsupported data type.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
nsIntPoint
|
nsIntPoint
|
||||||
PuppetWidget::GetChromeDimensions()
|
PuppetWidget::GetChromeDimensions()
|
||||||
{
|
{
|
||||||
|
@ -119,6 +119,9 @@ public:
|
|||||||
|
|
||||||
// PuppetWidgets don't have native data, as they're purely nonnative.
|
// PuppetWidgets don't have native data, as they're purely nonnative.
|
||||||
virtual void* GetNativeData(uint32_t aDataType) override;
|
virtual void* GetNativeData(uint32_t aDataType) override;
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
void SetNativeData(uint32_t aDataType, uintptr_t aVal) override;
|
||||||
|
#endif
|
||||||
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) override
|
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) override
|
||||||
{ return NS_ERROR_UNEXPECTED; }
|
{ return NS_ERROR_UNEXPECTED; }
|
||||||
|
|
||||||
|
@ -102,6 +102,8 @@ typedef void* nsNativeWidget;
|
|||||||
// HWND on Windows and XID on X11
|
// HWND on Windows and XID on X11
|
||||||
#define NS_NATIVE_SHAREABLE_WINDOW 11
|
#define NS_NATIVE_SHAREABLE_WINDOW 11
|
||||||
#define NS_NATIVE_OPENGL_CONTEXT 12
|
#define NS_NATIVE_OPENGL_CONTEXT 12
|
||||||
|
// See RegisterPluginWindowForRemoteUpdates
|
||||||
|
#define NS_NATIVE_PLUGIN_ID 13
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
#define NS_NATIVE_PLUGIN_PORT_QD 100
|
#define NS_NATIVE_PLUGIN_PORT_QD 100
|
||||||
#define NS_NATIVE_PLUGIN_PORT_CG 101
|
#define NS_NATIVE_PLUGIN_PORT_CG 101
|
||||||
@ -112,13 +114,12 @@ typedef void* nsNativeWidget;
|
|||||||
#define NS_NATIVE_TSF_DISPLAY_ATTR_MGR 102
|
#define NS_NATIVE_TSF_DISPLAY_ATTR_MGR 102
|
||||||
#define NS_NATIVE_ICOREWINDOW 103 // winrt specific
|
#define NS_NATIVE_ICOREWINDOW 103 // winrt specific
|
||||||
#define NS_NATIVE_CHILD_WINDOW 104
|
#define NS_NATIVE_CHILD_WINDOW 104
|
||||||
|
#define NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW 105
|
||||||
#endif
|
#endif
|
||||||
#if defined(MOZ_WIDGET_GTK)
|
#if defined(MOZ_WIDGET_GTK)
|
||||||
// set/get nsPluginNativeWindowGtk, e10s specific
|
// set/get nsPluginNativeWindowGtk, e10s specific
|
||||||
#define NS_NATIVE_PLUGIN_OBJECT_PTR 104
|
#define NS_NATIVE_PLUGIN_OBJECT_PTR 104
|
||||||
#endif
|
#endif
|
||||||
// See RegisterPluginWindowForRemoteUpdates
|
|
||||||
#define NS_NATIVE_PLUGIN_ID 105
|
|
||||||
|
|
||||||
#define NS_IWIDGET_IID \
|
#define NS_IWIDGET_IID \
|
||||||
{ 0x483BF75C, 0xF909, 0x45C3, \
|
{ 0x483BF75C, 0xF909, 0x45C3, \
|
||||||
|
@ -3153,24 +3153,31 @@ void* nsWindow::GetNativeData(uint32_t aDataType)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SetChildStyleAndParent(HWND aChildWindow, HWND aParentWindow)
|
||||||
|
{
|
||||||
|
// Make sure the window is styled to be a child window.
|
||||||
|
LONG_PTR style = GetWindowLongPtr(aChildWindow, GWL_STYLE);
|
||||||
|
style |= WS_CHILD;
|
||||||
|
style &= ~WS_POPUP;
|
||||||
|
SetWindowLongPtr(aChildWindow, GWL_STYLE, style);
|
||||||
|
|
||||||
|
// Do the reparenting. Note that this call will probably cause a sync native
|
||||||
|
// message to the process that owns the child window.
|
||||||
|
::SetParent(aChildWindow, aParentWindow);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsWindow::SetNativeData(uint32_t aDataType, uintptr_t aVal)
|
nsWindow::SetNativeData(uint32_t aDataType, uintptr_t aVal)
|
||||||
{
|
{
|
||||||
switch (aDataType) {
|
switch (aDataType) {
|
||||||
case NS_NATIVE_CHILD_WINDOW:
|
case NS_NATIVE_CHILD_WINDOW:
|
||||||
{
|
SetChildStyleAndParent(reinterpret_cast<HWND>(aVal), mWnd);
|
||||||
HWND childWindow = reinterpret_cast<HWND>(aVal);
|
break;
|
||||||
|
case NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW:
|
||||||
// Make sure the window is styled to be a child window.
|
SetChildStyleAndParent(reinterpret_cast<HWND>(aVal),
|
||||||
LONG_PTR style = GetWindowLongPtr(childWindow, GWL_STYLE);
|
WinUtils::GetTopLevelHWND(mWnd));
|
||||||
style |= WS_CHILD;
|
break;
|
||||||
style &= ~WS_POPUP;
|
|
||||||
SetWindowLongPtr(childWindow, GWL_STYLE, style);
|
|
||||||
|
|
||||||
// Do the reparenting.
|
|
||||||
::SetParent(childWindow, mWnd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
NS_ERROR("SetNativeData called with unsupported data type.");
|
NS_ERROR("SetNativeData called with unsupported data type.");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user