5#include <QtGui/qtguiglobal.h>
7#include <AppKit/AppKit.h>
8#include <MetalKit/MetalKit.h>
9#include <UniformTypeIdentifiers/UTCoreTypes.h>
18#include <qpa/qplatformintegration.h>
20#include <qpa/qwindowsysteminterface.h>
21#include <QtGui/QTextFormat>
22#include <QtCore/QDebug>
23#include <QtCore/QPointer>
25#include <QtCore/private/qcore_mac_p.h>
26#include <QtGui/QAccessible>
27#include <QtGui/QImage>
28#include <private/qguiapplication_p.h>
29#include <private/qcoregraphics_p.h>
30#include <private/qwindow_p.h>
31#include <private/qpointingdevice_p.h>
32#include <private/qhighdpiscaling_p.h>
38#include <QtGui/private/qmacmimeregistry_p.h>
39#include <QtGui/private/qmetallayer_p.h>
41#include <QuartzCore/CATransaction.h>
43@interface QNSView (Drawing) <CALayerDelegate>
47@interface QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) : NSObject
48- (instancetype)initWithView:(QNSView *)theView;
49- (
void)mouseMoved:(NSEvent *)theEvent;
50- (
void)mouseEntered:(NSEvent *)theEvent;
51- (
void)mouseExited:(NSEvent *)theEvent;
52- (
void)cursorUpdate:(NSEvent *)theEvent;
55QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMouseMoveHelper);
57@interface QNSView (Mouse)
59- (NSPoint)screenMousePoint:(NSEvent *)theEvent;
60- (
void)mouseMovedImpl:(NSEvent *)theEvent;
61- (
void)mouseEnteredImpl:(NSEvent *)theEvent;
62- (
void)mouseExitedImpl:(NSEvent *)theEvent;
65@interface QNSView (Touch)
68@interface QNSView (Tablet)
69- (
bool)handleTabletEvent:(NSEvent *)theEvent;
72@interface QNSView (Gestures)
75@interface QNSView (Dragging)
76-(
void)registerDragTypes;
79@interface QNSView (Keys)
82@interface QNSView (ComplexText) <NSTextInputClient>
83@property (readonly) QObject* focusObject;
86@interface QNSView (ServicesMenu) <NSServicesMenuRequestor>
89#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000
)
90@interface QNSView (ContentSelectionInfo) <NSViewContentSelectionInfo>
94@interface QT_MANGLE_NAMESPACE(QNSViewMenuHelper) : NSObject
95- (instancetype)initWithView:(QNSView *)theView;
97QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMenuHelper);
101- (BOOL)isTransparentForUserInput;
102@property (assign) NSView* previousSuperview;
103@property (assign) NSWindow* previousWindow;
104@property (retain) QNSViewMenuHelper* menuHelper;
105@property (nonatomic, retain) NSColorSpace *colorSpace;
108@implementation QNSView {
109 QPointer<QCocoaWindow> m_platformWindow;
112 QNSViewMouseMoveHelper *m_mouseMoveHelper;
113 Qt::MouseButtons m_buttons;
114 Qt::MouseButtons m_acceptedMouseDowns;
115 Qt::MouseButtons m_frameStrutButtons;
116 Qt::KeyboardModifiers m_currentWheelModifiers;
117 bool m_dontOverrideCtrlLMB;
118 bool m_sendUpAsRightButton;
125 bool m_sendKeyEventWithoutText;
126 NSEvent *m_currentlyInterpretedKeyEvent;
127 QSet<quint32> m_acceptedKeyDowns;
130 QString m_composingText;
131 QPointer<QObject> m_composingFocusObject;
134@synthesize colorSpace = m_colorSpace;
136- (instancetype)initWithCocoaWindow:(QCocoaWindow *)platformWindow
138 if ((self = [super initWithFrame:NSZeroRect])) {
139 m_platformWindow = platformWindow;
148 self.focusRingType = NSFocusRingTypeNone;
150 self.previousSuperview = nil;
151 self.previousWindow = nil;
155 [self registerDragTypes];
157 m_updatingDrag =
false;
159 m_lastKeyDead =
false;
160 m_sendKeyEvent =
false;
161 m_currentlyInterpretedKeyEvent = nil;
163 self.menuHelper = [[[QNSViewMenuHelper alloc] initWithView:self] autorelease];
170 qCDebug(lcQpaWindow) <<
"Deallocating" << self;
172 self.menuHelper = nil;
174 [[NSNotificationCenter defaultCenter] removeObserver:self];
175 [m_mouseMoveHelper release];
182 NSMutableString *description = [NSMutableString stringWithString:[super description]];
184#ifndef QT_NO_DEBUG_STREAM
185 QString platformWindowDescription;
186 QDebug debug(&platformWindowDescription);
187 debug.nospace() <<
"; " << m_platformWindow <<
">";
189 NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1];
190 [description replaceCharactersInRange:lastCharacter withString:platformWindowDescription.toNSString()];
198- (
void)removeFromSuperview
200 qCDebug(lcQpaWindow) <<
"Removing" << self <<
"from" << self.superview;
201 QMacAutoReleasePool pool;
202 [super removeFromSuperview];
205- (
void)viewWillMoveToSuperview:(NSView *)newSuperview
207 Q_ASSERT(!self.previousSuperview);
208 self.previousSuperview = self.superview;
210 if (newSuperview == self.superview)
211 qCDebug(lcQpaWindow) <<
"Re-ordering" << self <<
"inside" << self.superview;
213 qCDebug(lcQpaWindow) <<
"Re-parenting" << self <<
"from" << self.superview <<
"to" << newSuperview;
216- (
void)viewDidMoveToSuperview
218 auto cleanup = qScopeGuard([&] { self.previousSuperview = nil; });
220 if (self.superview == self.previousSuperview) {
221 qCDebug(lcQpaWindow) <<
"Done re-ordering" << self <<
"new index:"
222 << [self.superview.subviews indexOfObject:self];
226 qCDebug(lcQpaWindow) <<
"Done re-parenting" << self <<
"into" << self.superview;
231 if (!m_platformWindow)
234 if (!m_platformWindow->isEmbedded())
237 if ([self superview]) {
238 QWindowSystemInterface::handleGeometryChange(m_platformWindow->window(), m_platformWindow->geometry());
239 [self setNeedsDisplay:YES];
240 QWindowSystemInterface::flushWindowSystemEvents();
244- (
void)viewWillMoveToWindow:(NSWindow *)newWindow
246 Q_ASSERT(!self.previousWindow);
247 self.previousWindow = self.window;
251 if (newWindow == self.window)
254 qCDebug(lcQpaWindow) <<
"Moving" << self <<
"from" << self.window <<
"to" << newWindow;
260- (
void)viewDidMoveToWindow
262 auto cleanup = qScopeGuard([&] { self.previousWindow = nil; });
266 if (self.window == self.previousWindow)
269 qCDebug(lcQpaWindow) <<
"Done moving" << self <<
"to" << self.window;
276 if (!m_platformWindow)
279 QWindow *focusWindow = m_platformWindow->window();
283 if (qstrcmp(focusWindow->metaObject()->className(),
"QWidgetWindow") == 0) {
284 while (focusWindow->parent()) {
285 focusWindow = focusWindow->parent();
293
294
295
298 qCDebug(lcQpaWindow) <<
"Did hide" << self;
300 if (!m_platformWindow->isExposed())
303 m_platformWindow->handleExposeEvent(QRegion());
307
308
309
312 qCDebug(lcQpaWindow) <<
"Did unhide" << self;
314 [self setNeedsDisplay:YES];
317- (BOOL)isTransparentForUserInput
319 return m_platformWindow->window() &&
320 m_platformWindow->window()->flags() & Qt::WindowTransparentForInput;
323- (BOOL)becomeFirstResponder
325 if (!m_platformWindow)
327 if ([self isTransparentForUserInput])
330 if (!m_platformWindow->windowIsPopupType()
331 && (!self.window.canBecomeKeyWindow || self.window.keyWindow)) {
347 QWindowSystemInterface::handleFocusWindowChanged<QWindowSystemInterface::SynchronousDelivery>(
348 [self topLevelWindow], Qt::ActiveWindowFocusReason);
354- (BOOL)acceptsFirstResponder
356 if (!m_platformWindow)
358 if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder())
360 if ([self isTransparentForUserInput])
362 if ((m_platformWindow->window()->flags() & Qt::ToolTip) == Qt::ToolTip)
367- (
NSView *)hitTest:(NSPoint)aPoint
369 NSView *candidate = [super hitTest:aPoint];
370 if (candidate == self) {
371 if ([self isTransparentForUserInput])
377- (
void)convertFromScreen:(NSPoint)mouseLocation toWindowPoint:(QPointF *)qtWindowPoint andScreenPoint:(QPointF *)qtScreenPoint
397 NSWindow *window = [self window];
398 NSPoint nsWindowPoint;
399 NSRect windowRect = [window convertRectFromScreen:NSMakeRect(mouseLocation.x, mouseLocation.y, 1, 1)];
400 nsWindowPoint = windowRect.origin;
401 NSPoint nsViewPoint = [self convertPoint: nsWindowPoint fromView: nil];
402 *qtWindowPoint = QPointF(nsViewPoint.x, nsViewPoint.y);
403 *qtScreenPoint = QCocoaScreen::mapFromNative(mouseLocation);
417#if QT_CONFIG(accessibility)
418#include "qnsview_accessibility.mm"
423@implementation QNSView (QtExtras)
425- (QCocoaWindow*)platformWindow
427 return m_platformWindow.data();;
Q_FORWARD_DECLARE_OBJC_CLASS(NSView)
Q_FORWARD_DECLARE_OBJC_CLASS(NSString)