mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1143197 part.1 Use current IM context at handling key events rather than active IM context r=m_kato
This commit is contained in:
parent
41894967bf
commit
ab8308aa78
@ -21,6 +21,12 @@ using namespace mozilla::widget;
|
|||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
PRLogModuleInfo* gGtkIMLog = nullptr;
|
PRLogModuleInfo* gGtkIMLog = nullptr;
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
GetBoolName(bool aBool)
|
||||||
|
{
|
||||||
|
return aBool ? "true" : "false";
|
||||||
|
}
|
||||||
|
|
||||||
static const char*
|
static const char*
|
||||||
GetRangeTypeName(uint32_t aRangeType)
|
GetRangeTypeName(uint32_t aRangeType)
|
||||||
{
|
{
|
||||||
@ -56,6 +62,19 @@ GetEnabledStateName(uint32_t aState)
|
|||||||
return "UNKNOWN ENABLED STATUS!!";
|
return "UNKNOWN ENABLED STATUS!!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
GetEventType(GdkEventKey* aKeyEvent)
|
||||||
|
{
|
||||||
|
switch (aKeyEvent->type) {
|
||||||
|
case GDK_KEY_PRESS:
|
||||||
|
return "GDK_KEY_PRESS";
|
||||||
|
case GDK_KEY_RELEASE:
|
||||||
|
return "GDK_KEY_RELEASE";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const static bool kUseSimpleContextDefault = MOZ_WIDGET_GTK == 2;
|
const static bool kUseSimpleContextDefault = MOZ_WIDGET_GTK == 2;
|
||||||
@ -298,8 +317,9 @@ nsGtkIMModule::OnBlurWindow(nsWindow* aWindow)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||||
("GtkIMModule(%p): OnBlurWindow, aWindow=%p, mLastFocusedWindow=%p, mIsIMFocused=%s",
|
("GtkIMModule(%p): OnBlurWindow, aWindow=%p, mLastFocusedWindow=%p, "
|
||||||
this, aWindow, mLastFocusedWindow, mIsIMFocused ? "YES" : "NO"));
|
"mIsIMFocused=%s",
|
||||||
|
this, aWindow, mLastFocusedWindow, GetBoolName(mIsIMFocused)));
|
||||||
|
|
||||||
if (!mIsIMFocused || mLastFocusedWindow != aWindow) {
|
if (!mIsIMFocused || mLastFocusedWindow != aWindow) {
|
||||||
return;
|
return;
|
||||||
@ -320,13 +340,12 @@ nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||||
("GtkIMModule(%p): OnKeyEvent, aCaller=%p, aKeyDownEventWasSent=%s",
|
("GtkIMModule(%p): OnKeyEvent, aCaller=%p, aKeyDownEventWasSent=%s, "
|
||||||
this, aCaller, aKeyDownEventWasSent ? "TRUE" : "FALSE"));
|
"mCompositionState=%s, current context=%p, active context=%p, "
|
||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
"aEvent(%p): { type=%s, keyval=%s, unicode=0x%X }",
|
||||||
(" aEvent: type=%s, keyval=%s, unicode=0x%X",
|
this, aCaller, GetBoolName(aKeyDownEventWasSent),
|
||||||
aEvent->type == GDK_KEY_PRESS ? "GDK_KEY_PRESS" :
|
GetCompositionStateName(), GetCurrentContext(), GetActiveContext(),
|
||||||
aEvent->type == GDK_KEY_RELEASE ? "GDK_KEY_RELEASE" : "Unknown",
|
aEvent, GetEventType(aEvent), gdk_keyval_name(aEvent->keyval),
|
||||||
gdk_keyval_name(aEvent->keyval),
|
|
||||||
gdk_keyval_to_unicode(aEvent->keyval)));
|
gdk_keyval_to_unicode(aEvent->keyval)));
|
||||||
|
|
||||||
if (aCaller != mLastFocusedWindow) {
|
if (aCaller != mLastFocusedWindow) {
|
||||||
@ -336,8 +355,10 @@ nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkIMContext* activeContext = GetActiveContext();
|
// Even if old IM context has composition, key event should be sent to
|
||||||
if (MOZ_UNLIKELY(!activeContext)) {
|
// current context since the user expects so.
|
||||||
|
GtkIMContext* currentContext = GetCurrentContext();
|
||||||
|
if (MOZ_UNLIKELY(!currentContext)) {
|
||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||||
(" FAILED, there are no context"));
|
(" FAILED, there are no context"));
|
||||||
return false;
|
return false;
|
||||||
@ -347,7 +368,7 @@ nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent,
|
|||||||
mFilterKeyEvent = true;
|
mFilterKeyEvent = true;
|
||||||
mProcessingKeyEvent = aEvent;
|
mProcessingKeyEvent = aEvent;
|
||||||
gboolean isFiltered =
|
gboolean isFiltered =
|
||||||
gtk_im_context_filter_keypress(activeContext, aEvent);
|
gtk_im_context_filter_keypress(currentContext, aEvent);
|
||||||
mProcessingKeyEvent = nullptr;
|
mProcessingKeyEvent = nullptr;
|
||||||
|
|
||||||
// We filter the key event if the event was not committed (because
|
// We filter the key event if the event was not committed (because
|
||||||
@ -357,7 +378,7 @@ nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent,
|
|||||||
// composed characters.
|
// composed characters.
|
||||||
bool filterThisEvent = isFiltered && mFilterKeyEvent;
|
bool filterThisEvent = isFiltered && mFilterKeyEvent;
|
||||||
|
|
||||||
if (IsComposing() && !isFiltered) {
|
if (IsComposingOnCurrentContext() && !isFiltered) {
|
||||||
if (aEvent->type == GDK_KEY_PRESS) {
|
if (aEvent->type == GDK_KEY_PRESS) {
|
||||||
if (!mDispatchedCompositionString.IsEmpty()) {
|
if (!mDispatchedCompositionString.IsEmpty()) {
|
||||||
// If there is composition string, we shouldn't dispatch
|
// If there is composition string, we shouldn't dispatch
|
||||||
@ -371,7 +392,7 @@ nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent,
|
|||||||
// IM. For compromising this issue, we should dispatch
|
// IM. For compromising this issue, we should dispatch
|
||||||
// compositionend event, however, we don't need to reset IM
|
// compositionend event, however, we don't need to reset IM
|
||||||
// actually.
|
// actually.
|
||||||
DispatchCompositionCommitEvent(activeContext, &EmptyString());
|
DispatchCompositionCommitEvent(currentContext, &EmptyString());
|
||||||
filterThisEvent = false;
|
filterThisEvent = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -382,9 +403,10 @@ nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||||
(" filterThisEvent=%s (isFiltered=%s, mFilterKeyEvent=%s)",
|
(" filterThisEvent=%s (isFiltered=%s, mFilterKeyEvent=%s), "
|
||||||
filterThisEvent ? "TRUE" : "FALSE", isFiltered ? "YES" : "NO",
|
"mCompositionState=%s",
|
||||||
mFilterKeyEvent ? "YES" : "NO"));
|
GetBoolName(filterThisEvent), GetBoolName(isFiltered),
|
||||||
|
GetBoolName(mFilterKeyEvent), GetCompositionStateName()));
|
||||||
|
|
||||||
return filterThisEvent;
|
return filterThisEvent;
|
||||||
}
|
}
|
||||||
@ -395,8 +417,8 @@ nsGtkIMModule::OnFocusChangeInGecko(bool aFocus)
|
|||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||||
("GtkIMModule(%p): OnFocusChangeInGecko, aFocus=%s, "
|
("GtkIMModule(%p): OnFocusChangeInGecko, aFocus=%s, "
|
||||||
"mCompositionState=%s, mIsIMFocused=%s",
|
"mCompositionState=%s, mIsIMFocused=%s",
|
||||||
this, aFocus ? "YES" : "NO", GetCompositionStateName(),
|
this, GetBoolName(aFocus), GetCompositionStateName(),
|
||||||
mIsIMFocused ? "YES" : "NO"));
|
GetBoolName(mIsIMFocused)));
|
||||||
|
|
||||||
// We shouldn't carry over the removed string to another editor.
|
// We shouldn't carry over the removed string to another editor.
|
||||||
mSelectedString.Truncate();
|
mSelectedString.Truncate();
|
||||||
@ -407,7 +429,7 @@ nsGtkIMModule::ResetIME()
|
|||||||
{
|
{
|
||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||||
("GtkIMModule(%p): ResetIME, mCompositionState=%s, mIsIMFocused=%s",
|
("GtkIMModule(%p): ResetIME, mCompositionState=%s, mIsIMFocused=%s",
|
||||||
this, GetCompositionStateName(), mIsIMFocused ? "YES" : "NO"));
|
this, GetCompositionStateName(), GetBoolName(mIsIMFocused)));
|
||||||
|
|
||||||
GtkIMContext* activeContext = GetActiveContext();
|
GtkIMContext* activeContext = GetActiveContext();
|
||||||
if (MOZ_UNLIKELY(!activeContext)) {
|
if (MOZ_UNLIKELY(!activeContext)) {
|
||||||
@ -646,7 +668,7 @@ nsGtkIMModule::Blur()
|
|||||||
{
|
{
|
||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||||
("GtkIMModule(%p): Blur, mIsIMFocused=%s",
|
("GtkIMModule(%p): Blur, mIsIMFocused=%s",
|
||||||
this, mIsIMFocused ? "YES" : "NO"));
|
this, GetBoolName(mIsIMFocused)));
|
||||||
|
|
||||||
if (!mIsIMFocused) {
|
if (!mIsIMFocused) {
|
||||||
return;
|
return;
|
||||||
@ -889,11 +911,13 @@ nsGtkIMModule::OnCommitCompositionNative(GtkIMContext *aContext,
|
|||||||
|
|
||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||||
("GtkIMModule(%p): OnCommitCompositionNative, aContext=%p, "
|
("GtkIMModule(%p): OnCommitCompositionNative, aContext=%p, "
|
||||||
"current context=%p, commitString=\"%s\"",
|
"current context=%p, active context=%p, commitString=\"%s\", "
|
||||||
this, aContext, GetCurrentContext(), commitString));
|
"mProcessingKeyEvent=%p, IsComposingOn(aContext)=%s",
|
||||||
|
this, aContext, GetCurrentContext(), GetActiveContext(), commitString,
|
||||||
|
mProcessingKeyEvent, GetBoolName(IsComposingOn(aContext))));
|
||||||
|
|
||||||
// See bug 472635, we should do nothing if IM context doesn't match.
|
// See bug 472635, we should do nothing if IM context doesn't match.
|
||||||
if (GetCurrentContext() != aContext) {
|
if (!IsValidContext(aContext)) {
|
||||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||||
(" FAILED, given context doesn't match"));
|
(" FAILED, given context doesn't match"));
|
||||||
return;
|
return;
|
||||||
@ -904,14 +928,17 @@ nsGtkIMModule::OnCommitCompositionNative(GtkIMContext *aContext,
|
|||||||
// signal, we would dispatch compositionstart, text, compositionend
|
// signal, we would dispatch compositionstart, text, compositionend
|
||||||
// events with empty string. Of course, they are unnecessary events
|
// events with empty string. Of course, they are unnecessary events
|
||||||
// for Web applications and our editor.
|
// for Web applications and our editor.
|
||||||
if (!IsComposing() && !commitString[0]) {
|
if (!IsComposingOn(aContext) && !commitString[0]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If IME doesn't change their keyevent that generated this commit,
|
// If IME doesn't change their keyevent that generated this commit,
|
||||||
// don't send it through XIM - just send it as a normal key press
|
// don't send it through XIM - just send it as a normal key press
|
||||||
// event.
|
// event.
|
||||||
if (!IsComposing() && mProcessingKeyEvent) {
|
// NOTE: While a key event is being handled, this might be caused on
|
||||||
|
// current context. Otherwise, this may be caused on active context.
|
||||||
|
if (!IsComposingOn(aContext) && mProcessingKeyEvent &&
|
||||||
|
aContext == GetCurrentContext()) {
|
||||||
char keyval_utf8[8]; /* should have at least 6 bytes of space */
|
char keyval_utf8[8]; /* should have at least 6 bytes of space */
|
||||||
gint keyval_utf8_len;
|
gint keyval_utf8_len;
|
||||||
guint32 keyval_unicode;
|
guint32 keyval_unicode;
|
||||||
|
@ -132,11 +132,21 @@ protected:
|
|||||||
};
|
};
|
||||||
eCompositionState mCompositionState;
|
eCompositionState mCompositionState;
|
||||||
|
|
||||||
bool IsComposing()
|
bool IsComposing() const
|
||||||
{
|
{
|
||||||
return (mCompositionState != eCompositionState_NotComposing);
|
return (mCompositionState != eCompositionState_NotComposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsComposingOn(GtkIMContext* aContext) const
|
||||||
|
{
|
||||||
|
return IsComposing() && mComposingContext == aContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsComposingOnCurrentContext() const
|
||||||
|
{
|
||||||
|
return IsComposingOn(GetCurrentContext());
|
||||||
|
}
|
||||||
|
|
||||||
bool EditorHasCompositionString()
|
bool EditorHasCompositionString()
|
||||||
{
|
{
|
||||||
return (mCompositionState ==
|
return (mCompositionState ==
|
||||||
|
Loading…
Reference in New Issue
Block a user