Bug 358899 [Cocoa] Improve nsIKBStateControl implementation r=josh+ere+masaki.katakai+roc, sr=roc

This commit is contained in:
masayuki@d-toybox.com 2007-04-15 06:43:55 -07:00
parent 3e830ee3c0
commit ad3d268bbe
18 changed files with 347 additions and 109 deletions

View File

@ -1019,6 +1019,10 @@ public:
void *mObject;
};
/**
* Convert nsIContent::IME_STATUS_* to nsIKBStateControll::IME_STATUS_*
*/
static PRUint32 GetKBStateControlStatusFromIMEStatus(PRUint32 aState);
private:
static PRBool InitializeEventTable();

View File

@ -524,16 +524,21 @@ public:
* 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).
* IME_STATUS_PASSWORD should be returned only from password editor,
* this value has a special meaning. It is used as alternative of
* IME_STATUS_DISABLED.
*/
enum {
IME_STATUS_NONE = 0x0000,
IME_STATUS_ENABLE = 0x0001,
IME_STATUS_DISABLE = 0x0002,
IME_STATUS_OPEN = 0x0004,
IME_STATUS_CLOSE = 0x0008
IME_STATUS_NONE = 0x0000,
IME_STATUS_ENABLE = 0x0001,
IME_STATUS_DISABLE = 0x0002,
IME_STATUS_PASSWORD = 0x0004,
IME_STATUS_OPEN = 0x0008,
IME_STATUS_CLOSE = 0x0010
};
enum {
IME_STATUS_MASK_ENABLED = IME_STATUS_ENABLE | IME_STATUS_DISABLE,
IME_STATUS_MASK_ENABLED = IME_STATUS_ENABLE | IME_STATUS_DISABLE |
IME_STATUS_PASSWORD,
IME_STATUS_MASK_OPENED = IME_STATUS_OPEN | IME_STATUS_CLOSE
};
virtual PRUint32 GetDesiredIMEState()

View File

@ -136,6 +136,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsTPtrArray.h"
#include "nsGUIEvent.h"
#include "nsMutationEvent.h"
#include "nsIKBStateControl.h"
#ifdef IBMBIDI
#include "nsIBidiKeyboard.h"
@ -3573,3 +3574,20 @@ nsContentUtils::DropScriptObject(PRUint32 aLangID, void *aObject)
}
return rv;
}
/* static */
PRUint32
nsContentUtils::GetKBStateControlStatusFromIMEStatus(PRUint32 aState)
{
switch (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
case nsIContent::IME_STATUS_DISABLE:
return nsIKBStateControl::IME_STATUS_DISABLED;
case nsIContent::IME_STATUS_ENABLE:
return nsIKBStateControl::IME_STATUS_ENABLED;
case nsIContent::IME_STATUS_PASSWORD:
return nsIKBStateControl::IME_STATUS_PASSWORD;
default:
NS_ERROR("The given state doesn't have valid enable state");
return nsIKBStateControl::IME_STATUS_ENABLED;
}
}

View File

