Bug 55751 Mnemonic doesn't work when IME is on / Bug 113187 Cannot use shortcut of single key(e.g., space key, "/", "'", "F", "N", "B", "P" and "T") if IME is active r+sr=roc

This commit is contained in:
masayuki%d-toybox.com 2005-11-14 23:55:24 +00:00
Родитель 8a4bb05d0c
Коммит 7061e4aebb
11 изменённых файлов: 193 добавлений и 68 удалений

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

@ -65,8 +65,8 @@ class nsAttrValue;
// IID for the nsIContent interface
#define NS_ICONTENT_IID \
{ 0x08b87f67, 0x2f64, 0x437b, \
{ 0x93, 0x35, 0x02, 0x60, 0x17, 0x5c, 0x0e, 0xc2 } }
{ 0x6a654488, 0xcbb3, 0x49d4, \
{ 0xad, 0x2d, 0x68, 0x4b, 0xad, 0xd5, 0xa7, 0x5d } }
/**
* A node of content in a document's content model. This interface
@ -563,6 +563,38 @@ public:
return PR_FALSE;
}
/*
* Get desired IME state for the content.
*
* @return The desired IME status for the content.
* This is a combination of IME_STATUS_* flags,
* controlling what happens to IME when the content takes focus.
* If this is IME_STATUS_NONE, IME remains in its current state.
* IME_STATUS_ENABLE and IME_STATUS_DISABLE must not be set
* together; likewise IME_STATUS_OPEN and IME_STATUS_CLOSE must
* not be set together.
* If you return IME_STATUS_DISABLE, you should not set the
* OPEN or CLOSE flag; that way, when IME is next enabled,
* the previous OPEN/CLOSE state will be restored (unless the newly
* focused content specifies the OPEN/CLOSE state by setting the OPEN
* or CLOSE flag with the ENABLE flag).
*/
enum {
IME_STATUS_NONE = 0x0000,
IME_STATUS_ENABLE = 0x0001,
IME_STATUS_DISABLE = 0x0002,
IME_STATUS_OPEN = 0x0004,
IME_STATUS_CLOSE = 0x0008
};
enum {
IME_STATUS_MASK_ENABLED = IME_STATUS_ENABLE | IME_STATUS_DISABLE,
IME_STATUS_MASK_OPENED = IME_STATUS_OPEN | IME_STATUS_CLOSE
};
virtual PRUint32 GetDesiredIMEState()
{
return IME_STATUS_DISABLE;
}
/**
* Gets content node with the binding responsible for our construction (and
* existence). Used by anonymous content (XBL-generated). null for all

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

@ -24,6 +24,7 @@
* Makoto Kato <m_kato@ga2.so-net.ne.jp>
* Dean Tessman <dean_tessman@hotmail.com>
* Mats Palmgren <mats.palmgren@bredband.net>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -47,6 +48,7 @@
#include "nsIDocument.h"
#include "nsIFrame.h"
#include "nsIWidget.h"
#include "nsIKBStateControl.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsDOMEvent.h"
@ -646,15 +648,18 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
// "leak" this reference, but we take it back later
SetFocusedContent(nsnull);
UpdateIMEState(aPresContext, currentFocus);
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent focusevent(PR_TRUE, NS_FOCUS_CONTENT);
if (gLastFocusedDocument != mDocument) {
mDocument->HandleDOMEvent(aPresContext, &focusevent, nsnull,
NS_EVENT_FLAG_INIT, &status);
if (currentFocus && currentFocus != gLastFocusedContent)
if (currentFocus && currentFocus != gLastFocusedContent) {
currentFocus->HandleDOMEvent(aPresContext, &focusevent, nsnull,
NS_EVENT_FLAG_INIT, &status);
}
}
globalObject->HandleDOMEvent(aPresContext, &focusevent, nsnull,
@ -3870,6 +3875,7 @@ nsEventStateManager::SetContentState(nsIContent *aContent, PRInt32 aState)
}
notifyContent[2] = gLastFocusedContent;
NS_IF_ADDREF(gLastFocusedContent);
UpdateIMEState(mPresContext, aContent);
// only raise window if the the focus controller is active
SendFocusBlur(mPresContext, aContent, fcActive);
if (mCurrentFocus != aContent) {
@ -4412,7 +4418,7 @@ nsEventStateManager::ContentRemoved(nsIContent* aContent)
// Note that we don't use SetContentState() here because
// we don't want to fire a blur. Blurs should only be fired
// in response to clicks or tabbing.
UpdateIMEState(mPresContext, nsnull);
SetFocusedContent(nsnull);
}
@ -5478,3 +5484,78 @@ nsEventStateManager::GetFocusControllerForDocument(nsIDocument* aDocument)
return windowPrivate ? windowPrivate->GetRootFocusController() : nsnull;
}
void
nsEventStateManager::UpdateIMEState(nsPresContext* aPresContext,
nsIContent* aContent)
{
if (!aPresContext)
return;
// On Printing or Print Preview, we don't need IME.
if (aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
aPresContext->Type() == nsPresContext::eContext_Print) {
SetIMEState(aPresContext, nsIContent::IME_STATUS_DISABLE);
return;
}
PRUint32 state = nsIContent::IME_STATUS_DISABLE;
PRBool isEditable = PR_FALSE;
nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
nsCOMPtr<nsIEditorDocShell> editorDocShell(do_QueryInterface(container));
if (editorDocShell)
editorDocShell->GetEditable(&isEditable);
if (isEditable)
state = nsIContent::IME_STATUS_ENABLE;
else if (aContent)
state = aContent->GetDesiredIMEState();
if (state == nsIContent::IME_STATUS_NONE)
return;
SetIMEState(aPresContext, state);
}
void
nsEventStateManager::SetIMEState(nsPresContext* aPresContext,
PRUint32 aState)
{
if (!aPresContext)
return;
nsCOMPtr<nsIKBStateControl> kb;
nsresult rv = GetKBStateControl(aPresContext, getter_AddRefs(kb));
if (NS_FAILED(rv) || !kb)
return;
if (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
PRBool enable = (aState & nsIContent::IME_STATUS_ENABLE);
kb->SetIMEEnabled(enable);
}
if (aState & nsIContent::IME_STATUS_MASK_OPENED) {
PRBool open = (aState & nsIContent::IME_STATUS_OPEN);
kb->SetIMEOpenState(open);
}
}
nsresult
nsEventStateManager::GetKBStateControl(nsPresContext* aPresContext,
nsIKBStateControl** aResult)
{
NS_ENSURE_ARG_POINTER(aPresContext);
NS_ENSURE_ARG_POINTER(aResult);
*aResult = nsnull;
nsIViewManager* vm = aPresContext->GetViewManager();
NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE);
nsCOMPtr<nsIWidget> widget = nsnull;
nsresult rv = vm->GetWidget(getter_AddRefs(widget));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);
nsCOMPtr<nsIKBStateControl> kb = do_QueryInterface(widget);
NS_ENSURE_TRUE(kb, NS_ERROR_FAILURE);
NS_ADDREF(*aResult = kb);
return NS_OK;
}

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

@ -57,6 +57,7 @@ class nsIDocShell;
class nsIDocShellTreeNode;
class nsIDocShellTreeItem;
class nsIFocusController;
class nsIKBStateControl;
class imgIContainer;
// mac uses click-hold context menus, a holdover from 4.x
@ -221,6 +222,11 @@ protected:
} ProcessingAccessKeyState;
void HandleAccessKey(nsPresContext* aPresContext, nsKeyEvent* aEvent, nsEventStatus* aStatus, PRInt32 aChildOffset, ProcessingAccessKeyState aAccessKeyState);
void UpdateIMEState(nsPresContext* aPresContext, nsIContent* aContent);
void SetIMEState(nsPresContext* aPresContext, PRUint32 aState);
nsresult GetKBStateControl(nsPresContext* aPresContext,
nsIKBStateControl** aResult);
//---------------------------------------------
// DocShell Focus Traversal Methods
//---------------------------------------------

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

@ -140,6 +140,9 @@
#include "nsCOMArray.h"
#include "nsNodeInfoManager.h"
#include "nsIEditor.h"
#include "nsIEditorIMESupport.h"
// XXX todo: add in missing out-of-memory checks
//----------------------------------------------------------------------
@ -3058,6 +3061,23 @@ nsGenericHTMLFormElement::GetForm(nsIDOMHTMLFormElement** aForm)
return NS_OK;
}
PRUint32
nsGenericHTMLFormElement::GetDesiredIMEState()
{
nsCOMPtr<nsIEditor> editor = nsnull;
nsresult rv = GetEditorInternal(getter_AddRefs(editor));
if (NS_FAILED(rv) || !editor)
return nsIContent::GetDesiredIMEState();
nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(editor);
if (!imeEditor)
return nsIContent::GetDesiredIMEState();
PRUint32 state;
rv = imeEditor->GetPreferredIMEState(&state);
if (NS_FAILED(rv))
return nsIContent::GetDesiredIMEState();
return state;
}
PRBool
nsGenericHTMLFrameElement::IsFocusable(PRInt32 *aTabIndex)
{
@ -4000,6 +4020,14 @@ nsGenericHTMLElement::GetEditor(nsIEditor** aEditor)
if (!nsContentUtils::IsCallerChrome())
return NS_ERROR_DOM_SECURITY_ERR;
return GetEditorInternal(aEditor);
}
nsresult
nsGenericHTMLElement::GetEditorInternal(nsIEditor** aEditor)
{
*aEditor = nsnull;
nsIFormControlFrame *fcFrame = GetFormControlFrame(PR_FALSE);
if (fcFrame) {
nsITextControlFrame *textFrame = nsnull;

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

@ -800,6 +800,7 @@ protected:
* Locate an nsIEditor rooted at this content node, if there is one.
*/
NS_HIDDEN_(nsresult) GetEditor(nsIEditor** aEditor);
NS_HIDDEN_(nsresult) GetEditorInternal(nsIEditor** aEditor);
};
@ -844,6 +845,7 @@ public:
PRBool aNullParent = PR_TRUE);
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
PRBool aNotify);
virtual PRUint32 GetDesiredIMEState();
protected:
/**

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

@ -85,6 +85,7 @@ public:
PRBool aNotify);
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual PRUint32 GetDesiredIMEState();
// Overriden nsIFormControl methods
NS_IMETHOD_(PRInt32) GetType() const { return NS_FORM_OBJECT; }
@ -254,7 +255,14 @@ PRBool nsHTMLObjectElement::IsFocusable(PRInt32 *aTabIndex)
return nsGenericHTMLFormElement::IsFocusable(aTabIndex);
}
PRUint32
nsHTMLObjectElement::GetDesiredIMEState()
{
if (Type() == eType_Plugin)
return nsIContent::IME_STATUS_ENABLE;
return nsGenericHTMLFormElement::GetDesiredIMEState();
}
// nsIFormControl
NS_IMETHODIMP

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

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -51,7 +52,7 @@ struct nsQueryCaretRectEventReply;
[ptr] native nsQueryCaretRectEventReplyPtr(nsQueryCaretRectEventReply);
[scriptable, uuid(205b3e49-aa58-499e-880b-aacab9dede01)]
[scriptable, uuid(228a76d3-5462-4322-a63c-5f94f7f5d4ed)]
interface nsIEditorIMESupport : nsISupports
{
@ -112,5 +113,10 @@ interface nsIEditorIMESupport : nsISupports
[noscript] void getQueryCaretRect(in nsQueryCaretRectEventReplyPtr aReply);
/**
* Get preferred IME status of current widget.
*/
[noscript] void getPreferredIMEState(out unsigned long aState);
};

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

