5#include <AppKit/AppKit.h>
6#include <ScreenCaptureKit/ScreenCaptureKit.h>
14#include <QtCore/qcoreapplication.h>
15#include <QtGui/private/qcoregraphics_p.h>
17#include <IOKit/graphics/IOGraphicsLib.h>
19#include <QtGui/private/qwindow_p.h>
20#include <QtGui/private/qhighdpiscaling_p.h>
22#include <QtCore/private/qcore_mac_p.h>
23#include <QtCore/private/qeventdispatcher_cf_p.h>
42 Q_ENUM_NS(DisplayChange)
45QMacNotificationObserver
QCocoaScreen::s_screenParameterObserver;
46CGDisplayReconfigurationCallBack
QCocoaScreen::s_displayReconfigurationCallBack =
nullptr;
52 s_displayReconfigurationCallBack = [](CGDirectDisplayID displayId, CGDisplayChangeSummaryFlags flags,
void *userInfo) {
55 const bool beforeReconfigure = flags & kCGDisplayBeginConfigurationFlag;
56 qCDebug(lcQpaScreen).verbosity(0) <<
"Display" << displayId
57 << (beforeReconfigure ?
"beginning" :
"finished") <<
"reconfigure"
60 if (!beforeReconfigure)
63 CGDisplayRegisterReconfigurationCallback(s_displayReconfigurationCallBack,
nullptr);
65 s_screenParameterObserver = QMacNotificationObserver(NSApplication.sharedApplication,
66 NSApplicationDidChangeScreenParametersNotification, [&]() {
67 qCDebug(lcQpaScreen) <<
"Received screen parameter change notification";
77
78
79
80
88 static bool updatingScreens =
false;
89 if (updatingScreens) {
90 qCInfo(lcQpaScreen) <<
"Skipping screen update, already updating";
93 QScopedValueRollback recursionGuard(updatingScreens,
true);
95 uint32_t displayCount = 0;
96 if (CGGetOnlineDisplayList(0,
nullptr, &displayCount) != kCGErrorSuccess)
97 qFatal(
"Failed to get number of online displays");
99 QVector<CGDirectDisplayID> onlineDisplays(displayCount);
100 if (CGGetOnlineDisplayList(displayCount, onlineDisplays.data(), &displayCount) != kCGErrorSuccess)
101 qFatal(
"Failed to get online displays");
103 qCInfo(lcQpaScreen) <<
"Updating screens with" << displayCount
104 <<
"online displays:" << onlineDisplays;
107 int mainDisplayIndex = onlineDisplays.indexOf(CGMainDisplayID());
108 if (mainDisplayIndex < 0) {
109 qCWarning(lcQpaScreen) <<
"Main display not in list of online displays!";
110 }
else if (mainDisplayIndex > 0) {
111 qCWarning(lcQpaScreen) <<
"Main display not first display, making sure it is";
112 onlineDisplays.move(mainDisplayIndex, 0);
115 for (CGDirectDisplayID displayId : onlineDisplays) {
116 Q_ASSERT(CGDisplayIsOnline(displayId));
118 if (CGDisplayMirrorsDisplay(displayId))
127 QCFType<CFUUIDRef> uuid = CGDisplayCreateUUIDFromDisplayID(displayId);
130 if (QCocoaScreen *existingScreen = QCocoaScreen::get(uuid)) {
131 existingScreen->update(displayId);
132 qCInfo(lcQpaScreen) <<
"Updated" << existingScreen;
133 if (CGDisplayIsMain(displayId) && existingScreen != qGuiApp->primaryScreen()->handle()) {
134 qCInfo(lcQpaScreen) <<
"Primary screen changed to" << existingScreen;
135 QWindowSystemInterface::handlePrimaryScreenChanged(existingScreen);
138 QCocoaScreen::add(displayId);
142 for (QScreen *screen : QGuiApplication::screens()) {
143 QCocoaScreen *platformScreen =
static_cast<QCocoaScreen*>(screen->handle());
144 if (!platformScreen->isOnline() || platformScreen->isMirroring())
145 platformScreen->remove();
151 const bool isPrimary = CGDisplayIsMain(displayId);
153 qCInfo(lcQpaScreen) <<
"Adding" << cocoaScreen
154 << (isPrimary ?
"as new primary screen" :
"");
155 QWindowSystemInterface::handleScreenAdded(cocoaScreen, isPrimary);
159 : QPlatformScreen(), m_displayId(displayId)
162 m_cursor =
new QCocoaCursor;
168 for (QScreen *screen : backwards(QGuiApplication::screens()))
169 static_cast<QCocoaScreen*>(screen->handle())->remove();
171 Q_ASSERT(s_displayReconfigurationCallBack);
172 CGDisplayRemoveReconfigurationCallback(s_displayReconfigurationCallBack,
nullptr);
173 s_displayReconfigurationCallBack =
nullptr;
175 s_screenParameterObserver.remove();
191 qCInfo(lcQpaScreen) <<
"Removing " <<
this;
192 QWindowSystemInterface::handleScreenRemoved(
this);
197 Q_ASSERT_X(!screen(),
"QCocoaScreen",
"QScreen should be deleted first");
201 CVDisplayLinkRelease(m_displayLink);
202 if (m_displayLinkSource)
203 dispatch_release(m_displayLinkSource);
208 if (displayId != m_displayId) {
209 qCDebug(lcQpaScreen) <<
"Reconnecting" <<
this <<
"as display" << displayId;
210 m_displayId = displayId;
216 NSScreen *nsScreen = nativeScreen();
218 qCDebug(lcQpaScreen) <<
"Corresponding NSScreen not yet available. Deferring update";
222 const QRect previousGeometry = m_geometry;
223 const QRect previousAvailableGeometry = m_availableGeometry;
224 const qreal previousRefreshRate = m_refreshRate;
225 const double previousRotation = m_rotation;
228 QRectF primaryScreenGeometry = QRectF::fromCGRect(CGDisplayBounds(CGMainDisplayID()));
229 m_geometry = qt_mac_flip(QRectF::fromCGRect(nsScreen.frame), primaryScreenGeometry).toRect();
230 m_availableGeometry = qt_mac_flip(QRectF::fromCGRect(nsScreen.visibleFrame), primaryScreenGeometry).toRect();
232 m_devicePixelRatio = nsScreen.backingScaleFactor;
234 m_format = QImage::Format_RGB32;
235 m_depth = NSBitsPerPixelFromDepth(nsScreen.depth);
236 m_colorSpace = QColorSpace::fromIccProfile(QByteArray::fromNSData(nsScreen.colorSpace.ICCProfileData));
237 if (!m_colorSpace.isValid()) {
238 qCWarning(lcQpaScreen) <<
"Failed to parse ICC profile for" << nsScreen.colorSpace
239 <<
"with ICC data" << nsScreen.colorSpace.ICCProfileData
240 <<
"- Falling back to sRGB";
241 m_colorSpace = QColorSpace::SRgb;
244 CGSize size = CGDisplayScreenSize(m_displayId);
245 m_physicalSize = QSizeF(size.width, size.height);
247 QCFType<CGDisplayModeRef> displayMode = CGDisplayCopyDisplayMode(m_displayId);
248 float refresh = CGDisplayModeGetRefreshRate(displayMode);
249 m_refreshRate = refresh > 0 ? refresh : 60.0;
250 m_rotation = CGDisplayRotation(displayId);
251 m_name = QString::fromNSString(nsScreen.localizedName);
253 const bool didChangeGeometry = m_geometry != previousGeometry || m_availableGeometry != previousAvailableGeometry;
255 if (m_rotation != previousRotation)
256 QWindowSystemInterface::handleScreenOrientationChange(screen(), orientation());
258 if (didChangeGeometry)
259 QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
260 if (m_refreshRate != previousRefreshRate)
261 QWindowSystemInterface::handleScreenRefreshRateChange(screen(), m_refreshRate);
270 Q_ASSERT(m_displayId);
273 qCDebug(lcQpaScreenUpdates) <<
this <<
"is not online. Ignoring update request";
280 ++m_pendingUpdateRequests;
282 if (!m_displayLink) {
283 qCDebug(lcQpaScreenUpdates) <<
"Creating display link for" <<
this;
284 if (CVDisplayLinkCreateWithCGDisplay(m_displayId, &m_displayLink) != kCVReturnSuccess) {
285 qCWarning(lcQpaScreenUpdates) <<
"Failed to create display link for" <<
this;
288 if (
auto displayId = CVDisplayLinkGetCurrentCGDisplay(m_displayLink); displayId != m_displayId) {
289 qCWarning(lcQpaScreenUpdates) <<
"Unexpected display" << displayId <<
"for display link";
290 CVDisplayLinkRelease(m_displayLink);
291 m_displayLink =
nullptr;
294 CVDisplayLinkSetOutputCallback(m_displayLink, [](CVDisplayLinkRef,
const CVTimeStamp*,
295 const CVTimeStamp*, CVOptionFlags, CVOptionFlags*,
void* displayLinkContext) ->
int {
298 return kCVReturnSuccess;
320 static CFMachPortRef eventTap = []() {
321 CFMachPortRef eventTap = CGEventTapCreateForPid(getpid(), kCGTailAppendEventTap,
322 kCGEventTapOptionListenOnly, NSEventMaskLeftMouseDragged,
323 [](CGEventTapProxy, CGEventType type, CGEventRef event,
void *) -> CGEventRef {
324 if (type == kCGEventTapDisabledByTimeout)
325 qCWarning(lcQpaScreenUpdates) <<
"Event tap disabled due to timeout!";
328 CGEventTapEnable(eventTap,
false);
329 static CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
330 CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
332 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
333 [center addObserverForName:NSWindowWillStartLiveResizeNotification object:nil queue:nil
334 usingBlock:^(NSNotification *notification) {
335 qCDebug(lcQpaScreenUpdates) <<
"Live resize of" << notification.object
336 <<
"started. Enabling event tap";
337 CGEventTapEnable(eventTap,
true);
339 [center addObserverForName:NSWindowDidEndLiveResizeNotification object:nil queue:nil
340 usingBlock:^(NSNotification *notification) {
341 qCDebug(lcQpaScreenUpdates) <<
"Live resize of" << notification.object
342 <<
"ended. Disabling event tap";
343 CGEventTapEnable(eventTap,
false);
350 if (!CVDisplayLinkIsRunning(m_displayLink)) {
351 qCDebug(lcQpaScreenUpdates) <<
"Starting display link for" <<
this;
352 CVDisplayLinkStart(m_displayLink);
362 if (cat.isDebugEnabled())
363 debug =
new QDebug(QMessageLogger().debug(cat).nospace());
377#define qDeferredDebug(helper) if (Q_UNLIKELY(helper.debug)) *helper.debug
382 qCDebug(lcQpaScreenUpdates) <<
this <<
"is not online. Ignoring update request delivery";
386 QMacAutoReleasePool pool;
393 if (!NSThread.isMainThread) {
397 const int pendingUpdates = ++m_pendingDisplayLinkUpdates;
399 const int pendingUpdateRequests = m_pendingUpdateRequests;
402 qDeferredDebug(screenUpdates) <<
"display link callback for screen " << m_displayId
403 <<
" with " << pendingUpdateRequests <<
" pending update requests";
405 if (
const int framesAheadOfDelivery = pendingUpdates - 1) {
410 qDeferredDebug(screenUpdates) <<
", " << framesAheadOfDelivery <<
" frame(s) ahead";
413 if (!pendingUpdateRequests) {
418 qDeferredDebug(screenUpdates) <<
"; skipping signaling dispatch source";
419 m_pendingDisplayLinkUpdates = 0;
425 if (!m_displayLinkSource) {
426 m_displayLinkSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
427 dispatch_source_set_event_handler(m_displayLinkSource, ^{
430 dispatch_resume(m_displayLinkSource);
433 dispatch_source_merge_data(m_displayLinkSource, 1);
439 const int pendingUpdates = m_pendingDisplayLinkUpdates;
440 if (pendingUpdates > 1)
441 qDeferredDebug(screenUpdates) <<
", " << (pendingUpdates - 1) <<
" frame(s) behind display link";
445 int pendingUpdateRequests = 0;
447 auto windows = QGuiApplication::allWindows();
448 for (
int i = 0; i < windows.size(); ++i) {
449 QWindow *window = windows.at(i);
450 if (window->screen() != screen())
453 QPointer<QCocoaWindow> platformWindow =
static_cast<
QCocoaWindow*>(window->handle());
457 if (!platformWindow->hasPendingUpdateRequest())
461 if (!platformWindow->updatesWithDisplayLink())
464 platformWindow->deliverUpdateRequest();
473 if (platformWindow->hasPendingUpdateRequest())
474 ++pendingUpdateRequests;
477 m_pendingUpdateRequests = pendingUpdateRequests;
479 if (
const int missedUpdates = m_pendingDisplayLinkUpdates.fetchAndStoreRelaxed(0) - pendingUpdates) {
480 qCWarning(lcQpaScreenUpdates) <<
"main thread missed" << missedUpdates
481 <<
"update(s) from display link during update request delivery";
488 if (!CVDisplayLinkIsRunning(m_displayLink))
491 const auto windows = QGuiApplication::allWindows();
492 for (
auto *window : windows) {
493 if (window->screen() != screen())
496 QPointer<QCocoaWindow> platformWindow =
static_cast<QCocoaWindow*>(window->handle());
500 if (window->isExposed())
503 if (platformWindow->hasPendingUpdateRequest())
507 qCDebug(lcQpaScreenUpdates) <<
"Stopping display link for" <<
this;
508 CVDisplayLinkStop(m_displayLink);
516 if (@available(macOS 14, *)) {
517 for (
auto *window : QGuiApplication::allWindows()) {
518 auto *platformWindow =
static_cast<QCocoaWindow*>(window->handle());
522 NSView *view = platformWindow->view();
524 if (!view.layer.wantsExtendedDynamicRangeContent)
527 [view setNeedsDisplay:YES];
536 QPlatformScreen::SubpixelAntialiasingType type = QPlatformScreen::subpixelAntialiasingTypeHint();
537 if (type == QPlatformScreen::Subpixel_None) {
539 type = QPlatformScreen::Subpixel_RGB;
547 return Qt::LandscapeOrientation;
548 if (m_rotation == 90)
549 return Qt::PortraitOrientation;
550 if (m_rotation == 180)
551 return Qt::InvertedLandscapeOrientation;
552 if (m_rotation == 270)
553 return Qt::InvertedPortraitOrientation;
554 return QPlatformScreen::orientation();
559 __block QWindow *window =
nullptr;
560 [NSApp enumerateWindowsWithOptions:NSWindowListOrderedFrontToBack
561 usingBlock:^(NSWindow *nsWindow, BOOL *stop) {
566 if (![nsWindow conformsToProtocol:@protocol(QNSWindowProtocol)])
569 QCocoaWindow *cocoaWindow = qnsview_cast(nsWindow.contentView).platformWindow;
573 QWindow *w = cocoaWindow->window();
577 auto nativeGeometry = QHighDpi::toNativePixels(w->geometry(), w);
578 if (!nativeGeometry.contains(point))
581 QRegion mask = QHighDpi::toNativeLocalPosition(w->mask(), w);
582 if (!mask.isEmpty() && !mask.contains(point - nativeGeometry.topLeft()))
588 if (!window->isTopLevel())
599
600
601
602
603
607 if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(
608 QPlatformIntegration::ScreenWindowGrabbing)) {
609 qCWarning(lcQpaScreen) <<
"Ignoring grabWindow to not bring down WindowServer";
613 auto grabFromDisplay = [](CGDirectDisplayID displayId,
const QRect &grabRect) -> QPixmap {
614 QMacAutoReleasePool pool;
616 const qreal scale = QCocoaScreen::nativeScreenForDisplayId(displayId).backingScaleFactor;
618 dispatch_semaphore_t sem = dispatch_semaphore_create(0);
619 auto cleanup = qScopeGuard([sem]() { dispatch_release(sem); });
621 auto captureShareableContent = [sem](
void (^capture)(SCShareableContent *)) {
625 [SCShareableContent getShareableContentWithCompletionHandler:
626 ^(SCShareableContent *content, NSError *error) {
628 qCDebug(lcQpaScreen) <<
"Failed to capture all windows" << error;
636 [SCShareableContent getCurrentProcessShareableContentWithCompletionHandler:
637 ^(SCShareableContent *content, NSError *error) {
639 qCWarning(lcQpaScreen) <<
"Failed to capture own windows" << error;
643 dispatch_semaphore_signal(sem);
650 __block QImage image;
651 captureShareableContent(^(SCShareableContent *content) {
654 QMacAutoReleasePool pool;
656 SCDisplay *scDisplay = nil;
657 for (SCDisplay *d in content.displays) {
658 if (d.displayID == displayId) {
664 qCWarning(lcQpaScreen) <<
"No SCDisplay for display" << displayId;
665 dispatch_semaphore_signal(sem);
669 SCContentFilter *filter = [[[SCContentFilter alloc]
670 initWithDisplay:scDisplay
671 includingApplications:content.applications
672 exceptingWindows:@[]] autorelease];
673 filter.includeMenuBar = YES;
675 SCStreamConfiguration *config = [[SCStreamConfiguration
new] autorelease];
676 config.sourceRect = grabRect.toCGRect();
677 config.width = qRound(grabRect.width() * scale);
678 config.height = qRound(grabRect.height() * scale);
679 config.showsCursor = NO;
680 config.capturesAudio = NO;
681 config.ignoreShadowsDisplay = NO;
682 config.ignoreShadowsSingleWindow = NO;
684 [SCScreenshotManager captureImageWithFilter:filter configuration:config
685 completionHandler:^(CGImageRef cgImage, NSError *error) {
687 qCWarning(lcQpaScreen) <<
"Failed screen capture" << error;
689 image = qt_mac_toQImage(cgImage);
690 dispatch_semaphore_signal(sem);
696 if (dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)) != 0) {
697 qCWarning(lcQpaScreen) <<
"Screen capture timed out for display" << displayId;
701 QPixmap pixmap = QPixmap::fromImage(image);
702 pixmap.setDevicePixelRatio(scale);
706 QRect grabRect = QRect(x, y, width, height);
707 qCDebug(lcQpaScreen) <<
"input grab rect" << grabRect;
711 NSView *nsView =
reinterpret_cast<NSView*>(view);
712 NSPoint windowPoint = [nsView convertPoint:NSMakePoint(0, 0) toView:nil];
713 NSRect screenRect = [nsView.window convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
714 QPoint position = mapFromNative(screenRect.origin).toPoint();
715 QSize size = QRectF::fromCGRect(NSRectToCGRect(nsView.bounds)).toRect().size();
716 QRect windowRect = QRect(position, size);
717 if (!grabRect.isValid())
718 grabRect = windowRect;
720 grabRect.translate(windowRect.topLeft());
723 if (!grabRect.isValid())
724 grabRect = geometry();
728 const int maxDisplays = 128;
729 CGDirectDisplayID displays[maxDisplays];
730 CGDisplayCount displayCount;
731 CGRect cgRect = grabRect.isValid() ? grabRect.toCGRect() : CGRectInfinite;
732 const CGDisplayErr err = CGGetDisplaysWithRect(cgRect, maxDisplays, displays, &displayCount);
733 if (err || displayCount == 0)
736 qCDebug(lcQpaScreen) <<
"final grab rect" << grabRect <<
"from" << displayCount <<
"displays";
741 QVector<QPixmap> pixmaps;
742 QVector<QRect> globalGrabBounds;
744 for (uint i = 0; i < displayCount; ++i) {
745 auto display = displays[i];
746 const QRect displayBounds = QRectF::fromCGRect(CGDisplayBounds(display)).toRect();
747 const QRect grabBounds = displayBounds.intersected(grabRect);
748 if (grabBounds.isNull()) {
749 globalGrabBounds.append(QRect());
750 pixmaps.append(QPixmap());
753 const QRect displayLocalGrabBounds = QRect(QPoint(grabBounds.topLeft() - displayBounds.topLeft()), grabBounds.size());
755 qCDebug(lcQpaScreen) <<
"grab display" << i <<
"global" << grabBounds <<
"local" << displayLocalGrabBounds;
756 QPixmap displayPixmap = grabFromDisplay(display, displayLocalGrabBounds);
758 if (displayCount == 1)
759 return displayPixmap;
761 qCDebug(lcQpaScreen) <<
"grab sub-image size" << displayPixmap.size() <<
"devicePixelRatio" << displayPixmap.devicePixelRatio();
762 pixmaps.append(displayPixmap);
763 globalGrabBounds.append(grabBounds);
764 outputRect = outputRect.united(grabBounds);
769 for (uint i = 0; i < displayCount; ++i)
770 dpr = qMax(dpr, pixmaps.at(i).devicePixelRatio());
773 qCDebug(lcQpaScreen) <<
"Create grap pixmap" << outputRect.size() <<
"at devicePixelRatio" << dpr;
774 QPixmap windowPixmap(outputRect.size() * dpr);
775 windowPixmap.setDevicePixelRatio(dpr);
776 windowPixmap.fill(Qt::transparent);
777 QPainter painter(&windowPixmap);
778 for (uint i = 0; i < displayCount; ++i) {
779 const QRect grabBounds = globalGrabBounds.at(i);
780 if (grabBounds.isNull())
782 const QRect dest(grabBounds.topLeft() - outputRect.topLeft(), grabBounds.size());
783 painter.drawPixmap(dest, pixmaps.at(i));
796 int isOnline = CGDisplayIsOnline(m_displayId);
797 static const int kCGDisplayIsDisconnected = 0xffffffff;
798 return isOnline != kCGDisplayIsDisconnected && isOnline;
802
803
809 return CGDisplayMirrorsDisplay(m_displayId);
813
814
820 return static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle());
825 QList<QPlatformScreen*> siblings;
828 for (QScreen *screen : QGuiApplication::screens())
829 siblings << screen->handle();
836 auto displayId = nsScreen.qt_displayId;
837 auto *cocoaScreen = get(displayId);
839 qCWarning(lcQpaScreen) <<
"Failed to map" << nsScreen
840 <<
"to QCocoaScreen. Doing last minute update.";
842 cocoaScreen = get(displayId);
844 qCWarning(lcQpaScreen) <<
"Last minute update failed!";
851 for (QScreen *screen : QGuiApplication::screens()) {
852 QCocoaScreen *cocoaScreen =
static_cast<QCocoaScreen*>(screen->handle());
853 if (cocoaScreen->m_displayId == displayId)
862 for (QScreen *screen : QGuiApplication::screens()) {
863 auto *platformScreen =
static_cast<QCocoaScreen*>(screen->handle());
864 if (!platformScreen->isOnline())
867 auto displayId = platformScreen->displayId();
868 QCFType<CFUUIDRef> candidateUuid(CGDisplayCreateUUIDFromDisplayID(displayId));
869 Q_ASSERT(candidateUuid);
871 if (candidateUuid == uuid)
872 return platformScreen;
878NSScreen *
QCocoaScreen::nativeScreenForDisplayId(CGDirectDisplayID displayId)
880 for (NSScreen *screen in NSScreen.screens) {
881 if (screen.qt_displayId == displayId)
892 return nativeScreenForDisplayId(m_displayId);
898 return qt_mac_flip(pos, screen->geometry()).toCGPoint();
904 return qt_mac_flip(rect, screen->geometry()).toCGRect();
910 return qt_mac_flip(QPointF::fromCGPoint(pos), screen->geometry());
916 return qt_mac_flip(QRectF::fromCGRect(rect), screen->geometry());
919#ifndef QT_NO_DEBUG_STREAM
922 QDebugStateSaver saver(debug);
924 debug <<
"QCocoaScreen(" << (
const void *)screen;
926 debug <<
", " << screen->name();
928 if (CGDisplayIsAsleep(screen->displayId()))
929 debug <<
", Sleeping";
930 if (
auto mirroring = CGDisplayMirrorsDisplay(screen->displayId()))
931 debug <<
", mirroring=" << mirroring;
933 debug <<
", Offline";
935 debug <<
", " << screen->geometry();
936 debug <<
", dpr=" << screen->devicePixelRatio();
937 debug <<
", displayId=" << screen->displayId();
939 if (
auto nativeScreen = screen->nativeScreen())
940 debug <<
", " << nativeScreen;
949#include "qcocoascreen.moc"
951@implementation NSScreen (QtExtras)
953- (CGDirectDisplayID)qt_displayId
955 return [self.deviceDescription[@
"NSScreenNumber"] unsignedIntValue];
QPixmap grabWindow(WId window, int x, int y, int width, int height) const override
void deliverUpdateRequests()
NSScreen * nativeScreen() const override
QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const override
Returns a hint about this screen's subpixel layout structure.
static QCocoaScreen * primaryScreen()
The screen used as a reference for global window geometry.
Qt::ScreenOrientation orientation() const override
Reimplement this function in subclass to return the current orientation of the screen,...
QList< QPlatformScreen * > virtualSiblings() const override
Returns a list of all the platform screens that are part of the same virtual desktop.
QWindow * topLevelAt(const QPoint &point) const override
Return the given top level window for a given position.
\inmodule QtCore\reentrant
@ ReconfiguredWithFlagsMissing
#define qDeferredDebug(helper)
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
DeferredDebugHelper(const QLoggingCategory &cat)