mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 21:00:50 +00:00
modal dialogs from C off the UI thread. a bit premature: works on Win and Mac. Issue addressed on gtk, but not there yet.
This commit is contained in:
parent
bbeffd28f0
commit
27430e415c
@ -80,6 +80,16 @@ public:
|
||||
|
||||
NS_IMETHOD Spindown() = 0;
|
||||
|
||||
/**
|
||||
* Push event queue onto current thread and begin processing events from it
|
||||
*/
|
||||
NS_IMETHOD PushThreadEventQueue() = 0;
|
||||
|
||||
/**
|
||||
* Pop event queue from current thread's stack
|
||||
*/
|
||||
NS_IMETHOD PopThreadEventQueue() = 0;
|
||||
|
||||
/**
|
||||
* After event dispatch execute app specific code
|
||||
*/
|
||||
|
@ -17,6 +17,8 @@
|
||||
*/
|
||||
|
||||
#include "nsAppShell.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIAppShell.h"
|
||||
#include "nsWindow.h"
|
||||
@ -57,6 +59,7 @@ static sem_id my_find_sem(const char *name)
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_DEFINE_IID(kIAppShellIID, NS_IAPPSHELL_IID);
|
||||
NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
NS_IMPL_ISUPPORTS(nsAppShell,kIAppShellIID);
|
||||
|
||||
static bool GetAppSig(char *sig)
|
||||
@ -268,6 +271,46 @@ NS_METHOD nsAppShell::Spindown()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PushThreadEventQueue - begin processing events from a new queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on beos.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PushThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PushThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PopThreadEventQueue - stop processing on a previously pushed event queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on beos.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PopThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PopThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent)
|
||||
{
|
||||
printf("nsAppShell::GetNativeEvent - FIXME: not implemented\n");
|
||||
|
@ -41,6 +41,8 @@ class nsAppShell : public nsIAppShell
|
||||
virtual nsresult Run();
|
||||
NS_IMETHOD Spinup();
|
||||
NS_IMETHOD Spindown();
|
||||
NS_IMETHOD PushThreadEventQueue();
|
||||
NS_IMETHOD PopThreadEventQueue();
|
||||
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
|
||||
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
|
||||
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent,
|
||||
|
@ -16,6 +16,7 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "prmon.h"
|
||||
#include "nsAppShell.h"
|
||||
#include "nsIAppShell.h"
|
||||
#include "nsIServiceManager.h"
|
||||
@ -35,6 +36,70 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
static NS_DEFINE_CID(kCmdLineServiceCID, NS_COMMANDLINE_SERVICE_CID);
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
|
||||
// a linked, ordered list of event queues and their tokens
|
||||
class EventQueueToken {
|
||||
public:
|
||||
EventQueueToken(const nsIEventQueue *aQueue, const gint aToken);
|
||||
|
||||
const nsIEventQueue *mQueue;
|
||||
gint mToken;
|
||||
EventQueueToken *next;
|
||||
};
|
||||
EventQueueToken::EventQueueToken(const nsIEventQueue *aQueue, const gint aToken) {
|
||||
mQueue = aQueue;
|
||||
mToken = aToken;
|
||||
next = 0;
|
||||
}
|
||||
class EventQueueTokenQueue {
|
||||
public:
|
||||
EventQueueTokenQueue();
|
||||
virtual ~EventQueueTokenQueue();
|
||||
void PushToken(nsIEventQueue *aQueue, gint aToken);
|
||||
PRBool PopToken(nsIEventQueue *aQueue, gint *aToken);
|
||||
|
||||
private:
|
||||
EventQueueToken *mHead;
|
||||
};
|
||||
EventQueueTokenQueue::EventQueueTokenQueue() {
|
||||
mHead = 0;
|
||||
}
|
||||
EventQueueTokenQueue::~EventQueueTokenQueue() {
|
||||
NS_ASSERTION(!mHead, "event queue token deleted when not empty");
|
||||
// and leak. it's an error, anyway
|
||||
}
|
||||
void EventQueueTokenQueue::PushToken(nsIEventQueue *aQueue, gint aToken) {
|
||||
EventQueueToken *newToken = new EventQueueToken(aQueue, aToken);
|
||||
NS_ASSERTION(newToken, "couldn't allocate token queue element");
|
||||
if (newToken) {
|
||||
newToken->next = mHead;
|
||||
mHead = newToken;
|
||||
}
|
||||
}
|
||||
PRBool EventQueueTokenQueue::PopToken(nsIEventQueue *aQueue, gint *aToken) {
|
||||
EventQueueToken *token, *lastToken;
|
||||
PRBool found = PR_FALSE;
|
||||
NS_ASSERTION(mHead, "attempt to retrieve event queue token from empty queue");
|
||||
if (mHead)
|
||||
NS_ASSERTION(mHead->mQueue == aQueue, "retrieving event queue from past head of queue queue");
|
||||
|
||||
token = mHead;
|
||||
lastToken = 0;
|
||||
while (token && token->mQueue != aQueue) {
|
||||
lastToken = token;
|
||||
token = token->next;
|
||||
}
|
||||
if (token) {
|
||||
if (lastToken)
|
||||
lastToken->next = token->next;
|
||||
else
|
||||
mHead = token->next;
|
||||
found = PR_TRUE;
|
||||
*aToken = token->mToken;
|
||||
delete token;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// nsAppShell constructor
|
||||
@ -44,6 +109,11 @@ nsAppShell::nsAppShell()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mDispatchListener = 0;
|
||||
mLock = PR_NewLock();
|
||||
mEventQueueTokens = new EventQueueTokenQueue();
|
||||
// throw on error would really be civilized here
|
||||
NS_ASSERTION(mLock, "couldn't obtain lock in appshell");
|
||||
NS_ASSERTION(mEventQueueTokens, "couldn't allocate event queue token queue");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -53,7 +123,8 @@ nsAppShell::nsAppShell()
|
||||
//-------------------------------------------------------------------------
|
||||
nsAppShell::~nsAppShell()
|
||||
{
|
||||
|
||||
PR_DestroyLock(mLock);
|
||||
delete mEventQueueTokens;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -185,6 +256,64 @@ NS_METHOD nsAppShell::Spindown()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PushThreadEventQueue
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD
|
||||
nsAppShell::PushThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
gint inputToken;
|
||||
nsIEventQueue *eQueue;
|
||||
|
||||
// push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PR_Lock(mLock);
|
||||
rv = eventQService->PushThreadEventQueue();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
eventQService->GetThreadEventQueue(PR_GetCurrentThread(), &eQueue);
|
||||
inputToken = gdk_input_add(eQueue->GetEventQueueSelectFD(),
|
||||
GDK_INPUT_READ,
|
||||
event_processor_callback,
|
||||
eQueue);
|
||||
mEventQueueTokens->PushToken(eQueue, inputToken);
|
||||
}
|
||||
PR_Unlock(mLock);
|
||||
} else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PopThreadEventQueue
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD
|
||||
nsAppShell::PopThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
nsIEventQueue *eQueue;
|
||||
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
gint queueToken;
|
||||
PR_Lock(mLock);
|
||||
eventQService->GetThreadEventQueue(PR_GetCurrentThread(), &eQueue);
|
||||
eventQService->PopThreadEventQueue();
|
||||
if (mEventQueueTokens->PopToken(eQueue, &queueToken))
|
||||
gdk_input_remove(queueToken);
|
||||
PR_Unlock(mLock);
|
||||
NS_IF_RELEASE(eQueue);
|
||||
} else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// Run
|
||||
@ -238,6 +367,7 @@ done:
|
||||
GDK_INPUT_READ,
|
||||
event_processor_callback,
|
||||
EQueue);
|
||||
|
||||
gtk_main();
|
||||
|
||||
NS_IF_RELEASE(EQueue);
|
||||
|
@ -27,6 +27,8 @@
|
||||
*/
|
||||
|
||||
class nsIEventQueueService;
|
||||
class EventQueueTokenQueue;
|
||||
struct PRLock;
|
||||
|
||||
class nsAppShell : public nsIAppShell
|
||||
{
|
||||
@ -41,6 +43,8 @@ class nsAppShell : public nsIAppShell
|
||||
NS_IMETHOD Run();
|
||||
NS_IMETHOD Spinup();
|
||||
NS_IMETHOD Spindown();
|
||||
NS_IMETHOD PushThreadEventQueue();
|
||||
NS_IMETHOD PopThreadEventQueue();
|
||||
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
|
||||
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
|
||||
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent,
|
||||
@ -50,8 +54,9 @@ class nsAppShell : public nsIAppShell
|
||||
virtual void* GetNativeData(PRUint32 aDataType);
|
||||
|
||||
private:
|
||||
nsDispatchListener *mDispatchListener;
|
||||
|
||||
nsDispatchListener *mDispatchListener;
|
||||
PRLock *mLock;
|
||||
EventQueueTokenQueue *mEventQueueTokens;
|
||||
};
|
||||
|
||||
#endif // nsAppShell_h__
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "nsAppShell.h"
|
||||
#include "nsIAppShell.h"
|
||||
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsMacMessageSink.h"
|
||||
#include "nsMacMessagePump.h"
|
||||
@ -53,6 +55,8 @@ PRBool nsAppShell::mInitializedToolbox = PR_FALSE;
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_DEFINE_IID(kIAppShellIID, NS_IAPPSHELL_IID);
|
||||
NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAppShell,kIAppShellIID);
|
||||
|
||||
NS_IMETHODIMP nsAppShell::SetDispatchListener(nsDispatchListener* aDispatchListener)
|
||||
@ -177,6 +181,42 @@ nsAppShell::~nsAppShell()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PushThreadEventQueue - begin processing events from a new queue
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PushThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PushThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PopThreadEventQueue - stop processing on a previously pushed event queue
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PopThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PopThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// GetNativeData
|
||||
|
@ -63,8 +63,10 @@ class nsAppShell : public nsIAppShell
|
||||
virtual nsresult Run();
|
||||
NS_IMETHOD Spinup();
|
||||
NS_IMETHOD Spindown();
|
||||
NS_IMETHOD PushThreadEventQueue();
|
||||
NS_IMETHOD PopThreadEventQueue();
|
||||
NS_IMETHOD Exit();
|
||||
NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener);
|
||||
NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener);
|
||||
|
||||
virtual void* GetNativeData(PRUint32 aDataType);
|
||||
|
||||
|
@ -215,6 +215,46 @@ NS_METHOD nsAppShell::Spindown()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PushThreadEventQueue - begin processing events from a new queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on motif.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PushThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PushThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PopThreadEventQueue - stop processing on a previously pushed event queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on motif.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PopThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PopThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent)
|
||||
{
|
||||
//XXX:Implement this.
|
||||
|
@ -44,6 +44,8 @@ class nsAppShell : public nsIAppShell
|
||||
NS_IMETHOD Run();
|
||||
NS_IMETHOD Spinup();
|
||||
NS_IMETHOD Spindown();
|
||||
NS_IMETHOD PushThreadEventQueue();
|
||||
NS_IMETHOD PopThreadEventQueue();
|
||||
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
|
||||
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
|
||||
NS_IMETHOD Exit();
|
||||
|
@ -21,6 +21,10 @@
|
||||
|
||||
#include "nsAppShell.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
// Appshell manager. Same threads must get the same appshell object,
|
||||
// or else the message queue will be taken over by the second (nested)
|
||||
@ -203,6 +207,46 @@ nsAppShell::~nsAppShell()
|
||||
WinTerminate( mHab);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PushThreadEventQueue - begin processing events from a new queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on os/2.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PushThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PushThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PopThreadEventQueue - stop processing on a previously pushed event queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on os/2.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PopThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PopThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// These are for modal dialogs and also tres weird.
|
||||
//
|
||||
// XXX must handle WM_QUIT sensibly (close window)
|
||||
|
@ -41,6 +41,8 @@ class nsAppShell : public nsIAppShell
|
||||
NS_IMETHOD Spinup() { return NS_OK; }
|
||||
NS_IMETHOD Run();
|
||||
NS_IMETHOD Spindown() { return NS_OK; }
|
||||
NS_IMETHOD PushThreadEventQueue();
|
||||
NS_IMETHOD PopThreadEventQueue();
|
||||
NS_IMETHOD Exit();
|
||||
|
||||
NS_IMETHOD GetNativeEvent( PRBool &aRealEvent, void *&aEvent);
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
|
||||
|
||||
#include "nsIWidget.h"
|
||||
@ -120,6 +120,46 @@ NS_METHOD nsAppShell::Spindown()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PushThreadEventQueue - begin processing events from a new queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on photon.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PushThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PushThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PopThreadEventQueue - stop processing on a previously pushed event queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on photon.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PopThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PopThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent)
|
||||
{
|
||||
PR_LOG(PhWidLog, PR_LOG_DEBUG, ("nsAppShell::GetNativeEvent - Not Implemented.\n"));
|
||||
|
@ -43,6 +43,8 @@ class nsAppShell : public nsIAppShell
|
||||
virtual nsresult Run();
|
||||
NS_IMETHOD Spinup();
|
||||
NS_IMETHOD Spindown();
|
||||
NS_IMETHOD PushThreadEventQueue();
|
||||
NS_IMETHOD PopThreadEventQueue();
|
||||
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
|
||||
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
|
||||
NS_IMETHOD SetDispatchListener(nsDispatchListener* aDispatchListener);
|
||||
|
@ -18,8 +18,12 @@
|
||||
|
||||
#include "nsAppShell.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include <windows.h>
|
||||
|
||||
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAppShell, NS_IAPPSHELL_IID)
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -74,6 +78,44 @@ nsresult nsAppShell::Run()
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PushThreadEventQueue - begin processing events from a new queue
|
||||
// (simple wrapper function on Windows)
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PushThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PushThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PopThreadEventQueue - stop processing on a previously pushed event queue
|
||||
// (simple wrapper function on Windows)
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PopThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PopThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent)
|
||||
{
|
||||
|
@ -41,6 +41,8 @@ class nsAppShell : public nsIAppShell
|
||||
virtual nsresult Run();
|
||||
NS_IMETHOD Spinup() { return NS_OK; }
|
||||
NS_IMETHOD Spindown() { return NS_OK; }
|
||||
NS_IMETHOD PushThreadEventQueue();
|
||||
NS_IMETHOD PopThreadEventQueue();
|
||||
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
|
||||
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
|
||||
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent,
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
#define CHAR_BUF_SIZE 40
|
||||
|
||||
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
|
||||
|
||||
#ifdef TOOLKIT_EXORCISM
|
||||
@ -372,6 +372,46 @@ nsresult nsAppShell::Run()
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PushThreadEventQueue - begin processing events from a new queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on xlib.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PushThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PushThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// PopThreadEventQueue - stop processing on a previously pushed event queue
|
||||
// note this is the Windows implementation and may suffice, but
|
||||
// this is untested on xlib.
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsAppShell::PopThreadEventQueue()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = eQueueService->PopThreadEventQueue();
|
||||
else
|
||||
NS_ERROR("Appshell unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsAppShell::GetNativeEvent(PRBool &aRealEvent, void *&aEvent)
|
||||
{
|
||||
|
@ -36,6 +36,8 @@ class nsAppShell : public nsIAppShell
|
||||
virtual nsresult Run();
|
||||
NS_IMETHOD Spinup() { return NS_OK; }
|
||||
NS_IMETHOD Spindown() { return NS_OK; }
|
||||
NS_IMETHOD PushThreadEventQueue();
|
||||
NS_IMETHOD PopThreadEventQueue();
|
||||
NS_IMETHOD GetNativeEvent(PRBool &aRealEvent, void *&aEvent);
|
||||
NS_IMETHOD DispatchNativeEvent(PRBool aRealEvent, void * aEvent);
|
||||
NS_IMETHOD EventIsForModalWindow(PRBool aRealEvent, void *aEvent,
|
||||
|
@ -65,6 +65,17 @@ interface nsIAppShellService : nsISupports
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* Push a new event queue onto the stack of queues and begin processing
|
||||
* messages from it.
|
||||
*/
|
||||
void PushThreadEventQueue();
|
||||
|
||||
/**
|
||||
* Pop the last pushed event queue and stop processing messages from it.
|
||||
*/
|
||||
void PopThreadEventQueue();
|
||||
|
||||
/**
|
||||
* Create a window.
|
||||
* @param aParent the parent window. Can be null.
|
||||
|
@ -98,8 +98,10 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Initialize(nsICmdLineService*aCmdLineService);
|
||||
NS_IMETHOD Run(void);
|
||||
NS_IMETHOD Shutdown(void);
|
||||
NS_IMETHOD Run();
|
||||
NS_IMETHOD Shutdown();
|
||||
NS_IMETHOD PushThreadEventQueue();
|
||||
NS_IMETHOD PopThreadEventQueue();
|
||||
|
||||
NS_IMETHOD CreateTopLevelWindow(nsIWebShellWindow *aParent,
|
||||
nsIURI *aUrl,
|
||||
@ -499,6 +501,16 @@ nsAppShellService::Shutdown(void)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppShellService::PushThreadEventQueue() {
|
||||
return mAppShell->PushThreadEventQueue();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppShellService::PopThreadEventQueue() {
|
||||
return mAppShell->PopThreadEventQueue();
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new top level window and display the given URL within it...
|
||||
*/
|
||||
@ -640,25 +652,18 @@ nsAppShellService::RunModalDialog(
|
||||
{
|
||||
nsresult rv;
|
||||
nsIWebShellWindow *theWindow;
|
||||
PRBool pushedQueue;
|
||||
|
||||
#ifdef XP_PC // XXX: Won't work with any other platforms yet.
|
||||
// First push a nested event queue for event processing from netlib
|
||||
// onto our UI thread queue stack.
|
||||
// nsCOMPtr<nsIEventQueue> innerQueue;
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("RunModalDialog unable to obtain eventqueue service.");
|
||||
return rv;
|
||||
}
|
||||
eQueueService->PushThreadEventQueue();
|
||||
#endif
|
||||
|
||||
pushedQueue = PR_FALSE;
|
||||
if (aWindow && *aWindow) {
|
||||
theWindow = *aWindow; // and rv is already some success indication
|
||||
NS_ADDREF(theWindow);
|
||||
} else
|
||||
} else {
|
||||
pushedQueue = PR_TRUE;
|
||||
PushThreadEventQueue();
|
||||
rv = CreateTopLevelWindow(aParent, aUrl, PR_TRUE, aChromeMask,
|
||||
aCallbacks, aInitialWidth, aInitialHeight, &theWindow);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIWidget> parentWindowWidgetThing;
|
||||
@ -682,10 +687,8 @@ nsAppShellService::RunModalDialog(
|
||||
NS_RELEASE(theWindow); // can't return it; let it go
|
||||
}
|
||||
|
||||
// Release the event queue
|
||||
#ifdef XP_PC // XXX Won't work on other platforms yet
|
||||
eQueueService->PopThreadEventQueue();
|
||||
#endif
|
||||
if (pushedQueue)
|
||||
PopThreadEventQueue();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
|
||||
static NS_DEFINE_IID(kINetSupportDialogIID, NS_INETSUPPORTDIALOGSERVICE_IID);
|
||||
#endif
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
|
||||
// Copy and paste
|
||||
#define APP_DEBUG 1
|
||||
static nsresult setAttribute( nsIWebShell *shell,
|
||||
@ -520,6 +521,8 @@ nsresult nsNetSupportDialog::DoDialog( nsString& inXULURL )
|
||||
return result;
|
||||
}
|
||||
|
||||
appShellService->PushThreadEventQueue();
|
||||
|
||||
result = appShellService->CreateTopLevelWindow(nsnull, dialogURL, PR_TRUE,
|
||||
NS_CHROME_ALL_CHROME | NS_CHROME_OPEN_AS_DIALOG,
|
||||
this, 300, 200, &dialogWindow);
|
||||
@ -530,6 +533,8 @@ nsresult nsNetSupportDialog::DoDialog( nsString& inXULURL )
|
||||
NS_CHROME_ALL_CHROME | NS_CHROME_OPEN_AS_DIALOG,
|
||||
this, 300, 200);
|
||||
|
||||
appShellService->PopThreadEventQueue();
|
||||
|
||||
// cleanup
|
||||
if ( mOKButton )
|
||||
RemoveEventListener( mOKButton );
|
||||
|
Loading…
x
Reference in New Issue
Block a user