@ -22,6 +22,7 @@
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Daniel Glazman <glazman@netscape.com>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -123,11 +124,6 @@ static PRBool gNoisy = PR_FALSE;
#endif
// Value of "ime.password.onFocus.dontCare"
static PRBool gDontCareForIMEOnFocusPassword = PR_FALSE;
// Value of "ime.password.onBlur.dontCare"
static PRBool gDontCareForIMEOnBlurPassword = PR_FALSE;
// Defined in nsEditorRegistration.cpp
extern nsIParserService *sParserService;
@ -160,7 +156,6 @@ nsEditor::nsEditor()
, mIMEBufferLength(0)
, mInIMEMode(PR_FALSE)
, mIsIMEComposing(PR_FALSE)
, mNeedRecoverIMEOpenState(PR_FALSE)
, mShouldTxnSetSelection(PR_TRUE)
, mActionListeners(nsnull)
, mEditorObservers(nsnull)
@ -316,17 +311,6 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot
NS_POSTCONDITION(mDocWeak && mPresShellWeak, "bad state");
nsresult result;
nsCOMPtr<nsIPrefBranch> prefBranch =
do_GetService(NS_PREFSERVICE_CONTRACTID, &result);
if (NS_SUCCEEDED(result) && prefBranch) {
PRBool val;
if (NS_SUCCEEDED(prefBranch->GetBoolPref("ime.password.onFocus.dontCare", &val)))
gDontCareForIMEOnFocusPassword = val;
if (NS_SUCCEEDED(prefBranch->GetBoolPref("ime.password.onBlur.dontCare", &val)))
gDontCareForIMEOnBlurPassword = val;
}
return NS_OK;
}
@ -2082,11 +2066,6 @@ nsEditor::BeginComposition(nsTextEventReply* aReply)
if (mPhonetic)
mPhonetic->Truncate(0);
// If user changes the IME open state, don't recover it.
// Because the user may not want to change the state.
if (mNeedRecoverIMEOpenState)
mNeedRecoverIMEOpenState = PR_FALSE;
return ret;
}
@ -2250,8 +2229,6 @@ nsEditor::ForceCompositionEnd()
NS_IMETHODIMP
nsEditor::NotifyIMEOnFocus()
{
mNeedRecoverIMEOpenState = PR_FALSE;
nsCOMPtr<nsIKBStateControl> kb;
nsresult res = GetKBStateControl(getter_AddRefs(kb));
if (NS_FAILED(res))
@ -2264,48 +2241,28 @@ nsEditor::NotifyIMEOnFocus()
if (NS_FAILED(res))
kb->ResetInputState();
if(gDontCareForIMEOnFocusPassword
|| !(mFlags & nsIPlaintextEditor::eEditorPasswordMask))
return NS_OK;
PRBool isOpen;
res = kb->GetIMEOpenState(&isOpen);
if (NS_FAILED(res))
return res;
if (isOpen) {
res = kb->SetIMEOpenState(PR_FALSE);
if (NS_FAILED(res))
return res;
}
mNeedRecoverIMEOpenState = isOpen;
return NS_OK;
}
NS_IMETHODIMP
nsEditor::NotifyIMEOnBlur()
{
if (!mNeedRecoverIMEOpenState)
return NS_OK;
mNeedRecoverIMEOpenState = PR_FALSE;
return NS_OK;
}
if (gDontCareForIMEOnBlurPassword
|| !(mFlags & nsIPlaintextEditor::eEditorPasswordMask))
return NS_OK;
nsCOMPtr<nsIKBStateControl> kb;
nsresult res = GetKBStateControl(getter_AddRefs(kb));
if (NS_FAILED(res))
return res;
if (kb) {
res = kb->SetIMEOpenState(PR_TRUE);
if (NS_FAILED(res))
return res;
}
NS_IMETHODIMP
nsEditor::GetPreferredIMEState(PRUint32 *aState)
{
NS_ENSURE_ARG_POINTER(aState);
PRUint32 flags;
if (NS_SUCCEEDED(GetFlags(&flags)) &&
flags & (nsIPlaintextEditor::eEditorPasswordMask |
nsIPlaintextEditor::eEditorReadonlyMask |
nsIPlaintextEditor::eEditorDisabledMask))
*aState = nsIContent::IME_STATUS_DISABLE;
else
*aState = nsIContent::IME_STATUS_ENABLE;
return NS_OK;
}

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

