Bug 337036 Crashes in IM_get_owning_window r=katakai, sr=roc

This commit is contained in:
masayuki%d-toybox.com 2006-05-12 08:46:54 +00:00
Родитель 5292695a2a
Коммит 6670030b01
2 изменённых файлов: 58 добавлений и 46 удалений

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

@ -256,7 +256,7 @@ static void IM_set_text_range (const PRInt32 aLen,
static nsWindow *IM_get_owning_window(MozDrawingarea *aArea);
static GtkIMContext *IM_get_input_context(MozDrawingarea *aArea);
static GtkIMContext *IM_get_input_context(nsWindow *window);
// If after selecting profile window, the startup fail, please refer to
// http://bugzilla.gnome.org/show_bug.cgi?id=88940
@ -745,8 +745,8 @@ nsWindow::SetFocus(PRBool aRaise)
// If the focus window and this window share the same input
// context we don't have to change the focus of the IME
// context
if (IM_get_input_context(this->mDrawingarea) !=
IM_get_input_context(gFocusWindow->mDrawingarea))
if (IM_get_input_context(this) !=
IM_get_input_context(gFocusWindow))
gFocusWindow->IMELoseFocus();
#endif
gFocusWindow->LoseFocus();
@ -4777,8 +4777,9 @@ nsChildWindow::~nsChildWindow()
void
nsWindow::IMEDestroyContext(void)
{
if (!mIMEData) {
// Clear reference to this.
if (!mIMEData || mIMEData->mOwner != this) {
// This nsWindow is not the owner of the instance of mIMEData,
// we should only clear reference to this.
if (IMEComposingWindow() == this)
CancelIMEComposition();
if (gIMEFocusWindow == this)
@ -4786,6 +4787,14 @@ nsWindow::IMEDestroyContext(void)
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.
*/
// 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.
GtkIMContext *im = IMEGetContext();
@ -4811,6 +4820,13 @@ nsWindow::IMEDestroyContext(void)
void
nsWindow::IMESetFocus(void)
{
// Initialize mIMEData for this window
if (!mIMEData) {
nsWindow *win = IMEGetOwningWindow();
if (win)
mIMEData = win->mIMEData;
}
LOGIM(("IMESetFocus %p\n", (void *)this));
GtkIMContext *im = IMEGetContext();
if (!im)
@ -4842,17 +4858,17 @@ nsWindow::IMEComposeStart(void)
{
LOGIM(("IMEComposeStart [%p]\n", (void *)this));
if (!mIMEData) {
NS_ERROR("This widget doesn't support IM");
return;
}
if (IMEComposingWindow()) {
NS_WARNING("tried to re-start text composition\n");
return;
}
nsWindow *win = IMEGetOwningWindow();
if (win) {
nsIMEData *data = win->mIMEData;
if (data)
data->mComposingWindow = this;
}
mIMEData->mComposingWindow = this;
nsCompositionEvent compEvent(PR_TRUE, NS_COMPOSITION_START, this);
@ -4882,6 +4898,11 @@ nsWindow::IMEComposeText (const PRUnichar *aText,
const gint aCursorPos,
const PangoAttrList *aFeedback)
{
if (!mIMEData) {
NS_ERROR("This widget doesn't support IM");
return;
}
// Send our start composition event if we need to
if (!IMEComposingWindow())
IMEComposeStart();
@ -4926,18 +4947,14 @@ void
nsWindow::IMEComposeEnd(void)
{
LOGIM(("IMEComposeEnd [%p]\n", (void *)this));
NS_ASSERTION(mIMEData, "This widget doesn't support IM");
if (!IMEComposingWindow()) {
NS_WARNING("tried to end text composition before it was started");
return;
}
nsWindow *win = IMEGetOwningWindow();
if (win) {
nsIMEData *data = win->mIMEData;
if (data)
data->mComposingWindow = nsnull;
}
mIMEData->mComposingWindow = nsnull;
nsCompositionEvent compEvent(PR_TRUE, NS_COMPOSITION_END, this);
@ -4948,25 +4965,19 @@ nsWindow::IMEComposeEnd(void)
GtkIMContext*
nsWindow::IMEGetContext()
{
return IM_get_input_context(this->mDrawingarea);
return IM_get_input_context(this);
}
PRBool
nsWindow::IMEIsEnabled(void)
{
nsWindow *win = IMEGetOwningWindow();
if (!win)
return PR_FALSE;
return win->mIMEData ? win->mIMEData->mEnabled : PR_FALSE;
return mIMEData ? mIMEData->mEnabled : PR_FALSE;
}
nsWindow*
nsWindow::IMEComposingWindow(void)
{
nsWindow *win = IMEGetOwningWindow();
if (!win)
return nsnull;
return win->mIMEData ? win->mIMEData->mComposingWindow : nsnull;
return mIMEData ? mIMEData->mComposingWindow : nsnull;
}
nsWindow*
@ -4979,7 +4990,7 @@ nsWindow::IMEGetOwningWindow(void)
void
nsWindow::IMECreateContext(void)
{
mIMEData = new nsIMEData;
mIMEData = new nsIMEData(this);
if (!mIMEData)
return;
@ -5080,35 +5091,31 @@ nsWindow::GetIMEOpenState(PRBool* aState)
NS_IMETHODIMP
nsWindow::SetIMEEnabled(PRBool aState)
{
nsWindow *window = IMEGetOwningWindow();
if (!window || !window->mIMEData || window->mIMEData->mEnabled == aState)
if (!mIMEData || mIMEData->mEnabled == aState)
return NS_OK;
GtkIMContext *focusedIm = nsnull;
// XXX Don't we need to check gFocusWindow?
nsWindow *focusedWin = gIMEFocusWindow;
if (focusedWin) {
nsWindow *owningWin = focusedWin->IMEGetOwningWindow();
if (owningWin && owningWin->mIMEData)
focusedIm = owningWin->mIMEData->mContext;
}
if (focusedWin && focusedWin->mIMEData)
focusedIm = focusedWin->mIMEData->mContext;
if (focusedIm && focusedIm == window->mIMEData->mContext) {
if (focusedIm && focusedIm == mIMEData->mContext) {
// Release current IME focus if IME is enabled.
if (window->mIMEData->mEnabled) {
if (mIMEData->mEnabled) {
focusedWin->ResetInputState();
focusedWin->IMELoseFocus();
}
window->mIMEData->mEnabled = aState;
mIMEData->mEnabled = aState;
// Even when aState is not PR_TRUE, we need to set IME focus.
// Because some IMs are updating the status bar of them in this time.
focusedWin->IMESetFocus();
} else {
if (window->mIMEData->mEnabled)
if (mIMEData->mEnabled)
ResetInputState();
window->mIMEData->mEnabled = aState;
mIMEData->mEnabled = aState;
}
return NS_OK;
@ -5404,11 +5411,11 @@ IM_get_owning_window(MozDrawingarea *aArea)
/* static */
GtkIMContext *
IM_get_input_context(MozDrawingarea *aArea)
IM_get_input_context(nsWindow *aWindow)
{
if (!aArea)
if (!aWindow)
return nsnull;
nsWindow::nsIMEData *data = IM_get_owning_window(aArea)->mIMEData;
nsWindow::nsIMEData *data = aWindow->mIMEData;
if (!data)
return nsnull;
return data->mEnabled ? data->mContext : data->mDummyContext;

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

@ -287,9 +287,10 @@ public:
/*
* |mIMEData| has all IME data for the window and its children widgets.
* So, this is created only on owner widget. Therefore, when the
* focused widget needs the data, it get from its owning window.
* See |IM_get_input_context|.
* Only stand-alone windows and child windows embedded in non-Mozilla GTK
* containers own IME contexts.
* But this is referred from all children after the widget gets focus.
* The children refers to its owning window's object.
*/
struct nsIMEData {
// Actual context. This is used for handling the user's input.
@ -307,12 +308,16 @@ public:
// changing input focus, we will use the original widget of
// mComposingWindow to commit or reset the composition.
nsWindow *mComposingWindow;
// Owner of this struct.
// The owner window must free this instance at destroying.
nsWindow *mOwner;
// IME enabled state in this window.
PRPackedBool mEnabled;
nsIMEData() {
nsIMEData(nsWindow* aOwner) {
mContext = nsnull;
mDummyContext = nsnull;
mComposingWindow = nsnull;
mOwner = aOwner;
mEnabled = PR_TRUE;
}
};