зеркало из https://github.com/mozilla/gecko-dev.git
Bug 513952 Refactor nsTSMManager r=josh
This commit is contained in:
Родитель
8168b8f791
Коммит
ba7930b505
|
@ -87,6 +87,7 @@ CMMSRCS = \
|
|||
nsPrintSettingsX.mm \
|
||||
nsIdleServiceX.mm \
|
||||
nsAccelerometerX.mm \
|
||||
nsCocoaTextInputHandler.mm \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_COCOA_PRINTING
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#include "nsIPluginWidget.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsCocoaTextInputHandler.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
|
||||
#include "nsIAppShell.h"
|
||||
|
||||
|
@ -236,6 +238,7 @@ enum {
|
|||
|
||||
|
||||
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// nsTSMManager
|
||||
|
@ -276,6 +279,7 @@ private:
|
|||
|
||||
static void KillComposing();
|
||||
};
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
class ChildViewMouseTracker {
|
||||
|
||||
|
@ -377,6 +381,7 @@ public:
|
|||
NS_IMETHOD CancelIMEComposition();
|
||||
NS_IMETHOD GetToggledKeyState(PRUint32 aKeyCode,
|
||||
PRBool* aLEDState);
|
||||
NS_IMETHOD OnIMEFocusChange(PRBool aFocus);
|
||||
|
||||
// nsIPluginWidget
|
||||
NS_IMETHOD GetPluginClipRect(nsIntRect& outClipRect, nsIntPoint& outOrigin, PRBool& outWidgetVisible);
|
||||
|
@ -426,6 +431,138 @@ public:
|
|||
const nsIWidget::Configuration& aConfiguration,
|
||||
PRBool aRepaint);
|
||||
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
nsCocoaTextInputHandler* TextInputHandler() { return &mTextInputHandler; }
|
||||
NSView<mozView>* GetEditorView();
|
||||
#endif
|
||||
|
||||
// Wrapper methods of nsIMEManager and nsTSMManager
|
||||
void IME_OnDestroyView(NSView<mozView> *aDestroyingView)
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.OnDestroyView(aDestroyingView);
|
||||
#else
|
||||
nsTSMManager::OnDestroyView(aDestroyingView);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IME_OnStartComposition(NSView<mozView>* aComposingView)
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.OnStartIMEComposition(aComposingView);
|
||||
#else
|
||||
nsTSMManager::StartComposing(aComposingView);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IME_OnUpdateComposition(NSString* aCompositionString)
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.OnUpdateIMEComposition(aCompositionString);
|
||||
#else
|
||||
nsTSMManager::UpdateComposing(aCompositionString);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IME_OnEndComposition()
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.OnEndIMEComposition();
|
||||
#else
|
||||
nsTSMManager::EndComposing();
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool IME_IsComposing()
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
return mTextInputHandler.IsIMEComposing();
|
||||
#else
|
||||
return nsTSMManager::IsComposing();
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool IME_IsASCIICapableOnly()
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
return mTextInputHandler.IsASCIICapableOnly();
|
||||
#else
|
||||
return nsTSMManager::IsRomanKeyboardsOnly();
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool IME_IsOpened()
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
return mTextInputHandler.IsIMEOpened();
|
||||
#else
|
||||
return nsTSMManager::GetIMEOpenState();
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool IME_IsEnabled()
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
return mTextInputHandler.IsIMEEnabled();
|
||||
#else
|
||||
return nsTSMManager::IsIMEEnabled();
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool IME_IgnoreCommit()
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
return mTextInputHandler.IgnoreIMECommit();
|
||||
#else
|
||||
return nsTSMManager::IgnoreCommit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void IME_CommitComposition()
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.CommitIMEComposition();
|
||||
#else
|
||||
nsTSMManager::CommitIME();
|
||||
#endif
|
||||
}
|
||||
|
||||
void IME_CancelComposition()
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.CancelIMEComposition();
|
||||
#else
|
||||
nsTSMManager::CancelIME();
|
||||
#endif
|
||||
}
|
||||
|
||||
void IME_SetASCIICapableOnly(PRBool aASCIICapableOnly)
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.SetASCIICapableOnly(aASCIICapableOnly);
|
||||
#else
|
||||
nsTSMManager::SetRomanKeyboardsOnly(aASCIICapableOnly);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IME_SetOpenState(PRBool aOpen)
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.SetIMEOpenState(aOpen);
|
||||
#else
|
||||
nsTSMManager::SetIMEOpenState(aOpen);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IME_Enable(PRBool aEnable)
|
||||
{
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.EnableIME(aEnable);
|
||||
#else
|
||||
nsTSMManager::EnableIME(aEnable);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
PRBool ReportDestroyEvent();
|
||||
|
@ -441,6 +578,9 @@ protected:
|
|||
protected:
|
||||
|
||||
NSView<mozView>* mView; // my parallel cocoa view (ChildView or NativeScrollbarView), [STRONG]
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
nsCocoaTextInputHandler mTextInputHandler;
|
||||
#endif
|
||||
|
||||
NSView<mozView>* mParentView;
|
||||
nsIWidget* mParentWidget;
|
||||
|
|
|
@ -106,172 +106,7 @@ extern "C" {
|
|||
CG_EXTERN void CGContextResetClip(CGContextRef);
|
||||
}
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
|
||||
#define LEOPARD_AND_LATER 1
|
||||
#endif
|
||||
|
||||
#ifdef LEOPARD_AND_LATER
|
||||
|
||||
/**
|
||||
* nsTISInputSource is a wrapper for the TISInputSourceRef. If we get the
|
||||
* TISInputSourceRef from InputSourceID, we need to release the CFArray instance
|
||||
* which is returned by TISCreateInputSourceList. However, when we release the
|
||||
* list, we cannot access the TISInputSourceRef. So, it's not usable, and it
|
||||
* may cause the memory leak bugs. nsTISInputSource automatically releases the
|
||||
* list when the instance is destroyed.
|
||||
*/
|
||||
class nsTISInputSource
|
||||
{
|
||||
public:
|
||||
nsTISInputSource()
|
||||
{
|
||||
mInputSourceList = nsnull;
|
||||
Clear();
|
||||
}
|
||||
|
||||
nsTISInputSource(const char* aID)
|
||||
{
|
||||
mInputSourceList = nsnull;
|
||||
InitByInputSourceID(aID);
|
||||
}
|
||||
|
||||
nsTISInputSource(SInt32 aLayoutID)
|
||||
{
|
||||
mInputSourceList = nsnull;
|
||||
InitByLayoutID(aLayoutID);
|
||||
}
|
||||
|
||||
nsTISInputSource(TISInputSourceRef aInputSource)
|
||||
{
|
||||
mInputSourceList = nsnull;
|
||||
InitByTISInputSourceRef(aInputSource);
|
||||
}
|
||||
|
||||
~nsTISInputSource() { Clear(); }
|
||||
|
||||
void InitByInputSourceID(const char* aID)
|
||||
{
|
||||
Clear();
|
||||
if (!aID)
|
||||
return;
|
||||
|
||||
CFStringRef idstr = ::CFStringCreateWithCString(kCFAllocatorDefault, aID,
|
||||
kCFStringEncodingASCII);
|
||||
const void* keys[] = { kTISPropertyInputSourceID };
|
||||
const void* values[] = { idstr };
|
||||
CFDictionaryRef filter =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);
|
||||
NS_ASSERTION(filter, "failed to create the filter");
|
||||
mInputSourceList = ::TISCreateInputSourceList(filter, true);
|
||||
::CFRelease(filter);
|
||||
if (::CFArrayGetCount(mInputSourceList) > 0) {
|
||||
mInputSource = static_cast<TISInputSourceRef>(
|
||||
const_cast<void *>(::CFArrayGetValueAtIndex(mInputSourceList, 0)));
|
||||
}
|
||||
::CFRelease(idstr);
|
||||
}
|
||||
|
||||
void InitByLayoutID(SInt32 aLayoutID)
|
||||
{
|
||||
Clear();
|
||||
switch (aLayoutID) {
|
||||
case 0:
|
||||
InitByInputSourceID("com.apple.keylayout.US");
|
||||
break;
|
||||
case -18944:
|
||||
InitByInputSourceID("com.apple.keylayout.Greek");
|
||||
break;
|
||||
case 3:
|
||||
InitByInputSourceID("com.apple.keylayout.German");
|
||||
break;
|
||||
case 224:
|
||||
InitByInputSourceID("com.apple.keylayout.Swedish-Pro");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitByCurrentKeyboardLayout()
|
||||
{
|
||||
Clear();
|
||||
mInputSource = ::TISCopyCurrentKeyboardLayoutInputSource();
|
||||
}
|
||||
|
||||
void InitByTISInputSourceRef(TISInputSourceRef aInputSource)
|
||||
{
|
||||
Clear();
|
||||
mInputSource = aInputSource;
|
||||
}
|
||||
|
||||
const UCKeyboardLayout* GetUCKeyboardLayout()
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, nsnull);
|
||||
CFDataRef uchr = static_cast<CFDataRef>(
|
||||
::TISGetInputSourceProperty(mInputSource,
|
||||
kTISPropertyUnicodeKeyLayoutData));
|
||||
|
||||
// We should be always able to get the layout here.
|
||||
NS_ENSURE_TRUE(uchr, nsnull);
|
||||
return reinterpret_cast<const UCKeyboardLayout*>(CFDataGetBytePtr(uchr));
|
||||
}
|
||||
|
||||
PRBool IsASCIICapable()
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, nsnull);
|
||||
CFBooleanRef isASCIICapable = static_cast<CFBooleanRef>(
|
||||
::TISGetInputSourceProperty(mInputSource,
|
||||
kTISPropertyInputSourceIsASCIICapable));
|
||||
return CFBooleanGetValue(isASCIICapable);
|
||||
}
|
||||
|
||||
CFArrayRef GetLanguageList()
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, nsnull);
|
||||
return static_cast<CFArrayRef>(
|
||||
::TISGetInputSourceProperty(mInputSource,
|
||||
kTISPropertyInputSourceLanguages));
|
||||
}
|
||||
|
||||
void GetLocalizedName(nsAString &aName)
|
||||
{
|
||||
NS_PRECONDITION(mInputSource, "mInputSource is null");
|
||||
if (!mInputSource)
|
||||
return;
|
||||
CFStringRef name = static_cast<CFStringRef>(
|
||||
::TISGetInputSourceProperty(mInputSource, kTISPropertyLocalizedName));
|
||||
GetStringForNSString((const NSString*)name, aName);
|
||||
}
|
||||
|
||||
void GetInputSourceID(nsAString &aID)
|
||||
{
|
||||
NS_PRECONDITION(mInputSource, "mInputSource is null");
|
||||
if (!mInputSource)
|
||||
return;
|
||||
CFStringRef isid = static_cast<CFStringRef>(
|
||||
::TISGetInputSourceProperty(mInputSource, kTISPropertyInputSourceID));
|
||||
GetStringForNSString((const NSString*)isid, aID);
|
||||
}
|
||||
|
||||
protected:
|
||||
void Clear()
|
||||
{
|
||||
if (mInputSourceList) {
|
||||
::CFRelease(mInputSourceList);
|
||||
}
|
||||
mInputSourceList = nsnull;
|
||||
mInputSource = nsnull;
|
||||
}
|
||||
|
||||
void GetStringForNSString(const NSString *aSrc, nsAString& aDist)
|
||||
{
|
||||
aDist.SetLength([aSrc length]);
|
||||
[aSrc getCharacters: aDist.BeginWriting()];
|
||||
}
|
||||
|
||||
TISInputSourceRef mInputSource;
|
||||
CFArrayRef mInputSourceList;
|
||||
};
|
||||
|
||||
#else // LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
|
||||
struct __TISInputSource;
|
||||
|
@ -285,7 +120,14 @@ CFStringRef kOurTISPropertyUnicodeKeyLayoutData = NULL;
|
|||
CFStringRef kOurTISPropertyInputSourceID = NULL;
|
||||
CFStringRef kOurTISPropertyInputSourceLanguages = NULL;
|
||||
|
||||
#endif // LEOPARD_AND_LATER
|
||||
PRBool nsTSMManager::sIsIMEEnabled = PR_TRUE;
|
||||
PRBool nsTSMManager::sIsRomanKeyboardsOnly = PR_FALSE;
|
||||
PRBool nsTSMManager::sIgnoreCommit = PR_FALSE;
|
||||
NSView<mozView>* nsTSMManager::sComposingView = nsnull;
|
||||
TSMDocumentID nsTSMManager::sDocumentID = nsnull;
|
||||
NSString* nsTSMManager::sComposingString = nsnull;
|
||||
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
// these are defined in nsCocoaWindow.mm
|
||||
extern PRBool gConsumeRollupEvent;
|
||||
|
@ -294,12 +136,6 @@ PRBool gChildViewMethodsSwizzled = PR_FALSE;
|
|||
|
||||
extern nsISupportsArray *gDraggedTransferables;
|
||||
|
||||
PRBool nsTSMManager::sIsIMEEnabled = PR_TRUE;
|
||||
PRBool nsTSMManager::sIsRomanKeyboardsOnly = PR_FALSE;
|
||||
PRBool nsTSMManager::sIgnoreCommit = PR_FALSE;
|
||||
NSView<mozView>* nsTSMManager::sComposingView = nsnull;
|
||||
TSMDocumentID nsTSMManager::sDocumentID = nsnull;
|
||||
NSString* nsTSMManager::sComposingString = nsnull;
|
||||
ChildView* ChildViewMouseTracker::sLastMouseEventView = nil;
|
||||
|
||||
static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
|
||||
|
@ -635,49 +471,13 @@ FillTextRangeInTextEvent(nsTextEvent *aTextEvent, NSAttributedString* aString, N
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
#ifdef LEOPARD_AND_LATER
|
||||
|
||||
static CFArrayRef CreateAllKeyboardLayoutList()
|
||||
{
|
||||
const void* keys[] = { kTISPropertyInputSourceType };
|
||||
const void* values[] = { kTISTypeKeyboardLayout };
|
||||
CFDictionaryRef filter =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);
|
||||
NS_ASSERTION(filter, "failed to create the filter");
|
||||
CFArrayRef list = ::TISCreateInputSourceList(filter, true);
|
||||
::CFRelease(filter);
|
||||
return list;
|
||||
}
|
||||
|
||||
#endif // LEOPARD_AND_LATER
|
||||
|
||||
#if defined(DEBUG) && defined(PR_LOGGING)
|
||||
|
||||
static void DebugPrintAllKeyboardLayouts()
|
||||
{
|
||||
#ifdef LEOPARD_AND_LATER
|
||||
CFArrayRef list = CreateAllKeyboardLayoutList();
|
||||
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("Keyboard layout configuration:"));
|
||||
CFIndex idx = ::CFArrayGetCount(list);
|
||||
nsTISInputSource tis;
|
||||
for (CFIndex i = 0; i < idx; ++i) {
|
||||
TISInputSourceRef inputSource = static_cast<TISInputSourceRef>(
|
||||
const_cast<void *>(::CFArrayGetValueAtIndex(list, i)));
|
||||
tis.InitByTISInputSourceRef(inputSource);
|
||||
nsAutoString name;
|
||||
tis.GetLocalizedName(name);
|
||||
nsAutoString isid;
|
||||
tis.GetInputSourceID(isid);
|
||||
const UCKeyboardLayout* uchr = tis.GetUCKeyboardLayout();
|
||||
PRBool isASCII = tis.IsASCIICapable();
|
||||
PR_LOG(sCocoaLog, PR_LOG_ALWAYS,
|
||||
(" %s\t<%s>%s%s\n",
|
||||
NS_ConvertUTF16toUTF8(name).get(),
|
||||
NS_ConvertUTF16toUTF8(isid).get(),
|
||||
isASCII ? "" : "\t(Isn't ASCII capable)",
|
||||
uchr ? "" : "\t(uchr is NOT AVAILABLE)"));
|
||||
}
|
||||
::CFRelease(list);
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
nsCocoaTextInputHandler::DebugPrintAllKeyboardLayouts(sCocoaLog);
|
||||
nsCocoaIMEHandler::DebugPrintAllIMEModes(sCocoaLog);
|
||||
#else
|
||||
CFIndex idx;
|
||||
KLGetKeyboardLayoutCount(&idx);
|
||||
|
@ -697,7 +497,7 @@ static void DebugPrintAllKeyboardLayouts()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // LEOPARD_AND_LATER
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
}
|
||||
|
||||
#endif // defined(DEBUG) && defined(PR_LOGGING)
|
||||
|
@ -726,7 +526,7 @@ nsChildView::nsChildView() : nsBaseWidget()
|
|||
SetBackgroundColor(NS_RGB(255, 255, 255));
|
||||
SetForegroundColor(NS_RGB(0, 0, 0));
|
||||
|
||||
#ifndef LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
if (nsToolkit::OnLeopardOrLater() && !Leopard_TISCopyCurrentKeyboardLayoutInputSource) {
|
||||
// This libary would already be open for LMGetKbdType (and probably other
|
||||
// symbols), so merely using RTLD_DEFAULT in dlsym would be sufficient,
|
||||
|
@ -744,7 +544,7 @@ nsChildView::nsChildView() : nsBaseWidget()
|
|||
kOurTISPropertyInputSourceLanguages = *static_cast<CFStringRef*>(dlsym(hitoolboxHandle, "kTISPropertyInputSourceLanguages"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
}
|
||||
|
||||
nsChildView::~nsChildView()
|
||||
|
@ -842,6 +642,10 @@ nsresult nsChildView::Create(nsIWidget *aParent,
|
|||
if ([mView isKindOfClass:[ChildView class]])
|
||||
[[WindowDataMap sharedWindowDataMap] ensureDataForWindow:[mView window]];
|
||||
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
mTextInputHandler.Init(this);
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
@ -1903,18 +1707,18 @@ void nsChildView::Scroll(const nsIntPoint& aDelta,
|
|||
if (!mParentView)
|
||||
return;
|
||||
|
||||
#ifndef LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
BOOL viewWasDirty = mVisible && [mView needsDisplay];
|
||||
#endif
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
if (mVisible) {
|
||||
for (PRUint32 i = 0; i < aDestRects.Length(); ++i) {
|
||||
NSRect rect;
|
||||
GeckoRectToNSRect(aDestRects[i] - aDelta, rect);
|
||||
NSSize scrollVector = {aDelta.x, aDelta.y};
|
||||
[mView scrollRect:rect by:scrollVector];
|
||||
#ifdef LEOPARD_AND_LATER
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
[mView translateRectsNeedingDisplayInRect:rect by:scrollVector];
|
||||
#endif
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1931,11 +1735,11 @@ void nsChildView::Scroll(const nsIntPoint& aDelta,
|
|||
if (mOnDestroyCalled)
|
||||
return;
|
||||
|
||||
#ifndef LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
if (viewWasDirty) {
|
||||
[mView setNeedsDisplay:YES];
|
||||
}
|
||||
#endif
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
@ -1947,7 +1751,7 @@ NS_IMETHODIMP nsChildView::DispatchEvent(nsGUIEvent* event, nsEventStatus& aStat
|
|||
debug_DumpEvent(stdout, event->widget, event, nsCAutoString("something"), 0);
|
||||
#endif
|
||||
|
||||
NS_ASSERTION(!(nsTSMManager::IsComposing() && NS_IS_KEY_EVENT(event)),
|
||||
NS_ASSERTION(!(IME_IsComposing() && NS_IS_KEY_EVENT(event)),
|
||||
"Any key events should not be fired during IME composing");
|
||||
|
||||
aStatus = nsEventStatus_eIgnore;
|
||||
|
@ -2119,7 +1923,7 @@ NS_IMETHODIMP nsChildView::ResetInputState()
|
|||
NSLog(@"**** ResetInputState");
|
||||
#endif
|
||||
|
||||
nsTSMManager::CommitIME();
|
||||
IME_CommitComposition();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2130,7 +1934,7 @@ NS_IMETHODIMP nsChildView::SetIMEOpenState(PRBool aState)
|
|||
NSLog(@"**** SetIMEOpenState aState = %d", aState);
|
||||
#endif
|
||||
|
||||
nsTSMManager::SetIMEOpenState(aState);
|
||||
IME_SetOpenState(aState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2141,7 +1945,7 @@ NS_IMETHODIMP nsChildView::GetIMEOpenState(PRBool* aState)
|
|||
NSLog(@"**** GetIMEOpenState");
|
||||
#endif
|
||||
|
||||
*aState = nsTSMManager::GetIMEOpenState();
|
||||
*aState = IME_IsOpened();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2154,16 +1958,16 @@ NS_IMETHODIMP nsChildView::SetIMEEnabled(PRUint32 aState)
|
|||
switch (aState) {
|
||||
case nsIWidget::IME_STATUS_ENABLED:
|
||||
case nsIWidget::IME_STATUS_PLUGIN:
|
||||
nsTSMManager::SetRomanKeyboardsOnly(PR_FALSE);
|
||||
nsTSMManager::EnableIME(PR_TRUE);
|
||||
IME_SetASCIICapableOnly(PR_FALSE);
|
||||
IME_Enable(PR_TRUE);
|
||||
break;
|
||||
case nsIWidget::IME_STATUS_DISABLED:
|
||||
nsTSMManager::SetRomanKeyboardsOnly(PR_FALSE);
|
||||
nsTSMManager::EnableIME(PR_FALSE);
|
||||
IME_SetASCIICapableOnly(PR_FALSE);
|
||||
IME_Enable(PR_FALSE);
|
||||
break;
|
||||
case nsIWidget::IME_STATUS_PASSWORD:
|
||||
nsTSMManager::SetRomanKeyboardsOnly(PR_TRUE);
|
||||
nsTSMManager::EnableIME(PR_FALSE);
|
||||
IME_SetASCIICapableOnly(PR_TRUE);
|
||||
IME_Enable(PR_FALSE);
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("not implemented!");
|
||||
|
@ -2177,9 +1981,9 @@ NS_IMETHODIMP nsChildView::GetIMEEnabled(PRUint32* aState)
|
|||
NSLog(@"**** GetIMEEnabled");
|
||||
#endif
|
||||
|
||||
if (nsTSMManager::IsIMEEnabled())
|
||||
if (IME_IsEnabled())
|
||||
*aState = nsIWidget::IME_STATUS_ENABLED;
|
||||
else if (nsTSMManager::IsRomanKeyboardsOnly())
|
||||
else if (IME_IsASCIICapableOnly())
|
||||
*aState = nsIWidget::IME_STATUS_PASSWORD;
|
||||
else
|
||||
*aState = nsIWidget::IME_STATUS_DISABLED;
|
||||
|
@ -2193,7 +1997,7 @@ NS_IMETHODIMP nsChildView::CancelIMEComposition()
|
|||
NSLog(@"**** CancelIMEComposition");
|
||||
#endif
|
||||
|
||||
nsTSMManager::CancelIME();
|
||||
IME_CancelComposition();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2225,6 +2029,35 @@ NS_IMETHODIMP nsChildView::GetToggledKeyState(PRUint32 aKeyCode,
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsChildView::OnIMEFocusChange(PRBool aFocus)
|
||||
{
|
||||
mTextInputHandler.OnFocusChangeInGecko(aFocus);
|
||||
// XXX Return NS_ERROR_NOT_IMPLEMENTED, see bug 496360.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
|
||||
NSView<mozView>* nsChildView::GetEditorView()
|
||||
{
|
||||
NSView<mozView>* editorView = mView;
|
||||
// We need to get editor's view. E.g., when the focus is in the bookmark
|
||||
// dialog, the view is <panel> element of the dialog. At this time, the key
|
||||
// events are processed the parent window's view that has native focus.
|
||||
nsQueryContentEvent textContent(PR_TRUE, NS_QUERY_TEXT_CONTENT, this);
|
||||
textContent.InitForQueryTextContent(0, 0);
|
||||
DispatchWindowEvent(textContent);
|
||||
if (textContent.mSucceeded && textContent.mReply.mFocusedWidget) {
|
||||
NSView<mozView>* view = static_cast<NSView<mozView>*>(
|
||||
textContent.mReply.mFocusedWidget->GetNativeData(NS_NATIVE_WIDGET));
|
||||
if (view)
|
||||
editorView = view;
|
||||
}
|
||||
return editorView;
|
||||
}
|
||||
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
#pragma mark -
|
||||
|
||||
gfxASurface*
|
||||
|
@ -2417,7 +2250,7 @@ NSEvent* gLastDragEvent = nil;
|
|||
|
||||
- (void)widgetDestroyed
|
||||
{
|
||||
nsTSMManager::OnDestroyView(self);
|
||||
mGeckoChild->IME_OnDestroyView(self);
|
||||
ChildViewMouseTracker::OnDestroyView(self);
|
||||
mGeckoChild = nsnull;
|
||||
|
||||
|
@ -4122,7 +3955,7 @@ static PRBool IsNormalCharInputtingEvent(const nsKeyEvent& aEvent)
|
|||
|
||||
// #define DEBUG_KB 1
|
||||
|
||||
#ifndef LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
|
||||
#define CHARCODE_MASK_1 0x00FF0000
|
||||
#define CHARCODE_MASK_2 0x000000FF
|
||||
|
@ -4173,7 +4006,7 @@ KeyTranslateToUnicode(Handle aHandle, UInt32 aKeyCode, UInt32 aModifiers,
|
|||
return ch;
|
||||
}
|
||||
|
||||
#endif // LEOPARD_AND_LATER
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
static PRUint32
|
||||
UCKeyTranslateToUnicode(const UCKeyboardLayout* aHandle, UInt32 aKeyCode, UInt32 aModifiers,
|
||||
|
@ -4210,30 +4043,30 @@ struct KeyTranslateData {
|
|||
KeyTranslateData() {
|
||||
mUchr.mLayout = nsnull;
|
||||
mUchr.mKbType = 0;
|
||||
#ifndef LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
mKchr.mHandle = nsnull;
|
||||
mKchr.mEncoding = nsnull;
|
||||
#endif
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
}
|
||||
|
||||
#ifndef LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
// The script of the layout determines the encoding of characters obtained
|
||||
// from kchr resources.
|
||||
SInt16 mScript;
|
||||
// The keyboard layout identifier
|
||||
SInt32 mLayoutID;
|
||||
#endif // LEOPARD_AND_LATER
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
struct {
|
||||
const UCKeyboardLayout* mLayout;
|
||||
UInt32 mKbType;
|
||||
} mUchr;
|
||||
#ifndef LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
struct {
|
||||
Handle mHandle;
|
||||
TextEncoding mEncoding;
|
||||
} mKchr;
|
||||
#endif // LEOPARD_AND_LATER
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
};
|
||||
|
||||
static PRUint32
|
||||
|
@ -4244,16 +4077,16 @@ GetUniCharFromKeyTranslate(KeyTranslateData& aData,
|
|||
return UCKeyTranslateToUnicode(aData.mUchr.mLayout, aKeyCode, aModifiers,
|
||||
aData.mUchr.mKbType);
|
||||
}
|
||||
#ifndef LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
if (aData.mKchr.mHandle) {
|
||||
return KeyTranslateToUnicode(aData.mKchr.mHandle, aKeyCode, aModifiers,
|
||||
aData.mKchr.mEncoding);
|
||||
}
|
||||
#endif
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef LEOPARD_AND_LATER
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
|
||||
static SInt32
|
||||
GetScriptFromKeyboardLayout(SInt32 aLayoutID)
|
||||
|
@ -4332,12 +4165,12 @@ GetKCHRData(KeyTranslateData &aKT)
|
|||
aKT.mKchr.mHandle = nsnull;
|
||||
}
|
||||
|
||||
#endif // LEOPARD_AND_LATER
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
static PRUint32
|
||||
GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
||||
{
|
||||
#ifdef LEOPARD_AND_LATER
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
static const UCKeyboardLayout* sUSLayout = nsnull;
|
||||
if (!sUSLayout) {
|
||||
nsTISInputSource tis("com.apple.keylayout.US");
|
||||
|
@ -4358,7 +4191,7 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
UInt32 kbType = 40; // ANSI, don't use actual layout
|
||||
return UCKeyTranslateToUnicode(layout, aKeyCode,
|
||||
aModifiers, kbType);
|
||||
#endif // LEOPARD_AND_LATER
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
}
|
||||
|
||||
- (void) convertCocoaKeyEvent:(NSEvent*)aKeyEvent toGeckoEvent:(nsKeyEvent*)outGeckoEvent
|
||||
|
@ -4402,7 +4235,7 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
KeyTranslateData kt;
|
||||
|
||||
PRBool isRomanKeyboardLayout;
|
||||
#ifdef LEOPARD_AND_LATER
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
nsTISInputSource tis;
|
||||
if (gOverrideKeyboardLayout.mOverrideEnabled) {
|
||||
tis.InitByLayoutID(gOverrideKeyboardLayout.mKeyboardLayout);
|
||||
|
@ -4411,7 +4244,7 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
}
|
||||
kt.mUchr.mLayout = tis.GetUCKeyboardLayout();
|
||||
isRomanKeyboardLayout = tis.IsASCIICapable();
|
||||
#else // LEOPARD_AND_LATER
|
||||
#else // NS_LEOPARD_AND_LATER
|
||||
if (gOverrideKeyboardLayout.mOverrideEnabled) {
|
||||
kt.mLayoutID = gOverrideKeyboardLayout.mKeyboardLayout;
|
||||
kt.mScript = GetScriptFromKeyboardLayout(kt.mLayoutID);
|
||||
|
@ -4488,7 +4321,7 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
if (!isUchrKeyboardLayout) {
|
||||
GetKCHRData(kt);
|
||||
}
|
||||
#endif // LEOPARD_AND_LATER
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
// If a keyboard layout override is set, we also need to force the
|
||||
// keyboard type to something ANSI to avoid test failures on machines
|
||||
|
@ -4782,6 +4615,11 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
if (mGeckoChild->TextInputHandler()->IgnoreIMEComposition())
|
||||
return;
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
if (![insertString isKindOfClass:[NSAttributedString class]])
|
||||
|
@ -4789,14 +4627,14 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
|
||||
NSString *tmpStr = [insertString string];
|
||||
unsigned int len = [tmpStr length];
|
||||
if (!nsTSMManager::IsComposing() && len == 0)
|
||||
if (!mGeckoChild->IME_IsComposing() && len == 0)
|
||||
return; // nothing to do
|
||||
PRUnichar buffer[MAX_BUFFER_SIZE];
|
||||
PRUnichar *bufPtr = (len >= MAX_BUFFER_SIZE) ? new PRUnichar[len + 1] : buffer;
|
||||
[tmpStr getCharacters:bufPtr];
|
||||
bufPtr[len] = PRUnichar('\0');
|
||||
|
||||
if (len == 1 && !nsTSMManager::IsComposing()) {
|
||||
if (len == 1 && !mGeckoChild->IME_IsComposing()) {
|
||||
// don't let the same event be fired twice when hitting
|
||||
// enter/return! (Bug 420502)
|
||||
if (mKeyPressSent)
|
||||
|
@ -4856,14 +4694,14 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!nsTSMManager::IsComposing()) {
|
||||
if (!mGeckoChild->IME_IsComposing()) {
|
||||
[self sendCompositionEvent:NS_COMPOSITION_START];
|
||||
// Note: mGeckoChild might have become null here. Don't count on it from here on.
|
||||
nsTSMManager::StartComposing(self);
|
||||
mGeckoChild->IME_OnStartComposition(self);
|
||||
// Note: mGeckoChild might have become null here. Don't count on it from here on.
|
||||
}
|
||||
|
||||
if (nsTSMManager::IgnoreCommit()) {
|
||||
if (mGeckoChild->IME_IgnoreCommit()) {
|
||||
tmpStr = [tmpStr init];
|
||||
len = 0;
|
||||
bufPtr[0] = PRUnichar('\0');
|
||||
|
@ -4878,7 +4716,7 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
|
||||
[self sendCompositionEvent:NS_COMPOSITION_END];
|
||||
// Note: mGeckoChild might have become null here. Don't count on it from here on.
|
||||
nsTSMManager::EndComposing();
|
||||
mGeckoChild->IME_OnEndComposition();
|
||||
mMarkedRange = NSMakeRange(NSNotFound, 0);
|
||||
}
|
||||
|
||||
|
@ -4917,6 +4755,11 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
NSLog(@" aString = '%@'", aString);
|
||||
#endif
|
||||
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
if (mGeckoChild->TextInputHandler()->IgnoreIMEComposition())
|
||||
return;
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
if (![aString isKindOfClass:[NSAttributedString class]])
|
||||
|
@ -4941,18 +4784,18 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
|
||||
mMarkedRange.length = len;
|
||||
|
||||
if (!nsTSMManager::IsComposing() && len > 0) {
|
||||
if (!mGeckoChild->IME_IsComposing() && len > 0) {
|
||||
nsQueryContentEvent selection(PR_TRUE, NS_QUERY_SELECTED_TEXT, mGeckoChild);
|
||||
mGeckoChild->DispatchWindowEvent(selection);
|
||||
mMarkedRange.location = selection.mSucceeded ? selection.mReply.mOffset : 0;
|
||||
[self sendCompositionEvent:NS_COMPOSITION_START];
|
||||
// Note: mGeckoChild might have become null here. Don't count on it from here on.
|
||||
nsTSMManager::StartComposing(self);
|
||||
mGeckoChild->IME_OnStartComposition(self);
|
||||
// Note: mGeckoChild might have become null here. Don't count on it from here on.
|
||||
}
|
||||
|
||||
if (nsTSMManager::IsComposing()) {
|
||||
nsTSMManager::UpdateComposing(tmpStr);
|
||||
if (mGeckoChild->IME_IsComposing()) {
|
||||
mGeckoChild->IME_OnUpdateComposition(tmpStr);
|
||||
|
||||
BOOL commit = len == 0;
|
||||
[self sendTextEvent:bufPtr attributedString:aString
|
||||
|
@ -4963,7 +4806,7 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
|
||||
if (commit) {
|
||||
[self sendCompositionEvent:NS_COMPOSITION_END];
|
||||
nsTSMManager::EndComposing();
|
||||
mGeckoChild->IME_OnEndComposition();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4979,7 +4822,7 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
NSLog(@"****in unmarkText");
|
||||
NSLog(@" markedRange = %d, %d", mMarkedRange.location, mMarkedRange.length);
|
||||
#endif
|
||||
nsTSMManager::CommitIME();
|
||||
mGeckoChild->IME_CommitComposition();
|
||||
}
|
||||
|
||||
- (BOOL) hasMarkedText
|
||||
|
@ -5224,7 +5067,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
mCurKeyEvent = theEvent;
|
||||
|
||||
BOOL nonDeadKeyPress = [[theEvent characters] length] > 0;
|
||||
if (nonDeadKeyPress && !nsTSMManager::IsComposing()) {
|
||||
if (nonDeadKeyPress && !mGeckoChild->IME_IsComposing()) {
|
||||
if (![theEvent isARepeat]) {
|
||||
NSResponder* firstResponder = [[self window] firstResponder];
|
||||
|
||||
|
@ -5282,7 +5125,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
// control-letter combinations etc before Cocoa tries to use
|
||||
// them for keybindings.
|
||||
if ((!geckoEvent.isChar || geckoEvent.isControl) &&
|
||||
!nsTSMManager::IsComposing()) {
|
||||
!mGeckoChild->IME_IsComposing()) {
|
||||
if (mKeyDownHandled)
|
||||
geckoEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
|
||||
|
@ -5308,10 +5151,10 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
// Let Cocoa interpret the key events, caching IsComposing first.
|
||||
// We don't do it if this came from performKeyEquivalent because
|
||||
// interpretKeyEvents isn't set up to handle those key combinations.
|
||||
PRBool wasComposing = nsTSMManager::IsComposing();
|
||||
PRBool wasComposing = mGeckoChild->IME_IsComposing();
|
||||
PRBool interpretKeyEventsCalled = PR_FALSE;
|
||||
if (!isKeyEquiv &&
|
||||
(nsTSMManager::IsIMEEnabled() || nsTSMManager::IsRomanKeyboardsOnly())) {
|
||||
(mGeckoChild->IME_IsEnabled() || mGeckoChild->IME_IsASCIICapableOnly())) {
|
||||
[super interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
|
||||
interpretKeyEventsCalled = PR_TRUE;
|
||||
}
|
||||
|
@ -5319,7 +5162,8 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
if (!mGeckoChild)
|
||||
return (mKeyDownHandled || mKeyPressHandled);;
|
||||
|
||||
if (!mKeyPressSent && nonDeadKeyPress && !wasComposing && !nsTSMManager::IsComposing()) {
|
||||
if (!mKeyPressSent && nonDeadKeyPress && !wasComposing &&
|
||||
!mGeckoChild->IME_IsComposing()) {
|
||||
nsKeyEvent geckoEvent(PR_TRUE, NS_KEY_PRESS, nsnull);
|
||||
[self convertCocoaKeyEvent:theEvent toGeckoEvent:&geckoEvent];
|
||||
|
||||
|
@ -5366,6 +5210,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
// We need to get actual focused view. E.g., the view is in bookmark dialog
|
||||
// that is <panel> element. Then, the key events are processed the parent
|
||||
// window's view that has native focus.
|
||||
|
@ -5382,6 +5227,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
focusedView = view;
|
||||
}
|
||||
nsTSMManager::InitTSMDocument(focusedView);
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
}
|
||||
|
||||
// Create a TSM document for use with plugins, so that we can support IME in
|
||||
|
@ -5512,7 +5358,7 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
|||
}
|
||||
|
||||
// if we don't have any characters we can't generate a keyUp event
|
||||
if ([[theEvent characters] length] == 0 || nsTSMManager::IsComposing())
|
||||
if ([[theEvent characters] length] == 0 || mGeckoChild->IME_IsComposing())
|
||||
return;
|
||||
|
||||
// Cocoa doesn't send an NSKeyDown event for control-tab on 10.4, so if this
|
||||
|
@ -5598,7 +5444,7 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
|||
}
|
||||
|
||||
// don't process if we're composing, but don't consume the event
|
||||
if (nsTSMManager::IsComposing())
|
||||
if (mGeckoChild->IME_IsComposing())
|
||||
return NO;
|
||||
|
||||
UInt32 modifierFlags =
|
||||
|
@ -5750,7 +5596,7 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
|||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (!mGeckoChild || [theEvent type] != NSFlagsChanged ||
|
||||
nsTSMManager::IsComposing())
|
||||
mGeckoChild->IME_IsComposing())
|
||||
return;
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
@ -6351,6 +6197,8 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
|||
|
||||
@end
|
||||
|
||||
#ifndef NS_LEOPARD_AND_LATER
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void
|
||||
|
@ -6382,11 +6230,6 @@ static const NSString* GetCurrentIMELanguage()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef LEOPARD_AND_LATER
|
||||
nsTISInputSource tis;
|
||||
tis.InitByCurrentKeyboardLayout();
|
||||
CFArrayRef langs = tis.GetLanguageList();
|
||||
#else
|
||||
NS_PRECONDITION(Leopard_TISCopyCurrentKeyboardInputSource,
|
||||
"Leopard_TISCopyCurrentKeyboardInputSource is not initialized");
|
||||
TISInputSourceRef inputSource = Leopard_TISCopyCurrentKeyboardInputSource();
|
||||
|
@ -6400,7 +6243,6 @@ static const NSString* GetCurrentIMELanguage()
|
|||
CFArrayRef langs = static_cast<CFArrayRef>(
|
||||
Leopard_TISGetInputSourceProperty(inputSource,
|
||||
kOurTISPropertyInputSourceLanguages));
|
||||
#endif // LEOPARD_AND_LATER
|
||||
return static_cast<const NSString*>(CFArrayGetValueAtIndex(langs, 0));
|
||||
}
|
||||
|
||||
|
@ -6567,6 +6409,8 @@ nsTSMManager::CancelIME()
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,326 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 et tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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
|
||||
* Mozilla Japan.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* 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"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsCocoaTextInputHandler_h_
|
||||
#define nsCocoaTextInputHandler_h_
|
||||
|
||||
#include "nsCocoaUtils.h"
|
||||
|
||||
#ifdef NS_LEOPARD_AND_LATER
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include "mozView.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITimer.h"
|
||||
#include "npapi.h"
|
||||
|
||||
struct PRLogModuleInfo;
|
||||
class nsChildView;
|
||||
|
||||
/**
|
||||
* nsTISInputSource is a wrapper for the TISInputSourceRef. If we get the
|
||||
* TISInputSourceRef from InputSourceID, we need to release the CFArray instance
|
||||
* which is returned by TISCreateInputSourceList. However, when we release the
|
||||
* list, we cannot access the TISInputSourceRef. So, it's not usable, and it
|
||||
* may cause the memory leak bugs. nsTISInputSource automatically releases the
|
||||
* list when the instance is destroyed.
|
||||
*/
|
||||
class nsTISInputSource
|
||||
{
|
||||
public:
|
||||
nsTISInputSource()
|
||||
{
|
||||
mInputSourceList = nsnull;
|
||||
Clear();
|
||||
}
|
||||
|
||||
nsTISInputSource(const char* aID)
|
||||
{
|
||||
mInputSourceList = nsnull;
|
||||
InitByInputSourceID(aID);
|
||||
}
|
||||
|
||||
nsTISInputSource(SInt32 aLayoutID)
|
||||
{
|
||||
mInputSourceList = nsnull;
|
||||
InitByLayoutID(aLayoutID);
|
||||
}
|
||||
|
||||
nsTISInputSource(TISInputSourceRef aInputSource)
|
||||
{
|
||||
mInputSourceList = nsnull;
|
||||
InitByTISInputSourceRef(aInputSource);
|
||||
}
|
||||
|
||||
~nsTISInputSource() { Clear(); }
|
||||
|
||||
void InitByInputSourceID(const char* aID);
|
||||
void InitByInputSourceID(const nsAFlatString &aID);
|
||||
void InitByInputSourceID(const CFStringRef aID);
|
||||
void InitByLayoutID(SInt32 aLayoutID);
|
||||
void InitByCurrentInputSource();
|
||||
void InitByCurrentKeyboardLayout();
|
||||
void InitByCurrentASCIICapableInputSource();
|
||||
void InitByCurrentASCIICapableKeyboardLayout();
|
||||
void InitByTISInputSourceRef(TISInputSourceRef aInputSource);
|
||||
void InitByLanguage(CFStringRef aLanguage);
|
||||
|
||||
const UCKeyboardLayout* GetUCKeyboardLayout();
|
||||
|
||||
PRBool IsOpenedIMEMode();
|
||||
PRBool IsIMEMode();
|
||||
|
||||
PRBool IsASCIICapable()
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetBoolProperty(kTISPropertyInputSourceIsASCIICapable);
|
||||
}
|
||||
|
||||
PRBool IsEnabled()
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetBoolProperty(kTISPropertyInputSourceIsEnabled);
|
||||
}
|
||||
|
||||
PRBool GetLanguageList(CFArrayRef &aLanguageList);
|
||||
PRBool GetPrimaryLanguage(CFStringRef &aPrimaryLanguage);
|
||||
PRBool GetPrimaryLanguage(nsAString &aPrimaryLanguage);
|
||||
|
||||
PRBool GetLocalizedName(CFStringRef &aName)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetStringProperty(kTISPropertyLocalizedName, aName);
|
||||
}
|
||||
|
||||
PRBool GetLocalizedName(nsAString &aName)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetStringProperty(kTISPropertyLocalizedName, aName);
|
||||
}
|
||||
|
||||
PRBool GetInputSourceID(CFStringRef &aID)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetStringProperty(kTISPropertyInputSourceID, aID);
|
||||
}
|
||||
|
||||
PRBool GetInputSourceID(nsAString &aID)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetStringProperty(kTISPropertyInputSourceID, aID);
|
||||
}
|
||||
|
||||
PRBool GetBundleID(CFStringRef &aBundleID)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetStringProperty(kTISPropertyBundleID, aBundleID);
|
||||
}
|
||||
|
||||
PRBool GetBundleID(nsAString &aBundleID)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetStringProperty(kTISPropertyBundleID, aBundleID);
|
||||
}
|
||||
|
||||
PRBool GetInputSourceType(CFStringRef &aType)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetStringProperty(kTISPropertyInputSourceType, aType);
|
||||
}
|
||||
|
||||
PRBool GetInputSourceType(nsAString &aType)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInputSource, PR_FALSE);
|
||||
return GetStringProperty(kTISPropertyInputSourceType, aType);
|
||||
}
|
||||
|
||||
void Select();
|
||||
|
||||
protected:
|
||||
void Clear();
|
||||
|
||||
PRBool GetBoolProperty(const CFStringRef aKey);
|
||||
PRBool GetStringProperty(const CFStringRef aKey, CFStringRef &aStr);
|
||||
PRBool GetStringProperty(const CFStringRef aKey, nsAString &aStr);
|
||||
|
||||
TISInputSourceRef mInputSource;
|
||||
CFArrayRef mInputSourceList;
|
||||
};
|
||||
|
||||
/**
|
||||
* nsCocoaIMEHandler manages:
|
||||
* 1. The IME/keyboard layout statement of nsChildView.
|
||||
* 2. The IME composition statement of nsChildView.
|
||||
* And also provides the methods which controls the current IME transaction of
|
||||
* the instance.
|
||||
*
|
||||
* Note that an nsChildView handles one or more NSView's events. E.g., even if
|
||||
* a text editor on XUL panel element, the input events handled on the parent
|
||||
* (or its ancestor) widget handles it (the native focus is set to it). The
|
||||
* actual focused view is notified by OnFocusChangeInGecko.
|
||||
*
|
||||
* NOTE: This class must not be used directly. The purpose of this class is
|
||||
* to protect the IME related code from non-IME using developers.
|
||||
* Use nsCocoaTextInputHandler class which inherits this class.
|
||||
*/
|
||||
|
||||
class nsCocoaIMEHandler
|
||||
{
|
||||
public:
|
||||
nsCocoaIMEHandler();
|
||||
virtual ~nsCocoaIMEHandler();
|
||||
|
||||
virtual void Init(nsChildView* aOwner);
|
||||
|
||||
virtual void OnFocusChangeInGecko(PRBool aFocus);
|
||||
virtual void OnDestroyView(NSView<mozView> *aDestroyingView);
|
||||
|
||||
void OnStartIMEComposition(NSView<mozView> *aView);
|
||||
void OnUpdateIMEComposition(NSString* aIMECompositionString);
|
||||
void OnEndIMEComposition();
|
||||
|
||||
PRBool IsIMEComposing() { return mIsIMEComposing; }
|
||||
PRBool IsIMEOpened();
|
||||
PRBool IsIMEEnabled() { return mIsIMEEnabled; }
|
||||
PRBool IsASCIICapableOnly() { return mIsASCIICapableOnly; }
|
||||
PRBool IgnoreIMECommit() { return mIgnoreIMECommit; }
|
||||
|
||||
PRBool IgnoreIMEComposition()
|
||||
{
|
||||
// Ignore the IME composition events when we're pending to discard the
|
||||
// composition and we are not to handle the IME composition now.
|
||||
return (mPendingMethods & kDiscardIMEComposition) &&
|
||||
(mIsInFocusProcessing || !IsFocused());
|
||||
}
|
||||
|
||||
void CommitIMEComposition();
|
||||
void CancelIMEComposition();
|
||||
|
||||
void EnableIME(PRBool aEnableIME);
|
||||
void SetIMEOpenState(PRBool aOpen);
|
||||
void SetASCIICapableOnly(PRBool aASCIICapableOnly);
|
||||
|
||||
static CFArrayRef CreateAllIMEModeList();
|
||||
static void DebugPrintAllIMEModes(PRLogModuleInfo* aLogModuleInfo);
|
||||
|
||||
protected:
|
||||
// The owner of this instance. The result of mOwnerWidget->TextInputHandler
|
||||
// returns this instance. This must not be null after initialized.
|
||||
nsChildView* mOwnerWidget;
|
||||
|
||||
// The native focused view, this is the native NSView of mOwnerWidget.
|
||||
// This view handling the actual text inputting.
|
||||
NSView<mozView>* mView;
|
||||
|
||||
// We cannot do some jobs in the given stack by some reasons.
|
||||
// Following flags and the timer provide the execution pending mechanism,
|
||||
// See the comment in nsCocoaTextInputHandler.mm.
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
enum {
|
||||
kResetIMEWindowLevel = 1,
|
||||
kDiscardIMEComposition = 2,
|
||||
kSyncASCIICapableOnly = 4
|
||||
};
|
||||
PRUint32 mPendingMethods;
|
||||
|
||||
PRBool IsFocused();
|
||||
void ResetTimer();
|
||||
|
||||
virtual void ExecutePendingMethods();
|
||||
|
||||
private:
|
||||
// If mIsIMEComposing is true, the composition string is stored here.
|
||||
NSString* mIMECompositionString;
|
||||
|
||||
PRPackedBool mIsIMEComposing;
|
||||
PRPackedBool mIsIMEEnabled;
|
||||
PRPackedBool mIsASCIICapableOnly;
|
||||
PRPackedBool mIgnoreIMECommit;
|
||||
// This flag is enabled by OnFocusChangeInGecko, and will be cleared by
|
||||
// ExecutePendingMethods. When this is true, IsFocus() returns TRUE. At
|
||||
// that time, the focus processing in Gecko might not be finished yet. So,
|
||||
// you cannot use nsQueryContentEvent or something.
|
||||
PRPackedBool mIsInFocusProcessing;
|
||||
|
||||
void KillIMEComposition();
|
||||
void SendCommittedText(NSString *aString);
|
||||
void OpenSystemPreferredLanguageIME();
|
||||
|
||||
// Pending methods
|
||||
void ResetIMEWindowLevel();
|
||||
void DiscardIMEComposition();
|
||||
void SyncASCIICapableOnly();
|
||||
|
||||
static PRBool sStaticMembersInitialized;
|
||||
static CFStringRef sLatestIMEOpenedModeInputSourceID;
|
||||
static void InitStaticMembers();
|
||||
static void OnCurrentTextInputSourceChange(CFNotificationCenterRef aCenter,
|
||||
void* aObserver,
|
||||
CFStringRef aName,
|
||||
const void* aObject,
|
||||
CFDictionaryRef aUserInfo);
|
||||
|
||||
static void FlushPendingMethods(nsITimer* aTimer, void* aClosure);
|
||||
|
||||
// The focused IME handler. Please note that the handler might lost the
|
||||
// actual focus by deactivating the application. If we are active, this
|
||||
// must have the actual focused handle.
|
||||
// We cannot access to the NSInputManager during we aren't active, so, the
|
||||
// focused handler can have an IME transaction even if we are deactive.
|
||||
static nsCocoaIMEHandler* sFocusedIMEHandler;
|
||||
};
|
||||
|
||||
/**
|
||||
* nsCocoaTextInputHandler is going to implement the NSTextInput protocol.
|
||||
*/
|
||||
class nsCocoaTextInputHandler : public nsCocoaIMEHandler
|
||||
{
|
||||
public:
|
||||
static CFArrayRef CreateAllKeyboardLayoutList();
|
||||
static void DebugPrintAllKeyboardLayouts(PRLogModuleInfo* aLogModuleInfo);
|
||||
|
||||
nsCocoaTextInputHandler();
|
||||
virtual ~nsCocoaTextInputHandler();
|
||||
};
|
||||
|
||||
#endif // NS_LEOPARD_AND_LATER
|
||||
|
||||
#endif // nsCocoaTextInputHandler_h_
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -43,6 +43,10 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
|
||||
#define NS_LEOPARD_AND_LATER 1
|
||||
#endif
|
||||
|
||||
#include "nsRect.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче