--- a/widget/src/cocoa/nsAppShell.mm
+++ b/widget/src/cocoa/nsAppShell.mm
@@ -51,17 +51,16 @@
#include "nsIWidget.h"
#include "nsThreadUtils.h"
#include "nsIWindowMediator.h"
#include "nsServiceManagerUtils.h"
#include "nsIInterfaceRequestor.h"
#include "nsIWebBrowserChrome.h"
#include "nsObjCExceptions.h"
#include "nsCocoaUtils.h"
-#include "nsChildView.h"
// defined in nsChildView.mm
extern nsIRollupListener * gRollupListener;
extern nsIWidget * gRollupWidget;
// defined in nsCocoaWindow.mm
extern PRInt32 gXULModalLevel;
@@ -232,18 +231,16 @@ nsAppShell::Init()
mCFRunLoopSource = ::CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
NS_ENSURE_STATE(mCFRunLoopSource);
::CFRunLoopAddSource(mCFRunLoop, mCFRunLoopSource, kCFRunLoopCommonModes);
rv = nsBaseAppShell::Init();
- NS_InstallPluginKeyEventsHandler();
-
[localPool release];
return rv;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
// ProcessGeckoEvents
@@ -605,18 +602,16 @@ nsAppShell::Exit(void)
// But we should also complain about it (since it isn't quite kosher).
if (mTerminated) {
NS_WARNING("nsAppShell::Exit() called redundantly");
return NS_OK;
}
mTerminated = PR_TRUE;
- NS_RemovePluginKeyEventsHandler();
-
// Quoting from Apple's doc on the [NSApplication stop:] method (from their
// doc on the NSApplication class): "If this method is invoked during a
// modal event loop, it will break that loop but not the main event loop."
// nsAppShell::Exit() shouldn't be called from a modal event loop. So if
// it is we complain about it (to users of debug builds) and call [NSApp
// stop:] one extra time. (I'm not sure if modal event loops can be nested
// -- Apple's docs don't say one way or the other. But the return value
// of [NSApp _isRunningModal] doesn't change immediately after a call to
--- a/widget/src/cocoa/nsChildView.h
+++ b/widget/src/cocoa/nsChildView.h
@@ -67,46 +67,16 @@
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
class gfxASurface;
class nsChildView;
union nsPluginPort;
-enum {
- // Currently focused ChildView (while this TSM document is active).
- // Transient (only set while TSMProcessRawKeyEvent() is processing a key
- // event), and the ChildView will be retained and released around the call
- // to TSMProcessRawKeyEvent() -- so it can be weak.
- kFocusedChildViewTSMDocPropertyTag = 'GKFV', // type ChildView* [WEAK]
-};
-
-// Undocumented HIToolbox function used by WebKit to allow Carbon-based IME
-// to work in a Cocoa-based browser (like Safari or Cocoa-widgets Firefox).
-// (Recent WebKit versions actually use a thin wrapper around this function
-// called WKSendKeyEventToTSM().)
-//
-// Calling TSMProcessRawKeyEvent() from ChildView's keyDown: and keyUp:
-// methods (when the ChildView is a plugin view) bypasses Cocoa's IME
-// infrastructure and (instead) causes Carbon TSM events to be sent on each
-// NSKeyDown event. We install a Carbon event handler
-// (PluginKeyEventsHandler()) to catch these events and pass them to Gecko
-// (which in turn passes them to the plugin).
-extern "C" long TSMProcessRawKeyEvent(EventRef carbonEvent);
-
-@interface NSEvent (Undocumented)
-
-// Return Cocoa event's corresponding Carbon event. Not initialized (on
-// synthetic events) until the OS actually "sends" the event. This method
-// has been present in the same form since at least OS X 10.2.8.
-- (EventRef)_eventRef;
-
-@end
-
@interface ChildView : NSView<
#ifdef ACCESSIBILITY
mozAccessible,
#endif
mozView, NSTextInput>
{
@private
NSWindow* mWindow; // shortcut to the top window, [WEAK]
@@ -157,35 +127,28 @@ extern "C" long TSMProcessRawKeyEvent(Ev
// Holds our drag service across multiple drag calls. The reference to the
// service is obtained when the mouse enters the view and is released when
// the mouse exits or there is a drop. This prevents us from having to
// re-establish the connection to the service manager many times per second
// when handling |draggingUpdated:| messages.
nsIDragService* mDragService;
PRUint32 mLastModifierState;
-
- // For use with plugins, so that we can support IME in them. We can't use
- // Cocoa TSM documents (those created and managed by the NSTSMInputContext
- // class) -- for some reason TSMProcessRawKeyEvent() doesn't work with them.
- TSMDocumentID mPluginTSMDoc;
}
// these are sent to the first responder when the window key status changes
- (void)viewsWindowDidBecomeKey;
- (void)viewsWindowDidResignKey;
// Stop NSView hierarchy being changed during [ChildView drawRect:]
- (void)delayedTearDown;
- (void)setTransparent:(BOOL)transparent;
- (void)sendFocusEvent:(PRUint32)eventType;
-
-- (void) processPluginKeyEvent:(EventRef)aKeyEvent;
@end
//-------------------------------------------------------------------------
//
// nsTSMManager
//
@@ -414,12 +377,10 @@ protected:
PRPackedBool mPluginIsCG; // true if this is a CoreGraphics plugin
PRPackedBool mInSetFocus;
nsPluginPort mPluginPort;
nsIPluginInstanceOwner* mPluginInstanceOwner; // [WEAK]
};
-void NS_InstallPluginKeyEventsHandler();
-void NS_RemovePluginKeyEventsHandler();
#endif // nsChildView_h_
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -2159,18 +2159,16 @@ NSEvent* gLastDragEvent = nil;
mKeyPressSent = NO;
// initialization for NSTextInput
mMarkedRange.location = NSNotFound;
mMarkedRange.length = 0;
mLastMouseDownEvent = nil;
mDragService = nsnull;
-
- mPluginTSMDoc = nil;
}
// register for things we'll take from other applications
PR_LOG(sCocoaLog, PR_LOG_ALWAYS, ("ChildView initWithFrame: registering drag types\n"));
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType,
NSStringPboardType,
NSURLPboardType,
NSFilesPromisePboardType,
@@ -2187,18 +2185,16 @@ NSEvent* gLastDragEvent = nil;
- (void)dealloc
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
[mPendingDirtyRects release];
[mLastMouseDownEvent release];
- if (mPluginTSMDoc)
- ::DeleteTSMDocument(mPluginTSMDoc);
if (sLastViewEntered == self)
sLastViewEntered = nil;
[super dealloc];
// This sets the current port to _savePort.
// todo: Only do if a Quickdraw plugin is present in the hierarchy!
@@ -4433,90 +4429,16 @@ GetUSLayoutCharFromKeyTranslate(UInt32 a
if (outGeckoEvent->message == NS_KEY_PRESS && !outGeckoEvent->isMeta)
[NSCursor setHiddenUntilMouseMoves:YES];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
-// Called from PluginKeyEventsHandler() (a handler for Carbon TSM events) to
-// process a Carbon key event for the currently focused plugin. Both Unicode
-// characters and "Mac encoding characters" (in the MBCS or "multibyte
-// character system") are (or should be) available from aKeyEvent, but here we
-// use the MCBS characters. This is how the WebKit does things, and seems to
-// be what plugins expect.
-- (void) processPluginKeyEvent:(EventRef)aKeyEvent
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- if (!mGeckoChild)
- return;
-
- nsAutoRetainCocoaObject kungFuDeathGrip(self);
-
- UInt32 numCharCodes;
- OSStatus status = ::GetEventParameter(aKeyEvent, kEventParamKeyMacCharCodes,
- typeChar, NULL, 0, &numCharCodes, NULL);
- if (status != noErr)
- return;
-
- nsAutoTArray<unsigned char, 3> charCodes;
- charCodes.SetLength(numCharCodes);
- status = ::GetEventParameter(aKeyEvent, kEventParamKeyMacCharCodes,
- typeChar, NULL, numCharCodes, NULL, charCodes.Elements());
- if (status != noErr)
- return;
-
- EventRef cloneEvent = ::CopyEvent(aKeyEvent);
- for (unsigned int i = 0; i < numCharCodes; ++i) {
- status = ::SetEventParameter(cloneEvent, kEventParamKeyMacCharCodes,
- typeChar, 1, charCodes.Elements() + i);
- if (status != noErr)
- break;
-
- EventRecord eventRec;
- if (::ConvertEventRefToEventRecord(cloneEvent, &eventRec)) {
- PRUint32 keyCode(GetGeckoKeyCodeFromChar((PRUnichar)charCodes.ElementAt(i)));
- PRUint32 charCode(charCodes.ElementAt(i));
-
- // For some reason we must send just an NS_KEY_PRESS to Gecko here: If
- // we send an NS_KEY_DOWN plus an NS_KEY_PRESS, or just an NS_KEY_DOWN,
- // the plugin receives two events.
- nsKeyEvent keyPressEvent(PR_TRUE, NS_KEY_PRESS, mGeckoChild);
- keyPressEvent.time = PR_IntervalNow();
- keyPressEvent.nativeMsg = &eventRec;
- if (IsSpecialGeckoKey(keyCode)) {
- keyPressEvent.keyCode = keyCode;
- } else {
- keyPressEvent.charCode = charCode;
- keyPressEvent.isChar = PR_TRUE;
- }
- mGeckoChild->DispatchWindowEvent(keyPressEvent);
- if (!mGeckoChild)
- break;
-
- // PluginKeyEventsHandler() never sends us keyUp events, so we need to
- // synthesize them for Gecko.
- nsKeyEvent keyUpEvent(PR_TRUE, NS_KEY_UP, mGeckoChild);
- keyUpEvent.time = PR_IntervalNow();
- keyUpEvent.keyCode = keyCode;
- keyUpEvent.nativeMsg = &eventRec;
- mGeckoChild->DispatchWindowEvent(keyUpEvent);
- if (!mGeckoChild)
- break;
- }
- }
-
- ::ReleaseEvent(cloneEvent);
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-
- (nsRect)sendCompositionEvent:(PRInt32) aEventType
{
#ifdef DEBUG_IME
NSLog(@"****in sendCompositionEvent; type = %d", aEventType);
#endif
if (!mGeckoChild)
return nsRect(0, 0, 0, 0);
@@ -5122,73 +5044,19 @@ static const char* ToEscapedString(NSStr
mKeyDownHandled = PR_FALSE;
return handled;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
}
-// 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
-// provices (those created and managed by the NSTSMInputContext class) -- for
-// some reason TSMProcessRawKeyEvent() doesn't work with them.)
-- (void)activatePluginTSMDoc
-{
- if (!mPluginTSMDoc) {
- // Create a TSM document that supports both non-Unicode and Unicode input.
- // Though [ChildView processPluginKeyEvent:] only sends Mac char codes to
- // the plugin, this makes the input window behave better when it contains
- // more than one kind of input (say Hiragana and Romaji). This is what
- // the OS does when it creates a TSM document for use by an
- // NSTSMInputContext class.
- InterfaceTypeList supportedServices;
- supportedServices[0] = kTextServiceDocumentInterfaceType;
- supportedServices[1] = kUnicodeDocumentInterfaceType;
- ::NewTSMDocument(2, supportedServices, &mPluginTSMDoc, 0);
- // We'll need to use the "input window".
- ::UseInputWindow(mPluginTSMDoc, YES);
- ::ActivateTSMDocument(mPluginTSMDoc);
- } else if (::TSMGetActiveDocument() != mPluginTSMDoc) {
- ::ActivateTSMDocument(mPluginTSMDoc);
- }
-}
-
-
- (void)keyDown:(NSEvent*)theEvent
{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- // If a plugin has the focus, we need to use an alternate method for
- // handling NSKeyDown and NSKeyUp events (otherwise Carbon-based IME won't
- // work in plugins like the Flash plugin). The same strategy is used by the
- // WebKit. See PluginKeyEventsHandler() and [ChildView processPluginKeyEvent:]
- // for more info.
- if (mGeckoChild && mIsPluginView) {
- [self activatePluginTSMDoc];
- // We use the active TSM document to pass a pointer to ourselves (the
- // currently focused ChildView) to PluginKeyEventsHandler(). Because this
- // pointer is weak, we should retain and release ourselves around the call
- // to TSMProcessRawKeyEvent().
- nsAutoRetainCocoaObject kungFuDeathGrip(self);
- ::TSMSetDocumentProperty(mPluginTSMDoc, kFocusedChildViewTSMDocPropertyTag,
- sizeof(ChildView *), &self);
- ::TSMProcessRawKeyEvent([theEvent _eventRef]);
- ::TSMRemoveDocumentProperty(mPluginTSMDoc, kFocusedChildViewTSMDocPropertyTag);
- return;
- }
-
[self processKeyDownEvent:theEvent keyEquiv:NO];
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
}
static BOOL keyUpAlreadySentKeyDown = NO;
- (void)keyUp:(NSEvent*)theEvent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@@ -5198,25 +5066,16 @@ static BOOL keyUpAlreadySentKeyDown = NO
nsCAutoString str2;
#endif
PR_LOG(sCocoaLog, PR_LOG_ALWAYS,
("ChildView keyUp: keycode=%d,modifiers=%x,chars=%s,charsIgnoringModifiers=%s\n",
[theEvent keyCode], [theEvent modifierFlags],
ToEscapedString([theEvent characters], str1),
ToEscapedString([theEvent charactersIgnoringModifiers], str2)));
- if (mGeckoChild && mIsPluginView) {
- // I'm not sure the call to TSMProcessRawKeyEvent() is needed here (though
- // WebKit makes one). But we definitely need to short-circuit NSKeyUp
- // handling when a plugin has the focus -- since we synthesize keyUp events
- // in [ChildView processPluginKeyEvent:].
- ::TSMProcessRawKeyEvent([theEvent _eventRef]);
- return;
- }
-
// if we don't have any characters we can't generate a keyUp event
if (!mGeckoChild || [[theEvent characters] length] == 0)
return;
nsAutoRetainCocoaObject kungFuDeathGrip(self);
// Cocoa doesn't send an NSKeyDown event for control-tab on 10.4, so if this
// is an NSKeyUp event for control-tab, send a down event to gecko first.
@@ -5996,77 +5855,8 @@ nsTSMManager::CancelIME()
// If the composing transaction is still there, KillComposing only kills the
// composing in TSM. We also need to kill the our composing transaction too.
NSAttributedString* str = [[NSAttributedString alloc] initWithString:@""];
[sComposingView insertText:str];
[str release];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
-
-
-// Target for text services events sent as the result of calls made to
-// TSMProcessRawKeyEvent() in [ChildView keyDown:] (above) when a plugin has
-// the focus. The calls to TSMProcessRawKeyEvent() short-circuit Cocoa-based
-// IME (which would otherwise interfere with our efforts) and allow Carbon-
-// based IME to work in plugins (via the NPAPI). This strategy doesn't cause
-// trouble for plugins that (like the Java Embedding Plugin) bypass the NPAPI
-// to get their keyboard events and do their own Cocoa-based IME.
-OSStatus PluginKeyEventsHandler(EventHandlerCallRef inHandlerRef,
- EventRef inEvent, void *userData)
-{
- id arp = [[NSAutoreleasePool alloc] init];
-
- TSMDocumentID activeDoc = ::TSMGetActiveDocument();
- if (!activeDoc) {
- [arp release];
- return eventNotHandledErr;
- }
-
- ChildView *target = nil;
- OSStatus status = ::TSMGetDocumentProperty(activeDoc, kFocusedChildViewTSMDocPropertyTag,
- sizeof(ChildView *), nil, &target);
- if (status != noErr)
- target = nil;
- if (!target) {
- [arp release];
- return eventNotHandledErr;
- }
-
- EventRef keyEvent = NULL;
- status = ::GetEventParameter(inEvent, kEventParamTextInputSendKeyboardEvent,
- typeEventRef, NULL, sizeof(EventRef), NULL, &keyEvent);
- if ((status != noErr) || !keyEvent) {
- [arp release];
- return eventNotHandledErr;
- }
-
- [target processPluginKeyEvent:keyEvent];
-
- [arp release];
- return noErr;
-}
-
-static EventHandlerRef gPluginKeyEventsHandler = NULL;
-
-// Called from nsAppShell::Init()
-void NS_InstallPluginKeyEventsHandler()
-{
- if (gPluginKeyEventsHandler)
- return;
- static const EventTypeSpec sTSMEvents[] =
- { { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } };
- ::InstallEventHandler(::GetEventDispatcherTarget(),
- ::NewEventHandlerUPP(PluginKeyEventsHandler),
- GetEventTypeCount(sTSMEvents),
- sTSMEvents,
- NULL,
- &gPluginKeyEventsHandler);
-}
-
-// Called from nsAppShell::Exit()
-void NS_RemovePluginKeyEventsHandler()
-{
- if (!gPluginKeyEventsHandler)
- return;
- ::RemoveEventHandler(gPluginKeyEventsHandler);
- gPluginKeyEventsHandler = NULL;
-}