mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 358899 [Cocoa] Improve nsIKBStateControl implementation r=josh+ere+masaki.katakai+roc, sr=roc
This commit is contained in:
parent
3e830ee3c0
commit
ad3d268bbe
@ -1019,6 +1019,10 @@ public:
|
||||
void *mObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert nsIContent::IME_STATUS_* to nsIKBStateControll::IME_STATUS_*
|
||||
*/
|
||||
static PRUint32 GetKBStateControlStatusFromIMEStatus(PRUint32 aState);
|
||||
private:
|
||||
|
||||
static PRBool InitializeEventTable();
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user