зеркало из https://github.com/mozilla/pjs.git
Fixing bug 176079. Provide an API for plugins to control whether popups are enabled or not. Disable popups by default from plugins, but enable/disable popups while handling user input events (mouse click, keydown etc) on the platforms where it's possible (Win32 and Mac), but do that only if the plugin doesn't support the popup enabling/disabling API. r+sr+a=brendan@mozilla.org
This commit is contained in:
Родитель
9edc942571
Коммит
4f8ee0f3ff
|
@ -137,7 +137,8 @@ public:
|
|||
|
||||
virtual void SetOpenerScriptURL(nsIURI* aURI) = 0;
|
||||
|
||||
virtual PopupControlState PushPopupControlState(PopupControlState aState) const = 0;
|
||||
virtual PopupControlState PushPopupControlState(PopupControlState aState,
|
||||
PRBool aForce) const = 0;
|
||||
virtual void PopPopupControlState(PopupControlState state) const = 0;
|
||||
virtual PopupControlState GetPopupControlState() const = 0;
|
||||
virtual OpenAllowValue GetOpenAllow(const nsAString &aName) = 0;
|
||||
|
@ -205,7 +206,7 @@ public:
|
|||
: mWindow(aWindow), mOldState(openAbused)
|
||||
{
|
||||
if (aWindow) {
|
||||
mOldState = aWindow->PushPopupControlState(aState);
|
||||
mOldState = aWindow->PushPopupControlState(aState, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -410,9 +410,10 @@ PopPopupControlState(PopupControlState aState)
|
|||
}
|
||||
|
||||
PopupControlState
|
||||
nsGlobalWindow::PushPopupControlState(PopupControlState aState) const
|
||||
nsGlobalWindow::PushPopupControlState(PopupControlState aState,
|
||||
PRBool aForce) const
|
||||
{
|
||||
return ::PushPopupControlState(aState, PR_FALSE);
|
||||
return ::PushPopupControlState(aState, aForce);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -199,7 +199,7 @@ public:
|
|||
|
||||
virtual NS_HIDDEN_(void) SetOpenerScriptURL(nsIURI* aURI);
|
||||
|
||||
virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state) const;
|
||||
virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, PRBool aForce) const;
|
||||
virtual NS_HIDDEN_(void) PopPopupControlState(PopupControlState state) const;
|
||||
virtual NS_HIDDEN_(PopupControlState) GetPopupControlState() const;
|
||||
virtual NS_HIDDEN_(OpenAllowValue) GetOpenAllow(const nsAString &aName);
|
||||
|
|
|
@ -420,6 +420,12 @@ pref("dom.popup_maximum", 20);
|
|||
pref("dom.popup_allowed_events", "change click dblclick mouseup reset submit");
|
||||
pref("dom.disable_open_click_delay", 1000);
|
||||
|
||||
// Disable popups from plugins by default
|
||||
// 0 = openAllowed
|
||||
// 1 = openControlled
|
||||
// 2 = openAbused
|
||||
pref("privacy.popups.disable_from_plugins", 2);
|
||||
|
||||
pref("dom.event.contextmenu.enabled", true);
|
||||
|
||||
pref("javascript.enabled", true);
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
/*
|
||||
* npapi.h $Revision: 3.39 $
|
||||
* npapi.h $Revision: 3.40 $
|
||||
* Netscape client plug-in API spec
|
||||
*/
|
||||
|
||||
|
@ -125,7 +125,7 @@
|
|||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define NP_VERSION_MAJOR 0
|
||||
#define NP_VERSION_MINOR 15
|
||||
#define NP_VERSION_MINOR 16
|
||||
|
||||
|
||||
/* The OS/2 version of Netscape uses RC_DATA to define the
|
||||
|
@ -673,9 +673,6 @@ void NP_LOADDS NPP_URLNotify(NPP instance, const char* url,
|
|||
jref NP_LOADDS NPP_GetJavaClass(void);
|
||||
#endif
|
||||
NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value);
|
||||
/*
|
||||
* Uh, shouldn't NPP_SetValue() take an NPPVariable and not an NPNVariable?
|
||||
*/
|
||||
NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value);
|
||||
|
||||
/*
|
||||
|
@ -714,6 +711,8 @@ NPError NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable, void *value);
|
|||
void NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect);
|
||||
void NP_LOADDS NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion);
|
||||
void NP_LOADDS NPN_ForceRedraw(NPP instance);
|
||||
void NP_LOADDS NPN_PushPopupEnabledState(NPP instance, NPBool enabled);
|
||||
void NP_LOADDS NPN_PopPopupEnabledState(NPP instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
|
||||
/*
|
||||
* npupp.h $Revision: 3.19 $
|
||||
* npupp.h $Revision: 3.20 $
|
||||
* function call mecahnics needed by platform specific glue code.
|
||||
*/
|
||||
|
||||
|
@ -1585,6 +1585,58 @@ typedef void (* NP_LOADDS NPN_SetExceptionUPP)(NPObject *obj, const NPUTF8 *mess
|
|||
|
||||
#endif
|
||||
|
||||
/* NPN_PushPopupsEnabledStateUPP */
|
||||
|
||||
#if _NPUPP_USE_UPP_
|
||||
|
||||
typedef UniversalProcPtr NPN_PushPopupsEnabledStateUPP;
|
||||
enum {
|
||||
uppNPN_PushPopupsEnabledStateProcInfo = kThinkCStackBased
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
|
||||
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPBool)))
|
||||
| RESULT_SIZE(SIZE_CODE(0))
|
||||
};
|
||||
|
||||
#define NewNPN_PushPopupsEnabledStateProc(FUNC) \
|
||||
(NPN_PushPopupsEnabledStateUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PushPopupsEnabledStateProcInfo, GetCurrentArchitecture())
|
||||
#define CallNPN_PushPopupsEnabledStateProc(FUNC, ARG1, ARG2) \
|
||||
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PushPopupsEnabledStateProcInfo, (ARG1), (ARG2))
|
||||
|
||||
#else
|
||||
|
||||
typedef bool (* NP_LOADDS NPN_PushPopupsEnabledStateUPP)(NPP npp, NPBool enabled);
|
||||
#define NewNPN_PushPopupsEnabledStateProc(FUNC) \
|
||||
((NPN_PushPopupsEnabledStateUPP) (FUNC))
|
||||
#define CallNPN_PushPopupsEnabledStateProc(FUNC, ARG1, ARG2) \
|
||||
(*(FUNC))((ARG1), (ARG2))
|
||||
|
||||
#endif
|
||||
|
||||
/* NPN_PopPopupsEnabledState */
|
||||
|
||||
#if _NPUPP_USE_UPP_
|
||||
|
||||
typedef UniversalProcPtr NPN_PopPopupsEnabledStateUPP;
|
||||
enum {
|
||||
uppNPN_PopPopupsEnabledStateProcInfo = kThinkCStackBased
|
||||
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
|
||||
| RESULT_SIZE(SIZE_CODE(0))
|
||||
};
|
||||
|
||||
#define NewNPN_PopPopupsEnabledStateProc(FUNC) \
|
||||
(NPN_PopPopupsEnabledStateUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PopPopupsEnabledStateProcInfo, GetCurrentArchitecture())
|
||||
#define CallNPN_PopPopupsEnabledStateProc(FUNC, ARG1) \
|
||||
(jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PopPopupsEnabledStateProcInfo, (ARG1))
|
||||
|
||||
#else
|
||||
|
||||
typedef bool (* NP_LOADDS NPN_PopPopupsEnabledStateUPP)(NPP npp);
|
||||
#define NewNPN_PopPopupsEnabledStateProc(FUNC) \
|
||||
((NPN_PopPopupsEnabledStateUPP) (FUNC))
|
||||
#define CallNPN_PopPopupsEnabledStateProc(FUNC, ARG1) \
|
||||
(*(FUNC))((ARG1))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -1660,6 +1712,8 @@ typedef struct _NPNetscapeFuncs {
|
|||
NPN_HasMethodUPP hasmethod;
|
||||
NPN_ReleaseVariantValueUPP releasevariantvalue;
|
||||
NPN_SetExceptionUPP setexception;
|
||||
NPN_PushPopupsEnabledStateUPP pushpopupsenabledstate;
|
||||
NPN_PopPopupsEnabledStateUPP poppopupsenabledstate;
|
||||
} NPNetscapeFuncs;
|
||||
|
||||
#ifdef XP_MAC
|
||||
|
|
|
@ -54,6 +54,11 @@ public:
|
|||
virtual JSObject *GetJSObject(JSContext *cx) = 0;
|
||||
|
||||
virtual nsresult GetFormValue(nsAString& aValue) = 0;
|
||||
|
||||
virtual void PushPopupsEnabledState(PRBool aEnabled) = 0;
|
||||
virtual void PopPopupsEnabledState() = 0;
|
||||
|
||||
virtual PRUint16 GetPluginAPIVersion() = 0;
|
||||
};
|
||||
|
||||
#endif /* nsIPluginInstanceInternal_h___ */
|
||||
|
|
|
@ -365,6 +365,8 @@ enum nsPluginReason {
|
|||
(nsMajorVersion(suppliedV) == nsMajorVersion(requiredV) \
|
||||
&& nsMinorVersion(suppliedV) >= nsMinorVersion(requiredV))
|
||||
|
||||
#define NP_POPUP_API_VERSION 16
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Classes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -169,6 +169,12 @@ PR_BEGIN_EXTERN_C
|
|||
static void NP_EXPORT
|
||||
_forceredraw(NPP npp);
|
||||
|
||||
static void NP_EXPORT
|
||||
_pushpopupsenabledstate(NPP npp, NPBool enabled);
|
||||
|
||||
static void NP_EXPORT
|
||||
_poppopupsenabledstate(NPP npp);
|
||||
|
||||
static const char* NP_EXPORT
|
||||
_useragent(NPP npp);
|
||||
|
||||
|
@ -375,6 +381,12 @@ ns4xPlugin::CheckClassInitialized(void)
|
|||
CALLBACKS.setexception =
|
||||
NewNPN_SetExceptionProc(FP2TV(_setexception));
|
||||
|
||||
CALLBACKS.pushpopupsenabledstate =
|
||||
NewNPN_PushPopupsEnabledStateProc(FP2TV(_pushpopupsenabledstate));
|
||||
|
||||
CALLBACKS.poppopupsenabledstate =
|
||||
NewNPN_PopPopupsEnabledStateProc(FP2TV(_poppopupsenabledstate));
|
||||
|
||||
initialized = TRUE;
|
||||
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,("NPN callbacks initialized\n"));
|
||||
|
@ -1858,27 +1870,16 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
|||
}
|
||||
|
||||
case NPNVDOMWindow: {
|
||||
ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata;
|
||||
ns4xPluginInstance *inst = (ns4xPluginInstance *)npp->ndata;
|
||||
NS_ENSURE_TRUE(inst, NPERR_GENERIC_ERROR);
|
||||
|
||||
nsCOMPtr<nsIPluginInstancePeer> pip;
|
||||
inst->GetPeer(getter_AddRefs(pip));
|
||||
nsCOMPtr<nsPIPluginInstancePeer> pp (do_QueryInterface(pip));
|
||||
if (pp) {
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
pp->GetOwner(getter_AddRefs(owner));
|
||||
if (owner) {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
owner->GetDocument(getter_AddRefs(doc));
|
||||
if (doc) {
|
||||
nsCOMPtr<nsIDOMWindow> domWindow =
|
||||
do_QueryInterface(doc->GetScriptGlobalObject());
|
||||
if (domWindow) {
|
||||
NS_ADDREF(*(nsIDOMWindow**)result = domWindow.get());
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
nsIDOMWindow *domWindow = inst->GetDOMWindow().get();
|
||||
|
||||
if (domWindow) {
|
||||
// Pass over ownership of domWindow to the caller.
|
||||
(*(nsIDOMWindow**)result) = domWindow;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
@ -2076,5 +2077,24 @@ _getJavaPeer(NPP npp)
|
|||
|
||||
#endif /* OJI */
|
||||
|
||||
void NP_EXPORT
|
||||
_pushpopupsenabledstate(NPP npp, NPBool enabled)
|
||||
{
|
||||
ns4xPluginInstance *inst = (ns4xPluginInstance *)npp->ndata;
|
||||
if (!inst)
|
||||
return;
|
||||
|
||||
inst->PushPopupsEnabledState(enabled);
|
||||
}
|
||||
|
||||
void NP_EXPORT
|
||||
_poppopupsenabledstate(NPP npp)
|
||||
{
|
||||
ns4xPluginInstance *inst = (ns4xPluginInstance *)npp->ndata;
|
||||
if (!inst)
|
||||
return;
|
||||
|
||||
inst->PopPopupsEnabledState();
|
||||
}
|
||||
|
||||
NPP NPPStack::sCurrentNPP = nsnull;
|
||||
|
|
|
@ -49,6 +49,12 @@
|
|||
#include "nsPluginSafety.h"
|
||||
#include "nsPluginLogging.h"
|
||||
|
||||
#include "nsPIPluginInstancePeer.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
|
||||
#include "nsJSNPRuntime.h"
|
||||
|
||||
#ifdef XP_OS2
|
||||
|
@ -877,6 +883,16 @@ NS_IMETHODIMP ns4xPluginInstance::Stop(void)
|
|||
|
||||
NPError error;
|
||||
|
||||
// Make sure the plugin didn't leave popups enabled.
|
||||
if (mPopupStates.Count() > 0) {
|
||||
nsCOMPtr<nsIDOMWindow> window = GetDOMWindow();
|
||||
nsCOMPtr<nsPIDOMWindow> piwindow = do_QueryInterface(window);
|
||||
|
||||
if (piwindow) {
|
||||
piwindow->PopPopupControlState(openAbused);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK) || defined (MOZ_WIDGET_GTK2)
|
||||
if (mXtBin) {
|
||||
gtk_widget_destroy(mXtBin);
|
||||
|
@ -927,6 +943,39 @@ NS_IMETHODIMP ns4xPluginInstance::Stop(void)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMWindow>
|
||||
ns4xPluginInstance::GetDOMWindow()
|
||||
{
|
||||
nsCOMPtr<nsPIPluginInstancePeer> pp (do_QueryInterface(mPeer));
|
||||
if (!pp) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
pp->GetOwner(getter_AddRefs(owner));
|
||||
|
||||
if (!owner) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
owner->GetDocument(getter_AddRefs(doc));
|
||||
|
||||
if (!doc) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject();
|
||||
|
||||
if (!sgo) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIDOMWindow *window;
|
||||
CallQueryInterface(sgo, &window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult ns4xPluginInstance::InitializePlugin(nsIPluginInstancePeer* peer)
|
||||
|
@ -1564,3 +1613,54 @@ ns4xPluginInstance::GetFormValue(nsAString& aValue)
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ns4xPluginInstance::PushPopupsEnabledState(PRBool aEnabled)
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindow> window = GetDOMWindow();
|
||||
nsCOMPtr<nsPIDOMWindow> piwindow = do_QueryInterface(window);
|
||||
|
||||
if (!piwindow)
|
||||
return;
|
||||
|
||||
PopupControlState oldState =
|
||||
piwindow->PushPopupControlState(aEnabled ? openAllowed : openAbused,
|
||||
PR_TRUE);
|
||||
|
||||
if (!mPopupStates.AppendElement(NS_INT32_TO_PTR(oldState))) {
|
||||
// Appending to our state stack failed, push what we just popped.
|
||||
|
||||
piwindow->PopPopupControlState(oldState);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ns4xPluginInstance::PopPopupsEnabledState()
|
||||
{
|
||||
PRInt32 last = mPopupStates.Count() - 1;
|
||||
|
||||
if (last < 0) {
|
||||
// Nothing to pop.
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window = GetDOMWindow();
|
||||
nsCOMPtr<nsPIDOMWindow> piwindow = do_QueryInterface(window);
|
||||
|
||||
if (!piwindow)
|
||||
return;
|
||||
|
||||
PopupControlState oldState =
|
||||
(PopupControlState)NS_PTR_TO_INT32(mPopupStates[last]);
|
||||
|
||||
piwindow->PopPopupControlState(oldState);
|
||||
|
||||
mPopupStates.RemoveElementAt(last);
|
||||
}
|
||||
|
||||
PRUint16
|
||||
ns4xPluginInstance::GetPluginAPIVersion()
|
||||
{
|
||||
return fCallbacks->version;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#endif /* HPUX11 */
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIPlugin.h"
|
||||
#include "nsIPluginInstance.h"
|
||||
#include "nsIPluginInstancePeer.h"
|
||||
|
@ -71,6 +72,7 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ns4xPluginStreamListener;
|
||||
class nsIDOMWindow;
|
||||
|
||||
struct nsInstanceStream
|
||||
{
|
||||
|
@ -132,6 +134,11 @@ public:
|
|||
|
||||
virtual nsresult GetFormValue(nsAString& aValue);
|
||||
|
||||
virtual void PushPopupsEnabledState(PRBool aEnabled);
|
||||
virtual void PopPopupsEnabledState();
|
||||
|
||||
virtual PRUint16 GetPluginAPIVersion();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// ns4xPluginInstance-specific methods
|
||||
|
||||
|
@ -174,7 +181,9 @@ public:
|
|||
{
|
||||
return mPeer;
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<nsIDOMWindow> GetDOMWindow();
|
||||
|
||||
protected:
|
||||
|
||||
nsresult InitializePlugin(nsIPluginInstancePeer* peer);
|
||||
|
@ -223,6 +232,8 @@ protected:
|
|||
public:
|
||||
PRLibrary* fLibrary;
|
||||
nsInstanceStream *mStreams;
|
||||
|
||||
nsVoidArray mPopupStates;
|
||||
};
|
||||
|
||||
#endif // ns4xPluginInstance_h__
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "nsIEventQueueService.h"
|
||||
|
||||
#include "nsIPluginInstancePeer.h"
|
||||
#include "nsIPluginInstanceInternal.h"
|
||||
#include "nsPluginSafety.h"
|
||||
#include "nsPluginNativeWindow.h"
|
||||
|
||||
|
@ -134,7 +135,7 @@ private:
|
|||
public:
|
||||
// locals
|
||||
WNDPROC GetWindowProc();
|
||||
nsresult GetEventService(nsCOMPtr<nsIEventQueueService> &aEventService);
|
||||
nsIEventQueueService *GetEventService();
|
||||
PluginWindowEvent * GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam);
|
||||
|
||||
private:
|
||||
|
@ -158,10 +159,11 @@ static PRBool ProcessFlashMessageDelayed(nsPluginNativeWindowWin * aWin,
|
|||
return PR_FALSE; // no need to delay
|
||||
|
||||
// do stuff
|
||||
nsCOMPtr<nsIEventQueueService> eventService;
|
||||
if (NS_SUCCEEDED(aWin->GetEventService(eventService))) {
|
||||
nsIEventQueueService *eventService = aWin->GetEventService();
|
||||
if (eventService) {
|
||||
nsCOMPtr<nsIEventQueue> eventQueue;
|
||||
eventService->GetThreadEventQueue(PR_GetCurrentThread(), getter_AddRefs(eventQueue));
|
||||
eventService->GetThreadEventQueue(PR_GetCurrentThread(),
|
||||
getter_AddRefs(eventQueue));
|
||||
if (eventQueue) {
|
||||
PluginWindowEvent *pwe = aWin->GetPluginWindowEvent(hWnd, msg, wParam, lParam);
|
||||
if (pwe) {
|
||||
|
@ -173,6 +175,28 @@ static PRBool ProcessFlashMessageDelayed(nsPluginNativeWindowWin * aWin,
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void*)
|
||||
DelayedPopupsEnabledEvent_Handle(PLEvent *event)
|
||||
{
|
||||
nsIPluginInstanceInternal *instInternal =
|
||||
(nsIPluginInstanceInternal *)event->owner;
|
||||
|
||||
instInternal->PushPopupsEnabledState();
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
DelayedPopupsEnabledEvent_Destroy(PLEvent *event)
|
||||
{
|
||||
nsIPluginInstanceInternal *instInternal =
|
||||
(nsIPluginInstanceInternal *)event->owner;
|
||||
|
||||
NS_RELEASE(instInternal);
|
||||
|
||||
delete event;
|
||||
}
|
||||
|
||||
/**
|
||||
* New plugin window procedure
|
||||
*/
|
||||
|
@ -220,7 +244,7 @@ static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
PRBool enablePopups = PR_FALSE;
|
||||
|
||||
// Activate/deactivate mouse capture on the plugin widget
|
||||
// here, before we pass the Windows event to the plugin
|
||||
|
@ -237,8 +261,11 @@ static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||
widget->CaptureMouse(PR_TRUE);
|
||||
break;
|
||||
}
|
||||
case WM_MBUTTONUP:
|
||||
case WM_LBUTTONUP:
|
||||
enablePopups = PR_TRUE;
|
||||
|
||||
// fall through
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP: {
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
win->GetPluginWidget(getter_AddRefs(widget));
|
||||
|
@ -246,8 +273,18 @@ static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||
widget->CaptureMouse(PR_FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case WM_KEYDOWN:
|
||||
// Ignore repeating keydown messages...
|
||||
if ((lParam & 0x40000000) != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// fall through
|
||||
case WM_KEYUP:
|
||||
enablePopups = PR_TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Macromedia Flash plugin may flood the message queue with some special messages
|
||||
// (WM_USER+1) causing 100% CPU consumption and GUI freeze, see mozilla bug 132759;
|
||||
|
@ -259,9 +296,21 @@ static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||
|
||||
LRESULT res = TRUE;
|
||||
|
||||
nsCOMPtr<nsIPluginInstanceInternal> instInternal;
|
||||
nsCOMPtr<nsIPluginInstance> inst;
|
||||
win->GetPluginInstance(inst);
|
||||
|
||||
if (enablePopups) {
|
||||
nsCOMPtr<nsIPluginInstanceInternal> tmp = do_QueryInterface(inst);
|
||||
|
||||
if (tmp && !nsVersionOK(tmp->GetPluginAPIVersion(),
|
||||
NP_POPUP_API_VERSION)) {
|
||||
tmp.swap(instInternal);
|
||||
|
||||
instInternal->PushPopupsEnabledState();
|
||||
}
|
||||
}
|
||||
|
||||
sInMessageDispatch = PR_TRUE;
|
||||
|
||||
NS_TRY_SAFE_CALL_RETURN(res,
|
||||
|
@ -270,6 +319,44 @@ static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||
|
||||
sInMessageDispatch = PR_FALSE;
|
||||
|
||||
if (instInternal) {
|
||||
// Popups are enabled (were enabled before the call to
|
||||
// CallWindowProc()). Some plugins (at least the flash player)
|
||||
// post messages from their key handlers etc that delay the actual
|
||||
// processing, so we need to delay the disabling of popups so that
|
||||
// popups remain enabled when the flash player ends up processing
|
||||
// the actual key handlers. We do this by posting an event that
|
||||
// does the disabling, this way our disabling will happen after
|
||||
// the handlers in the plugin are done.
|
||||
|
||||
// Note that it's not fatal if any of this fails (which won't
|
||||
// happen unless we're out of memory anyways) since the plugin
|
||||
// code will pop any popup state pushed by this plugin on
|
||||
// destruction.
|
||||
|
||||
nsIEventQueueService *eventService = win->GetEventService();
|
||||
if (eventService) {
|
||||
nsCOMPtr<nsIEventQueue> eventQueue;
|
||||
eventService->GetThreadEventQueue(PR_GetCurrentThread(),
|
||||
getter_AddRefs(eventQueue));
|
||||
if (eventQueue) {
|
||||
PLEvent *event = new PLEvent;
|
||||
|
||||
if (event) {
|
||||
nsIPluginInstanceInternal *eventInst = instInternal;
|
||||
|
||||
// Make the event own the plugin instance.
|
||||
NS_ADDREF(eventInst);
|
||||
|
||||
PL_InitEvent(event, eventInst, DelayedPopupsEnabledEvent_Handle,
|
||||
DelayedPopupsEnabledEvent_Destroy);
|
||||
|
||||
eventQueue->PostEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -349,15 +436,13 @@ PluginWindowEvent_Destroy(PLEvent* self)
|
|||
event->Clear();
|
||||
}
|
||||
|
||||
nsresult nsPluginNativeWindowWin::GetEventService(nsCOMPtr<nsIEventQueueService> &aEventService)
|
||||
nsIEventQueueService *nsPluginNativeWindowWin::GetEventService()
|
||||
{
|
||||
if (!mEventService) {
|
||||
mEventService = do_GetService(kEventQueueServiceCID);
|
||||
if (!mEventService)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aEventService = mEventService;
|
||||
return NS_OK;
|
||||
|
||||
return mEventService;
|
||||
}
|
||||
|
||||
PluginWindowEvent*
|
||||
|
|
Загрузка…
Ссылка в новой задаче