@ -53,6 +53,7 @@
#include "nsIKBStateControl.h"
#include "nsIFocusController.h"
#include "nsIDOMWindow.h"
#include "nsContentUtils.h"
/******************************************************************/
/* nsIMEStateManager */
@ -123,13 +124,13 @@ nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
// the enabled state isn't changing, we should do nothing.
return NS_OK;
}
PRBool enabled;
PRUint32 enabled;
if (NS_FAILED(kb->GetIMEEnabled(&enabled))) {
// this platform doesn't support IME controlling
return NS_OK;
}
if ((enabled && newEnabledState == nsIContent::IME_STATUS_ENABLE) ||
(!enabled && newEnabledState == nsIContent::IME_STATUS_DISABLE)) {
if (enabled ==
nsContentUtils::GetKBStateControlStatusFromIMEStatus(newEnabledState)) {
// the enabled state isn't changing.
return NS_OK;
}
@ -172,9 +173,20 @@ nsIMEStateManager::OnDeactivate(nsPresContext* aPresContext)
{
NS_ENSURE_ARG_POINTER(aPresContext);
NS_ENSURE_TRUE(aPresContext->Document()->GetWindow(), NS_ERROR_FAILURE);
if (sActiveWindow ==
if (sActiveWindow !=
aPresContext->Document()->GetWindow()->GetPrivateRoot())
sActiveWindow = nsnull;
return NS_OK;
sActiveWindow = nsnull;
#ifdef NS_KBSC_USE_SHARED_CONTEXT
// Reset the latest content. When the window is activated, the IME state
// may be changed on other applications.
sContent = nsnull;
// We should enable the IME state for other applications.
nsIKBStateControl* kb = GetKBStateControl(aPresContext);
if (kb)
SetIMEState(aPresContext, nsIContent::IME_STATUS_ENABLE, kb);
#endif // NS_KBSC_USE_SHARED_CONTEXT
return NS_OK;
}
@ -238,8 +250,9 @@ nsIMEStateManager::SetIMEState(nsPresContext* aPresContext,
nsIKBStateControl* aKB)
{
if (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
PRBool enable = (aState & nsIContent::IME_STATUS_ENABLE);
aKB->SetIMEEnabled(enable);
PRUint32 state =
nsContentUtils::GetKBStateControlStatusFromIMEStatus(aState);
aKB->SetIMEEnabled(state);
}
if (aState & nsIContent::IME_STATUS_MASK_OPENED) {
PRBool open = (aState & nsIContent::IME_STATUS_OPEN);

View File

@ -2208,10 +2208,11 @@ nsEditor::GetPreferredIMEState(PRUint32 *aState)
PRUint32 flags;
if (NS_SUCCEEDED(GetFlags(&flags)) &&
flags & (nsIPlaintextEditor::eEditorPasswordMask |
nsIPlaintextEditor::eEditorReadonlyMask |
flags & (nsIPlaintextEditor::eEditorReadonlyMask |
nsIPlaintextEditor::eEditorDisabledMask))
*aState = nsIContent::IME_STATUS_DISABLE;
else if (flags & nsIPlaintextEditor::eEditorPasswordMask)
*aState = nsIContent::IME_STATUS_PASSWORD;
else
*aState = nsIContent::IME_STATUS_ENABLE;
return NS_OK;

View File

@ -41,12 +41,21 @@
#include "nsISupports.h"
// {8C636698-8075-4547-80AD-B032F08EF2D3}
// {BC33E975-C433-4df5-B4BA-041CDE6D1A17}
#define NS_IKBSTATECONTROL_IID \
{ 0x8c636698, 0x8075, 0x4547, \
{ 0x80, 0xad, 0xb0, 0x32, 0xf0, 0x8e, 0xf2, 0xd3 } }
{ 0xbc33e975, 0xc433, 0x4df5, \
{ 0xb4, 0xba, 0x04, 0x1c, 0xde, 0x6d, 0x1a, 0x17 } }
#if defined(XP_MACOSX)
/*
* If the all applications use same context for IME, i.e., When gecko changes
* the state of IME, the same changes can be on other processes.
* Then, NS_KBSC_USE_SHARED_CONTEXT should be defined.
*/
#define NS_KBSC_USE_SHARED_CONTEXT 1
#endif
/**
* interface to control keyboard input state
*/
@ -86,18 +95,37 @@ class nsIKBStateControl : public nsISupports {
NS_IMETHOD GetIMEOpenState(PRBool* aState) = 0;
/*
* Set the state to 'Enabled' or 'Disabled'.
* If aState is TRUE, IME enable state is set to 'Enabled'.
* If aState is FALSE, set to 'Disabled'.
* IME enabled states, the aState value of SetIMEEnabled/GetIMEEnabled
* should be one value of following values.
*/
NS_IMETHOD SetIMEEnabled(PRBool aState) = 0;
enum {
/*
* 'Disabled' means the user cannot use IME. So, the open state should be
* 'closed' during 'disabled'.
*/
IME_STATUS_DISABLED = 0,
/*
* 'Enabled' means the user can use IME.
*/
IME_STATUS_ENABLED = 1,
/*
* 'Password' state is a special case for the password editors.
* E.g., on mac, the password editors should disable the non-Roman
* keyboard layouts at getting focus. Thus, the password editor may have
* special rules on some platforms.
*/
IME_STATUS_PASSWORD = 2
};
/*
* Get IME is 'Enabled' or 'Disabled'.
* If IME is 'Enabled', aState is set PR_TRUE.
* If IME is 'Disabled', aState is set PR_FALSE.
* Set the state to 'Enabled' or 'Disabled' or 'Password'.
*/
NS_IMETHOD GetIMEEnabled(PRBool* aState) = 0;
NS_IMETHOD SetIMEEnabled(PRUint32 aState) = 0;
/*
* Get IME is 'Enabled' or 'Disabled' or 'Password'.
*/
NS_IMETHOD GetIMEEnabled(PRUint32* aState) = 0;
/*
* Destruct and don't commit the IME composition string.

View File

@ -98,7 +98,6 @@ union nsPluginPort;
// needed for NSTextInput implementation
NSRange mMarkedRange;
NSRange mSelectedRange;
BOOL mInComposition;
BOOL mIgnoreDoCommand;
BOOL mInHandScroll; // true for as long as we are hand scrolling
@ -126,12 +125,41 @@ union nsPluginPort;
// these are sent to the first responder when the window key status changes
- (void)viewsWindowDidBecomeKey;
- (void)viewsWindowDidResignKey;
- (BOOL)isComposing;
@end
//-------------------------------------------------------------------------
//
// nsTSMManager
//
//-------------------------------------------------------------------------
class nsTSMManager {
public:
static PRBool IsComposing() { return sComposingView ? PR_TRUE : PR_FALSE; }
static PRBool IsIMEEnabled() { return sIsIMEEnabled; }
// Note that we cannot get the actual state in TSM. But we can trust this
// value. Because nsIMEStateManager reset this at every focus changing.
static PRBool IsRomanKeyboardsOnly() { return sIsRomanKeyboardsOnly; }
static PRBool GetIMEOpenState();
static void StartComposing(NSView<mozView>* aComposingView);
static void EndComposing();
static void EnableIME(PRBool aEnable);
static void SetIMEOpenState(PRBool aOpen);
static void SetRomanKeyboardsOnly(PRBool aRomanOnly);
static void CommitIME();
static void CancelIME();
private:
static PRBool sIsIMEEnabled;
static PRBool sIsRomanKeyboardsOnly;
static NSView<mozView>* sComposingView;
};
//-------------------------------------------------------------------------
//
// nsChildView
@ -157,8 +185,8 @@ public:
NS_IMETHOD ResetInputState();
NS_IMETHOD SetIMEOpenState(PRBool aState);
NS_IMETHOD GetIMEOpenState(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRBool aState);
NS_IMETHOD GetIMEEnabled(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRUint32 aState);
NS_IMETHOD GetIMEEnabled(PRUint32* aState);
NS_IMETHOD CancelIMEComposition();
// nsIWidget interface

View File

@ -78,6 +78,10 @@ extern "C" {
CG_EXTERN void CGContextResetClip(CGContextRef);
}
PRBool nsTSMManager::sIsIMEEnabled = PR_TRUE;
PRBool nsTSMManager::sIsRomanKeyboardsOnly = PR_FALSE;
NSView<mozView>* nsTSMManager::sComposingView = nsnull;
static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
static NSView* sLastViewEntered = nil;
#ifdef INVALIDATE_DEBUGGING
@ -1575,17 +1579,7 @@ NS_IMETHODIMP nsChildView::ResetInputState()
NSLog(@"**** ResetInputState");
#endif
if (![mView isComposing])
return NS_OK;
NSInputManager *currentIM = [NSInputManager currentInputManager];
// commit the current text
[currentIM unmarkText];
// and clear the input manager's string
[currentIM markedTextAbandoned:mView];
nsTSMManager::CommitIME();
return NS_OK;
}
@ -1593,26 +1587,66 @@ NS_IMETHODIMP nsChildView::ResetInputState()
// 'open' means that it can take non-ASCII chars
NS_IMETHODIMP nsChildView::SetIMEOpenState(PRBool aState)
{
return NS_ERROR_NOT_IMPLEMENTED;
#ifdef DEBUG_IME
NSLog(@"**** SetIMEOpenState aState = %d", aState);
#endif
nsTSMManager::SetIMEOpenState(aState);
return NS_OK;
}
// 'open' means that it can take non-ASCII chars
NS_IMETHODIMP nsChildView::GetIMEOpenState(PRBool* aState)
{
return NS_ERROR_NOT_IMPLEMENTED;
#ifdef DEBUG_IME
NSLog(@"**** GetIMEOpenState");
#endif
*aState = nsTSMManager::GetIMEOpenState();
return NS_OK;
}
NS_IMETHODIMP nsChildView::SetIMEEnabled(PRBool aState)
NS_IMETHODIMP nsChildView::SetIMEEnabled(PRUint32 aState)
{
return NS_ERROR_NOT_IMPLEMENTED;
#ifdef DEBUG_IME
NSLog(@"**** SetIMEEnabled aState = %d", aState);
#endif
switch (aState) {
case nsIKBStateControl::IME_STATUS_ENABLED:
nsTSMManager::SetRomanKeyboardsOnly(PR_FALSE);
nsTSMManager::EnableIME(PR_TRUE);
break;
case nsIKBStateControl::IME_STATUS_DISABLED:
nsTSMManager::SetRomanKeyboardsOnly(PR_FALSE);
nsTSMManager::EnableIME(PR_FALSE);
break;
case nsIKBStateControl::IME_STATUS_PASSWORD:
nsTSMManager::SetRomanKeyboardsOnly(PR_TRUE);
nsTSMManager::EnableIME(PR_FALSE);
break;
default:
NS_ERROR("not implemented!");
}
return NS_OK;
}
NS_IMETHODIMP nsChildView::GetIMEEnabled(PRBool* aState)
NS_IMETHODIMP nsChildView::GetIMEEnabled(PRUint32* aState)
{
return NS_ERROR_NOT_IMPLEMENTED;
#ifdef DEBUG_IME
NSLog(@"**** GetIMEEnabled");
#endif
if (nsTSMManager::IsIMEEnabled())
*aState = nsIKBStateControl::IME_STATUS_ENABLED;
else if (nsTSMManager::IsRomanKeyboardsOnly())
*aState = nsIKBStateControl::IME_STATUS_PASSWORD;
else
*aState = nsIKBStateControl::IME_STATUS_DISABLED;
return NS_OK;
}
@ -1623,12 +1657,7 @@ NS_IMETHODIMP nsChildView::CancelIMEComposition()
NSLog(@"**** CancelIMEComposition");
#endif
if (![mView isComposing])
return NS_OK;
NSInputManager *currentIM = [NSInputManager currentInputManager];
[currentIM markedTextAbandoned:mView];
nsTSMManager::CancelIME();
return NS_OK;
}
@ -1785,7 +1814,6 @@ NSEvent* globalDragEvent = nil;
mMarkedRange.length = 0;
mSelectedRange.location = NSNotFound;
mSelectedRange.length = 0;
mInComposition = NO;
mLastMenuForEventEvent = nil;
mDragService = nsnull;
}
@ -2915,7 +2943,7 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
[tmpStr getCharacters: bufPtr];
bufPtr[len] = (PRUnichar)'\0';
if (len == 1 && !mInComposition) {
if (len == 1 && !nsTSMManager::IsComposing()) {
// dispatch keypress event with char instead of textEvent
nsKeyEvent geckoEvent(PR_TRUE, NS_KEY_PRESS, mGeckoChild);
geckoEvent.time = PR_IntervalNow();
@ -2938,10 +2966,10 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
mGeckoChild->DispatchWindowEvent(geckoEvent);
}
else {
if (!mInComposition) {
if (!nsTSMManager::IsComposing()) {
// send start composition event to gecko
[self sendCompositionEvent: NS_COMPOSITION_START];
mInComposition = YES;
nsTSMManager::StartComposing(self);
}
// dispatch textevent (is this redundant?)
@ -2952,7 +2980,7 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
// send end composition event to gecko
[self sendCompositionEvent: NS_COMPOSITION_END];
mInComposition = NO;
nsTSMManager::EndComposing();
mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0);
}
@ -3009,9 +3037,9 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
mMarkedRange.location = 0;
mMarkedRange.length = len;
if (!mInComposition) {
if (!nsTSMManager::IsComposing()) {
[self sendCompositionEvent:NS_COMPOSITION_START];
mInComposition = YES;
nsTSMManager::StartComposing(self);
}
[self sendTextEvent:bufPtr attributedString:aString
@ -3019,7 +3047,7 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
markedRange:mMarkedRange
doCommit:NO];
if (mInComposition && len == 0)
if (nsTSMManager::IsComposing() && len == 0)
[self unmarkText];
if (bufPtr != buffer)
@ -3036,9 +3064,10 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
#endif
mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0);
if (mInComposition) {
if (nsTSMManager::IsComposing()) {
[self sendCompositionEvent: NS_COMPOSITION_END];
mInComposition = NO; // brade: do we need to send an end composition event?
// brade: do we need to send an end composition event?
nsTSMManager::EndComposing();
}
}
@ -3191,6 +3220,7 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
return;
}
PRBool dispatchedKeyPress = PR_FALSE;
if (nonDeadKeyPress) {
nsKeyEvent geckoEvent(PR_TRUE, NS_KEY_PRESS, nsnull);
[self convertKeyEvent:theEvent toGeckoEvent:&geckoEvent];
@ -3202,17 +3232,26 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
// dispatch the keydown to gecko, so that we trap delete,
// control-letter combinations etc before Cocoa tries to use
// them for keybindings.
if ((!geckoEvent.isChar || geckoEvent.isControl) && !mInComposition) {
if ((!geckoEvent.isChar || geckoEvent.isControl) &&
!nsTSMManager::IsComposing()) {
// plugins need a native event, it will either be keyDown or autoKey
EventRecord macEvent;
ConvertCocoaKeyEventToMacEvent(theEvent, macEvent);
geckoEvent.nativeMsg = &macEvent;
mIgnoreDoCommand = mGeckoChild->DispatchWindowEvent(geckoEvent);
dispatchedKeyPress = PR_TRUE;
}
}
[super interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
// We should send this event to the superclass if IME is enabled.
// Otherwise, we need to suppress IME composition. We can do it by
// not sending this event to the superclass. But in that case,
// we need to call insertText ourselves.
if (nsTSMManager::IsIMEEnabled())
[super interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
else if (nonDeadKeyPress && !dispatchedKeyPress)
[self insertText:[theEvent characters]];
mIgnoreDoCommand = NO;
mCurKeyEvent = nil;
@ -3242,7 +3281,7 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent
{
// don't bother if we're in composition
if (mInComposition)
if (nsTSMManager::IsComposing())
return NO;
// see if the menu system will handle the event
@ -3372,12 +3411,6 @@ static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& mac
}
- (BOOL)isComposing
{
return mInComposition;
}
// Key code constants
enum
{
@ -3925,3 +3958,94 @@ static PRBool IsSpecialGeckoKey(UInt32 macKeyCode)
#endif /* ACCESSIBILITY */
@end
#pragma mark -
PRBool
nsTSMManager::GetIMEOpenState()
{
return GetScriptManagerVariable(smKeyScript) != smRoman ? PR_TRUE : PR_FALSE;
}
void
nsTSMManager::StartComposing(NSView<mozView>* aComposingView)
{
if (sComposingView && sComposingView != sComposingView)
CommitIME();
sComposingView = aComposingView;
}
void
nsTSMManager::EndComposing()
{
sComposingView = nsnull;
}
void
nsTSMManager::EnableIME(PRBool aEnable)
{
if (aEnable == sIsIMEEnabled)
return;
CommitIME();
sIsIMEEnabled = aEnable;
}
void
nsTSMManager::SetIMEOpenState(PRBool aOpen)
{
if (aOpen == GetIMEOpenState())
return;
CommitIME();
KeyScript(aOpen ? smKeySwapScript : smKeyRoman);
}
#define ENABLE_ROMAN_KYBDS_ONLY -23
void
nsTSMManager::SetRomanKeyboardsOnly(PRBool aRomanOnly)
{
if (aRomanOnly == sIsRomanKeyboardsOnly)
return;
CommitIME();
KeyScript(aRomanOnly ? ENABLE_ROMAN_KYBDS_ONLY : smKeyEnableKybds);
sIsRomanKeyboardsOnly = aRomanOnly;
}
void
nsTSMManager::CommitIME()
{
if (!sComposingView)
return;
NSInputManager *currentIM = [NSInputManager currentInputManager];
// commit the current text
[currentIM unmarkText];
// and clear the input manager's string
[currentIM markedTextAbandoned:sComposingView];
EndComposing();
}
void
nsTSMManager::CancelIME()
{
if (!sComposingView)
return;
NSInputManager *currentIM = [NSInputManager currentInputManager];
// clear the input manager's string
[currentIM markedTextAbandoned:sComposingView];
EndComposing();
}

View File

@ -2374,11 +2374,11 @@ NS_IMETHODIMP nsWidget::GetIMEOpenState(PRBool* aState) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsWidget::SetIMEEnabled(PRBool aState) {
NS_IMETHODIMP nsWidget::SetIMEEnabled(PRUint32 aState) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsWidget::GetIMEEnabled(PRBool* aState) {
NS_IMETHODIMP nsWidget::GetIMEEnabled(PRUint32* aState) {
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -174,8 +174,8 @@ public:
NS_IMETHOD ResetInputState();
NS_IMETHOD SetIMEOpenState(PRBool aState);
NS_IMETHOD GetIMEOpenState(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRBool aState);
NS_IMETHOD GetIMEEnabled(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRUint32 aState);
NS_IMETHOD GetIMEEnabled(PRUint32* aState);
NS_IMETHOD CancelIMEComposition();
void InitEvent(nsGUIEvent& event, nsPoint* aPoint = nsnull);

View File

@ -5068,7 +5068,7 @@ nsWindow::IMEDestroyContext(void)
}
mIMEData->mOwner = nsnull;
mIMEData->mEnabled = PR_FALSE;
mIMEData->mEnabled = nsIKBStateControl::IME_STATUS_DISABLED;
if (mIMEData->mContext) {
gtk_im_context_set_client_window(mIMEData->mContext, nsnull);
@ -5231,10 +5231,16 @@ nsWindow::IMEGetContext()
return IM_get_input_context(this);
}
static PRBool
IsIMEEnabledState(PRUint32 aState)
{
return aState == nsIKBStateControl::IME_STATUS_ENABLED ? PR_TRUE : PR_FALSE;
}
PRBool
nsWindow::IMEIsEnabled(void)
{
return mIMEData ? mIMEData->mEnabled : PR_FALSE;
return mIMEData ? IsIMEEnabledState(mIMEData->mEnabled) : PR_FALSE;
}
nsWindow*
@ -5354,13 +5360,19 @@ nsWindow::GetIMEOpenState(PRBool* aState)
}
NS_IMETHODIMP
nsWindow::SetIMEEnabled(PRBool aState)
nsWindow::SetIMEEnabled(PRUint32 aState)
{
IMEInitData();
if (!mIMEData || mIMEData->mEnabled == aState)
if (!mIMEData)
return NS_OK;
PRBool newState = IsIMEEnabledState(aState);
PRBool oldState = IsIMEEnabledState(mIMEData->mEnabled);
if (newState == oldState) {
mIMEData->mEnabled = aState;
return NS_OK;
}
GtkIMContext *focusedIm = nsnull;
// XXX Don't we need to check gFocusWindow?
nsWindow *focusedWin = gIMEFocusWindow;
@ -5369,7 +5381,7 @@ nsWindow::SetIMEEnabled(PRBool aState)
if (focusedIm && focusedIm == mIMEData->mContext) {
// Release current IME focus if IME is enabled.
if (mIMEData->mEnabled) {
if (oldState) {
focusedWin->ResetInputState();
focusedWin->IMELoseFocus();
}
@ -5380,7 +5392,7 @@ nsWindow::SetIMEEnabled(PRBool aState)
// Because some IMs are updating the status bar of them in this time.
focusedWin->IMESetFocus();
} else {
if (mIMEData->mEnabled)
if (oldState)
ResetInputState();
mIMEData->mEnabled = aState;
}
@ -5389,13 +5401,14 @@ nsWindow::SetIMEEnabled(PRBool aState)
}
NS_IMETHODIMP
nsWindow::GetIMEEnabled(PRBool* aState)
nsWindow::GetIMEEnabled(PRUint32* aState)
{
NS_ENSURE_ARG_POINTER(aState);
IMEInitData();
*aState = IMEIsEnabled();
*aState =
mIMEData ? mIMEData->mEnabled : nsIKBStateControl::IME_STATUS_DISABLED;
return NS_OK;
}

View File

@ -318,14 +318,14 @@ public:
// the decrementer must free the instance.
PRUint32 mRefCount;
// IME enabled state in this window.
PRPackedBool mEnabled;
PRUint32 mEnabled;
nsIMEData(nsWindow* aOwner) {
mContext = nsnull;
mDummyContext = nsnull;
mComposingWindow = nsnull;
mOwner = aOwner;
mRefCount = 1;
mEnabled = PR_TRUE;
mEnabled = nsIKBStateControl::IME_STATUS_ENABLED;
}
};
nsIMEData *mIMEData;
@ -334,8 +334,8 @@ public:
NS_IMETHOD ResetInputState();
NS_IMETHOD SetIMEOpenState(PRBool aState);
NS_IMETHOD GetIMEOpenState(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRBool aState);
NS_IMETHOD GetIMEEnabled(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRUint32 aState);
NS_IMETHOD GetIMEEnabled(PRUint32* aState);
NS_IMETHOD CancelIMEComposition();
#endif

View File

@ -475,7 +475,7 @@ void* nsWindow::GetNativeData(PRUint32 aDataType)
break;
case NS_NATIVE_COLORMAP:
//¥TODO
// TODO
break;
case NS_NATIVE_OFFSETX:
@ -638,7 +638,7 @@ NS_IMETHODIMP nsWindow::SetFont(const nsFont &aFont)
//-------------------------------------------------------------------------
NS_IMETHODIMP nsWindow::SetColorMap(nsColorMap *aColorMap)
{
//¥TODO
// TODO
// We may need to move this to nsMacWindow:
// I'm not sure all the individual widgets
// can have each their own colorMap on Mac.
@ -1107,7 +1107,7 @@ void nsWindow::StartDraw(nsIRenderingContext* aRenderingContext)
return;
mDrawing = PR_TRUE;
CalcWindowRegions(); //¥REVISIT
CalcWindowRegions(); // REVISIT
if (aRenderingContext == nsnull)
{
@ -2367,11 +2367,11 @@ NS_IMETHODIMP nsWindow::GetIMEOpenState(PRBool* aState) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsWindow::SetIMEEnabled(PRBool aState) {
NS_IMETHODIMP nsWindow::SetIMEEnabled(PRUint32 aState) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsWindow::GetIMEEnabled(PRBool* aState) {
NS_IMETHODIMP nsWindow::GetIMEEnabled(PRUint32* aState) {
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -219,8 +219,8 @@ public:
NS_IMETHOD ResetInputState();
NS_IMETHOD SetIMEOpenState(PRBool aState);
NS_IMETHOD GetIMEOpenState(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRBool aState);
NS_IMETHOD GetIMEEnabled(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRUint32 aState);
NS_IMETHOD GetIMEEnabled(PRUint32* aState);
NS_IMETHOD CancelIMEComposition();
protected:

View File

@ -239,11 +239,11 @@ NS_IMETHODIMP nsWidget::GetIMEOpenState(PRBool* aState) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsWidget::SetIMEEnabled(PRBool aState) {
NS_IMETHODIMP nsWidget::SetIMEEnabled(PRUint32 aState) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsWidget::GetIMEEnabled(PRBool* aState) {
NS_IMETHODIMP nsWidget::GetIMEEnabled(PRUint32* aState) {
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -216,8 +216,8 @@ public:
NS_IMETHOD ResetInputState();
NS_IMETHOD SetIMEOpenState(PRBool aState);
NS_IMETHOD GetIMEOpenState(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRBool aState);
NS_IMETHOD GetIMEEnabled(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRUint32 aState);
NS_IMETHOD GetIMEEnabled(PRUint32* aState);
NS_IMETHOD CancelIMEComposition();
inline void InitEvent(nsGUIEvent& event, PRUint32 aEventType, nsPoint* aPoint = nsnull)

View File

@ -818,6 +818,7 @@ nsWindow::nsWindow() : nsBaseWidget()
mOldExStyle = 0;
mPainting = 0;
mOldIMC = NULL;
mIMEEnabled = nsIKBStateControl::IME_STATUS_ENABLED;
mLeadByte = '\0';
mBlurEventSuppressionLevel = 0;
@ -7473,22 +7474,24 @@ NS_IMETHODIMP nsWindow::GetIMEOpenState(PRBool* aState)
}
//==========================================================================
NS_IMETHODIMP nsWindow::SetIMEEnabled(PRBool aState)
NS_IMETHODIMP nsWindow::SetIMEEnabled(PRUint32 aState)
{
if (sIMEIsComposing)
ResetInputState();
if (!aState != !mOldIMC)
mIMEEnabled = aState;
PRBool enable = (aState == nsIKBStateControl::IME_STATUS_ENABLED);
if (!enable != !mOldIMC)
return NS_OK;
mOldIMC = ::ImmAssociateContext(mWnd, aState ? mOldIMC : NULL);
NS_ASSERTION(!aState || !mOldIMC, "Another IMC was associated");
mOldIMC = ::ImmAssociateContext(mWnd, enable ? mOldIMC : NULL);
NS_ASSERTION(!enable || !mOldIMC, "Another IMC was associated");
return NS_OK;
}
//==========================================================================
NS_IMETHODIMP nsWindow::GetIMEEnabled(PRBool* aState)
NS_IMETHODIMP nsWindow::GetIMEEnabled(PRUint32* aState)
{
*aState = !mOldIMC;
*aState = mIMEEnabled;
return NS_OK;
}

View File

@ -230,8 +230,8 @@ public:
NS_IMETHOD ResetInputState();
NS_IMETHOD SetIMEOpenState(PRBool aState);
NS_IMETHOD GetIMEOpenState(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRBool aState);
NS_IMETHOD GetIMEEnabled(PRBool* aState);
NS_IMETHOD SetIMEEnabled(PRUint32 aState);
NS_IMETHOD GetIMEEnabled(PRUint32* aState);
NS_IMETHOD CancelIMEComposition();
PRBool IMEMouseHandling(PRInt32 aAction, LPARAM lParam);
@ -451,6 +451,7 @@ protected:
// To enable/disable IME
HIMC mOldIMC;
PRUint32 mIMEEnabled;
static HKL gKeyboardLayout;
static PRBool gSwitchKeyboardLayout;