14 static const int kDefaultPrimaryPointingDeviceId = 1;
16 deviceID = kDefaultPrimaryPointingDeviceId;
22 if (primaryDevice->systemId() == kDefaultPrimaryPointingDeviceId) {
25 qCDebug(lcInputDevices) <<
"primaryPointingDevice is now" << primaryDevice;
58- (instancetype)initWithView:(
QNSView *)theView
60 if ((self = [super
init]))
66- (
void)mouseMoved:(NSEvent *)theEvent
68 [view mouseMovedImpl:theEvent];
71- (
void)mouseEntered:(NSEvent *)theEvent
73 [view mouseEnteredImpl:theEvent];
76- (
void)mouseExited:(NSEvent *)theEvent
78 [view mouseExitedImpl:theEvent];
81- (
void)cursorUpdate:(NSEvent *)theEvent
83 [view cursorUpdate:theEvent];
88@implementation QNSView (MouseAPI)
90- (
void)resetMouseButtons
92 qCDebug(lcQpaMouse) <<
"Resetting mouse buttons";
97- (
void)handleMouseEvent:(NSEvent *)theEvent
99 if (!m_platformWindow)
102#ifndef QT_NO_TABLETEVENT
105 if ([self handleTabletEvent: theEvent])
112 if (!targetView.platformWindow)
116 [targetView convertFromScreen:[
self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
117 ulong timestamp = [theEvent timestamp] * 1000;
122 const auto modifiers = QAppleKeyMapper::fromCocoaModifiers(theEvent.modifierFlags);
132 qCDebug(lcQpaMouse) << eventType <<
"at" << qtWindowPoint <<
"with" <<
m_buttons;
137 timestamp, qtWindowPoint, qtScreenPoint,
141- (
void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
143 if (!m_platformWindow)
146 switch (theEvent.type) {
147 case NSEventTypeLeftMouseDown:
150 case NSEventTypeLeftMouseUp:
153 case NSEventTypeRightMouseDown:
156 case NSEventTypeRightMouseUp:
159 case NSEventTypeOtherMouseDown:
162 case NSEventTypeOtherMouseUp:
184 NSWindow *
window = [
self window];
185 NSPoint windowPoint = [theEvent locationInWindow];
188 NSPoint windowCoord = [
self convertPoint:[
self frame].origin toView:nil];
189 int viewScreenY = [window convertRectToScreen:NSMakeRect(windowCoord.x, windowCoord.y, 0, 0)].origin.
y;
190 int titleBarHeight = windowScreenY - viewScreenY;
192 NSPoint nsViewPoint = [
self convertPoint: windowPoint fromView: nil];
193 QPoint qtWindowPoint =
QPoint(nsViewPoint.x, titleBarHeight + nsViewPoint.y);
194 NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 0, 0)].origin;
197 ulong timestamp = [theEvent timestamp] * 1000;
200 auto eventType = [&]() {
201 switch (theEvent.type) {
202 case NSEventTypeLeftMouseDown:
203 case NSEventTypeRightMouseDown:
204 case NSEventTypeOtherMouseDown:
207 case NSEventTypeLeftMouseUp:
208 case NSEventTypeRightMouseUp:
209 case NSEventTypeOtherMouseUp:
212 case NSEventTypeMouseMoved:
213 case NSEventTypeLeftMouseDragged:
214 case NSEventTypeRightMouseDragged:
215 case NSEventTypeOtherMouseDragged:
229@implementation QNSView (Mouse)
242 "_q_platform_MacDontOverrideCtrlLMB",
"QT_MAC_DONT_OVERRIDE_CTRL_LMB");
246 NSUInteger trackingOptions = NSTrackingCursorUpdate | NSTrackingMouseEnteredAndExited;
252 trackingOptions |= NSTrackingActiveAlways;
259 trackingOptions |= NSTrackingMouseMoved;
263 trackingOptions |= NSTrackingInVisibleRect;
264 static const NSRect trackingRect = NSZeroRect;
267 [
self addTrackingArea:[[[NSTrackingArea alloc] initWithRect:trackingRect
268 options:trackingOptions owner:m_mouseMoveHelper userInfo:nil] autorelease]];
271- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
274 if (!m_platformWindow)
276 if ([self isTransparentForUserInput])
280 [
self convertFromScreen:[NSEvent mouseLocation] toWindowPoint: &windowPoint andScreenPoint: &screenPoint];
284- (NSPoint)screenMousePoint:(NSEvent *)theEvent
288 NSPoint windowPoint = [theEvent locationInWindow];
290 screenPoint = [NSEvent mouseLocation];
292 NSRect screenRect = [[theEvent window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
293 screenPoint = screenRect.origin;
296 screenPoint = [NSEvent mouseLocation];
301- (bool)handleMouseDownEvent:(NSEvent *)theEvent
303 if ([self isTransparentForUserInput])
310 [
self convertFromScreen:[
self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
315 const bool masked = !
mask.isEmpty() && !
mask.contains(qtWindowPoint.
toPoint());
327 [
self handleMouseEvent:theEvent];
331- (bool)handleMouseDraggedEvent:(NSEvent *)theEvent
333 if ([self isTransparentForUserInput])
343 [
self handleMouseEvent:theEvent];
347- (bool)handleMouseUpEvent:(NSEvent *)theEvent
349 if ([self isTransparentForUserInput])
364 [
self handleMouseEvent:theEvent];
372- (
void)mouseDown:(NSEvent *)theEvent
374 if ([self isTransparentForUserInput])
375 return [
super mouseDown:theEvent];
380 [
self convertFromScreen:[
self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
384 const bool masked = !
mask.isEmpty() && !
mask.contains(qtWindowPoint.
toPoint());
393 [
super mouseDown:theEvent];
400 auto *focusObject = m_platformWindow->window()->focusObject();
405 qCDebug(lcQpaInputMethods) <<
"Asking input context to handle mouse press"
406 <<
"for focus object" << focusObject;
407 if ([NSTextInputContext.currentInputContext handleEvent:theEvent]) {
412 qCDebug(lcQpaInputMethods) <<
"Input context handled event; bailing out.";
425 [
self handleMouseEvent:theEvent];
428- (
void)mouseDragged:(NSEvent *)theEvent
430 const bool accepted = [
self handleMouseDraggedEvent:theEvent];
432 [
super mouseDragged:theEvent];
435- (
void)mouseUp:(NSEvent *)theEvent
437 const bool accepted = [
self handleMouseUpEvent:theEvent];
439 [
super mouseUp:theEvent];
442- (
void)rightMouseDown:(NSEvent *)theEvent
444 const bool accepted = [
self handleMouseDownEvent:theEvent];
446 [
super rightMouseDown:theEvent];
449- (
void)rightMouseDragged:(NSEvent *)theEvent
451 const bool accepted = [
self handleMouseDraggedEvent:theEvent];
453 [
super rightMouseDragged:theEvent];
456- (
void)rightMouseUp:(NSEvent *)theEvent
458 const bool accepted = [
self handleMouseUpEvent:theEvent];
460 [
super rightMouseUp:theEvent];
463- (
void)otherMouseDown:(NSEvent *)theEvent
465 const bool accepted = [
self handleMouseDownEvent:theEvent];
467 [
super otherMouseDown:theEvent];
470- (
void)otherMouseDragged:(NSEvent *)theEvent
472 const bool accepted = [
self handleMouseDraggedEvent:theEvent];
474 [
super otherMouseDragged:theEvent];
477- (
void)otherMouseUp:(NSEvent *)theEvent
479 const bool accepted = [
self handleMouseUpEvent:theEvent];
481 [
super otherMouseUp:theEvent];
484- (
void)cursorUpdate:(NSEvent *)theEvent
489 auto previousCursor = NSCursor.currentCursor;
494 [
super cursorUpdate:theEvent];
496 if (NSCursor.currentCursor != previousCursor)
497 qCInfo(lcQpaMouse) <<
"Cursor update for" <<
self <<
"resulted in new cursor" << NSCursor.currentCursor;
500- (
void)mouseMovedImpl:(NSEvent *)theEvent
502 if (!m_platformWindow)
514 if (m_platformWindow->isContentView()) {
515 [
self convertFromScreen:[
self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
516 QWindow *childUnderMouse = m_platformWindow->childWindowAt(windowPoint.
toPoint());
528 if ([self isTransparentForUserInput])
532 qCInfo(lcQpaMouse) <<
"Detected new window under mouse at" << windowPoint <<
"; sending"
543 [
self handleMouseEvent: theEvent];
546- (BOOL)shouldPropagateMouseEnterExit
555 if (m_platformWindow->isContentView())
559 if (m_platformWindow->isEmbedded())
563 QPlatformWindow *parentWindow = m_platformWindow->QPlatformWindow::parent();
570- (
void)mouseEnteredImpl:(NSEvent *)theEvent
573 if (!m_platformWindow)
593 if (![self shouldPropagateMouseEnterExit])
598 [
self convertFromScreen:[
self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
599 QWindow *childUnderMouse = m_platformWindow->childWindowAt(windowPoint.
toPoint());
602 if ([self isTransparentForUserInput])
613- (
void)mouseExitedImpl:(NSEvent *)theEvent
616 if (!m_platformWindow)
619 if (![self shouldPropagateMouseEnterExit])
625 if ([self isTransparentForUserInput])
638#if QT_CONFIG(wheelevent)
639- (
void)scrollWheel:(NSEvent *)theEvent
641 if (!m_platformWindow)
644 if ([self isTransparentForUserInput])
645 return [
super scrollWheel:theEvent];
649 if ([theEvent hasPreciseScrollingDeltas]) {
655 const int pixelsToDegrees = 2;
656 angleDelta.
setX([theEvent scrollingDeltaX] * pixelsToDegrees);
657 angleDelta.
setY([theEvent scrollingDeltaY] * pixelsToDegrees);
661 angleDelta.
setX(
qBound(-120,
int([theEvent deltaX] * 10000), 120));
662 angleDelta.
setY(
qBound(-120,
int([theEvent deltaY] * 10000), 120));
666 if ([theEvent hasPreciseScrollingDeltas]) {
667 pixelDelta.
setX([theEvent scrollingDeltaX]);
668 pixelDelta.
setY([theEvent scrollingDeltaY]);
672 const CGFloat lineWithEstimate = 20.0;
673 pixelDelta.
setX([theEvent scrollingDeltaX] * lineWithEstimate);
674 pixelDelta.
setY([theEvent scrollingDeltaY] * lineWithEstimate);
679 [
self convertFromScreen:[
self screenMousePoint:theEvent] toWindowPoint:&qt_windowPoint andScreenPoint:&qt_screenPoint];
680 NSTimeInterval timestamp = [theEvent timestamp];
681 ulong qt_timestamp = timestamp * 1000;
684 if (theEvent.phase == NSEventPhaseMayBegin || theEvent.phase == NSEventPhaseBegan) {
689 }
else if (theEvent.phase == NSEventPhaseStationary || theEvent.phase == NSEventPhaseChanged) {
691 }
else if (theEvent.phase == NSEventPhaseEnded) {
698 if ([NSApp nextEventMatchingMask:NSEventMaskScrollWheel untilDate:[NSDate distantPast]
699 inMode:
@"QtMomementumEventSearchMode" dequeue:NO].momentumPhase == NSEventPhaseBegan) {
705 }
else if (theEvent.momentumPhase == NSEventPhaseBegan) {
712 }
else if (theEvent.momentumPhase == NSEventPhaseChanged) {
714 }
else if (theEvent.phase == NSEventPhaseCancelled
715 || theEvent.momentumPhase == NSEventPhaseEnded
716 || theEvent.momentumPhase == NSEventPhaseCancelled) {
720 Q_ASSERT(theEvent.momentumPhase != NSEventPhaseStationary);
725 if (theEvent.phase == NSEventPhaseCancelled) {
727 qCInfo(lcQpaMouse) <<
"Ignoring unexpected delta for" << theEvent;
740 if (theEvent.momentumPhase == NSEventPhaseNone)
744 bool isInverted = [theEvent isDirectionInvertedFromDevice];
746 qCInfo(lcQpaMouse).nospace() << phase <<
" at " << qt_windowPoint
747 <<
" pixelDelta=" << pixelDelta <<
" angleDelta=" << angleDelta
748 << (isInverted ?
" inverted=true" :
"");
753 if (theEvent.hasPreciseScrollingDeltas) {
756 devicePriv->name =
"trackpad or magic mouse"_L1;
759 qCDebug(lcInputDevices) <<
"mouse scrolling: updated capabilities" <<
device;
764 device, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta,
IOBluetoothDevice * device
void setLastMouseEvent(NSEvent *event, NSView *view)
static QCocoaIntegration * instance()
QCocoaDrag * drag() const override
static QPointF mapFromNative(CGPoint pos, QCocoaScreen *screen=QCocoaScreen::primaryScreen())
static QPointer< QCocoaWindow > s_windowUnderMouse
@ NonClientAreaMouseButtonRelease
@ NonClientAreaMouseButtonPress
static QRectF inputItemClipRectangle()
QPlatformInputContext::inputItemClipRectangle.
\inmodule QtCore\reentrant
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
\inmodule QtCore\reentrant
constexpr bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0, otherwise returns false.
constexpr void setY(int y) noexcept
Sets the y coordinate of this point to the given y coordinate.
constexpr void setX(int x) noexcept
Sets the x coordinate of this point to the given x coordinate.
static const QPointingDevice * pointingDeviceById(qint64 systemId)
static QPointingDevicePrivate * get(QPointingDevice *q)
QPointingDeviceUniqueId identifies a unique object, such as a tagged token or stylus,...
The QPointingDevice class describes a device from which mouse, touch or tablet events originate.
static const QPointingDevice * primaryPointingDevice(const QString &seatName=QString())
Returns the primary pointing device (the core pointer, traditionally assumed to be a mouse) on the gi...
The QRegion class specifies a clip region for a painter.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static void handleLeaveEvent(QWindow *window)
static bool handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons state, Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
static void registerInputDevice(const QInputDevice *device)
static void handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local=QPointF(), const QPointF &global=QPointF())
This method can be used to ensure leave and enter events are both in queue when moving from one QWind...
static void handleEnterEvent(QWindow *window, const QPointF &local=QPointF(), const QPointF &global=QPointF())
static bool handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::ScrollPhase phase=Qt::NoScrollPhase, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
EGLImageKHR int int EGLuint64KHR * modifiers
T toNativeLocalPosition(const T &value, const C *context)
@ MouseEventSynthesizedBySystem
@ MouseEventNotSynthesized
QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event)
Returns the QEvent::Type that corresponds to an NSEvent.type.
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
Returns the Qt::Button that corresponds to an NSEvent.buttonNumber.
InputMethodQueryResult queryInputMethod(QObject *object, Qt::InputMethodQueries queries)
Qt::MouseButtons currentlyPressedMouseButtons()
Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
bool qIsNaN(qfloat16 f) noexcept
#define qCInfo(category,...)
#define qCDebug(category,...)
constexpr const T & qBound(const T &min, const T &val, const T &max)
bool m_sendUpAsRightButton
Qt::MouseButtons m_buttons
bool m_dontOverrideCtrlLMB
QNSViewMouseMoveHelper * m_mouseMoveHelper
Qt::MouseButtons m_acceptedMouseDowns
Qt::MouseButtons m_frameStrutButtons
Qt::KeyboardModifiers m_currentWheelModifiers
static const QPointingDevice * pointingDeviceFor(qint64 deviceID)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLsizei GLsizei GLchar * source
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)