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
221 if (self.superview == self.previousSuperview) {
222 qCDebug(lcQpaWindow) <<
"Done re-ordering" << self <<
"new index:"
223 << [self.superview.subviews indexOfObject:self];
231- (
void)viewWillMoveToWindow:(NSWindow *)newWindow
233 Q_ASSERT(!self.previousWindow);
234 self.previousWindow = self.window;
238 if (newWindow != self.window)
239 qCDebug(lcQpaWindow) <<
"Moving" << self <<
"from" << self.window <<
"to" << newWindow;
242- (
void)viewDidMoveToWindow
245 auto previousSuperview = self.previousSuperview;
246 self.previousSuperview = nil;
247 auto previousWindow = self.previousWindow;
248 self.previousWindow = nil;
250 if (!m_platformWindow)
257 if (self.superview != previousSuperview)
258 m_platformWindow->viewDidMoveToSuperview(previousSuperview);
260 if (self.window != previousWindow)
261 m_platformWindow->viewDidMoveToWindow(previousWindow);
271- (
void)didAddSubview:(NSView *)subview
273 self.clipsToBounds = YES;
276- (
void)willRemoveSubview:(NSView *)subview
278 self.clipsToBounds = self.subviews.count > 1;
285 if (!m_platformWindow)
288 QWindow *focusWindow = m_platformWindow->window();
292 if (qstrcmp(focusWindow->metaObject()->className(),
"QWidgetWindow") == 0) {
293 while (focusWindow->parent()) {
294 focusWindow = focusWindow->parent();
302
303
304
307 qCDebug(lcQpaWindow) <<
"Did hide" << self;
309 if (!m_platformWindow->isExposed())
312 m_platformWindow->handleExposeEvent(QRegion());
316
317
318
321 qCDebug(lcQpaWindow) <<
"Did unhide" << self;
323 [self setNeedsDisplay:YES];
326- (BOOL)isTransparentForUserInput
328 return m_platformWindow->window() &&
329 m_platformWindow->window()->flags() & Qt::WindowTransparentForInput;
332- (BOOL)becomeFirstResponder
334 if (!m_platformWindow)
336 if ([self isTransparentForUserInput])
339 if (!m_platformWindow->windowIsPopupType()
340 && (!self.window.canBecomeKeyWindow || self.window.keyWindow)) {
356 QWindowSystemInterface::handleFocusWindowChanged<QWindowSystemInterface::SynchronousDelivery>(
357 [self topLevelWindow], Qt::ActiveWindowFocusReason);
363- (BOOL)acceptsFirstResponder
365 if (!m_platformWindow)
367 if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder())
369 if ([self isTransparentForUserInput])
371 if ((m_platformWindow->window()->flags() & Qt::ToolTip) == Qt::ToolTip)
376- (
NSView *)hitTest:(NSPoint)aPoint
378 NSView *candidate = [super hitTest:aPoint];
379 if (candidate == self) {
380 if ([self isTransparentForUserInput])
386- (
void)convertFromScreen:(NSPoint)mouseLocation toWindowPoint:(QPointF *)qtWindowPoint andScreenPoint:(QPointF *)qtScreenPoint
406 NSWindow *window = [self window];
407 NSPoint nsWindowPoint;
408 NSRect windowRect = [window convertRectFromScreen:NSMakeRect(mouseLocation.x, mouseLocation.y, 1, 1)];
409 nsWindowPoint = windowRect.origin;
410 NSPoint nsViewPoint = [self convertPoint: nsWindowPoint fromView: nil];
411 *qtWindowPoint = QPointF(nsViewPoint.x, nsViewPoint.y);
412 *qtScreenPoint = QCocoaScreen::mapFromNative(mouseLocation);
426#if QT_CONFIG(accessibility)
427#include "qnsview_accessibility.mm"
432@implementation QNSView (QtExtras)
434- (QCocoaWindow*)platformWindow
436 return m_platformWindow.data();;
Q_FORWARD_DECLARE_OBJC_CLASS(NSView)
Q_FORWARD_DECLARE_OBJC_CLASS(NSString)