зеркало из https://github.com/mozilla/pjs.git
Add support for NPCocoaEventWindowFocusChanged. b=555290 r=roc
This commit is contained in:
Родитель
c5e09b6795
Коммит
9fa9cdcdee
|
@ -5964,7 +5964,7 @@ PresShell::HandleEvent(nsIView *aView,
|
|||
// view that has a frame.
|
||||
if (!frame &&
|
||||
(dispatchUsingCoordinates || NS_IS_KEY_EVENT(aEvent) ||
|
||||
NS_IS_IME_RELATED_EVENT(aEvent) ||
|
||||
NS_IS_IME_RELATED_EVENT(aEvent) || NS_IS_NON_RETARGETED_PLUGIN_EVENT(aEvent) ||
|
||||
aEvent->message == NS_PLUGIN_ACTIVATE)) {
|
||||
nsIView* targetView = aView;
|
||||
while (targetView && !targetView->GetClientData()) {
|
||||
|
|
|
@ -413,7 +413,7 @@ public:
|
|||
#ifdef XP_WIN
|
||||
return mPluginWindow->type == NPWindowTypeDrawable &&
|
||||
MatchPluginName("Shockwave Flash");
|
||||
#elif defined(MOZ_X11)
|
||||
#elif defined(MOZ_X11) || defined(XP_MACOSX)
|
||||
return PR_TRUE;
|
||||
#else
|
||||
return PR_FALSE;
|
||||
|
@ -450,6 +450,7 @@ private:
|
|||
nsCARenderer mCARenderer;
|
||||
static nsCOMPtr<nsITimer> *sCATimer;
|
||||
static nsTArray<nsPluginInstanceOwner*> *sCARefreshListeners;
|
||||
PRBool mSentInitialTopLevelWindowEvent;
|
||||
#endif
|
||||
|
||||
// Initially, the event loop nesting level we were created on, it's updated
|
||||
|
@ -1941,7 +1942,8 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
|
|||
return fm->SetFocus(elem, 0);
|
||||
}
|
||||
|
||||
if (mInstanceOwner->SendNativeEvents() && NS_IS_PLUGIN_EVENT(anEvent)) {
|
||||
if (mInstanceOwner->SendNativeEvents() &&
|
||||
(NS_IS_PLUGIN_EVENT(anEvent) || NS_IS_NON_RETARGETED_PLUGIN_EVENT(anEvent))) {
|
||||
*anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);
|
||||
return rv;
|
||||
}
|
||||
|
@ -2473,6 +2475,7 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
|
|||
memset(&mCGPluginPortCopy, 0, sizeof(NP_CGContext));
|
||||
memset(&mQDPluginPortCopy, 0, sizeof(NP_Port));
|
||||
mInCGPaintLevel = 0;
|
||||
mSentInitialTopLevelWindowEvent = PR_FALSE;
|
||||
#endif
|
||||
mContentFocused = PR_FALSE;
|
||||
mWidgetVisible = PR_TRUE;
|
||||
|
@ -5852,6 +5855,17 @@ void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
|
|||
return nsnull;
|
||||
#endif
|
||||
|
||||
// We'll need the top-level Cocoa window for the Cocoa event model.
|
||||
void* cocoaTopLevelWindow = nsnull;
|
||||
if (eventModel == NPEventModelCocoa) {
|
||||
nsIWidget* widget = mObjectFrame->GetWindow();
|
||||
if (!widget)
|
||||
return nsnull;
|
||||
cocoaTopLevelWindow = widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
if (!cocoaTopLevelWindow)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIntPoint pluginOrigin;
|
||||
nsIntRect widgetClip;
|
||||
PRBool widgetVisible;
|
||||
|
@ -5884,13 +5898,7 @@ void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
nsIWidget* widget = mObjectFrame->GetWindow();
|
||||
if (!widget)
|
||||
return nsnull;
|
||||
void* nativeData = widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
if (!nativeData)
|
||||
return nsnull;
|
||||
NS_NPAPI_CocoaWindowFrame(nativeData, windowRect);
|
||||
NS_NPAPI_CocoaWindowFrame(cocoaTopLevelWindow, windowRect);
|
||||
}
|
||||
|
||||
mPluginWindow->x = geckoScreenCoords.x - windowRect.x;
|
||||
|
@ -5938,6 +5946,21 @@ void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
|
|||
mPluginPortChanged = PR_FALSE;
|
||||
}
|
||||
|
||||
// After the first NPP_SetWindow call we need to send an initial
|
||||
// top-level window focus event.
|
||||
if (eventModel == NPEventModelCocoa && !mSentInitialTopLevelWindowEvent) {
|
||||
// Set this before calling ProcessEvent to avoid endless recursion.
|
||||
mSentInitialTopLevelWindowEvent = PR_TRUE;
|
||||
|
||||
nsGUIEvent pluginEvent(PR_TRUE, NS_NON_RETARGETED_PLUGIN_EVENT, nsnull);
|
||||
NPCocoaEvent cocoaEvent;
|
||||
InitializeNPCocoaEvent(&cocoaEvent);
|
||||
cocoaEvent.type = NPCocoaEventWindowFocusChanged;
|
||||
cocoaEvent.data.focus.hasFocus = NS_NPAPI_CocoaWindowIsMain(cocoaTopLevelWindow);
|
||||
pluginEvent.pluginEvent = &cocoaEvent;
|
||||
ProcessEvent(pluginEvent);
|
||||
}
|
||||
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
if (drawingModel == NPDrawingModelQuickDraw)
|
||||
return ::GetWindowFromPort(static_cast<NP_Port*>(pluginPort)->port);
|
||||
|
|
|
@ -57,6 +57,9 @@ void NS_NPAPI_CarbonWindowFrame(WindowRef aWindow, nsRect& outRect);
|
|||
// Get the rect for an entire top-level Cocoa window in screen coords.
|
||||
void NS_NPAPI_CocoaWindowFrame(void* aWindow, nsRect& outRect);
|
||||
|
||||
// Returns whether or not a Cocoa NSWindow has main status.
|
||||
PRBool NS_NPAPI_CocoaWindowIsMain(void* aWindow);
|
||||
|
||||
// Puts up a Cocoa context menu (NSMenu) for a particular NPCocoaEvent.
|
||||
NPError NS_NPAPI_ShowCocoaContextMenu(void* menu, nsIWidget* widget, NPCocoaEvent* event);
|
||||
|
||||
|
|
|
@ -83,6 +83,20 @@ void NS_NPAPI_CocoaWindowFrame(void* aWindow, nsRect& outRect)
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
PRBool NS_NPAPI_CocoaWindowIsMain(void* aWindow)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if (!aWindow)
|
||||
return PR_TRUE;
|
||||
|
||||
NSWindow* window = (NSWindow*)aWindow;
|
||||
|
||||
return (PRBool)[window isMainWindow];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_TRUE);
|
||||
}
|
||||
|
||||
NPError NS_NPAPI_ShowCocoaContextMenu(void* menu, nsIWidget* widget, NPCocoaEvent* event)
|
||||
{
|
||||
if (!menu || !widget || !event)
|
||||
|
|
|
@ -112,6 +112,11 @@ ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
|||
_MOCHICHROME_FILES += \
|
||||
test_convertpoint.xul \
|
||||
$(NULL)
|
||||
|
||||
_MOCHITEST_FILES += \
|
||||
test_cocoa_window_focus.html \
|
||||
cocoa_window_focus.html \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>NPCocoaEventWindowFocusChanged Tests</title>
|
||||
</head>
|
||||
<body onload="runTests()">
|
||||
<embed id="plugin1" type="application/x-test" width="400" height="400"></embed>
|
||||
<embed id="plugin2" type="application/x-test" width="400" height="400"></embed>
|
||||
<script type="application/javascript">
|
||||
function is(aLeft, aRight, aMessage) {
|
||||
window.opener.SimpleTest.is(aLeft, aRight, aMessage);
|
||||
}
|
||||
|
||||
function ok(aValue, aMessage) {
|
||||
window.opener.SimpleTest.ok(aValue, aMessage);
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
var plugin1 = document.getElementById("plugin1");
|
||||
var plugin2 = document.getElementById("plugin2");
|
||||
|
||||
// Don't run any tests if we're not testing the Cocoa event model.
|
||||
if (plugin1.getEventModel() != 1) {
|
||||
window.opener.testsFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
// The first plugin will have in-page focus for these tests.
|
||||
plugin1.focus();
|
||||
|
||||
// The expected event count which applies to all instances.
|
||||
// Initialize to 1 to account for the initial state event.
|
||||
var expectedEventCount = 1;
|
||||
|
||||
// First make sure the plugins got an initial window focus event.
|
||||
// Since this window was just opened it should be in the front. If
|
||||
// the plugin has not been sent an initial window state then it will
|
||||
// be in an unknown state and it will throw an exception.
|
||||
try {
|
||||
is(plugin1.getTopLevelWindowActivationState(), true, "Activation state should be: activated");
|
||||
is(plugin1.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount);
|
||||
|
||||
is(plugin2.getTopLevelWindowActivationState(), true, "Activation state should be: activated");
|
||||
is(plugin2.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount);
|
||||
} catch (e) {
|
||||
ok(false, "Plugin does not know its initial top-level window activation state!");
|
||||
}
|
||||
|
||||
// Send our window to the back and make sure plugins were properly notified.
|
||||
window.blur();
|
||||
expectedEventCount++;
|
||||
|
||||
is(plugin1.getTopLevelWindowActivationState(), false, "Activation state should be: deactivated");
|
||||
is(plugin1.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount);
|
||||
|
||||
is(plugin2.getTopLevelWindowActivationState(), false, "Activation state should be: deactivated");
|
||||
is(plugin2.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount);
|
||||
|
||||
// Bring our window back to the front and make sure plugins were properly notified.
|
||||
window.focus();
|
||||
expectedEventCount++;
|
||||
|
||||
is(plugin1.getTopLevelWindowActivationState(), true, "Activation state should be: activated");
|
||||
is(plugin1.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount);
|
||||
|
||||
is(plugin2.getTopLevelWindowActivationState(), true, "Activation state should be: activated");
|
||||
is(plugin2.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount);
|
||||
|
||||
window.opener.testsFinished();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>NPCocoaEventWindowFocusChanged Tests</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="runTests()">
|
||||
<script class="testbody" type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var gOtherWindow;
|
||||
|
||||
function runTests() {
|
||||
// We have to have two top-level windows in play in order to run these tests.
|
||||
gOtherWindow = window.open("cocoa_window_focus.html", "", "width=200,height=200");
|
||||
}
|
||||
|
||||
function testsFinished() {
|
||||
// Tests have finished running, close the new window and end tests.
|
||||
gOtherWindow.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -4,6 +4,12 @@
|
|||
|
||||
The test plugin registers itself for the MIME type "application/x-test".
|
||||
|
||||
== Event Model ==
|
||||
|
||||
* getEventModel()
|
||||
Returns the NPAPI event model in use. On platforms without event models,
|
||||
simply returns 0;
|
||||
|
||||
== Rendering ==
|
||||
|
||||
By default, the plugin fills its rectangle with gray, with a black border, and
|
||||
|
@ -32,6 +38,17 @@ returns true if it succeeds and false if it doesn't. It should never succeed.
|
|||
The plugin uses NPN_ConvertPoint to convert sourceX and sourceY from the source
|
||||
to dest space and returns the X or Y result based on the call.
|
||||
|
||||
== NPCocoaEventWindowFocusChanged ==
|
||||
|
||||
* getTopLevelWindowActivationState()
|
||||
Returns the activation state for the top-level window as set by the last
|
||||
NPCocoaEventWindowFocusChanged event. Returns true for active, false for
|
||||
inactive, and throws an exception if the state is unknown (uninitialized).
|
||||
|
||||
* getTopLevelWindowActivationEventCount()
|
||||
Returns the number of NPCocoaEventWindowFocusChanged events received by
|
||||
the instance.
|
||||
|
||||
== NPRuntime testing ==
|
||||
|
||||
The test plugin object supports the following scriptable methods:
|
||||
|
|
|
@ -161,6 +161,9 @@ static bool callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCo
|
|||
static bool reinitWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool propertyAndMethod(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool getTopLevelWindowActivationState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool getTopLevelWindowActivationEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool getEventModel(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
|
||||
static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
||||
"npnEvaluateTest",
|
||||
|
@ -204,7 +207,10 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
|||
"callOnDestroy",
|
||||
"reinitWidget",
|
||||
"crashInNestedLoop",
|
||||
"propertyAndMethod"
|
||||
"propertyAndMethod",
|
||||
"getTopLevelWindowActivationState",
|
||||
"getTopLevelWindowActivationEventCount",
|
||||
"getEventModel"
|
||||
};
|
||||
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
|
||||
static const ScriptableFunction sPluginMethodFunctions[] = {
|
||||
|
@ -249,7 +255,10 @@ static const ScriptableFunction sPluginMethodFunctions[] = {
|
|||
callOnDestroy,
|
||||
reinitWidget,
|
||||
crashPluginInNestedLoop,
|
||||
propertyAndMethod
|
||||
propertyAndMethod,
|
||||
getTopLevelWindowActivationState,
|
||||
getTopLevelWindowActivationEventCount,
|
||||
getEventModel
|
||||
};
|
||||
|
||||
STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) ==
|
||||
|
@ -669,6 +678,9 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char*
|
|||
instanceData->writeReadyCount = 0;
|
||||
memset(&instanceData->window, 0, sizeof(instanceData->window));
|
||||
instanceData->crashOnDestroy = false;
|
||||
instanceData->topLevelWindowActivationState = ACTIVATION_STATE_UNKNOWN;
|
||||
instanceData->topLevelWindowActivationEventCount = 0;
|
||||
instanceData->eventModel = 0;
|
||||
instance->pdata = instanceData;
|
||||
|
||||
TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass);
|
||||
|
@ -2791,3 +2803,61 @@ propertyAndMethod(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
|||
INT32_TO_NPVARIANT(5, *result);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns top-level window activation state as indicated by Cocoa NPAPI's
|
||||
// NPCocoaEventWindowFocusChanged events - 'true' if active, 'false' if not.
|
||||
// Throws an exception if no events have been received and thus this state
|
||||
// is unknown.
|
||||
bool
|
||||
getTopLevelWindowActivationState(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||
NPVariant* result)
|
||||
{
|
||||
if (argCount != 0)
|
||||
return false;
|
||||
|
||||
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(npp->pdata);
|
||||
|
||||
// Throw an exception for unknown state.
|
||||
if (id->topLevelWindowActivationState == ACTIVATION_STATE_UNKNOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (id->topLevelWindowActivationState == ACTIVATION_STATE_ACTIVATED) {
|
||||
BOOLEAN_TO_NPVARIANT(true, *result);
|
||||
} else if (id->topLevelWindowActivationState == ACTIVATION_STATE_DEACTIVATED) {
|
||||
BOOLEAN_TO_NPVARIANT(false, *result);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
getTopLevelWindowActivationEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||
NPVariant* result)
|
||||
{
|
||||
if (argCount != 0)
|
||||
return false;
|
||||
|
||||
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(npp->pdata);
|
||||
|
||||
INT32_TO_NPVARIANT(id->topLevelWindowActivationEventCount, *result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
getEventModel(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||
NPVariant* result)
|
||||
{
|
||||
if (argCount != 0)
|
||||
return false;
|
||||
|
||||
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(npp->pdata);
|
||||
|
||||
INT32_TO_NPVARIANT(id->eventModel, *result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,12 @@ typedef enum {
|
|||
FUNCTION_NPP_WRITE_RPC
|
||||
} TestFunction;
|
||||
|
||||
typedef enum {
|
||||
ACTIVATION_STATE_UNKNOWN,
|
||||
ACTIVATION_STATE_ACTIVATED,
|
||||
ACTIVATION_STATE_DEACTIVATED
|
||||
} ActivationState;
|
||||
|
||||
typedef struct FunctionTable {
|
||||
TestFunction funcId;
|
||||
const char* funcName;
|
||||
|
@ -123,6 +129,9 @@ typedef struct InstanceData {
|
|||
void* streamBuf;
|
||||
void* fileBuf;
|
||||
bool crashOnDestroy;
|
||||
ActivationState topLevelWindowActivationState;
|
||||
int32_t topLevelWindowActivationEventCount;
|
||||
int32_t eventModel;
|
||||
} InstanceData;
|
||||
|
||||
void notifyDidPaint(InstanceData* instanceData);
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
NPEventModel sCurrentEventModel = NPEventModelCocoa;
|
||||
|
||||
bool
|
||||
pluginSupportsWindowMode()
|
||||
{
|
||||
|
@ -72,21 +70,20 @@ pluginInstanceInit(InstanceData* instanceData)
|
|||
NPBool supportsCarbonEvents = false;
|
||||
if ((NPN_GetValue(npp, NPNVsupportsCarbonBool, &supportsCarbonEvents) == NPERR_NO_ERROR) &&
|
||||
supportsCarbonEvents) {
|
||||
sCurrentEventModel = NPEventModelCarbon;
|
||||
instanceData->eventModel = NPEventModelCarbon;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sCurrentEventModel == NPEventModelCocoa) {
|
||||
NPBool supportsCocoaEvents = false;
|
||||
if ((NPN_GetValue(npp, NPNVsupportsCocoaBool, &supportsCocoaEvents) == NPERR_NO_ERROR) &&
|
||||
supportsCocoaEvents) {
|
||||
NPN_SetValue(npp, NPPVpluginEventModel, (void*)NPEventModelCocoa);
|
||||
sCurrentEventModel = NPEventModelCocoa;
|
||||
} else {
|
||||
printf("Cocoa event model not supported, can't create a plugin instance.\n");
|
||||
return NPERR_INCOMPATIBLE_VERSION_ERROR;
|
||||
}
|
||||
NPBool supportsCocoaEvents = false;
|
||||
if ((NPN_GetValue(npp, NPNVsupportsCocoaBool, &supportsCocoaEvents) == NPERR_NO_ERROR) &&
|
||||
supportsCocoaEvents) {
|
||||
NPN_SetValue(npp, NPPVpluginEventModel, (void*)NPEventModelCocoa);
|
||||
instanceData->eventModel = NPEventModelCocoa;
|
||||
} else {
|
||||
printf("Cocoa event model not supported, can't create a plugin instance.\n");
|
||||
return NPERR_INCOMPATIBLE_VERSION_ERROR;
|
||||
}
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
|
@ -154,7 +151,7 @@ pluginDraw(InstanceData* instanceData, NPCocoaEvent* event)
|
|||
|
||||
CGContextRef cgContext = NULL;
|
||||
#ifndef NP_NO_CARBON
|
||||
if (sCurrentEventModel == NPEventModelCocoa) {
|
||||
if (instanceData->eventModel == NPEventModelCocoa) {
|
||||
cgContext = event->data.draw.context;
|
||||
} else {
|
||||
cgContext = ((NP_CGContext*)(window.window))->context;
|
||||
|
@ -249,7 +246,7 @@ int16_t
|
|||
pluginHandleEvent(InstanceData* instanceData, void* event)
|
||||
{
|
||||
#ifndef NP_NO_CARBON
|
||||
if (sCurrentEventModel == NPEventModelCarbon) {
|
||||
if (instanceData->eventModel == NPEventModelCarbon) {
|
||||
EventRecord* carbonEvent = (EventRecord*)event;
|
||||
if (!carbonEvent)
|
||||
return 1;
|
||||
|
@ -292,6 +289,11 @@ pluginHandleEvent(InstanceData* instanceData, void* event)
|
|||
instanceData->lastMouseX = (int32_t)cocoaEvent->data.mouse.pluginX;
|
||||
instanceData->lastMouseY = (int32_t)cocoaEvent->data.mouse.pluginY;
|
||||
return 1;
|
||||
case NPCocoaEventWindowFocusChanged:
|
||||
instanceData->topLevelWindowActivationState = cocoaEvent->data.focus.hasFocus ?
|
||||
ACTIVATION_STATE_ACTIVATED : ACTIVATION_STATE_DEACTIVATED;
|
||||
instanceData->topLevelWindowActivationEventCount = instanceData->topLevelWindowActivationEventCount + 1;
|
||||
return 1;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -958,7 +958,8 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
|
|||
aEvent->message != NS_MOUSE_ENTER) ||
|
||||
NS_IS_KEY_EVENT(aEvent) ||
|
||||
NS_IS_IME_EVENT(aEvent) ||
|
||||
NS_IS_PLUGIN_EVENT(aEvent)) {
|
||||
NS_IS_PLUGIN_EVENT(aEvent) ||
|
||||
NS_IS_NON_RETARGETED_PLUGIN_EVENT(aEvent)) {
|
||||
gLastUserEventTime = PR_IntervalToMicroseconds(PR_IntervalNow());
|
||||
}
|
||||
|
||||
|
|
|
@ -424,10 +424,10 @@ class nsHashKey;
|
|||
#define NS_SIMPLE_GESTURE_TAP (NS_SIMPLE_GESTURE_EVENT_START+7)
|
||||
#define NS_SIMPLE_GESTURE_PRESSTAP (NS_SIMPLE_GESTURE_EVENT_START+8)
|
||||
|
||||
// Plug-in event. This is used when a plug-in has focus and when the native
|
||||
// event needs to be passed to the focused plug-in directly.
|
||||
// These are used to send events to plugins.
|
||||
#define NS_PLUGIN_EVENT_START 3600
|
||||
#define NS_PLUGIN_EVENT (NS_PLUGIN_EVENT_START)
|
||||
#define NS_PLUGIN_EVENT (NS_PLUGIN_EVENT_START)
|
||||
#define NS_NON_RETARGETED_PLUGIN_EVENT (NS_PLUGIN_EVENT_START+1)
|
||||
|
||||
// Events to manipulate selection (nsSelectionEvent)
|
||||
#define NS_SELECTION_EVENT_START 3700
|
||||
|
@ -1444,6 +1444,9 @@ enum nsDragDropEventStatus {
|
|||
#define NS_IS_PLUGIN_EVENT(evnt) \
|
||||
(((evnt)->message == NS_PLUGIN_EVENT))
|
||||
|
||||
#define NS_IS_NON_RETARGETED_PLUGIN_EVENT(evnt) \
|
||||
(((evnt)->message == NS_NON_RETARGETED_PLUGIN_EVENT))
|
||||
|
||||
#define NS_IS_TRUSTED_EVENT(event) \
|
||||
(((event)->flags & NS_EVENT_FLAG_TRUSTED) != 0)
|
||||
|
||||
|
@ -1648,7 +1651,8 @@ inline PRBool NS_IsEventUsingCoordinates(nsEvent* aEvent)
|
|||
{
|
||||
return !NS_IS_KEY_EVENT(aEvent) && !NS_IS_IME_RELATED_EVENT(aEvent) &&
|
||||
!NS_IS_CONTEXT_MENU_KEY(aEvent) && !NS_IS_ACTIVATION_EVENT(aEvent) &&
|
||||
!NS_IS_PLUGIN_EVENT(aEvent) && !NS_IS_CONTENT_COMMAND_EVENT(aEvent) &&
|
||||
!NS_IS_PLUGIN_EVENT(aEvent) && !NS_IS_NON_RETARGETED_PLUGIN_EVENT(aEvent) &&
|
||||
!NS_IS_CONTENT_COMMAND_EVENT(aEvent) &&
|
||||
aEvent->eventStructType != NS_ACCESSIBLE_EVENT;
|
||||
}
|
||||
|
||||
|
|
|
@ -2210,6 +2210,14 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
|||
kCorePboardType_urld,
|
||||
kCorePboardType_urln,
|
||||
nil]];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(windowBecameMain:)
|
||||
name:NSWindowDidBecomeMainNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(windowResignedMain:)
|
||||
name:NSWindowDidResignMainNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(systemMetricsChanged)
|
||||
name:NSControlTintDidChangeNotification
|
||||
|
@ -2255,6 +2263,43 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)updatePluginTopLevelWindowStatus:(BOOL)hasMain
|
||||
{
|
||||
nsGUIEvent pluginEvent(PR_TRUE, NS_NON_RETARGETED_PLUGIN_EVENT, mGeckoChild);
|
||||
NPCocoaEvent cocoaEvent;
|
||||
InitNPCocoaEvent(&cocoaEvent);
|
||||
cocoaEvent.type = NPCocoaEventWindowFocusChanged;
|
||||
cocoaEvent.data.focus.hasFocus = hasMain;
|
||||
pluginEvent.pluginEvent = &cocoaEvent;
|
||||
mGeckoChild->DispatchWindowEvent(pluginEvent);
|
||||
}
|
||||
|
||||
- (void)windowBecameMain:(NSNotification*)inNotification
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (mIsPluginView && mPluginEventModel == NPEventModelCocoa) {
|
||||
if ((NSWindow*)[inNotification object] == [self window]) {
|
||||
[self updatePluginTopLevelWindowStatus:YES];
|
||||
}
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)windowResignedMain:(NSNotification*)inNotification
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (mIsPluginView && mPluginEventModel == NPEventModelCocoa) {
|
||||
if ((NSWindow*)[inNotification object] == [self window]) {
|
||||
[self updatePluginTopLevelWindowStatus:NO];
|
||||
}
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)widgetDestroyed
|
||||
{
|
||||
mGeckoChild->IME_OnDestroyView(self);
|
||||
|
|
Загрузка…
Ссылка в новой задаче