зеркало из https://github.com/mozilla/pjs.git
Mouse-down doesn't always change focus appropriately. b=413882 r=joshmoz sr=roc
This commit is contained in:
Родитель
7bcf1c47a2
Коммит
70b9f0657b
|
@ -96,6 +96,8 @@ extern "C" {
|
||||||
CG_EXTERN void CGContextResetClip(CGContextRef);
|
CG_EXTERN void CGContextResetClip(CGContextRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern PRBool gCocoaWindowMethodsSwizzled; // Defined in nsCocoaWindow.mm
|
||||||
|
|
||||||
extern nsISupportsArray *gDraggedTransferables;
|
extern nsISupportsArray *gDraggedTransferables;
|
||||||
|
|
||||||
PRBool nsTSMManager::sIsIMEEnabled = PR_TRUE;
|
PRBool nsTSMManager::sIsIMEEnabled = PR_TRUE;
|
||||||
|
@ -391,6 +393,13 @@ nsresult nsChildView::StandardCreate(nsIWidget *aParent,
|
||||||
nsWidgetInitData *aInitData,
|
nsWidgetInitData *aInitData,
|
||||||
nsNativeWidget aNativeParent)
|
nsNativeWidget aNativeParent)
|
||||||
{
|
{
|
||||||
|
// See NSWindow (MethodSwizzling) in nsCocoaWindow.mm.
|
||||||
|
if (!gCocoaWindowMethodsSwizzled) {
|
||||||
|
nsToolkit::SwizzleMethods([NSWindow class], @selector(sendEvent:),
|
||||||
|
@selector(nsCocoaWindow_NSWindow_sendEvent:));
|
||||||
|
gCocoaWindowMethodsSwizzled = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
mBounds = aRect;
|
mBounds = aRect;
|
||||||
|
|
||||||
BaseCreate(aParent, aRect, aHandleEventFunction,
|
BaseCreate(aParent, aRect, aHandleEventFunction,
|
||||||
|
|
|
@ -54,9 +54,12 @@
|
||||||
#include "nsIPrefBranch.h"
|
#include "nsIPrefBranch.h"
|
||||||
#include "nsToolkit.h"
|
#include "nsToolkit.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
PRInt32 gXULModalLevel = 0;
|
PRInt32 gXULModalLevel = 0;
|
||||||
|
|
||||||
|
PRBool gCocoaWindowMethodsSwizzled = PR_FALSE;
|
||||||
|
|
||||||
// defined in nsMenuBarX.mm
|
// defined in nsMenuBarX.mm
|
||||||
extern NSMenu* sApplicationMenu; // Application menu shared by all menubars
|
extern NSMenu* sApplicationMenu; // Application menu shared by all menubars
|
||||||
|
|
||||||
|
@ -1750,6 +1753,42 @@ void patternDraw(void* aInfo, CGContextRef aContext)
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@interface NSWindow (MethodSwizzling)
|
||||||
|
- (void)nsCocoaWindow_NSWindow_sendEvent:(NSEvent *)anEvent;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSWindow (MethodSwizzling)
|
||||||
|
|
||||||
|
// A mouseDown event can change the focus, and (if this happens) we may need
|
||||||
|
// to send NS_LOSTFOCUS and NS_GOTFOCUS events to Gecko. Otherwise other
|
||||||
|
// Gecko events may be sent to the wrong nsChildView, or the "right"
|
||||||
|
// nsChildView may not be focused. This resolves bmo bug 413882.
|
||||||
|
// For non-embedders (e.g. Firefox and Seamonkey), it would probably only be
|
||||||
|
// necessary to add a sendEvent: method to the ToolbarWindow class. But
|
||||||
|
// embedders (like Camino) generally create their own NSWindows. So in order
|
||||||
|
// to fix this problem everywhere, it's necessary to "hook" NSWindow's own
|
||||||
|
// sendEvent: method.
|
||||||
|
- (void)nsCocoaWindow_NSWindow_sendEvent:(NSEvent *)anEvent
|
||||||
|
{
|
||||||
|
NSResponder *oldFirstResponder = nil;
|
||||||
|
NSEventType type = [anEvent type];
|
||||||
|
if (type == NSLeftMouseDown)
|
||||||
|
oldFirstResponder = [[self firstResponder] retain];
|
||||||
|
[self nsCocoaWindow_NSWindow_sendEvent:anEvent];
|
||||||
|
if (type == NSLeftMouseDown) {
|
||||||
|
NSResponder *newFirstResponder = [self firstResponder];
|
||||||
|
if (oldFirstResponder != newFirstResponder) {
|
||||||
|
if ([oldFirstResponder isKindOfClass:[ChildView class]])
|
||||||
|
[(ChildView *)oldFirstResponder sendFocusEvent:NS_LOSTFOCUS];
|
||||||
|
if ([newFirstResponder isKindOfClass:[ChildView class]])
|
||||||
|
[(ChildView *)newFirstResponder sendFocusEvent:NS_GOTFOCUS];
|
||||||
|
}
|
||||||
|
[oldFirstResponder release];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation PopupWindow
|
@implementation PopupWindow
|
||||||
|
|
||||||
// The OS treats our custom popup windows very strangely -- many mouse events
|
// The OS treats our custom popup windows very strangely -- many mouse events
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#include "nsIToolkit.h"
|
#include "nsIToolkit.h"
|
||||||
|
|
||||||
#import <Carbon/Carbon.h>
|
#import <Carbon/Carbon.h>
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <objc/Object.h>
|
||||||
#import <IOKit/IOKitLib.h>
|
#import <IOKit/IOKitLib.h>
|
||||||
|
|
||||||
#define MAC_OS_X_VERSION_10_4_HEX 0x00001040
|
#define MAC_OS_X_VERSION_10_4_HEX 0x00001040
|
||||||
|
@ -64,6 +66,8 @@ public:
|
||||||
|
|
||||||
static void PostSleepWakeNotification(const char* aNotification);
|
static void PostSleepWakeNotification(const char* aNotification);
|
||||||
|
|
||||||
|
static nsresult SwizzleMethods(Class aClass, SEL orgMethod, SEL posedMethod);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
nsresult RegisterForSleepWakeNotifcations();
|
nsresult RegisterForSleepWakeNotifcations();
|
||||||
|
|
|
@ -382,3 +382,37 @@ PRBool nsToolkit::OnLeopardOrLater()
|
||||||
{
|
{
|
||||||
return (OSXVersion() >= MAC_OS_X_VERSION_10_5_HEX) ? PR_TRUE : PR_FALSE;
|
return (OSXVersion() >= MAC_OS_X_VERSION_10_5_HEX) ? PR_TRUE : PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// An alternative to [NSObject poseAsClass:] that isn't deprecated on OS X
|
||||||
|
// Leopard and is available to 64-bit binaries on Leopard and above. Based on
|
||||||
|
// ideas and code from http://www.cocoadev.com/index.pl?MethodSwizzling.
|
||||||
|
// Since the Method type becomes an opaque type as of Objective-C 2.0, we'll
|
||||||
|
// have to switch to using accessor methods like method_exchangeImplementations()
|
||||||
|
// when we build 64-bit binaries that use Objective-C 2.0 (on and for Leopard
|
||||||
|
// and above). But these accessor methods aren't available in Objective-C 1
|
||||||
|
// (or on Tiger). So we need to access Method's members directly for (Tiger-
|
||||||
|
// capable) binaries (32-bit or 64-bit) that use Objective-C 1 (as long as we
|
||||||
|
// keep supporting Tiger).
|
||||||
|
//
|
||||||
|
// Be aware that, if aClass doesn't have an orgMethod selector but one of its
|
||||||
|
// superclasses does, the method substitution will (in effect) take place in
|
||||||
|
// that superclass (rather than in aClass itself). The substitution has
|
||||||
|
// effect on the class where it takes place and all of that class's
|
||||||
|
// subclasses. In order for method swizzling to work properly, posedMethod
|
||||||
|
// needs to be unique in the class where the substitution takes place and all
|
||||||
|
// of its subclasses.
|
||||||
|
nsresult nsToolkit::SwizzleMethods(Class aClass, SEL orgMethod, SEL posedMethod)
|
||||||
|
{
|
||||||
|
Method original = class_getInstanceMethod(aClass, orgMethod);
|
||||||
|
Method posed = class_getInstanceMethod(aClass, posedMethod);
|
||||||
|
|
||||||
|
if (!original || !posed)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
IMP aMethodImp = original->method_imp;
|
||||||
|
original->method_imp = posed->method_imp;
|
||||||
|
posed->method_imp = aMethodImp;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче