mirror of
https://github.com/crystalidea/qt-build-tools.git
synced 2024-11-22 19:00:04 +08:00
5.13.2: qcocoascreen patched from QTBUG-80193
This commit is contained in:
parent
ad520af861
commit
3085d86f9b
@ -53,9 +53,6 @@ class QCocoaIntegration;
|
||||
class QCocoaScreen : public QPlatformScreen
|
||||
{
|
||||
public:
|
||||
static void initializeScreens();
|
||||
static void cleanupScreens();
|
||||
|
||||
~QCocoaScreen();
|
||||
|
||||
// ----------------------------------------------------
|
||||
@ -68,6 +65,7 @@ public:
|
||||
qreal devicePixelRatio() const override { return m_devicePixelRatio; }
|
||||
QSizeF physicalSize() const override { return m_physicalSize; }
|
||||
QDpi logicalDpi() const override { return m_logicalDpi; }
|
||||
QDpi logicalBaseDpi() const override { return m_logicalDpi; }
|
||||
qreal refreshRate() const override { return m_refreshRate; }
|
||||
QString name() const override { return m_name; }
|
||||
QPlatformCursor *cursor() const override { return m_cursor; }
|
||||
@ -78,7 +76,6 @@ public:
|
||||
// ----------------------------------------------------
|
||||
|
||||
NSScreen *nativeScreen() const;
|
||||
void updateProperties();
|
||||
|
||||
void requestUpdate();
|
||||
void deliverUpdateRequests();
|
||||
@ -87,6 +84,7 @@ public:
|
||||
static QCocoaScreen *primaryScreen();
|
||||
static QCocoaScreen *get(NSScreen *nsScreen);
|
||||
static QCocoaScreen *get(CGDirectDisplayID displayId);
|
||||
static QCocoaScreen *get(CFUUIDRef uuid);
|
||||
|
||||
static CGPoint mapToNative(const QPointF &pos, QCocoaScreen *screen = QCocoaScreen::primaryScreen());
|
||||
static CGRect mapToNative(const QRectF &rect, QCocoaScreen *screen = QCocoaScreen::primaryScreen());
|
||||
@ -94,27 +92,41 @@ public:
|
||||
static QRectF mapFromNative(CGRect rect, QCocoaScreen *screen = QCocoaScreen::primaryScreen());
|
||||
|
||||
private:
|
||||
QCocoaScreen(CGDirectDisplayID displayId);
|
||||
static void initializeScreens();
|
||||
static void updateScreens();
|
||||
static void cleanupScreens();
|
||||
|
||||
static bool updateScreensIfNeeded();
|
||||
static NSArray *s_screenConfigurationBeforeUpdate;
|
||||
|
||||
static void add(CGDirectDisplayID displayId);
|
||||
QCocoaScreen(CGDirectDisplayID displayId);
|
||||
void update(CGDirectDisplayID displayId);
|
||||
void remove();
|
||||
|
||||
CGDirectDisplayID m_displayId = 0;
|
||||
bool isOnline() const;
|
||||
bool isMirroring() const;
|
||||
|
||||
CGDirectDisplayID m_displayId = kCGNullDirectDisplay;
|
||||
CGDirectDisplayID displayId() const { return m_displayId; }
|
||||
|
||||
QRect m_geometry;
|
||||
QRect m_availableGeometry;
|
||||
QDpi m_logicalDpi;
|
||||
qreal m_refreshRate;
|
||||
int m_depth;
|
||||
qreal m_refreshRate = 0;
|
||||
int m_depth = 0;
|
||||
QString m_name;
|
||||
QImage::Format m_format;
|
||||
QSizeF m_physicalSize;
|
||||
QCocoaCursor *m_cursor;
|
||||
qreal m_devicePixelRatio;
|
||||
qreal m_devicePixelRatio = 0;
|
||||
|
||||
CVDisplayLinkRef m_displayLink = nullptr;
|
||||
dispatch_source_t m_displayLinkSource = nullptr;
|
||||
QAtomicInt m_pendingUpdates;
|
||||
|
||||
friend class QCocoaIntegration;
|
||||
friend class QCocoaWindow;
|
||||
friend QDebug operator<<(QDebug debug, const QCocoaScreen *screen);
|
||||
};
|
||||
|
||||
|
@ -54,67 +54,185 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace CoreGraphics {
|
||||
Q_NAMESPACE
|
||||
enum DisplayChange {
|
||||
ReconfiguredWithFlagsMissing = 0,
|
||||
Moved = kCGDisplayMovedFlag,
|
||||
SetMain = kCGDisplaySetMainFlag,
|
||||
SetMode = kCGDisplaySetModeFlag,
|
||||
Added = kCGDisplayAddFlag,
|
||||
Removed = kCGDisplayRemoveFlag,
|
||||
Enabled = kCGDisplayEnabledFlag,
|
||||
Disabled = kCGDisplayDisabledFlag,
|
||||
Mirrored = kCGDisplayMirrorFlag,
|
||||
UnMirrored = kCGDisplayUnMirrorFlag,
|
||||
DesktopShapeChanged = kCGDisplayDesktopShapeChangedFlag
|
||||
};
|
||||
Q_ENUM_NS(DisplayChange)
|
||||
}
|
||||
|
||||
NSArray *QCocoaScreen::s_screenConfigurationBeforeUpdate = nil;
|
||||
|
||||
void QCocoaScreen::initializeScreens()
|
||||
{
|
||||
uint32_t displayCount = 0;
|
||||
if (CGGetActiveDisplayList(0, nullptr, &displayCount) != kCGErrorSuccess)
|
||||
qFatal("Failed to get number of active displays");
|
||||
|
||||
CGDirectDisplayID activeDisplays[displayCount];
|
||||
if (CGGetActiveDisplayList(displayCount, &activeDisplays[0], &displayCount) != kCGErrorSuccess)
|
||||
qFatal("Failed to get active displays");
|
||||
|
||||
for (CGDirectDisplayID displayId : activeDisplays)
|
||||
QCocoaScreen::add(displayId);
|
||||
updateScreens();
|
||||
|
||||
CGDisplayRegisterReconfigurationCallback([](CGDirectDisplayID displayId, CGDisplayChangeSummaryFlags flags, void *userInfo) {
|
||||
if (flags & kCGDisplayBeginConfigurationFlag)
|
||||
return; // Wait for changes to apply
|
||||
|
||||
Q_UNUSED(userInfo);
|
||||
|
||||
QCocoaScreen *cocoaScreen = QCocoaScreen::get(displayId);
|
||||
// Displays are reconfigured in batches, and we want to update our screens
|
||||
// once a batch ends, so that all the states of the displays are up to date.
|
||||
static int displayReconfigurationsInProgress = 0;
|
||||
|
||||
if ((flags & kCGDisplayAddFlag) || !cocoaScreen) {
|
||||
if (!CGDisplayIsActive(displayId)) {
|
||||
qCDebug(lcQpaScreen) << "Not adding inactive display" << displayId;
|
||||
return; // Will be added when activated
|
||||
const bool beforeReconfigure = flags & kCGDisplayBeginConfigurationFlag;
|
||||
qCDebug(lcQpaScreen).verbosity(0).nospace() << "Display " << displayId
|
||||
<< (beforeReconfigure ? " about to reconfigure" : " was ")
|
||||
<< QFlags<CoreGraphics::DisplayChange>(flags)
|
||||
<< " with " << displayReconfigurationsInProgress
|
||||
<< " display configuration(s) in progress";
|
||||
|
||||
if (!flags) {
|
||||
// CGDisplayRegisterReconfigurationCallback has been observed to be called
|
||||
// with flags unset. This seems like a bug. The callback is not paired with
|
||||
// a matching "completion" callback either, so we don't know whether to treat
|
||||
// it as a begin or end of reconfigure.
|
||||
return;
|
||||
}
|
||||
|
||||
if (beforeReconfigure) {
|
||||
if (!displayReconfigurationsInProgress++) {
|
||||
// There might have been a screen reconfigure before this that
|
||||
// we didn't process yet, so do that now if that's the case.
|
||||
updateScreensIfNeeded();
|
||||
|
||||
Q_ASSERT(!s_screenConfigurationBeforeUpdate);
|
||||
s_screenConfigurationBeforeUpdate = NSScreen.screens;
|
||||
qCDebug(lcQpaScreen, "Display reconfigure transaction started"
|
||||
" with screen configuration %p", s_screenConfigurationBeforeUpdate);
|
||||
|
||||
static void (^tryScreenUpdate)();
|
||||
tryScreenUpdate = ^void () {
|
||||
qCDebug(lcQpaScreen) << "Attempting screen update from runloop block";
|
||||
if (!updateScreensIfNeeded())
|
||||
CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, tryScreenUpdate);
|
||||
};
|
||||
CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, tryScreenUpdate);
|
||||
}
|
||||
QCocoaScreen::add(displayId);
|
||||
} else if ((flags & kCGDisplayRemoveFlag) || !CGDisplayIsActive(displayId)) {
|
||||
cocoaScreen->remove();
|
||||
} else {
|
||||
// Detect changes to the primary screen immediately, instead of
|
||||
// waiting for a display reconfigure with kCGDisplaySetMainFlag.
|
||||
// This ensures that any property updates to the other screens
|
||||
// will be in reference to the correct primary screen.
|
||||
QCocoaScreen *mainDisplay = QCocoaScreen::get(CGMainDisplayID());
|
||||
if (QGuiApplication::primaryScreen()->handle() != mainDisplay) {
|
||||
mainDisplay->updateProperties();
|
||||
qCInfo(lcQpaScreen) << "Primary screen changed to" << mainDisplay;
|
||||
QWindowSystemInterface::handlePrimaryScreenChanged(mainDisplay);
|
||||
Q_ASSERT_X(displayReconfigurationsInProgress, "QCococaScreen",
|
||||
"Display configuration transactions are expected to be balanced");
|
||||
|
||||
if (!--displayReconfigurationsInProgress) {
|
||||
qCDebug(lcQpaScreen) << "Display reconfigure transaction completed";
|
||||
// We optimistically update now, in case the NSScreens have changed
|
||||
updateScreensIfNeeded();
|
||||
}
|
||||
|
||||
if (cocoaScreen == mainDisplay)
|
||||
return; // Already reconfigured
|
||||
|
||||
cocoaScreen->updateProperties();
|
||||
qCInfo(lcQpaScreen) << "Reconfigured" << cocoaScreen;
|
||||
}
|
||||
}, nullptr);
|
||||
|
||||
static QMacNotificationObserver screenParamaterObserver(NSApplication.sharedApplication,
|
||||
NSApplicationDidChangeScreenParametersNotification, [&]() {
|
||||
qCDebug(lcQpaScreen) << "Received screen parameter change notification";
|
||||
updateScreensIfNeeded(); // As a last resort we update screens here
|
||||
});
|
||||
}
|
||||
|
||||
bool QCocoaScreen::updateScreensIfNeeded()
|
||||
{
|
||||
if (!s_screenConfigurationBeforeUpdate) {
|
||||
qCDebug(lcQpaScreen) << "QScreens have already been updated, all good";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (s_screenConfigurationBeforeUpdate == NSScreen.screens) {
|
||||
qCDebug(lcQpaScreen) << "Still waiting for NSScreen configuration change";
|
||||
return false;
|
||||
}
|
||||
|
||||
qCDebug(lcQpaScreen, "NSScreen configuration changed to %p", NSScreen.screens);
|
||||
updateScreens();
|
||||
|
||||
s_screenConfigurationBeforeUpdate = nil;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Update the list of available QScreens, and the properties of existing screens.
|
||||
|
||||
At this point we rely on the NSScreen.screens to be up to date.
|
||||
*/
|
||||
void QCocoaScreen::updateScreens()
|
||||
{
|
||||
uint32_t displayCount = 0;
|
||||
if (CGGetOnlineDisplayList(0, nullptr, &displayCount) != kCGErrorSuccess)
|
||||
qFatal("Failed to get number of online displays");
|
||||
|
||||
QVector<CGDirectDisplayID> onlineDisplays(displayCount);
|
||||
if (CGGetOnlineDisplayList(displayCount, onlineDisplays.data(), &displayCount) != kCGErrorSuccess)
|
||||
qFatal("Failed to get online displays");
|
||||
|
||||
qCInfo(lcQpaScreen) << "Updating screens with" << displayCount
|
||||
<< "online displays:" << onlineDisplays;
|
||||
|
||||
// TODO: Verify whether we can always assume the main display is first
|
||||
int mainDisplayIndex = onlineDisplays.indexOf(CGMainDisplayID());
|
||||
if (mainDisplayIndex < 0) {
|
||||
qCWarning(lcQpaScreen) << "Main display not in list of online displays!";
|
||||
} else if (mainDisplayIndex > 0) {
|
||||
qCWarning(lcQpaScreen) << "Main display not first display, making sure it is";
|
||||
onlineDisplays.move(mainDisplayIndex, 0);
|
||||
}
|
||||
|
||||
for (CGDirectDisplayID displayId : onlineDisplays) {
|
||||
Q_ASSERT(CGDisplayIsOnline(displayId));
|
||||
|
||||
if (CGDirectDisplayID mirroring = CGDisplayMirrorsDisplay(displayId))
|
||||
continue;
|
||||
|
||||
// A single physical screen can map to multiple displays IDs,
|
||||
// depending on which GPU is in use or which physical port the
|
||||
// screen is connected to. By mapping the display ID to a UUID,
|
||||
// which are shared between displays that target the same screen,
|
||||
// we can pick an existing QScreen to update instead of needlessly
|
||||
// adding and removing QScreens.
|
||||
QCFType<CFUUIDRef> uuid = CGDisplayCreateUUIDFromDisplayID(displayId);
|
||||
Q_ASSERT(uuid);
|
||||
|
||||
if (QCocoaScreen *existingScreen = QCocoaScreen::get(uuid)) {
|
||||
existingScreen->update(displayId);
|
||||
qCInfo(lcQpaScreen) << "Updated" << existingScreen;
|
||||
if (CGDisplayIsMain(displayId) && existingScreen != qGuiApp->primaryScreen()->handle()) {
|
||||
qCInfo(lcQpaScreen) << "Primary screen changed to" << existingScreen;
|
||||
QWindowSystemInterface::handlePrimaryScreenChanged(existingScreen);
|
||||
}
|
||||
} else {
|
||||
QCocoaScreen::add(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
for (QScreen *screen : QGuiApplication::screens()) {
|
||||
QCocoaScreen *platformScreen = static_cast<QCocoaScreen*>(screen->handle());
|
||||
if (!platformScreen->isOnline())
|
||||
platformScreen->remove();
|
||||
else if (platformScreen->isMirroring())
|
||||
platformScreen->remove();
|
||||
}
|
||||
}
|
||||
|
||||
void QCocoaScreen::add(CGDirectDisplayID displayId)
|
||||
{
|
||||
const bool isPrimary = CGDisplayIsMain(displayId);
|
||||
QCocoaScreen *cocoaScreen = new QCocoaScreen(displayId);
|
||||
qCInfo(lcQpaScreen) << "Adding" << cocoaScreen;
|
||||
QWindowSystemInterface::handleScreenAdded(cocoaScreen, CGDisplayIsMain(displayId));
|
||||
qCInfo(lcQpaScreen) << "Adding" << cocoaScreen
|
||||
<< (isPrimary ? "as new primary screen" : "");
|
||||
QWindowSystemInterface::handleScreenAdded(cocoaScreen, isPrimary);
|
||||
}
|
||||
|
||||
QCocoaScreen::QCocoaScreen(CGDirectDisplayID displayId)
|
||||
: QPlatformScreen(), m_displayId(displayId)
|
||||
{
|
||||
updateProperties();
|
||||
update(m_displayId);
|
||||
m_cursor = new QCocoaCursor;
|
||||
}
|
||||
|
||||
@ -127,8 +245,6 @@ void QCocoaScreen::cleanupScreens()
|
||||
|
||||
void QCocoaScreen::remove()
|
||||
{
|
||||
m_displayId = 0; // Prevent stale references during removal
|
||||
|
||||
// This may result in the application responding to QGuiApplication::screenRemoved
|
||||
// by moving the window to another screen, either by setGeometry, or by setScreen.
|
||||
// If the window isn't moved by the application, Qt will as a fallback move it to
|
||||
@ -140,6 +256,7 @@ void QCocoaScreen::remove()
|
||||
// QCocoaWindow::windowDidChangeScreen. At that point the window will appear to have
|
||||
// already changed its screen, but that's only true if comparing the Qt screens,
|
||||
// not when comparing the NSScreens.
|
||||
qCInfo(lcQpaScreen) << "Removing " << this;
|
||||
QWindowSystemInterface::handleScreenRemoved(this);
|
||||
}
|
||||
|
||||
@ -186,9 +303,14 @@ static QString displayName(CGDirectDisplayID displayID)
|
||||
return QString();
|
||||
}
|
||||
|
||||
void QCocoaScreen::updateProperties()
|
||||
void QCocoaScreen::update(CGDirectDisplayID displayId)
|
||||
{
|
||||
Q_ASSERT(m_displayId);
|
||||
if (displayId != m_displayId) {
|
||||
qCDebug(lcQpaScreen) << "Reconnecting" << this << "as display" << displayId;
|
||||
m_displayId = displayId;
|
||||
}
|
||||
|
||||
Q_ASSERT(isOnline());
|
||||
|
||||
const QRect previousGeometry = m_geometry;
|
||||
const QRect previousAvailableGeometry = m_availableGeometry;
|
||||
@ -326,8 +448,8 @@ struct DeferredDebugHelper
|
||||
|
||||
void QCocoaScreen::deliverUpdateRequests()
|
||||
{
|
||||
if (!m_displayId)
|
||||
return; // Screen removed
|
||||
if (!isOnline())
|
||||
return;
|
||||
|
||||
QMacAutoReleasePool pool;
|
||||
|
||||
@ -351,15 +473,6 @@ void QCocoaScreen::deliverUpdateRequests()
|
||||
// it on the main thread yet, because the processing of the update request is taking
|
||||
// too long, or because the update request was deferred due to window live resizing.
|
||||
qDeferredDebug(screenUpdates) << ", " << framesAheadOfDelivery << " frame(s) ahead";
|
||||
|
||||
// We skip the frame completely if we're live-resizing, to not put any extra
|
||||
// strain on the main thread runloop. Otherwise we assume we should push frames
|
||||
// as fast as possible, and hopefully the callback will be delivered on the
|
||||
// main thread just when the previous finished.
|
||||
if (qt_apple_sharedApplication().keyWindow.inLiveResize) {
|
||||
qDeferredDebug(screenUpdates) << "; waiting for main thread to catch up";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qDeferredDebug(screenUpdates) << "; signaling dispatch source";
|
||||
@ -547,15 +660,38 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height)
|
||||
return windowPixmap;
|
||||
}
|
||||
|
||||
bool QCocoaScreen::isOnline() const
|
||||
{
|
||||
// When a display is disconnected CGDisplayIsOnline and other CGDisplay
|
||||
// functions that take a displayId will not return false, but will start
|
||||
// returning -1 to signal that the displayId is invalid. Some functions
|
||||
// will also assert or even crash in this case, so it's important that
|
||||
// we double check if a display is online before calling other functions.
|
||||
auto isOnline = CGDisplayIsOnline(m_displayId);
|
||||
static const uint32_t kCGDisplayIsDisconnected = int32_t(-1);
|
||||
return isOnline != kCGDisplayIsDisconnected && isOnline;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns true if a screen is mirroring another screen
|
||||
*/
|
||||
bool QCocoaScreen::isMirroring() const
|
||||
{
|
||||
if (!isOnline())
|
||||
return false;
|
||||
|
||||
return CGDisplayMirrorsDisplay(m_displayId);
|
||||
}
|
||||
|
||||
/*!
|
||||
The screen used as a reference for global window geometry
|
||||
*/
|
||||
QCocoaScreen *QCocoaScreen::primaryScreen()
|
||||
{
|
||||
auto screen = static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle());
|
||||
Q_ASSERT_X(screen == get(CGMainDisplayID()), "QCocoaScreen",
|
||||
"The application's primary screen should always be in sync with the main display");
|
||||
return screen;
|
||||
// Note: The primary screen that Qt knows about may not match the current CGMainDisplayID()
|
||||
// if macOS has not yet been able to inform us that the main display has changed, but we
|
||||
// will update the primary screen accordingly once the reconfiguration callback comes in.
|
||||
return static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle());
|
||||
}
|
||||
|
||||
QList<QPlatformScreen*> QCocoaScreen::virtualSiblings() const
|
||||
@ -571,6 +707,12 @@ QList<QPlatformScreen*> QCocoaScreen::virtualSiblings() const
|
||||
|
||||
QCocoaScreen *QCocoaScreen::get(NSScreen *nsScreen)
|
||||
{
|
||||
if (s_screenConfigurationBeforeUpdate) {
|
||||
qCWarning(lcQpaScreen) << "Trying to resolve screen while waiting for screen reconfigure!";
|
||||
if (!updateScreensIfNeeded())
|
||||
qCWarning(lcQpaScreen) << "Failed to do last minute screen update. Expect crashes.";
|
||||
}
|
||||
|
||||
return get(nsScreen.qt_displayId);
|
||||
}
|
||||
|
||||
@ -585,23 +727,34 @@ QCocoaScreen *QCocoaScreen::get(CGDirectDisplayID displayId)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QCocoaScreen *QCocoaScreen::get(CFUUIDRef uuid)
|
||||
{
|
||||
for (QScreen *screen : QGuiApplication::screens()) {
|
||||
auto *platformScreen = static_cast<QCocoaScreen*>(screen->handle());
|
||||
if (!platformScreen->isOnline())
|
||||
continue;
|
||||
|
||||
auto displayId = platformScreen->displayId();
|
||||
QCFType<CFUUIDRef> candidateUuid(CGDisplayCreateUUIDFromDisplayID(displayId));
|
||||
Q_ASSERT(candidateUuid);
|
||||
|
||||
if (candidateUuid == uuid)
|
||||
return platformScreen;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NSScreen *QCocoaScreen::nativeScreen() const
|
||||
{
|
||||
if (!m_displayId)
|
||||
return nil; // The display has been disconnected
|
||||
|
||||
// A single display may have different displayIds depending on
|
||||
// which GPU is in use or which physical port the display is
|
||||
// connected to. By comparing UUIDs instead of display IDs we
|
||||
// ensure that we always pick up the appropriate NSScreen.
|
||||
QCFType<CFUUIDRef> uuid = CGDisplayCreateUUIDFromDisplayID(m_displayId);
|
||||
|
||||
for (NSScreen *screen in [NSScreen screens]) {
|
||||
if (CGDisplayCreateUUIDFromDisplayID(screen.qt_displayId) == uuid)
|
||||
for (NSScreen *screen in NSScreen.screens) {
|
||||
if (screen.qt_displayId == m_displayId)
|
||||
return screen;
|
||||
}
|
||||
|
||||
qCWarning(lcQpaScreen) << "Could not find NSScreen for display ID" << m_displayId;
|
||||
return nil;
|
||||
}
|
||||
|
||||
@ -636,16 +789,29 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen)
|
||||
debug.nospace();
|
||||
debug << "QCocoaScreen(" << (const void *)screen;
|
||||
if (screen) {
|
||||
debug << ", geometry=" << screen->geometry();
|
||||
debug << ", " << screen->name();
|
||||
if (screen->isOnline()) {
|
||||
if (CGDisplayIsAsleep(screen->displayId()))
|
||||
debug << ", Sleeping";
|
||||
if (auto mirroring = CGDisplayMirrorsDisplay(screen->displayId()))
|
||||
debug << ", mirroring=" << mirroring;
|
||||
} else {
|
||||
debug << ", Offline";
|
||||
}
|
||||
debug << ", " << screen->geometry();
|
||||
debug << ", dpr=" << screen->devicePixelRatio();
|
||||
debug << ", name=" << screen->name();
|
||||
debug << ", native=" << screen->nativeScreen();
|
||||
debug << ", displayId=" << screen->displayId();
|
||||
|
||||
if (auto nativeScreen = screen->nativeScreen())
|
||||
debug << ", " << nativeScreen;
|
||||
}
|
||||
debug << ')';
|
||||
return debug;
|
||||
}
|
||||
#endif // !QT_NO_DEBUG_STREAM
|
||||
|
||||
#include "qcocoascreen.moc"
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@implementation NSScreen (QtExtras)
|
||||
|
Loading…
Reference in New Issue
Block a user