From 16665642da794b404e03e02a283a26de00d3d5a0 Mon Sep 17 00:00:00 2001 From: "masayuki%d-toybox.com" Date: Tue, 29 Aug 2006 16:05:49 +0000 Subject: [PATCH] --- yaml --- r: 167481 b: refs/heads/master c: e09105ffab9281a2d83b5341f6dfa7e61aad47b8 h: refs/heads/master i: 167479: 2ca656807e2a6d4b2d15c58054359c39e7065e17 v: v3 --- [refs] | 2 +- trunk/widget/src/gtk2/nsWindow.cpp | 54 +++++++++++++++++++++++------- trunk/widget/src/gtk2/nsWindow.h | 8 ++++- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index 32213b81bfc99..dd4b2a897ba8a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dc2469abccaae7bf68098978300c7d489f1e8f4f +refs/heads/master: e09105ffab9281a2d83b5341f6dfa7e61aad47b8 diff --git a/trunk/widget/src/gtk2/nsWindow.cpp b/trunk/widget/src/gtk2/nsWindow.cpp index 5c3beed17e33b..c977de04a8941 100644 --- a/trunk/widget/src/gtk2/nsWindow.cpp +++ b/trunk/widget/src/gtk2/nsWindow.cpp @@ -4824,25 +4824,52 @@ nsChildWindow::~nsChildWindow() #ifdef USE_XIM +void +nsWindow::IMEInitData(void) +{ + NS_ASSERTION(!mIMEData, "This window was already initialized."); + nsWindow *win = IMEGetOwningWindow(); + if (!win) + return; + mIMEData = win->mIMEData; + if (!mIMEData) + return; + mIMEData->mRefCount++; +} + +void +nsWindow::IMEReleaseData(void) +{ + if (!mIMEData) + return; + + mIMEData->mRefCount--; + if (mIMEData->mRefCount != 0) + return; + + delete mIMEData; + mIMEData = nsnull; +} + void nsWindow::IMEDestroyContext(void) { if (!mIMEData || mIMEData->mOwner != this) { - // This nsWindow is not the owner of the instance of mIMEData, - // we should only clear reference to this. + // This nsWindow is not the owner of the instance of mIMEData. if (IMEComposingWindow() == this) CancelIMEComposition(); if (gIMEFocusWindow == this) gIMEFocusWindow = nsnull; + IMEReleaseData(); return; } /* NOTE: * This nsWindow is the owner of the instance of mIMEData, - * so, we must free the instance now. But that was referred from other - * nsWindows.(They are children of this.) But we don't need to worry about - * this issue. Because this function is only called on destroying this - * nsWindow. So, the children of this window should already be destroyed. + * so, we must release the contexts now. But that might be referred from + * other nsWindows.(They are children of this. But we don't know why there + * are the cases.) So, we need to clear the pointers that refers to contexts + * and this if the other referrers are still alive. See bug 349727. */ // If this is the focus window and we have an IM context we need @@ -4853,29 +4880,30 @@ nsWindow::IMEDestroyContext(void) gIMEFocusWindow = nsnull; } + mIMEData->mOwner = nsnull; + mIMEData->mEnabled = PR_FALSE; + if (mIMEData->mContext) { gtk_im_context_set_client_window(mIMEData->mContext, nsnull); g_object_unref(G_OBJECT(mIMEData->mContext)); + mIMEData->mContext = nsnull; } if (mIMEData->mDummyContext) { gtk_im_context_set_client_window(mIMEData->mDummyContext, nsnull); g_object_unref(G_OBJECT(mIMEData->mDummyContext)); + mIMEData->mDummyContext = nsnull; } - delete mIMEData; - mIMEData = nsnull; + IMEReleaseData(); } void nsWindow::IMESetFocus(void) { // Initialize mIMEData for this window - if (!mIMEData) { - nsWindow *win = IMEGetOwningWindow(); - if (win) - mIMEData = win->mIMEData; - } + if (!mIMEData) + IMEInitData(); LOGIM(("IMESetFocus %p\n", (void *)this)); GtkIMContext *im = IMEGetContext(); diff --git a/trunk/widget/src/gtk2/nsWindow.h b/trunk/widget/src/gtk2/nsWindow.h index 3505a811f73a2..1fe961b476e91 100644 --- a/trunk/widget/src/gtk2/nsWindow.h +++ b/trunk/widget/src/gtk2/nsWindow.h @@ -268,6 +268,8 @@ class nsWindow : public nsCommonWidget, public nsSupportsWeakReference static guint32 mLastButtonReleaseTime; #ifdef USE_XIM + void IMEInitData (void); + void IMEReleaseData (void); void IMEDestroyContext (void); void IMESetFocus (void); void IMELoseFocus (void); @@ -309,8 +311,11 @@ class nsWindow : public nsCommonWidget, public nsSupportsWeakReference // mComposingWindow to commit or reset the composition. nsWindow *mComposingWindow; // Owner of this struct. - // The owner window must free this instance at destroying. + // The owner window must release the contexts at destroying. nsWindow *mOwner; + // The reference counter. When this will be zero by the decrement, + // the decrementer must free the instance. + PRUint32 mRefCount; // IME enabled state in this window. PRPackedBool mEnabled; nsIMEData(nsWindow* aOwner) { @@ -318,6 +323,7 @@ class nsWindow : public nsCommonWidget, public nsSupportsWeakReference mDummyContext = nsnull; mComposingWindow = nsnull; mOwner = aOwner; + mRefCount = 1; mEnabled = PR_TRUE; } };