зеркало из https://github.com/mozilla/gecko-dev.git
Add support for Cocoa NPAPI complex text input. This patch contains a TSM-based implementation for 32-bit builds, and an NSInputContext-based implementation for 64-bit builds. b=512886 r=smichaud sr=jst
This commit is contained in:
Родитель
8c6be1cd28
Коммит
d5610f20b4
|
@ -1730,9 +1730,7 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
|
|||
pluginEvent.event = mDoublePassEvent;
|
||||
pluginEvent.wParam = 0;
|
||||
pluginEvent.lParam = 0;
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
|
||||
inst->HandleEvent(&pluginEvent, &eventHandled);
|
||||
inst->HandleEvent(&pluginEvent, nsnull);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1793,9 +1791,7 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
|
|||
pluginEvent.event = WM_WINDOWPOSCHANGED;
|
||||
pluginEvent.wParam = 0;
|
||||
pluginEvent.lParam = (uint32)&winpos;
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
|
||||
inst->HandleEvent(&pluginEvent, &eventHandled);
|
||||
inst->HandleEvent(&pluginEvent, nsnull);
|
||||
}
|
||||
|
||||
inst->SetWindow(window);
|
||||
|
@ -3797,8 +3793,7 @@ void nsPluginInstanceOwner::ScrollPositionWillChange(nscoord aX, nscoord aY)
|
|||
|
||||
void* window = FixUpPluginWindow(ePluginPaintDisable);
|
||||
if (window) {
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&scrollEvent, &eventHandled);
|
||||
mInstance->HandleEvent(&scrollEvent, nsnull);
|
||||
}
|
||||
pluginWidget->EndDrawPlugin();
|
||||
}
|
||||
|
@ -3821,8 +3816,7 @@ void nsPluginInstanceOwner::ScrollPositionDidChange(nscoord aX, nscoord aY)
|
|||
|
||||
void* window = FixUpPluginWindow(ePluginPaintEnable);
|
||||
if (window) {
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&scrollEvent, &eventHandled);
|
||||
mInstance->HandleEvent(&scrollEvent, nsnull);
|
||||
}
|
||||
pluginWidget->EndDrawPlugin();
|
||||
}
|
||||
|
@ -4415,9 +4409,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEventX11Composited(const nsGUIEvent&
|
|||
|
||||
#if 0
|
||||
/* we've sent the event via XSendEvent so don't send it directly to the plugin */
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&pluginEvent, &eventHandled);
|
||||
if (eventHandled)
|
||||
PRInt16 response = kNPEventNotHandled;
|
||||
mInstance->HandleEvent(&pluginEvent, &response);
|
||||
if (response == kNPEventHandled)
|
||||
rv = nsEventStatus_eConsumeNoDefault;
|
||||
#endif
|
||||
|
||||
|
@ -4578,13 +4572,17 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
|
|||
::DeactivateTSMDocument(::TSMGetActiveDocument());
|
||||
#endif
|
||||
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
PRInt16 response = kNPEventNotHandled;
|
||||
void* window = FixUpPluginWindow(ePluginPaintEnable);
|
||||
if (window || (eventModel == NPEventModelCocoa)) {
|
||||
mInstance->HandleEvent(event, &eventHandled);
|
||||
mInstance->HandleEvent(event, &response);
|
||||
}
|
||||
|
||||
if (eventHandled &&
|
||||
if (eventModel == NPEventModelCocoa && response == kNPEventStartIME) {
|
||||
pluginWidget->StartComplexTextInputForCurrentEvent();
|
||||
}
|
||||
|
||||
if ((response == kNPEventHandled || response == kNPEventStartIME) &&
|
||||
!(anEvent.eventStructType == NS_MOUSE_EVENT &&
|
||||
anEvent.message == NS_MOUSE_BUTTON_DOWN &&
|
||||
static_cast<const nsMouseEvent&>(anEvent).button == nsMouseEvent::eLeftButton &&
|
||||
|
@ -4692,9 +4690,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
|
|||
}
|
||||
|
||||
if (pPluginEvent) {
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(pPluginEvent, &eventHandled);
|
||||
if (eventHandled)
|
||||
PRInt16 response = kNPEventNotHandled;
|
||||
mInstance->HandleEvent(pPluginEvent, &response);
|
||||
if (response == kNPEventHandled)
|
||||
rv = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
#endif
|
||||
|
@ -4893,10 +4891,10 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
|
|||
event.serial = 0;
|
||||
event.send_event = False;
|
||||
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&pluginEvent, &eventHandled);
|
||||
if (eventHandled)
|
||||
rv = nsEventStatus_eConsumeNoDefault;
|
||||
PRInt16 response = kNPEventNotHandled;
|
||||
mInstance->HandleEvent(&pluginEvent, &response);
|
||||
if (response == kNPEventHandled)
|
||||
rv = nsEventStatus_eConsumeNoDefault;
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
|
@ -5019,8 +5017,7 @@ void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgCont
|
|||
updateEvent.what = updateEvt;
|
||||
updateEvent.message = UInt32(window);
|
||||
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&updateEvent, &eventHandled);
|
||||
mInstance->HandleEvent(&updateEvent, nsnull);
|
||||
} else if (GetEventModel() == NPEventModelCocoa)
|
||||
#endif
|
||||
{
|
||||
|
@ -5034,8 +5031,7 @@ void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgCont
|
|||
updateEvent.data.draw.width = aDirtyRect.Width();
|
||||
updateEvent.data.draw.height = aDirtyRect.Height();
|
||||
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&updateEvent, &eventHandled);
|
||||
mInstance->HandleEvent(&updateEvent, nsnull);
|
||||
}
|
||||
pluginWidget->EndDrawPlugin();
|
||||
}
|
||||
|
@ -5052,8 +5048,7 @@ void nsPluginInstanceOwner::Paint(const RECT& aDirty, HDC aDC)
|
|||
pluginEvent.event = WM_PAINT;
|
||||
pluginEvent.wParam = WPARAM(aDC);
|
||||
pluginEvent.lParam = LPARAM(&aDirty);
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&pluginEvent, &eventHandled);
|
||||
mInstance->HandleEvent(&pluginEvent, nsnull);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -5079,9 +5074,7 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, HPS aHPS)
|
|||
pluginEvent.event = WM_PAINT;
|
||||
pluginEvent.wParam = (uint32)aHPS;
|
||||
pluginEvent.lParam = (uint32)&rectl;
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&pluginEvent, &eventHandled);
|
||||
|
||||
mInstance->HandleEvent(&pluginEvent, nsnull);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -5420,10 +5413,9 @@ nsPluginInstanceOwner::NativeImageDraw(NPRect* invalidRect)
|
|||
if (invalidRect)
|
||||
memset(mSharedXImage->data, 0, mPluginSize.width * mPluginSize.height * 2);
|
||||
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&pluginEvent, &eventHandled);
|
||||
|
||||
if (!eventHandled)
|
||||
PRInt16 response = kNPEventNotHandled;
|
||||
mInstance->HandleEvent(&pluginEvent, &response);
|
||||
if (response == kNPEventNotHandled)
|
||||
return;
|
||||
|
||||
// Setup the clip rectangle
|
||||
|
@ -5600,8 +5592,7 @@ nsPluginInstanceOwner::Renderer::NativeDraw(gfxXlibSurface * xsurface,
|
|||
exposeEvent.major_code = 0;
|
||||
exposeEvent.minor_code = 0;
|
||||
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&pluginEvent, &eventHandled);
|
||||
mInstance->HandleEvent(&pluginEvent, nsnull);
|
||||
#ifdef MOZ_COMPOSITED_PLUGINS
|
||||
}
|
||||
else {
|
||||
|
@ -5654,8 +5645,7 @@ void nsPluginInstanceOwner::SendIdleEvent()
|
|||
if (!mWidgetVisible)
|
||||
idleEvent.where.h = idleEvent.where.v = 20000;
|
||||
|
||||
PRBool eventHandled = PR_FALSE;
|
||||
mInstance->HandleEvent(&idleEvent, &eventHandled);
|
||||
mInstance->HandleEvent(&idleEvent, nsnull);
|
||||
}
|
||||
|
||||
pluginWidget->EndDrawPlugin();
|
||||
|
@ -5879,13 +5869,12 @@ PRBool nsPluginInstanceOwner::UpdateVisibility(PRBool aVisible)
|
|||
if (!mInstance)
|
||||
return PR_TRUE;
|
||||
|
||||
PRBool handled;
|
||||
NPEvent pluginEvent;
|
||||
XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility;
|
||||
visibilityEvent.type = VisibilityNotify;
|
||||
visibilityEvent.display = 0;
|
||||
visibilityEvent.state = aVisible ? VisibilityUnobscured : VisibilityFullyObscured;
|
||||
mInstance->HandleEvent(&pluginEvent, &handled);
|
||||
mInstance->HandleEvent(&pluginEvent, nsnull);
|
||||
|
||||
mWidgetVisible = PR_TRUE;
|
||||
return PR_TRUE;
|
||||
|
|
|
@ -53,7 +53,7 @@ struct JSObject;
|
|||
[ptr] native JSContextPtr(JSContext);
|
||||
[ptr] native JSObjectPtr(JSObject);
|
||||
|
||||
[uuid(3B091A81-D15A-4645-83B3-AC0C68A776DB)]
|
||||
[uuid(84994340-E120-4051-824F-D4EE8AEF1A3E)]
|
||||
interface nsIPluginInstance : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -144,10 +144,11 @@ interface nsIPluginInstance : nsISupports
|
|||
* (Corresponds to NPP_HandleEvent.)
|
||||
*
|
||||
* @param aEvent - the event to be handled
|
||||
* @param aHandled - set to PR_TRUE if event was handled
|
||||
* @param aHandled - if non-NULL, set to the NPAPI NPP_HandleEvent
|
||||
* return value
|
||||
* @result - NS_OK if this operation was successful
|
||||
*/
|
||||
void handleEvent(in voidPtr aEvent, out boolean aHandled);
|
||||
void handleEvent(in voidPtr aEvent, out PRInt16 aHandled);
|
||||
|
||||
/**
|
||||
* Corresponds to NPN_InvalidateRect
|
||||
|
|
|
@ -1360,7 +1360,7 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Print(NPPrint* platformPrint)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNPAPIPluginInstance::HandleEvent(void* event, PRBool* handled)
|
||||
NS_IMETHODIMP nsNPAPIPluginInstance::HandleEvent(void* event, PRInt16* result)
|
||||
{
|
||||
if (RUNNING != mRunning)
|
||||
return NS_OK;
|
||||
|
@ -1370,20 +1370,21 @@ NS_IMETHODIMP nsNPAPIPluginInstance::HandleEvent(void* event, PRBool* handled)
|
|||
|
||||
PluginDestructionGuard guard(this);
|
||||
|
||||
PRInt16 result = 0;
|
||||
|
||||
PRInt16 tmpResult = kNPEventNotHandled;
|
||||
|
||||
if (mCallbacks->event) {
|
||||
mCurrentPluginEvent = event;
|
||||
#if defined(XP_WIN) || defined(XP_OS2)
|
||||
NS_TRY_SAFE_CALL_RETURN(result, (*mCallbacks->event)(&mNPP, event), mLibrary, this);
|
||||
NS_TRY_SAFE_CALL_RETURN(tmpResult, (*mCallbacks->event)(&mNPP, event), mLibrary, this);
|
||||
#else
|
||||
result = (*mCallbacks->event)(&mNPP, event);
|
||||
tmpResult = (*mCallbacks->event)(&mNPP, event);
|
||||
#endif
|
||||
NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
||||
("NPP HandleEvent called: this=%p, npp=%p, event=%p, return=%d\n",
|
||||
this, &mNPP, event, result));
|
||||
this, &mNPP, event, tmpResult));
|
||||
|
||||
*handled = result;
|
||||
if (result)
|
||||
*result = tmpResult;
|
||||
mCurrentPluginEvent = nsnull;
|
||||
}
|
||||
|
||||
|
|
|
@ -1946,7 +1946,7 @@ necessary. Here is a sample; alter the names:
|
|||
|
||||
<h1><a name="apple"></a>Apple License</h1>
|
||||
|
||||
<p class="correctme">This license applies to certain files in the directories <span class="path">js/src/assembler/assembler/</span> and <span class="path">js/src/assembler/wtf/</span>.</p>
|
||||
<p class="correctme">This license applies to certain files in the directories <span class="path">js/src/assembler/assembler/</span>, <span class="path">js/src/assembler/wtf/</span>, and <span class="path">widget/src/cocoa</span>.</p>
|
||||
|
||||
<pre>
|
||||
Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
|
||||
|
|
|
@ -37,12 +37,9 @@
|
|||
|
||||
#include "nsISupports.h"
|
||||
|
||||
/* starting interface: nsIPluginWidget */
|
||||
#define NS_IPLUGINWIDGET_IID_STR "034E8A7E-BE36-4039-B229-39C41E9D4CD2"
|
||||
|
||||
#define NS_IPLUGINWIDGET_IID \
|
||||
{ 0x034E8A7E, 0xBE36, 0x4039, \
|
||||
{ 0xB2, 0x29, 0x39, 0xC4, 0x1E, 0x9D, 0x4C, 0xD2 } }
|
||||
{ 0xEB9207E0, 0xD8F1, 0x44B9, \
|
||||
{ 0xB7, 0x52, 0xAF, 0x8E, 0x9F, 0x8E, 0xBD, 0xF7 } }
|
||||
|
||||
struct nsIntPoint;
|
||||
class nsIPluginInstanceOwner;
|
||||
|
@ -64,6 +61,8 @@ class NS_NO_VTABLE nsIPluginWidget : public nsISupports
|
|||
NS_IMETHOD SetPluginEventModel(int inEventModel) = 0;
|
||||
|
||||
NS_IMETHOD GetPluginEventModel(int* outEventModel) = 0;
|
||||
|
||||
NS_IMETHOD StartComplexTextInputForCurrentEvent() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIPluginWidget, NS_IPLUGINWIDGET_IID)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Modified by Josh Aas of Mozilla Corporation.
|
||||
*/
|
||||
|
||||
#ifndef ComplexTextInputPanel_h_
|
||||
#define ComplexTextInputPanel_h_
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface ComplexTextInputPanel : NSPanel {
|
||||
NSTextView *mInputTextView;
|
||||
}
|
||||
|
||||
+ (ComplexTextInputPanel*)sharedComplexTextInputPanel;
|
||||
|
||||
- (NSTextInputContext*)inputContext;
|
||||
- (BOOL)interpretKeyEvent:(NSEvent*)event string:(NSString**)string;
|
||||
|
||||
@end
|
||||
|
||||
#endif // ComplexTextInputPanel_h_
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Modified by Josh Aas of Mozilla Corporation.
|
||||
*/
|
||||
|
||||
#import "ComplexTextInputPanel.h"
|
||||
|
||||
#define kInputWindowHeight 20
|
||||
|
||||
@implementation ComplexTextInputPanel
|
||||
|
||||
+ (ComplexTextInputPanel*)sharedComplexTextInputPanel
|
||||
{
|
||||
static ComplexTextInputPanel *sComplexTextInputPanel;
|
||||
if (!sComplexTextInputPanel)
|
||||
sComplexTextInputPanel = [[ComplexTextInputPanel alloc] init];
|
||||
return sComplexTextInputPanel;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
// In the original Apple code the style mask is given by a function which is not open source.
|
||||
// What could possibly be worth hiding in that function, I do not know.
|
||||
// Courtesy of gdb: stylemask: 011000011111, 0x61f
|
||||
self = [super initWithContentRect:NSZeroRect styleMask:0x61f backing:NSBackingStoreBuffered defer:YES];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
// Set the frame size.
|
||||
NSRect visibleFrame = [[NSScreen mainScreen] visibleFrame];
|
||||
NSRect frame = NSMakeRect(visibleFrame.origin.x, visibleFrame.origin.y, visibleFrame.size.width, kInputWindowHeight);
|
||||
|
||||
[self setFrame:frame display:NO];
|
||||
|
||||
mInputTextView = [[NSTextView alloc] initWithFrame:[self.contentView frame]];
|
||||
mInputTextView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable | NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin;
|
||||
|
||||
NSScrollView* scrollView = [[NSScrollView alloc] initWithFrame:[self.contentView frame]];
|
||||
scrollView.documentView = mInputTextView;
|
||||
self.contentView = scrollView;
|
||||
[scrollView release];
|
||||
|
||||
[self setFloatingPanel:YES];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(keyboardInputSourceChanged:)
|
||||
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
||||
object:nil];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
[mInputTextView release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)keyboardInputSourceChanged:(NSNotification *)notification
|
||||
{
|
||||
[mInputTextView setString:@""];
|
||||
[self orderOut:nil];
|
||||
}
|
||||
|
||||
- (BOOL)interpretKeyEvent:(NSEvent*)event string:(NSString**)string
|
||||
{
|
||||
BOOL hadMarkedText = [mInputTextView hasMarkedText];
|
||||
|
||||
*string = nil;
|
||||
|
||||
if (![[mInputTextView inputContext] handleEvent:event])
|
||||
return NO;
|
||||
|
||||
if ([mInputTextView hasMarkedText]) {
|
||||
// Don't show the input method window for dead keys
|
||||
if ([[event characters] length] > 0)
|
||||
[self orderFront:nil];
|
||||
|
||||
return YES;
|
||||
} else {
|
||||
[self orderOut:nil];
|
||||
|
||||
NSString *text = [[mInputTextView textStorage] string];
|
||||
if ([text length] > 0)
|
||||
*string = [[text copy] autorelease];
|
||||
}
|
||||
|
||||
[mInputTextView setString:@""];
|
||||
return hadMarkedText;
|
||||
}
|
||||
|
||||
- (NSTextInputContext*)inputContext
|
||||
{
|
||||
return [mInputTextView inputContext];
|
||||
}
|
||||
|
||||
@end
|
|
@ -94,6 +94,10 @@ CMMSRCS = \
|
|||
nsStandaloneNativeMenu.mm \
|
||||
$(NULL)
|
||||
|
||||
ifeq (x86_64,$(TARGET_CPU))
|
||||
CMMSRCS += ComplexTextInputPanel.mm
|
||||
endif
|
||||
|
||||
XPIDLSRCS += \
|
||||
nsPIWidgetCocoa.idl \
|
||||
$(NULL)
|
||||
|
|
|
@ -162,6 +162,7 @@ extern "C" long TSMProcessRawKeyEvent(EventRef carbonEvent);
|
|||
// class) -- for some reason TSMProcessRawKeyEvent() doesn't work with them.
|
||||
TSMDocumentID mPluginTSMDoc;
|
||||
#endif
|
||||
BOOL mPluginComplexTextInputRequested;
|
||||
|
||||
NSOpenGLContext *mContext;
|
||||
|
||||
|
@ -212,6 +213,7 @@ extern "C" long TSMProcessRawKeyEvent(EventRef carbonEvent);
|
|||
#ifndef NP_NO_CARBON
|
||||
- (void) processPluginKeyEvent:(EventRef)aKeyEvent;
|
||||
#endif
|
||||
- (void)pluginRequestsComplexTextInputForCurrentEvent;
|
||||
|
||||
- (void)update;
|
||||
- (void)lockFocus;
|
||||
|
@ -349,6 +351,8 @@ public:
|
|||
NS_IMETHOD SetPluginEventModel(int inEventModel);
|
||||
NS_IMETHOD GetPluginEventModel(int* outEventModel);
|
||||
|
||||
NS_IMETHOD StartComplexTextInputForCurrentEvent();
|
||||
|
||||
virtual nsTransparencyMode GetTransparencyMode();
|
||||
virtual void SetTransparencyMode(nsTransparencyMode aMode);
|
||||
|
||||
|
|
|
@ -74,6 +74,9 @@
|
|||
#include "nsCocoaUtils.h"
|
||||
#include "nsMenuUtilsX.h"
|
||||
#include "nsMenuBarX.h"
|
||||
#ifdef __LP64__
|
||||
#include "ComplexTextInputPanel.h"
|
||||
#endif
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxQuartzSurface.h"
|
||||
|
@ -1331,6 +1334,12 @@ NS_IMETHODIMP nsChildView::GetPluginEventModel(int* outEventModel)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsChildView::StartComplexTextInputForCurrentEvent()
|
||||
{
|
||||
[(ChildView*)mView pluginRequestsComplexTextInputForCurrentEvent];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NSString* ToNSString(const nsAString& aString)
|
||||
{
|
||||
return [NSString stringWithCharacters:aString.BeginReading()
|
||||
|
@ -2203,6 +2212,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
|||
#ifndef NP_NO_CARBON
|
||||
mPluginTSMDoc = nil;
|
||||
#endif
|
||||
mPluginComplexTextInputRequested = NO;
|
||||
|
||||
mGestureState = eGestureState_None;
|
||||
mCumulativeMagnification = 0.0;
|
||||
|
@ -4464,6 +4474,44 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
UInt32 size;
|
||||
OSStatus status = ::GetEventParameter(aKeyEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, 0, &size, NULL);
|
||||
if (status != noErr)
|
||||
return;
|
||||
|
||||
UniChar* chars = (UniChar*)malloc(size);
|
||||
if (!chars)
|
||||
return;
|
||||
|
||||
status = ::GetEventParameter(aKeyEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, size, NULL, chars);
|
||||
if (status != noErr) {
|
||||
free(chars);
|
||||
return;
|
||||
}
|
||||
|
||||
CFStringRef text = ::CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, chars, (size / sizeof(UniChar)), kCFAllocatorNull);
|
||||
if (!text) {
|
||||
free(chars);
|
||||
return;
|
||||
}
|
||||
|
||||
NPCocoaEvent cocoaTextEvent;
|
||||
InitNPCocoaEvent(&cocoaTextEvent);
|
||||
cocoaTextEvent.type = NPCocoaEventTextInput;
|
||||
cocoaTextEvent.data.text.text = (NPNSString*)text;
|
||||
|
||||
nsGUIEvent pluginTextEvent(PR_TRUE, NS_NON_RETARGETED_PLUGIN_EVENT, mGeckoChild);
|
||||
pluginTextEvent.time = PR_IntervalNow();
|
||||
pluginTextEvent.pluginEvent = (void*)&cocoaTextEvent;
|
||||
mGeckoChild->DispatchWindowEvent(pluginTextEvent);
|
||||
|
||||
::CFRelease(text);
|
||||
free(chars);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
UInt32 numCharCodes;
|
||||
|
@ -4529,6 +4577,11 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
}
|
||||
#endif // NP_NO_CARBON
|
||||
|
||||
- (void)pluginRequestsComplexTextInputForCurrentEvent
|
||||
{
|
||||
mPluginComplexTextInputRequested = YES;
|
||||
}
|
||||
|
||||
- (void)sendCompositionEvent:(PRInt32) aEventType
|
||||
{
|
||||
#ifdef DEBUG_IME
|
||||
|
@ -4624,7 +4677,6 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
#ifndef NP_NO_CARBON
|
||||
EventRecord carbonEvent;
|
||||
#endif
|
||||
NPCocoaEvent cocoaEvent;
|
||||
if (mCurKeyEvent) {
|
||||
// XXX The ASCII characters inputting mode of egbridge (Japanese IME)
|
||||
// might send the keyDown event with wrong keyboard layout if other
|
||||
|
@ -4636,10 +4688,6 @@ GetUSLayoutCharFromKeyTranslate(UInt32 aKeyCode, UInt32 aModifiers)
|
|||
geckoEvent.pluginEvent = &carbonEvent;
|
||||
}
|
||||
#endif
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
ConvertCocoaKeyEventToNPCocoaEvent(mCurKeyEvent, cocoaEvent);
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
}
|
||||
|
||||
geckoEvent.isShift = ([mCurKeyEvent modifierFlags] & NSShiftKeyMask) != 0;
|
||||
if (!IsPrintableChar(geckoEvent.charCode)) {
|
||||
|
@ -5109,13 +5157,6 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
!mGeckoChild->IME_IsComposing()) {
|
||||
if (mKeyDownHandled)
|
||||
geckoEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
|
||||
NPCocoaEvent cocoaEvent;
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
ConvertCocoaKeyEventToNPCocoaEvent(theEvent, cocoaEvent);
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
}
|
||||
|
||||
mKeyPressHandled = mGeckoChild->DispatchWindowEvent(geckoEvent);
|
||||
mKeyPressSent = YES;
|
||||
if (!mGeckoChild)
|
||||
|
@ -5148,13 +5189,6 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
if (!(interpretKeyEventsCalled && IsNormalCharInputtingEvent(geckoEvent))) {
|
||||
if (mKeyDownHandled)
|
||||
geckoEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
|
||||
NPCocoaEvent cocoaEvent;
|
||||
if (mPluginEventModel == NPEventModelCocoa) {
|
||||
ConvertCocoaKeyEventToNPCocoaEvent(theEvent, cocoaEvent);
|
||||
geckoEvent.pluginEvent = &cocoaEvent;
|
||||
}
|
||||
|
||||
mKeyPressHandled = mGeckoChild->DispatchWindowEvent(geckoEvent);
|
||||
}
|
||||
}
|
||||
|
@ -5174,6 +5208,16 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
#ifdef NP_NO_CARBON
|
||||
- (NSTextInputContext *)inputContext
|
||||
{
|
||||
if (mIsPluginView && mPluginEventModel == NPEventModelCocoa)
|
||||
return [[ComplexTextInputPanel sharedComplexTextInputPanel] inputContext];
|
||||
else
|
||||
return [super inputContext];
|
||||
}
|
||||
#endif
|
||||
|
||||
#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.
|
||||
|
@ -5210,14 +5254,52 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (mGeckoChild && mIsPluginView) {
|
||||
// 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 (mPluginEventModel == NPEventModelCocoa) {
|
||||
// Reset complex text input request.
|
||||
mPluginComplexTextInputRequested = NO;
|
||||
|
||||
// Send key down event.
|
||||
nsGUIEvent pluginEvent(PR_TRUE, NS_NON_RETARGETED_PLUGIN_EVENT, mGeckoChild);
|
||||
NPCocoaEvent cocoaEvent;
|
||||
ConvertCocoaKeyEventToNPCocoaEvent(theEvent, cocoaEvent);
|
||||
pluginEvent.pluginEvent = &cocoaEvent;
|
||||
mGeckoChild->DispatchWindowEvent(pluginEvent);
|
||||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
if (!mPluginComplexTextInputRequested) {
|
||||
// Ideally we'd cancel any TSM composition here.
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef NP_NO_CARBON
|
||||
ComplexTextInputPanel* ctInputPanel = [ComplexTextInputPanel sharedComplexTextInputPanel];
|
||||
NSString* textString = nil;
|
||||
[ctInputPanel interpretKeyEvent:theEvent string:&textString];
|
||||
if (textString) {
|
||||
NPCocoaEvent cocoaTextEvent;
|
||||
InitNPCocoaEvent(&cocoaTextEvent);
|
||||
cocoaTextEvent.type = NPCocoaEventTextInput;
|
||||
cocoaTextEvent.data.text.text = (NPNSString*)textString;
|
||||
|
||||
nsGUIEvent pluginTextEvent(PR_TRUE, NS_NON_RETARGETED_PLUGIN_EVENT, mGeckoChild);
|
||||
pluginTextEvent.time = PR_IntervalNow();
|
||||
pluginTextEvent.pluginEvent = (void*)&cocoaTextEvent;
|
||||
mGeckoChild->DispatchWindowEvent(pluginTextEvent);
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
// 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 &&
|
||||
(mPluginEventModel == NPEventModelCarbon)) {
|
||||
// This will take care of all Carbon plugin events and also send Cocoa plugin
|
||||
// text events when NSInputContext is not available (ifndef NP_NO_CARBON).
|
||||
[self activatePluginTSMDoc];
|
||||
// We use the active TSM document to pass a pointer to ourselves (the
|
||||
// currently focused ChildView) to PluginKeyEventsHandler(). Because this
|
||||
|
@ -5229,8 +5311,8 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
::TSMProcessRawKeyEvent([theEvent _eventRef]);
|
||||
::TSMRemoveDocumentProperty(mPluginTSMDoc, kFocusedChildViewTSMDocPropertyTag);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[self processKeyDownEvent:theEvent keyEquiv:NO];
|
||||
|
||||
|
@ -5409,6 +5491,44 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
|||
(modifierFlags & (NSControlKeyMask | NSAlternateKeyMask)))
|
||||
return handledByEmbedding;
|
||||
|
||||
// At this point we're about to hand the event off to "processKeyDownEvent:keyEquiv:".
|
||||
// Don't bother if this is a Cocoa plugin event, just handle it directly.
|
||||
if (mGeckoChild && mIsPluginView && mPluginEventModel == NPEventModelCocoa) {
|
||||
// Reset complex text input request.
|
||||
mPluginComplexTextInputRequested = NO;
|
||||
|
||||
// Send key down event.
|
||||
nsGUIEvent pluginEvent(PR_TRUE, NS_NON_RETARGETED_PLUGIN_EVENT, mGeckoChild);
|
||||
NPCocoaEvent cocoaEvent;
|
||||
ConvertCocoaKeyEventToNPCocoaEvent(theEvent, cocoaEvent);
|
||||
pluginEvent.pluginEvent = &cocoaEvent;
|
||||
mGeckoChild->DispatchWindowEvent(pluginEvent);
|
||||
if (!mGeckoChild)
|
||||
return YES;
|
||||
|
||||
if (!mPluginComplexTextInputRequested) {
|
||||
// Ideally we'd cancel any TSM composition here.
|
||||
return YES;
|
||||
}
|
||||
|
||||
// We send these events to Carbon TSM but not to the ComplexTextInputPanel.
|
||||
// We assume that events coming in through pKE: are only relevant to TSM.
|
||||
#ifndef NP_NO_CARBON
|
||||
[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);
|
||||
#endif
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
if ([theEvent type] == NSKeyDown) {
|
||||
// We trust the Gecko handled status for cmd key events. See bug 417466 for more info.
|
||||
if (modifierFlags & NSCommandKeyMask)
|
||||
|
|
Загрузка…
Ссылка в новой задаче