mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 519972 part.8 Move keydown and insertText implementation to TextInputHandler r=smichaud
This commit is contained in:
parent
940e8ac3cb
commit
8ab42896da
@ -407,29 +407,6 @@ public:
|
||||
const nsAString& aCharacters,
|
||||
const nsAString& aUnmodifiedCharacters);
|
||||
|
||||
/**
|
||||
* IsPrintableChar() checks whether the unicode character is
|
||||
* a non-printable ASCII character or not. Note that this returns
|
||||
* TRUE even if aChar is a non-printable UNICODE character.
|
||||
*
|
||||
* @param aChar A unicode character.
|
||||
* @return TRUE if aChar is a printable ASCII character
|
||||
* or a unicode character. Otherwise, i.e,
|
||||
* if aChar is a non-printable ASCII character,
|
||||
* FALSE.
|
||||
*/
|
||||
static PRBool IsPrintableChar(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* ComputeGeckoKeyCodeFromChar() computes Gecko defined keyCode value from
|
||||
* aChar. If aChar is not an ASCII character, this always returns FALSE.
|
||||
*
|
||||
* @param aChar A unicode character.
|
||||
* @return A Gecko defined keyCode. Or zero if aChar
|
||||
* is a unicode character.
|
||||
*/
|
||||
static PRUint32 ComputeGeckoKeyCodeFromChar(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* ComputeGeckoKeyCode() computes Gecko defined keyCode from the native
|
||||
* keyCode or the characters.
|
||||
@ -459,24 +436,6 @@ public:
|
||||
*/
|
||||
static PRBool IsSpecialGeckoKey(UInt32 aNativeKeyCode);
|
||||
|
||||
/**
|
||||
* IsNormalCharInputtingEvent() checks whether aKeyEvent causes text input.
|
||||
*
|
||||
* @param aKeyEvent A key event.
|
||||
* @return TRUE if the key event causes text input.
|
||||
* Otherwise, FALSE.
|
||||
*/
|
||||
static PRBool IsNormalCharInputtingEvent(const nsKeyEvent& aKeyEvent);
|
||||
|
||||
/**
|
||||
* IsModifierKey() checks whether the native keyCode is for a modifier key.
|
||||
*
|
||||
* @param aNativeKeyCode A native keyCode.
|
||||
* @return TRUE if aNativeKeyCode is for a modifier key.
|
||||
* Otherwise, FALSE.
|
||||
*/
|
||||
static PRBool IsModifierKey(UInt32 aNativeKeyCode);
|
||||
|
||||
protected:
|
||||
nsAutoRefCnt mRefCnt;
|
||||
|
||||
@ -507,6 +466,121 @@ protected:
|
||||
|
||||
PRBool Destroyed() { return !mWidget; }
|
||||
|
||||
/**
|
||||
* mCurrentKeyEvent indicates what key event we are handling. While
|
||||
* handling a native keydown event, we need to store the event for insertText,
|
||||
* doCommandBySelector and various action message handlers of NSResponder
|
||||
* such as [NSResponder insertNewline:sender].
|
||||
*/
|
||||
struct KeyEventState
|
||||
{
|
||||
// Handling native key event
|
||||
NSEvent* mKeyEvent;
|
||||
// Whether keydown event was consumed by web contents or chrome contents.
|
||||
PRPackedBool mKeyDownHandled;
|
||||
// Whether keypress event was dispatched for mKeyEvent.
|
||||
PRPackedBool mKeyPressDispatched;
|
||||
// Whether keypress event was consumed by web contents or chrome contents.
|
||||
PRPackedBool mKeyPressHandled;
|
||||
|
||||
KeyEventState() : mKeyEvent(nsnull)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
~KeyEventState()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Set(NSEvent* aNativeKeyEvent)
|
||||
{
|
||||
NS_PRECONDITION(aNativeKeyEvent, "aNativeKeyEvent must not be NULL");
|
||||
Clear();
|
||||
mKeyEvent = [aNativeKeyEvent retain];
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (mKeyEvent) {
|
||||
[mKeyEvent release];
|
||||
mKeyEvent = nsnull;
|
||||
}
|
||||
mKeyDownHandled = PR_FALSE;
|
||||
mKeyPressDispatched = PR_FALSE;
|
||||
mKeyPressHandled = PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool KeyDownOrPressHandled()
|
||||
{
|
||||
return mKeyDownHandled || mKeyPressHandled;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class for guaranteeing cleaning mCurrentKeyEvent
|
||||
*/
|
||||
class AutoKeyEventStateCleaner
|
||||
{
|
||||
public:
|
||||
AutoKeyEventStateCleaner(TextInputHandlerBase* aHandler) :
|
||||
mHandler(aHandler)
|
||||
{
|
||||
}
|
||||
|
||||
~AutoKeyEventStateCleaner()
|
||||
{
|
||||
mHandler->mCurrentKeyEvent.Clear();
|
||||
}
|
||||
private:
|
||||
TextInputHandlerBase* mHandler;
|
||||
};
|
||||
|
||||
// XXX If keydown event was nested, the key event is overwritten by newer
|
||||
// event. This is wrong behavior. Some IMEs are making such situation.
|
||||
KeyEventState mCurrentKeyEvent;
|
||||
|
||||
/**
|
||||
* IsPrintableChar() checks whether the unicode character is
|
||||
* a non-printable ASCII character or not. Note that this returns
|
||||
* TRUE even if aChar is a non-printable UNICODE character.
|
||||
*
|
||||
* @param aChar A unicode character.
|
||||
* @return TRUE if aChar is a printable ASCII character
|
||||
* or a unicode character. Otherwise, i.e,
|
||||
* if aChar is a non-printable ASCII character,
|
||||
* FALSE.
|
||||
*/
|
||||
static PRBool IsPrintableChar(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* ComputeGeckoKeyCodeFromChar() computes Gecko defined keyCode value from
|
||||
* aChar. If aChar is not an ASCII character, this always returns FALSE.
|
||||
*
|
||||
* @param aChar A unicode character.
|
||||
* @return A Gecko defined keyCode. Or zero if aChar
|
||||
* is a unicode character.
|
||||
*/
|
||||
static PRUint32 ComputeGeckoKeyCodeFromChar(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* IsNormalCharInputtingEvent() checks whether aKeyEvent causes text input.
|
||||
*
|
||||
* @param aKeyEvent A key event.
|
||||
* @return TRUE if the key event causes text input.
|
||||
* Otherwise, FALSE.
|
||||
*/
|
||||
static PRBool IsNormalCharInputtingEvent(const nsKeyEvent& aKeyEvent);
|
||||
|
||||
/**
|
||||
* IsModifierKey() checks whether the native keyCode is for a modifier key.
|
||||
*
|
||||
* @param aNativeKeyCode A native keyCode.
|
||||
* @return TRUE if aNativeKeyCode is for a modifier key.
|
||||
* Otherwise, FALSE.
|
||||
*/
|
||||
static PRBool IsModifierKey(UInt32 aNativeKeyCode);
|
||||
|
||||
private:
|
||||
struct KeyboardLayoutOverride {
|
||||
PRInt32 mKeyboardLayout;
|
||||
@ -527,9 +601,46 @@ private:
|
||||
|
||||
class PluginTextInputHandler : public TextInputHandlerBase
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
/**
|
||||
* ConvertCocoaKeyEventToCarbonEvent() converts aCocoaKeyEvent to
|
||||
* aCarbonKeyEvent.
|
||||
*
|
||||
* @param aCocoaKeyEvent A Cocoa key event.
|
||||
* @param aCarbonKeyEvent Converted Carbon event from aCocoaEvent.
|
||||
* @param aMakeKeyDownEventIfNSFlagsChanged
|
||||
* If aCocoaKeyEvent isn't NSFlagsChanged event,
|
||||
* this is ignored. Otherwise, i.e., if
|
||||
* aCocoaKeyEvent is NSFlagsChanged event,
|
||||
* set TRUE if you need a keydown event.
|
||||
* Otherwise, Set FALSE for a keyup event.
|
||||
*/
|
||||
static void ConvertCocoaKeyEventToCarbonEvent(
|
||||
NSEvent* aCocoaKeyEvent,
|
||||
EventRecord& aCarbonKeyEvent,
|
||||
PRBool aMakeKeyDownEventIfNSFlagsChanged = PR_FALSE);
|
||||
#endif // NP_NO_CARBON
|
||||
|
||||
protected:
|
||||
PluginTextInputHandler(nsChildView* aWidget, NSView<mozView> *aNativeView);
|
||||
~PluginTextInputHandler();
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
|
||||
/**
|
||||
* ConvertUnicodeToCharCode() converts aUnichar to native encoded string.
|
||||
*
|
||||
* @param aUniChar A unicode character.
|
||||
* @param aOutChar Native encoded string for aUniChar.
|
||||
* @return TRUE if the converting succeeded.
|
||||
* Otherwise, FALSE.
|
||||
*/
|
||||
static PRBool ConvertUnicodeToCharCode(PRUnichar aUniChar,
|
||||
unsigned char* aOutChar);
|
||||
|
||||
#endif // NP_NO_CARBON
|
||||
};
|
||||
|
||||
/**
|
||||
@ -581,14 +692,6 @@ public:
|
||||
void SetMarkedText(NSAttributedString* aAttrString,
|
||||
NSRange& aSelectedRange);
|
||||
|
||||
/**
|
||||
* InsertTextAsCommittingComposition() commits current composition. If there
|
||||
* is no composition, this starts a composition and commits it immediately.
|
||||
*
|
||||
* @param aAttrString A string which is committed.
|
||||
*/
|
||||
void InsertTextAsCommittingComposition(NSAttributedString* aAttrString);
|
||||
|
||||
/**
|
||||
* ConversationIdentifier() returns an ID for the current editor. The ID is
|
||||
* guaranteed to be unique among currently existing editors. But it might be
|
||||
@ -713,6 +816,14 @@ protected:
|
||||
|
||||
virtual void ExecutePendingMethods();
|
||||
|
||||
/**
|
||||
* InsertTextAsCommittingComposition() commits current composition. If there
|
||||
* is no composition, this starts a composition and commits it immediately.
|
||||
*
|
||||
* @param aAttrString A string which is committed.
|
||||
*/
|
||||
void InsertTextAsCommittingComposition(NSAttributedString* aAttrString);
|
||||
|
||||
private:
|
||||
// If mIsIMEComposing is true, the composition string is stored here.
|
||||
NSString* mIMECompositionString;
|
||||
@ -831,6 +942,39 @@ public:
|
||||
|
||||
TextInputHandler(nsChildView* aWidget, NSView<mozView> *aNativeView);
|
||||
virtual ~TextInputHandler();
|
||||
|
||||
/**
|
||||
* KeyDown event handler.
|
||||
*
|
||||
* @param aNativeEvent A native keydown event which you want to
|
||||
* handle.
|
||||
* @return TRUE if the event is consumed by web contents
|
||||
* or chrome contents. Otherwise, FALSE.
|
||||
*/
|
||||
PRBool HandleKeyDownEvent(NSEvent* aNativeEvent);
|
||||
|
||||
/**
|
||||
* Insert the string to content. I.e., this is a text input event handler.
|
||||
* If this is called during keydown event handling, this may dispatch a
|
||||
* NS_KEY_PRESS event. If this is called during composition, this commits
|
||||
* the composition by the aAttrString.
|
||||
*
|
||||
* @param aAttrString An inserted string.
|
||||
*/
|
||||
void InsertText(NSAttributedString *aAttrString);
|
||||
|
||||
/**
|
||||
* KeyPressWasHandled() checks whether keypress event was handled or not.
|
||||
*
|
||||
* @return TRUE if keypress event for latest native key
|
||||
* event was handled. Otherwise, FALSE.
|
||||
* If this handler isn't handling any key events,
|
||||
* always returns FALSE.
|
||||
*/
|
||||
PRBool KeyPressWasHandled()
|
||||
{
|
||||
return mCurrentKeyEvent.mKeyPressHandled;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
|
@ -804,6 +804,227 @@ TextInputHandler::~TextInputHandler()
|
||||
[mView uninstallTextInputHandler];
|
||||
}
|
||||
|
||||
PRBool
|
||||
TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if (Destroyed()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsRefPtr<nsChildView> kungFuDeathGrip(mWidget);
|
||||
|
||||
mCurrentKeyEvent.Set(aNativeEvent);
|
||||
AutoKeyEventStateCleaner remover(this);
|
||||
|
||||
BOOL nonDeadKeyPress = [[aNativeEvent characters] length] > 0;
|
||||
if (nonDeadKeyPress && !IsIMEComposing()) {
|
||||
NSResponder* firstResponder = [[mView window] firstResponder];
|
||||
|
||||
nsKeyEvent keydownEvent(PR_TRUE, NS_KEY_DOWN, mWidget);
|
||||
InitKeyEvent(aNativeEvent, keydownEvent);
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
if ([mView pluginEventModel] == NPEventModelCarbon) {
|
||||
ConvertCocoaKeyEventToCarbonEvent(aNativeEvent, carbonEvent, PR_TRUE);
|
||||
keydownEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif // #ifndef NP_NO_CARBON
|
||||
|
||||
mCurrentKeyEvent.mKeyDownHandled = DispatchEvent(keydownEvent);
|
||||
if (Destroyed()) {
|
||||
return mCurrentKeyEvent.KeyDownOrPressHandled();
|
||||
}
|
||||
|
||||
// The key down event may have shifted the focus, in which
|
||||
// case we should not fire the key press.
|
||||
// XXX This is a special code only on Cocoa widget, why is this needed?
|
||||
if (firstResponder != [[mView window] firstResponder]) {
|
||||
return mCurrentKeyEvent.KeyDownOrPressHandled();
|
||||
}
|
||||
|
||||
// If this is the context menu key command, send a context menu key event.
|
||||
NSUInteger modifierFlags =
|
||||
[aNativeEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||
if (modifierFlags == NSControlKeyMask &&
|
||||
[[aNativeEvent charactersIgnoringModifiers] isEqualToString:@" "]) {
|
||||
nsMouseEvent contextMenuEvent(PR_TRUE, NS_CONTEXTMENU,
|
||||
[mView widget], nsMouseEvent::eReal,
|
||||
nsMouseEvent::eContextMenuKey);
|
||||
contextMenuEvent.isShift = contextMenuEvent.isControl =
|
||||
contextMenuEvent.isAlt = contextMenuEvent.isMeta = PR_FALSE;
|
||||
|
||||
PRBool cmEventHandled = DispatchEvent(contextMenuEvent);
|
||||
[mView maybeInitContextMenuTracking];
|
||||
// Bail, there is nothing else to do here.
|
||||
return (cmEventHandled || mCurrentKeyEvent.KeyDownOrPressHandled());
|
||||
}
|
||||
|
||||
nsKeyEvent keypressEvent(PR_TRUE, NS_KEY_PRESS, mWidget);
|
||||
InitKeyEvent(aNativeEvent, keypressEvent);
|
||||
|
||||
// if this is a non-letter keypress, or the control key is down,
|
||||
// dispatch the keydown to gecko, so that we trap delete,
|
||||
// control-letter combinations etc before Cocoa tries to use
|
||||
// them for keybindings.
|
||||
// XXX This is wrong. IME may be handle the non-letter keypress event as
|
||||
// its owning shortcut key. See bug 477291.
|
||||
if ((!keypressEvent.isChar || keypressEvent.isControl) &&
|
||||
!IsIMEComposing()) {
|
||||
if (mCurrentKeyEvent.mKeyDownHandled) {
|
||||
keypressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
}
|
||||
mCurrentKeyEvent.mKeyPressHandled = DispatchEvent(keypressEvent);
|
||||
mCurrentKeyEvent.mKeyPressDispatched = PR_TRUE;
|
||||
if (Destroyed()) {
|
||||
return mCurrentKeyEvent.KeyDownOrPressHandled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let Cocoa interpret the key events, caching IsIMEComposing first.
|
||||
PRBool wasComposing = IsIMEComposing();
|
||||
PRBool interpretKeyEventsCalled = PR_FALSE;
|
||||
if (IsIMEEnabled() || IsASCIICapableOnly()) {
|
||||
[mView interpretKeyEvents:[NSArray arrayWithObject:aNativeEvent]];
|
||||
interpretKeyEventsCalled = PR_TRUE;
|
||||
}
|
||||
|
||||
if (Destroyed()) {
|
||||
return mCurrentKeyEvent.KeyDownOrPressHandled();
|
||||
}
|
||||
|
||||
if (!mCurrentKeyEvent.mKeyPressDispatched && nonDeadKeyPress &&
|
||||
!wasComposing && !IsIMEComposing()) {
|
||||
nsKeyEvent keypressEvent(PR_TRUE, NS_KEY_PRESS, mWidget);
|
||||
InitKeyEvent(aNativeEvent, keypressEvent);
|
||||
|
||||
// If we called interpretKeyEvents and this isn't normal character input
|
||||
// then IME probably ate the event for some reason. We do not want to
|
||||
// send a key press event in that case.
|
||||
// TODO:
|
||||
// There are some other cases which IME eats the current event.
|
||||
// 1. If key events were nested during calling interpretKeyEvents, it means
|
||||
// that IME did something. Then, we should do nothing.
|
||||
// 2. If one or more commands are called like "deleteBackward", we should
|
||||
// dispatch keypress event at that time. Note that the command may have
|
||||
// been a converted or generated action by IME. Then, we shouldn't do
|
||||
// our default action for this key.
|
||||
if (!(interpretKeyEventsCalled &&
|
||||
IsNormalCharInputtingEvent(keypressEvent))) {
|
||||
if (mCurrentKeyEvent.mKeyDownHandled) {
|
||||
keypressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
}
|
||||
mCurrentKeyEvent.mKeyPressHandled = DispatchEvent(keypressEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: mWidget might have become null here. Don't count on it from here on.
|
||||
|
||||
return mCurrentKeyEvent.KeyDownOrPressHandled();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
TextInputHandler::InsertText(NSAttributedString *aAttrString)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IgnoreIMEComposition()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsString str;
|
||||
GetStringForNSString([aAttrString string], str);
|
||||
if (!IsIMEComposing() && str.IsEmpty()) {
|
||||
return; // nothing to do
|
||||
}
|
||||
|
||||
if (str.Length() != 1 || IsIMEComposing()) {
|
||||
InsertTextAsCommittingComposition(aAttrString);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't let the same event be fired twice when hitting
|
||||
// enter/return! (Bug 420502)
|
||||
if (mCurrentKeyEvent.mKeyPressDispatched) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsChildView> kungFuDeathGrip(mWidget);
|
||||
|
||||
// Dispatch keypress event with char instead of textEvent
|
||||
nsKeyEvent keypressEvent(PR_TRUE, NS_KEY_PRESS, mWidget);
|
||||
keypressEvent.time = PR_IntervalNow();
|
||||
keypressEvent.charCode = str.CharAt(0);
|
||||
keypressEvent.keyCode = 0;
|
||||
keypressEvent.isChar = PR_TRUE;
|
||||
|
||||
// Don't set other modifiers from the current event, because here in
|
||||
// -insertText: they've already been taken into account in creating
|
||||
// the input string.
|
||||
|
||||
// create event for use by plugins
|
||||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
#endif // #ifndef NP_NO_CARBON
|
||||
|
||||
if (mCurrentKeyEvent.mKeyEvent) {
|
||||
NSEvent* keyEvent = mCurrentKeyEvent.mKeyEvent;
|
||||
|
||||
// XXX The ASCII characters inputting mode of egbridge (Japanese IME)
|
||||
// might send the keyDown event with wrong keyboard layout if other
|
||||
// keyboard layouts are already loaded. In that case, the native event
|
||||
// doesn't match to this gecko event...
|
||||
#ifndef NP_NO_CARBON
|
||||
if ([mView pluginEventModel] == NPEventModelCarbon) {
|
||||
ConvertCocoaKeyEventToCarbonEvent(keyEvent, carbonEvent, PR_TRUE);
|
||||
keypressEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif // #ifndef NP_NO_CARBON
|
||||
|
||||
if (mCurrentKeyEvent.mKeyDownHandled) {
|
||||
keypressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
}
|
||||
|
||||
keypressEvent.isShift = ([keyEvent modifierFlags] & NSShiftKeyMask) != 0;
|
||||
if (!IsPrintableChar(keypressEvent.charCode)) {
|
||||
keypressEvent.keyCode =
|
||||
ComputeGeckoKeyCode([keyEvent keyCode],
|
||||
[keyEvent charactersIgnoringModifiers]);
|
||||
keypressEvent.charCode = 0;
|
||||
}
|
||||
} else {
|
||||
// Note that insertText is not called only at key pressing.
|
||||
if (!IsPrintableChar(keypressEvent.charCode)) {
|
||||
keypressEvent.keyCode =
|
||||
ComputeGeckoKeyCodeFromChar(keypressEvent.charCode);
|
||||
keypressEvent.charCode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// If mCurrentKeyEvent.mKeyEvent is null and when we implement textInput
|
||||
// event of DOM3 Events, we should dispatch it instead of keypress event.
|
||||
PRBool keyPressHandled = DispatchEvent(keypressEvent);
|
||||
|
||||
// Note: mWidget might have become null here. Don't count on it from here on.
|
||||
|
||||
if (mCurrentKeyEvent.mKeyEvent) {
|
||||
mCurrentKeyEvent.mKeyPressHandled = keyPressHandled;
|
||||
mCurrentKeyEvent.mKeyPressDispatched = PR_TRUE;
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@ -949,6 +1170,7 @@ IMEInputHandler::GetCurrentTSMDocumentID()
|
||||
return ::TSMGetActiveDocument();
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
@ -2015,6 +2237,103 @@ PluginTextInputHandler::~PluginTextInputHandler()
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
|
||||
/* static */ PRBool
|
||||
PluginTextInputHandler::ConvertUnicodeToCharCode(PRUnichar aUniChar,
|
||||
unsigned char* aOutChar)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
UnicodeToTextInfo converterInfo;
|
||||
TextEncoding systemEncoding;
|
||||
Str255 convertedString;
|
||||
|
||||
*aOutChar = nsnull;
|
||||
|
||||
OSStatus err =
|
||||
::UpgradeScriptInfoToTextEncoding(smSystemScript,
|
||||
kTextLanguageDontCare,
|
||||
kTextRegionDontCare,
|
||||
NULL,
|
||||
&systemEncoding);
|
||||
NS_ENSURE_TRUE(err == noErr, PR_FALSE);
|
||||
|
||||
err = ::CreateUnicodeToTextInfoByEncoding(systemEncoding, &converterInfo);
|
||||
NS_ENSURE_TRUE(err == noErr, PR_FALSE);
|
||||
|
||||
err = ::ConvertFromUnicodeToPString(converterInfo, sizeof(PRUnichar),
|
||||
&aUniChar, convertedString);
|
||||
NS_ENSURE_TRUE(err == noErr, PR_FALSE);
|
||||
|
||||
*aOutChar = convertedString[1];
|
||||
::DisposeUnicodeToTextInfo(&converterInfo);
|
||||
return PR_TRUE;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PluginTextInputHandler::ConvertCocoaKeyEventToCarbonEvent(
|
||||
NSEvent* aCocoaKeyEvent,
|
||||
EventRecord& aCarbonKeyEvent,
|
||||
PRBool aMakeKeyDownEventIfNSFlagsChanged)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
UInt32 charCode = 0;
|
||||
if ([aCocoaKeyEvent type] == NSFlagsChanged) {
|
||||
aCarbonKeyEvent.what = aMakeKeyDownEventIfNSFlagsChanged ? keyDown : keyUp;
|
||||
} else {
|
||||
if ([[aCocoaKeyEvent characters] length] > 0) {
|
||||
charCode = [[aCocoaKeyEvent characters] characterAtIndex:0];
|
||||
}
|
||||
if ([aCocoaKeyEvent type] == NSKeyDown) {
|
||||
aCarbonKeyEvent.what = [aCocoaKeyEvent isARepeat] ? autoKey : keyDown;
|
||||
} else {
|
||||
aCarbonKeyEvent.what = keyUp;
|
||||
}
|
||||
}
|
||||
|
||||
if (charCode >= 0x0080) {
|
||||
switch (charCode) {
|
||||
case NSUpArrowFunctionKey:
|
||||
charCode = kUpArrowCharCode;
|
||||
break;
|
||||
case NSDownArrowFunctionKey:
|
||||
charCode = kDownArrowCharCode;
|
||||
break;
|
||||
case NSLeftArrowFunctionKey:
|
||||
charCode = kLeftArrowCharCode;
|
||||
break;
|
||||
case NSRightArrowFunctionKey:
|
||||
charCode = kRightArrowCharCode;
|
||||
break;
|
||||
default:
|
||||
unsigned char convertedCharCode;
|
||||
if (ConvertUnicodeToCharCode(charCode, &convertedCharCode)) {
|
||||
charCode = convertedCharCode;
|
||||
}
|
||||
//NSLog(@"charcode is %d, converted to %c, char is %@",
|
||||
// charCode, convertedCharCode, [aCocoaKeyEvent characters]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aCarbonKeyEvent.message =
|
||||
(charCode & 0x00FF) | ([aCocoaKeyEvent keyCode] << 8);
|
||||
aCarbonKeyEvent.when = ::TickCount();
|
||||
::GetGlobalMouse(&aCarbonKeyEvent.where);
|
||||
// XXX Is this correct? If ::GetCurrentKeyModifiers() returns "current"
|
||||
// state and there is one or more pending modifier key events,
|
||||
// the result is mismatch with the state at current key event.
|
||||
aCarbonKeyEvent.modifiers = ::GetCurrentKeyModifiers();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
#endif // NP_NO_CARBON
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
@ -38,6 +38,8 @@
|
||||
#ifndef mozView_h_
|
||||
#define mozView_h_
|
||||
|
||||
#include "npapi.h"
|
||||
|
||||
#undef DARWIN
|
||||
#import <Cocoa/Cocoa.h>
|
||||
class nsIWidget;
|
||||
@ -76,6 +78,15 @@ class TextInputHandler;
|
||||
|
||||
- (BOOL)isDragInProgress;
|
||||
|
||||
// Gets the plugin event model for the view
|
||||
- (NPEventModel)pluginEventModel;
|
||||
|
||||
// Checks whether the view is first responder or not
|
||||
- (BOOL)isFirstResponder;
|
||||
|
||||
// Call when you dispatch an event which may cause to open context menu.
|
||||
- (void)maybeInitContextMenuTracking;
|
||||
|
||||
@end
|
||||
|
||||
// An informal protocol implemented by the NSWindow of the host application.
|
||||
|
@ -192,20 +192,6 @@ extern "C" long TSMProcessRawKeyEvent(EventRef carbonEvent);
|
||||
NPEventModel mPluginEventModel;
|
||||
NPDrawingModel mPluginDrawingModel;
|
||||
|
||||
// The following variables are only valid during key down event processing.
|
||||
// Their current usage needs to be fixed to avoid problems with nested event
|
||||
// loops that can confuse them. Once a variable is set during key down event
|
||||
// processing, if an event spawns a nested event loop the previously set value
|
||||
// will be wiped out.
|
||||
NSEvent* mCurKeyEvent;
|
||||
PRBool mKeyDownHandled;
|
||||
// While we process key down events we need to keep track of whether or not
|
||||
// we sent a key press event. This helps us make sure we do send one
|
||||
// eventually.
|
||||
BOOL mKeyPressSent;
|
||||
// Valid when mKeyPressSent is true.
|
||||
PRBool mKeyPressHandled;
|
||||
|
||||
// when mouseDown: is called, we store its event here (strong)
|
||||
NSEvent* mLastMouseDownEvent;
|
||||
|
||||
|
@ -169,7 +169,6 @@ PRUint32 nsChildView::sLastInputEventCount = 0;
|
||||
- (BOOL)isPluginView;
|
||||
- (void)setPluginEventModel:(NPEventModel)eventModel;
|
||||
- (void)setPluginDrawingModel:(NPDrawingModel)drawingModel;
|
||||
- (NPEventModel)pluginEventModel;
|
||||
- (NPDrawingModel)pluginDrawingModel;
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
@ -180,8 +179,6 @@ PRUint32 nsChildView::sLastInputEventCount = 0;
|
||||
|
||||
- (void)processPendingRedraws;
|
||||
|
||||
- (void)maybeInitContextMenuTracking;
|
||||
|
||||
- (void)drawRect:(NSRect)aRect inContext:(CGContextRef)aContext;
|
||||
|
||||
// Called using performSelector:withObject:afterDelay:0 to release
|
||||
@ -198,8 +195,6 @@ PRUint32 nsChildView::sLastInputEventCount = 0;
|
||||
- (id<mozAccessible>)accessible;
|
||||
#endif
|
||||
|
||||
- (BOOL)isFirstResponder;
|
||||
|
||||
- (void)fireKeyEventForFlagsChanged:(NSEvent*)theEvent keyDown:(BOOL)isKeyDown;
|
||||
|
||||
- (BOOL)inactiveWindowAcceptsMouseEvent:(NSEvent*)aEvent;
|
||||
@ -2069,10 +2064,6 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
#else
|
||||
mPluginDrawingModel = NPDrawingModelCoreGraphics;
|
||||
#endif
|
||||
mCurKeyEvent = nil;
|
||||
mKeyDownHandled = PR_FALSE;
|
||||
mKeyPressHandled = NO;
|
||||
mKeyPressSent = NO;
|
||||
mPendingDisplay = NO;
|
||||
mBlockedLastMouseDown = NO;
|
||||
|
||||
@ -3853,38 +3844,6 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
static PRBool ConvertUnicodeToCharCode(PRUnichar inUniChar, unsigned char* outChar)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
UnicodeToTextInfo converterInfo;
|
||||
TextEncoding systemEncoding;
|
||||
Str255 convertedString;
|
||||
OSStatus err;
|
||||
|
||||
*outChar = 0;
|
||||
|
||||
err = ::UpgradeScriptInfoToTextEncoding(smSystemScript, kTextLanguageDontCare, kTextRegionDontCare, NULL, &systemEncoding);
|
||||
if (err != noErr)
|
||||
return PR_FALSE;
|
||||
|
||||
err = ::CreateUnicodeToTextInfoByEncoding(systemEncoding, &converterInfo);
|
||||
if (err != noErr)
|
||||
return PR_FALSE;
|
||||
|
||||
err = ::ConvertFromUnicodeToPString(converterInfo, sizeof(PRUnichar), &inUniChar, convertedString);
|
||||
if (err != noErr)
|
||||
return PR_FALSE;
|
||||
|
||||
*outChar = convertedString[1];
|
||||
::DisposeUnicodeToTextInfo(&converterInfo);
|
||||
return PR_TRUE;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);
|
||||
}
|
||||
#endif // NP_NO_CARBON
|
||||
|
||||
static void ConvertCocoaKeyEventToNPCocoaEvent(NSEvent* cocoaEvent, NPCocoaEvent& pluginEvent, PRUint32 keyType = 0)
|
||||
{
|
||||
InitNPCocoaEvent(&pluginEvent);
|
||||
@ -3912,54 +3871,6 @@ static void ConvertCocoaKeyEventToNPCocoaEvent(NSEvent* cocoaEvent, NPCocoaEvent
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
static void ConvertCocoaKeyEventToCarbonEvent(NSEvent* cocoaEvent, EventRecord& pluginEvent, PRUint32 keyType = 0)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
UInt32 charCode = 0;
|
||||
if ([cocoaEvent type] == NSFlagsChanged) {
|
||||
pluginEvent.what = keyType == NS_KEY_DOWN ? keyDown : keyUp;
|
||||
} else {
|
||||
if ([[cocoaEvent characters] length] > 0)
|
||||
charCode = [[cocoaEvent characters] characterAtIndex:0];
|
||||
if ([cocoaEvent type] == NSKeyDown)
|
||||
pluginEvent.what = [cocoaEvent isARepeat] ? autoKey : keyDown;
|
||||
else
|
||||
pluginEvent.what = keyUp;
|
||||
}
|
||||
|
||||
if (charCode >= 0x0080) {
|
||||
switch (charCode) {
|
||||
case NSUpArrowFunctionKey:
|
||||
charCode = kUpArrowCharCode;
|
||||
break;
|
||||
case NSDownArrowFunctionKey:
|
||||
charCode = kDownArrowCharCode;
|
||||
break;
|
||||
case NSLeftArrowFunctionKey:
|
||||
charCode = kLeftArrowCharCode;
|
||||
break;
|
||||
case NSRightArrowFunctionKey:
|
||||
charCode = kRightArrowCharCode;
|
||||
break;
|
||||
default:
|
||||
unsigned char convertedCharCode;
|
||||
if (ConvertUnicodeToCharCode(charCode, &convertedCharCode))
|
||||
charCode = convertedCharCode;
|
||||
//NSLog(@"charcode is %d, converted to %c, char is %@", charCode, convertedCharCode, [cocoaEvent characters]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pluginEvent.message = (charCode & 0x00FF) | ([cocoaEvent keyCode] << 8);
|
||||
pluginEvent.when = ::TickCount();
|
||||
::GetGlobalMouse(&pluginEvent.where);
|
||||
pluginEvent.modifiers = ::GetCurrentKeyModifiers();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
#endif // NP_NO_CARBON
|
||||
|
||||
// Basic conversion for cocoa to gecko events, common to all conversions.
|
||||
// Note that it is OK for inEvent to be nil.
|
||||
- (void) convertGenericCocoaEvent:(NSEvent*)inEvent toGeckoEvent:(nsInputEvent*)outGeckoEvent
|
||||
@ -4128,8 +4039,6 @@ static void ConvertCocoaKeyEventToCarbonEvent(NSEvent* cocoaEvent, EventRecord&
|
||||
#pragma mark -
|
||||
// NSTextInput implementation
|
||||
|
||||
#define MAX_BUFFER_SIZE 32
|
||||
|
||||
- (void)insertText:(id)insertString
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
@ -4137,93 +4046,20 @@ static void ConvertCocoaKeyEventToCarbonEvent(NSEvent* cocoaEvent, EventRecord&
|
||||
#if DEBUG_IME
|
||||
NSLog(@"****in insertText: '%@'", insertString);
|
||||
#endif
|
||||
if (!mGeckoChild || !mTextInputHandler)
|
||||
return;
|
||||
|
||||
if (mTextInputHandler->IgnoreIMEComposition())
|
||||
return;
|
||||
NS_ENSURE_TRUE(mGeckoChild, );
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
if (![insertString isKindOfClass:[NSAttributedString class]])
|
||||
insertString = [[[NSAttributedString alloc] initWithString:insertString] autorelease];
|
||||
|
||||
NSString *tmpStr = [insertString string];
|
||||
unsigned int len = [tmpStr length];
|
||||
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 && !mTextInputHandler->IsIMEComposing()) {
|
||||
// don't let the same event be fired twice when hitting
|
||||
// enter/return! (Bug 420502)
|
||||
if (mKeyPressSent)
|
||||
return;
|
||||
|
||||
// dispatch keypress event with char instead of textEvent
|
||||
nsKeyEvent geckoEvent(PR_TRUE, NS_KEY_PRESS, mGeckoChild);
|
||||
geckoEvent.time = PR_IntervalNow();
|
||||
geckoEvent.charCode = bufPtr[0]; // gecko expects OS-translated unicode
|
||||
geckoEvent.keyCode = 0;
|
||||
geckoEvent.isChar = PR_TRUE;
|
||||
if (mKeyDownHandled)
|
||||
geckoEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
// don't set other modifiers from the current event, because here in
|
||||
// -insertText: they've already been taken into account in creating
|
||||
// the input string.
|
||||
|
||||
// create event for use by plugins
|
||||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
#endif
|
||||
if (mCurKeyEvent) {
|
||||
// XXX The ASCII characters inputting mode of egbridge (Japanese IME)
|
||||
// might send the keyDown event with wrong keyboard layout if other
|
||||
// keyboard layouts are already loaded. In that case, the native event
|
||||
// doesn't match to this gecko event...
|
||||
#ifndef NP_NO_CARBON
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
ConvertCocoaKeyEventToCarbonEvent(mCurKeyEvent, carbonEvent);
|
||||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif
|
||||
|
||||
geckoEvent.isShift = ([mCurKeyEvent modifierFlags] & NSShiftKeyMask) != 0;
|
||||
if (!TextInputHandler::IsPrintableChar(geckoEvent.charCode)) {
|
||||
geckoEvent.keyCode =
|
||||
TextInputHandler::ComputeGeckoKeyCode([mCurKeyEvent keyCode],
|
||||
[mCurKeyEvent charactersIgnoringModifiers]);
|
||||
geckoEvent.charCode = 0;
|
||||
}
|
||||
} else {
|
||||
// Note that insertText is not called only at key pressing.
|
||||
if (!TextInputHandler::IsPrintableChar(geckoEvent.charCode)) {
|
||||
geckoEvent.keyCode =
|
||||
TextInputHandler::ComputeGeckoKeyCodeFromChar(geckoEvent.charCode);
|
||||
geckoEvent.charCode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool keyPressHandled = mTextInputHandler->DispatchEvent(geckoEvent);
|
||||
// Note: mGeckoChild might have become null here. Don't count on it from here on.
|
||||
// Only record the results of dispatching geckoEvent if we're currently
|
||||
// processing a keyDown event.
|
||||
if (mCurKeyEvent) {
|
||||
mKeyPressHandled = keyPressHandled;
|
||||
mKeyPressSent = YES;
|
||||
}
|
||||
}
|
||||
else {
|
||||
NSAttributedString* attrStr =
|
||||
static_cast<NSAttributedString*>(insertString);
|
||||
mTextInputHandler->InsertTextAsCommittingComposition(attrStr);
|
||||
NSAttributedString* attrStr;
|
||||
if ([insertString isKindOfClass:[NSAttributedString class]]) {
|
||||
attrStr = static_cast<NSAttributedString*>(insertString);
|
||||
} else {
|
||||
attrStr =
|
||||
[[[NSAttributedString alloc] initWithString:insertString] autorelease];
|
||||
}
|
||||
|
||||
if (bufPtr != buffer)
|
||||
delete[] bufPtr;
|
||||
mTextInputHandler->InsertText(attrStr);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
@ -4237,12 +4073,15 @@ static void ConvertCocoaKeyEventToCarbonEvent(NSEvent* cocoaEvent, EventRecord&
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
PRBool ignore = mGeckoChild && mTextInputHandler->KeyPressWasHandled();
|
||||
|
||||
#if DEBUG_IME
|
||||
NSLog(@"**** in doCommandBySelector %s (ignore %d)", aSelector, mKeyPressHandled);
|
||||
NSLog(@"**** in doCommandBySelector %s (ignore %d)", aSelector, ignore);
|
||||
#endif
|
||||
|
||||
if (!mKeyPressHandled)
|
||||
if (!ignore) {
|
||||
[super doCommandBySelector:aSelector];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
@ -4374,110 +4213,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
||||
ToEscapedString([theEvent charactersIgnoringModifiers], str2)));
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
mCurKeyEvent = theEvent;
|
||||
|
||||
BOOL nonDeadKeyPress = [[theEvent characters] length] > 0;
|
||||
if (nonDeadKeyPress && !mTextInputHandler->IsIMEComposing()) {
|
||||
NSResponder* firstResponder = [[self window] firstResponder];
|
||||
|
||||
nsKeyEvent geckoKeydown(PR_TRUE, NS_KEY_DOWN, mGeckoChild);
|
||||
mTextInputHandler->InitKeyEvent(theEvent, geckoKeydown);
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
ConvertCocoaKeyEventToCarbonEvent(theEvent, carbonEvent);
|
||||
geckoKeydown.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif
|
||||
|
||||
mKeyDownHandled = mGeckoChild->DispatchWindowEvent(geckoKeydown);
|
||||
if (!mGeckoChild) {
|
||||
return mKeyDownHandled;
|
||||
}
|
||||
|
||||
// The key down event may have shifted the focus, in which
|
||||
// case we should not fire the key press.
|
||||
if (firstResponder != [[self window] firstResponder]) {
|
||||
PRBool handled = mKeyDownHandled;
|
||||
mCurKeyEvent = nil;
|
||||
mKeyDownHandled = PR_FALSE;
|
||||
return handled;
|
||||
}
|
||||
|
||||
// If this is the context menu key command, send a context menu key event.
|
||||
unsigned int modifierFlags = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||
if (modifierFlags == NSControlKeyMask && [[theEvent charactersIgnoringModifiers] isEqualToString:@" "]) {
|
||||
nsMouseEvent contextMenuEvent(PR_TRUE, NS_CONTEXTMENU, [self widget], nsMouseEvent::eReal, nsMouseEvent::eContextMenuKey);
|
||||
contextMenuEvent.isShift = contextMenuEvent.isControl = contextMenuEvent.isAlt = contextMenuEvent.isMeta = PR_FALSE;
|
||||
PRBool cmEventHandled = mGeckoChild->DispatchWindowEvent(contextMenuEvent);
|
||||
[self maybeInitContextMenuTracking];
|
||||
// Bail, there is nothing else to do here.
|
||||
PRBool handled = (cmEventHandled || mKeyDownHandled);
|
||||
mCurKeyEvent = nil;
|
||||
mKeyDownHandled = PR_FALSE;
|
||||
return handled;
|
||||
}
|
||||
|
||||
nsKeyEvent geckoKeypress(PR_TRUE, NS_KEY_PRESS, mGeckoChild);
|
||||
mTextInputHandler->InitKeyEvent(theEvent, geckoKeypress);
|
||||
|
||||
// if this is a non-letter keypress, or the control key is down,
|
||||
// dispatch the keydown to gecko, so that we trap delete,
|
||||
// control-letter combinations etc before Cocoa tries to use
|
||||
// them for keybindings.
|
||||
if ((!geckoKeypress.isChar || geckoKeypress.isControl) &&
|
||||
!mTextInputHandler->IsIMEComposing()) {
|
||||
if (mKeyDownHandled)
|
||||
geckoKeypress.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
mKeyPressHandled = mTextInputHandler->DispatchEvent(geckoKeypress);
|
||||
mKeyPressSent = YES;
|
||||
if (!mGeckoChild)
|
||||
return (mKeyDownHandled || mKeyPressHandled);
|
||||
}
|
||||
}
|
||||
|
||||
// Let Cocoa interpret the key events, caching IsIMEComposing first.
|
||||
PRBool wasComposing = mTextInputHandler->IsIMEComposing();
|
||||
PRBool interpretKeyEventsCalled = PR_FALSE;
|
||||
if (mTextInputHandler->IsIMEEnabled() ||
|
||||
mTextInputHandler->IsASCIICapableOnly()) {
|
||||
[super interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
|
||||
interpretKeyEventsCalled = PR_TRUE;
|
||||
}
|
||||
|
||||
if (!mGeckoChild) {
|
||||
return (mKeyDownHandled || mKeyPressHandled);
|
||||
}
|
||||
|
||||
if (!mKeyPressSent && nonDeadKeyPress && !wasComposing &&
|
||||
!mTextInputHandler->IsIMEComposing()) {
|
||||
nsKeyEvent geckoKeypress(PR_TRUE, NS_KEY_PRESS, mGeckoChild);
|
||||
mTextInputHandler->InitKeyEvent(theEvent, geckoKeypress);
|
||||
|
||||
// If we called interpretKeyEvents and this isn't normal character input
|
||||
// then IME probably ate the event for some reason. We do not want to
|
||||
// send a key press event in that case.
|
||||
if (!(interpretKeyEventsCalled &&
|
||||
TextInputHandler::IsNormalCharInputtingEvent(geckoKeypress))) {
|
||||
if (mKeyDownHandled) {
|
||||
geckoKeypress.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
}
|
||||
mKeyPressHandled = mTextInputHandler->DispatchEvent(geckoKeypress);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: mGeckoChild might have become null here. Don't count on it from here on.
|
||||
|
||||
PRBool handled = (mKeyDownHandled || mKeyPressHandled);
|
||||
|
||||
// See note about nested event loops where these variables are declared in header.
|
||||
mKeyPressHandled = NO;
|
||||
mKeyPressSent = NO;
|
||||
mCurKeyEvent = nil;
|
||||
mKeyDownHandled = PR_FALSE;
|
||||
|
||||
return handled;
|
||||
return mTextInputHandler->HandleKeyDownEvent(theEvent);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
@ -4746,7 +4482,9 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
||||
nsKeyEvent keyUpEvent(PR_TRUE, NS_KEY_UP, mGeckoChild);
|
||||
mTextInputHandler->InitKeyEvent(theEvent, keyUpEvent);
|
||||
EventRecord macKeyUpEvent;
|
||||
ConvertCocoaKeyEventToCarbonEvent(theEvent, macKeyUpEvent);
|
||||
TextInputHandler::ConvertCocoaKeyEventToCarbonEvent(theEvent,
|
||||
macKeyUpEvent,
|
||||
PR_FALSE);
|
||||
keyUpEvent.pluginEvent = &macKeyUpEvent;
|
||||
mGeckoChild->DispatchWindowEvent(keyUpEvent);
|
||||
}
|
||||
@ -4864,7 +4602,9 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
||||
if (mIsPluginView) {
|
||||
#ifndef NP_NO_CARBON
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
ConvertCocoaKeyEventToCarbonEvent(theEvent, carbonEvent, message);
|
||||
TextInputHandler::ConvertCocoaKeyEventToCarbonEvent(theEvent,
|
||||
carbonEvent,
|
||||
isKeyDown);
|
||||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif
|
||||
@ -5474,8 +5214,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
||||
if (NS_FAILED(rv))
|
||||
return NO;
|
||||
|
||||
if (!mGeckoChild)
|
||||
return NO;
|
||||
NS_ENSURE_TRUE(mGeckoChild, PR_FALSE);
|
||||
|
||||
nsContentCommandEvent command(PR_TRUE,
|
||||
NS_CONTENT_COMMAND_PASTE_TRANSFERABLE,
|
||||
|
Loading…
Reference in New Issue
Block a user