Bug 875674 part.8 Notify IME of focus change in Gecko for resetting IME stored window level r=smichaud

This commit is contained in:
Masayuki Nakano 2013-07-11 16:46:36 +09:00
Родитель 1aa2e2af61
Коммит 941229d8ad
2 изменённых файлов: 28 добавлений и 37 удалений

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

@ -955,9 +955,9 @@ protected:
// See the comment in nsCocoaTextInputHandler.mm. // See the comment in nsCocoaTextInputHandler.mm.
nsCOMPtr<nsITimer> mTimer; nsCOMPtr<nsITimer> mTimer;
enum { enum {
kResetIMEWindowLevel = 1, kNotifyIMEOfFocusChangeInGecko = 1,
kDiscardIMEComposition = 2, kDiscardIMEComposition = 2,
kSyncASCIICapableOnly = 4 kSyncASCIICapableOnly = 4
}; };
uint32_t mPendingMethods; uint32_t mPendingMethods;
@ -1006,7 +1006,7 @@ private:
void OpenSystemPreferredLanguageIME(); void OpenSystemPreferredLanguageIME();
// Pending methods // Pending methods
void ResetIMEWindowLevel(); void NotifyIMEOfFocusChangeInGecko();
void DiscardIMEComposition(); void DiscardIMEComposition();
void SyncASCIICapableOnly(); void SyncASCIICapableOnly();

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

@ -2289,15 +2289,15 @@ IMEInputHandler::GetCurrentTSMDocumentID()
******************************************************************************/ ******************************************************************************/
void void
IMEInputHandler::ResetIMEWindowLevel() IMEInputHandler::NotifyIMEOfFocusChangeInGecko()
{ {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK; NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
PR_LOG(gLog, PR_LOG_ALWAYS, PR_LOG(gLog, PR_LOG_ALWAYS,
("%p IMEInputHandler::ResetIMEWindowLevel, " ("%p IMEInputHandler::NotifyIMEOfFocusChangeInGecko, "
"Destroyed()=%s, IsFocused()=%s, GetCurrentTSMDocumentID()=%p", "Destroyed()=%s, IsFocused()=%s, inputContext=%p",
this, TrueOrFalse(Destroyed()), TrueOrFalse(IsFocused()), this, TrueOrFalse(Destroyed()), TrueOrFalse(IsFocused()),
GetCurrentTSMDocumentID())); mView ? [mView inputContext] : nullptr));
if (Destroyed()) { if (Destroyed()) {
return; return;
@ -2305,32 +2305,24 @@ IMEInputHandler::ResetIMEWindowLevel()
if (!IsFocused()) { if (!IsFocused()) {
// retry at next focus event // retry at next focus event
mPendingMethods |= kResetIMEWindowLevel; mPendingMethods |= kNotifyIMEOfFocusChangeInGecko;
return; return;
} }
TSMDocumentID doc = GetCurrentTSMDocumentID(); MOZ_ASSERT(mView);
if (!doc) { NSTextInputContext* inputContext = [mView inputContext];
// retry NS_ENSURE_TRUE_VOID(inputContext);
mPendingMethods |= kResetIMEWindowLevel;
NS_WARNING("Application is active but there is no active document");
ResetTimer();
return;
}
// We need to set the focused window level to TSMDocument. Then, the popup // When an <input> element on a XUL <panel> element gets focus from an <input>
// windows of IME (E.g., a candidate list window) will be over the focused // element on the opener window of the <panel> element, the owner window
// view. See http://developer.apple.com/technotes/tn2005/tn2128.html#TNTAG1 // still has native focus. Therefore, IMEs may store the opener window's
NSInteger windowLevel = GetWindowLevel(); // level at this time because they don't know the actual focus is moved to
// different window. If IMEs try to get the newest window level after the
// Chinese IMEs on 10.5 don't work fine if the level is NSNormalWindowLevel, // focus change, we return the window level of the XUL <panel>'s widget.
// then, we need to increment the value. // Therefore, let's emulate the native focus change. Then, IMEs can refresh
if (windowLevel == NSNormalWindowLevel) // the stored window level.
windowLevel++; [inputContext deactivate];
[inputContext activate];
::TSMSetDocumentProperty(GetCurrentTSMDocumentID(),
kTSMDocumentWindowLevelPropertyTag,
sizeof(windowLevel), &windowLevel);
NS_OBJC_END_TRY_ABORT_BLOCK; NS_OBJC_END_TRY_ABORT_BLOCK;
} }
@ -2458,8 +2450,9 @@ IMEInputHandler::ExecutePendingMethods()
DiscardIMEComposition(); DiscardIMEComposition();
if (pendingMethods & kSyncASCIICapableOnly) if (pendingMethods & kSyncASCIICapableOnly)
SyncASCIICapableOnly(); SyncASCIICapableOnly();
if (pendingMethods & kResetIMEWindowLevel) if (pendingMethods & kNotifyIMEOfFocusChangeInGecko) {
ResetIMEWindowLevel(); NotifyIMEOfFocusChangeInGecko();
}
mIsInFocusProcessing = false; mIsInFocusProcessing = false;
@ -3191,11 +3184,9 @@ IMEInputHandler::OnFocusChangeInGecko(bool aFocus)
sFocusedIMEHandler = this; sFocusedIMEHandler = this;
mIsInFocusProcessing = true; mIsInFocusProcessing = true;
// We need to reset the IME's window level by the current focused view of // We need to notify IME of focus change in Gecko as native focus change
// Gecko. It may be different from mView. However, we cannot get the // because the window level of the focused element in Gecko may be changed.
// new focused view here because the focus change process in Gecko hasn't mPendingMethods |= kNotifyIMEOfFocusChangeInGecko;
// been finished yet. So, we should post the job to the todo list.
mPendingMethods |= kResetIMEWindowLevel;
ResetTimer(); ResetTimer();
} }