Fix shutdown leak of GDK windows by destroying hidden widget before event loop shutdown. b=219521 r=blizzard sr=bryner

This commit is contained in:
dbaron%dbaron.org 2003-10-30 01:48:41 +00:00
Родитель 4fd72ff1cd
Коммит 3b1531ab56
4 изменённых файлов: 70 добавлений и 8 удалений

Просмотреть файл

@ -25,6 +25,7 @@
#include "nsIServiceManager.h"
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "nsIObserverService.h"
#include "prlog.h"
#include "nsVoidArray.h"
#include "nsXPIDLString.h"
@ -45,8 +46,11 @@ static const char gTextUriListType[] = "text/uri-list";
NS_IMPL_ADDREF_INHERITED(nsDragService, nsBaseDragService)
NS_IMPL_RELEASE_INHERITED(nsDragService, nsBaseDragService)
NS_IMPL_QUERY_INTERFACE3(nsDragService, nsIDragService, nsIDragSession, \
nsIDragSessionGTK)
NS_IMPL_QUERY_INTERFACE4(nsDragService,
nsIDragService,
nsIDragSession,
nsIDragSessionGTK,
nsIObserver)
static void
invisibleSourceDragEnd (GtkWidget *aWidget,
@ -63,6 +67,11 @@ invisibleSourceDragDataGet (GtkWidget *aWidget,
nsDragService::nsDragService()
{
// We have to destroy the hidden widget before the event loop stops running.
nsCOMPtr<nsIObserverService> obsServ =
do_GetService("@mozilla.org/observer-service;1");
obsServ->AddObserver(this, "quit-application", PR_FALSE);
// our hidden source widget
mHiddenWidget = gtk_invisible_new();
// make sure that the widget is realized so that
@ -94,8 +103,25 @@ nsDragService::nsDragService()
nsDragService::~nsDragService()
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::~nsDragService"));
gtk_widget_unref(mHiddenWidget);
TargetResetData();
}
// nsIObserver
NS_IMETHODIMP
nsDragService::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *aData)
{
if (!nsCRT::strcmp(aTopic, "quit-application")) {
PR_LOG(sDragLm, PR_LOG_DEBUG,
("nsDragService::Observe(\"quit-application\")"));
gtk_widget_unref(mHiddenWidget);
TargetResetData();
} else {
NS_NOTREACHED("unexpected topic");
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
// nsIDragService

Просмотреть файл

@ -25,6 +25,7 @@
#include "nsBaseDragService.h"
#include "nsIDragSessionGTK.h"
#include "nsIObserver.h"
#include <gtk/gtk.h>
@ -32,7 +33,9 @@
* Native GTK DragService wrapper
*/
class nsDragService : public nsBaseDragService, public nsIDragSessionGTK
class nsDragService : public nsBaseDragService,
public nsIDragSessionGTK,
public nsIObserver
{
public:
@ -41,6 +44,8 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIOBSERVER
// nsIDragService
NS_IMETHOD InvokeDragSession (nsIDOMNode *aDOMNode,
nsISupportsArray * anArrayTransferables,

Просмотреть файл

@ -26,6 +26,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsDragService.h"
#include "nsIObserverService.h"
#include "nsWidgetsCID.h"
#include "nsWindow.h"
#include "nsIServiceManager.h"
@ -50,10 +51,11 @@ static const char gTextUriListType[] = "text/uri-list";
NS_IMPL_ADDREF_INHERITED(nsDragService, nsBaseDragService)
NS_IMPL_RELEASE_INHERITED(nsDragService, nsBaseDragService)
NS_IMPL_QUERY_INTERFACE3(nsDragService,
NS_IMPL_QUERY_INTERFACE4(nsDragService,
nsIDragService,
nsIDragSession,
nsIDragSessionGTK)
nsIDragSessionGTK,
nsIObserver)
static void
invisibleSourceDragEnd(GtkWidget *aWidget,
@ -70,6 +72,12 @@ invisibleSourceDragDataGet(GtkWidget *aWidget,
nsDragService::nsDragService()
{
// We have to destroy the hidden widget before the event loop stops
// running.
nsCOMPtr<nsIObserverService> obsServ =
do_GetService("@mozilla.org/observer-service;1");
obsServ->AddObserver(this, "quit-application", PR_FALSE);
// our hidden source widget
mHiddenWidget = gtk_invisible_new();
// make sure that the widget is realized so that
@ -98,8 +106,25 @@ nsDragService::nsDragService()
nsDragService::~nsDragService()
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::~nsDragService"));
}
// nsIObserver
NS_IMETHODIMP
nsDragService::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *aData)
{
if (!nsCRT::strcmp(aTopic, "quit-application")) {
PR_LOG(sDragLm, PR_LOG_DEBUG,
("nsDragService::Observe(\"quit-application\")"));
gtk_widget_destroy(mHiddenWidget);
TargetResetData();
} else {
NS_NOTREACHED("unexpected topic");
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
// nsIDragService

Просмотреть файл

@ -30,6 +30,7 @@
#include "nsBaseDragService.h"
#include "nsIDragSessionGTK.h"
#include "nsIObserver.h"
#include <gtk/gtk.h>
@ -37,13 +38,18 @@
* Native GTK DragService wrapper
*/
class nsDragService : public nsBaseDragService, public nsIDragSessionGTK {
class nsDragService : public nsBaseDragService,
public nsIDragSessionGTK,
public nsIObserver
{
public:
nsDragService();
virtual ~nsDragService();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIOBSERVER
// nsIDragService
NS_IMETHOD InvokeDragSession (nsIDOMNode *aDOMNode,
nsISupportsArray * anArrayTransferables,