Revert "Revert "macOS: Deduplicate QNSWindow/QNSPanel code""
This reverts commit 3ad8295451aa30a212eb6efe6330b5bfccd9f599. The fix for the issue was landed in 5.10 as 1be1ed014b1deacb51fef4, and will be merged into dev as a followup. Change-Id: Id7773d1cc2caecbe358aadd9ade427a9c1eed9ef Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
parent
bec9afba6e
commit
4b6c144804
@ -55,6 +55,9 @@
|
||||
#include <QtGui/qpalette.h>
|
||||
#include <QtGui/qscreen.h>
|
||||
|
||||
#include <objc/runtime.h>
|
||||
#include <objc/message.h>
|
||||
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSView));
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -188,5 +191,131 @@ QT_END_NAMESPACE
|
||||
|
||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSPanelContentsWrapper);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// Depending on the ABI of the platform, we may need to use objc_msgSendSuper_stret:
|
||||
// - http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html
|
||||
// - https://lists.apple.com/archives/cocoa-dev/2008/Feb/msg02338.html
|
||||
template <typename T>
|
||||
struct objc_msgsend_requires_stret
|
||||
{ static const bool value =
|
||||
#if defined(Q_PROCESSOR_X86)
|
||||
// Any return value larger than two registers on i386/x86_64
|
||||
sizeof(T) > sizeof(void*) * 2;
|
||||
#elif defined(Q_PROCESSOR_ARM_32)
|
||||
// Any return value larger than a single register on arm
|
||||
sizeof(T) > sizeof(void*);
|
||||
#elif defined(Q_PROCESSOR_ARM_64)
|
||||
// Stret not used on arm64
|
||||
false;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <>
|
||||
struct objc_msgsend_requires_stret<void>
|
||||
{ static const bool value = false; };
|
||||
|
||||
template <typename ReturnType, typename... Args>
|
||||
ReturnType qt_msgSendSuper(id receiver, SEL selector, Args... args)
|
||||
{
|
||||
static_assert(!objc_msgsend_requires_stret<ReturnType>::value,
|
||||
"The given return type requires stret on this platform");
|
||||
|
||||
typedef ReturnType (*SuperFn)(objc_super *, SEL, Args...);
|
||||
SuperFn superFn = reinterpret_cast<SuperFn>(objc_msgSendSuper);
|
||||
objc_super sup = { receiver, class_getSuperclass(object_getClass(receiver)) };
|
||||
return superFn(&sup, selector, args...);
|
||||
}
|
||||
|
||||
template <typename ReturnType, typename... Args>
|
||||
ReturnType qt_msgSendSuper_stret(id receiver, SEL selector, Args... args)
|
||||
{
|
||||
static_assert(objc_msgsend_requires_stret<ReturnType>::value,
|
||||
"The given return type does not use stret on this platform");
|
||||
|
||||
typedef void (*SuperStretFn)(ReturnType *, objc_super *, SEL, Args...);
|
||||
SuperStretFn superStretFn = reinterpret_cast<SuperStretFn>(objc_msgSendSuper_stret);
|
||||
|
||||
objc_super sup = { receiver, class_getSuperclass(object_getClass(receiver)) };
|
||||
ReturnType ret;
|
||||
superStretFn(&ret, &sup, selector, args...);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
class QSendSuperHelper {
|
||||
public:
|
||||
QSendSuperHelper(id receiver, SEL sel, Args... args)
|
||||
: m_receiver(receiver), m_selector(sel), m_args(std::make_tuple(args...)), m_sent(false)
|
||||
{
|
||||
}
|
||||
|
||||
~QSendSuperHelper()
|
||||
{
|
||||
if (!m_sent)
|
||||
msgSendSuper<void>(m_args);
|
||||
}
|
||||
|
||||
template <typename ReturnType>
|
||||
operator ReturnType()
|
||||
{
|
||||
#if defined(QT_DEBUG)
|
||||
Method method = class_getInstanceMethod(object_getClass(m_receiver), m_selector);
|
||||
char returnTypeEncoding[256];
|
||||
method_getReturnType(method, returnTypeEncoding, sizeof(returnTypeEncoding));
|
||||
NSUInteger alignedReturnTypeSize = 0;
|
||||
NSGetSizeAndAlignment(returnTypeEncoding, nullptr, &alignedReturnTypeSize);
|
||||
Q_ASSERT(alignedReturnTypeSize == sizeof(ReturnType));
|
||||
#endif
|
||||
m_sent = true;
|
||||
return msgSendSuper<ReturnType>(m_args);
|
||||
}
|
||||
|
||||
private:
|
||||
template <std::size_t... Ts>
|
||||
struct index {};
|
||||
|
||||
template <std::size_t N, std::size_t... Ts>
|
||||
struct gen_seq : gen_seq<N - 1, N - 1, Ts...> {};
|
||||
|
||||
template <std::size_t... Ts>
|
||||
struct gen_seq<0, Ts...> : index<Ts...> {};
|
||||
|
||||
template <typename ReturnType, bool V>
|
||||
using if_requires_stret = typename std::enable_if<objc_msgsend_requires_stret<ReturnType>::value == V, ReturnType>::type;
|
||||
|
||||
template <typename ReturnType, std::size_t... Is>
|
||||
if_requires_stret<ReturnType, false> msgSendSuper(std::tuple<Args...>& args, index<Is...>)
|
||||
{
|
||||
return qt_msgSendSuper<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...);
|
||||
}
|
||||
|
||||
template <typename ReturnType, std::size_t... Is>
|
||||
if_requires_stret<ReturnType, true> msgSendSuper(std::tuple<Args...>& args, index<Is...>)
|
||||
{
|
||||
return qt_msgSendSuper_stret<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...);
|
||||
}
|
||||
|
||||
template <typename ReturnType>
|
||||
ReturnType msgSendSuper(std::tuple<Args...>& args)
|
||||
{
|
||||
return msgSendSuper<ReturnType>(args, gen_seq<sizeof...(Args)>{});
|
||||
}
|
||||
|
||||
id m_receiver;
|
||||
SEL m_selector;
|
||||
std::tuple<Args...> m_args;
|
||||
bool m_sent;
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
QSendSuperHelper<Args...> qt_objcDynamicSuperHelper(id receiver, SEL selector, Args... args)
|
||||
{
|
||||
return QSendSuperHelper<Args...>(receiver, selector, args...);
|
||||
}
|
||||
|
||||
// Same as calling super, but the super_class field resolved at runtime instead of compile time
|
||||
#define qt_objcDynamicSuper(...) qt_objcDynamicSuperHelper(self, _cmd, ##__VA_ARGS__)
|
||||
|
||||
#endif //QCOCOAHELPERS_H
|
||||
|
||||
|
@ -218,7 +218,7 @@ QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
|
||||
continue;
|
||||
|
||||
id<QNSWindowProtocol> proto = static_cast<id<QNSWindowProtocol> >(nsWindow);
|
||||
QCocoaWindow *cocoaWindow = proto.helper.platformWindow;
|
||||
QCocoaWindow *cocoaWindow = proto.platformWindow;
|
||||
if (!cocoaWindow)
|
||||
continue;
|
||||
window = cocoaWindow->window();
|
||||
|
@ -210,7 +210,6 @@ QCocoaWindow::~QCocoaWindow()
|
||||
QMacAutoReleasePool pool;
|
||||
[m_nsWindow makeFirstResponder:nil];
|
||||
[m_nsWindow setContentView:nil];
|
||||
[m_nsWindow.helper detachFromPlatformWindow];
|
||||
if ([m_view superview])
|
||||
[m_view removeFromSuperview];
|
||||
|
||||
@ -1279,10 +1278,34 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
|
||||
// Create NSWindow
|
||||
Class windowClass = shouldBePanel ? [QNSPanel class] : [QNSWindow class];
|
||||
QCocoaNSWindow *nsWindow = [[windowClass alloc] initWithContentRect:frame
|
||||
screen:cocoaScreen->nativeScreen() styleMask:windowStyleMask(flags) qPlatformWindow:this];
|
||||
styleMask:windowStyleMask(flags)
|
||||
// Deferring window creation breaks OpenGL (the GL context is
|
||||
// set up before the window is shown and needs a proper window)
|
||||
backing:NSBackingStoreBuffered defer:NO
|
||||
screen:cocoaScreen->nativeScreen()];
|
||||
|
||||
Q_ASSERT_X(nsWindow.screen == cocoaScreen->nativeScreen(), "QCocoaWindow",
|
||||
"Resulting NSScreen should match the requested NSScreen");
|
||||
|
||||
nsWindow.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
|
||||
|
||||
// Prevent Cocoa from releasing the window on close. Qt
|
||||
// handles the close event asynchronously and we want to
|
||||
// make sure that NSWindow stays valid until the
|
||||
// QCocoaWindow is deleted by Qt.
|
||||
[nsWindow setReleasedWhenClosed:NO];
|
||||
|
||||
if (alwaysShowToolWindow()) {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:[QNSWindow class] selector:@selector(applicationActivationChanged:)
|
||||
name:NSApplicationWillResignActiveNotification object:nil];
|
||||
[center addObserver:[QNSWindow class] selector:@selector(applicationActivationChanged:)
|
||||
name:NSApplicationWillBecomeActiveNotification object:nil];
|
||||
});
|
||||
}
|
||||
|
||||
if (targetScreen != window()->screen())
|
||||
QWindowSystemInterface::handleWindowScreenChanged(window(), targetScreen);
|
||||
|
||||
|
@ -47,62 +47,26 @@
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QCocoaWindow)
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSWindowHelper));
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@interface NSWindow (FullScreenProperty)
|
||||
@property(readonly) BOOL qt_fullScreen;
|
||||
@end
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@protocol QNSWindowProtocol
|
||||
|
||||
@property (nonatomic, readonly) QT_MANGLE_NAMESPACE(QNSWindowHelper) *helper;
|
||||
|
||||
- (id)initWithContentRect:(NSRect)contentRect screen:(NSScreen*)screen
|
||||
styleMask:(NSUInteger)windowStyle qPlatformWindow:(QCocoaWindow *)qpw;
|
||||
|
||||
- (void)superSendEvent:(NSEvent *)theEvent;
|
||||
@optional
|
||||
- (BOOL)canBecomeKeyWindow;
|
||||
- (void)sendEvent:(NSEvent*)theEvent;
|
||||
- (void)closeAndRelease;
|
||||
|
||||
- (void)dealloc;
|
||||
@property (nonatomic, readonly) QCocoaWindow *platformWindow;
|
||||
@end
|
||||
|
||||
typedef NSWindow<QNSWindowProtocol> QCocoaNSWindow;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@interface QT_MANGLE_NAMESPACE(QNSWindowHelper) : NSObject
|
||||
{
|
||||
QPointer<QCocoaWindow> _platformWindow;
|
||||
}
|
||||
|
||||
@property (nonatomic, readonly) QCocoaNSWindow *window;
|
||||
@property (nonatomic, readonly) QCocoaWindow *platformWindow;
|
||||
|
||||
- (id)initWithNSWindow:(QCocoaNSWindow *)window platformWindow:(QCocoaWindow *)platformWindow;
|
||||
- (void)handleWindowEvent:(NSEvent *)theEvent;
|
||||
- (void)detachFromPlatformWindow;
|
||||
|
||||
@end
|
||||
|
||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindowHelper);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@interface QT_MANGLE_NAMESPACE(QNSWindow) : NSWindow<QNSWindowProtocol>
|
||||
@end
|
||||
|
||||
@interface QT_MANGLE_NAMESPACE(QNSWindow) : NSWindow<QNSWindowProtocol> @end
|
||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindow);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@interface QT_MANGLE_NAMESPACE(QNSPanel) : NSPanel<QNSWindowProtocol>
|
||||
@end
|
||||
|
||||
@interface QT_MANGLE_NAMESPACE(QNSPanel) : NSPanel<QNSWindowProtocol> @end
|
||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSPanel);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
#endif // QNSWINDOW_H
|
||||
|
@ -88,32 +88,72 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation QNSWindowHelper
|
||||
#define super USE_qt_objcDynamicSuper_INSTEAD
|
||||
|
||||
@implementation QNSWindow
|
||||
|
||||
+ (void)load
|
||||
{
|
||||
const Class windowClass = [self class];
|
||||
const Class panelClass = [QNSPanel class];
|
||||
|
||||
unsigned int methodDescriptionsCount;
|
||||
objc_method_description *methods = protocol_copyMethodDescriptionList(
|
||||
objc_getProtocol("QNSWindowProtocol"), NO, YES, &methodDescriptionsCount);
|
||||
|
||||
for (unsigned int i = 0; i < methodDescriptionsCount; ++i) {
|
||||
objc_method_description method = methods[i];
|
||||
class_addMethod(panelClass, method.name,
|
||||
class_getMethodImplementation(windowClass, method.name),
|
||||
method.types);
|
||||
}
|
||||
|
||||
free(methods);
|
||||
}
|
||||
|
||||
- (QCocoaWindow *)platformWindow
|
||||
{
|
||||
return _platformWindow.data();
|
||||
return qnsview_cast(self.contentView).platformWindow;
|
||||
}
|
||||
|
||||
- (id)initWithNSWindow:(QCocoaNSWindow *)window platformWindow:(QCocoaWindow *)platformWindow
|
||||
- (BOOL)canBecomeKeyWindow
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_window = window;
|
||||
_platformWindow = platformWindow;
|
||||
QCocoaWindow *pw = self.platformWindow;
|
||||
if (!pw)
|
||||
return NO;
|
||||
|
||||
_window.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:_platformWindow];
|
||||
if (pw->shouldRefuseKeyWindowAndFirstResponder())
|
||||
return NO;
|
||||
|
||||
// Prevent Cocoa from releasing the window on close. Qt
|
||||
// handles the close event asynchronously and we want to
|
||||
// make sure that NSWindow stays valid until the
|
||||
// QCocoaWindow is deleted by Qt.
|
||||
[_window setReleasedWhenClosed:NO];
|
||||
if ([self isKindOfClass:[QNSPanel class]]) {
|
||||
// Only tool or dialog windows should become key:
|
||||
Qt::WindowType type = pw->window()->type();
|
||||
if (type == Qt::Tool || type == Qt::Dialog)
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
} else {
|
||||
// The default implementation returns NO for title-bar less windows,
|
||||
// override and return yes here to make sure popup windows such as
|
||||
// the combobox popup can become the key window.
|
||||
return YES;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)handleWindowEvent:(NSEvent *)theEvent
|
||||
- (BOOL)canBecomeMainWindow
|
||||
{
|
||||
BOOL canBecomeMain = YES; // By default, windows can become the main window
|
||||
|
||||
// Windows with a transient parent (such as combobox popup windows)
|
||||
// cannot become the main window:
|
||||
QCocoaWindow *pw = self.platformWindow;
|
||||
if (!pw || pw->window()->transientParent())
|
||||
canBecomeMain = NO;
|
||||
|
||||
return canBecomeMain;
|
||||
}
|
||||
|
||||
- (void)sendEvent:(NSEvent*)theEvent
|
||||
{
|
||||
// We might get events for a NSWindow after the corresponding platform
|
||||
// window has been deleted, as the NSWindow can outlive the QCocoaWindow
|
||||
@ -129,7 +169,7 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
return;
|
||||
}
|
||||
|
||||
[self.window superSendEvent:theEvent];
|
||||
qt_objcDynamicSuper(theEvent);
|
||||
|
||||
if (!self.platformWindow)
|
||||
return; // Platform window went away while processing event
|
||||
@ -137,108 +177,31 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
QCocoaWindow *pw = self.platformWindow;
|
||||
if (pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
|
||||
NSPoint loc = [theEvent locationInWindow];
|
||||
NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]];
|
||||
NSRect contentFrame = [[self.window contentView] frame];
|
||||
NSRect windowFrame = [self convertRectFromScreen:self.frame];
|
||||
NSRect contentFrame = self.contentView.frame;
|
||||
if (NSMouseInRect(loc, windowFrame, NO) && !NSMouseInRect(loc, contentFrame, NO))
|
||||
[qnsview_cast(pw->view()) handleFrameStrutMouseEvent:theEvent];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)detachFromPlatformWindow
|
||||
{
|
||||
_platformWindow.clear();
|
||||
[self.window.delegate release];
|
||||
self.window.delegate = nil;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_window = nil;
|
||||
_platformWindow.clear();
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// Deferring window creation breaks OpenGL (the GL context is
|
||||
// set up before the window is shown and needs a proper window)
|
||||
static const bool kNoDefer = NO;
|
||||
|
||||
@implementation QNSWindow
|
||||
|
||||
@synthesize helper = _helper;
|
||||
|
||||
- (id)initWithContentRect:(NSRect)contentRect
|
||||
screen:(NSScreen*)screen
|
||||
styleMask:(NSUInteger)windowStyle
|
||||
qPlatformWindow:(QCocoaWindow *)qpw
|
||||
{
|
||||
if (self = [super initWithContentRect:contentRect styleMask:windowStyle
|
||||
backing:NSBackingStoreBuffered defer:kNoDefer screen:screen]) {
|
||||
_helper = [[QNSWindowHelper alloc] initWithNSWindow:self platformWindow:qpw];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeKeyWindow
|
||||
{
|
||||
QCocoaWindow *pw = self.helper.platformWindow;
|
||||
if (!pw)
|
||||
return NO;
|
||||
|
||||
if (pw->shouldRefuseKeyWindowAndFirstResponder())
|
||||
return NO;
|
||||
|
||||
// The default implementation returns NO for title-bar less windows,
|
||||
// override and return yes here to make sure popup windows such as
|
||||
// the combobox popup can become the key window.
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeMainWindow
|
||||
{
|
||||
BOOL canBecomeMain = YES; // By default, windows can become the main window
|
||||
|
||||
// Windows with a transient parent (such as combobox popup windows)
|
||||
// cannot become the main window:
|
||||
QCocoaWindow *pw = self.helper.platformWindow;
|
||||
if (!pw || pw->window()->transientParent())
|
||||
canBecomeMain = NO;
|
||||
|
||||
return canBecomeMain;
|
||||
}
|
||||
|
||||
- (void)sendEvent:(NSEvent*)theEvent
|
||||
{
|
||||
[self.helper handleWindowEvent:theEvent];
|
||||
}
|
||||
|
||||
- (void)superSendEvent:(NSEvent *)theEvent
|
||||
{
|
||||
[super sendEvent:theEvent];
|
||||
}
|
||||
|
||||
- (void)closeAndRelease
|
||||
{
|
||||
qCDebug(lcQpaCocoaWindow) << "closeAndRelease" << self;
|
||||
|
||||
[self.helper detachFromPlatformWindow];
|
||||
[self.delegate release];
|
||||
self.delegate = nil;
|
||||
|
||||
[self close];
|
||||
[self release];
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wobjc-missing-super-calls"
|
||||
- (void)dealloc
|
||||
{
|
||||
[_helper release];
|
||||
_helper = nil;
|
||||
[super dealloc];
|
||||
qt_objcDynamicSuper();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation QNSPanel
|
||||
|
||||
@synthesize helper = _helper;
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
+ (void)applicationActivationChanged:(NSNotification*)notification
|
||||
{
|
||||
@ -284,7 +247,7 @@ static const bool kNoDefer = NO;
|
||||
continue;
|
||||
|
||||
if ([window conformsToProtocol:@protocol(QNSWindowProtocol)]) {
|
||||
QCocoaWindow *cocoaWindow = static_cast<id<QNSWindowProtocol>>(window).helper.platformWindow;
|
||||
QCocoaWindow *cocoaWindow = static_cast<QCocoaNSWindow *>(window).platformWindow;
|
||||
window.level = notification.name == NSApplicationWillResignActiveNotification ?
|
||||
NSNormalWindowLevel : cocoaWindow->windowLevel(cocoaWindow->window()->flags());
|
||||
}
|
||||
@ -305,70 +268,10 @@ static const bool kNoDefer = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (id)initWithContentRect:(NSRect)contentRect
|
||||
screen:(NSScreen*)screen
|
||||
styleMask:(NSUInteger)windowStyle
|
||||
qPlatformWindow:(QCocoaWindow *)qpw
|
||||
{
|
||||
if (self = [super initWithContentRect:contentRect styleMask:windowStyle
|
||||
backing:NSBackingStoreBuffered defer:kNoDefer screen:screen]) {
|
||||
_helper = [[QNSWindowHelper alloc] initWithNSWindow:self platformWindow:qpw];
|
||||
|
||||
if (qpw->alwaysShowToolWindow()) {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:[self class] selector:@selector(applicationActivationChanged:)
|
||||
name:NSApplicationWillResignActiveNotification object:nil];
|
||||
[center addObserver:[self class] selector:@selector(applicationActivationChanged:)
|
||||
name:NSApplicationWillBecomeActiveNotification object:nil];
|
||||
});
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeKeyWindow
|
||||
{
|
||||
QCocoaWindow *pw = self.helper.platformWindow;
|
||||
if (!pw)
|
||||
return NO;
|
||||
|
||||
if (pw->shouldRefuseKeyWindowAndFirstResponder())
|
||||
return NO;
|
||||
|
||||
// Only tool or dialog windows should become key:
|
||||
Qt::WindowType type = pw->window()->type();
|
||||
if (type == Qt::Tool || type == Qt::Dialog)
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)sendEvent:(NSEvent*)theEvent
|
||||
{
|
||||
[self.helper handleWindowEvent:theEvent];
|
||||
}
|
||||
|
||||
- (void)superSendEvent:(NSEvent *)theEvent
|
||||
{
|
||||
[super sendEvent:theEvent];
|
||||
}
|
||||
|
||||
- (void)closeAndRelease
|
||||
{
|
||||
qCDebug(lcQpaCocoaWindow) << "closeAndRelease" << self;
|
||||
|
||||
[self.helper detachFromPlatformWindow];
|
||||
[self close];
|
||||
[self release];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_helper release];
|
||||
_helper = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation QNSPanel
|
||||
// Implementation shared with QNSWindow, see +[QNSWindow load] above
|
||||
@end
|
||||
|
||||
#undef super
|
||||
|
Loading…
x
Reference in New Issue
Block a user