зеркало из https://github.com/mozilla/gecko-dev.git
Bug 337036 Crashes in IM_get_owning_window r=katakai, sr=roc
This commit is contained in:
Родитель
278c093be5
Коммит
b4ba4f607e
|
@ -256,7 +256,7 @@ static void IM_set_text_range (const PRInt32 aLen,
|
||||||
|
|
||||||
static nsWindow *IM_get_owning_window(MozDrawingarea *aArea);
|
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
|
// If after selecting profile window, the startup fail, please refer to
|
||||||
// http://bugzilla.gnome.org/show_bug.cgi?id=88940
|
// 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
|
// If the focus window and this window share the same input
|
||||||
// context we don't have to change the focus of the IME
|
// context we don't have to change the focus of the IME
|
||||||
// context
|
// context
|
||||||
if (IM_get_input_context(this->mDrawingarea) !=
|
if (IM_get_input_context(this) !=
|
||||||
IM_get_input_context(gFocusWindow->mDrawingarea))
|
IM_get_input_context(gFocusWindow))
|
||||||
gFocusWindow->IMELoseFocus();
|
gFocusWindow->IMELoseFocus();
|
||||||
#endif
|
#endif
|
||||||
gFocusWindow->LoseFocus();
|
gFocusWindow->LoseFocus();
|
||||||
|
@ -4777,8 +4777,9 @@ nsChildWindow::~nsChildWindow()
|
||||||
void
|
void
|
||||||
nsWindow::IMEDestroyContext(void)
|
nsWindow::IMEDestroyContext(void)
|
||||||
{
|
{
|
||||||
if (!mIMEData) {
|
if (!mIMEData || mIMEData->mOwner != this) {
|
||||||
// Clear reference to this.
|
// This nsWindow is not the owner of the instance of mIMEData,
|
||||||
|
// we should only clear reference to this.
|
||||||
if (IMEComposingWindow() == this)
|
if (IMEComposingWindow() == this)
|
||||||
CancelIMEComposition();
|
CancelIMEComposition();
|
||||||
if (gIMEFocusWindow == this)
|
if (gIMEFocusWindow == this)
|
||||||
|
@ -4786,6 +4787,14 @@ nsWindow::IMEDestroyContext(void)
|
||||||
return;
|
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
|
// 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.
|
// to unset the focus on this window before we destroy the window.
|
||||||
GtkIMContext *im = IMEGetContext();
|
GtkIMContext *im = IMEGetContext();
|
||||||
|
@ -4811,6 +4820,13 @@ nsWindow::IMEDestroyContext(void)
|
||||||
void
|
void
|
||||||
nsWindow::IMESetFocus(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));
|
LOGIM(("IMESetFocus %p\n", (void *)this));
|
||||||
GtkIMContext *im = IMEGetContext();
|
GtkIMContext *im = IMEGetContext();
|
||||||
if (!im)
|
if (!im)
|
||||||
|
@ -4842,17 +4858,17 @@ nsWindow::IMEComposeStart(void)
|
||||||
{
|
{
|
||||||
LOGIM(("IMEComposeStart [%p]\n", (void *)this));
|
LOGIM(("IMEComposeStart [%p]\n", (void *)this));
|
||||||
|
|
||||||
|
if (!mIMEData) {
|
||||||
|
NS_ERROR("This widget doesn't support IM");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (IMEComposingWindow()) {
|
if (IMEComposingWindow()) {
|
||||||
NS_WARNING("tried to re-start text composition\n");
|
NS_WARNING("tried to re-start text composition\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsWindow *win = IMEGetOwningWindow();
|
mIMEData->mComposingWindow = this;
|
||||||
if (win) {
|
|
||||||
nsIMEData *data = win->mIMEData;
|
|
||||||
if (data)
|
|
||||||
data->mComposingWindow = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCompositionEvent compEvent(PR_TRUE, NS_COMPOSITION_START, this);
|
nsCompositionEvent compEvent(PR_TRUE, NS_COMPOSITION_START, this);
|
||||||
|
|
||||||
|
@ -4882,6 +4898,11 @@ nsWindow::IMEComposeText (const PRUnichar *aText,
|
||||||
const gint aCursorPos,
|
const gint aCursorPos,
|
||||||
const PangoAttrList *aFeedback)
|
const PangoAttrList *aFeedback)
|
||||||
{
|
{
|
||||||
|
if (!mIMEData) {
|
||||||
|
NS_ERROR("This widget doesn't support IM");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Send our start composition event if we need to
|
// Send our start composition event if we need to
|
||||||
if (!IMEComposingWindow())
|
if (!IMEComposingWindow())
|
||||||
IMEComposeStart();
|
IMEComposeStart();
|
||||||
|
@ -4926,18 +4947,14 @@ void
|
||||||
nsWindow::IMEComposeEnd(void)
|
nsWindow::IMEComposeEnd(void)
|
||||||
{
|
{
|
||||||
LOGIM(("IMEComposeEnd [%p]\n", (void *)this));
|
LOGIM(("IMEComposeEnd [%p]\n", (void *)this));
|
||||||
|
NS_ASSERTION(mIMEData, "This widget doesn't support IM");
|
||||||
|
|
||||||
if (!IMEComposingWindow()) {
|
if (!IMEComposingWindow()) {
|
||||||
NS_WARNING("tried to end text composition before it was started");
|
NS_WARNING("tried to end text composition before it was started");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsWindow *win = IMEGetOwningWindow();
|
mIMEData->mComposingWindow = nsnull;
|
||||||
if (win) {
|
|
||||||
nsIMEData *data = win->mIMEData;
|
|
||||||
if (data)
|
|
||||||
data->mComposingWindow = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCompositionEvent compEvent(PR_TRUE, NS_COMPOSITION_END, this);
|
nsCompositionEvent compEvent(PR_TRUE, NS_COMPOSITION_END, this);
|
||||||
|
|
||||||
|
@ -4948,25 +4965,19 @@ nsWindow::IMEComposeEnd(void)
|
||||||
GtkIMContext*
|
GtkIMContext*
|
||||||
nsWindow::IMEGetContext()
|
nsWindow::IMEGetContext()
|
||||||
{
|
{
|
||||||
return IM_get_input_context(this->mDrawingarea);
|
return IM_get_input_context(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsWindow::IMEIsEnabled(void)
|
nsWindow::IMEIsEnabled(void)
|
||||||
{
|
{
|
||||||
nsWindow *win = IMEGetOwningWindow();
|
return mIMEData ? mIMEData->mEnabled : PR_FALSE;
|
||||||
if (!win)
|
|
||||||
return PR_FALSE;
|
|
||||||
return win->mIMEData ? win->mIMEData->mEnabled : PR_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsWindow*
|
nsWindow*
|
||||||
nsWindow::IMEComposingWindow(void)
|
nsWindow::IMEComposingWindow(void)
|
||||||
{
|
{
|
||||||
nsWindow *win = IMEGetOwningWindow();
|
return mIMEData ? mIMEData->mComposingWindow : nsnull;
|
||||||
if (!win)
|
|
||||||
return nsnull;
|
|
||||||
return win->mIMEData ? win->mIMEData->mComposingWindow : nsnull;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsWindow*
|
nsWindow*
|
||||||
|
@ -4979,7 +4990,7 @@ nsWindow::IMEGetOwningWindow(void)
|
||||||
void
|
void
|
||||||
nsWindow::IMECreateContext(void)
|
nsWindow::IMECreateContext(void)
|
||||||
{
|
{
|
||||||
mIMEData = new nsIMEData;
|
mIMEData = new nsIMEData(this);
|
||||||
if (!mIMEData)
|
if (!mIMEData)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -5080,35 +5091,31 @@ nsWindow::GetIMEOpenState(PRBool* aState)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsWindow::SetIMEEnabled(PRBool aState)
|
nsWindow::SetIMEEnabled(PRBool aState)
|
||||||
{
|
{
|
||||||
nsWindow *window = IMEGetOwningWindow();
|
if (!mIMEData || mIMEData->mEnabled == aState)
|
||||||
if (!window || !window->mIMEData || window->mIMEData->mEnabled == aState)
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
GtkIMContext *focusedIm = nsnull;
|
GtkIMContext *focusedIm = nsnull;
|
||||||
// XXX Don't we need to check gFocusWindow?
|
// XXX Don't we need to check gFocusWindow?
|
||||||
nsWindow *focusedWin = gIMEFocusWindow;
|
nsWindow *focusedWin = gIMEFocusWindow;
|
||||||
if (focusedWin) {
|
if (focusedWin && focusedWin->mIMEData)
|
||||||
nsWindow *owningWin = focusedWin->IMEGetOwningWindow();
|
focusedIm = focusedWin->mIMEData->mContext;
|
||||||
if (owningWin && owningWin->mIMEData)
|
|
||||||
focusedIm = owningWin->mIMEData->mContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (focusedIm && focusedIm == window->mIMEData->mContext) {
|
if (focusedIm && focusedIm == mIMEData->mContext) {
|
||||||
// Release current IME focus if IME is enabled.
|
// Release current IME focus if IME is enabled.
|
||||||
if (window->mIMEData->mEnabled) {
|
if (mIMEData->mEnabled) {
|
||||||
focusedWin->ResetInputState();
|
focusedWin->ResetInputState();
|
||||||
focusedWin->IMELoseFocus();
|
focusedWin->IMELoseFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
window->mIMEData->mEnabled = aState;
|
mIMEData->mEnabled = aState;
|
||||||
|
|
||||||
// Even when aState is not PR_TRUE, we need to set IME focus.
|
// 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.
|
// Because some IMs are updating the status bar of them in this time.
|
||||||
focusedWin->IMESetFocus();
|
focusedWin->IMESetFocus();
|
||||||
} else {
|
} else {
|
||||||
if (window->mIMEData->mEnabled)
|
if (mIMEData->mEnabled)
|
||||||
ResetInputState();
|
ResetInputState();
|
||||||
window->mIMEData->mEnabled = aState;
|
mIMEData->mEnabled = aState;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -5404,11 +5411,11 @@ IM_get_owning_window(MozDrawingarea *aArea)
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
GtkIMContext *
|
GtkIMContext *
|
||||||
IM_get_input_context(MozDrawingarea *aArea)
|
IM_get_input_context(nsWindow *aWindow)
|
||||||
{
|
{
|
||||||
if (!aArea)
|
if (!aWindow)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
nsWindow::nsIMEData *data = IM_get_owning_window(aArea)->mIMEData;
|
nsWindow::nsIMEData *data = aWindow->mIMEData;
|
||||||
if (!data)
|
if (!data)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
return data->mEnabled ? data->mContext : data->mDummyContext;
|
return data->mEnabled ? data->mContext : data->mDummyContext;
|
||||||
|
|
|
@ -287,9 +287,10 @@ public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* |mIMEData| has all IME data for the window and its children widgets.
|
* |mIMEData| has all IME data for the window and its children widgets.
|
||||||
* So, this is created only on owner widget. Therefore, when the
|
* Only stand-alone windows and child windows embedded in non-Mozilla GTK
|
||||||
* focused widget needs the data, it get from its owning window.
|
* containers own IME contexts.
|
||||||
* See |IM_get_input_context|.
|
* But this is referred from all children after the widget gets focus.
|
||||||
|
* The children refers to its owning window's object.
|
||||||
*/
|
*/
|
||||||
struct nsIMEData {
|
struct nsIMEData {
|
||||||
// Actual context. This is used for handling the user's input.
|
// 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
|
// changing input focus, we will use the original widget of
|
||||||
// mComposingWindow to commit or reset the composition.
|
// mComposingWindow to commit or reset the composition.
|
||||||
nsWindow *mComposingWindow;
|
nsWindow *mComposingWindow;
|
||||||
|
// Owner of this struct.
|
||||||
|
// The owner window must free this instance at destroying.
|
||||||
|
nsWindow *mOwner;
|
||||||
// IME enabled state in this window.
|
// IME enabled state in this window.
|
||||||
PRPackedBool mEnabled;
|
PRPackedBool mEnabled;
|
||||||
nsIMEData() {
|
nsIMEData(nsWindow* aOwner) {
|
||||||
mContext = nsnull;
|
mContext = nsnull;
|
||||||
mDummyContext = nsnull;
|
mDummyContext = nsnull;
|
||||||
mComposingWindow = nsnull;
|
mComposingWindow = nsnull;
|
||||||
|
mOwner = aOwner;
|
||||||
mEnabled = PR_TRUE;
|
mEnabled = PR_TRUE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче