Bug 582893 IME isn't disabled when password fields on sheet dialog get focus r=smichaud, b2.0=final+

This commit is contained in:
Masayuki Nakano 2010-08-16 17:20:27 +09:00
Родитель 9e435b667a
Коммит f9c3117ab6
3 изменённых файлов: 108 добавлений и 18 удалений

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

@ -259,6 +259,10 @@ public:
static CFArrayRef CreateAllIMEModeList(); static CFArrayRef CreateAllIMEModeList();
static void DebugPrintAllIMEModes(PRLogModuleInfo* aLogModuleInfo); static void DebugPrintAllIMEModes(PRLogModuleInfo* aLogModuleInfo);
// Don't use ::TSMGetActiveDocument() API directly, the document may not
// be what you want.
static TSMDocumentID GetCurrentTSMDocumentID();
protected: protected:
// The owner of this instance. The result of mOwnerWidget->TextInputHandler // The owner of this instance. The result of mOwnerWidget->TextInputHandler
// returns this instance. This must not be null after initialized. // returns this instance. This must not be null after initialized.

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

@ -682,6 +682,17 @@ nsCocoaIMEHandler::DebugPrintAllIMEModes(PRLogModuleInfo* aLogModuleInfo)
::CFRelease(list); ::CFRelease(list);
} }
//static
TSMDocumentID
nsCocoaIMEHandler::GetCurrentTSMDocumentID()
{
// On OS X 10.6.x at least, ::TSMGetActiveDocument() has a bug that prevents
// it from returning accurate results unless
// [NSInputManager currentInputManager] is called first.
// So, we need to call [NSInputManager currentInputManager] first here.
[NSInputManager currentInputManager];
return ::TSMGetActiveDocument();
}
#pragma mark - #pragma mark -
@ -706,8 +717,8 @@ nsCocoaIMEHandler::ResetIMEWindowLevel()
#ifdef DEBUG_IME_HANDLER #ifdef DEBUG_IME_HANDLER
DebugPrintPointer(this); DebugPrintPointer(this);
NSLog(@"nsCocoaIMEHandler::ResetIMEWindowLevel"); NSLog(@"nsCocoaIMEHandler::ResetIMEWindowLevel");
NSLog(@" IsFocused:%s ::TSMGetActiveDocument():%p", NSLog(@" IsFocused:%s GetCurrentTSMDocumentID():%p",
TrueOrFalse(IsFocused()), ::TSMGetActiveDocument()); TrueOrFalse(IsFocused()), GetCurrentTSMDocumentID());
#endif // DEBUG_IME_HANDLER #endif // DEBUG_IME_HANDLER
if (!mView) if (!mView)
@ -719,7 +730,7 @@ nsCocoaIMEHandler::ResetIMEWindowLevel()
return; return;
} }
TSMDocumentID doc = ::TSMGetActiveDocument(); TSMDocumentID doc = GetCurrentTSMDocumentID();
if (!doc) { if (!doc) {
// retry // retry
mPendingMethods |= kResetIMEWindowLevel; mPendingMethods |= kResetIMEWindowLevel;
@ -752,7 +763,7 @@ nsCocoaIMEHandler::ResetIMEWindowLevel()
if (windowLevel == NSNormalWindowLevel) if (windowLevel == NSNormalWindowLevel)
windowLevel++; windowLevel++;
::TSMSetDocumentProperty(::TSMGetActiveDocument(), ::TSMSetDocumentProperty(GetCurrentTSMDocumentID(),
kTSMDocumentWindowLevelPropertyTag, kTSMDocumentWindowLevelPropertyTag,
sizeof(windowLevel), &windowLevel); sizeof(windowLevel), &windowLevel);
@ -803,8 +814,8 @@ nsCocoaIMEHandler::SyncASCIICapableOnly()
#ifdef DEBUG_IME_HANDLER #ifdef DEBUG_IME_HANDLER
DebugPrintPointer(this); DebugPrintPointer(this);
NSLog(@"nsCocoaIMEHandler::SyncASCIICapableOnly"); NSLog(@"nsCocoaIMEHandler::SyncASCIICapableOnly");
NSLog(@" IsFocused:%s ::TSMGetActiveDocument():%p", NSLog(@" IsFocused:%s GetCurrentTSMDocumentID():%p",
TrueOrFalse(IsFocused()), ::TSMGetActiveDocument()); TrueOrFalse(IsFocused()), GetCurrentTSMDocumentID());
#endif #endif
if (!mView) if (!mView)
@ -816,7 +827,7 @@ nsCocoaIMEHandler::SyncASCIICapableOnly()
return; return;
} }
TSMDocumentID doc = ::TSMGetActiveDocument(); TSMDocumentID doc = GetCurrentTSMDocumentID();
if (!doc) { if (!doc) {
// retry // retry
mPendingMethods |= kSyncASCIICapableOnly; mPendingMethods |= kSyncASCIICapableOnly;
@ -847,12 +858,9 @@ nsCocoaIMEHandler::ResetTimer()
"There are not pending methods, why this is called?"); "There are not pending methods, why this is called?");
if (mTimer) { if (mTimer) {
mTimer->Cancel(); mTimer->Cancel();
return; } else {
} mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID); NS_ENSURE_TRUE(mTimer, );
if (!mTimer) {
NS_ERROR("mTimer is null");
return;
} }
mTimer->InitWithFuncCallback(FlushPendingMethods, this, 0, mTimer->InitWithFuncCallback(FlushPendingMethods, this, 0,
nsITimer::TYPE_ONE_SHOT); nsITimer::TYPE_ONE_SHOT);
@ -863,6 +871,11 @@ nsCocoaIMEHandler::ExecutePendingMethods()
{ {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK; NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (mTimer) {
mTimer->Cancel();
mTimer = nsnull;
}
if (![[NSApplication sharedApplication] isActive]) { if (![[NSApplication sharedApplication] isActive]) {
mIsInFocusProcessing = PR_FALSE; mIsInFocusProcessing = PR_FALSE;
// If we're not active, we should retry at focus event // If we're not active, we should retry at focus event
@ -873,10 +886,6 @@ nsCocoaIMEHandler::ExecutePendingMethods()
// First, reset the pending method flags because if each methods cannot // First, reset the pending method flags because if each methods cannot
// run now, they can reentry to the pending flags by theirselves. // run now, they can reentry to the pending flags by theirselves.
mPendingMethods = 0; mPendingMethods = 0;
if (mTimer) {
mTimer->Cancel();
mTimer = nsnull;
}
if (pendingMethods & kDiscardIMEComposition) if (pendingMethods & kDiscardIMEComposition)
DiscardIMEComposition(); DiscardIMEComposition();
@ -1164,7 +1173,8 @@ nsCocoaIMEHandler::IsFocused()
NS_ENSURE_TRUE(mView, PR_FALSE); NS_ENSURE_TRUE(mView, PR_FALSE);
NSWindow* window = [mView window]; NSWindow* window = [mView window];
NS_ENSURE_TRUE(window, PR_FALSE); NS_ENSURE_TRUE(window, PR_FALSE);
return [window firstResponder] == mView && [window isMainWindow] && return [window firstResponder] == mView &&
([window isMainWindow] || [window isSheet]) &&
[[NSApplication sharedApplication] isActive]; [[NSApplication sharedApplication] isActive];
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE); NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);

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

@ -861,6 +861,79 @@ function runEditableSubframeTests()
"width=600,height=600"); "width=600,height=600");
} }
function runTestPasswordFieldOnDialog()
{
if (!kIMEEnabledSupported) {
return;
}
if (document.activeElement) {
document.activeElement.blur();
}
var dialog;
function WindowObserver()
{
Components.classes["@mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService).
addObserver(this, "domwindowopened", false);
}
WindowObserver.prototype = {
QueryInterface: function (iid)
{
if (iid.equals(Components.interfaces.nsIObserver) ||
iid.equals(Components.interfaces.nsISupports)) {
return this;
}
},
observe: function (subject, topic, data)
{
if (topic === "domwindowopened") {
ok(true, "dialog window is created");
dialog = subject.QueryInterface(Components.interfaces.nsIDOMWindow);
dialog.addEventListener("load", onPasswordDialogLoad, false);
}
}
};
var observer = new WindowObserver();
var arg1 = new Object(), arg2 = new Object();
Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
getService(Components.interfaces.nsIPromptService).
promptPassword(window, "title", "text", arg1, "msg", arg2);
ok(true, "password dialog was closed");
Components.classes["@mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService).
removeObserver(observer, "domwindowopened");
var passwordField;
function onPasswordDialogLoad()
{
ok(true, "onPasswordDialogLoad is called");
dialog.removeEventListener("load", onPasswordDialogLoad, false);
passwordField = dialog.document.getElementById("password1Textbox");
passwordField.addEventListener("focus", onPasswordFieldFocus, false);
}
function onPasswordFieldFocus()
{
ok(true, "onPasswordFieldFocus is called");
passwordField.removeEventListener("focus", onPasswordFieldFocus, false);
var utils = dialog.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
is(utils.IMEStatus, utils.IME_STATUS_PASSWORD,
"IME isn't disabled on a password field of password dialog");
synthesizeKey("VK_ESCAPE", { }, dialog);
}
}
function runTests() function runTests()
{ {
if (!kIMEEnabledSupported && !kIMEOpenSupported) if (!kIMEEnabledSupported && !kIMEOpenSupported)
@ -908,6 +981,9 @@ function runTests()
// test whether the IME state and composition are not changed unexpectedly // test whether the IME state and composition are not changed unexpectedly
runEditorFlagChangeTests(); runEditorFlagChangeTests();
// test password field on dialog
runTestPasswordFieldOnDialog();
runASyncTests(); runASyncTests();
} }