From dc97c80e3564c46e208d6ab9c3f49ccb4f29fd7b Mon Sep 17 00:00:00 2001 From: "mark%moxienet.com" Date: Mon, 22 May 2006 00:34:35 +0000 Subject: [PATCH] 337199 Key event/text input regressions on Mac after bug 332579, RETURN key events double-processed. Also: 337277 Typed characters appear twice after visiting site with Java applet, 337338 Typing special characters (accents) and symbols with Option fails, 337370 Japanese IME broken, 336357 Keystrokes inserted twice into text input fields. Rework key event and TSM handlers. r=josh sr=shaver a/1.8.1=me&shaver --- widget/src/mac/Makefile.in | 1 - widget/src/mac/nsMacEventHandler.cpp | 186 ++++++++++++++++--------- widget/src/mac/nsMacEventHandler.h | 5 +- widget/src/mac/nsMacMessagePump.cpp | 3 + widget/src/mac/nsMacTSMMessagePump.cpp | 42 ++---- widget/src/mac/nsMacWindow.cpp | 79 ++++++++--- widget/src/mac/nsMacWindow.h | 3 + widget/src/mac/nsTSMStrategy.cpp | 95 ------------- widget/src/mac/nsTSMStrategy.h | 54 ------- 9 files changed, 204 insertions(+), 264 deletions(-) delete mode 100644 widget/src/mac/nsTSMStrategy.cpp delete mode 100644 widget/src/mac/nsTSMStrategy.h diff --git a/widget/src/mac/Makefile.in b/widget/src/mac/Makefile.in index ba829a78aca8..87f50b00415c 100644 --- a/widget/src/mac/Makefile.in +++ b/widget/src/mac/Makefile.in @@ -103,7 +103,6 @@ CPPSRCS = nsAppShell.cpp \ nsMimeMapper.cpp \ nsNativeThemeMac.cpp \ nsSound.cpp \ - nsTSMStrategy.cpp \ nsToolkitBase.cpp \ nsToolkit.cpp \ nsWidgetFactory.cpp \ diff --git a/widget/src/mac/nsMacEventHandler.cpp b/widget/src/mac/nsMacEventHandler.cpp index b1da131b0be6..6ee422786709 100644 --- a/widget/src/mac/nsMacEventHandler.cpp +++ b/widget/src/mac/nsMacEventHandler.cpp @@ -49,13 +49,8 @@ #include "nsCarbonHelpers.h" #include "nsIRollupListener.h" #include "nsIMenuRollup.h" -#include "nsTSMStrategy.h" #include "nsGfxUtils.h" -#ifndef XP_MACOSX -#include -#endif - #define PINK_PROFILING_ACTIVATE 0 #if PINK_PROFILING_ACTIVATE #include "profilerutils.h" @@ -92,20 +87,6 @@ nsMacEventDispatchHandler gEventDispatchHandler; static void ConvertKeyEventToContextMenuEvent(const nsKeyEvent* inKeyEvent, nsMouseEvent* outCMEvent); static inline PRBool IsContextMenuKey(const nsKeyEvent& inKeyEvent); -class StPackedBoolSetter { - public: - StPackedBoolSetter(PRPackedBool& aFlag): mFlag(aFlag) { - mFlag = PR_TRUE; - }; - - ~StPackedBoolSetter() { - mFlag = PR_FALSE; - }; - - protected: - PRPackedBool& mFlag; -}; - //------------------------------------------------------------------------- // @@ -362,23 +343,17 @@ void nsMacEventDispatchHandler::SetGlobalPoint(Point inPoint) //------------------------------------------------------------------------- nsMacEventHandler::nsMacEventHandler(nsMacWindow* aTopLevelWidget) { - OSErr err; - InterfaceTypeList supportedServices; - - mTopLevelWidget = aTopLevelWidget; - - nsTSMStrategy tsmstrategy; - - // - // create a TSMDocument for this window. We are allocating a TSM document for - // each Mac window - // - mTSMDocument = nsnull; - if (tsmstrategy.UseUnicodeForInputMethod()) { - supportedServices[0] = kUnicodeDocument; - } else { - supportedServices[0] = kTextService; - } + OSErr err; + InterfaceTypeList supportedServices; + + mTopLevelWidget = aTopLevelWidget; + + // + // create a TSMDocument for this window. We are allocating a TSM document for + // each Mac window + // + mTSMDocument = nsnull; + supportedServices[0] = kUnicodeDocument; err = ::NewTSMDocument(1, supportedServices,&mTSMDocument, (long)this); NS_ASSERTION(err==noErr, "nsMacEventHandler::nsMacEventHandler: NewTSMDocument failed."); #ifdef DEBUG_TSM @@ -393,7 +368,8 @@ nsMacEventHandler::nsMacEventHandler(nsMacWindow* aTopLevelWidget) mIMEIsComposing = PR_FALSE; mIMECompositionStr = nsnull; - mHandlingKeyEvent = PR_FALSE; + mKeyIgnore = PR_FALSE; + mKeyHandled = PR_FALSE; } @@ -690,10 +666,8 @@ enum }; -static PRUint32 ConvertMacToRaptorKeyCode(UInt32 eventMessage, UInt32 eventModifiers) +static PRUint32 ConvertMacToRaptorKeyCode(char charCode, UInt32 keyCode, UInt32 eventModifiers) { - UInt8 charCode = (eventMessage & charCodeMask); - UInt8 keyCode = (eventMessage & keyCodeMask) >> 8; PRUint32 raptorKeyCode = 0; switch (keyCode) @@ -881,7 +855,7 @@ void nsMacEventHandler::InitializeKeyEvent(nsKeyEvent& aKeyEvent, } // if (message == NS_KEY_PRESS && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) ) else { - aKeyEvent.keyCode = ConvertMacToRaptorKeyCode(aOSEvent.message, aOSEvent.modifiers); + aKeyEvent.keyCode = ConvertMacToRaptorKeyCode(aOSEvent.message & charCodeMask, (aOSEvent.message & keyCodeMask) >> 8, aOSEvent.modifiers); aKeyEvent.charCode = 0; } // else for if (message == NS_KEY_PRESS && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) ) @@ -1045,12 +1019,6 @@ PRUint32 nsMacEventHandler::ConvertKeyEventToUnicode(EventRecord& aOSEvent) PRBool nsMacEventHandler::HandleKeyEvent(EventRecord& aOSEvent) { - // Avoid reentrancy - if (mHandlingKeyEvent) - return PR_FALSE; - - StPackedBoolSetter handling(mHandlingKeyEvent); - nsresult result = NS_ERROR_UNEXPECTED; nsWindow* checkFocusedWidget; @@ -1166,34 +1134,17 @@ IsContextMenuKey(const nsKeyEvent& inKeyEvent) //------------------------------------------------------------------------- PRBool nsMacEventHandler::HandleUKeyEvent(const PRUnichar* text, long charCount, EventRecord& aOSEvent) { - // Avoid reentrancy - if (mHandlingKeyEvent) + // The focused widget changed in HandleKeyUpDownEvent, so no NS_KEY_PRESS + // events should be generated. + if (mKeyIgnore) return PR_FALSE; - StPackedBoolSetter handling(mHandlingKeyEvent); - nsresult result = NS_ERROR_UNEXPECTED; // get the focused widget nsWindow* focusedWidget = gEventDispatchHandler.GetActive(); if (!focusedWidget) focusedWidget = mTopLevelWidget; - // simulate key down event if this isn't an autoKey event - if (aOSEvent.what == keyDown) - { - nsKeyEvent keyDownEvent(PR_TRUE, NS_KEY_DOWN, nsnull); - InitializeKeyEvent(keyDownEvent, aOSEvent, focusedWidget, NS_KEY_DOWN, PR_FALSE); - result = focusedWidget->DispatchWindowEvent(keyDownEvent); - NS_ASSERTION(NS_SUCCEEDED(result), "cannot DispatchWindowEvent keydown"); - - // check if focus changed; see also HandleKeyEvent above - nsWindow *checkFocusedWidget = gEventDispatchHandler.GetActive(); - if (!checkFocusedWidget) - checkFocusedWidget = mTopLevelWidget; - if (checkFocusedWidget != focusedWidget) - return result; - } - // simulate key press events if (!IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8)) { @@ -1205,6 +1156,10 @@ PRBool nsMacEventHandler::HandleUKeyEvent(const PRUnichar* text, long charCount, InitializeKeyEvent(keyPressEvent, aOSEvent, focusedWidget, NS_KEY_PRESS, PR_FALSE); keyPressEvent.charCode = text[i]; + // If keydown default was prevented, do same for keypress + if (mKeyHandled) + keyPressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT; + // control key is special in that it doesn't give us letters // it generates a charcode of 0x01 for control-a // so we offset to do the right thing for gecko (as in HandleKeyEvent) @@ -2669,3 +2624,100 @@ nsresult nsMacEventHandler::ResetInputState() return NS_OK; } +PRBool +nsMacEventHandler::HandleKeyUpDownEvent(EventHandlerCallRef aHandlerCallRef, + EventRef aEvent) +{ + PRUint32 eventKind = ::GetEventKind(aEvent); + NS_ASSERTION(eventKind == kEventRawKeyDown || + eventKind == kEventRawKeyUp, + "Unknown event kind"); + + PRBool handled = PR_FALSE; + nsWindow* focusedWidget = gEventDispatchHandler.GetActive(); + if (!focusedWidget) + focusedWidget = mTopLevelWidget; + + PRUint32 modifiers = 0; + OSStatus err = ::GetEventParameter(aEvent, kEventParamKeyModifiers, + typeUInt32, NULL, + sizeof(modifiers), NULL, + &modifiers); + NS_ASSERTION(err == noErr, "Could not get kEventParamKeyModifiers"); + + PRUint32 keyCode = 0; + err = ::GetEventParameter(aEvent, kEventParamKeyCode, + typeUInt32, NULL, + sizeof(keyCode), NULL, + &keyCode); + NS_ASSERTION(err == noErr, "Could not get kEventParamKeyCode"); + + PRUint8 charCode = 0; + ::GetEventParameter(aEvent, kEventParamKeyMacCharCodes, + typeChar, NULL, + sizeof(charCode), NULL, + &charCode); + // Failure is not a fatal condition. + + // The event's nativeMsg field historically held an EventRecord. Some + // consumers (plugins) rely on this behavior. Note that + // ConvertEventRefToEventRecord can return false and produce a null + // event record in some cases, such as when entering an IME session. + EventRecord eventRecord; + ::ConvertEventRefToEventRecord(aEvent, &eventRecord); + + // kEventRawKeyDown or kEventRawKeyUp only + + PRUint32 message = (eventKind == kEventRawKeyUp ? NS_KEY_UP : NS_KEY_DOWN); + nsKeyEvent upDownEvent(PR_TRUE, message, nsnull); + upDownEvent.time = PR_IntervalNow(); + upDownEvent.widget = focusedWidget; + upDownEvent.nativeMsg = (void*)&eventRecord; + upDownEvent.isShift = ((modifiers & shiftKey) != 0); + upDownEvent.isControl = ((modifiers & controlKey) != 0); + upDownEvent.isAlt = ((modifiers & optionKey) != 0); + upDownEvent.isMeta = ((modifiers & cmdKey) != 0); + upDownEvent.keyCode = ConvertMacToRaptorKeyCode(charCode, keyCode, + modifiers); + upDownEvent.charCode = 0; + handled = focusedWidget->DispatchWindowEvent(upDownEvent); + + if (eventKind == kEventRawKeyUp) + return handled; + + // kEventRawKeyDown only. Prepare for a possible NS_KEY_PRESS event. + + nsWindow* checkFocusedWidget = gEventDispatchHandler.GetActive(); + if (!checkFocusedWidget) + checkFocusedWidget = mTopLevelWidget; + + // Set a flag indicating that NS_KEY_PRESS events should not be dispatched, + // because focus changed. + PRBool lastIgnore = PR_FALSE; + if (checkFocusedWidget != focusedWidget) { + lastIgnore = mKeyIgnore; + mKeyIgnore = PR_TRUE; + } + + // Set a flag indicating that the NS_KEY_DOWN event came back with + // preventDefault, and NS_KEY_PRESS events should have the same flag set. + PRBool lastHandled = PR_FALSE; + if (handled) { + lastHandled = mKeyHandled; + mKeyHandled = PR_TRUE; + } + + // The event needs further processing. + // - If no input method is active, an event will be delivered to the + // kEventTextInputUnicodeForKeyEvent handler, which will call + // HandleUKeyEvent, which takes care of dispatching NS_KEY_PRESS events. + // - If an input method is active, an event will be delivered to the + // kEventTextInputUpdateActiveInputArea handler, which will call + // UnicodeHandleUpdateInputArea to handle the input session. + ::CallNextEventHandler(aHandlerCallRef, aEvent); + + mKeyHandled = lastHandled; + mKeyIgnore = lastIgnore; + + return handled; +} diff --git a/widget/src/mac/nsMacEventHandler.h b/widget/src/mac/nsMacEventHandler.h index 4073cfade919..e51ae775a42d 100644 --- a/widget/src/mac/nsMacEventHandler.h +++ b/widget/src/mac/nsMacEventHandler.h @@ -131,6 +131,8 @@ public: virtual nsresult HandleUnicodeGetSelectedText(nsAString& outString); virtual nsresult ResetInputState(); virtual PRBool HandleUKeyEvent(const PRUnichar* text, long charCount, EventRecord& aOSEvent); + virtual PRBool HandleKeyUpDownEvent(EventHandlerCallRef aHandlerCallRef, + EventRef aEvent); // // Synthetic events, generated internally to do things at specific times and @@ -172,7 +174,8 @@ protected: nsPoint mIMEPos; nsAutoString *mIMECompositionStr; PRPackedBool mIMEIsComposing; - PRPackedBool mHandlingKeyEvent; + PRPackedBool mKeyIgnore; + PRPackedBool mKeyHandled; }; #endif // MacMacEventHandler_h__ diff --git a/widget/src/mac/nsMacMessagePump.cpp b/widget/src/mac/nsMacMessagePump.cpp index baad43c276b8..c5efaa19d12d 100644 --- a/widget/src/mac/nsMacMessagePump.cpp +++ b/widget/src/mac/nsMacMessagePump.cpp @@ -81,9 +81,12 @@ nsMacMessagePump::nsMacMessagePump(nsToolkit *aToolkit) { kEventClassMouse, kEventMouseUp }, { kEventClassMouse, kEventMouseMoved }, { kEventClassMouse, kEventMouseDragged }, +#if 0 + // These are now handled by nsMacWindow::KeyEventHandler { kEventClassKeyboard, kEventRawKeyDown }, { kEventClassKeyboard, kEventRawKeyUp }, { kEventClassKeyboard, kEventRawKeyRepeat }, +#endif { kEventClassWindow, kEventWindowUpdate }, { kEventClassWindow, kEventWindowActivated }, { kEventClassWindow, kEventWindowDeactivated }, diff --git a/widget/src/mac/nsMacTSMMessagePump.cpp b/widget/src/mac/nsMacTSMMessagePump.cpp index 86a6e2371ab2..5edc2e51dc6d 100644 --- a/widget/src/mac/nsMacTSMMessagePump.cpp +++ b/widget/src/mac/nsMacTSMMessagePump.cpp @@ -42,7 +42,6 @@ #include #include #include -#include "nsTSMStrategy.h" #include "nsCarbonHelpers.h" @@ -67,7 +66,6 @@ AEEventHandlerUPP nsMacTSMMessagePump::mGetSelectedTextUPP = NULL; nsMacTSMMessagePump::nsMacTSMMessagePump() { OSErr err; - nsTSMStrategy tsmstrategy; mPos2OffsetUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::PositionToOffsetHandler); NS_ASSERTION(mPos2OffsetUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[Pos2Pffset] failed"); @@ -75,11 +73,7 @@ nsMacTSMMessagePump::nsMacTSMMessagePump() mOffset2PosUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::OffsetToPositionHandler); NS_ASSERTION(mPos2OffsetUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[Pos2Pffset] failed"); - if (tsmstrategy.UseUnicodeForInputMethod()) { - mUpdateUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeUpdateHandler); - } else { - mUpdateUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UpdateHandler); - } + mUpdateUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeUpdateHandler); NS_ASSERTION(mPos2OffsetUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[Pos2Pffset] failed"); err = AEInstallEventHandler(kTextServiceClass, kPos2Offset, mPos2OffsetUPP, (long)this, false); @@ -91,20 +85,17 @@ nsMacTSMMessagePump::nsMacTSMMessagePump() err = AEInstallEventHandler(kTextServiceClass, kUpdateActiveInputArea, mUpdateUPP, (long)this, false); NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[Update] failed"); - if (tsmstrategy.UseUnicodeForKeyboard()) { - mKeyboardUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeNotFromInputMethodHandler); - NS_ASSERTION(mKeyboardUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[FromInputMethod] failed"); + mKeyboardUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeNotFromInputMethodHandler); + NS_ASSERTION(mKeyboardUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[FromInputMethod] failed"); - err = AEInstallEventHandler(kTextServiceClass, kUnicodeNotFromInputMethod, mKeyboardUPP, (long)this, false); - NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[FromInputMethod] failed"); + err = AEInstallEventHandler(kTextServiceClass, kUnicodeNotFromInputMethod, mKeyboardUPP, (long)this, false); + NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[FromInputMethod] failed"); - mGetSelectedTextUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeGetSelectedTextHandler); - NS_ASSERTION(mGetSelectedTextUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[GetSelectedText] failed"); + mGetSelectedTextUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeGetSelectedTextHandler); + NS_ASSERTION(mGetSelectedTextUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[GetSelectedText] failed"); - err = AEInstallEventHandler(kTextServiceClass, kGetSelectedText, mGetSelectedTextUPP, (long)this, false); - NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[GetSelectedText] failed"); - - } + err = AEInstallEventHandler(kTextServiceClass, kGetSelectedText, mGetSelectedTextUPP, (long)this, false); + NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[GetSelectedText] failed"); } @@ -125,16 +116,13 @@ nsMacTSMMessagePump::~nsMacTSMMessagePump() ::DisposeAEEventHandlerUPP(mOffset2PosUPP); ::DisposeAEEventHandlerUPP(mUpdateUPP); - nsTSMStrategy tsmstrategy; - if (tsmstrategy.UseUnicodeForKeyboard()) { - err = AERemoveEventHandler(kTextServiceClass, kUnicodeNotFromInputMethod, mKeyboardUPP, false); - NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::RemoveTSMAEHandlers: AERemoveEventHandler[FromInputMethod] failed"); - ::DisposeAEEventHandlerUPP(mKeyboardUPP); + err = AERemoveEventHandler(kTextServiceClass, kUnicodeNotFromInputMethod, mKeyboardUPP, false); + NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::RemoveTSMAEHandlers: AERemoveEventHandler[FromInputMethod] failed"); + ::DisposeAEEventHandlerUPP(mKeyboardUPP); - err = AERemoveEventHandler(kTextServiceClass, kGetSelectedText, mGetSelectedTextUPP, false); - NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::RemoveTSMAEHandlers: AERemoveEventHandler[GetSelectedText] failed"); - ::DisposeAEEventHandlerUPP(mGetSelectedTextUPP); - } + err = AERemoveEventHandler(kTextServiceClass, kGetSelectedText, mGetSelectedTextUPP, false); + NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::RemoveTSMAEHandlers: AERemoveEventHandler[GetSelectedText] failed"); + ::DisposeAEEventHandlerUPP(mGetSelectedTextUPP); } diff --git a/widget/src/mac/nsMacWindow.cpp b/widget/src/mac/nsMacWindow.cpp index eca7100dbe34..2c482e61bf42 100644 --- a/widget/src/mac/nsMacWindow.cpp +++ b/widget/src/mac/nsMacWindow.cpp @@ -563,25 +563,25 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, if ( mWindowType != eWindowType_invisible && mWindowType != eWindowType_plugin && mWindowType != eWindowType_java) { - const EventTypeSpec scrollEventList[] = { - { kEventClassMouse, kEventMouseWheelMoved } + const EventTypeSpec kScrollEventList[] = { + { kEventClassMouse, kEventMouseWheelMoved }, }; - // note, passing NULL as the final param to IWEH() causes the UPP to be - // disposed automatically when the event target (the window) goes away. - // See CarbonEvents.h for info. - err = ::InstallWindowEventHandler(mWindowPtr, - NewEventHandlerUPP(ScrollEventHandler), - GetEventTypeCount(scrollEventList), - scrollEventList, this, NULL); - NS_ASSERTION(err == noErr, - "Couldn't install Carbon Scroll Event handlers"); + static EventHandlerUPP sScrollEventHandlerUPP; + if (!sScrollEventHandlerUPP) + sScrollEventHandlerUPP = ::NewEventHandlerUPP(ScrollEventHandler); + + err = ::InstallWindowEventHandler(mWindowPtr, + sScrollEventHandlerUPP, + GetEventTypeCount(kScrollEventList), + kScrollEventList, + (void*)this, + NULL); + NS_ASSERTION(err == noErr, "Couldn't install scroll event handler"); } - // Since we can only call IWEH() once for each event class such as - // kEventClassWindow, we register all the event types that we are going to - // handle here. - const EventTypeSpec windEventList[] = { + // Window event handler + const EventTypeSpec kWindowEventList[] = { // to enable live resizing { kEventClassWindow, kEventWindowBoundsChanged }, // to roll up popups when we're minimized @@ -594,12 +594,35 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, { kEventClassWindow, kEventWindowUpdate }, }; - PRUint32 typeCount = GetEventTypeCount(windEventList); + static EventHandlerUPP sWindowEventHandlerUPP; + if (!sWindowEventHandlerUPP) + sWindowEventHandlerUPP = ::NewEventHandlerUPP(WindowEventHandler); err = ::InstallWindowEventHandler(mWindowPtr, - NewEventHandlerUPP(WindowEventHandler), - typeCount, windEventList, this, NULL); - NS_ASSERTION(err == noErr, "Couldn't install sheet Event handlers"); + sWindowEventHandlerUPP, + GetEventTypeCount(kWindowEventList), + kWindowEventList, + (void*)this, + NULL); + NS_ASSERTION(err == noErr, "Couldn't install window event handler"); + + // Key event handler + const EventTypeSpec kKeyEventList[] = { + { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassKeyboard, kEventRawKeyUp }, + }; + + static EventHandlerUPP sKeyEventHandlerUPP; + if (!sKeyEventHandlerUPP) + sKeyEventHandlerUPP = ::NewEventHandlerUPP(KeyEventHandler); + + err = ::InstallWindowEventHandler(mWindowPtr, + sKeyEventHandlerUPP, + GetEventTypeCount(kKeyEventList), + kKeyEventList, + NS_STATIC_CAST(void*, this), + NULL); + NS_ASSERTION(err == noErr, "Couldn't install key event handler"); // register tracking and receive handlers with the native Drag Manager if ( mDragTrackingHandlerUPP ) { @@ -2193,3 +2216,21 @@ NS_IMETHODIMP nsMacWindow::Update() return rv; } + +pascal OSStatus +nsMacWindow::KeyEventHandler(EventHandlerCallRef aHandlerCallRef, + EventRef aEvent, + void* aUserData) +{ + nsMacWindow* self = NS_STATIC_CAST(nsMacWindow*, aUserData); + NS_ASSERTION(self, "No self?"); + NS_ASSERTION(self->mMacEventHandler.get(), "No mMacEventHandler?"); + + PRBool handled = self->mMacEventHandler->HandleKeyUpDownEvent(aHandlerCallRef, + aEvent); + + if (!handled) + return eventNotHandledErr; + + return noErr; +} diff --git a/widget/src/mac/nsMacWindow.h b/widget/src/mac/nsMacWindow.h index 840ca43c17bd..de236210f314 100644 --- a/widget/src/mac/nsMacWindow.h +++ b/widget/src/mac/nsMacWindow.h @@ -151,6 +151,9 @@ protected: EventRef inEvent, void* userData ) ; pascal static OSStatus ScrollEventHandler ( EventHandlerCallRef inHandlerChain, EventRef inEvent, void* userData ) ; + pascal static OSStatus KeyEventHandler(EventHandlerCallRef aHandlerCallRef, + EventRef aEvent, + void* aUserData); nsresult GetDesktopRect(Rect* desktopRect); PRPackedBool mWindowMadeHere; // true if we created the window diff --git a/widget/src/mac/nsTSMStrategy.cpp b/widget/src/mac/nsTSMStrategy.cpp deleted file mode 100644 index 121dd4413cda..000000000000 --- a/widget/src/mac/nsTSMStrategy.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Frank Yung-Fong Tang - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include "nsTSMStrategy.h" - -#ifdef DEBUG - -//#define FORCE_USE_UNICODE_API -//#define FORCE_NOT_USE_UNICODE_API - -#endif - - -PRBool nsTSMStrategy::gUseUnicodeForInputMethod = PR_FALSE; -PRBool nsTSMStrategy::gUseUnicodeForKeyboard = PR_FALSE; -PRBool nsTSMStrategy::gInit = PR_FALSE; - -void nsTSMStrategy::Init() -{ - if ( !gInit) - { - gInit = PR_TRUE; - OSErr err; - long version; - err = Gestalt(gestaltTSMgrVersion, &version); - if ((err == noErr) && (version >= gestaltTSMgr15)) - { - // only enable if OS 9.0 or greater; there is a bug - // (in at least OS 8.6) that causes double input (Bug #106022) - // see also bug #110828 - err = Gestalt(gestaltSystemVersion, &version); - PRBool doEnable = (err == noErr) && (version >= 0x900); - gUseUnicodeForKeyboard = doEnable; - gUseUnicodeForInputMethod = doEnable; - } -#ifdef FORCE_USE_UNICODE_API - gUseUnicodeForInputMethod = PR_TRUE; -#elif defined( FORCE_NOT_USE_UNICODE_API ) - gUseUnicodeForInputMethod = PR_FALSE; -#endif - // there are no way we can use unicode for keyboard, but not using - // Unicode for IME - if ( !gUseUnicodeForInputMethod) - gUseUnicodeForKeyboard = PR_FALSE; - } - -} - -PRBool nsTSMStrategy::UseUnicodeForInputMethod() -{ - Init(); - return gUseUnicodeForInputMethod; -} - -PRBool nsTSMStrategy::UseUnicodeForKeyboard() -{ - Init(); - return gUseUnicodeForKeyboard; -} \ No newline at end of file diff --git a/widget/src/mac/nsTSMStrategy.h b/widget/src/mac/nsTSMStrategy.h deleted file mode 100644 index 41537bb8a2b3..000000000000 --- a/widget/src/mac/nsTSMStrategy.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Frank Yung-Fong Tang - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsTSMStrategy_h__ -#define nsTSMStrategyr_h__ -#include "nscore.h" - -class nsTSMStrategy { - public: - PRBool UseUnicodeForInputMethod(); - PRBool UseUnicodeForKeyboard(); - private: - static PRBool gUseUnicodeForInputMethod; - static PRBool gUseUnicodeForKeyboard; - static PRBool gInit; - void Init(); -}; - -#endif // nsTSMStrategy_h__