зеркало из https://github.com/mozilla/gecko-dev.git
add nsIKBStateControl for IME force commit and password field disable. Change window implementation to implement nsIKBStateControl in nsWindow. Fix 12250 by filtering out the composition window flag in OnIMESetContext. r=erik
This commit is contained in:
Родитель
f0fed40b89
Коммит
b125de60fe
|
@ -4,6 +4,7 @@
|
|||
|
||||
nsIDragSessionMac.h
|
||||
nsIWidget.h
|
||||
nsIKBStateControl.h
|
||||
nsIButton.h
|
||||
nsICheckButton.h
|
||||
nsIListWidget.h
|
||||
|
|
|
@ -40,6 +40,7 @@ EXPORTS = \
|
|||
nsIFileWidget.h \
|
||||
nsStringUtil.h \
|
||||
nsIWidget.h \
|
||||
nsIKBStateControl.h \
|
||||
nsIButton.h \
|
||||
nsICheckButton.h \
|
||||
nsIListWidget.h \
|
||||
|
|
|
@ -47,6 +47,7 @@ EXPORTS=\
|
|||
nsIFontRetrieverService.h \
|
||||
nsIFileWidget.h \
|
||||
nsIWidget.h \
|
||||
nsIKBStateControl.h \
|
||||
nsIButton.h \
|
||||
nsICheckButton.h \
|
||||
nsIListWidget.h \
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Frank Tang <ftang@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsIKBStateControl_h__
|
||||
#define nsIKBStateControl_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
// {6A9AC731-988A-11d3-86CC-005004832142}
|
||||
#define NS_IKBSTATECONTROL_IID \
|
||||
{ 0x6a9ac731, 0x988a, 0x11d3, \
|
||||
{ 0x86, 0xcc, 0x0, 0x50, 0x4, 0x83, 0x21, 0x42 } }
|
||||
|
||||
|
||||
/**
|
||||
* interface to control keyboard input state
|
||||
*/
|
||||
class nsIKBStateControl : public nsISupports {
|
||||
|
||||
public:
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IKBSTATECONTROL_IID)
|
||||
|
||||
/*
|
||||
* Force Input Method Editor to commit the uncommited input
|
||||
*/
|
||||
NS_IMETHOD ResetInputState()=0;
|
||||
|
||||
/*
|
||||
* This method is called in the init stage of a password field
|
||||
*/
|
||||
NS_IMETHOD PasswordFieldInit()=0;
|
||||
|
||||
};
|
||||
|
||||
#endif // nsIKBStateControl_h__
|
|
@ -311,37 +311,37 @@ nsresult nsWidgetFactory::CreateInstance( nsISupports* aOuter,
|
|||
|
||||
if (mClassID.Equals(kCWindow)) {
|
||||
|
||||
inst = (nsISupports*)new nsWindow();
|
||||
inst = (nsISupports*)(nsBaseWidget*)new nsWindow();
|
||||
|
||||
}
|
||||
|
||||
else if (mClassID.Equals(kCChild)) {
|
||||
|
||||
inst = (nsISupports*)new ChildWindow();
|
||||
inst = (nsISupports*)(nsBaseWidget*)new ChildWindow();
|
||||
|
||||
}
|
||||
|
||||
else if (mClassID.Equals(kCButton)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsButton();
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsButton();
|
||||
|
||||
}
|
||||
|
||||
else if (mClassID.Equals(kCCheckButton)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsCheckButton();
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsCheckButton();
|
||||
|
||||
}
|
||||
|
||||
else if (mClassID.Equals(kCCombobox)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsComboBox();
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsComboBox();
|
||||
|
||||
}
|
||||
|
||||
else if (mClassID.Equals(kCRadioButton)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsRadioButton();
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsRadioButton();
|
||||
|
||||
}
|
||||
|
||||
|
@ -353,31 +353,31 @@ nsresult nsWidgetFactory::CreateInstance( nsISupports* aOuter,
|
|||
|
||||
else if (mClassID.Equals(kCListbox)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsListBox();
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsListBox();
|
||||
|
||||
}
|
||||
|
||||
else if (mClassID.Equals(kCHorzScrollbar)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsScrollbar(PR_FALSE);
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsScrollbar(PR_FALSE);
|
||||
|
||||
}
|
||||
|
||||
else if (mClassID.Equals(kCVertScrollbar)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsScrollbar(PR_TRUE);
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsScrollbar(PR_TRUE);
|
||||
|
||||
}
|
||||
|
||||
else if (mClassID.Equals(kCTextArea)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsTextAreaWidget();
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsTextAreaWidget();
|
||||
|
||||
}
|
||||
|
||||
else if (mClassID.Equals(kCTextField)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsTextWidget();
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsTextWidget();
|
||||
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ nsresult nsWidgetFactory::CreateInstance( nsISupports* aOuter,
|
|||
|
||||
else if (mClassID.Equals(kCLabel)) {
|
||||
|
||||
inst = (nsISupports*)(nsWindow*)new nsLabel();
|
||||
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsLabel();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
*/
|
||||
|
||||
#if defined(DEBUG_ftang)
|
||||
#define KE_DEBUG
|
||||
#define DEBUG_IME
|
||||
//#define KE_DEBUG
|
||||
//#define DEBUG_IME
|
||||
//#define DEBUG_KBSTATE
|
||||
#endif
|
||||
|
||||
#include "nsWindow.h"
|
||||
|
@ -122,6 +123,8 @@ static PRBool NS_IsDBCSLeadByte(UINT aCP, BYTE aByte)
|
|||
}
|
||||
#endif // IME_FROM_ON_CHAR
|
||||
|
||||
#define IS_IME_CODEPAGE(cp) ((932==(cp))||(936==(cp))||(949==(cp))||(950==(cp)))
|
||||
|
||||
static PRBool LangIDToCP(WORD aLangID, UINT& oCP)
|
||||
{
|
||||
int localeid=MAKELCID(aLangID,SORT_DEFAULT);
|
||||
|
@ -145,6 +148,28 @@ static PRBool LangIDToCP(WORD aLangID, UINT& oCP)
|
|||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// nsISupport stuff
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
NS_IMPL_ADDREF(nsWindow)
|
||||
NS_IMPL_RELEASE(nsWindow)
|
||||
NS_IMETHODIMP nsWindow::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (aIID.Equals(nsIKBStateControl::GetIID())) {
|
||||
*aInstancePtr = (void*) ((nsIKBStateControl*)this);
|
||||
NS_ADDREF((nsBaseWidget*)this);
|
||||
// NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsBaseWidget::QueryInterface(aIID,aInstancePtr);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// nsWindow constructor
|
||||
|
@ -581,7 +606,7 @@ LRESULT CALLBACK nsWindow::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||
// is not really an interface.
|
||||
nsCOMPtr<nsISupports> kungFuDeathGrip;
|
||||
if (!someWindow->mIsDestroying) // not if we're in the destructor!
|
||||
kungFuDeathGrip = do_QueryInterface(someWindow);
|
||||
kungFuDeathGrip = do_QueryInterface((nsBaseWidget*)someWindow);
|
||||
|
||||
// Re-direct a tab change message destined for its parent window to the
|
||||
// the actual window which generated the event.
|
||||
|
@ -2707,6 +2732,10 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
|||
case WM_LBUTTONDOWN:
|
||||
//SetFocus(); // this is bad
|
||||
//RelayMouseEvent(msg,wParam, lParam);
|
||||
if(mIMEIsComposing) {
|
||||
nsresult res = ResetInputState();
|
||||
NS_ASSERTION(NS_SUCCEEDED(res) , "ResetInputState failed");
|
||||
}
|
||||
result = DispatchMouseEvent(NS_MOUSE_LEFT_BUTTON_DOWN);
|
||||
break;
|
||||
|
||||
|
@ -2720,6 +2749,10 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
|||
break;
|
||||
|
||||
case WM_MBUTTONDOWN:
|
||||
if(mIMEIsComposing) {
|
||||
nsresult res = ResetInputState();
|
||||
NS_ASSERTION(NS_SUCCEEDED(res) , "ResetInputState failed");
|
||||
}
|
||||
result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_DOWN);
|
||||
break;
|
||||
|
||||
|
@ -2732,6 +2765,10 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
|||
break;
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
if(mIMEIsComposing) {
|
||||
nsresult res = ResetInputState();
|
||||
NS_ASSERTION(NS_SUCCEEDED(res) , "ResetInputState failed");
|
||||
}
|
||||
result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_DOWN);
|
||||
break;
|
||||
|
||||
|
@ -4198,7 +4235,48 @@ BOOL nsWindow::OnIMEEndComposition()
|
|||
BOOL nsWindow::OnIMENotify(WPARAM aIMN, LPARAM aData, LRESULT *oResult)
|
||||
{
|
||||
#ifdef DEBUG_IME
|
||||
printf("OnIMENotify\n");
|
||||
printf("OnIMENotify ");
|
||||
switch(aIMN) {
|
||||
case IMN_CHANGECANDIDATE:
|
||||
printf("IMN_CHANGECANDIDATE %x\n", aData);
|
||||
break;
|
||||
case IMN_CLOSECANDIDATE:
|
||||
printf("IMN_CLOSECANDIDATE %x\n", aData);
|
||||
break;
|
||||
case IMN_CLOSESTATUSWINDOW:
|
||||
printf("IMN_CLOSESTATUSWINDOW\n");
|
||||
break;
|
||||
case IMN_GUIDELINE:
|
||||
printf("IMN_GUIDELINE\n");
|
||||
break;
|
||||
case IMN_OPENCANDIDATE:
|
||||
printf("IMN_OPENCANDIDATE %x\n", aData);
|
||||
break;
|
||||
case IMN_OPENSTATUSWINDOW:
|
||||
printf("IMN_OPENSTATUSWINDOW\n");
|
||||
break;
|
||||
case IMN_SETCANDIDATEPOS:
|
||||
printf("IMN_SETCANDIDATEPOS %x\n", aData);
|
||||
break;
|
||||
case IMN_SETCOMPOSITIONFONT:
|
||||
printf("IMN_SETCOMPOSITIONFONT\n");
|
||||
break;
|
||||
case IMN_SETCOMPOSITIONWINDOW:
|
||||
printf("IMN_SETCOMPOSITIONWINDOW\n");
|
||||
break;
|
||||
case IMN_SETCONVERSIONMODE:
|
||||
printf("IMN_SETCONVERSIONMODE\n");
|
||||
break;
|
||||
case IMN_SETOPENSTATUS:
|
||||
printf("IMN_SETOPENSTATUS\n");
|
||||
break;
|
||||
case IMN_SETSENTENCEMODE:
|
||||
printf("IMN_SETSENTENCEMODE\n");
|
||||
break;
|
||||
case IMN_SETSTATUSWINDOWPOS:
|
||||
printf("IMN_SETSTATUSWINDOWPOS\n");
|
||||
break;
|
||||
};
|
||||
#endif
|
||||
|
||||
// not implement yet
|
||||
|
@ -4225,13 +4303,26 @@ BOOL nsWindow::OnIMESelect(BOOL aSelected, WORD aLangID)
|
|||
return PR_FALSE;
|
||||
}
|
||||
//==========================================================================
|
||||
BOOL nsWindow::OnIMESetContext(BOOL aActive, LPARAM aISC)
|
||||
BOOL nsWindow::OnIMESetContext(BOOL aActive, LPARAM& aISC)
|
||||
{
|
||||
#ifdef DEBUG_IME
|
||||
printf("OnIMESetContext\n");
|
||||
printf("OnIMESetContext %x %s %s %s Candidate[%s%s%s%s]\n", this,
|
||||
(aActive ? "Active" : "Deactiv"),
|
||||
((aISC & ISC_SHOWUICOMPOSITIONWINDOW) ? "[Comp]" : ""),
|
||||
((aISC & ISC_SHOWUIGUIDELINE) ? "[GUID]" : ""),
|
||||
((aISC & ISC_SHOWUICANDIDATEWINDOW) ? "0" : ""),
|
||||
((aISC & (ISC_SHOWUICANDIDATEWINDOW<<1)) ? "1" : ""),
|
||||
((aISC & (ISC_SHOWUICANDIDATEWINDOW<<2)) ? "2" : ""),
|
||||
((aISC & (ISC_SHOWUICANDIDATEWINDOW<<3)) ? "3" : "")
|
||||
);
|
||||
#endif
|
||||
if(! aActive)
|
||||
ResetInputState();
|
||||
|
||||
// not implement yet
|
||||
aISC &= ~ ISC_SHOWUICOMPOSITIONWINDOW;
|
||||
// We still return false here because we need to pass the
|
||||
// aISC w/ ISC_SHOWUICOMPOSITIONWINDOW clear to the default
|
||||
// window proc so it will draw the candidcate window for us...
|
||||
return PR_FALSE;
|
||||
}
|
||||
//==========================================================================
|
||||
|
@ -4254,3 +4345,74 @@ BOOL nsWindow::OnIMEStartComposition()
|
|||
::ImmReleaseContext(mWnd,hIMEContext);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
NS_IMETHODIMP nsWindow::ResetInputState()
|
||||
{
|
||||
#ifdef DEBUG_KBSTATE
|
||||
printf("ResetInputState\n");
|
||||
#endif
|
||||
if(mIMEIsComposing) {
|
||||
HIMC hIMC = ::ImmGetContext(mWnd);
|
||||
if(hIMC) {
|
||||
BOOL ret = ::ImmNotifyIME(hIMC,NI_COMPOSITIONSTR,CPS_COMPLETE,NULL);
|
||||
NS_ASSERTION(ret, "ImmNotify failed");
|
||||
::ImmReleaseContext(mWnd,hIMC);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsWindow::PasswordFieldInit()
|
||||
{
|
||||
#ifdef DEBUG_KBSTATE
|
||||
printf("PasswordFieldInit\n");
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsWindow::PasswordFieldEnter(PRUint32& oState)
|
||||
{
|
||||
#ifdef DEBUG_KBSTATE
|
||||
printf("PasswordFieldEnter\n");
|
||||
#endif
|
||||
if(IS_IME_CODEPAGE(mCurrentKeyboardCP))
|
||||
{
|
||||
HIMC hIMC = ::ImmGetContext(mWnd);
|
||||
if(hIMC) {
|
||||
DWORD st1,st2;
|
||||
|
||||
BOOL ret = ::ImmGetConversionStatus(hIMC, &st1, &st2);
|
||||
NS_ASSERTION(ret, "ImmGetConversionStatus failed");
|
||||
if(ret) {
|
||||
oState = st1;
|
||||
ret = ::ImmSetConversionStatus(hIMC, IME_CMODE_NOCONVERSION, st2);
|
||||
NS_ASSERTION(ret, "ImmSetConversionStatus failed");
|
||||
}
|
||||
::ImmReleaseContext(mWnd,hIMC);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsWindow::PasswordFieldExit(PRUint32 aState)
|
||||
{
|
||||
#ifdef DEBUG_KBSTATE
|
||||
printf("PasswordFieldExit\n");
|
||||
#endif
|
||||
if(IS_IME_CODEPAGE(mCurrentKeyboardCP))
|
||||
{
|
||||
HIMC hIMC = ::ImmGetContext(mWnd);
|
||||
if(hIMC) {
|
||||
DWORD st1,st2;
|
||||
|
||||
BOOL ret = ::ImmGetConversionStatus(hIMC, &st1, &st2);
|
||||
NS_ASSERTION(ret, "ImmGetConversionStatus failed");
|
||||
if(ret) {
|
||||
ret = ::ImmSetConversionStatus(hIMC, (DWORD)aState, st2);
|
||||
NS_ASSERTION(ret, "ImmSetConversionStatus failed");
|
||||
}
|
||||
::ImmReleaseContext(mWnd,hIMC);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "nsToolkit.h"
|
||||
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIKBStateControl.h"
|
||||
|
||||
#include "nsIMenuBar.h"
|
||||
|
||||
|
@ -50,13 +51,19 @@ class nsIRollupListener;
|
|||
*/
|
||||
|
||||
class nsWindow : public nsSwitchToUIThread,
|
||||
public nsBaseWidget
|
||||
public nsBaseWidget,
|
||||
public nsIKBStateControl
|
||||
{
|
||||
|
||||
public:
|
||||
nsWindow();
|
||||
virtual ~nsWindow();
|
||||
|
||||
// nsISupports
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||
|
||||
// nsIWidget interface
|
||||
NS_IMETHOD Create(nsIWidget *aParent,
|
||||
const nsRect &aRect,
|
||||
|
@ -135,6 +142,11 @@ public:
|
|||
|
||||
NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent);
|
||||
|
||||
// nsIKBStateControl interface
|
||||
|
||||
NS_IMETHOD ResetInputState();
|
||||
NS_IMETHOD PasswordFieldInit();
|
||||
|
||||
HWND mBorderlessParent;
|
||||
|
||||
// nsSwitchToUIThread interface
|
||||
|
@ -191,7 +203,7 @@ protected:
|
|||
BOOL OnIMENotify(WPARAM aIMN, LPARAM aData, LRESULT *oResult);
|
||||
BOOL OnIMERequest(WPARAM aIMR, LPARAM aData, LRESULT *oResult);
|
||||
BOOL OnIMESelect(BOOL aSelected, WORD aLangID);
|
||||
BOOL OnIMESetContext(BOOL aActive, LPARAM aISC);
|
||||
BOOL OnIMESetContext(BOOL aActive, LPARAM& aISC);
|
||||
BOOL OnIMEStartComposition();
|
||||
|
||||
ULONG IsSpecialChar(UINT aVirtualKeyCode, WORD *aAsciiKey);
|
||||
|
@ -219,6 +231,9 @@ protected:
|
|||
void HandleEndComposition(void);
|
||||
void MapDBCSAtrributeArrayToUnicodeOffsets(PRUint32* textRangeListLengthResult, nsTextRangeArray* textRangeListResult);
|
||||
|
||||
NS_IMETHOD PasswordFieldEnter(PRUint32& oSavedState);
|
||||
NS_IMETHOD PasswordFieldExit(PRUint32 aRestoredState);
|
||||
|
||||
private:
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
Загрузка…
Ссылка в новой задаче