Backout of bug 357670 due to bug 434914. a=shaver

This commit is contained in:
dtownsend@oxymoronical.com 2008-05-30 07:32:43 -07:00
Родитель 2505ae95f9
Коммит deb15a4120
3 изменённых файлов: 0 добавлений и 254 удалений

Просмотреть файл

@ -56,7 +56,6 @@
#include "nsIWebBrowserChrome.h"
#include "nsObjCExceptions.h"
#include "nsCocoaUtils.h"
#include "nsChildView.h"
// defined in nsChildView.mm
extern nsIRollupListener * gRollupListener;
@ -237,8 +236,6 @@ nsAppShell::Init()
rv = nsBaseAppShell::Init();
NS_InstallPluginKeyEventsHandler();
[localPool release];
return rv;
@ -610,8 +607,6 @@ nsAppShell::Exit(void)
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."

Просмотреть файл

@ -72,36 +72,6 @@ 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,
@ -162,11 +132,6 @@ extern "C" long TSMProcessRawKeyEvent(EventRef carbonEvent);
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
@ -179,8 +144,6 @@ extern "C" long TSMProcessRawKeyEvent(EventRef carbonEvent);
- (void)setTransparent:(BOOL)transparent;
- (void)sendFocusEvent:(PRUint32)eventType;
- (void) processPluginKeyEvent:(EventRef)aKeyEvent;
@end
@ -419,7 +382,5 @@ protected:
nsIPluginInstanceOwner* mPluginInstanceOwner; // [WEAK]
};
void NS_InstallPluginKeyEventsHandler();
void NS_RemovePluginKeyEventsHandler();
#endif // nsChildView_h_

Просмотреть файл

@ -2164,8 +2164,6 @@ NSEvent* gLastDragEvent = nil;
mLastMouseDownEvent = nil;
mDragService = nsnull;
mPluginTSMDoc = nil;
}
// register for things we'll take from other applications
@ -2192,8 +2190,6 @@ NSEvent* gLastDragEvent = nil;
[mPendingDirtyRects release];
[mLastMouseDownEvent release];
if (mPluginTSMDoc)
::DeleteTSMDocument(mPluginTSMDoc);
if (sLastViewEntered == self)
sLastViewEntered = nil;
@ -4438,80 +4434,6 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
}
// 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
@ -5127,63 +5049,9 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
}
// 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;
}
@ -5203,15 +5071,6 @@ static BOOL keyUpAlreadySentKeyDown = NO;
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;
@ -6001,72 +5860,3 @@ nsTSMManager::CancelIME()
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;
}