mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 519972 part.10 Move keyup and flagsChanged code to TextInputHandler r=smichaud
This commit is contained in:
parent
160860a0e2
commit
599da8a7a1
@ -628,9 +628,6 @@ public:
|
||||
*/
|
||||
void HandleKeyUpEventForPlugin(NSEvent* aNativeKeyEvent);
|
||||
|
||||
PRBool DoesIgnoreNextKeyUpEvent() { return mIgnoreNextKeyUpEvent; }
|
||||
void ResetIgnoreNextKeyUpEvent() { mIgnoreNextKeyUpEvent = PR_FALSE; }
|
||||
|
||||
/**
|
||||
* ConvertCocoaKeyEventToNPCocoaEvent() converts aCocoaEvent to NPCocoaEvent.
|
||||
*
|
||||
@ -665,26 +662,15 @@ public:
|
||||
mPluginTSMInComposition = aInComposition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TSM document for use with plugins, so that we can support IME in
|
||||
* them. Once it's created, if need be (re)activate it. Some plugins (e.g.
|
||||
* the Flash plugin running in Camino) don't create their own TSM document --
|
||||
* without which IME can't work. Others (e.g. the Flash plugin running in
|
||||
* Firefox) create a TSM document that (somehow) makes the input window behave
|
||||
* badly when it contains more than one kind of input (say Hiragana and
|
||||
* Romaji). (We can't just use the per-NSView TSM documents that Cocoa
|
||||
* provides (those created and managed by the NSTSMInputContext class) -- for
|
||||
* some reason TSMProcessRawKeyEvent() doesn't work with them.)
|
||||
*/
|
||||
void ActivatePluginTSMDocument();
|
||||
#endif // #ifndef NP_NO_CARBON
|
||||
|
||||
/**
|
||||
* HandleCarbonPluginKeyEvent() handles the aKeyEvent. This is called by
|
||||
* PluginKeyEventsHandler().
|
||||
*
|
||||
* @param aKeyEvent A native Carbon event.
|
||||
*/
|
||||
void HandleCarbonPluginKeyEvent(EventRef aKeyEvent);
|
||||
protected:
|
||||
PRPackedBool mIgnoreNextKeyUpEvent;
|
||||
|
||||
PluginTextInputHandler(nsChildView* aWidget, NSView<mozView> *aNativeView);
|
||||
~PluginTextInputHandler();
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
|
||||
/**
|
||||
* ConvertCocoaKeyEventToCarbonEvent() converts aCocoaKeyEvent to
|
||||
@ -706,12 +692,6 @@ public:
|
||||
|
||||
#endif // #ifndef NP_NO_CARBON
|
||||
|
||||
protected:
|
||||
PRPackedBool mIgnoreNextKeyUpEvent;
|
||||
|
||||
PluginTextInputHandler(nsChildView* aWidget, NSView<mozView> *aNativeView);
|
||||
~PluginTextInputHandler();
|
||||
|
||||
private:
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
@ -743,6 +723,27 @@ private:
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
|
||||
/**
|
||||
* Create a TSM document for use with plugins, so that we can support IME in
|
||||
* them. Once it's created, if need be (re)activate it. Some plugins (e.g.
|
||||
* the Flash plugin running in Camino) don't create their own TSM document --
|
||||
* without which IME can't work. Others (e.g. the Flash plugin running in
|
||||
* Firefox) create a TSM document that (somehow) makes the input window behave
|
||||
* badly when it contains more than one kind of input (say Hiragana and
|
||||
* Romaji). (We can't just use the per-NSView TSM documents that Cocoa
|
||||
* provides (those created and managed by the NSTSMInputContext class) -- for
|
||||
* some reason TSMProcessRawKeyEvent() doesn't work with them.)
|
||||
*/
|
||||
void ActivatePluginTSMDocument();
|
||||
|
||||
/**
|
||||
* HandleCarbonPluginKeyEvent() handles the aKeyEvent. This is called by
|
||||
* PluginKeyEventsHandler().
|
||||
*
|
||||
* @param aKeyEvent A native Carbon event.
|
||||
*/
|
||||
void HandleCarbonPluginKeyEvent(EventRef aKeyEvent);
|
||||
|
||||
/**
|
||||
* ConvertUnicodeToCharCode() converts aUnichar to native encoded string.
|
||||
*
|
||||
@ -1066,6 +1067,8 @@ private:
|
||||
class TextInputHandler : public IMEInputHandler
|
||||
{
|
||||
public:
|
||||
static PRBool sLastModifierState;
|
||||
|
||||
static CFArrayRef CreateAllKeyboardLayoutList();
|
||||
static void DebugPrintAllKeyboardLayouts(PRLogModuleInfo* aLogModuleInfo);
|
||||
|
||||
@ -1075,13 +1078,26 @@ public:
|
||||
/**
|
||||
* KeyDown event handler.
|
||||
*
|
||||
* @param aNativeEvent A native keydown event which you want to
|
||||
* handle.
|
||||
* @param aNativeEvent A native NSKeyDown event.
|
||||
* @return TRUE if the event is consumed by web contents
|
||||
* or chrome contents. Otherwise, FALSE.
|
||||
*/
|
||||
PRBool HandleKeyDownEvent(NSEvent* aNativeEvent);
|
||||
|
||||
/**
|
||||
* KeyUp event handler.
|
||||
*
|
||||
* @param aNativeEvent A native NSKeyUp event.
|
||||
*/
|
||||
void HandleKeyUpEvent(NSEvent* aNativeEvent);
|
||||
|
||||
/**
|
||||
* FlagsChanged event handler.
|
||||
*
|
||||
* @param aNativeEvent A native NSFlagsChanged event.
|
||||
*/
|
||||
void HandleFlagsChanged(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
|
||||
@ -1104,6 +1120,20 @@ public:
|
||||
{
|
||||
return mCurrentKeyEvent.mKeyPressHandled;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* DispatchKeyEventForFlagsChanged() dispatches keydown event or keyup event
|
||||
* for the aNativeEvent.
|
||||
*
|
||||
* @param aNativeEvent A native flagschanged event which you want to
|
||||
* dispatch our key event for.
|
||||
* @param aDispatchKeyDown TRUE if you want to dispatch a keydown event.
|
||||
* Otherwise, i.e., to dispatch keyup event,
|
||||
* FALSE.
|
||||
*/
|
||||
void DispatchKeyEventForFlagsChanged(NSEvent* aNativeEvent,
|
||||
PRBool aDispatchKeyDown);
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
|
@ -766,6 +766,8 @@ TISInputSourceWrapper::InitKeyPressEvent(NSEvent *aNativeKeyEvent,
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
PRBool TextInputHandler::sLastModifierState = PR_FALSE;
|
||||
|
||||
// static
|
||||
CFArrayRef
|
||||
TextInputHandler::CreateAllKeyboardLayoutList()
|
||||
@ -951,6 +953,132 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent)
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
TextInputHandler::HandleKeyUpEvent(NSEvent* aNativeEvent)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (mIgnoreNextKeyUpEvent) {
|
||||
mIgnoreNextKeyUpEvent = PR_FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if we don't have any characters we can't generate a keyUp event
|
||||
if ([[aNativeEvent characters] length] == 0 || IsIMEComposing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsKeyEvent keyupEvent(PR_TRUE, NS_KEY_UP, mWidget);
|
||||
InitKeyEvent(aNativeEvent, keyupEvent);
|
||||
|
||||
DispatchEvent(keyupEvent);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
void
|
||||
TextInputHandler::HandleFlagsChanged(NSEvent* aNativeEvent)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsChildView> kungFuDeathGrip(mWidget);
|
||||
|
||||
// CapsLock state and other modifier states are different:
|
||||
// CapsLock state does not revert when the CapsLock key goes up, as the
|
||||
// modifier state does for other modifier keys on key up.
|
||||
if ([aNativeEvent keyCode] == kCapsLockKeyCode) {
|
||||
// Fire key down event for caps lock.
|
||||
DispatchKeyEventForFlagsChanged(aNativeEvent, PR_TRUE);
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
// XXX should we fire keyup event too? The keyup event for CapsLock key
|
||||
// is never dispatched on Gecko.
|
||||
} else if ([aNativeEvent type] == NSFlagsChanged) {
|
||||
// Fire key up/down events for the modifier keys (shift, alt, ctrl, command)
|
||||
NSUInteger modifiers =
|
||||
[aNativeEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||
const NSUInteger kModifierMaskTable[] =
|
||||
{ NSShiftKeyMask, NSControlKeyMask,
|
||||
NSAlternateKeyMask, NSCommandKeyMask };
|
||||
const PRUint32 kModifierCount = NS_ARRAY_LENGTH(kModifierMaskTable);
|
||||
|
||||
for (PRUint32 i = 0; i < kModifierCount; i++) {
|
||||
NSUInteger modifierBit = kModifierMaskTable[i];
|
||||
if ((modifiers & modifierBit) != (sLastModifierState & modifierBit)) {
|
||||
PRBool isKeyDown = ((modifiers & modifierBit) != 0);
|
||||
DispatchKeyEventForFlagsChanged(aNativeEvent, isKeyDown);
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop if focus has changed.
|
||||
// Check to see if mView is still the first responder.
|
||||
if (![mView isFirstResponder]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sLastModifierState = modifiers;
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
void
|
||||
TextInputHandler::DispatchKeyEventForFlagsChanged(NSEvent* aNativeEvent,
|
||||
PRBool aDispatchKeyDown)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ([aNativeEvent type] != NSFlagsChanged || IsIMEComposing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 message = aDispatchKeyDown ? NS_KEY_DOWN : NS_KEY_UP;
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
#endif // ifndef NP_NO_CARBON
|
||||
NPCocoaEvent cocoaEvent;
|
||||
|
||||
// Fire a key event.
|
||||
nsKeyEvent keyEvent(PR_TRUE, message, mWidget);
|
||||
InitKeyEvent(aNativeEvent, keyEvent);
|
||||
|
||||
// create event for use by plugins
|
||||
if ([mView isPluginView]) {
|
||||
#ifndef NP_NO_CARBON
|
||||
if ([mView pluginEventModel] == NPEventModelCarbon) {
|
||||
ConvertCocoaKeyEventToCarbonEvent(aNativeEvent, carbonEvent,
|
||||
aDispatchKeyDown);
|
||||
keyEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif // ifndef NP_NO_CARBON
|
||||
if ([mView pluginEventModel] == NPEventModelCocoa) {
|
||||
ConvertCocoaKeyEventToNPCocoaEvent(aNativeEvent, cocoaEvent);
|
||||
keyEvent.pluginEvent = &cocoaEvent;
|
||||
}
|
||||
}
|
||||
|
||||
DispatchEvent(keyEvent);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
void
|
||||
TextInputHandler::InsertText(NSAttributedString *aAttrString)
|
||||
{
|
||||
@ -2739,6 +2867,11 @@ PluginTextInputHandler::HandleKeyDownEventForPlugin(NSEvent* aNativeKeyEvent)
|
||||
void
|
||||
PluginTextInputHandler::HandleKeyUpEventForPlugin(NSEvent* aNativeKeyEvent)
|
||||
{
|
||||
if (mIgnoreNextKeyUpEvent) {
|
||||
mIgnoreNextKeyUpEvent = PR_FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
@ -87,6 +87,9 @@ class TextInputHandler;
|
||||
// Call when you dispatch an event which may cause to open context menu.
|
||||
- (void)maybeInitContextMenuTracking;
|
||||
|
||||
// Checks whether the view is for plugin or not
|
||||
- (BOOL)isPluginView;
|
||||
|
||||
@end
|
||||
|
||||
// An informal protocol implemented by the NSWindow of the host application.
|
||||
|
@ -70,7 +70,6 @@ using namespace mozilla::widget;
|
||||
// defined in nsChildView.mm
|
||||
extern nsIRollupListener * gRollupListener;
|
||||
extern nsIWidget * gRollupWidget;
|
||||
extern PRUint32 gLastModifierState;
|
||||
|
||||
// defined in nsCocoaWindow.mm
|
||||
extern PRInt32 gXULModalLevel;
|
||||
@ -950,8 +949,9 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
|
||||
|
||||
// applicationDidBecomeActive
|
||||
//
|
||||
// Make sure gLastModifierState is updated when we become active (since we
|
||||
// won't have received [ChildView flagsChanged:] messages while inactive).
|
||||
// Make sure TextInputHandler::sLastModifierState is updated when we become
|
||||
// active (since we won't have received [ChildView flagsChanged:] messages
|
||||
// while inactive).
|
||||
- (void)applicationDidBecomeActive:(NSNotification*)aNotification
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
@ -960,7 +960,8 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
|
||||
// to worry about getting an NSInternalInconsistencyException here.
|
||||
NSEvent* currentEvent = [NSApp currentEvent];
|
||||
if (currentEvent) {
|
||||
gLastModifierState = [currentEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||
TextInputHandler::sLastModifierState =
|
||||
[currentEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
|
@ -145,8 +145,6 @@ nsIRollupListener * gRollupListener = nsnull;
|
||||
nsIMenuRollup * gMenuRollup = nsnull;
|
||||
nsIWidget * gRollupWidget = nsnull;
|
||||
|
||||
PRUint32 gLastModifierState = 0;
|
||||
|
||||
PRBool gUserCancelledDrag = PR_FALSE;
|
||||
|
||||
PRUint32 nsChildView::sLastInputEventCount = 0;
|
||||
@ -166,7 +164,6 @@ PRUint32 nsChildView::sLastInputEventCount = 0;
|
||||
- (NSMenu*)contextMenu;
|
||||
|
||||
- (void)setIsPluginView:(BOOL)aIsPlugin;
|
||||
- (BOOL)isPluginView;
|
||||
- (void)setPluginEventModel:(NPEventModel)eventModel;
|
||||
- (void)setPluginDrawingModel:(NPDrawingModel)drawingModel;
|
||||
- (NPDrawingModel)pluginDrawingModel;
|
||||
@ -191,8 +188,6 @@ PRUint32 nsChildView::sLastInputEventCount = 0;
|
||||
- (id<mozAccessible>)accessible;
|
||||
#endif
|
||||
|
||||
- (void)fireKeyEventForFlagsChanged:(NSEvent*)theEvent keyDown:(BOOL)isKeyDown;
|
||||
|
||||
- (BOOL)inactiveWindowAcceptsMouseEvent:(NSEvent*)aEvent;
|
||||
|
||||
@end
|
||||
@ -4094,13 +4089,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
||||
ToEscapedString([theEvent characters], str1),
|
||||
ToEscapedString([theEvent charactersIgnoringModifiers], str2)));
|
||||
|
||||
if (!mGeckoChild || !mTextInputHandler)
|
||||
return;
|
||||
|
||||
if (mTextInputHandler->DoesIgnoreNextKeyUpEvent()) {
|
||||
mTextInputHandler->ResetIgnoreNextKeyUpEvent();
|
||||
return;
|
||||
}
|
||||
NS_ENSURE_TRUE(mGeckoChild, );
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
@ -4109,16 +4098,7 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
||||
return;
|
||||
}
|
||||
|
||||
// if we don't have any characters we can't generate a keyUp event
|
||||
if ([[theEvent characters] length] == 0 ||
|
||||
mTextInputHandler->IsIMEComposing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsKeyEvent geckoEvent(PR_TRUE, NS_KEY_UP, mGeckoChild);
|
||||
mTextInputHandler->InitKeyEvent(theEvent, geckoEvent);
|
||||
|
||||
mGeckoChild->DispatchWindowEvent(geckoEvent);
|
||||
mTextInputHandler->HandleKeyUpEvent(theEvent);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
@ -4127,48 +4107,10 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (!mGeckoChild)
|
||||
return;
|
||||
NS_ENSURE_TRUE(mGeckoChild, );
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
// CapsLock state and other modifier states are different:
|
||||
// CapsLock state does not revert when the CapsLock key goes up, as the
|
||||
// modifier state does for other modifier keys on key up.
|
||||
if ([theEvent keyCode] == kCapsLockKeyCode) {
|
||||
// Fire key down event for caps lock.
|
||||
[self fireKeyEventForFlagsChanged:theEvent keyDown:YES];
|
||||
if (!mGeckoChild)
|
||||
return;
|
||||
// XXX should we fire keyup event too? The keyup event for CapsLock key
|
||||
// is never sent to gecko.
|
||||
} else if ([theEvent type] == NSFlagsChanged) {
|
||||
// Fire key up/down events for the modifier keys (shift, alt, ctrl, command).
|
||||
unsigned int modifiers = [theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||
const PRUint32 kModifierMaskTable[] =
|
||||
{ NSShiftKeyMask, NSControlKeyMask, NSAlternateKeyMask, NSCommandKeyMask };
|
||||
const PRUint32 kModifierCount = sizeof(kModifierMaskTable) /
|
||||
sizeof(kModifierMaskTable[0]);
|
||||
|
||||
for (PRUint32 i = 0; i < kModifierCount; i++) {
|
||||
PRUint32 modifierBit = kModifierMaskTable[i];
|
||||
if ((modifiers & modifierBit) != (gLastModifierState & modifierBit)) {
|
||||
BOOL isKeyDown = (modifiers & modifierBit) != 0 ? YES : NO;
|
||||
|
||||
[self fireKeyEventForFlagsChanged:theEvent keyDown:isKeyDown];
|
||||
|
||||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
// Stop if focus has changed.
|
||||
// Check to see if we are still the first responder.
|
||||
if (![self isFirstResponder])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gLastModifierState = modifiers;
|
||||
}
|
||||
mTextInputHandler->HandleFlagsChanged(theEvent);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
@ -4193,50 +4135,6 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
||||
return dragSession != nsnull;
|
||||
}
|
||||
|
||||
- (void)fireKeyEventForFlagsChanged:(NSEvent*)theEvent keyDown:(BOOL)isKeyDown
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (!mGeckoChild || !mTextInputHandler || [theEvent type] != NSFlagsChanged ||
|
||||
mTextInputHandler->IsIMEComposing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
PRUint32 message = isKeyDown ? NS_KEY_DOWN : NS_KEY_UP;
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
#endif // ifndef NP_NO_CARBON
|
||||
NPCocoaEvent cocoaEvent;
|
||||
|
||||
// Fire a key event.
|
||||
nsKeyEvent geckoEvent(PR_TRUE, message, mGeckoChild);
|
||||
mTextInputHandler->InitKeyEvent(theEvent, geckoEvent);
|
||||
|
||||
// create event for use by plugins
|
||||
if (mIsPluginView) {
|
||||
#ifndef NP_NO_CARBON
|
||||
if (mPluginEventModel == NPEventModelCarbon) {
|
||||
TextInputHandler::ConvertCocoaKeyEventToCarbonEvent(theEvent,
|
||||
carbonEvent,
|
||||
isKeyDown);
|
||||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
TextInputHandler::ConvertCocoaKeyEventToNPCocoaEvent(theEvent,
|
||||
cocoaEvent);
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
}
|
||||
}
|
||||
|
||||
mGeckoChild->DispatchWindowEvent(geckoEvent);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (BOOL)inactiveWindowAcceptsMouseEvent:(NSEvent*)aEvent
|
||||
{
|
||||
// If we're being destroyed assume the default -- return YES.
|
||||
|
Loading…
Reference in New Issue
Block a user