@ -609,7 +609,6 @@ protected:
PRPackedBool mInIMEMode; // are we inside an IME composition?
PRPackedBool mIsIMEComposing; // is IME in composition state?
// This is different from mInIMEMode. see Bug 98434.
PRPackedBool mNeedRecoverIMEOpenState; // Need IME open state change on blur.
PRPackedBool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
// various listeners

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

@ -723,9 +723,6 @@ pref("network.enablePad", false); // Allow client to do proxy
pref("converter.html2txt.structs", true); // Output structured phrases (strong, em, code, sub, sup, b, i, u)
pref("converter.html2txt.header_strategy", 1); // 0 = no indention; 1 = indention, increased with header level; 2 = numbering and slight indention
pref("ime.password.onFocus.dontCare", false);
pref("ime.password.onBlur.dontCare", false);
pref("intl.accept_languages", "chrome://navigator/locale/navigator.properties");
pref("intl.accept_charsets", "iso-8859-1,*,utf-8");
pref("intl.collationOption", "chrome://navigator-platform/locale/navigator.properties");

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

@ -4623,6 +4623,15 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
result = PR_TRUE;
break;
case WM_ENABLE:
if (!wParam) {
// We must enable IME for common dialogs.
// NOTE: we don't need to recover IME status in nsWindow.
// Because when this window will be enabled, we will get focus event.
SetIMEEnabled(PR_TRUE);
}
break;
case WM_ACTIVATE:
if (mEventCallback) {
PRInt32 fActive = LOWORD(wParam);