Backout of bug 357670 due to bug 434914. a=shaver
authordtownsend@oxymoronical.com
Fri, 30 May 2008 07:32:43 -0700
changeset 15200 9a2801dccb5dff9e14056960bead0c73437174ec
parent 15199 33a6b9b325a7f9a8c75bfa30d9ed7367dc638e5a
child 15201 a61611c9992a4f57427da96bdc668713ae236ea1
push id52
push userbsmedberg@mozilla.com
push dateFri, 30 May 2008 16:09:28 +0000
treeherdermozilla-central@a61611c9992a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshaver
bugs357670, 434914
milestone1.9pre
Backout of bug 357670 due to bug 434914. a=shaver
widget/src/cocoa/nsAppShell.mm
widget/src/cocoa/nsChildView.h
widget/src/cocoa/nsChildView.mm
--- 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;
-}