diff options
Diffstat (limited to 'net-www/mozilla/files/1.3')
4 files changed, 754 insertions, 0 deletions
diff --git a/net-www/mozilla/files/1.3/mozilla-1.3-fix-RAW-target.patch b/net-www/mozilla/files/1.3/mozilla-1.3-fix-RAW-target.patch new file mode 100644 index 000000000000..5951496e9893 --- /dev/null +++ b/net-www/mozilla/files/1.3/mozilla-1.3-fix-RAW-target.patch @@ -0,0 +1,12 @@ +--- mozilla/xpinstall/packager/Makefile.in.orig 2003-02-23 14:41:08.000000000 +0200 ++++ mozilla/xpinstall/packager/Makefile.in 2003-02-23 14:41:36.000000000 +0200 +@@ -87,6 +87,9 @@ + ifeq ($(MOZ_PKG_FORMAT),DEB) + PKG_SUFFIX = .deb + endif ++ifeq ($(MOZ_PKG_FORMAT),RAW) ++MAKE_SDK = echo ++endif + + TARGETS = $(PACKAGE) $(SDK) + diff --git a/net-www/mozilla/files/1.3/mozilla-1.3-fix-gtkim.patch b/net-www/mozilla/files/1.3/mozilla-1.3-fix-gtkim.patch new file mode 100644 index 000000000000..9c0e642aed9f --- /dev/null +++ b/net-www/mozilla/files/1.3/mozilla-1.3-fix-gtkim.patch @@ -0,0 +1,31 @@ +--- mozilla/widget/src/gtk2/nsWindow.cpp.orig 2002-11-17 21:04:42.000000000 +0900 ++++ mozilla/widget/src/gtk2/nsWindow.cpp 2002-11-20 02:17:53.000000000 +0900 +@@ -2094,7 +2094,7 @@ + } + #ifdef USE_XIM + // get mIMEShellWindow and keep it +- IMEGetShellWindow(); ++// IMEGetShellWindow(); + #endif + } + break; +@@ -2144,6 +2144,8 @@ + if (mShell) { + // init GtkIMContext for shell + IMECreateContext(mShell->window); ++ } else if (mDrawingarea) { ++ IMECreateContext(mDrawingarea->inner_window); + } + #endif + +--- mozilla/widget/src/gtk2/Makefile.in.orig 2002-11-17 21:04:40.000000000 +0900 ++++ mozilla/widget/src/gtk2/Makefile.in 2002-11-20 02:19:26.000000000 +0900 +@@ -88,7 +88,7 @@ + CFLAGS += $(MOZ_GTK2_CFLAGS) + CXXFLAGS += $(MOZ_GTK2_CFLAGS) + +-#DEFINES += -DUSE_XIM ++DEFINES += -DUSE_XIM + + INCLUDES += \ + -I$(srcdir)/../xpwidgets \ diff --git a/net-www/mozilla/files/1.3/mozilla-1.3-gtk2.patch b/net-www/mozilla/files/1.3/mozilla-1.3-gtk2.patch new file mode 100644 index 000000000000..9026767d0a9e --- /dev/null +++ b/net-www/mozilla/files/1.3/mozilla-1.3-gtk2.patch @@ -0,0 +1,588 @@ +--- mozilla/widget/src/gtk2/Makefile.in.gtk2 2002-12-28 02:14:45.000000000 +0100 ++++ mozilla/widget/src/gtk2/Makefile.in 2003-03-11 14:05:45.000000000 +0100 +@@ -90,7 +90,7 @@ + CFLAGS += $(MOZ_GTK2_CFLAGS) + CXXFLAGS += $(MOZ_GTK2_CFLAGS) + +-#DEFINES += -DUSE_XIM ++DEFINES += -DUSE_XIM + + INCLUDES += \ + -I$(srcdir)/../xpwidgets \ +--- mozilla/widget/src/gtk2/nsWindow.h.gtk2 2003-02-17 19:50:01.000000000 +0100 ++++ mozilla/widget/src/gtk2/nsWindow.h 2003-03-13 10:14:36.000000000 +0100 +@@ -139,9 +139,11 @@ + PRBool aDoCapture, + PRBool aConsumeRollupEvent); + NS_IMETHOD GetAttention(); ++ NS_IMETHOD HideWindowChrome(PRBool aShouldHide); + + // utility methods + void LoseFocus(); ++ gint ConvertBorderStyles(nsBorderStyle bs); + + // event callbacks + gboolean OnExposeEvent(GtkWidget *aWidget, +@@ -239,6 +241,9 @@ + static guint32 mLastButtonPressTime; + + #ifdef USE_XIM ++ void IMEDestroyContext(void); ++ void IMESetFocus(void); ++ void IMELoseFocus(void); + void IMEComposeStart(void); + void IMEComposeText(const PRUnichar *aText, + const PRInt32 aLen, +@@ -249,9 +254,14 @@ + void IMEGetShellWindow(void); + GtkIMContext* IMEGetContext(void); + void IMECreateContext(GdkWindow* aGdkWindow); ++ PRBool IMFilterKeypress (GtkIMContext *context, ++ GdkEventKey *aEvent); ++ + + nsWindow* mIMEShellWindow; + static PLDHashTable gXICLookupTable; ++ static GdkEventKey* gIMEKeyEvent; ++ static PRBool gIMEStringCommited; + #endif + + private: +--- mozilla/widget/src/gtk2/nsWindow.cpp.gtk2 2003-02-21 02:09:17.000000000 +0100 ++++ mozilla/widget/src/gtk2/nsWindow.cpp 2003-03-13 10:13:17.000000000 +0100 +@@ -179,6 +179,7 @@ + nsWeakPtr gRollupWindow; + + #ifdef USE_XIM ++static nsWindow *gIMEFocusWindow = NULL; + + struct nsXICLookupEntry { + PLDHashEntryHdr mKeyHash; +@@ -186,7 +187,9 @@ + GtkIMContext* mXIC; + }; + +-PLDHashTable nsWindow::gXICLookupTable; ++PLDHashTable nsWindow::gXICLookupTable; ++GdkEventKey* nsWindow::gIMEKeyEvent = NULL; ++PRBool nsWindow::gIMEStringCommited = PR_TRUE; + + static void IM_commit_cb (GtkIMContext *context, + const gchar *str, +@@ -257,61 +260,6 @@ + #endif + } + +-#ifdef USE_XIM +-void +-nsWindow::IMEGetShellWindow(void) +-{ +- GtkWidget* top_window = nsnull; +- GetToplevelWidget(&top_window); +- if (top_window) { +- mIMEShellWindow = get_window_for_gtk_widget(top_window); +- } +-} +- +-GtkIMContext* +-nsWindow::IMEGetContext() +-{ +- if (!mIMEShellWindow) { +- return NULL; +- } +- PLDHashEntryHdr* hash_entry; +- nsXICLookupEntry* entry; +- +- hash_entry = PL_DHashTableOperate(&gXICLookupTable, +- mIMEShellWindow, PL_DHASH_LOOKUP); +- +- if (hash_entry) { +- entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); +- if (entry->mXIC) { +- return entry->mXIC; +- } +- } +- return NULL; +-} +- +-void +-nsWindow::IMECreateContext(GdkWindow* aGdkWindow) +-{ +- PLDHashEntryHdr* hash_entry; +- nsXICLookupEntry* entry; +- GtkIMContext *im = gtk_im_multicontext_new(); +- if (im) { +- hash_entry = PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_ADD); +- if (hash_entry) { +- entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); +- entry->mShellWindow = this; +- entry->mXIC = im; +- } +- gtk_im_context_set_client_window(im, aGdkWindow); +- g_signal_connect(G_OBJECT(im), "commit", +- G_CALLBACK(IM_commit_cb), this); +- g_signal_connect(G_OBJECT(im), "preedit_changed", +- G_CALLBACK(IM_preedit_changed_cb), this); +- this->mIMEShellWindow = this; +- } +-} +-#endif +- + nsWindow::~nsWindow() + { + LOG(("nsWindow::~nsWindow() [%p]\n", (void *)this)); +@@ -397,22 +345,7 @@ + } + + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- // If this is the focus window and we have an IM context we need +- // to unset the focus on this window before we destroy the window. +- if (im && gFocusWindow == this) { +- LOGFOCUS((" gtk_im_context_focus_out() from Destroy()\n")); +- gtk_im_context_focus_out(im); +- } +- +- // if shell, delete GtkIMContext +- if (im && mShell) { +- gtk_im_context_reset(im); +- PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_REMOVE); +- g_object_unref(G_OBJECT(im)); +- } +- +- mIMEShellWindow = nsnull; ++ IMEDestroyContext(); + #endif + + // make sure that we remove ourself as the focus window +@@ -666,11 +599,7 @@ + gFocusWindow = this; + + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im && !mIsTopLevel) { +- LOGFOCUS((" gtk_im_context_focus_in()\n")); +- gtk_im_context_focus_in(im); +- } ++ IMESetFocus(); + #endif + + LOGFOCUS((" widget now has focus - dispatching events [%p]\n", +@@ -735,7 +664,11 @@ + GtkWidget *widget = + get_gtk_widget_for_gdk_window(mDrawingarea->inner_window); + nsWindow *window = get_window_for_gtk_widget(widget); +- return window->SetCursor(aCursor); ++ if (window) { ++ return window->SetCursor(aCursor); ++ } ++ else ++ return NS_OK; + } + + // Only change cursor if it's actually been changed +@@ -746,7 +679,12 @@ + + if (nsnull != newCursor) { + mCursor = aCursor; ++ ++ if (!mContainer) ++ return NS_OK; ++ + gdk_window_set_cursor(GTK_WIDGET(mContainer)->window, newCursor); ++ + XFlush(GDK_DISPLAY()); + } + } +@@ -1161,17 +1099,8 @@ + nsWindow::LoseFocus(void) + { + #ifdef USE_XIM +- GtkIMContext *im = IMEGetContext(); +- if (im && !mIsTopLevel) { +- LOGFOCUS((" gtk_im_context_focus_out()\n")); +- gtk_im_context_focus_out(im); +- IMEComposeStart(); +- IMEComposeText(NULL, 0, NULL, NULL); +- IMEComposeEnd(); +- LOG(("gtk_im_context_focus_out\n")); +- } ++ IMELoseFocus(); + #endif +- + // make sure that we reset our repeat counter so the next keypress + // for this widget will get the down event + mInKeyRepeat = PR_FALSE; +@@ -1382,7 +1311,7 @@ + nsWindow *containerWindow; + GetContainerWindow(&containerWindow); + +- if (!gFocusWindow) { ++ if (!gFocusWindow && !containerWindow) { + containerWindow->mActivatePending = PR_FALSE; + DispatchActivateEvent(); + } +@@ -1532,7 +1461,7 @@ + #ifdef USE_XIM + GtkIMContext *im = IMEGetContext(); + if (im) { +- if (gtk_im_context_filter_keypress(im, aEvent)) { ++ if (IMFilterKeypress(im, aEvent)) { + LOGFOCUS((" keypress filtered by XIM\n")); + return TRUE; + } +@@ -1616,7 +1545,7 @@ + #ifdef USE_XIM + GtkIMContext *im = IMEGetContext(); + if (im) { +- if (gtk_im_context_filter_keypress(im, aEvent)) { ++ if (IMFilterKeypress(im, aEvent)) { + LOGFOCUS((" keypress filtered by XIM\n")); + return TRUE; + } +@@ -2150,6 +2079,13 @@ + + // and the drawing area + mDrawingarea = moz_drawingarea_new(nsnull, mContainer); ++ ++#if defined(USE_XIM) && !defined(XIM_CREATE_IC_AT_FOCUS) ++ if (mWindowType != eWindowType_popup) { ++ // create im context for shell ++ IMECreateContext(mShell->window); ++ } ++#endif /* XIM_CREATE_IC_AT_FOCUS && !XIM_CREATE_IC_AT_FOCUS*/ + } + break; + case eWindowType_child: { +@@ -2162,11 +2098,11 @@ + gtk_widget_realize(GTK_WIDGET(mContainer)); + + mDrawingarea = moz_drawingarea_new(nsnull, mContainer); ++#if defined(USE_XIM) && !defined(XIM_CREATE_IC_AT_FOCUS) ++ // create im context for gtk container ++ IMECreateContext(GTK_WIDGET(mContainer)->window); ++#endif /* XIM_CREATE_IC_AT_FOCUS && !XIM_CREATE_IC_AT_FOCUS*/ + } +-#ifdef USE_XIM +- // get mIMEShellWindow and keep it +- IMEGetShellWindow(); +-#endif + } + break; + default: +@@ -2211,13 +2147,6 @@ + G_CALLBACK(property_notify_event_cb), NULL); + } + +-#ifdef USE_XIM +- if (mShell) { +- // init GtkIMContext for shell +- IMECreateContext(mShell->window); +- } +-#endif +- + if (mContainer) { + g_signal_connect_after(G_OBJECT(mContainer), "size_allocate", + G_CALLBACK(size_allocate_cb), NULL); +@@ -2694,6 +2623,83 @@ + } + + ++gint ++nsWindow::ConvertBorderStyles(nsBorderStyle bs) ++{ ++ gint w = 0; ++ ++ if (bs == eBorderStyle_default) ++ return -1; ++ ++ if (bs & eBorderStyle_all) ++ w |= GDK_DECOR_ALL; ++ if (bs & eBorderStyle_border) ++ w |= GDK_DECOR_BORDER; ++ if (bs & eBorderStyle_resizeh) ++ w |= GDK_DECOR_RESIZEH; ++ if (bs & eBorderStyle_title) ++ w |= GDK_DECOR_TITLE; ++ if (bs & eBorderStyle_menu) ++ w |= GDK_DECOR_MENU; ++ if (bs & eBorderStyle_minimize) ++ w |= GDK_DECOR_MINIMIZE; ++ if (bs & eBorderStyle_maximize) ++ w |= GDK_DECOR_MAXIMIZE; ++ if (bs & eBorderStyle_close) { ++#ifdef DEBUG ++ printf("we don't handle eBorderStyle_close yet... please fix me\n"); ++#endif /* DEBUG */ ++ } ++ ++ return w; ++} ++ ++NS_IMETHODIMP ++nsWindow::HideWindowChrome(PRBool aShouldHide) ++{ ++ if (!mShell) { ++ // Pass the request to the toplevel window ++ GtkWidget *topWidget = nsnull; ++ GetToplevelWidget(&topWidget); ++ nsWindow *topWindow = get_window_for_gtk_widget(topWidget); ++ if (topWindow) ++ return topWindow->HideWindowChrome(aShouldHide); ++ else ++ return NS_OK; ++ } ++ ++ // Sawfish, metacity, and presumably other window managers get ++ // confused if we change the window decorations while the window ++ // is visible. ++#if GTK_CHECK_VERSION(2,2,0) ++ if (aShouldHide) ++ gdk_window_fullscreen (mShell->window); ++ else ++ gdk_window_unfullscreen (mShell->window); ++#else ++ gdk_window_hide(mShell->window); ++ ++ gint wmd; ++ if (aShouldHide) ++ wmd = 0; ++ else ++ wmd = ConvertBorderStyles(mBorderStyle); ++ ++ gdk_window_set_decorations(mShell->window, (GdkWMDecoration) wmd); ++ ++ gdk_window_show(mShell->window); ++#endif ++ ++ // For some window managers, adding or removing window decorations ++ // requires unmapping and remapping our toplevel window. Go ahead ++ // and flush the queue here so that we don't end up with a BadWindow ++ // error later when this happens (when the persistence timer fires ++ // and GetWindowPos is called) ++ XSync(GDK_DISPLAY(), False); ++ ++ return NS_OK; ++} ++ + PRBool + check_for_rollup(GdkWindow *aWindow, gdouble aMouseX, gdouble aMouseY, + PRBool aIsWheel) +@@ -3662,6 +3668,77 @@ + } + + #ifdef USE_XIM ++void ++nsWindow::IMEGetShellWindow(void) ++{ ++ GtkWidget* top_window = nsnull; ++ GetToplevelWidget(&top_window); ++ if (top_window) { ++ mIMEShellWindow = get_window_for_gtk_widget(top_window); ++ if (mIMEShellWindow) { ++ return; ++ } ++ } ++ ++ // find deepest nsWindow ++ if (!mDrawingarea) { ++ return; ++ } ++ GdkWindow *parent = gdk_window_get_parent(mDrawingarea->inner_window); ++ while (parent) { ++ nsWindow *window = get_window_for_gdk_window(parent); ++ if (window == nsnull) { ++ break; ++ } ++ if (window->mContainer) { ++ mIMEShellWindow = window; ++ } ++ parent = gdk_window_get_parent (parent); ++ } ++} ++ ++GtkIMContext* ++nsWindow::IMEGetContext() ++{ ++ if (!mIMEShellWindow) { ++ return NULL; ++ } ++ PLDHashEntryHdr* hash_entry; ++ nsXICLookupEntry* entry; ++ ++ hash_entry = PL_DHashTableOperate(&gXICLookupTable, ++ mIMEShellWindow, PL_DHASH_LOOKUP); ++ ++ if (hash_entry) { ++ entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); ++ if (entry->mXIC) { ++ return entry->mXIC; ++ } ++ } ++ return NULL; ++} ++ ++void ++nsWindow::IMECreateContext(GdkWindow* aGdkWindow) ++{ ++ PLDHashEntryHdr* hash_entry; ++ nsXICLookupEntry* entry; ++ GtkIMContext *im = gtk_im_multicontext_new(); ++ if (im) { ++ hash_entry = PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_ADD); ++ if (hash_entry) { ++ entry = NS_REINTERPRET_CAST(nsXICLookupEntry *, hash_entry); ++ entry->mShellWindow = this; ++ entry->mXIC = im; ++ } ++ gtk_im_context_set_client_window(im, aGdkWindow); ++ g_signal_connect(G_OBJECT(im), "commit", ++ G_CALLBACK(IM_commit_cb), this); ++ g_signal_connect(G_OBJECT(im), "preedit_changed", ++ G_CALLBACK(IM_preedit_changed_cb), this); ++ this->mIMEShellWindow = this; ++ } ++} + + void + nsWindow::IMEComposeStart(void) +@@ -3732,6 +3809,26 @@ + DispatchEvent(&compEvent, status); + } + ++PRBool ++nsWindow::IMFilterKeypress (GtkIMContext *context, ++ GdkEventKey *aEvent) ++{ ++ gIMEKeyEvent = aEvent; ++ if (gtk_im_context_filter_keypress(context, aEvent)) { ++ /* return true if the keyevent is commited as string and ++ ** has been dispatched as TextEvent. ++ */ ++ if( gIMEStringCommited ) { ++ return TRUE; ++ } ++ gIMEStringCommited = PR_TRUE; ++ } ++ gIMEKeyEvent = NULL; ++ ++ /* the Keyevent is not filtered by IME */ ++ return FALSE; ++} ++ + /* static */ + void + IM_preedit_changed_cb(GtkIMContext *context, +@@ -3742,7 +3839,8 @@ + PangoAttrList *feedback_list; + + // call for focused window +- nsWindow *window = gFocusWindow; ++ // if gFocusWindow is null, use the last focused gIMEFocusWindow ++ nsWindow *window = gFocusWindow ? gFocusWindow : gIMEFocusWindow; + if (!window) return; + + // Should use cursor_pos ? +@@ -3755,6 +3853,7 @@ + if (!preedit_string || !*preedit_string) { + window->IMEComposeStart(); + window->IMEComposeText(NULL, 0, NULL, NULL); ++ window->IMEComposeEnd(); + return; + } + +@@ -3795,9 +3894,31 @@ + glong uniStrLen; + + // call for focused window +- nsWindow *window = gFocusWindow; ++ // if gFocusWindow is null, use the last focused gIMEFocusWindow ++ nsWindow *window = gFocusWindow ? gFocusWindow : gIMEFocusWindow; + if (!window) return; + ++ /* if the IME does not change the keystrock, we won't send it ++ * through the TextEvent. ++ */ ++ nsWindow::gIMEStringCommited = PR_TRUE; ++ if ( nsWindow::gIMEKeyEvent ) ++ { ++ char keyval_utf8[8]; /* should have at least 6 bytes of space */ ++ gint keyval_utf8_len; ++ keyval_utf8_len = g_unichar_to_utf8( ++ gdk_keyval_to_unicode(nsWindow::gIMEKeyEvent->keyval), ++ keyval_utf8); ++ ++ keyval_utf8[keyval_utf8_len] = '\0'; ++ if ( strcmp(utf8_str, keyval_utf8) == 0) ++ { ++ nsWindow::gIMEStringCommited = PR_FALSE; ++ return; ++ } ++ nsWindow::gIMEKeyEvent = NULL; ++ } ++ + uniStr = NULL; + uniStrLen = 0; + uniStr = g_utf8_to_utf16(utf8_str, -1, NULL, &uniStrLen, NULL); +@@ -3941,4 +4062,61 @@ + pango_attr_iterator_destroy(aFeedbackIterator); + } + ++void ++nsWindow::IMELoseFocus(void) ++{ ++ GtkIMContext *im = IMEGetContext(); ++ if (!im) { ++ return; ++ } ++ gtk_im_context_focus_out(im); ++} ++ ++void ++nsWindow::IMESetFocus(void) ++{ ++ if (mWindowType == eWindowType_child && !mIMEShellWindow) { ++ IMEGetShellWindow(); ++ } ++ GtkIMContext *im = IMEGetContext(); ++#ifdef XIM_CREATE_IC_AT_FOCUS ++ if (!im && mIMEShellWindow) { ++ if (mIMEShellWindow->mShell) { ++ // init GtkIMContext for shell ++ mIMEShellWindow->IMECreateContext(mIMEShellWindow->mShell->window); ++ } else if (mIMEShellWindow->mContainer) { ++ // init GtkIMContext for mContainer ++ mIMEShellWindow->IMECreateContext(GTK_WIDGET(mIMEShellWindow->mContainer)->window); ++ } ++ } ++ im = IMEGetContext(); ++#endif /* XIM_CREATE_IC_AT_FOCUS */ ++ if (!im) { ++ return; ++ } ++ gtk_im_context_focus_in(im); ++ gIMEFocusWindow = this; ++} ++ ++void ++nsWindow::IMEDestroyContext(void) ++{ ++ GtkIMContext *im = IMEGetContext(); ++ if (im) { ++ // If this is the focus window and we have an IM context we need ++ // to unset the focus on this window before we destroy the window. ++ if (gIMEFocusWindow == this) { ++ gIMEFocusWindow->IMELoseFocus(); ++ gIMEFocusWindow = nsnull; ++ } ++ // if shell, delete GtkIMContext ++ if (mIMEShellWindow == this) { ++ gtk_im_context_set_client_window(im, NULL); ++ PL_DHashTableOperate(&gXICLookupTable, this, PL_DHASH_REMOVE); ++ g_object_unref(G_OBJECT(im)); ++ } ++ } ++ mIMEShellWindow = nsnull; ++} ++ + #endif diff --git a/net-www/mozilla/files/1.3/mozilla-1.3-provider-shutdown.patch b/net-www/mozilla/files/1.3/mozilla-1.3-provider-shutdown.patch new file mode 100644 index 000000000000..78f5eeb5a437 --- /dev/null +++ b/net-www/mozilla/files/1.3/mozilla-1.3-provider-shutdown.patch @@ -0,0 +1,123 @@ +Index: embedding/browser/gtk/src/EmbedPrivate.cpp +=================================================================== +RCS file: /cvsroot/mozilla/embedding/browser/gtk/src/EmbedPrivate.cpp,v +retrieving revision 1.30 +diff -u -r1.30 EmbedPrivate.cpp +--- embedding/browser/gtk/src/EmbedPrivate.cpp 9 Nov 2002 19:38:31 -0000 1.30 ++++ embedding/browser/gtk/src/EmbedPrivate.cpp 11 Feb 2003 00:11:18 -0000 +@@ -78,6 +78,7 @@ + GtkWidget *EmbedPrivate::sOffscreenWindow = 0; + GtkWidget *EmbedPrivate::sOffscreenFixed = 0; + nsIDirectoryServiceProvider *EmbedPrivate::sAppFileLocProvider = nsnull; ++nsProfileDirServiceProvider *EmbedPrivate::sProfileDirServiceProvider = nsnull; + + EmbedPrivate::EmbedPrivate(void) + { +@@ -796,16 +797,14 @@ + NS_NewProfileDirServiceProvider(PR_TRUE, getter_AddRefs(locProvider)); + if (!locProvider) + return NS_ERROR_FAILURE; +- +- // Directory service holds an strong reference to any +- // provider that is registered with it. Let it hold the +- // only ref. locProvider won't die when we leave this scope. + rv = locProvider->Register(); + if (NS_FAILED(rv)) + return rv; + rv = locProvider->SetProfileDir(profileDir); + if (NS_FAILED(rv)) + return rv; ++ // Keep a ref so we can shut it down. ++ NS_ADDREF(sProfileDirServiceProvider = locProvider); + + // get prefs + nsCOMPtr<nsIPref> pref; +@@ -822,6 +821,11 @@ + void + EmbedPrivate::ShutdownProfile(void) + { ++ if (sProfileDirServiceProvider) { ++ sProfileDirServiceProvider->Shutdown(); ++ NS_RELEASE(sProfileDirServiceProvider); ++ sProfileDirServiceProvider = 0; ++ } + if (sPrefs) { + NS_RELEASE(sPrefs); + sPrefs = 0; +Index: embedding/browser/gtk/src/EmbedPrivate.h +=================================================================== +RCS file: /cvsroot/mozilla/embedding/browser/gtk/src/EmbedPrivate.h,v +retrieving revision 1.16 +diff -u -r1.16 EmbedPrivate.h +--- embedding/browser/gtk/src/EmbedPrivate.h 29 Jan 2002 21:39:30 -0000 1.16 ++++ embedding/browser/gtk/src/EmbedPrivate.h 11 Feb 2003 00:11:18 -0000 +@@ -46,6 +46,7 @@ + + class nsPIDOMWindow; + class nsIDirectoryServiceProvider; ++class nsProfileDirServiceProvider; + + class EmbedPrivate { + +@@ -134,6 +135,7 @@ + static char *sProfileDir; + static char *sProfileName; + // for profiles ++ static nsProfileDirServiceProvider *sProfileDirServiceProvider; + static nsIPref *sPrefs; + + static nsIDirectoryServiceProvider * sAppFileLocProvider; +Index: profile/dirserviceprovider/public/nsProfileDirServiceProvider.h +=================================================================== +RCS file: /cvsroot/mozilla/profile/dirserviceprovider/public/nsProfileDirServiceProvider.h,v +retrieving revision 1.1 +diff -u -r1.1 nsProfileDirServiceProvider.h +--- profile/dirserviceprovider/public/nsProfileDirServiceProvider.h 9 Nov 2002 19:38:23 -0000 1.1 ++++ profile/dirserviceprovider/public/nsProfileDirServiceProvider.h 11 Feb 2003 00:11:54 -0000 +@@ -79,6 +79,16 @@ + + virtual nsresult Register(); + ++ /** ++ * Shutdown ++ * ++ * This method must be called before shutting down XPCOM if this object ++ * was created with aNotifyObservers == PR_TRUE. If this object was ++ * created with aNotifyObservers == PR_FALSE, this method is a no-op. ++ */ ++ ++ virtual nsresult Shutdown(); ++ + protected: + nsProfileDirServiceProvider(PRBool aNotifyObservers = PR_TRUE); + virtual ~nsProfileDirServiceProvider(); +Index: profile/dirserviceprovider/src/nsProfileDirServiceProvider.cpp +=================================================================== +RCS file: /cvsroot/mozilla/profile/dirserviceprovider/src/nsProfileDirServiceProvider.cpp,v +retrieving revision 1.3 +diff -u -r1.3 nsProfileDirServiceProvider.cpp +--- profile/dirserviceprovider/src/nsProfileDirServiceProvider.cpp 8 Jan 2003 22:41:35 -0000 1.3 ++++ profile/dirserviceprovider/src/nsProfileDirServiceProvider.cpp 11 Feb 2003 00:11:54 -0000 +@@ -155,6 +155,22 @@ + return directoryService->RegisterProvider(this); + } + ++nsresult ++nsProfileDirServiceProvider::Shutdown() ++{ ++ if (!mNotifyObservers) ++ return NS_OK; ++ ++ nsCOMPtr<nsIObserverService> observerService = ++ do_GetService("@mozilla.org/observer-service;1"); ++ if (!observerService) ++ return NS_ERROR_FAILURE; ++ ++ NS_NAMED_LITERAL_STRING(context, "shutdown-persist"); ++ observerService->NotifyObservers(nsnull, "profile-before-change", context.get()); ++ return NS_OK; ++} ++ + //***************************************************************************** + // nsProfileDirServiceProvider::nsISupports + //***************************************************************************** |