зеркало из https://github.com/mozilla/gecko-dev.git
Bug 519972 part 6: Make TextInputHandler grabbed by nsChildView and its methods which dispatch events r=smichaud
This commit is contained in:
Родитель
6caadfb6f9
Коммит
34e8fcc741
|
@ -218,38 +218,55 @@ protected:
|
|||
class TextInputHandlerBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Init must be called when aOwner is initializing and finished attaching
|
||||
* an NSView.
|
||||
*
|
||||
* @param aOwner An owner nsChildView of the instance.
|
||||
*/
|
||||
virtual void Init(nsChildView* aOwner);
|
||||
nsrefcnt AddRef()
|
||||
{
|
||||
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "mRefCnt is negative");
|
||||
++mRefCnt;
|
||||
NS_LOG_ADDREF(this, mRefCnt, "TextInputHandlerBase", sizeof(*this));
|
||||
return mRefCnt;
|
||||
}
|
||||
nsrefcnt Release()
|
||||
{
|
||||
NS_PRECONDITION(mRefCnt != 0, "mRefCnt is alrady zero");
|
||||
--mRefCnt;
|
||||
NS_LOG_RELEASE(this, mRefCnt, "TextInputHandlerBase");
|
||||
if (mRefCnt == 0) {
|
||||
mRefCnt = 1; /* stabilize */
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* OnDestroyView must be called when mOwnerWidget is destroying and detaching
|
||||
* mView.
|
||||
protected:
|
||||
nsAutoRefCnt mRefCnt;
|
||||
|
||||
public:
|
||||
/**
|
||||
* mWidget must not be destroyed without OnDestroyWidget being called.
|
||||
*
|
||||
* @param aDestroyingView Destroying view. This might not be mView.
|
||||
* @param aDestroyingWidget Destroying widget. This might not be mWidget.
|
||||
* @return This result doesn't have any meaning for
|
||||
* callers. When the aDstroyingView isn't same
|
||||
* as mView, FALSE. Then, inherited methods in
|
||||
* callers. When aDstroyingWidget isn't the same
|
||||
* as mWidget, FALSE. Then, inherited methods in
|
||||
* sub classes should return from this method
|
||||
* without cleaning up.
|
||||
*/
|
||||
virtual PRBool OnDestroyView(NSView<mozView> *aDestroyingView);
|
||||
virtual PRBool OnDestroyWidget(nsChildView* aDestroyingWidget);
|
||||
|
||||
protected:
|
||||
// The owner of this instance. The result of mOwnerWidget->TextInputHandler
|
||||
// returns this instance. This must not be null after initialized.
|
||||
nsChildView* mOwnerWidget;
|
||||
// The creater of this instance and client.
|
||||
// This must not be null after initialized until OnDestroyWidget() is called.
|
||||
nsChildView* mWidget; // [WEAK]
|
||||
|
||||
// The native focused view, this is the native NSView of mOwnerWidget.
|
||||
// The native view for mWidget.
|
||||
// This view handles the actual text inputting.
|
||||
NSView<mozView>* mView;
|
||||
NSView<mozView>* mView; // [STRONG]
|
||||
|
||||
TextInputHandlerBase();
|
||||
TextInputHandlerBase(nsChildView* aWidget, NSView<mozView> *aNativeView);
|
||||
virtual ~TextInputHandlerBase();
|
||||
|
||||
PRBool Destroyed() { return !mWidget; }
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -259,7 +276,7 @@ protected:
|
|||
class PluginTextInputHandler : public TextInputHandlerBase
|
||||
{
|
||||
protected:
|
||||
PluginTextInputHandler();
|
||||
PluginTextInputHandler(nsChildView* aWidget, NSView<mozView> *aNativeView);
|
||||
~PluginTextInputHandler();
|
||||
};
|
||||
|
||||
|
@ -279,12 +296,12 @@ protected:
|
|||
class IMEInputHandler : public PluginTextInputHandler
|
||||
{
|
||||
public:
|
||||
virtual PRBool OnDestroyView(NSView<mozView> *aDestroyingView);
|
||||
virtual PRBool OnDestroyWidget(nsChildView* aDestroyingWidget);
|
||||
|
||||
virtual void OnFocusChangeInGecko(PRBool aFocus);
|
||||
|
||||
/**
|
||||
* DispatchTextEvent() dispatches a text event on mOwnerWidget.
|
||||
* DispatchTextEvent() dispatches a text event on mWidget.
|
||||
*
|
||||
* @param aText User text input.
|
||||
* @param aAttrString An NSAttributedString instance which indicates
|
||||
|
@ -436,7 +453,7 @@ protected:
|
|||
};
|
||||
PRUint32 mPendingMethods;
|
||||
|
||||
IMEInputHandler();
|
||||
IMEInputHandler(nsChildView* aWidget, NSView<mozView> *aNativeView);
|
||||
virtual ~IMEInputHandler();
|
||||
|
||||
PRBool IsFocused();
|
||||
|
@ -560,7 +577,7 @@ public:
|
|||
static CFArrayRef CreateAllKeyboardLayoutList();
|
||||
static void DebugPrintAllKeyboardLayouts(PRLogModuleInfo* aLogModuleInfo);
|
||||
|
||||
TextInputHandler();
|
||||
TextInputHandler(nsChildView* aWidget, NSView<mozView> *aNativeView);
|
||||
virtual ~TextInputHandler();
|
||||
};
|
||||
|
||||
|
|
|
@ -560,13 +560,16 @@ TextInputHandler::DebugPrintAllKeyboardLayouts(PRLogModuleInfo* aLogModuleInfo)
|
|||
*
|
||||
******************************************************************************/
|
||||
|
||||
TextInputHandler::TextInputHandler() :
|
||||
IMEInputHandler()
|
||||
TextInputHandler::TextInputHandler(nsChildView* aWidget,
|
||||
NSView<mozView> *aNativeView) :
|
||||
IMEInputHandler(aWidget, aNativeView)
|
||||
{
|
||||
[mView installTextInputHandler:this];
|
||||
}
|
||||
|
||||
TextInputHandler::~TextInputHandler()
|
||||
{
|
||||
[mView uninstallTextInputHandler];
|
||||
}
|
||||
|
||||
|
||||
|
@ -741,8 +744,9 @@ IMEInputHandler::ResetIMEWindowLevel()
|
|||
TrueOrFalse(IsFocused()), GetCurrentTSMDocumentID());
|
||||
#endif // DEBUG_IME_HANDLER
|
||||
|
||||
if (!mView)
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsFocused()) {
|
||||
// retry at next focus event
|
||||
|
@ -763,7 +767,7 @@ IMEInputHandler::ResetIMEWindowLevel()
|
|||
// focused view is the panel's parent view (mView). But the editor is
|
||||
// displayed on the popuped widget's view (editorView). So, their window
|
||||
// level may be different.
|
||||
NSView<mozView>* editorView = mOwnerWidget->GetEditorView();
|
||||
NSView<mozView>* editorView = mWidget->GetEditorView();
|
||||
if (!editorView) {
|
||||
NS_ERROR("editorView is null");
|
||||
return;
|
||||
|
@ -801,8 +805,9 @@ IMEInputHandler::DiscardIMEComposition()
|
|||
NSLog(@" currentInputManager:%p", [NSInputManager currentInputManager]);
|
||||
#endif // DEBUG_IME_HANDLER
|
||||
|
||||
if (!mView)
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsFocused()) {
|
||||
// retry at next focus event
|
||||
|
@ -838,8 +843,9 @@ IMEInputHandler::SyncASCIICapableOnly()
|
|||
TrueOrFalse(IsFocused()), GetCurrentTSMDocumentID());
|
||||
#endif
|
||||
|
||||
if (!mView)
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsFocused()) {
|
||||
// retry at next focus event
|
||||
|
@ -1041,7 +1047,11 @@ IMEInputHandler::DispatchTextEvent(const nsString& aText,
|
|||
aSelectedRange.location, aSelectedRange.length);
|
||||
#endif
|
||||
|
||||
nsTextEvent textEvent(PR_TRUE, NS_TEXT_TEXT, mOwnerWidget);
|
||||
NS_ENSURE_TRUE(!Destroyed(), PR_FALSE);
|
||||
|
||||
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
nsTextEvent textEvent(PR_TRUE, NS_TEXT_TEXT, mWidget);
|
||||
textEvent.time = PR_IntervalNow();
|
||||
textEvent.theText = aText;
|
||||
nsAutoTArray<nsTextRange, 4> textRanges;
|
||||
|
@ -1051,7 +1061,7 @@ IMEInputHandler::DispatchTextEvent(const nsString& aText,
|
|||
textEvent.rangeArray = textRanges.Elements();
|
||||
textEvent.rangeCount = textRanges.Length();
|
||||
|
||||
return mOwnerWidget->DispatchWindowEvent(textEvent);
|
||||
return mWidget->DispatchWindowEvent(textEvent);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1071,7 +1081,11 @@ IMEInputHandler::InsertTextAsCommittingComposition(
|
|||
NSLog(@" mMarkedRange = %d, %d", mMarkedRange.location, mMarkedRange.length);
|
||||
#endif
|
||||
|
||||
nsRefPtr<nsChildView> kungFuDeathGrip(mOwnerWidget);
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
nsString str;
|
||||
GetStringForNSString([aAttrString string], str);
|
||||
|
@ -1079,12 +1093,12 @@ IMEInputHandler::InsertTextAsCommittingComposition(
|
|||
if (!IsIMEComposing()) {
|
||||
// XXXmnakano Probably, we shouldn't emulate composition in this case.
|
||||
// I think that we should just fire DOM3 textInput event if we implement it.
|
||||
nsCompositionEvent compStart(PR_TRUE, NS_COMPOSITION_START, mOwnerWidget);
|
||||
nsCompositionEvent compStart(PR_TRUE, NS_COMPOSITION_START, mWidget);
|
||||
InitCompositionEvent(compStart);
|
||||
|
||||
mOwnerWidget->DispatchWindowEvent(compStart);
|
||||
if (!mView) {
|
||||
return; // we're destroyed
|
||||
mWidget->DispatchWindowEvent(compStart);
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OnStartIMEComposition();
|
||||
|
@ -1096,17 +1110,17 @@ IMEInputHandler::InsertTextAsCommittingComposition(
|
|||
|
||||
NSRange range = NSMakeRange(0, str.Length());
|
||||
DispatchTextEvent(str, aAttrString, range, PR_TRUE);
|
||||
if (!mView) {
|
||||
return; // we're destroyed
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OnUpdateIMEComposition([aAttrString string]);
|
||||
|
||||
nsCompositionEvent compEnd(PR_TRUE, NS_COMPOSITION_END, mOwnerWidget);
|
||||
nsCompositionEvent compEnd(PR_TRUE, NS_COMPOSITION_END, mWidget);
|
||||
InitCompositionEvent(compEnd);
|
||||
mOwnerWidget->DispatchWindowEvent(compEnd);
|
||||
if (!mView) {
|
||||
return; // we're destroyed
|
||||
mWidget->DispatchWindowEvent(compEnd);
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OnEndIMEComposition();
|
||||
|
@ -1129,11 +1143,11 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString,
|
|||
NSLog(@" aAttrString = '%@'", aAttrString);
|
||||
#endif
|
||||
|
||||
if (IgnoreIMEComposition()) {
|
||||
if (Destroyed() || IgnoreIMEComposition()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsChildView> kungFuDeathGrip(mOwnerWidget);
|
||||
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
nsString str;
|
||||
GetStringForNSString([aAttrString string], str);
|
||||
|
@ -1142,16 +1156,16 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString,
|
|||
|
||||
if (!IsIMEComposing() && !str.IsEmpty()) {
|
||||
nsQueryContentEvent selection(PR_TRUE, NS_QUERY_SELECTED_TEXT,
|
||||
mOwnerWidget);
|
||||
mOwnerWidget->DispatchWindowEvent(selection);
|
||||
mWidget);
|
||||
mWidget->DispatchWindowEvent(selection);
|
||||
mMarkedRange.location = selection.mSucceeded ? selection.mReply.mOffset : 0;
|
||||
|
||||
nsCompositionEvent compStart(PR_TRUE, NS_COMPOSITION_START, mOwnerWidget);
|
||||
nsCompositionEvent compStart(PR_TRUE, NS_COMPOSITION_START, mWidget);
|
||||
InitCompositionEvent(compStart);
|
||||
|
||||
mOwnerWidget->DispatchWindowEvent(compStart);
|
||||
if (!mView) {
|
||||
return; // we're destroyed
|
||||
mWidget->DispatchWindowEvent(compStart);
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OnStartIMEComposition();
|
||||
|
@ -1162,16 +1176,16 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString,
|
|||
|
||||
PRBool doCommit = str.IsEmpty();
|
||||
DispatchTextEvent(str, aAttrString, aSelectedRange, doCommit);
|
||||
if (!mView) {
|
||||
return; // we're destroyed
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (doCommit) {
|
||||
nsCompositionEvent compEnd(PR_TRUE, NS_COMPOSITION_END, mOwnerWidget);
|
||||
nsCompositionEvent compEnd(PR_TRUE, NS_COMPOSITION_END, mWidget);
|
||||
InitCompositionEvent(compEnd);
|
||||
mOwnerWidget->DispatchWindowEvent(compEnd);
|
||||
if (!mView) {
|
||||
return; // we're destroyed
|
||||
mWidget->DispatchWindowEvent(compEnd);
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
OnEndIMEComposition();
|
||||
}
|
||||
|
@ -1183,10 +1197,16 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString,
|
|||
NSInteger
|
||||
IMEInputHandler::ConversationIdentifier()
|
||||
{
|
||||
if (Destroyed()) {
|
||||
return reinterpret_cast<NSInteger>(mView);
|
||||
}
|
||||
|
||||
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
// NOTE: The size of NSInteger is same as pointer size.
|
||||
nsQueryContentEvent textContent(PR_TRUE, NS_QUERY_TEXT_CONTENT, mOwnerWidget);
|
||||
nsQueryContentEvent textContent(PR_TRUE, NS_QUERY_TEXT_CONTENT, mWidget);
|
||||
textContent.InitForQueryTextContent(0, 0);
|
||||
mOwnerWidget->DispatchWindowEvent(textContent);
|
||||
mWidget->DispatchWindowEvent(textContent);
|
||||
if (!textContent.mSucceeded) {
|
||||
return reinterpret_cast<NSInteger>(mView);
|
||||
}
|
||||
|
@ -1205,14 +1225,16 @@ IMEInputHandler::GetAttributedSubstringFromRange(NSRange& aRange)
|
|||
NSLog(@" aRange = %d, %d", aRange.location, aRange.length);
|
||||
#endif
|
||||
|
||||
if (aRange.location == NSNotFound || aRange.length == 0) {
|
||||
if (Destroyed() || aRange.location == NSNotFound || aRange.length == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
nsAutoString str;
|
||||
nsQueryContentEvent textContent(PR_TRUE, NS_QUERY_TEXT_CONTENT, mOwnerWidget);
|
||||
nsQueryContentEvent textContent(PR_TRUE, NS_QUERY_TEXT_CONTENT, mWidget);
|
||||
textContent.InitForQueryTextContent(aRange.location, aRange.length);
|
||||
mOwnerWidget->DispatchWindowEvent(textContent);
|
||||
mWidget->DispatchWindowEvent(textContent);
|
||||
|
||||
if (!textContent.mSucceeded || textContent.mReply.mString.IsEmpty()) {
|
||||
return nil;
|
||||
|
@ -1235,10 +1257,18 @@ IMEInputHandler::SelectedRange()
|
|||
#if DEBUG_IME_HANDLER
|
||||
NSLog(@"****in SelectedRange");
|
||||
#endif
|
||||
nsQueryContentEvent selection(PR_TRUE, NS_QUERY_SELECTED_TEXT, mOwnerWidget);
|
||||
mOwnerWidget->DispatchWindowEvent(selection);
|
||||
|
||||
NSRange range = NSMakeRange(NSNotFound, 0);
|
||||
if (Destroyed()) {
|
||||
return range;
|
||||
}
|
||||
|
||||
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
nsQueryContentEvent selection(PR_TRUE, NS_QUERY_SELECTED_TEXT, mWidget);
|
||||
mWidget->DispatchWindowEvent(selection);
|
||||
if (!selection.mSucceeded) {
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
return range;
|
||||
}
|
||||
|
||||
#if DEBUG_IME_HANDLER
|
||||
|
@ -1260,21 +1290,24 @@ IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange)
|
|||
NSLog(@"****in FirstRectForCharacterRange");
|
||||
NSLog(@" aRange = %d, %d", aRange.location, aRange.length);
|
||||
#endif
|
||||
|
||||
// XXX this returns first character rect or caret rect, it is limitation of
|
||||
// now. We need more work for returns first line rect. But current
|
||||
// implementation is enough for IMEs.
|
||||
|
||||
NSRect rect;
|
||||
if (aRange.location == NSNotFound) {
|
||||
if (Destroyed() || aRange.location == NSNotFound) {
|
||||
return rect;
|
||||
}
|
||||
|
||||
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
nsIntRect r;
|
||||
PRBool useCaretRect = (aRange.length == 0);
|
||||
if (!useCaretRect) {
|
||||
nsQueryContentEvent charRect(PR_TRUE, NS_QUERY_TEXT_RECT, mOwnerWidget);
|
||||
nsQueryContentEvent charRect(PR_TRUE, NS_QUERY_TEXT_RECT, mWidget);
|
||||
charRect.InitForQueryTextRect(aRange.location, 1);
|
||||
mOwnerWidget->DispatchWindowEvent(charRect);
|
||||
mWidget->DispatchWindowEvent(charRect);
|
||||
if (charRect.mSucceeded) {
|
||||
r = charRect.mReply.mRect;
|
||||
} else {
|
||||
|
@ -1283,9 +1316,9 @@ IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange)
|
|||
}
|
||||
|
||||
if (useCaretRect) {
|
||||
nsQueryContentEvent caretRect(PR_TRUE, NS_QUERY_CARET_RECT, mOwnerWidget);
|
||||
nsQueryContentEvent caretRect(PR_TRUE, NS_QUERY_CARET_RECT, mWidget);
|
||||
caretRect.InitForQueryCaretRect(aRange.location);
|
||||
mOwnerWidget->DispatchWindowEvent(caretRect);
|
||||
mWidget->DispatchWindowEvent(caretRect);
|
||||
if (!caretRect.mSucceeded) {
|
||||
return rect;
|
||||
}
|
||||
|
@ -1293,7 +1326,7 @@ IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange)
|
|||
r.width = 0;
|
||||
}
|
||||
|
||||
nsIWidget* rootWidget = mOwnerWidget->GetTopLevelWidget();
|
||||
nsIWidget* rootWidget = mWidget->GetTopLevelWidget();
|
||||
NSWindow* rootWindow =
|
||||
static_cast<NSWindow*>(rootWidget->GetNativeData(NS_NATIVE_WINDOW));
|
||||
NSView* rootView =
|
||||
|
@ -1319,6 +1352,9 @@ IMEInputHandler::CharacterIndexForPoint(NSPoint& aPoint)
|
|||
#if DEBUG_IME
|
||||
NSLog(@"****in CharacterIndexForPoint");
|
||||
#endif
|
||||
|
||||
//nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
// To implement this, we'd have to grovel in text frames looking at text
|
||||
// offsets.
|
||||
return 0;
|
||||
|
@ -1333,6 +1369,8 @@ IMEInputHandler::GetValidAttributesForMarkedText()
|
|||
NSLog(@"****in GetValidAttributesForMarkedText");
|
||||
#endif
|
||||
|
||||
//nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
//return [NSArray arrayWithObjects:NSUnderlineStyleAttributeName,
|
||||
// NSMarkedClauseSegmentAttributeName,
|
||||
// NSTextInputReplacementRangeAttributeName,
|
||||
|
@ -1353,8 +1391,9 @@ IMEInputHandler::GetValidAttributesForMarkedText()
|
|||
*
|
||||
******************************************************************************/
|
||||
|
||||
IMEInputHandler::IMEInputHandler() :
|
||||
PluginTextInputHandler(),
|
||||
IMEInputHandler::IMEInputHandler(nsChildView* aWidget,
|
||||
NSView<mozView> *aNativeView) :
|
||||
PluginTextInputHandler(aWidget, aNativeView),
|
||||
mPendingMethods(0), mIMECompositionString(nsnull),
|
||||
mIsIMEComposing(PR_FALSE), mIsIMEEnabled(PR_TRUE),
|
||||
mIsASCIICapableOnly(PR_FALSE), mIgnoreIMECommit(PR_FALSE),
|
||||
|
@ -1408,21 +1447,20 @@ IMEInputHandler::OnFocusChangeInGecko(PRBool aFocus)
|
|||
}
|
||||
|
||||
PRBool
|
||||
IMEInputHandler::OnDestroyView(NSView<mozView> *aDestroyingView)
|
||||
IMEInputHandler::OnDestroyWidget(nsChildView* aDestroyingWidget)
|
||||
{
|
||||
// If we're not focused, the destroying view might be composing with it in
|
||||
// another instance.
|
||||
// If we're not focused, the focused IMEInputHandler may have been
|
||||
// created by another widget/nsChildView.
|
||||
if (sFocusedIMEHandler && sFocusedIMEHandler != this) {
|
||||
sFocusedIMEHandler->OnDestroyView(aDestroyingView);
|
||||
sFocusedIMEHandler->OnDestroyWidget(aDestroyingWidget);
|
||||
}
|
||||
|
||||
if (!PluginTextInputHandler::OnDestroyView(aDestroyingView)) {
|
||||
if (!PluginTextInputHandler::OnDestroyWidget(aDestroyingWidget)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (IsIMEComposing()) {
|
||||
// If our view is in the composition, we should clean up it.
|
||||
// XXX Might CancelIMEComposition() fail because mView is being destroyed?
|
||||
CancelIMEComposition();
|
||||
OnEndIMEComposition();
|
||||
}
|
||||
|
@ -1498,7 +1536,11 @@ IMEInputHandler::SendCommittedText(NSString *aString)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NS_ASSERTION(mView, "mView is null");
|
||||
NS_ENSURE_TRUE(mWidget, );
|
||||
// XXX We should send the string without mView.
|
||||
if (!mView) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSAttributedString* attrStr =
|
||||
[[NSAttributedString alloc] initWithString:aString];
|
||||
|
@ -1519,8 +1561,9 @@ IMEInputHandler::KillIMEComposition()
|
|||
NSLog(@" currentInputManager:%p", [NSInputManager currentInputManager]);
|
||||
#endif // DEBUG_IME_HANDLER
|
||||
|
||||
if (!mView)
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFocused()) {
|
||||
[[NSInputManager currentInputManager] markedTextAbandoned: mView];
|
||||
|
@ -1604,7 +1647,7 @@ IMEInputHandler::IsFocused()
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NS_ENSURE_TRUE(mView, PR_FALSE);
|
||||
NS_ENSURE_TRUE(!Destroyed(), PR_FALSE);
|
||||
NSWindow* window = [mView window];
|
||||
NS_ENSURE_TRUE(window, PR_FALSE);
|
||||
return [window firstResponder] == mView &&
|
||||
|
@ -1730,8 +1773,9 @@ IMEInputHandler::OpenSystemPreferredLanguageIME()
|
|||
*
|
||||
******************************************************************************/
|
||||
|
||||
PluginTextInputHandler::PluginTextInputHandler() :
|
||||
TextInputHandlerBase()
|
||||
PluginTextInputHandler::PluginTextInputHandler(nsChildView* aWidget,
|
||||
NSView<mozView> *aNativeView) :
|
||||
TextInputHandlerBase(aWidget, aNativeView)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1749,35 +1793,29 @@ PluginTextInputHandler::~PluginTextInputHandler()
|
|||
*
|
||||
******************************************************************************/
|
||||
|
||||
TextInputHandlerBase::TextInputHandlerBase() :
|
||||
mOwnerWidget(nsnull), mView(nsnull)
|
||||
TextInputHandlerBase::TextInputHandlerBase(nsChildView* aWidget,
|
||||
NSView<mozView> *aNativeView) :
|
||||
mWidget(aWidget)
|
||||
{
|
||||
gHandlerInstanceCount++;
|
||||
mView = [aNativeView retain];
|
||||
}
|
||||
|
||||
TextInputHandlerBase::~TextInputHandlerBase()
|
||||
{
|
||||
[mView release];
|
||||
if (--gHandlerInstanceCount == 0) {
|
||||
FinalizeCurrentKeyboardLayout();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextInputHandlerBase::Init(nsChildView* aOwner)
|
||||
{
|
||||
mOwnerWidget = aOwner;
|
||||
mView =
|
||||
static_cast<NSView<mozView>*>(aOwner->GetNativeData(NS_NATIVE_WIDGET));
|
||||
}
|
||||
|
||||
PRBool
|
||||
TextInputHandlerBase::OnDestroyView(NSView<mozView> *aDestroyingView)
|
||||
TextInputHandlerBase::OnDestroyWidget(nsChildView* aDestroyingWidget)
|
||||
{
|
||||
if (aDestroyingView != mView) {
|
||||
if (aDestroyingWidget != mWidget) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
mView = nsnull;
|
||||
|
||||
mWidget = nsnull;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -42,12 +42,24 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
class nsIWidget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget{
|
||||
class TextInputHandler;
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
// A protocol listing all the methods that an object which wants
|
||||
// to live in gecko's widget hierarchy must implement. |nsChildView|
|
||||
// makes assumptions that any NSView with which it comes in contact will
|
||||
// implement this protocol.
|
||||
@protocol mozView
|
||||
|
||||
// aHandler is Gecko's default text input handler: It implements the
|
||||
// NSTextInput protocol to handle key events. Don't make aHandler a
|
||||
// strong reference -- that causes a memory leak.
|
||||
- (void)installTextInputHandler:(mozilla::widget::TextInputHandler*)aHandler;
|
||||
- (void)uninstallTextInputHandler;
|
||||
|
||||
// access the nsIWidget associated with this view. DOES NOT ADDREF.
|
||||
- (nsIWidget*)widget;
|
||||
|
||||
|
|
|
@ -133,6 +133,15 @@ extern "C" long TSMProcessRawKeyEvent(EventRef carbonEvent);
|
|||
// the link back to it must be weak.
|
||||
nsChildView* mGeckoChild;
|
||||
|
||||
// Text input handler for mGeckoChild and us. Note that this is a weak
|
||||
// reference. Ideally, this should be a strong reference but a ChildView
|
||||
// object can live longer than the mGeckoChild that owns it. And if
|
||||
// mTextInputHandler were a strong reference, this would make it difficult
|
||||
// for Gecko's leak detector to detect leaked TextInputHandler objects.
|
||||
// This is initialized by [mozView installTextInputHandler:aHandler] and
|
||||
// cleared by [mozView uninstallTextInputHandler].
|
||||
mozilla::widget::TextInputHandler* mTextInputHandler; // [WEAK]
|
||||
|
||||
BOOL mIsPluginView;
|
||||
NPEventModel mPluginEventModel;
|
||||
NPDrawingModel mPluginDrawingModel;
|
||||
|
@ -418,11 +427,6 @@ public:
|
|||
static PRUint32 GetCurrentInputEventCount();
|
||||
static void UpdateCurrentInputEventCount();
|
||||
|
||||
mozilla::widget::TextInputHandler* TextInputHandler()
|
||||
{
|
||||
return &mTextInputHandler;
|
||||
}
|
||||
|
||||
NSView<mozView>* GetEditorView();
|
||||
|
||||
PRBool IsPluginView() { return (mWindowType == eWindowType_plugin); }
|
||||
|
@ -454,7 +458,7 @@ protected:
|
|||
protected:
|
||||
|
||||
NSView<mozView>* mView; // my parallel cocoa view (ChildView or NativeScrollbarView), [STRONG]
|
||||
mozilla::widget::TextInputHandler mTextInputHandler;
|
||||
nsRefPtr<mozilla::widget::TextInputHandler> mTextInputHandler;
|
||||
IMEContext mIMEContext;
|
||||
|
||||
NSView<mozView>* mParentView;
|
||||
|
|
|
@ -491,7 +491,8 @@ nsresult nsChildView::Create(nsIWidget *aParent,
|
|||
if ([mView isKindOfClass:[ChildView class]])
|
||||
[[WindowDataMap sharedWindowDataMap] ensureDataForWindow:[mView window]];
|
||||
|
||||
mTextInputHandler.Init(this);
|
||||
NS_ASSERTION(!mTextInputHandler, "mTextInputHandler has already existed");
|
||||
mTextInputHandler = new TextInputHandler(this, mView);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
|
@ -1654,7 +1655,8 @@ NS_IMETHODIMP nsChildView::DispatchEvent(nsGUIEvent* event, nsEventStatus& aStat
|
|||
debug_DumpEvent(stdout, event->widget, event, nsCAutoString("something"), 0);
|
||||
#endif
|
||||
|
||||
NS_ASSERTION(!(mTextInputHandler.IsIMEComposing() && NS_IS_KEY_EVENT(event)),
|
||||
NS_ASSERTION(!(mTextInputHandler && mTextInputHandler->IsIMEComposing() &&
|
||||
NS_IS_KEY_EVENT(event)),
|
||||
"Any key events should not be fired during IME composing");
|
||||
|
||||
aStatus = nsEventStatus_eIgnore;
|
||||
|
@ -1832,7 +1834,8 @@ NS_IMETHODIMP nsChildView::ResetInputState()
|
|||
NSLog(@"**** ResetInputState");
|
||||
#endif
|
||||
|
||||
mTextInputHandler.CommitIMEComposition();
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE);
|
||||
mTextInputHandler->CommitIMEComposition();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1843,7 +1846,8 @@ NS_IMETHODIMP nsChildView::SetIMEOpenState(PRBool aState)
|
|||
NSLog(@"**** SetIMEOpenState aState = %d", aState);
|
||||
#endif
|
||||
|
||||
mTextInputHandler.SetIMEOpenState(aState);
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE);
|
||||
mTextInputHandler->SetIMEOpenState(aState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1854,7 +1858,8 @@ NS_IMETHODIMP nsChildView::GetIMEOpenState(PRBool* aState)
|
|||
NSLog(@"**** GetIMEOpenState");
|
||||
#endif
|
||||
|
||||
*aState = mTextInputHandler.IsIMEOpened();
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE);
|
||||
*aState = mTextInputHandler->IsIMEOpened();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1864,20 +1869,21 @@ NS_IMETHODIMP nsChildView::SetInputMode(const IMEContext& aContext)
|
|||
NSLog(@"**** SetInputMode mStatus = %d", aContext.mStatus);
|
||||
#endif
|
||||
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE);
|
||||
mIMEContext = aContext;
|
||||
switch (aContext.mStatus) {
|
||||
case nsIWidget::IME_STATUS_ENABLED:
|
||||
case nsIWidget::IME_STATUS_PLUGIN:
|
||||
mTextInputHandler.SetASCIICapableOnly(PR_FALSE);
|
||||
mTextInputHandler.EnableIME(PR_TRUE);
|
||||
mTextInputHandler->SetASCIICapableOnly(PR_FALSE);
|
||||
mTextInputHandler->EnableIME(PR_TRUE);
|
||||
break;
|
||||
case nsIWidget::IME_STATUS_DISABLED:
|
||||
mTextInputHandler.SetASCIICapableOnly(PR_FALSE);
|
||||
mTextInputHandler.EnableIME(PR_FALSE);
|
||||
mTextInputHandler->SetASCIICapableOnly(PR_FALSE);
|
||||
mTextInputHandler->EnableIME(PR_FALSE);
|
||||
break;
|
||||
case nsIWidget::IME_STATUS_PASSWORD:
|
||||
mTextInputHandler.SetASCIICapableOnly(PR_TRUE);
|
||||
mTextInputHandler.EnableIME(PR_FALSE);
|
||||
mTextInputHandler->SetASCIICapableOnly(PR_TRUE);
|
||||
mTextInputHandler->EnableIME(PR_FALSE);
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("not implemented!");
|
||||
|
@ -1902,7 +1908,8 @@ NS_IMETHODIMP nsChildView::CancelIMEComposition()
|
|||
NSLog(@"**** CancelIMEComposition");
|
||||
#endif
|
||||
|
||||
mTextInputHandler.CancelIMEComposition();
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE);
|
||||
mTextInputHandler->CancelIMEComposition();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1936,7 +1943,8 @@ NS_IMETHODIMP nsChildView::GetToggledKeyState(PRUint32 aKeyCode,
|
|||
|
||||
NS_IMETHODIMP nsChildView::OnIMEFocusChange(PRBool aFocus)
|
||||
{
|
||||
mTextInputHandler.OnFocusChangeInGecko(aFocus);
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE);
|
||||
mTextInputHandler->OnFocusChangeInGecko(aFocus);
|
||||
// XXX Return NS_ERROR_NOT_IMPLEMENTED, see bug 496360.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -2267,6 +2275,16 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void)installTextInputHandler:(TextInputHandler*)aHandler
|
||||
{
|
||||
mTextInputHandler = aHandler;
|
||||
}
|
||||
|
||||
- (void)uninstallTextInputHandler
|
||||
{
|
||||
mTextInputHandler = nsnull;
|
||||
}
|
||||
|
||||
// Work around bug 603134.
|
||||
// OS X has a bug that causes new OpenGL windows to only paint once or twice,
|
||||
// then stop painting altogether. By clearing the drawable from the GL context,
|
||||
|
@ -2354,7 +2372,10 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
|||
|
||||
- (void)widgetDestroyed
|
||||
{
|
||||
mGeckoChild->TextInputHandler()->OnDestroyView(self);
|
||||
if (mTextInputHandler) {
|
||||
mTextInputHandler->OnDestroyWidget(mGeckoChild);
|
||||
mTextInputHandler = nsnull;
|
||||
}
|
||||
mGeckoChild = nsnull;
|
||||
|
||||
// Just in case we're destroyed abruptly and missed the draggingExited
|
||||
|
@ -4750,10 +4771,10 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
#if DEBUG_IME
|
||||
NSLog(@"****in insertText: '%@'", insertString);
|
||||
#endif
|
||||
if (!mGeckoChild)
|
||||
if (!mGeckoChild || !mTextInputHandler)
|
||||
return;
|
||||
|
||||
if (mGeckoChild->TextInputHandler()->IgnoreIMEComposition())
|
||||
if (mTextInputHandler->IgnoreIMEComposition())
|
||||
return;
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
@ -4763,14 +4784,14 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
|
||||
NSString *tmpStr = [insertString string];
|
||||
unsigned int len = [tmpStr length];
|
||||
if (!mGeckoChild->TextInputHandler()->IsIMEComposing() && len == 0)
|
||||
if (!mTextInputHandler->IsIMEComposing() && 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 && !mGeckoChild->TextInputHandler()->IsIMEComposing()) {
|
||||
if (len == 1 && !mTextInputHandler->IsIMEComposing()) {
|
||||
// don't let the same event be fired twice when hitting
|
||||
// enter/return! (Bug 420502)
|
||||
if (mKeyPressSent)
|
||||
|
@ -4831,7 +4852,7 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
else {
|
||||
NSAttributedString* attrStr =
|
||||
static_cast<NSAttributedString*>(insertString);
|
||||
mGeckoChild->TextInputHandler()->InsertTextAsCommittingComposition(attrStr);
|
||||
mTextInputHandler->InsertTextAsCommittingComposition(attrStr);
|
||||
}
|
||||
|
||||
if (bufPtr != buffer)
|
||||
|
@ -4863,7 +4884,7 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NS_ENSURE_TRUE(mGeckoChild, );
|
||||
NS_ENSURE_TRUE(mTextInputHandler, );
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
|
@ -4874,42 +4895,41 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
attrStr = [[[NSAttributedString alloc] initWithString:aString] autorelease];
|
||||
}
|
||||
|
||||
mGeckoChild->TextInputHandler()->SetMarkedText(attrStr, selRange);
|
||||
mTextInputHandler->SetMarkedText(attrStr, selRange);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void) unmarkText
|
||||
{
|
||||
NS_ENSURE_TRUE(mGeckoChild, );
|
||||
mGeckoChild->TextInputHandler()->CommitIMEComposition();
|
||||
NS_ENSURE_TRUE(mTextInputHandler, );
|
||||
mTextInputHandler->CommitIMEComposition();
|
||||
}
|
||||
|
||||
- (BOOL) hasMarkedText
|
||||
{
|
||||
NS_ENSURE_TRUE(mGeckoChild, NO);
|
||||
return mGeckoChild->TextInputHandler()->HasMarkedText();
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NO);
|
||||
return mTextInputHandler->HasMarkedText();
|
||||
}
|
||||
|
||||
- (NSInteger) conversationIdentifier
|
||||
{
|
||||
NS_ENSURE_TRUE(mGeckoChild, reinterpret_cast<NSInteger>(self));
|
||||
return mGeckoChild->TextInputHandler()->ConversationIdentifier();
|
||||
NS_ENSURE_TRUE(mTextInputHandler, reinterpret_cast<NSInteger>(self));
|
||||
return mTextInputHandler->ConversationIdentifier();
|
||||
}
|
||||
|
||||
- (NSAttributedString *) attributedSubstringFromRange:(NSRange)theRange
|
||||
{
|
||||
NS_ENSURE_TRUE(mGeckoChild, nil);
|
||||
return mGeckoChild->TextInputHandler()->
|
||||
GetAttributedSubstringFromRange(theRange);
|
||||
NS_ENSURE_TRUE(mTextInputHandler, nil);
|
||||
return mTextInputHandler->GetAttributedSubstringFromRange(theRange);
|
||||
}
|
||||
|
||||
- (NSRange) markedRange
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
NS_ENSURE_TRUE(mGeckoChild, NSMakeRange(NSNotFound, 0));
|
||||
return mGeckoChild->TextInputHandler()->MarkedRange();
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NSMakeRange(NSNotFound, 0));
|
||||
return mTextInputHandler->MarkedRange();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NSMakeRange(0, 0));
|
||||
}
|
||||
|
@ -4918,8 +4938,8 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
NS_ENSURE_TRUE(mGeckoChild, NSMakeRange(NSNotFound, 0));
|
||||
return mGeckoChild->TextInputHandler()->SelectedRange();
|
||||
NS_ENSURE_TRUE(mTextInputHandler, NSMakeRange(NSNotFound, 0));
|
||||
return mTextInputHandler->SelectedRange();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NSMakeRange(0, 0));
|
||||
}
|
||||
|
@ -4927,22 +4947,22 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
- (NSRect) firstRectForCharacterRange:(NSRange)theRange
|
||||
{
|
||||
NSRect rect;
|
||||
NS_ENSURE_TRUE(mGeckoChild, rect);
|
||||
return mGeckoChild->TextInputHandler()->FirstRectForCharacterRange(theRange);
|
||||
NS_ENSURE_TRUE(mTextInputHandler, rect);
|
||||
return mTextInputHandler->FirstRectForCharacterRange(theRange);
|
||||
}
|
||||
|
||||
- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
|
||||
{
|
||||
NS_ENSURE_TRUE(mGeckoChild, 0);
|
||||
return mGeckoChild->TextInputHandler()->CharacterIndexForPoint(thePoint);
|
||||
NS_ENSURE_TRUE(mTextInputHandler, 0);
|
||||
return mTextInputHandler->CharacterIndexForPoint(thePoint);
|
||||
}
|
||||
|
||||
- (NSArray*) validAttributesForMarkedText
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
NS_ENSURE_TRUE(mGeckoChild, [NSArray array]);
|
||||
return mGeckoChild->TextInputHandler()->GetValidAttributesForMarkedText();
|
||||
NS_ENSURE_TRUE(mTextInputHandler, [NSArray array]);
|
||||
return mTextInputHandler->GetValidAttributesForMarkedText();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
@ -4991,7 +5011,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if (!mGeckoChild)
|
||||
if (!mGeckoChild || !mTextInputHandler)
|
||||
return NO;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -5009,7 +5029,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
mCurKeyEvent = theEvent;
|
||||
|
||||
BOOL nonDeadKeyPress = [[theEvent characters] length] > 0;
|
||||
if (nonDeadKeyPress && !mGeckoChild->TextInputHandler()->IsIMEComposing()) {
|
||||
if (nonDeadKeyPress && !mTextInputHandler->IsIMEComposing()) {
|
||||
NSResponder* firstResponder = [[self window] firstResponder];
|
||||
|
||||
nsKeyEvent geckoKeydown(PR_TRUE, NS_KEY_DOWN, nsnull);
|
||||
|
@ -5059,7 +5079,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
// control-letter combinations etc before Cocoa tries to use
|
||||
// them for keybindings.
|
||||
if ((!geckoKeypress.isChar || geckoKeypress.isControl) &&
|
||||
!mGeckoChild->TextInputHandler()->IsIMEComposing()) {
|
||||
!mTextInputHandler->IsIMEComposing()) {
|
||||
if (mKeyDownHandled)
|
||||
geckoKeypress.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
mKeyPressHandled = mGeckoChild->DispatchWindowEvent(geckoKeypress);
|
||||
|
@ -5070,10 +5090,10 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
}
|
||||
|
||||
// Let Cocoa interpret the key events, caching IsIMEComposing first.
|
||||
PRBool wasComposing = mGeckoChild->TextInputHandler()->IsIMEComposing();
|
||||
PRBool wasComposing = mTextInputHandler->IsIMEComposing();
|
||||
PRBool interpretKeyEventsCalled = PR_FALSE;
|
||||
if (mGeckoChild->TextInputHandler()->IsIMEEnabled() ||
|
||||
mGeckoChild->TextInputHandler()->IsASCIICapableOnly()) {
|
||||
if (mTextInputHandler->IsIMEEnabled() ||
|
||||
mTextInputHandler->IsASCIICapableOnly()) {
|
||||
[super interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
|
||||
interpretKeyEventsCalled = PR_TRUE;
|
||||
}
|
||||
|
@ -5083,7 +5103,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
}
|
||||
|
||||
if (!mKeyPressSent && nonDeadKeyPress && !wasComposing &&
|
||||
!mGeckoChild->TextInputHandler()->IsIMEComposing()) {
|
||||
!mTextInputHandler->IsIMEComposing()) {
|
||||
nsKeyEvent geckoKeypress(PR_TRUE, NS_KEY_PRESS, nsnull);
|
||||
[self convertCocoaKeyEvent:theEvent toGeckoEvent:&geckoKeypress];
|
||||
|
||||
|
@ -5327,7 +5347,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
ToEscapedString([theEvent characters], str1),
|
||||
ToEscapedString([theEvent charactersIgnoringModifiers], str2)));
|
||||
|
||||
if (!mGeckoChild)
|
||||
if (!mGeckoChild || !mTextInputHandler)
|
||||
return;
|
||||
|
||||
if (mIgnoreNextKeyUpEvent) {
|
||||
|
@ -5388,7 +5408,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
|
||||
// if we don't have any characters we can't generate a keyUp event
|
||||
if ([[theEvent characters] length] == 0 ||
|
||||
mGeckoChild->TextInputHandler()->IsIMEComposing()) {
|
||||
mTextInputHandler->IsIMEComposing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5474,8 +5494,8 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (!mGeckoChild || [theEvent type] != NSFlagsChanged ||
|
||||
mGeckoChild->TextInputHandler()->IsIMEComposing()) {
|
||||
if (!mGeckoChild || !mTextInputHandler || [theEvent type] != NSFlagsChanged ||
|
||||
mTextInputHandler->IsIMEComposing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче