summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/bsdfb/qbsdfbscreen.cpp2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.mm24
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm14
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h17
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm105
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h60
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm567
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h7
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm123
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h7
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm58
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp21
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp18
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp5
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp21
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp19
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp166
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp9
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp27
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp36
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h11
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp24
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp15
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp23
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h14
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp21
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h7
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp14
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp429
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h60
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp121
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h30
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp52
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h33
-rw-r--r--src/plugins/platforms/ios/kernel.pro5
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro6
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm3
-rw-r--r--src/plugins/platforms/ios/qiosmessagedialog.mm3
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm7
-rw-r--r--src/plugins/platforms/ios/qiostextinputoverlay.mm4
-rw-r--r--src/plugins/platforms/ios/quiview.mm3
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp2
-rw-r--r--src/plugins/platforms/qnx/qnx.pro14
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp8
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h4
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h8
-rw-r--r--src/plugins/platforms/vnc/qvncscreen.cpp13
-rw-r--r--src/plugins/platforms/vnc/qvncscreen.h4
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp17
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp27
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp50
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h1
-rw-r--r--src/plugins/platforms/windows/windows.pri4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp45
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h2
68 files changed, 1015 insertions, 1418 deletions
diff --git a/src/plugins/platforms/bsdfb/qbsdfbscreen.cpp b/src/plugins/platforms/bsdfb/qbsdfbscreen.cpp
index 0ef57d37e5..03c6f0dbe9 100644
--- a/src/plugins/platforms/bsdfb/qbsdfbscreen.cpp
+++ b/src/plugins/platforms/bsdfb/qbsdfbscreen.cpp
@@ -243,7 +243,7 @@ QRegion QBsdFbScreen::doRedraw()
const auto rects = touched.rects();
for (const QRect &rect : rects)
- m_blitter->drawImage(rect, *mScreenImage, rect);
+ m_blitter->drawImage(rect, mScreenImage, rect);
return touched;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm
index c5ae4bc2bf..3b950efa55 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm
@@ -76,6 +76,7 @@
#include "qcocoaintrospection.h"
#include "qcocoaapplicationdelegate.h"
#include "qcocoahelpers.h"
+#include "qcocoawindow.h"
#include <qguiapplication.h>
#include <qdebug.h>
@@ -148,6 +149,21 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE
@end
+static void qt_maybeSendKeyEquivalentUpEvent(NSEvent *event)
+{
+ // Cocoa is known for not sending key up events for key
+ // equivalents, regardless of whether it's an actual
+ // recognized key equivalent. We decide to force fate
+ // and forward the key event to the key (focus) window.
+ // However, non-Qt windows will not (and should not) get
+ // any special treatment, only QWindow-owned NSWindows.
+ if (event.type == NSKeyUp && (event.modifierFlags & NSCommandKeyMask)) {
+ NSWindow *targetWindow = event.window;
+ if ([targetWindow.class conformsToProtocol:@protocol(QNSWindowProtocol)])
+ [targetWindow sendEvent:event];
+ }
+}
+
@implementation QT_MANGLE_NAMESPACE(QNSApplication)
- (void)QT_MANGLE_NAMESPACE(qt_sendEvent_original):(NSEvent *)event
@@ -164,16 +180,20 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE
// be called instead of sendEvent if redirection occurs.
// 'self' will then be an instance of NSApplication
// (and not QNSApplication)
- if (![NSApp QT_MANGLE_NAMESPACE(qt_filterEvent):event])
+ if (![NSApp QT_MANGLE_NAMESPACE(qt_filterEvent):event]) {
[self QT_MANGLE_NAMESPACE(qt_sendEvent_original):event];
+ qt_maybeSendKeyEquivalentUpEvent(event);
+ }
}
- (void)sendEvent:(NSEvent *)event
{
// This method will be called if
// no redirection occurs
- if (![NSApp QT_MANGLE_NAMESPACE(qt_filterEvent):event])
+ if (![NSApp QT_MANGLE_NAMESPACE(qt_filterEvent):event]) {
[super sendEvent:event];
+ qt_maybeSendKeyEquivalentUpEvent(event);
+ }
}
@end
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index a74995319b..1d7ad772dc 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -57,7 +57,8 @@ QCocoaBackingStore::~QCocoaBackingStore()
QImage::Format QCocoaBackingStore::format() const
{
- if (static_cast<QCocoaWindow *>(window()->handle())->m_drawContentBorderGradient)
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
+ if (cocoaWindow && cocoaWindow->m_drawContentBorderGradient)
return QImage::Format_ARGB32_Premultiplied;
return QRasterBackingStore::format();
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index 7d11023b78..de4fa95530 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -132,7 +132,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
QPixmap pm = dragPixmap(m_drag, hotSpot);
QSize pmDeviceIndependentSize = pm.size() / pm.devicePixelRatio();
NSImage *nsimage = qt_mac_create_nsimage(pm);
- [nsimage setSize:pmDeviceIndependentSize.toCGSize()];
+ [nsimage setSize:NSSizeFromCGSize(pmDeviceIndependentSize.toCGSize())];
QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND);
m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 234da57f59..41a809cdd2 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -63,6 +63,7 @@
#include <stdlib.h>
#include <qabstracteventdispatcher.h>
#include <qsysinfo.h>
+#include <qoperatingsystemversion.h>
#include <qglobal.h>
#include <QDir>
@@ -164,7 +165,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
[mSavePanel setDelegate:self];
#if QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_11)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_11)
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::OSXElCapitan)
mOpenPanel.accessoryViewDisclosed = YES;
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 01fbb7bad2..fa0365dbf7 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -160,10 +160,8 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
*/
QNSView *qnsview_cast(NSView *view)
{
- if (![view isKindOfClass:[QNSView class]]) {
- qCWarning(lcQpaCocoaWindow) << "NSView is not QNSView, consider checking for Qt::ForeignWindow";
+ if (![view isKindOfClass:[QNSView class]])
return nil;
- }
return static_cast<QNSView *>(view);
}
@@ -235,13 +233,13 @@ QString qt_mac_applicationName()
return appName;
}
-int qt_mac_mainScreenHeight()
+int qt_mac_primaryScreenHeight()
{
QMacAutoReleasePool pool;
NSArray *screens = [NSScreen screens];
if ([screens count] > 0) {
- // The first screen in the screens array is documented
- // to have the (0,0) origin.
+ // The first screen in the screens array is documented to
+ // have the (0,0) origin and is designated the primary screen.
NSRect screenFrame = [[screens objectAtIndex: 0] frame];
return screenFrame.size.height;
}
@@ -250,12 +248,12 @@ int qt_mac_mainScreenHeight()
int qt_mac_flipYCoordinate(int y)
{
- return qt_mac_mainScreenHeight() - y;
+ return qt_mac_primaryScreenHeight() - y;
}
qreal qt_mac_flipYCoordinate(qreal y)
{
- return qt_mac_mainScreenHeight() - y;
+ return qt_mac_primaryScreenHeight() - y;
}
QPointF qt_mac_flipPoint(const NSPoint &p)
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 32f6fe0af1..5cf8e7d237 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QCocoaScreen : public QPlatformScreen
{
public:
- QCocoaScreen(int screenIndex);
+ QCocoaScreen(NSScreen *screen);
~QCocoaScreen();
// ----------------------------------------------------
@@ -84,11 +84,20 @@ public:
// ----------------------------------------------------
// Additional methods
void setVirtualSiblings(const QList<QPlatformScreen *> &siblings) { m_siblings = siblings; }
- NSScreen *osScreen() const;
+ NSScreen *nsScreen() const;
void updateGeometry();
+ QPointF mapToNative(const QPointF &pos) const { return flipCoordinate(pos); }
+ QRectF mapToNative(const QRectF &rect) const { return flipCoordinate(rect); }
+ QPointF mapFromNative(const QPointF &pos) const { return flipCoordinate(pos); }
+ QRectF mapFromNative(const QRectF &rect) const { return flipCoordinate(rect); }
+
+private:
+ QPointF flipCoordinate(const QPointF &pos) const;
+ QRectF flipCoordinate(const QRectF &rect) const;
+
public:
- int m_screenIndex;
+ NSScreen *m_nsScreen;
QRect m_geometry;
QRect m_availableGeometry;
QDpi m_logicalDpi;
@@ -144,7 +153,7 @@ public:
QList<int> possibleKeys(const QKeyEvent *event) const Q_DECL_OVERRIDE;
void updateScreens();
- QCocoaScreen *screenAtIndex(int index);
+ QCocoaScreen *screenForNSScreen(NSScreen *nsScreen);
void setToolbar(QWindow *window, NSToolbar *toolbar);
NSToolbar *toolbar(QWindow *window) const;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 92fffb4d15..7e9f554520 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -69,8 +69,8 @@ static void initResources()
QT_BEGIN_NAMESPACE
-QCocoaScreen::QCocoaScreen(int screenIndex) :
- QPlatformScreen(), m_screenIndex(screenIndex), m_refreshRate(60.0)
+QCocoaScreen::QCocoaScreen(NSScreen *screen)
+ : QPlatformScreen(), m_nsScreen(screen), m_refreshRate(60.0)
{
updateGeometry();
m_cursor = new QCocoaCursor;
@@ -81,46 +81,63 @@ QCocoaScreen::~QCocoaScreen()
delete m_cursor;
}
-NSScreen *QCocoaScreen::osScreen() const
+NSScreen *QCocoaScreen::nsScreen() const
{
- NSArray *screens = [NSScreen screens];
- return ((NSUInteger)m_screenIndex < [screens count]) ? [screens objectAtIndex:m_screenIndex] : nil;
+ return m_nsScreen;
+}
+
+/*!
+ Flips the Y coordinate of the point between quadrant I and IV.
+
+ The native coordinate system on macOS uses quadrant I, with origin
+ in bottom left, and Qt uses quadrant IV, with origin in top left.
+
+ By flippig the Y coordinate, we can map the position between the
+ two coordinate systems.
+*/
+QPointF QCocoaScreen::flipCoordinate(const QPointF &pos) const
+{
+ return QPointF(pos.x(), m_geometry.height() - pos.y());
+}
+
+/*!
+ Flips the Y coordinate of the rectangle between quadrant I and IV.
+
+ The native coordinate system on macOS uses quadrant I, with origin
+ in bottom left, and Qt uses quadrant IV, with origin in top left.
+
+ By flippig the Y coordinate, we can map the rectangle between the
+ two coordinate systems.
+*/
+QRectF QCocoaScreen::flipCoordinate(const QRectF &rect) const
+{
+ return QRectF(flipCoordinate(rect.topLeft() + QPoint(0, rect.height())), rect.size());
}
void QCocoaScreen::updateGeometry()
{
- NSScreen *nsScreen = osScreen();
- if (!nsScreen)
+ if (!m_nsScreen)
return;
- NSRect frameRect = [nsScreen frame];
+ // At this point the geometry is in native coordinates, but the size
+ // is correct, which we take advantage of next when we map the native
+ // coordinates to the Qt coordinate system.
+ m_geometry = QRectF::fromCGRect(NSRectToCGRect(m_nsScreen.frame)).toRect();
+ m_availableGeometry = QRectF::fromCGRect(NSRectToCGRect(m_nsScreen.visibleFrame)).toRect();
- if (m_screenIndex == 0) {
- m_geometry = QRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height);
- // This is the primary screen, the one that contains the menubar. Its origin should be
- // (0, 0), and it's the only one whose available geometry differs from its full geometry.
- NSRect visibleRect = [nsScreen visibleFrame];
- m_availableGeometry = QRect(visibleRect.origin.x,
- frameRect.size.height - (visibleRect.origin.y + visibleRect.size.height), // invert y
- visibleRect.size.width, visibleRect.size.height);
- } else {
- // NSScreen origin is at the bottom-left corner, QScreen is at the top-left corner.
- // When we get the NSScreen frame rect, we need to re-align its origin y coordinate
- // w.r.t. the primary screen, whose origin is (0, 0).
- NSRect r = [[[NSScreen screens] objectAtIndex:0] frame];
- QRect referenceScreenGeometry = QRect(r.origin.x, r.origin.y, r.size.width, r.size.height);
- m_geometry = QRect(frameRect.origin.x,
- referenceScreenGeometry.height() - (frameRect.origin.y + frameRect.size.height),
- frameRect.size.width, frameRect.size.height);
-
- // Not primary screen. See above.
- m_availableGeometry = m_geometry;
- }
+ // The reference screen for the geometry is always the primary screen, but since
+ // we may be in the process of creating and registering the primary screen, we
+ // must special-case that and assign it direcly.
+ QCocoaScreen *primaryScreen = (m_nsScreen == [[NSScreen screens] firstObject]) ?
+ this : static_cast<QCocoaScreen*>(QGuiApplication::primaryScreen()->handle());
+
+ m_geometry = primaryScreen->mapFromNative(m_geometry).toRect();
+ m_availableGeometry = primaryScreen->mapFromNative(m_availableGeometry).toRect();
m_format = QImage::Format_RGB32;
- m_depth = NSBitsPerPixelFromDepth([nsScreen depth]);
+ m_depth = NSBitsPerPixelFromDepth([m_nsScreen depth]);
- NSDictionary *devDesc = [nsScreen deviceDescription];
+ NSDictionary *devDesc = [m_nsScreen deviceDescription];
CGDirectDisplayID dpy = [[devDesc objectForKey:@"NSScreenNumber"] unsignedIntValue];
CGSize size = CGDisplayScreenSize(dpy);
m_physicalSize = QSizeF(size.width, size.height);
@@ -147,8 +164,7 @@ void QCocoaScreen::updateGeometry()
qreal QCocoaScreen::devicePixelRatio() const
{
QMacAutoReleasePool pool;
- NSScreen * screen = osScreen();
- return qreal(screen ? [screen backingScaleFactor] : 1.0);
+ return qreal(m_nsScreen ? [m_nsScreen backingScaleFactor] : 1.0);
}
QPlatformScreen::SubpixelAntialiasingType QCocoaScreen::subpixelAntialiasingTypeHint() const
@@ -423,7 +439,7 @@ void QCocoaIntegration::updateScreens()
// NSScreen documentation says do not cache the array returned from [NSScreen screens].
// However in practice, we can identify a screen by its pointer: if resolution changes,
// the NSScreen object will be the same instance, just with different values.
- if (existingScr->osScreen() == scr) {
+ if (existingScr->nsScreen() == scr) {
screen = existingScr;
break;
}
@@ -431,7 +447,7 @@ void QCocoaIntegration::updateScreens()
remainingScreens.remove(screen);
screen->updateGeometry();
} else {
- screen = new QCocoaScreen(i);
+ screen = new QCocoaScreen(scr);
mScreens.append(screen);
screenAdded(screen);
}
@@ -451,16 +467,21 @@ void QCocoaIntegration::updateScreens()
}
}
-QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
+QCocoaScreen *QCocoaIntegration::screenForNSScreen(NSScreen *nsScreen)
{
- if (index >= mScreens.count())
+ NSUInteger index = [[NSScreen screens] indexOfObject:nsScreen];
+ if (index == NSNotFound)
+ return 0;
+
+ if (index >= unsigned(mScreens.count()))
updateScreens();
- // It is possible that the screen got removed while updateScreens was called
- // so we do a sanity check to be certain
- if (index >= mScreens.count())
- return 0;
- return mScreens.at(index);
+ for (QCocoaScreen *screen : mScreens) {
+ if (screen->nsScreen() == nsScreen)
+ return screen;
+ }
+
+ return 0;
}
bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 16639fd8b1..ac5f1a6851 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -96,6 +96,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindowHelper);
@property (nonatomic, readonly) QNSWindowHelper *helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw;
@@ -111,6 +112,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindow);
@property (nonatomic, readonly) QNSWindowHelper *helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw;
@@ -141,6 +143,13 @@ QT_BEGIN_NAMESPACE
// See the qt_on_cocoa manual tests for a working example, located
// in tests/manual/cocoa at the time of writing.
+#ifdef Q_MOC_RUN
+#define Q_NOTIFICATION_HANDLER(notification) Q_INVOKABLE Q_COCOA_NOTIFICATION_##notification
+#else
+#define Q_NOTIFICATION_HANDLER(notification)
+#define Q_NOTIFICATION_PREFIX QT_STRINGIFY2(Q_COCOA_NOTIFICATION_)
+#endif
+
class QCocoaMenuBar;
class QCocoaWindow : public QObject, public QPlatformWindow
@@ -187,12 +196,25 @@ public:
void setEmbeddedInForeignView(bool subwindow);
- void windowWillMove();
- void windowDidMove();
- void windowDidResize();
- void windowDidEndLiveResize();
+ Q_NOTIFICATION_HANDLER(NSWindowWillMoveNotification) void windowWillMove();
+ Q_NOTIFICATION_HANDLER(NSWindowDidMoveNotification) void windowDidMove();
+ Q_NOTIFICATION_HANDLER(NSWindowDidResizeNotification) void windowDidResize();
+ Q_NOTIFICATION_HANDLER(NSViewFrameDidChangeNotification) void viewDidChangeFrame();
+ Q_NOTIFICATION_HANDLER(NSViewGlobalFrameDidChangeNotification) void viewDidChangeGlobalFrame();
+ Q_NOTIFICATION_HANDLER(NSWindowDidEndLiveResizeNotification) void windowDidEndLiveResize();
+ Q_NOTIFICATION_HANDLER(NSWindowDidBecomeKeyNotification) void windowDidBecomeKey();
+ Q_NOTIFICATION_HANDLER(NSWindowDidResignKeyNotification) void windowDidResignKey();
+ Q_NOTIFICATION_HANDLER(NSWindowDidMiniaturizeNotification) void windowDidMiniaturize();
+ Q_NOTIFICATION_HANDLER(NSWindowDidDeminiaturizeNotification) void windowDidDeminiaturize();
+ Q_NOTIFICATION_HANDLER(NSWindowDidEnterFullScreenNotification) void windowDidEnterFullScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidExitFullScreenNotification) void windowDidExitFullScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidOrderOnScreenAndFinishAnimatingNotification) void windowDidOrderOnScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidChangeOcclusionStateNotification) void windowDidChangeOcclusionState();
+ Q_NOTIFICATION_HANDLER(NSWindowDidChangeScreenNotification) void windowDidChangeScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowWillCloseNotification) void windowWillClose();
+
bool windowShouldClose();
- void windowWillClose();
bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const;
void setSynchedWindowStateFromWindow();
@@ -239,19 +261,33 @@ public:
static QPoint bottomLeftClippedByNSWindowOffsetStatic(QWindow *window);
QPoint bottomLeftClippedByNSWindowOffset() const;
+
+ enum RecreationReason {
+ RecreationNotNeeded = 0,
+ ParentChanged = 0x1,
+ MissingWindow = 0x2,
+ WindowModalityChanged = 0x4,
+ ChildNSWindowChanged = 0x8,
+ ContentViewChanged = 0x10,
+ PanelChanged = 0x20,
+ };
+ Q_DECLARE_FLAGS(RecreationReasons, RecreationReason)
+ Q_FLAG(RecreationReasons)
+
protected:
- void recreateWindow(const QPlatformWindow *parentWindow);
- QCocoaNSWindow *createNSWindow();
- void setNSWindow(QCocoaNSWindow *window);
+ bool isChildNSWindow() const;
+ bool isContentView() const;
- bool shouldUseNSPanel();
+ void foreachChildNSWindow(void (^block)(QCocoaWindow *));
+
+ void recreateWindowIfNeeded();
+ QCocoaNSWindow *createNSWindow(bool shouldBeChildNSWindow, bool shouldBePanel);
QRect nativeWindowGeometry() const;
QCocoaWindow *parentCocoaWindow() const;
void syncWindowState(Qt::WindowState newState);
void reinsertChildWindow(QCocoaWindow *child);
void removeChildWindow(QCocoaWindow *child);
- bool isNativeWindowTypeInconsistent();
// private:
public: // for QNSView
@@ -268,10 +304,6 @@ public: // for QNSView
bool m_viewIsEmbedded; // true if the m_view is actually embedded in a "foreign" NSView hiearchy
bool m_viewIsToBeEmbedded; // true if the m_view is intended to be embedded in a "foreign" NSView hiearchy
- QCocoaWindow *m_parentCocoaWindow;
- bool m_isNSWindowChild; // this window is a non-top level QWindow with a NSWindow.
- QList<QCocoaWindow *> m_childWindows;
-
Qt::WindowFlags m_windowFlags;
bool m_effectivelyMaximized;
Qt::WindowState m_synchedWindowState;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 602da0a175..0b33b9255f 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -130,8 +130,7 @@ static void qt_closePopups()
[forwardView mouseDragged:theEvent];
}
}
-
- if (!pw->m_isNSWindowChild && theEvent.type == NSLeftMouseDown) {
+ if (pw->window()->isTopLevel() && theEvent.type == NSLeftMouseDown) {
pw->m_forwardWindow.clear();
}
}
@@ -202,13 +201,14 @@ static void qt_closePopups()
@synthesize helper = _helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw
{
self = [super initWithContentRect:contentRect
styleMask:windowStyle
backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is
+ defer:NO screen:screen]; // Deferring window creation breaks OpenGL (the GL context is
// set up before the window is shown and needs a proper window)
if (self) {
@@ -222,7 +222,7 @@ static void qt_closePopups()
// Prevent child NSWindows from becoming the key window in
// order keep the active apperance of the top-level window.
QCocoaWindow *pw = self.helper.platformWindow;
- if (!pw || pw->m_isNSWindowChild)
+ if (!pw || !pw->window()->isTopLevel())
return NO;
if (pw->shouldRefuseKeyWindowAndFirstResponder())
@@ -241,7 +241,7 @@ static void qt_closePopups()
// Windows with a transient parent (such as combobox popup windows)
// cannot become the main window:
QCocoaWindow *pw = self.helper.platformWindow;
- if (!pw || pw->m_isNSWindowChild || pw->window()->transientParent())
+ if (!pw || !pw->window()->isTopLevel() || pw->window()->transientParent())
canBecomeMain = NO;
return canBecomeMain;
@@ -284,13 +284,14 @@ static void qt_closePopups()
@synthesize helper = _helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw
{
self = [super initWithContentRect:contentRect
styleMask:windowStyle
backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is
+ defer:NO screen:screen]; // Deferring window creation breaks OpenGL (the GL context is
// set up before the window is shown and needs a proper window)
if (self) {
@@ -343,6 +344,63 @@ static void qt_closePopups()
@end
+static void qRegisterNotificationCallbacks()
+{
+ static const QLatin1String notificationHandlerPrefix(Q_NOTIFICATION_PREFIX);
+
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+
+ const QMetaObject *metaObject = QMetaType::metaObjectForType(qRegisterMetaType<QCocoaWindow*>());
+ Q_ASSERT(metaObject);
+
+ for (int i = 0; i < metaObject->methodCount(); ++i) {
+ QMetaMethod method = metaObject->method(i);
+ const QString methodTag = QString::fromLatin1(method.tag());
+ if (!methodTag.startsWith(notificationHandlerPrefix))
+ continue;
+
+ const QString notificationName = methodTag.mid(notificationHandlerPrefix.size());
+ [center addObserverForName:notificationName.toNSString() object:nil queue:nil
+ usingBlock:^(NSNotification *notification) {
+
+ NSView *view = nullptr;
+ if ([notification.object isKindOfClass:[NSWindow class]]) {
+ NSWindow *window = notification.object;
+ // Only top level NSWindows should notify their QNSViews
+ if (window.parentWindow)
+ return;
+
+ if (!window.contentView)
+ return;
+
+ view = window.contentView;
+ } else if ([notification.object isKindOfClass:[NSView class]]) {
+ view = notification.object;
+ } else {
+ qCWarning(lcQpaCocoaWindow) << "Unhandled notifcation"
+ << notification.name << "for" << notification.object;
+ return;
+ }
+ Q_ASSERT(view);
+
+ QCocoaWindow *cocoaWindow = nullptr;
+ if (QNSView *qnsView = qnsview_cast(view))
+ cocoaWindow = qnsView.platformWindow;
+
+ // FIXME: Could be a foreign window, look up by iterating top level QWindows
+
+ if (!cocoaWindow)
+ return;
+
+ if (!method.invoke(cocoaWindow, Qt::DirectConnection)) {
+ qCWarning(lcQpaCocoaWindow) << "Failed to invoke NSNotification callback for"
+ << notification.name << "on" << cocoaWindow;
+ }
+ }];
+ }
+}
+Q_CONSTRUCTOR_FUNCTION(qRegisterNotificationCallbacks)
+
const int QCocoaWindow::NoAlertRequest = -1;
QCocoaWindow::QCocoaWindow(QWindow *tlw)
@@ -351,8 +409,6 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_nsWindow(0)
, m_viewIsEmbedded(false)
, m_viewIsToBeEmbedded(false)
- , m_parentCocoaWindow(0)
- , m_isNSWindowChild(false)
, m_effectivelyMaximized(false)
, m_synchedWindowState(Qt::WindowActive)
, m_windowModality(Qt::NonModal)
@@ -405,7 +461,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
[m_view setWantsLayer:enable];
}
setGeometry(tlw->geometry());
- recreateWindow(QPlatformWindow::parent());
+ recreateWindowIfNeeded();
tlw->setGeometry(geometry());
if (tlw->isTopLevel())
setWindowIcon(tlw->icon());
@@ -420,12 +476,10 @@ QCocoaWindow::~QCocoaWindow()
[m_nsWindow makeFirstResponder:nil];
[m_nsWindow setContentView:nil];
[m_nsWindow.helper detachFromPlatformWindow];
- if (m_isNSWindowChild) {
- if (m_parentCocoaWindow)
- m_parentCocoaWindow->removeChildWindow(this);
- } else if ([m_view superview]) {
+ if (m_view.window.parentWindow)
+ [m_view.window.parentWindow removeChildWindow:m_view.window];
+ else if ([m_view superview])
[m_view removeFromSuperview];
- }
removeMonitor();
@@ -440,10 +494,9 @@ QCocoaWindow::~QCocoaWindow()
QCocoaIntegration::instance()->popupWindowStack()->removeAll(this);
}
- foreach (QCocoaWindow *child, m_childWindows) {
- [m_nsWindow removeChildWindow:child->m_nsWindow];
- child->m_parentCocoaWindow = 0;
- }
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
+ [m_nsWindow removeChildWindow:childWindow->m_nsWindow];
+ });
[m_view release];
[m_nsWindow release];
@@ -491,7 +544,7 @@ QRect QCocoaWindow::geometry() const
NSRect screenRect = [[m_view window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
NSPoint screenPoint = screenRect.origin;
QPoint position = qt_mac_flipPoint(screenPoint).toPoint();
- QSize size = QRectF::fromCGRect([m_view bounds]).toRect().size();
+ QSize size = QRectF::fromCGRect(NSRectToCGRect([m_view bounds])).toRect().size();
return QRect(position, size);
}
@@ -512,9 +565,9 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
return;
}
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
QPlatformWindow::setGeometry(rect);
- NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSWindow *parentNSWindow = m_view.window.parentWindow;
NSRect parentWindowFrame = [parentNSWindow contentRectForFrameRect:parentNSWindow.frame];
clipWindow(parentWindowFrame);
@@ -536,14 +589,14 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
void QCocoaWindow::clipChildWindows()
{
- foreach (QCocoaWindow *childWindow, m_childWindows) {
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->clipWindow(m_nsWindow.frame);
- }
+ });
}
void QCocoaWindow::clipWindow(const NSRect &clipRect)
{
- if (!m_isNSWindowChild)
+ if (!isChildNSWindow())
return;
NSRect clippedWindowRect = NSZeroRect;
@@ -568,15 +621,15 @@ void QCocoaWindow::clipWindow(const NSRect &clipRect)
m_hiddenByClipping = false;
if (!m_hiddenByAncestor) {
[m_nsWindow orderFront:nil];
- m_parentCocoaWindow->reinsertChildWindow(this);
+ static_cast<QCocoaWindow *>(QPlatformWindow::parent())->reinsertChildWindow(this);
}
}
}
// recurse
- foreach (QCocoaWindow *childWindow, m_childWindows) {
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->clipWindow(clippedWindowRect);
- }
+ });
}
void QCocoaWindow::hide(bool becauseOfAncestor)
@@ -593,8 +646,9 @@ void QCocoaWindow::hide(bool becauseOfAncestor)
if (!visible) // Could have been clipped before
return;
- foreach (QCocoaWindow *childWindow, m_childWindows)
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->hide(true);
+ });
[m_nsWindow orderOut:nil];
}
@@ -604,20 +658,21 @@ void QCocoaWindow::show(bool becauseOfAncestor)
if ([m_nsWindow isVisible])
return;
- if (m_parentCocoaWindow && ![m_parentCocoaWindow->m_nsWindow isVisible]) {
+ if (m_view.window.parentWindow && !m_view.window.parentWindow.visible) {
m_hiddenByAncestor = true; // Parent still hidden, don't show now
} else if ((becauseOfAncestor == m_hiddenByAncestor) // Was NEITHER explicitly hidden
&& !m_hiddenByClipping) { // ... NOR clipped
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
m_hiddenByAncestor = false;
setCocoaGeometry(windowGeometry());
}
if (!m_hiddenByClipping) { // setCocoaGeometry() can change the clipping status
[m_nsWindow orderFront:nil];
- if (m_isNSWindowChild)
- m_parentCocoaWindow->reinsertChildWindow(this);
- foreach (QCocoaWindow *childWindow, m_childWindows)
+ if (isChildNSWindow())
+ static_cast<QCocoaWindow *>(QPlatformWindow::parent())->reinsertChildWindow(this);
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->show(true);
+ });
}
}
}
@@ -626,7 +681,7 @@ void QCocoaWindow::setVisible(bool visible)
{
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setVisible" << window() << visible;
- if (m_isNSWindowChild && m_hiddenByClipping)
+ if (isChildNSWindow() && m_hiddenByClipping)
return;
m_inSetVisible = true;
@@ -638,8 +693,7 @@ void QCocoaWindow::setVisible(bool visible)
if (visible) {
// We need to recreate if the modality has changed as the style mask will need updating
- if (m_windowModality != window()->modality() || isNativeWindowTypeInconsistent())
- recreateWindow(QPlatformWindow::parent());
+ recreateWindowIfNeeded();
// Register popup windows. The Cocoa platform plugin will forward mouse events
// to them and close them when needed.
@@ -700,8 +754,9 @@ void QCocoaWindow::setVisible(bool visible)
else
[m_nsWindow orderFront:nil];
- foreach (QCocoaWindow *childWindow, m_childWindows)
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->show(true);
+ });
} else {
show();
}
@@ -879,7 +934,7 @@ void QCocoaWindow::setWindowZoomButton(Qt::WindowFlags flags)
void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (m_nsWindow && !m_isNSWindowChild) {
+ if (m_nsWindow && !isChildNSWindow()) {
NSUInteger styleMask = windowStyleMask(flags);
NSInteger level = this->windowLevel(flags);
// While setting style mask we can have -updateGeometry calls on a content
@@ -983,19 +1038,16 @@ void QCocoaWindow::raise()
// ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
if (!m_nsWindow)
return;
- if (m_isNSWindowChild) {
- QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
- siblings.removeOne(this);
- siblings.append(this);
+ if (isChildNSWindow()) {
if (m_hiddenByClipping)
return;
}
if ([m_nsWindow isVisible]) {
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
// -[NSWindow orderFront:] doesn't work with attached windows.
// The only solution is to remove and add the child window.
// This will place it on top of all the other NSWindows.
- NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSWindow *parentNSWindow = m_view.window.parentWindow;
[parentNSWindow removeChildWindow:m_nsWindow];
[parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
} else {
@@ -1021,20 +1073,17 @@ void QCocoaWindow::lower()
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::lower" << window();
if (!m_nsWindow)
return;
- if (m_isNSWindowChild) {
- QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
- siblings.removeOne(this);
- siblings.prepend(this);
+ if (isChildNSWindow()) {
if (m_hiddenByClipping)
return;
}
if ([m_nsWindow isVisible]) {
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
// -[NSWindow orderBack:] doesn't work with attached windows.
// The only solution is to remove and add all the child windows except this one.
// This will keep the current window at the bottom while adding the others on top of it,
// hopefully in the same order (this is not documented anywhere in the Cocoa documentation).
- NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSWindow *parentNSWindow = m_view.window.parentWindow;
NSArray *children = [parentNSWindow.childWindows copy];
for (NSWindow *child in children)
if (m_nsWindow != child) {
@@ -1095,7 +1144,7 @@ void QCocoaWindow::propagateSizeHints()
QSize sizeIncrement = windowSizeIncrement();
if (sizeIncrement.isEmpty())
sizeIncrement = QSize(1, 1);
- [m_nsWindow setResizeIncrements:sizeIncrement.toCGSize()];
+ [m_nsWindow setResizeIncrements:NSSizeFromCGSize(sizeIncrement.toCGSize())];
QRect rect = geometry();
QSize baseSize = windowBaseSize();
@@ -1158,7 +1207,7 @@ void QCocoaWindow::setParent(const QPlatformWindow *parentWindow)
// recreate the window for compatibility
bool unhideAfterRecreate = parentWindow && !m_viewIsToBeEmbedded && ![m_view isHidden];
- recreateWindow(parentWindow);
+ recreateWindowIfNeeded();
if (unhideAfterRecreate)
[m_view setHidden:NO];
setCocoaGeometry(geometry());
@@ -1182,6 +1231,8 @@ void QCocoaWindow::setEmbeddedInForeignView(bool embedded)
m_nsWindow = 0;
}
+// ----------------------- NSWindow notifications -----------------------
+
void QCocoaWindow::windowWillMove()
{
// Close any open popups on window move
@@ -1190,7 +1241,7 @@ void QCocoaWindow::windowWillMove()
void QCocoaWindow::windowDidMove()
{
- if (m_isNSWindowChild)
+ if (isChildNSWindow())
return;
[qnsview_cast(m_view) updateGeometry];
@@ -1201,13 +1252,30 @@ void QCocoaWindow::windowDidResize()
if (!m_nsWindow)
return;
- if (m_isNSWindowChild)
+ if (isChildNSWindow())
return;
clipChildWindows();
[qnsview_cast(m_view) updateGeometry];
}
+void QCocoaWindow::viewDidChangeFrame()
+{
+ [qnsview_cast(m_view) updateGeometry];
+}
+
+/*!
+ Callback for NSViewGlobalFrameDidChangeNotification.
+
+ Posted whenever an NSView object that has attached surfaces (that is,
+ NSOpenGLContext objects) moves to a different screen, or other cases
+ where the NSOpenGLContext object needs to be updated.
+*/
+void QCocoaWindow::viewDidChangeGlobalFrame()
+{
+ updateExposedGeometry();
+}
+
void QCocoaWindow::windowDidEndLiveResize()
{
if (m_synchedWindowState == Qt::WindowMaximized && ![m_nsWindow isZoomed]) {
@@ -1216,6 +1284,104 @@ void QCocoaWindow::windowDidEndLiveResize()
}
}
+void QCocoaWindow::windowDidBecomeKey()
+{
+ if (window()->type() == Qt::ForeignWindow)
+ return;
+
+ if (m_windowUnderMouse) {
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [qnsview_cast(m_view) convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleEnterEvent(m_enterLeaveTargetWindow, windowPoint, screenPoint);
+ }
+
+ if (!windowIsPopupType() && !qnsview_cast(m_view).isMenuView)
+ QWindowSystemInterface::handleWindowActivated(window());
+}
+
+void QCocoaWindow::windowDidResignKey()
+{
+ if (window()->type() == Qt::ForeignWindow)
+ return;
+
+ // Key window will be non-nil if another window became key, so do not
+ // set the active window to zero here -- the new key window's
+ // NSWindowDidBecomeKeyNotification hander will change the active window.
+ NSWindow *keyWindow = [NSApp keyWindow];
+ if (!keyWindow || keyWindow == m_view.window) {
+ // No new key window, go ahead and set the active window to zero
+ if (!windowIsPopupType() && !qnsview_cast(m_view).isMenuView)
+ QWindowSystemInterface::handleWindowActivated(0);
+ }
+}
+
+void QCocoaWindow::windowDidMiniaturize()
+{
+ [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowMinimized];
+}
+
+void QCocoaWindow::windowDidDeminiaturize()
+{
+ [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowNoState];
+}
+
+void QCocoaWindow::windowDidEnterFullScreen()
+{
+ [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowFullScreen];
+}
+
+void QCocoaWindow::windowDidExitFullScreen()
+{
+ [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowNoState];
+}
+
+void QCocoaWindow::windowDidOrderOffScreen()
+{
+ obscureWindow();
+}
+
+void QCocoaWindow::windowDidOrderOnScreen()
+{
+ exposeWindow();
+}
+
+void QCocoaWindow::windowDidChangeOcclusionState()
+{
+ // Several unit tests expect paint and/or expose events for windows that are
+ // sometimes (unpredictably) occluded and some unit tests depend on QWindow::isExposed.
+ // Don't send Expose/Obscure events when running under QTestLib.
+ static const bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING");
+ if (!onTestLib) {
+ if ((NSUInteger)[m_view.window occlusionState] & NSWindowOcclusionStateVisible) {
+ exposeWindow();
+ } else {
+ // Send Obscure events on window occlusion to stop animations.
+ obscureWindow();
+ }
+ }
+}
+
+void QCocoaWindow::windowDidChangeScreen()
+{
+ if (!window())
+ return;
+
+ if (QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen))
+ QWindowSystemInterface::handleWindowScreenChanged(window(), cocoaScreen->screen());
+
+ updateExposedGeometry();
+}
+
+void QCocoaWindow::windowWillClose()
+{
+ // Close any open popups on window closing.
+ if (window() && !windowIsPopupType(window()->type()))
+ qt_closePopups();
+}
+
+// ----------------------- NSWindowDelegate callbacks -----------------------
+
bool QCocoaWindow::windowShouldClose()
{
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::windowShouldClose" << window();
@@ -1229,12 +1395,7 @@ bool QCocoaWindow::windowShouldClose()
return accepted;
}
-void QCocoaWindow::windowWillClose()
-{
- // Close any open popups on window closing.
- if (window() && !windowIsPopupType(window()->type()))
- qt_closePopups();
-}
+// --------------------------------------------------------------------------
void QCocoaWindow::setSynchedWindowStateFromWindow()
{
@@ -1264,62 +1425,141 @@ QCocoaGLContext *QCocoaWindow::currentContext() const
}
#endif
-void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
+/*!
+ Checks if the window is a non-top level QWindow with a NSWindow.
+
+ \sa _q_platform_MacUseNSWindow, QT_MAC_USE_NSWINDOW
+*/
+bool QCocoaWindow::isChildNSWindow() const
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::recreateWindow" << window()
+ return m_view.window.parentWindow != nil;
+}
+
+/*!
+ Checks if the window is the content view of its immediate NSWindow.
+
+ Being the content view of a NSWindow means the QWindow is
+ the highest accessible NSView object in the window's view
+ hierarchy.
+
+ This can only happen in two cases, either if the QWindow is
+ itself a top level window, or if it's a child NSWindow.
+
+ \sa isChildNSWindow
+*/
+bool QCocoaWindow::isContentView() const
+{
+ return m_view.window.contentView == m_view;
+}
+
+/*!
+ Iterates child NSWindows that have a corresponding QCocoaWindow.
+*/
+void QCocoaWindow::foreachChildNSWindow(void (^block)(QCocoaWindow *))
+{
+ NSArray *windows = m_view.window.childWindows;
+ [windows enumerateObjectsUsingBlock:^(NSWindow *window, NSUInteger index, BOOL *stop) {
+ Q_UNUSED(index);
+ Q_UNUSED(stop);
+ if (QNSView *view = qnsview_cast(window.contentView))
+ block(view.platformWindow);
+ }];
+}
+
+/*!
+ Recreates (or removes) the NSWindow for this QWindow, if needed.
+
+ A QWindow may need a corresponding NSWindow, depending on whether
+ or not it's a top level or not (or explicitly set to be a child
+ NSWindow), whether it is a NSPanel or not, etc.
+*/
+void QCocoaWindow::recreateWindowIfNeeded()
+{
+ QPlatformWindow *parentWindow = QPlatformWindow::parent();
+ qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::recreateWindowIfNeeded" << window()
<< "parent" << (parentWindow ? parentWindow->window() : 0);
- bool wasNSWindowChild = m_isNSWindowChild;
- BOOL requestNSWindowChild = qt_mac_resolveOption(NO, window(), "_q_platform_MacUseNSWindow",
- "QT_MAC_USE_NSWINDOW");
- m_isNSWindowChild = parentWindow && requestNSWindowChild;
- bool needsNSWindow = m_isNSWindowChild || !parentWindow;
+ RecreationReasons recreateReason = RecreationNotNeeded;
+
+ QCocoaWindow *oldParentCocoaWindow = nullptr;
+ if (QNSView *qnsView = qnsview_cast(m_view.superview))
+ oldParentCocoaWindow = qnsView.platformWindow;
+
+ if (parentWindow != oldParentCocoaWindow)
+ recreateReason |= ParentChanged;
+
+ if (!m_view.window)
+ recreateReason |= MissingWindow;
+
+ // If the modality has changed the style mask will need updating
+ if (m_windowModality != window()->modality())
+ recreateReason |= WindowModalityChanged;
+
+ const bool shouldBeChildNSWindow = parentWindow && qt_mac_resolveOption(NO,
+ window(), "_q_platform_MacUseNSWindow", "QT_MAC_USE_NSWINDOW");
+
+ if (isChildNSWindow() != shouldBeChildNSWindow)
+ recreateReason |= ChildNSWindowChanged;
+
+ const bool shouldBeContentView = !parentWindow || shouldBeChildNSWindow;
+ if (isContentView() != shouldBeContentView)
+ recreateReason |= ContentViewChanged;
- QCocoaWindow *oldParentCocoaWindow = m_parentCocoaWindow;
- m_parentCocoaWindow = const_cast<QCocoaWindow *>(static_cast<const QCocoaWindow *>(parentWindow));
- if (m_parentCocoaWindow && m_isNSWindowChild) {
- QWindow *parentQWindow = m_parentCocoaWindow->window();
+ Qt::WindowType type = window()->type();
+ const bool isPanel = isContentView() && [m_view.window isKindOfClass:[QNSPanel class]];
+ const bool shouldBePanel = shouldBeContentView && !shouldBeChildNSWindow &&
+ ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog);
+
+ if (isPanel != shouldBePanel)
+ recreateReason |= PanelChanged;
+
+ if (recreateReason == RecreationNotNeeded) {
+ qCDebug(lcQpaCocoaWindow) << "No need to recreate NSWindow";
+ return;
+ }
+
+ qCDebug(lcQpaCocoaWindow) << "Recreating NSWindow due to" << recreateReason;
+
+ QCocoaWindow *parentCocoaWindow = static_cast<QCocoaWindow *>(parentWindow);
+
+ if (shouldBeChildNSWindow) {
+ QWindow *parentQWindow = parentWindow->window();
+ // Ensure that all parents in the hierarchy are also child NSWindows
if (!parentQWindow->property("_q_platform_MacUseNSWindow").toBool()) {
parentQWindow->setProperty("_q_platform_MacUseNSWindow", QVariant(true));
- m_parentCocoaWindow->recreateWindow(m_parentCocoaWindow->m_parentCocoaWindow);
+ parentCocoaWindow->recreateWindowIfNeeded();
}
}
- bool usesNSPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
-
- // No child QNSWindow should notify its QNSView
- if (m_nsWindow && (window()->type() != Qt::ForeignWindow) && m_parentCocoaWindow && !oldParentCocoaWindow)
- [[NSNotificationCenter defaultCenter] removeObserver:m_view
- name:nil object:m_nsWindow];
-
// Remove current window (if any)
- if ((m_nsWindow && !needsNSWindow) || (usesNSPanel != shouldUseNSPanel())) {
+ if ((isContentView() && !shouldBeContentView) || (recreateReason & PanelChanged)) {
[m_nsWindow closeAndRelease];
- if (wasNSWindowChild && oldParentCocoaWindow)
- oldParentCocoaWindow->removeChildWindow(this);
+ if (isChildNSWindow())
+ [m_view.window.parentWindow removeChildWindow:m_view.window];
m_nsWindow = 0;
}
- if (needsNSWindow) {
+ if (shouldBeContentView) {
bool noPreviousWindow = m_nsWindow == 0;
if (noPreviousWindow)
- m_nsWindow = createNSWindow();
-
- // Only non-child QNSWindows should notify their QNSViews
- // (but don't register more than once).
- if ((window()->type() != Qt::ForeignWindow) && (noPreviousWindow || (wasNSWindowChild && !m_isNSWindowChild)))
- [[NSNotificationCenter defaultCenter] addObserver:m_view
- selector:@selector(windowNotification:)
- name:nil // Get all notifications
- object:m_nsWindow];
-
- if (oldParentCocoaWindow) {
- if (!m_isNSWindowChild || oldParentCocoaWindow != m_parentCocoaWindow)
- oldParentCocoaWindow->removeChildWindow(this);
+ m_nsWindow = createNSWindow(shouldBeChildNSWindow, shouldBePanel);
+
+ if (m_view.window.parentWindow) {
+ if (!shouldBeChildNSWindow || (recreateReason & ParentChanged))
+ [m_view.window.parentWindow removeChildWindow:m_view.window];
m_forwardWindow = oldParentCocoaWindow;
}
- setNSWindow(m_nsWindow);
+ // Move view to new NSWindow if needed
+ if (m_nsWindow.contentView != m_view) {
+ [m_view setPostsFrameChangedNotifications:NO];
+ [m_view retain];
+ if (m_view.superview) // m_view comes from another NSWindow
+ [m_view removeFromSuperview];
+ [m_nsWindow setContentView:m_view];
+ [m_view release];
+ [m_view setPostsFrameChangedNotifications:YES];
+ }
}
if (m_viewIsToBeEmbedded) {
@@ -1330,7 +1570,13 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
setWindowFlags(window()->flags());
setWindowTitle(window()->title());
setWindowState(window()->windowState());
- } else if (m_isNSWindowChild) {
+ } else if (shouldBeChildNSWindow) {
+ if (!m_hiddenByClipping) {
+ [parentCocoaWindow->m_nsWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
+ parentCocoaWindow->reinsertChildWindow(this);
+ }
+
+ // Set properties after the window has been made a child NSWindow
m_nsWindow.styleMask = NSBorderlessWindowMask;
m_nsWindow.hasShadow = NO;
m_nsWindow.level = NSNormalWindowLevel;
@@ -1340,22 +1586,12 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
m_nsWindow.collectionBehavior = collectionBehavior;
setCocoaGeometry(windowGeometry());
-
- QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
- if (siblings.contains(this)) {
- if (!m_hiddenByClipping)
- m_parentCocoaWindow->reinsertChildWindow(this);
- } else {
- if (!m_hiddenByClipping)
- [m_parentCocoaWindow->m_nsWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
- siblings.append(this);
- }
} else {
// Child windows have no NSWindow, link the NSViews instead.
if ([m_view superview])
[m_view removeFromSuperview];
- [m_parentCocoaWindow->m_view addSubview:m_view];
+ [parentCocoaWindow->m_view addSubview:m_view];
QRect rect = windowGeometry();
// Prevent setting a (0,0) window size; causes opengl context
// "Invalid Drawable" warnings.
@@ -1381,11 +1617,17 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
void QCocoaWindow::reinsertChildWindow(QCocoaWindow *child)
{
- int childIndex = m_childWindows.indexOf(child);
+ const QObjectList &childWindows = window()->children();
+ int childIndex = childWindows.indexOf(child->window());
Q_ASSERT(childIndex != -1);
- for (int i = childIndex; i < m_childWindows.size(); i++) {
- NSWindow *nsChild = m_childWindows[i]->m_nsWindow;
+ for (int i = childIndex; i < childWindows.size(); ++i) {
+ QWindow *window = static_cast<QWindow *>(childWindows.at(i));
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (!cocoaWindow)
+ continue;
+
+ NSWindow *nsChild = cocoaWindow->m_nsWindow;
if (i != childIndex)
[m_nsWindow removeChildWindow:nsChild];
[m_nsWindow addChildWindow:nsChild ordered:NSWindowAbove];
@@ -1399,26 +1641,39 @@ void QCocoaWindow::requestActivateWindow()
[window makeKeyWindow];
}
-bool QCocoaWindow::shouldUseNSPanel()
-{
- Qt::WindowType type = window()->type();
-
- return !m_isNSWindowChild &&
- ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog);
-}
-
-QCocoaNSWindow * QCocoaWindow::createNSWindow()
+QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBeChildNSWindow, bool shouldBePanel)
{
QMacAutoReleasePool pool;
QRect rect = initialGeometry(window(), windowGeometry(), defaultWindowWidth, defaultWindowHeight);
- NSRect frame = qt_mac_flipRect(rect);
+
+ QScreen *targetScreen = nullptr;
+ for (QScreen *screen : QGuiApplication::screens()) {
+ if (screen->geometry().contains(rect.topLeft())) {
+ targetScreen = screen;
+ break;
+ }
+ }
+
+ if (!targetScreen) {
+ qCWarning(lcQpaCocoaWindow) << "Window position outside any known screen, using primary screen";
+ targetScreen = QGuiApplication::primaryScreen();
+ }
+
+ rect.translate(-targetScreen->geometry().topLeft());
+ QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(targetScreen->handle());
+ NSRect frame = NSRectFromCGRect(cocoaScreen->mapToNative(rect).toCGRect());
+
+ // Note: The macOS window manager has a bug, where if a screen is rotated, it will not allow
+ // a window to be created within the area of the screen that has a Y coordinate (I quadrant)
+ // higher than the height of the screen in its non-rotated state, unless the window is
+ // created with the NSWindowStyleMaskBorderless style mask.
Qt::WindowType type = window()->type();
Qt::WindowFlags flags = window()->flags();
NSUInteger styleMask;
- if (m_isNSWindowChild) {
+ if (shouldBeChildNSWindow) {
styleMask = NSBorderlessWindowMask;
} else {
styleMask = windowStyleMask(flags);
@@ -1427,32 +1682,28 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
// Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen)
// and dialogs
- if (shouldUseNSPanel()) {
- QNSPanel *window;
- window = [[QNSPanel alloc] initWithContentRect:frame
- styleMask: styleMask
- qPlatformWindow:this];
+ if (shouldBePanel) {
+ QNSPanel *panel = [[QNSPanel alloc] initWithContentRect:frame screen:cocoaScreen->nsScreen()
+ styleMask: styleMask qPlatformWindow:this];
+
if ((type & Qt::Popup) == Qt::Popup)
- [window setHasShadow:YES];
+ [panel setHasShadow:YES];
// Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set.
QVariant showWithoutActivating = QPlatformWindow::window()->property("_q_macAlwaysShowToolWindow");
bool shouldHideOnDeactivate = ((type & Qt::Tool) == Qt::Tool) &&
!(showWithoutActivating.isValid() && showWithoutActivating.toBool());
- [window setHidesOnDeactivate: shouldHideOnDeactivate];
+ [panel setHidesOnDeactivate: shouldHideOnDeactivate];
// Make popup windows show on the same desktop as the parent full-screen window.
- [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
+ [panel setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
if ((type & Qt::Popup) == Qt::Popup)
- [window setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow];
+ [panel setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow];
- createdWindow = window;
+ createdWindow = panel;
} else {
- QNSWindow *window;
- window = [[QNSWindow alloc] initWithContentRect:frame
- styleMask: styleMask
- qPlatformWindow:this];
- createdWindow = window;
+ createdWindow = [[QNSWindow alloc] initWithContentRect:frame screen:cocoaScreen->nsScreen()
+ styleMask: styleMask qPlatformWindow:this];
}
if ([createdWindow respondsToSelector:@selector(setRestorable:)])
@@ -1479,36 +1730,6 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
return createdWindow;
}
-void QCocoaWindow::setNSWindow(QCocoaNSWindow *window)
-{
- if (window.contentView != m_view) {
- [m_view setPostsFrameChangedNotifications:NO];
- [m_view retain];
- if (m_view.superview) // m_view comes from another NSWindow
- [m_view removeFromSuperview];
- [window setContentView:m_view];
- [m_view release];
- [m_view setPostsFrameChangedNotifications:YES];
- }
-}
-
-void QCocoaWindow::removeChildWindow(QCocoaWindow *child)
-{
- m_childWindows.removeOne(child);
- [m_nsWindow removeChildWindow:child->m_nsWindow];
-}
-
-bool QCocoaWindow::isNativeWindowTypeInconsistent()
-{
- if (!m_nsWindow)
- return false;
-
- const bool isPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
- const bool usePanel = shouldUseNSPanel();
-
- return isPanel != usePanel;
-}
-
void QCocoaWindow::removeMonitor()
{
if (!monitor)
@@ -1520,7 +1741,7 @@ void QCocoaWindow::removeMonitor()
// Returns the current global screen geometry for the nswindow associated with this window.
QRect QCocoaWindow::nativeWindowGeometry() const
{
- if (!m_nsWindow || m_isNSWindowChild)
+ if (!m_nsWindow || isChildNSWindow())
return geometry();
NSRect rect = [m_nsWindow frame];
@@ -1819,12 +2040,8 @@ void QCocoaWindow::exposeWindow()
// time, and we won't get a NSWindowDidChangeScreenNotification
// on show. The case where the window is initially displayed
// on a non-primary screen needs special handling here.
- NSUInteger screenIndex = [[NSScreen screens] indexOfObject:m_nsWindow.screen];
- if (screenIndex != NSNotFound) {
- QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
- if (cocoaScreen)
- window()->setScreen(cocoaScreen->screen());
- }
+ if (QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenForNSScreen(m_nsWindow.screen))
+ window()->setScreen(cocoaScreen->screen());
if (!m_isExposed) {
m_isExposed = true;
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index f226547b90..84be7eb797 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -74,7 +74,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
QStringList *currentCustomDragTypes;
bool m_sendUpAsRightButton;
Qt::KeyboardModifiers currentWheelModifiers;
- bool m_subscribesForGlobalFrameNotifications;
#ifndef QT_NO_OPENGL
QCocoaGLContext *m_glContext;
bool m_shouldSetGLContextinDrawRect;
@@ -102,7 +101,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)drawBackingStoreUsingCoreGraphics:(NSRect)dirtyRect;
- (void)updateGeometry;
- (void)notifyWindowStateChanged:(Qt::WindowState)newState;
-- (void)windowNotification : (NSNotification *) windowNotification;
- (void)notifyWindowWillZoom:(BOOL)willZoom;
- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification;
- (void)viewDidHide;
@@ -152,6 +150,11 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
@end
+@interface QT_MANGLE_NAMESPACE(QNSView) (QtExtras)
+@property (nonatomic, readonly) QCocoaWindow *platformWindow;
+@property (nonatomic, readonly) BOOL isMenuView;
+@end
+
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSView);
#endif //QNSVIEW_H
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index a63bc4d570..689fd06d66 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -149,7 +149,6 @@ static bool _q_dontOverrideCtrlLMB = false;
m_acceptedMouseDowns = Qt::NoButton;
m_frameStrutButtons = Qt::NoButton;
m_sendKeyEvent = false;
- m_subscribesForGlobalFrameNotifications = false;
#ifndef QT_NO_OPENGL
m_glContext = 0;
m_shouldSetGLContextinDrawRect = false;
@@ -181,7 +180,6 @@ static bool _q_dontOverrideCtrlLMB = false;
CGImageRelease(m_maskImage);
[m_trackingArea release];
m_maskImage = 0;
- m_subscribesForGlobalFrameNotifications = false;
[m_inputSource release];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[m_mouseMoveHelper release];
@@ -217,11 +215,6 @@ static bool _q_dontOverrideCtrlLMB = false;
#endif
[self registerDragTypes];
- [self setPostsFrameChangedNotifications : YES];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(updateGeometry)
- name:NSViewFrameDidChangeNotification
- object:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textInputContextKeyboardSelectionDidChangeNotification:)
@@ -240,27 +233,9 @@ static bool _q_dontOverrideCtrlLMB = false;
//was unable to set view
m_shouldSetGLContextinDrawRect = true;
}
-
- if (!m_subscribesForGlobalFrameNotifications) {
- // NSOpenGLContext expects us to repaint (or update) the view when
- // it changes position on screen. Since this happens unnoticed for
- // the view when the parent view moves, we need to register a special
- // notification that lets us handle this case:
- m_subscribesForGlobalFrameNotifications = true;
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(globalFrameChanged:)
- name:NSViewGlobalFrameDidChangeNotification
- object:self];
- }
}
#endif
-- (void) globalFrameChanged:(NSNotification*)notification
-{
- Q_UNUSED(notification);
- m_platformWindow->updateExposedGeometry();
-}
-
- (void)viewDidMoveToSuperview
{
if (!(m_platformWindow->m_viewIsToBeEmbedded))
@@ -281,22 +256,6 @@ static bool _q_dontOverrideCtrlLMB = false;
m_backingStore = Q_NULLPTR;
}
-- (void)viewWillMoveToWindow:(NSWindow *)newWindow
-{
- // ### Merge "normal" window code path with this one for 5.1.
- if (!(m_platformWindow->window()->type() & Qt::SubWindow))
- return;
-
- if (newWindow) {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(windowNotification:)
- name:nil // Get all notifications
- object:newWindow];
- }
- if ([self window])
- [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]];
-}
-
- (QWindow *)topLevelWindow
{
QWindow *focusWindow = m_platformWindow->window();
@@ -316,7 +275,7 @@ static bool _q_dontOverrideCtrlLMB = false;
{
QRect geometry;
- if (m_platformWindow->m_isNSWindowChild) {
+ if (self.window.parentWindow) {
return;
#if 0
//geometry = QRectF::fromCGRect([self frame]).toRect();
@@ -336,10 +295,10 @@ static bool _q_dontOverrideCtrlLMB = false;
geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height);
} else if (m_platformWindow->m_viewIsToBeEmbedded) {
// embedded child window, use the frame rect ### merge with case below
- geometry = QRectF::fromCGRect([self bounds]).toRect();
+ geometry = QRectF::fromCGRect(NSRectToCGRect([self bounds])).toRect();
} else {
// child window, use the frame rect
- geometry = QRectF::fromCGRect([self frame]).toRect();
+ geometry = QRectF::fromCGRect(NSRectToCGRect([self frame])).toRect();
}
if (m_platformWindow->m_nsWindow && geometry == m_platformWindow->geometry())
@@ -395,64 +354,6 @@ static bool _q_dontOverrideCtrlLMB = false;
m_platformWindow->setSynchedWindowStateFromWindow();
}
-- (void)windowNotification : (NSNotification *) windowNotification
-{
- //qDebug() << "windowNotification" << QString::fromNSString([windowNotification name]);
-
- NSString *notificationName = [windowNotification name];
- if (notificationName == NSWindowDidBecomeKeyNotification) {
- if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
- QWindowSystemInterface::handleWindowActivated(m_platformWindow->window());
- } else if (notificationName == NSWindowDidResignKeyNotification) {
- // key window will be non-nil if another window became key... do not
- // set the active window to zero here, the new key window's
- // NSWindowDidBecomeKeyNotification hander will change the active window
- NSWindow *keyWindow = [NSApp keyWindow];
- if (!keyWindow || keyWindow == windowNotification.object) {
- // no new key window, go ahead and set the active window to zero
- if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
- QWindowSystemInterface::handleWindowActivated(0);
- }
- } else if (notificationName == NSWindowDidMiniaturizeNotification
- || notificationName == NSWindowDidDeminiaturizeNotification) {
- Qt::WindowState newState = notificationName == NSWindowDidMiniaturizeNotification ?
- Qt::WindowMinimized : Qt::WindowNoState;
- [self notifyWindowStateChanged:newState];
- } else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
- m_platformWindow->obscureWindow();
- } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
- m_platformWindow->exposeWindow();
- } else if ([notificationName isEqualToString:NSWindowDidChangeOcclusionStateNotification]) {
- // Several unit tests expect paint and/or expose events for windows that are
- // sometimes (unpredictably) occluded and some unit tests depend on QWindow::isExposed -
- // don't send Expose/Obscure events when running under QTestLib.
- static const bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING");
- if (!onTestLib) {
- if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) {
- m_platformWindow->exposeWindow();
- } else {
- // Send Obscure events on window occlusion to stop animations.
- m_platformWindow->obscureWindow();
- }
- }
- } else if (notificationName == NSWindowDidChangeScreenNotification) {
- if (m_platformWindow->window()) {
- NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];
- if (screenIndex != NSNotFound) {
- QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
- if (cocoaScreen)
- QWindowSystemInterface::handleWindowScreenChanged(m_platformWindow->window(), cocoaScreen->screen());
- m_platformWindow->updateExposedGeometry();
- }
- }
- } else if (notificationName == NSWindowDidEnterFullScreenNotification
- || notificationName == NSWindowDidExitFullScreenNotification) {
- Qt::WindowState newState = notificationName == NSWindowDidEnterFullScreenNotification ?
- Qt::WindowFullScreen : Qt::WindowNoState;
- [self notifyWindowStateChanged:newState];
- }
-}
-
- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification
{
Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification)
@@ -553,7 +454,7 @@ static bool _q_dontOverrideCtrlLMB = false;
- (void) drawRect:(NSRect)dirtyRect
{
- qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_platformWindow->window() << QRectF::fromCGRect(dirtyRect);
+ qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_platformWindow->window() << QRectF::fromCGRect(NSRectToCGRect(dirtyRect));
#ifndef QT_NO_OPENGL
if (m_glContext && m_shouldSetGLContextinDrawRect) {
@@ -1336,7 +1237,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (bool)handleGestureAsBeginEnd:(NSEvent *)event
{
- if (QSysInfo::QSysInfo::MacintoshVersion < QSysInfo::MV_10_11)
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::OSXElCapitan)
return false;
if ([event phase] == NSEventPhaseBegan) {
@@ -2201,3 +2102,17 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
}
@end
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (QtExtras)
+
+- (QCocoaWindow*)platformWindow
+{
+ return m_platformWindow.data();;
+}
+
+- (BOOL)isMenuView
+{
+ return m_isMenuView;
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
index f29aa97b68..a465b249c5 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.h
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h
@@ -49,15 +49,10 @@
QCocoaWindow *m_cocoaWindow;
}
-- (id)initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow;
+- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow;
-- (void)windowDidBecomeKey:(NSNotification *)notification;
-- (void)windowDidResize:(NSNotification *)notification;
-- (void)windowDidMove:(NSNotification *)notification;
-- (void)windowWillMove:(NSNotification *)notification;
- (BOOL)windowShouldClose:(NSNotification *)notification;
- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame;
-- (void)windowWillClose:(NSNotification *)notification;
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu;
- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard;
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 7f988ac963..3781a4cc65 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -45,57 +45,12 @@
@implementation QNSWindowDelegate
-- (id) initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow
+- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow
{
- self = [super init];
-
- if (self) {
+ if (self = [super init])
m_cocoaWindow = cocoaWindow;
- }
- return self;
-}
-
-- (void)windowDidBecomeKey:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow->m_windowUnderMouse) {
- QPointF windowPoint;
- QPointF screenPoint;
- [qnsview_cast(m_cocoaWindow->view()) convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindowSystemInterface::handleEnterEvent(m_cocoaWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
- }
-}
-
-- (void)windowDidResize:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowDidResize();
- }
-}
-
-- (void)windowDidEndLiveResize:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowDidEndLiveResize();
- }
-}
-
-- (void)windowWillMove:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowWillMove();
- }
-}
-- (void)windowDidMove:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowDidMove();
- }
+ return self;
}
- (BOOL)windowShouldClose:(NSNotification *)notification
@@ -116,13 +71,6 @@
return YES;
}
-- (void)windowWillClose:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow)
- m_cocoaWindow->windowWillClose();
-}
-
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
{
Q_UNUSED(window);
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
index b5065ba380..38425f8fa1 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
@@ -55,8 +55,9 @@ class QWindowsDirect2DBitmapPrivate
{
public:
QWindowsDirect2DBitmapPrivate(ID2D1DeviceContext *dc = 0, ID2D1Bitmap1 *bm = 0)
- : bitmap(bm)
- , deviceContext(new QWindowsDirect2DDeviceContext(dc))
+ : deviceContext(new QWindowsDirect2DDeviceContext(dc))
+ , bitmap(bm)
+
{
deviceContext->get()->SetTarget(bm);
}
@@ -83,13 +84,13 @@ public:
UINT32(width), UINT32(height)
};
- HRESULT hr = deviceContext->get()->CreateBitmap(size, data, pitch,
+ HRESULT hr = deviceContext->get()->CreateBitmap(size, data, UINT32(pitch),
bitmapProperties(),
bitmap.ReleaseAndGetAddressOf());
if (SUCCEEDED(hr))
deviceContext->get()->SetTarget(bitmap.Get());
else
- qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create bitmap: %#lx", __FUNCTION__, hr);
return SUCCEEDED(hr);
}
@@ -107,28 +108,28 @@ public:
D2D1_BITMAP_PROPERTIES1 properties = bitmapProperties();
properties.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ;
- hr = deviceContext->get()->CreateBitmap(size, NULL, NULL,
+ hr = deviceContext->get()->CreateBitmap(size, NULL, 0,
properties, &mappingCopy);
if (FAILED(hr)) {
- qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create bitmap: %#lx", __FUNCTION__, hr);
return QImage();
}
hr = mappingCopy->CopyFromBitmap(NULL, bitmap.Get(), NULL);
if (FAILED(hr)) {
- qWarning("%s: Could not copy from bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not copy from bitmap: %#lx", __FUNCTION__, hr);
return QImage();
}
D2D1_MAPPED_RECT mappedRect;
hr = mappingCopy->Map(D2D1_MAP_OPTIONS_READ, &mappedRect);
if (FAILED(hr)) {
- qWarning("%s: Could not map: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not map: %#lx", __FUNCTION__, hr);
return QImage();
}
return QImage(static_cast<const uchar *>(mappedRect.bits),
- size.width, size.height, mappedRect.pitch,
+ int(size.width), int(size.height), int(mappedRect.pitch),
QImage::Format_ARGB32_Premultiplied).copy(rect);
}
@@ -197,7 +198,7 @@ QSize QWindowsDirect2DBitmap::size() const
Q_D(const QWindowsDirect2DBitmap);
D2D1_SIZE_U size = d->bitmap->GetPixelSize();
- return QSize(size.width, size.height);
+ return QSize(int(size.width), int(size.height));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
index fb5bb43d17..a5817016e6 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
@@ -84,7 +84,7 @@ public:
}
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct3D Device: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct3D Device: %#lx", __FUNCTION__, hr);
return false;
}
@@ -93,7 +93,7 @@ public:
hr = d3dDevice.As(&dxgiDevice);
if (FAILED(hr)) {
- qWarning("%s: DXGI Device interface query failed on D3D Device: %#x", __FUNCTION__, hr);
+ qWarning("%s: DXGI Device interface query failed on D3D Device: %#lx", __FUNCTION__, hr);
return false;
}
@@ -102,13 +102,13 @@ public:
hr = dxgiDevice->GetAdapter(&dxgiAdapter);
if (FAILED(hr)) {
- qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#x", __FUNCTION__, hr);
+ qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#lx", __FUNCTION__, hr);
return false;
}
hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
if (FAILED(hr)) {
- qWarning("%s: Failed to probe DXGI Adapter for parent DXGI Factory: %#x", __FUNCTION__, hr);
+ qWarning("%s: Failed to probe DXGI Adapter for parent DXGI Factory: %#lx", __FUNCTION__, hr);
return false;
}
@@ -121,26 +121,26 @@ public:
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, options, d2dFactory.GetAddressOf());
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D Factory: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D Factory: %#lx", __FUNCTION__, hr);
return false;
}
hr = d2dFactory->CreateDevice(dxgiDevice.Get(), &d2dDevice);
if (FAILED(hr)) {
- qWarning("%s: Could not create D2D Device: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create D2D Device: %#lx", __FUNCTION__, hr);
return false;
}
hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
static_cast<IUnknown **>(&directWriteFactory));
if (FAILED(hr)) {
- qWarning("%s: Could not create DirectWrite factory: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create DirectWrite factory: %#lx", __FUNCTION__, hr);
return false;
}
hr = directWriteFactory->GetGdiInterop(&directWriteGdiInterop);
if (FAILED(hr)) {
- qWarning("%s: Could not create DirectWrite GDI Interop: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create DirectWrite GDI Interop: %#lx", __FUNCTION__, hr);
return false;
}
@@ -161,7 +161,7 @@ QWindowsDirect2DContext::QWindowsDirect2DContext()
{
}
-QWindowsDirect2DContext::~QWindowsDirect2DContext() {}
+QWindowsDirect2DContext::~QWindowsDirect2DContext() = default;
bool QWindowsDirect2DContext::init()
{
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
index a3478d2d4e..0d42c65964 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
@@ -59,7 +59,7 @@ class QWindowsDirect2DContext
public:
QWindowsDirect2DContext();
- virtual ~QWindowsDirect2DContext();
+ ~QWindowsDirect2DContext();
bool init();
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
index 30238217dd..8a34f6974f 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
@@ -51,14 +51,13 @@ class QWindowsDirect2DDeviceContextPrivate {
public:
QWindowsDirect2DDeviceContextPrivate(ID2D1DeviceContext *dc)
: deviceContext(dc)
- , refCount(0)
{
if (!dc) {
HRESULT hr = QWindowsDirect2DContext::instance()->d2dDevice()->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
&deviceContext);
if (Q_UNLIKELY(FAILED(hr)))
- qFatal("%s: Couldn't create Direct2D Device Context: %#x", __FUNCTION__, hr);
+ qFatal("%s: Couldn't create Direct2D Device Context: %#lx", __FUNCTION__, hr);
}
Q_ASSERT(deviceContext);
@@ -98,7 +97,7 @@ public:
}
ComPtr<ID2D1DeviceContext> deviceContext;
- int refCount;
+ int refCount = 0;
};
QWindowsDirect2DDeviceContext::QWindowsDirect2DDeviceContext(ID2D1DeviceContext *dc)
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
index da4a4e6ce6..ea51135583 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -76,12 +76,7 @@ public:
class Direct2DVersion
{
private:
- Direct2DVersion()
- : partOne(0)
- , partTwo(0)
- , partThree(0)
- , partFour(0)
- {}
+ Direct2DVersion() = default;
Direct2DVersion(int one, int two, int three, int four)
: partOne(one)
@@ -108,13 +103,14 @@ public:
if (_tcscat_s(filename, bufSize, __TEXT("\\d2d1.dll")) == 0) {
DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL);
if (versionInfoSize) {
- QVarLengthArray<BYTE> info(versionInfoSize);
- if (GetFileVersionInfo(filename, NULL, versionInfoSize, info.data())) {
+ QVarLengthArray<BYTE> info(static_cast<int>(versionInfoSize));
+ if (GetFileVersionInfo(filename, 0, versionInfoSize, info.data())) {
UINT size;
DWORD *fi;
- if (VerQueryValue(info.constData(), __TEXT("\\"), (LPVOID *) &fi, &size) && size) {
- VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *) fi;
+ if (VerQueryValue(info.constData(), __TEXT("\\"),
+ reinterpret_cast<void **>(&fi), &size) && size) {
+ const VS_FIXEDFILEINFO *verInfo = reinterpret_cast<const VS_FIXEDFILEINFO *>(fi);
return Direct2DVersion(HIWORD(verInfo->dwFileVersionMS),
LOWORD(verInfo->dwFileVersionMS),
HIWORD(verInfo->dwFileVersionLS),
@@ -171,7 +167,10 @@ public:
return a - b;
}
- int partOne, partTwo, partThree, partFour;
+ int partOne = 0;
+ int partTwo = 0;
+ int partThree = 0;
+ int partFour = 0;
};
QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList &paramList)
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
index 29b01391e2..3c86168a74 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
@@ -93,42 +93,33 @@ int QWindowsDirect2DPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric)
switch (metric) {
case QPaintDevice::PdmWidth:
- return d->bitmap->bitmap()->GetPixelSize().width;
- break;
+ return int(d->bitmap->bitmap()->GetPixelSize().width);
case QPaintDevice::PdmHeight:
- return d->bitmap->bitmap()->GetPixelSize().height;
- break;
+ return int(d->bitmap->bitmap()->GetPixelSize().height);
case QPaintDevice::PdmNumColors:
return INT_MAX;
- break;
case QPaintDevice::PdmDepth:
return 32;
- break;
case QPaintDevice::PdmDpiX:
case QPaintDevice::PdmPhysicalDpiX:
{
FLOAT x, y;
QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
- return x;
+ return qRound(x);
}
- break;
case QPaintDevice::PdmDpiY:
case QPaintDevice::PdmPhysicalDpiY:
{
FLOAT x, y;
QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
- return y;
+ return qRound(y);
}
- break;
case QPaintDevice::PdmDevicePixelRatio:
return 1;
- break;
case QPaintDevice::PdmDevicePixelRatioScaled:
- return 1 * devicePixelRatioFScale();
- break;
+ return qRound(devicePixelRatioFScale());
case QPaintDevice::PdmWidthMM:
case QPaintDevice::PdmHeightMM:
- return -1;
break;
}
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index 69d2e12778..85f333ac78 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -87,7 +87,7 @@ enum {
};
//Clipping flags
-enum {
+enum : unsigned {
SimpleSystemClip = 0x1
};
@@ -125,28 +125,30 @@ static inline D2D1_MATRIX_3X2_F transformFromLine(const QLineF &line, qreal penW
static void adjustLine(QPointF *p1, QPointF *p2);
static bool isLinePositivelySloped(const QPointF &p1, const QPointF &p2);
-class Direct2DPathGeometryWriter
+static QVector<D2D1_GRADIENT_STOP> qGradientStopsToD2DStops(const QGradientStops &qstops)
{
-public:
- Direct2DPathGeometryWriter()
- : m_inFigure(false)
- , m_roundCoordinates(false)
- , m_adjustPositivelySlopedLines(false)
- {
-
+ QVector<D2D1_GRADIENT_STOP> stops(qstops.count());
+ for (int i = 0, count = stops.size(); i < count; ++i) {
+ stops[i].position = FLOAT(qstops.at(i).first);
+ stops[i].color = to_d2d_color_f(qstops.at(i).second);
}
+ return stops;
+}
+class Direct2DPathGeometryWriter
+{
+public:
bool begin()
{
HRESULT hr = factory()->CreatePathGeometry(&m_geometry);
if (FAILED(hr)) {
- qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create path geometry: %#lx", __FUNCTION__, hr);
return false;
}
hr = m_geometry->Open(&m_sink);
if (FAILED(hr)) {
- qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create geometry sink: %#lx", __FUNCTION__, hr);
return false;
}
@@ -239,9 +241,9 @@ private:
ComPtr<ID2D1PathGeometry1> m_geometry;
ComPtr<ID2D1GeometrySink> m_sink;
- bool m_inFigure;
- bool m_roundCoordinates;
- bool m_adjustPositivelySlopedLines;
+ bool m_inFigure = false;
+ bool m_roundCoordinates = false;
+ bool m_adjustPositivelySlopedLines = false;
QPointF m_previousPoint;
};
@@ -262,7 +264,6 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate
public:
QWindowsDirect2DPaintEnginePrivate(QWindowsDirect2DBitmap *bm, QWindowsDirect2DPaintEngine::Flags flags)
: bitmap(bm)
- , clipFlags(0)
, flags(flags)
{
pen.reset();
@@ -274,7 +275,7 @@ public:
QWindowsDirect2DBitmap *bitmap;
QImage fallbackImage;
- unsigned int clipFlags;
+ unsigned int clipFlags = 0;
QStack<ClipType> pushedClips;
QWindowsDirect2DPaintEngine::Flags flags;
@@ -348,9 +349,9 @@ public:
void updateOpacity(qreal opacity)
{
if (brush.brush)
- brush.brush->SetOpacity(opacity);
+ brush.brush->SetOpacity(FLOAT(opacity));
if (pen.brush)
- pen.brush->SetOpacity(opacity);
+ pen.brush->SetOpacity(FLOAT(opacity));
}
void pushClip(const QVectorPath &path)
@@ -459,7 +460,7 @@ public:
brush.qbrush = newBrush;
if (brush.brush) {
- brush.brush->SetOpacity(q->state()->opacity);
+ brush.brush->SetOpacity(FLOAT(q->state()->opacity));
applyBrushOrigin(currentBrushOrigin);
}
}
@@ -477,8 +478,8 @@ public:
brush.brush->GetTransform(&transform);
brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
- * D2D1::Matrix3x2F::Translation(-currentBrushOrigin.x(),
- -currentBrushOrigin.y()));
+ * D2D1::Matrix3x2F::Translation(FLOAT(-currentBrushOrigin.x()),
+ FLOAT(-currentBrushOrigin.y())));
}
}
@@ -489,7 +490,7 @@ public:
brush.brush->GetTransform(&transform);
brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
- * D2D1::Matrix3x2F::Translation(origin.x(), origin.y()));
+ * D2D1::Matrix3x2F::Translation(FLOAT(origin.x()), FLOAT(origin.y())));
}
currentBrushOrigin = origin;
@@ -511,7 +512,7 @@ public:
if (!pen.brush)
return;
- pen.brush->SetOpacity(q->state()->opacity);
+ pen.brush->SetOpacity(FLOAT(q->state()->opacity));
D2D1_STROKE_STYLE_PROPERTIES1 props = {};
@@ -541,8 +542,8 @@ public:
break;
}
- props.miterLimit = newPen.miterLimit() * qreal(2.0); // D2D and Qt miter specs differ
- props.dashOffset = newPen.dashOffset();
+ props.miterLimit = FLOAT(newPen.miterLimit() * qreal(2.0)); // D2D and Qt miter specs differ
+ props.dashOffset = FLOAT(newPen.dashOffset());
if (newPen.widthF() == 0)
props.transformType = D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE;
@@ -577,24 +578,24 @@ public:
qreal penWidth = pen.qpen.widthF();
qreal brushWidth = 0;
for (int i = 0; i < dashes.size(); i++) {
- converted[i] = dashes[i];
+ converted[i] = FLOAT(dashes[i]);
brushWidth += penWidth * dashes[i];
}
- hr = factory()->CreateStrokeStyle(props, converted.constData(), converted.size(), &pen.strokeStyle);
+ hr = factory()->CreateStrokeStyle(props, converted.constData(), UINT32(converted.size()), &pen.strokeStyle);
// Create a combined brush/dash pattern for optimized line drawing
QWindowsDirect2DBitmap bitmap;
- bitmap.resize(ceil(brushWidth), ceil(penWidth));
+ bitmap.resize(int(ceil(brushWidth)), int(ceil(penWidth)));
bitmap.deviceContext()->begin();
bitmap.deviceContext()->get()->SetAntialiasMode(antialiasMode());
bitmap.deviceContext()->get()->SetTransform(D2D1::IdentityMatrix());
bitmap.deviceContext()->get()->Clear();
const qreal offsetX = (qreal(bitmap.size().width()) - brushWidth) / 2;
const qreal offsetY = qreal(bitmap.size().height()) / 2;
- bitmap.deviceContext()->get()->DrawLine(D2D1::Point2F(offsetX, offsetY),
- D2D1::Point2F(brushWidth, offsetY),
- pen.brush.Get(), penWidth, pen.strokeStyle.Get());
+ bitmap.deviceContext()->get()->DrawLine(D2D1::Point2F(FLOAT(offsetX), FLOAT(offsetY)),
+ D2D1::Point2F(FLOAT(brushWidth), FLOAT(offsetY)),
+ pen.brush.Get(), FLOAT(penWidth), pen.strokeStyle.Get());
bitmap.deviceContext()->end();
D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = D2D1::BitmapBrushProperties1(
D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_CLAMP, D2D1_INTERPOLATION_MODE_LINEAR);
@@ -605,7 +606,7 @@ public:
}
if (FAILED(hr))
- qWarning("%s: Could not create stroke style: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create stroke style: %#lx", __FUNCTION__, hr);
}
ComPtr<ID2D1Brush> to_d2d_brush(const QBrush &newBrush, bool *needsEmulation)
@@ -627,13 +628,13 @@ public:
hr = dc()->CreateSolidColorBrush(to_d2d_color_f(newBrush.color()), &solid);
if (FAILED(hr)) {
- qWarning("%s: Could not create solid color brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create solid color brush: %#lx", __FUNCTION__, hr);
break;
}
hr = solid.As(&result);
if (FAILED(hr))
- qWarning("%s: Could not convert solid color brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert solid color brush: %#lx", __FUNCTION__, hr);
}
break;
@@ -673,13 +674,13 @@ public:
bitmapBrushProperties,
&bitmapBrush);
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D bitmap brush for Qt pattern brush: %#lx", __FUNCTION__, hr);
break;
}
hr = bitmapBrush.As(&result);
if (FAILED(hr))
- qWarning("%s: Could not convert Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert Direct2D bitmap brush for Qt pattern brush: %#lx", __FUNCTION__, hr);
}
break;
@@ -693,33 +694,29 @@ public:
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties;
ComPtr<ID2D1GradientStopCollection> gradientStopCollection;
- const QGradientStops &qstops = qlinear->stops();
- QVector<D2D1_GRADIENT_STOP> stops(qstops.count());
-
linearGradientBrushProperties.startPoint = to_d2d_point_2f(qlinear->start());
linearGradientBrushProperties.endPoint = to_d2d_point_2f(qlinear->finalStop());
- for (int i = 0; i < stops.size(); i++) {
- stops[i].position = qstops[i].first;
- stops[i].color = to_d2d_color_f(qstops[i].second);
- }
+ const QVector<D2D1_GRADIENT_STOP> stops = qGradientStopsToD2DStops(qlinear->stops());
- hr = dc()->CreateGradientStopCollection(stops.constData(), stops.size(), &gradientStopCollection);
+ hr = dc()->CreateGradientStopCollection(stops.constData(),
+ UINT32(stops.size()),
+ &gradientStopCollection);
if (FAILED(hr)) {
- qWarning("%s: Could not create gradient stop collection for linear gradient: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create gradient stop collection for linear gradient: %#lx", __FUNCTION__, hr);
break;
}
hr = dc()->CreateLinearGradientBrush(linearGradientBrushProperties, gradientStopCollection.Get(),
&linear);
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D linear gradient brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D linear gradient brush: %#lx", __FUNCTION__, hr);
break;
}
hr = linear.As(&result);
if (FAILED(hr)) {
- qWarning("%s: Could not convert Direct2D linear gradient brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert Direct2D linear gradient brush: %#lx", __FUNCTION__, hr);
break;
}
}
@@ -735,35 +732,29 @@ public:
D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties;
ComPtr<ID2D1GradientStopCollection> gradientStopCollection;
- const QGradientStops &qstops = qradial->stops();
- QVector<D2D1_GRADIENT_STOP> stops(qstops.count());
-
radialGradientBrushProperties.center = to_d2d_point_2f(qradial->center());
radialGradientBrushProperties.gradientOriginOffset = to_d2d_point_2f(qradial->focalPoint() - qradial->center());
- radialGradientBrushProperties.radiusX = qradial->radius();
- radialGradientBrushProperties.radiusY = qradial->radius();
+ radialGradientBrushProperties.radiusX = FLOAT(qradial->radius());
+ radialGradientBrushProperties.radiusY = FLOAT(qradial->radius());
- for (int i = 0; i < stops.size(); i++) {
- stops[i].position = qstops[i].first;
- stops[i].color = to_d2d_color_f(qstops[i].second);
- }
+ const QVector<D2D1_GRADIENT_STOP> stops = qGradientStopsToD2DStops(qradial->stops());
hr = dc()->CreateGradientStopCollection(stops.constData(), stops.size(), &gradientStopCollection);
if (FAILED(hr)) {
- qWarning("%s: Could not create gradient stop collection for radial gradient: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create gradient stop collection for radial gradient: %#lx", __FUNCTION__, hr);
break;
}
hr = dc()->CreateRadialGradientBrush(radialGradientBrushProperties, gradientStopCollection.Get(),
&radial);
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D radial gradient brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D radial gradient brush: %#lx", __FUNCTION__, hr);
break;
}
radial.As(&result);
if (FAILED(hr)) {
- qWarning("%s: Could not convert Direct2D radial gradient brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert Direct2D radial gradient brush: %#lx", __FUNCTION__, hr);
break;
}
}
@@ -789,13 +780,13 @@ public:
&bitmapBrush);
if (FAILED(hr)) {
- qWarning("%s: Could not create texture brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create texture brush: %#lx", __FUNCTION__, hr);
break;
}
hr = bitmapBrush.As(&result);
if (FAILED(hr))
- qWarning("%s: Could not convert texture brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert texture brush: %#lx", __FUNCTION__, hr);
}
break;
}
@@ -958,7 +949,8 @@ public:
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
return;
}
- dc()->DrawGeometry(geometry.Get(), pen.brush.Get(), pen.qpen.widthF(), pen.strokeStyle.Get());
+ dc()->DrawGeometry(geometry.Get(), pen.brush.Get(),
+ FLOAT(pen.qpen.widthF()), pen.strokeStyle.Get());
return;
}
@@ -998,7 +990,7 @@ public:
dashOffset = pen.dashLength - fmod(lineLength - dashOffset, pen.dashLength);
}
dc()->DrawLine(to_d2d_point_2f(p1), to_d2d_point_2f(p2),
- brush, pen.qpen.widthF(), NULL);
+ brush, FLOAT(pen.qpen.widthF()), NULL);
if (skipJoin)
continue;
@@ -1013,7 +1005,8 @@ public:
writer.lineTo(p1);
writer.lineTo(line.pointAt(patchSegment));
writer.close();
- dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(), pen.qpen.widthF(), pen.strokeStyle.Get());
+ dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(),
+ FLOAT(pen.qpen.widthF()), pen.strokeStyle.Get());
}
// Record the start position of the next joint
jointStart = line.pointAt(1 - patchSegment);
@@ -1025,7 +1018,8 @@ public:
writer.lineTo(p2);
writer.lineTo(QLineF(p2, QPointF(points[2], points[3])).pointAt(patchSegment));
writer.close();
- dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(), pen.qpen.widthF(), pen.strokeStyle.Get());
+ dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(),
+ FLOAT(pen.qpen.widthF()), pen.strokeStyle.Get());
}
}
}
@@ -1045,20 +1039,20 @@ public:
const QString nameSubstitute = QSettings(QLatin1String(keyC), QSettings::NativeFormat).value(familyName, familyName).toString();
if (nameSubstitute != familyName) {
const int nameSubstituteLength = qMin(nameSubstitute.length(), LF_FACESIZE - 1);
- memcpy(lf.lfFaceName, nameSubstitute.utf16(), nameSubstituteLength * sizeof(wchar_t));
+ memcpy(lf.lfFaceName, nameSubstitute.utf16(), size_t(nameSubstituteLength) * sizeof(wchar_t));
lf.lfFaceName[nameSubstituteLength] = 0;
}
ComPtr<IDWriteFont> dwriteFont;
HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFromLOGFONT(&lf, &dwriteFont);
if (FAILED(hr)) {
- qDebug("%s: CreateFontFromLOGFONT failed: %#x", __FUNCTION__, hr);
+ qDebug("%s: CreateFontFromLOGFONT failed: %#lx", __FUNCTION__, hr);
return fontFace;
}
hr = dwriteFont->CreateFontFace(&fontFace);
if (FAILED(hr)) {
- qDebug("%s: CreateFontFace failed: %#x", __FUNCTION__, hr);
+ qDebug("%s: CreateFontFace failed: %#lx", __FUNCTION__, hr);
return fontFace;
}
@@ -1332,7 +1326,8 @@ void QWindowsDirect2DPaintEngine::drawRects(const QRect *rects, int rectCount)
d->dc()->FillRectangle(d2d_rect, d->brush.brush.Get());
if (d->pen.brush)
- d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(),
+ FLOAT(d->pen.qpen.widthF()), d->pen.strokeStyle.Get());
}
}
}
@@ -1359,7 +1354,8 @@ void QWindowsDirect2DPaintEngine::drawRects(const QRectF *rects, int rectCount)
d->dc()->FillRectangle(d2d_rect, d->brush.brush.Get());
if (d->pen.brush)
- d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(),
+ FLOAT(d->pen.qpen.widthF()), d->pen.strokeStyle.Get());
}
}
}
@@ -1407,7 +1403,9 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRectF &r)
d->dc()->FillEllipse(ellipse, d->brush.brush.Get());
if (d->pen.brush)
- d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(),
+ FLOAT(d->pen.qpen.widthF()),
+ d->pen.strokeStyle.Get());
}
}
@@ -1435,7 +1433,9 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRect &r)
d->dc()->FillEllipse(ellipse, d->brush.brush.Get());
if (d->pen.brush)
- d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(),
+ FLOAT(d->pen.qpen.widthF()),
+ d->pen.strokeStyle.Get());
}
}
@@ -1490,12 +1490,12 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
// Good, src bitmap != dst bitmap
if (sr.isValid())
d->dc()->DrawBitmap(bitmap->bitmap(),
- to_d2d_rect_f(r), state()->opacity,
+ to_d2d_rect_f(r), FLOAT(state()->opacity),
d->interpolationMode(),
to_d2d_rect_f(sr));
else
d->dc()->DrawBitmap(bitmap->bitmap(),
- to_d2d_rect_f(r), state()->opacity,
+ to_d2d_rect_f(r), FLOAT(state()->opacity),
d->interpolationMode());
} else {
// Ok, so the source pixmap and destination pixmap is the same.
@@ -1504,7 +1504,7 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
QWindowsDirect2DBitmap intermediate;
if (sr.isValid()) {
- bool r = intermediate.resize(sr.width(), sr.height());
+ bool r = intermediate.resize(int(sr.width()), int(sr.height()));
if (!r) {
qWarning("%s: Could not resize intermediate bitmap to source rect size", __FUNCTION__);
return;
@@ -1515,7 +1515,7 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
bitmap->bitmap(),
&d2d_sr);
if (FAILED(hr)) {
- qWarning("%s: Could not copy source rect area from source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not copy source rect area from source bitmap to intermediate bitmap: %#lx", __FUNCTION__, hr);
return;
}
} else {
@@ -1530,13 +1530,13 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
bitmap->bitmap(),
NULL);
if (FAILED(hr)) {
- qWarning("%s: Could not copy source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not copy source bitmap to intermediate bitmap: %#lx", __FUNCTION__, hr);
return;
}
}
d->dc()->DrawBitmap(intermediate.bitmap(),
- to_d2d_rect_f(r), state()->opacity,
+ to_d2d_rect_f(r), FLOAT(state()->opacity),
d->interpolationMode());
}
}
@@ -1573,9 +1573,9 @@ void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticText
// This looks a little funky because the positions are precalculated
glyphAdvances[i] = 0;
- glyphOffsets[i].advanceOffset = staticTextItem->glyphPositions[i].x.toReal();
+ glyphOffsets[i].advanceOffset = FLOAT(staticTextItem->glyphPositions[i].x.toReal());
// Qt and Direct2D seem to disagree on the direction of the ascender offset...
- glyphOffsets[i].ascenderOffset = staticTextItem->glyphPositions[i].y.toReal() * -1;
+ glyphOffsets[i].ascenderOffset = FLOAT(staticTextItem->glyphPositions[i].y.toReal() * -1);
}
d->drawGlyphRun(D2D1::Point2F(0, 0),
@@ -1618,11 +1618,11 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem
for (int i = 0; i < ti.glyphs.numGlyphs; i++) {
glyphIndices[i] = UINT16(ti.glyphs.glyphs[i]); // Imperfect conversion here
- glyphAdvances[i] = ti.glyphs.effectiveAdvance(i).toReal();
- glyphOffsets[i].advanceOffset = ti.glyphs.offsets[i].x.toReal();
+ glyphAdvances[i] = FLOAT(ti.glyphs.effectiveAdvance(i).toReal());
+ glyphOffsets[i].advanceOffset = FLOAT(ti.glyphs.offsets[i].x.toReal());
// XXX Should we negate the y value like for static text items?
- glyphOffsets[i].ascenderOffset = ti.glyphs.offsets[i].y.toReal();
+ glyphOffsets[i].ascenderOffset = FLOAT(ti.glyphs.offsets[i].y.toReal());
}
const bool rtl = (ti.flags & QTextItem::RightToLeft);
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
index e7e2fa4ff7..65e056d312 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
@@ -57,15 +57,12 @@ public:
: owns_bitmap(true)
, bitmap(new QWindowsDirect2DBitmap)
, device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap))
- , devicePixelRatio(1.0)
{}
QWindowsDirect2DPlatformPixmapPrivate(QWindowsDirect2DBitmap *bitmap,
QWindowsDirect2DPaintEngine::Flags flags)
- : owns_bitmap(false)
- , bitmap(bitmap)
+ : bitmap(bitmap)
, device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap, flags))
- , devicePixelRatio(1.0)
{}
~QWindowsDirect2DPlatformPixmapPrivate()
@@ -74,10 +71,10 @@ public:
delete bitmap;
}
- bool owns_bitmap;
+ bool owns_bitmap = false;
QWindowsDirect2DBitmap *bitmap;
QScopedPointer<QWindowsDirect2DPaintDevice> device;
- qreal devicePixelRatio;
+ qreal devicePixelRatio = 1.0;
};
static int qt_d2dpixmap_serno = 0;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
index c750b02078..21294cfb15 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
@@ -54,7 +54,6 @@ QT_BEGIN_NAMESPACE
QWindowsDirect2DWindow::QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data)
: QWindowsWindow(window, data)
- , m_needsFullFlush(true)
, m_directRendering(!(data.flags & Qt::FramelessWindowHint && window->format().hasAlpha()))
{
if (window->type() == Qt::Desktop)
@@ -67,7 +66,7 @@ QWindowsDirect2DWindow::QWindowsDirect2DWindow(QWindow *window, const QWindowsWi
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
m_deviceContext.GetAddressOf());
if (FAILED(hr))
- qWarning("%s: Couldn't create Direct2D Device context: %#x", __FUNCTION__, hr);
+ qWarning("%s: Couldn't create Direct2D Device context: %#lx", __FUNCTION__, hr);
}
QWindowsDirect2DWindow::~QWindowsDirect2DWindow()
@@ -100,12 +99,12 @@ void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion
HRESULT hr = m_swapChain->GetDesc1(&desc);
QRect geom = geometry();
- if ((FAILED(hr) || (desc.Width != geom.width()) || (desc.Height != geom.height()))) {
+ if (FAILED(hr) || (desc.Width != UINT(geom.width()) || (desc.Height != UINT(geom.height())))) {
resizeSwapChain(geom.size());
m_swapChain->GetDesc1(&desc);
}
- size.setWidth(desc.Width);
- size.setHeight(desc.Height);
+ size.setWidth(int(desc.Width));
+ size.setHeight(int(desc.Height));
} else {
size = geometry().size();
}
@@ -175,7 +174,7 @@ void QWindowsDirect2DWindow::present(const QRegion &region)
UPDATELAYEREDWINDOWINFO info = { sizeof(UPDATELAYEREDWINDOWINFO), NULL,
&ptDst, &size, hdc, &ptSrc, 0, &blend, ULW_ALPHA, &dirty };
if (!UpdateLayeredWindowIndirect(handle(), &info))
- qErrnoWarning(GetLastError(), "Failed to update the layered window");
+ qErrnoWarning(int(GetLastError()), "Failed to update the layered window");
hr = dxgiSurface->ReleaseDC(NULL);
if (FAILED(hr))
@@ -201,7 +200,7 @@ void QWindowsDirect2DWindow::setupSwapChain()
m_swapChain.ReleaseAndGetAddressOf()); // [out] IDXGISwapChain1 **ppSwapChain
if (FAILED(hr))
- qWarning("%s: Could not create swap chain: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create swap chain: %#lx", __FUNCTION__, hr);
m_needsFullFlush = true;
}
@@ -217,11 +216,11 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
return;
HRESULT hr = m_swapChain->ResizeBuffers(0,
- size.width(), size.height(),
+ UINT(size.width()), UINT(size.height()),
DXGI_FORMAT_UNKNOWN,
0);
if (FAILED(hr))
- qWarning("%s: Could not resize swap chain: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not resize swap chain: %#lx", __FUNCTION__, hr);
}
QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() const
@@ -248,13 +247,13 @@ QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer()
HRESULT hr = m_deviceContext.Get()->CreateBitmap(size, NULL, 0, properties, &copy);
if (FAILED(hr)) {
- qWarning("%s: Could not create staging bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create staging bitmap: %#lx", __FUNCTION__, hr);
return null_result;
}
hr = copy.Get()->CopyFromBitmap(NULL, m_bitmap->bitmap(), NULL);
if (FAILED(hr)) {
- qWarning("%s: Could not copy from bitmap! %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not copy from bitmap! %#lx", __FUNCTION__, hr);
return null_result;
}
@@ -277,12 +276,12 @@ void QWindowsDirect2DWindow::setupBitmap()
if (m_directRendering) {
hr = m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBufferSurface));
if (FAILED(hr)) {
- qWarning("%s: Could not query backbuffer for DXGI Surface: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not query backbuffer for DXGI Surface: %#lx", __FUNCTION__, hr);
return;
}
} else {
const QRect rect = geometry();
- CD3D11_TEXTURE2D_DESC backBufferDesc(DXGI_FORMAT_B8G8R8A8_UNORM, rect.width(), rect.height(), 1, 1);
+ CD3D11_TEXTURE2D_DESC backBufferDesc(DXGI_FORMAT_B8G8R8A8_UNORM, UINT(rect.width()), UINT(rect.height()), 1, 1);
backBufferDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
backBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
ComPtr<ID3D11Texture2D> backBufferTexture;
@@ -302,7 +301,7 @@ void QWindowsDirect2DWindow::setupBitmap()
ComPtr<ID2D1Bitmap1> backBufferBitmap;
hr = m_deviceContext->CreateBitmapFromDxgiSurface(backBufferSurface.Get(), NULL, backBufferBitmap.GetAddressOf());
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D Bitmap from DXGI Surface: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D Bitmap from DXGI Surface: %#lx", __FUNCTION__, hr);
return;
}
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
index 2da0e5f507..156d4660d1 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
@@ -74,8 +74,8 @@ private:
Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_deviceContext;
QScopedPointer<QWindowsDirect2DBitmap> m_bitmap;
QScopedPointer<QPixmap> m_pixmap;
- bool m_needsFullFlush;
- bool m_directRendering;
+ bool m_needsFullFlush = true;
+ bool m_directRendering = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro
index 255db824b7..e522c0ee1b 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro
@@ -4,7 +4,7 @@ PLUGIN_TYPE = egldeviceintegrations
PLUGIN_CLASS_NAME = QEglFSKmsGbmIntegrationPlugin
load(qt_plugin)
-QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private
+QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private
INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
index 3a220ec942..2040d6bc0e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
@@ -46,7 +46,6 @@
#include <QtCore/QLoggingCategory>
#include <QtCore/private/qcore_unix_p.h>
-#include <QtGui/private/qguiapplication_p.h>
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
@@ -65,8 +64,8 @@ void QEglFSKmsGbmDevice::pageFlipHandler(int fd, unsigned int sequence, unsigned
screen->flipFinished();
}
-QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QEglFSKmsIntegration *integration, const QString &path)
- : QEglFSKmsDevice(integration, path)
+QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path)
+ : QEglFSKmsDevice(screenConfig, path)
, m_gbm_device(Q_NULLPTR)
, m_globalCursor(Q_NULLPTR)
{
@@ -77,7 +76,6 @@ bool QEglFSKmsGbmDevice::open()
Q_ASSERT(fd() == -1);
Q_ASSERT(m_gbm_device == Q_NULLPTR);
- qCDebug(qLcEglfsKmsDebug) << "Opening device" << devicePath();
int fd = qt_safe_open(devicePath().toLocal8Bit().constData(), O_RDWR | O_CLOEXEC);
if (fd == -1) {
qErrnoWarning("Could not open DRM device %s", qPrintable(devicePath()));
@@ -101,6 +99,8 @@ bool QEglFSKmsGbmDevice::open()
void QEglFSKmsGbmDevice::close()
{
+ // Note: screens are gone at this stage.
+
if (m_gbm_device) {
gbm_device_destroy(m_gbm_device);
m_gbm_device = Q_NULLPTR;
@@ -110,15 +110,11 @@ void QEglFSKmsGbmDevice::close()
qt_safe_close(fd());
setFd(-1);
}
-
- if (m_globalCursor)
- m_globalCursor->deleteLater();
- m_globalCursor = Q_NULLPTR;
}
-EGLNativeDisplayType QEglFSKmsGbmDevice::nativeDisplay() const
+void *QEglFSKmsGbmDevice::nativeDisplay() const
{
- return reinterpret_cast<EGLNativeDisplayType>(m_gbm_device);
+ return m_gbm_device;
}
gbm_device * QEglFSKmsGbmDevice::gbmDevice() const
@@ -131,6 +127,17 @@ QPlatformCursor *QEglFSKmsGbmDevice::globalCursor() const
return m_globalCursor;
}
+// Cannot do this from close(), it may be too late.
+// Call this from the last screen dtor instead.
+void QEglFSKmsGbmDevice::destroyGlobalCursor()
+{
+ if (m_globalCursor) {
+ qCDebug(qLcEglfsKmsDebug, "Destroying global GBM mouse cursor");
+ delete m_globalCursor;
+ m_globalCursor = Q_NULLPTR;
+ }
+}
+
void QEglFSKmsGbmDevice::handleDrmEvent()
{
drmEventContext drmEvent = {
@@ -142,14 +149,13 @@ void QEglFSKmsGbmDevice::handleDrmEvent()
drmHandleEvent(fd(), &drmEvent);
}
-QEglFSKmsScreen *QEglFSKmsGbmDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output)
+QPlatformScreen *QEglFSKmsGbmDevice::createScreen(const QKmsOutput &output)
{
- static bool firstScreen = true;
- QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(integration, device, output);
+ QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(this, output);
- if (firstScreen && integration->hwCursor()) {
+ if (!m_globalCursor && screenConfig()->hwCursor()) {
+ qCDebug(qLcEglfsKmsDebug, "Creating new global GBM mouse cursor");
m_globalCursor = new QEglFSKmsGbmCursor(screen);
- firstScreen = false;
}
return screen;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
index 7c0af84422..25284c6468 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
@@ -43,7 +43,7 @@
#define QEGLFSKMSGBMDEVICE_H
#include "qeglfskmsgbmcursor.h"
-#include "qeglfskmsdevice.h"
+#include <qeglfskmsdevice.h>
#include <gbm.h>
@@ -54,21 +54,20 @@ class QEglFSKmsScreen;
class QEglFSKmsGbmDevice: public QEglFSKmsDevice
{
public:
- QEglFSKmsGbmDevice(QEglFSKmsIntegration *integration, const QString &path);
+ QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path);
bool open() Q_DECL_OVERRIDE;
void close() Q_DECL_OVERRIDE;
- EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
+ void *nativeDisplay() const Q_DECL_OVERRIDE;
gbm_device *gbmDevice() const;
QPlatformCursor *globalCursor() const;
+ void destroyGlobalCursor();
void handleDrmEvent();
- virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output) Q_DECL_OVERRIDE;
+ QPlatformScreen *createScreen(const QKmsOutput &output) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QEglFSKmsGbmDevice)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
index 38419a55c8..16767114ab 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
@@ -63,8 +63,9 @@ QT_BEGIN_NAMESPACE
QMutex QEglFSKmsGbmScreen::m_waitForFlipMutex;
QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration()
- : QEglFSKmsIntegration()
-{}
+{
+ qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via GBM integration created");
+}
EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeWindow(QPlatformWindow *platformWindow,
const QSize &size,
@@ -104,10 +105,12 @@ void QEglFSKmsGbmIntegration::destroyNativeWindow(EGLNativeWindowType window)
QPlatformCursor *QEglFSKmsGbmIntegration::createCursor(QPlatformScreen *screen) const
{
- if (hwCursor())
- return Q_NULLPTR;
- else
+ if (screenConfig()->hwCursor()) {
+ return nullptr;
+ } else {
+ qCDebug(qLcEglfsKmsDebug, "Using plain OpenGL mouse cursor");
return new QEglFSCursor(screen);
+ }
}
void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface)
@@ -118,13 +121,12 @@ void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface)
screen->flip();
}
-QEglFSKmsDevice *QEglFSKmsGbmIntegration::createDevice(const QString &devicePath)
+QKmsDevice *QEglFSKmsGbmIntegration::createDevice()
{
- QString path = devicePath;
- if (!devicePath.isEmpty()) {
- qCDebug(qLcEglfsKmsDebug) << "Using DRM device" << path << "specified in config file";
+ QString path = screenConfig()->devicePath();
+ if (!path.isEmpty()) {
+ qCDebug(qLcEglfsKmsDebug) << "GBM: Using DRM device" << path << "specified in config file";
} else {
-
QDeviceDiscovery *d = QDeviceDiscovery::create(QDeviceDiscovery::Device_VideoMask);
const QStringList devices = d->scanConnectedDevices();
qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices;
@@ -137,7 +139,7 @@ QEglFSKmsDevice *QEglFSKmsGbmIntegration::createDevice(const QString &devicePath
qCDebug(qLcEglfsKmsDebug) << "Using" << path;
}
- return new QEglFSKmsGbmDevice(this, path);
+ return new QEglFSKmsGbmDevice(screenConfig(), path);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
index 727571d3e3..fa2e494a89 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
@@ -65,7 +65,7 @@ public:
void presentBuffer(QPlatformSurface *surface) Q_DECL_OVERRIDE;
protected:
- QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE;
+ QKmsDevice *createDevice() Q_DECL_OVERRIDE;
private:
};
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
index bed775ff81..ebce0a4776 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
@@ -92,10 +92,8 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject(
return fb.take();
}
-QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output)
- : QEglFSKmsScreen(integration, device, output)
+QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output)
+ : QEglFSKmsScreen(device, output)
, m_gbm_surface(Q_NULLPTR)
, m_gbm_bo_current(Q_NULLPTR)
, m_gbm_bo_next(Q_NULLPTR)
@@ -105,12 +103,17 @@ QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration,
QEglFSKmsGbmScreen::~QEglFSKmsGbmScreen()
{
+ const int remainingScreenCount = qGuiApp->screens().count();
+ qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount);
+ if (!remainingScreenCount && !device()->screenConfig()->separateScreens())
+ static_cast<QEglFSKmsGbmDevice *>(device())->destroyGlobalCursor();
}
QPlatformCursor *QEglFSKmsGbmScreen::cursor() const
{
- if (integration()->hwCursor()) {
- if (!integration()->separateScreens())
+ QKmsScreenConfig *config = device()->screenConfig();
+ if (config->hwCursor()) {
+ if (!config->separateScreens())
return static_cast<QEglFSKmsGbmDevice *>(device())->globalCursor();
if (m_cursor.isNull()) {
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
index d7ad348291..ffc96955d4 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
@@ -54,9 +54,7 @@ class QEglFSKmsGbmCursor;
class QEglFSKmsGbmScreen : public QEglFSKmsScreen
{
public:
- QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output);
+ QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output);
~QEglFSKmsGbmScreen();
QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro
index a625021aba..a2dc9c4a50 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro
@@ -1,6 +1,6 @@
TARGET = qeglfs-kms-egldevice-integration
-QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private
+QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private
INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp
index 60989e2bd0..f0bf59466e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp
@@ -40,14 +40,16 @@
#include "qeglfskmsegldevice.h"
#include "qeglfskmsegldevicescreen.h"
#include "qeglfskmsegldeviceintegration.h"
+#include "private/qeglfsintegration_p.h"
#include "private/qeglfscursor_p.h"
#include <QtCore/private/qcore_unix_p.h>
QT_BEGIN_NAMESPACE
-QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path)
- : QEglFSKmsDevice(integration, path),
+QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsEglDeviceIntegration *devInt, QKmsScreenConfig *screenConfig, const QString &path)
+ : QEglFSKmsDevice(screenConfig, path),
+ m_devInt(devInt),
m_globalCursor(nullptr)
{
}
@@ -56,11 +58,9 @@ bool QEglFSKmsEglDevice::open()
{
Q_ASSERT(fd() == -1);
- qCDebug(qLcEglfsKmsDebug, "Opening DRM device %s", qPrintable(devicePath()));
-
int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR);
if (Q_UNLIKELY(fd < 0))
- qFatal("Could not open DRM device");
+ qFatal("Could not open DRM (NV) device");
setFd(fd);
@@ -69,25 +69,24 @@ bool QEglFSKmsEglDevice::open()
void QEglFSKmsEglDevice::close()
{
- qCDebug(qLcEglfsKmsDebug, "Closing DRM device");
+ // Note: screens are gone at this stage.
if (qt_safe_close(fd()) == -1)
- qErrnoWarning("Could not close DRM device");
+ qErrnoWarning("Could not close DRM (NV) device");
setFd(-1);
}
EGLNativeDisplayType QEglFSKmsEglDevice::nativeDisplay() const
{
- return reinterpret_cast<EGLNativeDisplayType>(static_cast<QEglFSKmsEglDeviceIntegration *>(m_integration)->eglDevice());
+ return reinterpret_cast<EGLNativeDisplayType>(m_devInt->eglDevice());
}
-QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device,
- QEglFSKmsOutput output)
+QPlatformScreen *QEglFSKmsEglDevice::createScreen(const QKmsOutput &output)
{
- QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(integration, device, output);
+ QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(this, output);
- if (!m_globalCursor && !integration->separateScreens()) {
+ if (!m_globalCursor && !screenConfig()->separateScreens()) {
qCDebug(qLcEglfsKmsDebug, "Creating new global mouse cursor");
m_globalCursor = new QEglFSCursor(screen);
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h
index 8c8f79f70c..b9304b8502 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h
@@ -45,25 +45,25 @@
QT_BEGIN_NAMESPACE
class QPlatformCursor;
+class QEglFSKmsEglDeviceIntegration;
class QEglFSKmsEglDevice: public QEglFSKmsDevice
{
public:
- QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path);
+ QEglFSKmsEglDevice(QEglFSKmsEglDeviceIntegration *devInt, QKmsScreenConfig *screenConfig, const QString &path);
- virtual bool open() Q_DECL_OVERRIDE;
- virtual void close() Q_DECL_OVERRIDE;
+ bool open() Q_DECL_OVERRIDE;
+ void close() Q_DECL_OVERRIDE;
- virtual EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
+ void *nativeDisplay() const Q_DECL_OVERRIDE;
- virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output) Q_DECL_OVERRIDE;
+ QPlatformScreen *createScreen(const QKmsOutput &output) Q_DECL_OVERRIDE;
QPlatformCursor *globalCursor() { return m_globalCursor; }
void destroyGlobalCursor();
private:
+ QEglFSKmsEglDeviceIntegration *m_devInt;
QPlatformCursor *m_globalCursor;
};
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
index d0c9c9565e..36fbfbd05c 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
@@ -50,8 +50,7 @@
QT_BEGIN_NAMESPACE
QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration()
- : QEglFSKmsIntegration()
- , m_egl_device(EGL_NO_DEVICE_EXT)
+ : m_egl_device(EGL_NO_DEVICE_EXT)
, m_funcs(Q_NULLPTR)
{
qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created");
@@ -101,10 +100,10 @@ bool QEglFSKmsEglDeviceIntegration::supportsPBuffers() const
return true;
}
-class QEglJetsonTK1Window : public QEglFSWindow
+class QEglFSKmsEglDeviceWindow : public QEglFSWindow
{
public:
- QEglJetsonTK1Window(QWindow *w, const QEglFSKmsEglDeviceIntegration *integration)
+ QEglFSKmsEglDeviceWindow(QWindow *w, const QEglFSKmsEglDeviceIntegration *integration)
: QEglFSWindow(w)
, m_integration(integration)
, m_egl_stream(EGL_NO_STREAM_KHR)
@@ -118,13 +117,13 @@ public:
EGLint m_latency;
};
-void QEglJetsonTK1Window::invalidateSurface()
+void QEglFSKmsEglDeviceWindow::invalidateSurface()
{
QEglFSWindow::invalidateSurface();
m_integration->m_funcs->destroy_stream(screen()->display(), m_egl_stream);
}
-void QEglJetsonTK1Window::resetSurface()
+void QEglFSKmsEglDeviceWindow::resetSurface()
{
qCDebug(qLcEglfsKmsDebug, "Creating stream");
@@ -213,7 +212,7 @@ void QEglJetsonTK1Window::resetSurface()
QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const
{
- QEglJetsonTK1Window *eglWindow = new QEglJetsonTK1Window(window, this);
+ QEglFSKmsEglDeviceWindow *eglWindow = new QEglFSKmsEglDeviceWindow(window, this);
m_funcs->initialize(eglWindow->screen()->display());
if (Q_UNLIKELY(!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm && m_funcs->has_egl_stream &&
@@ -223,10 +222,8 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const
return eglWindow;
}
-QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devicePath)
+QKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice()
{
- Q_UNUSED(devicePath)
-
if (Q_UNLIKELY(!query_egl_device()))
qFatal("Could not set up EGL device!");
@@ -234,7 +231,7 @@ QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devi
if (Q_UNLIKELY(!deviceName))
qFatal("Failed to query device name from EGLDevice");
- return new QEglFSKmsEglDevice(this, deviceName);
+ return new QEglFSKmsEglDevice(this, screenConfig(), deviceName);
}
bool QEglFSKmsEglDeviceIntegration::query_egl_device()
@@ -261,7 +258,7 @@ bool QEglFSKmsEglDeviceIntegration::query_egl_device()
QPlatformCursor *QEglFSKmsEglDeviceIntegration::createCursor(QPlatformScreen *screen) const
{
- return separateScreens() ? new QEglFSCursor(screen) : nullptr;
+ return screenConfig()->separateScreens() ? new QEglFSCursor(screen) : nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
index cddfdbd5c6..a274474433 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
@@ -64,7 +64,7 @@ public:
EGLDeviceEXT eglDevice() const { return m_egl_device; }
protected:
- QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE;
+ QKmsDevice *createDevice() Q_DECL_OVERRIDE;
QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE;
private:
@@ -72,10 +72,9 @@ private:
bool query_egl_device();
EGLDeviceEXT m_egl_device;
-
- friend class QEglJetsonTK1Window;
- // EGLStream infrastructure
QEGLStreamConvenience *m_funcs;
+
+ friend class QEglFSKmsEglDeviceWindow;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
index 1f672afeb4..532ec0b440 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
@@ -40,11 +40,14 @@
#include "qeglfskmsegldevicescreen.h"
#include "qeglfskmsegldevice.h"
#include <QGuiApplication>
+#include <QLoggingCategory>
QT_BEGIN_NAMESPACE
-QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output)
- : QEglFSKmsScreen(integration, device, output)
+Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
+
+QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output)
+ : QEglFSKmsScreen(device, output)
{
}
@@ -52,7 +55,7 @@ QEglFSKmsEglDeviceScreen::~QEglFSKmsEglDeviceScreen()
{
const int remainingScreenCount = qGuiApp->screens().count();
qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount);
- if (!remainingScreenCount && !m_integration->separateScreens())
+ if (!remainingScreenCount && !device()->screenConfig()->separateScreens())
static_cast<QEglFSKmsEglDevice *>(device())->destroyGlobalCursor();
}
@@ -62,7 +65,10 @@ QPlatformCursor *QEglFSKmsEglDeviceScreen::cursor() const
// in its ctor. With separateScreens just use that. Otherwise
// there's a virtual desktop and the device has a global cursor
// and the base class has no dedicated cursor at all.
- return m_integration->separateScreens() ? QEglFSScreen::cursor() : static_cast<QEglFSKmsEglDevice *>(device())->globalCursor();
+ // config->hwCursor() is ignored for now, just use the standard OpenGL cursor.
+ return device()->screenConfig()->separateScreens()
+ ? QEglFSScreen::cursor()
+ : static_cast<QEglFSKmsEglDevice *>(device())->globalCursor();
}
void QEglFSKmsEglDeviceScreen::waitForFlip()
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
index c57f52c6b7..1655a3f038 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
@@ -47,9 +47,7 @@ QT_BEGIN_NAMESPACE
class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen
{
public:
- QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output);
+ QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output);
~QEglFSKmsEglDeviceScreen();
QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
index 487edb569e..3c0a0ce30f 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
@@ -2,7 +2,7 @@ TARGET = QtEglFsKmsSupport
CONFIG += no_module_headers internal_module
load(qt_module)
-QT += core-private gui-private eglfsdeviceintegration-private
+QT += core-private gui-private eglfsdeviceintegration-private kms_support-private
INCLUDEPATH += $$PWD/../../api
@@ -15,8 +15,8 @@ QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfskmsintegration.cpp \
$$PWD/qeglfskmsdevice.cpp \
- $$PWD/qeglfskmsscreen.cpp \
+ $$PWD/qeglfskmsscreen.cpp
HEADERS += $$PWD/qeglfskmsintegration.h \
$$PWD/qeglfskmsdevice.h \
- $$PWD/qeglfskmsscreen.h \
+ $$PWD/qeglfskmsscreen.h
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
index f6b58d1ba6..e99a6957a8 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
@@ -1,6 +1,5 @@
/****************************************************************************
**
-** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Pelagicore AG
** Contact: https://www.qt.io/licensing/
@@ -41,432 +40,24 @@
#include "qeglfskmsdevice.h"
#include "qeglfskmsscreen.h"
-
-#include "qeglfsintegration_p.h"
-
-#include <QtCore/QLoggingCategory>
-#include <QtCore/private/qcore_unix_p.h>
+#include "private/qeglfsintegration_p.h"
#include <QtGui/private/qguiapplication_p.h>
-#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
-
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
-
-enum OutputConfiguration {
- OutputConfigOff,
- OutputConfigPreferred,
- OutputConfigCurrent,
- OutputConfigMode,
- OutputConfigModeline
-};
-
-int QEglFSKmsDevice::crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector)
-{
- for (int i = 0; i < connector->count_encoders; i++) {
- drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->encoders[i]);
- if (!encoder) {
- qWarning("Failed to get encoder");
- continue;
- }
-
- quint32 possibleCrtcs = encoder->possible_crtcs;
- drmModeFreeEncoder(encoder);
-
- for (int j = 0; j < resources->count_crtcs; j++) {
- bool isPossible = possibleCrtcs & (1 << j);
- bool isAvailable = !(m_crtc_allocator & 1 << resources->crtcs[j]);
-
- if (isPossible && isAvailable)
- return j;
- }
- }
-
- return -1;
-}
-
-static const char * const connector_type_names[] = { // must match DRM_MODE_CONNECTOR_*
- "None",
- "VGA",
- "DVI",
- "DVI",
- "DVI",
- "Composite",
- "TV",
- "LVDS",
- "CTV",
- "DIN",
- "DP",
- "HDMI",
- "HDMI",
- "TV",
- "eDP",
- "Virtual",
- "DSI"
-};
-
-static QByteArray nameForConnector(const drmModeConnectorPtr connector)
-{
- QByteArray connectorName("UNKNOWN");
-
- if (connector->connector_type < ARRAY_LENGTH(connector_type_names))
- connectorName = connector_type_names[connector->connector_type];
-
- connectorName += QByteArray::number(connector->connector_type_id);
-
- return connectorName;
-}
-
-static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode)
-{
- char hsync[16];
- char vsync[16];
- float fclock;
-
- mode->type = DRM_MODE_TYPE_USERDEF;
- mode->hskew = 0;
- mode->vscan = 0;
- mode->vrefresh = 0;
- mode->flags = 0;
-
- if (sscanf(text.constData(), "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
- &fclock,
- &mode->hdisplay,
- &mode->hsync_start,
- &mode->hsync_end,
- &mode->htotal,
- &mode->vdisplay,
- &mode->vsync_start,
- &mode->vsync_end,
- &mode->vtotal, hsync, vsync) != 11)
- return false;
-
- mode->clock = fclock * 1000;
-
- if (strcmp(hsync, "+hsync") == 0)
- mode->flags |= DRM_MODE_FLAG_PHSYNC;
- else if (strcmp(hsync, "-hsync") == 0)
- mode->flags |= DRM_MODE_FLAG_NHSYNC;
- else
- return false;
-
- if (strcmp(vsync, "+vsync") == 0)
- mode->flags |= DRM_MODE_FLAG_PVSYNC;
- else if (strcmp(vsync, "-vsync") == 0)
- mode->flags |= DRM_MODE_FLAG_NVSYNC;
- else
- return false;
-
- return true;
-}
-
-QEglFSKmsScreen *QEglFSKmsDevice::createScreenForConnector(drmModeResPtr resources,
- drmModeConnectorPtr connector,
- VirtualDesktopInfo *vinfo)
-{
- const QByteArray connectorName = nameForConnector(connector);
-
- const int crtc = crtcForConnector(resources, connector);
- if (crtc < 0) {
- qWarning() << "No usable crtc/encoder pair for connector" << connectorName;
- return Q_NULLPTR;
- }
-
- OutputConfiguration configuration;
- QSize configurationSize;
- drmModeModeInfo configurationModeline;
-
- auto userConfig = m_integration->outputSettings();
- auto userConnectorConfig = userConfig.value(QString::fromUtf8(connectorName));
- // default to the preferred mode unless overridden in the config
- const QByteArray mode = userConnectorConfig.value(QStringLiteral("mode"), QStringLiteral("preferred"))
- .toByteArray().toLower();
- if (mode == "off") {
- configuration = OutputConfigOff;
- } else if (mode == "preferred") {
- configuration = OutputConfigPreferred;
- } else if (mode == "current") {
- configuration = OutputConfigCurrent;
- } else if (sscanf(mode.constData(), "%dx%d", &configurationSize.rwidth(), &configurationSize.rheight()) == 2) {
- configuration = OutputConfigMode;
- } else if (parseModeline(mode, &configurationModeline)) {
- configuration = OutputConfigModeline;
- } else {
- qWarning("Invalid mode \"%s\" for output %s", mode.constData(), connectorName.constData());
- configuration = OutputConfigPreferred;
- }
- if (vinfo) {
- *vinfo = VirtualDesktopInfo();
- vinfo->virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt();
- if (userConnectorConfig.contains(QStringLiteral("virtualPos"))) {
- const QByteArray vpos = userConnectorConfig.value(QStringLiteral("virtualPos")).toByteArray();
- const QByteArrayList vposComp = vpos.split(',');
- if (vposComp.count() == 2)
- vinfo->virtualPos = QPoint(vposComp[0].trimmed().toInt(), vposComp[1].trimmed().toInt());
- }
- }
-
- const uint32_t crtc_id = resources->crtcs[crtc];
-
- if (configuration == OutputConfigOff) {
- qCDebug(qLcEglfsKmsDebug) << "Turning off output" << connectorName;
- drmModeSetCrtc(m_dri_fd, crtc_id, 0, 0, 0, 0, 0, Q_NULLPTR);
- return Q_NULLPTR;
- }
-
- // Skip disconnected output
- if (configuration == OutputConfigPreferred && connector->connection == DRM_MODE_DISCONNECTED) {
- qCDebug(qLcEglfsKmsDebug) << "Skipping disconnected output" << connectorName;
- return Q_NULLPTR;
- }
-
- // Get the current mode on the current crtc
- drmModeModeInfo crtc_mode;
- memset(&crtc_mode, 0, sizeof crtc_mode);
- if (drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->connector_id)) {
- drmModeCrtcPtr crtc = drmModeGetCrtc(m_dri_fd, encoder->crtc_id);
- drmModeFreeEncoder(encoder);
-
- if (!crtc)
- return Q_NULLPTR;
-
- if (crtc->mode_valid)
- crtc_mode = crtc->mode;
-
- drmModeFreeCrtc(crtc);
- }
-
- QList<drmModeModeInfo> modes;
- modes.reserve(connector->count_modes);
- qCDebug(qLcEglfsKmsDebug) << connectorName << "mode count:" << connector->count_modes;
- for (int i = 0; i < connector->count_modes; i++) {
- const drmModeModeInfo &mode = connector->modes[i];
- qCDebug(qLcEglfsKmsDebug) << "mode" << i << mode.hdisplay << "x" << mode.vdisplay
- << '@' << mode.vrefresh << "hz";
- modes << connector->modes[i];
- }
-
- int preferred = -1;
- int current = -1;
- int configured = -1;
- int best = -1;
-
- for (int i = modes.size() - 1; i >= 0; i--) {
- const drmModeModeInfo &m = modes.at(i);
-
- if (configuration == OutputConfigMode &&
- m.hdisplay == configurationSize.width() &&
- m.vdisplay == configurationSize.height()) {
- configured = i;
- }
-
- if (!memcmp(&crtc_mode, &m, sizeof m))
- current = i;
-
- if (m.type & DRM_MODE_TYPE_PREFERRED)
- preferred = i;
-
- best = i;
- }
-
- if (configuration == OutputConfigModeline) {
- modes << configurationModeline;
- configured = modes.size() - 1;
- }
-
- if (current < 0 && crtc_mode.clock != 0) {
- modes << crtc_mode;
- current = mode.size() - 1;
- }
-
- if (configuration == OutputConfigCurrent)
- configured = current;
-
- int selected_mode = -1;
-
- if (configured >= 0)
- selected_mode = configured;
- else if (preferred >= 0)
- selected_mode = preferred;
- else if (current >= 0)
- selected_mode = current;
- else if (best >= 0)
- selected_mode = best;
-
- if (selected_mode < 0) {
- qWarning() << "No modes available for output" << connectorName;
- return Q_NULLPTR;
- } else {
- int width = modes[selected_mode].hdisplay;
- int height = modes[selected_mode].vdisplay;
- int refresh = modes[selected_mode].vrefresh;
- qCDebug(qLcEglfsKmsDebug) << "Selected mode" << selected_mode << ":" << width << "x" << height
- << '@' << refresh << "hz for output" << connectorName;
- }
-
- // physical size from connector < config values < env vars
- static const int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH");
- static const int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT");
- QSizeF physSize(width, height);
- if (physSize.isEmpty()) {
- physSize = QSize(userConnectorConfig.value(QStringLiteral("physicalWidth")).toInt(),
- userConnectorConfig.value(QStringLiteral("physicalHeight")).toInt());
- if (physSize.isEmpty()) {
- physSize.setWidth(connector->mmWidth);
- physSize.setHeight(connector->mmHeight);
- }
- }
- qCDebug(qLcEglfsKmsDebug) << "Physical size is" << physSize << "mm" << "for output" << connectorName;
-
- QEglFSKmsOutput output = {
- QString::fromUtf8(connectorName),
- connector->connector_id,
- crtc_id,
- physSize,
- selected_mode,
- false,
- drmModeGetCrtc(m_dri_fd, crtc_id),
- modes,
- connector->subpixel,
- connectorProperty(connector, QByteArrayLiteral("DPMS"))
- };
-
- m_crtc_allocator |= (1 << output.crtc_id);
- m_connector_allocator |= (1 << output.connector_id);
-
- return createScreen(m_integration, this, output);
-}
-
-drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name)
-{
- drmModePropertyPtr prop;
-
- for (int i = 0; i < connector->count_props; i++) {
- prop = drmModeGetProperty(m_dri_fd, connector->props[i]);
- if (!prop)
- continue;
- if (strcmp(prop->name, name.constData()) == 0)
- return prop;
- drmModeFreeProperty(prop);
- }
-
- return Q_NULLPTR;
-}
-
-QEglFSKmsDevice::QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path)
- : m_integration(integration)
- , m_path(path)
- , m_dri_fd(-1)
- , m_crtc_allocator(0)
- , m_connector_allocator(0)
-{
-}
-
-QEglFSKmsDevice::~QEglFSKmsDevice()
-{
-}
-
-struct OrderedScreen
-{
- OrderedScreen() : screen(nullptr) { }
- OrderedScreen(QEglFSKmsScreen *screen, const QEglFSKmsDevice::VirtualDesktopInfo &vinfo)
- : screen(screen), vinfo(vinfo) { }
- QEglFSKmsScreen *screen;
- QEglFSKmsDevice::VirtualDesktopInfo vinfo;
-};
-
-QDebug operator<<(QDebug dbg, const OrderedScreen &s)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace() << "OrderedScreen(" << s.screen << " : " << s.vinfo.virtualIndex
- << " / " << s.vinfo.virtualPos << ")";
- return dbg;
-}
-
-static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b)
-{
- return a.vinfo.virtualIndex < b.vinfo.virtualIndex;
-}
-
-void QEglFSKmsDevice::createScreens()
-{
- drmModeResPtr resources = drmModeGetResources(m_dri_fd);
- if (!resources) {
- qWarning("drmModeGetResources failed");
- return;
- }
-
- QVector<OrderedScreen> screens;
-
- for (int i = 0; i < resources->count_connectors; i++) {
- drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]);
- if (!connector)
- continue;
-
- VirtualDesktopInfo vinfo;
- QEglFSKmsScreen *screen = createScreenForConnector(resources, connector, &vinfo);
- if (screen)
- screens.append(OrderedScreen(screen, vinfo));
-
- drmModeFreeConnector(connector);
- }
-
- drmModeFreeResources(resources);
-
- // Use stable sort to preserve the original order for outputs with unspecified indices.
- std::stable_sort(screens.begin(), screens.end(), orderedScreenLessThan);
- qCDebug(qLcEglfsKmsDebug) << "Sorted screen list:" << screens;
-
- QPoint pos(0, 0);
- QList<QPlatformScreen *> siblings;
- QEglFSIntegration *qpaIntegration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
-
- for (const OrderedScreen &orderedScreen : screens) {
- QEglFSKmsScreen *s = orderedScreen.screen;
- // set up a horizontal or vertical virtual desktop
- if (orderedScreen.vinfo.virtualPos.isNull()) {
- s->setVirtualPosition(pos);
- if (m_integration->virtualDesktopLayout() == QEglFSKmsIntegration::VirtualDesktopLayoutVertical)
- pos.ry() += s->geometry().height();
- else
- pos.rx() += s->geometry().width();
- } else {
- s->setVirtualPosition(orderedScreen.vinfo.virtualPos);
- }
- qCDebug(qLcEglfsKmsDebug) << "Adding screen" << s << "to QPA with geometry" << s->geometry();
- // The order in qguiapp's screens list will match the order set by
- // virtualIndex. This is not only handy but also required since for instance
- // evdevtouch relies on it when performing touch device - screen mapping.
- qpaIntegration->addScreen(s);
- siblings << s;
- }
-
- if (!m_integration->separateScreens()) {
- // enable the virtual desktop
- Q_FOREACH (QPlatformScreen *screen, siblings)
- static_cast<QEglFSKmsScreen *>(screen)->setVirtualSiblings(siblings);
- }
-}
-
-int QEglFSKmsDevice::fd() const
-{
- return m_dri_fd;
-}
-
-QString QEglFSKmsDevice::devicePath() const
-{
- return m_path;
-}
-
-QEglFSKmsScreen *QEglFSKmsDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output)
+QEglFSKmsDevice::QEglFSKmsDevice(QKmsScreenConfig *screenConfig, const QString &path)
+ : QKmsDevice(screenConfig, path)
{
- return new QEglFSKmsScreen(integration, device, output);
}
-void QEglFSKmsDevice::setFd(int fd)
+void QEglFSKmsDevice::registerScreen(QPlatformScreen *screen,
+ const QPoint &virtualPos,
+ const QList<QPlatformScreen *> &virtualSiblings)
{
- m_dri_fd = fd;
+ QEglFSKmsScreen *s = static_cast<QEglFSKmsScreen *>(screen);
+ s->setVirtualPosition(virtualPos);
+ s->setVirtualSiblings(virtualSiblings);
+ static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->addScreen(s);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
index 3e7ac7e3f0..1bbea250bb 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
@@ -1,6 +1,5 @@
/****************************************************************************
**
-** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Pelagicore AG
** Contact: https://www.qt.io/licensing/
@@ -42,64 +41,21 @@
#ifndef QEGLFSKMSDEVICE_H
#define QEGLFSKMSDEVICE_H
-#include "qeglfskmsintegration.h"
-#include "qeglfskmsscreen.h"
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
+#include "private/qeglfsglobal_p.h"
+#include <QtKmsSupport/private/qkmsdevice_p.h>
QT_BEGIN_NAMESPACE
-class Q_EGLFS_EXPORT QEglFSKmsDevice
+class Q_EGLFS_EXPORT QEglFSKmsDevice : public QKmsDevice
{
public:
- struct VirtualDesktopInfo {
- VirtualDesktopInfo() : virtualIndex(0) { }
- int virtualIndex;
- QPoint virtualPos;
- };
-
- QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path);
- virtual ~QEglFSKmsDevice();
-
- virtual bool open() = 0;
- virtual void close() = 0;
-
- virtual void createScreens();
-
- virtual EGLNativeDisplayType nativeDisplay() const = 0;
- int fd() const;
- QString devicePath() const;
-
-protected:
- virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output);
- void setFd(int fd);
-
- QEglFSKmsIntegration *m_integration;
- QString m_path;
- int m_dri_fd;
-
- quint32 m_crtc_allocator;
- quint32 m_connector_allocator;
-
- int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector);
- QEglFSKmsScreen *createScreenForConnector(drmModeResPtr resources,
- drmModeConnectorPtr connector,
- VirtualDesktopInfo *vinfo);
- drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name);
-
- static void pageFlipHandler(int fd,
- unsigned int sequence,
- unsigned int tv_sec,
- unsigned int tv_usec,
- void *user_data);
+ QEglFSKmsDevice(QKmsScreenConfig *screenConfig, const QString &path);
-private:
- Q_DISABLE_COPY(QEglFSKmsDevice)
+ void registerScreen(QPlatformScreen *screen,
+ const QPoint &virtualPos,
+ const QList<QPlatformScreen *> &virtualSiblings) override;
};
QT_END_NAMESPACE
-#endif
+#endif // QEGLFSKMSDEVICE_H
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
index 5368a6d031..c77151181e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
@@ -40,13 +40,10 @@
****************************************************************************/
#include "qeglfskmsintegration.h"
-#include "qeglfskmsdevice.h"
#include "qeglfskmsscreen.h"
-#include <QtCore/QJsonDocument>
-#include <QtCore/QJsonObject>
-#include <QtCore/QJsonArray>
-#include <QtCore/QFile>
+#include <QtKmsSupport/private/qkmsdevice_p.h>
+
#include <QtGui/qpa/qplatformwindow.h>
#include <QtGui/QScreen>
@@ -58,28 +55,27 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "qt.qpa.eglfs.kms")
QEglFSKmsIntegration::QEglFSKmsIntegration()
- : m_device(Q_NULLPTR)
- , m_hwCursor(false)
- , m_pbuffers(false)
- , m_separateScreens(false)
- , m_virtualDesktopLayout(VirtualDesktopLayoutHorizontal)
-{}
-
-void QEglFSKmsIntegration::platformInit()
+ : m_device(Q_NULLPTR),
+ m_screenConfig(new QKmsScreenConfig)
{
- loadConfig();
+}
- if (!m_devicePath.isEmpty()) {
- qCDebug(qLcEglfsKmsDebug) << "Using DRM device" << m_devicePath << "specified in config file";
- }
+QEglFSKmsIntegration::~QEglFSKmsIntegration()
+{
+ delete m_screenConfig;
+}
- m_device = createDevice(m_devicePath);
+void QEglFSKmsIntegration::platformInit()
+{
+ qCDebug(qLcEglfsKmsDebug, "platformInit: Opening DRM device");
+ m_device = createDevice();
if (Q_UNLIKELY(!m_device->open()))
- qFatal("Could not open device %s - aborting!", qPrintable(m_devicePath));
+ qFatal("Could not open DRM device");
}
void QEglFSKmsIntegration::platformDestroy()
{
+ qCDebug(qLcEglfsKmsDebug, "platformDestroy: Closing DRM device");
m_device->close();
delete m_device;
m_device = Q_NULLPTR;
@@ -88,7 +84,7 @@ void QEglFSKmsIntegration::platformDestroy()
EGLNativeDisplayType QEglFSKmsIntegration::platformDisplay() const
{
Q_ASSERT(m_device);
- return m_device->nativeDisplay();
+ return (EGLNativeDisplayType) m_device->nativeDisplay();
}
bool QEglFSKmsIntegration::usesDefaultScreen()
@@ -134,94 +130,17 @@ void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const
bool QEglFSKmsIntegration::supportsPBuffers() const
{
- return m_pbuffers;
-}
-
-bool QEglFSKmsIntegration::hwCursor() const
-{
- return m_hwCursor;
-}
-
-bool QEglFSKmsIntegration::separateScreens() const
-{
- return m_separateScreens;
-}
-
-QEglFSKmsIntegration::VirtualDesktopLayout QEglFSKmsIntegration::virtualDesktopLayout() const
-{
- return m_virtualDesktopLayout;
+ return m_screenConfig->supportsPBuffers();
}
-QMap<QString, QVariantMap> QEglFSKmsIntegration::outputSettings() const
-{
- return m_outputSettings;
-}
-
-QEglFSKmsDevice *QEglFSKmsIntegration::device() const
+QKmsDevice *QEglFSKmsIntegration::device() const
{
return m_device;
}
-void QEglFSKmsIntegration::loadConfig()
+QKmsScreenConfig *QEglFSKmsIntegration::screenConfig() const
{
- static QByteArray json = qgetenv("QT_QPA_EGLFS_KMS_CONFIG");
- if (json.isEmpty())
- return;
-
- qCDebug(qLcEglfsKmsDebug) << "Loading KMS setup from" << json;
-
- QFile file(QString::fromUtf8(json));
- if (!file.open(QFile::ReadOnly)) {
- qCWarning(qLcEglfsKmsDebug) << "Could not open config file"
- << json << "for reading";
- return;
- }
-
- const QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
- if (!doc.isObject()) {
- qCWarning(qLcEglfsKmsDebug) << "Invalid config file" << json
- << "- no top-level JSON object";
- return;
- }
-
- const QJsonObject object = doc.object();
-
- m_hwCursor = object.value(QLatin1String("hwcursor")).toBool(m_hwCursor);
- m_pbuffers = object.value(QLatin1String("pbuffers")).toBool(m_pbuffers);
- m_devicePath = object.value(QLatin1String("device")).toString();
- m_separateScreens = object.value(QLatin1String("separateScreens")).toBool(m_separateScreens);
-
- const QString vdOriString = object.value(QLatin1String("virtualDesktopLayout")).toString();
- if (!vdOriString.isEmpty()) {
- if (vdOriString == QLatin1String("horizontal"))
- m_virtualDesktopLayout = VirtualDesktopLayoutHorizontal;
- else if (vdOriString == QLatin1String("vertical"))
- m_virtualDesktopLayout = VirtualDesktopLayoutVertical;
- else
- qCWarning(qLcEglfsKmsDebug) << "Unknown virtualDesktopOrientation value" << vdOriString;
- }
-
- const QJsonArray outputs = object.value(QLatin1String("outputs")).toArray();
- for (int i = 0; i < outputs.size(); i++) {
- const QVariantMap outputSettings = outputs.at(i).toObject().toVariantMap();
-
- if (outputSettings.contains(QStringLiteral("name"))) {
- const QString name = outputSettings.value(QStringLiteral("name")).toString();
-
- if (m_outputSettings.contains(name)) {
- qCDebug(qLcEglfsKmsDebug) << "Output" << name << "configured multiple times!";
- }
-
- m_outputSettings.insert(name, outputSettings);
- }
- }
-
- qCDebug(qLcEglfsKmsDebug) << "Configuration:\n"
- << "\thwcursor:" << m_hwCursor << "\n"
- << "\tpbuffers:" << m_pbuffers << "\n"
- << "\tseparateScreens:" << m_separateScreens << "\n"
- << "\tvirtualDesktopLayout:" << m_virtualDesktopLayout << "\n"
- << "\toutputs:" << m_outputSettings;
+ return m_screenConfig;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h
index ba49945715..21347d9131 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h
@@ -49,19 +49,16 @@
QT_BEGIN_NAMESPACE
-class QEglFSKmsDevice;
+class QKmsDevice;
+class QKmsScreenConfig;
Q_EGLFS_EXPORT Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
class Q_EGLFS_EXPORT QEglFSKmsIntegration : public QEglFSDeviceIntegration
{
public:
- enum VirtualDesktopLayout {
- VirtualDesktopLayoutHorizontal,
- VirtualDesktopLayoutVertical
- };
-
QEglFSKmsIntegration();
+ ~QEglFSKmsIntegration();
void platformInit() Q_DECL_OVERRIDE;
void platformDestroy() Q_DECL_OVERRIDE;
@@ -73,25 +70,14 @@ public:
void waitForVSync(QPlatformSurface *surface) const Q_DECL_OVERRIDE;
bool supportsPBuffers() const Q_DECL_OVERRIDE;
- virtual bool hwCursor() const;
- virtual bool separateScreens() const;
- virtual VirtualDesktopLayout virtualDesktopLayout() const;
- QMap<QString, QVariantMap> outputSettings() const;
-
- QEglFSKmsDevice *device() const;
+ QKmsDevice *device() const;
+ QKmsScreenConfig *screenConfig() const;
protected:
- virtual QEglFSKmsDevice *createDevice(const QString &devicePath) = 0;
-
- void loadConfig();
+ virtual QKmsDevice *createDevice() = 0;
- QEglFSKmsDevice *m_device;
- bool m_hwCursor;
- bool m_pbuffers;
- bool m_separateScreens;
- VirtualDesktopLayout m_virtualDesktopLayout;
- QString m_devicePath;
- QMap<QString, QVariantMap> m_outputSettings;
+ QKmsDevice *m_device;
+ QKmsScreenConfig *m_screenConfig;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
index 4021609407..a2af586947 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qeglfskmsscreen.h"
-#include "qeglfskmsdevice.h"
#include "qeglfsintegration_p.h"
#include <QtCore/QLoggingCategory>
@@ -69,30 +68,19 @@ private:
QEglFSKmsScreen *m_screen;
};
-QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output)
- : QEglFSScreen(eglGetDisplay(device->nativeDisplay()))
- , m_integration(integration)
+QEglFSKmsScreen::QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output)
+ : QEglFSScreen(eglGetDisplay((EGLNativeDisplayType) device->nativeDisplay()))
, m_device(device)
, m_output(output)
, m_powerState(PowerStateOn)
, m_interruptHandler(new QEglFSKmsInterruptHandler(this))
{
- m_siblings << this; // gets overridden by QEglFSKmsDevice later if !separateScreens
+ m_siblings << this; // gets overridden later
}
QEglFSKmsScreen::~QEglFSKmsScreen()
{
- if (m_output.dpms_prop) {
- drmModeFreeProperty(m_output.dpms_prop);
- m_output.dpms_prop = Q_NULLPTR;
- }
- restoreMode();
- if (m_output.saved_crtc) {
- drmModeFreeCrtc(m_output.saved_crtc);
- m_output.saved_crtc = Q_NULLPTR;
- }
+ m_output.cleanup(m_device);
delete m_interruptHandler;
}
@@ -171,16 +159,7 @@ void QEglFSKmsScreen::flipFinished()
void QEglFSKmsScreen::restoreMode()
{
- if (m_output.mode_set && m_output.saved_crtc) {
- drmModeSetCrtc(m_device->fd(),
- m_output.saved_crtc->crtc_id,
- m_output.saved_crtc->buffer_id,
- 0, 0,
- &m_output.connector_id, 1,
- &m_output.saved_crtc->mode);
-
- m_output.mode_set = false;
- }
+ m_output.restoreMode(m_device);
}
qreal QEglFSKmsScreen::refreshRate() const
@@ -191,20 +170,7 @@ qreal QEglFSKmsScreen::refreshRate() const
QPlatformScreen::SubpixelAntialiasingType QEglFSKmsScreen::subpixelAntialiasingTypeHint() const
{
- switch (m_output.subpixel) {
- default:
- case DRM_MODE_SUBPIXEL_UNKNOWN:
- case DRM_MODE_SUBPIXEL_NONE:
- return Subpixel_None;
- case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
- return Subpixel_RGB;
- case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
- return Subpixel_BGR;
- case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
- return Subpixel_VRGB;
- case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
- return Subpixel_VBGR;
- }
+ return m_output.subpixelAntialiasingTypeHint();
}
QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const
@@ -214,11 +180,7 @@ QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const
void QEglFSKmsScreen::setPowerState(QPlatformScreen::PowerState state)
{
- if (!m_output.dpms_prop)
- return;
-
- drmModeConnectorSetProperty(m_device->fd(), m_output.connector_id,
- m_output.dpms_prop->prop_id, (int)state);
+ m_output.setPowerState(m_device, state);
m_powerState = state;
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
index 2b6a0ffe6c..25740697d7 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
@@ -42,39 +42,20 @@
#ifndef QEGLFSKMSSCREEN_H
#define QEGLFSKMSSCREEN_H
-#include "qeglfskmsintegration.h"
#include "private/qeglfsscreen_p.h"
#include <QtCore/QList>
#include <QtCore/QMutex>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
+#include <QtKmsSupport/private/qkmsdevice_p.h>
QT_BEGIN_NAMESPACE
-class QEglFSKmsDevice;
class QEglFSKmsInterruptHandler;
-struct QEglFSKmsOutput
-{
- QString name;
- uint32_t connector_id;
- uint32_t crtc_id;
- QSizeF physical_size;
- int mode; // index of selected mode in list below
- bool mode_set;
- drmModeCrtcPtr saved_crtc;
- QList<drmModeModeInfo> modes;
- int subpixel;
- drmModePropertyPtr dpms_prop;
-};
-
class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen
{
public:
- QEglFSKmsScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output);
+ QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output);
~QEglFSKmsScreen();
void setVirtualPosition(const QPoint &pos);
@@ -96,8 +77,7 @@ public:
QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; }
void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; }
- QEglFSKmsIntegration *integration() const { return m_integration; }
- QEglFSKmsDevice *device() const { return m_device; }
+ QKmsDevice *device() const { return m_device; }
void destroySurface();
@@ -105,7 +85,7 @@ public:
virtual void flip();
virtual void flipFinished();
- QEglFSKmsOutput &output() { return m_output; }
+ QKmsOutput &output() { return m_output; }
void restoreMode();
SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE;
@@ -114,10 +94,9 @@ public:
void setPowerState(QPlatformScreen::PowerState state) Q_DECL_OVERRIDE;
protected:
- QEglFSKmsIntegration *m_integration;
- QEglFSKmsDevice *m_device;
+ QKmsDevice *m_device;
- QEglFSKmsOutput m_output;
+ QKmsOutput m_output;
QPoint m_pos;
QList<QPlatformScreen *> m_siblings;
diff --git a/src/plugins/platforms/ios/kernel.pro b/src/plugins/platforms/ios/kernel.pro
index caafe89730..71257d09f7 100644
--- a/src/plugins/platforms/ios/kernel.pro
+++ b/src/plugins/platforms/ios/kernel.pro
@@ -1,5 +1,10 @@
TARGET = qios
+# QTBUG-42937: Work around linker errors caused by circular
+# dependencies between the iOS platform plugin and the user
+# application's main() when the plugin is a shared library.
+qtConfig(shared): CONFIG += static
+
QT += \
core-private gui-private \
clipboard_support-private fontdatabase_support-private graphics_support-private
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro
index f4588dda03..7379765599 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro
@@ -1,7 +1,11 @@
TARGET = qiosnsphotolibrarysupport
+# QTBUG-42937: Since the iOS plugin (kernel) is
+# static, this plugin needs to be static as well.
+qtConfig(shared): CONFIG += static
+
QT += core gui gui-private
-LIBS += -framework UIKit -framework AssetsLibrary
+LIBS += -framework Foundation -framework UIKit -framework AssetsLibrary
HEADERS = \
qiosfileengineassetslibrary.h \
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index e5b4d6da85..fbf167b514 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -61,6 +61,7 @@
#include <QtFontDatabaseSupport/private/qcoretextfontdatabase_p.h>
#include <QtClipboardSupport/private/qmacmime_p.h>
#include <QDir>
+#include <QOperatingSystemVersion>
#import <AudioToolbox/AudioServices.h>
@@ -119,7 +120,7 @@ QIOSIntegration::QIOSIntegration()
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition;
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_9_0) {
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9)) {
if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
touchCapabilities |= QTouchDevice::Pressure;
}
diff --git a/src/plugins/platforms/ios/qiosmessagedialog.mm b/src/plugins/platforms/ios/qiosmessagedialog.mm
index 50d5442f17..4f0c667861 100644
--- a/src/plugins/platforms/ios/qiosmessagedialog.mm
+++ b/src/plugins/platforms/ios/qiosmessagedialog.mm
@@ -39,6 +39,7 @@
#import <UIKit/UIKit.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/qwindow.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
@@ -109,7 +110,7 @@ bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality win
if (m_alertController // Ensure that the dialog is not showing already
|| !options() // Some message dialogs don't have options (QErrorMessage)
|| windowModality == Qt::NonModal // We can only do modal dialogs
- || QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_8_0) // API limitation
+ || QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) // API limitation
return false;
m_alertController = [[UIAlertController
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index c518f9111d..49268ee076 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -45,6 +45,7 @@
#include "qiosapplicationdelegate.h"
#include "qiosviewcontroller.h"
#include "quiview.h"
+#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/private/qwindow_p.h>
#include <private/qcoregraphics_p.h>
@@ -274,7 +275,7 @@ void QIOSScreen::updateProperties()
if (m_uiScreen == [UIScreen mainScreen]) {
Qt::ScreenOrientation statusBarOrientation = toQtScreenOrientation(UIDeviceOrientation([UIApplication sharedApplication].statusBarOrientation));
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_8_0) {
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) {
// On iOS < 8.0 the UIScreen geometry is always in portait, and the system applies
// the screen rotation to the root view-controller's view instead of directly to the
// screen, like iOS 8 and above does.
@@ -302,7 +303,7 @@ void QIOSScreen::updateProperties()
if (m_geometry != previousGeometry) {
QRectF physicalGeometry;
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_8_0) {
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) {
// We can't use the primaryOrientation of screen(), as we haven't reported the new geometry yet
Qt::ScreenOrientation primaryOrientation = m_geometry.width() >= m_geometry.height() ?
Qt::LandscapeOrientation : Qt::PortraitOrientation;
@@ -407,7 +408,7 @@ Qt::ScreenOrientation QIOSScreen::nativeOrientation() const
{
CGRect nativeBounds =
#if !defined(Q_OS_TVOS) && QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_8_0)
- QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_8_0 ? m_uiScreen.nativeBounds :
+ QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8) ? m_uiScreen.nativeBounds :
#endif
m_uiScreen.bounds;
diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm
index 238d7addf6..48262dad10 100644
--- a/src/plugins/platforms/ios/qiostextinputoverlay.mm
+++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm
@@ -219,7 +219,7 @@ static void executeBlockWithoutAnimation(Block block)
borderLayer.borderColor = [[UIColor lightGrayColor] CGColor];
[self addSublayer:borderLayer];
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_7_0) {
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 7)) {
// [UIView snapshotViewAfterScreenUpdates:] is available since iOS 7.0.
// Just silently ignore showing the loupe for older versions.
self.hidden = YES;
@@ -267,7 +267,7 @@ static void executeBlockWithoutAnimation(Block block)
- (void)display
{
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_7_0)
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 7))
return;
// Take a snapshow of the target view, magnify the area around the focal
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 2a1444e9e5..259070216e 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -48,6 +48,7 @@
#include "qiosmenu.h"
#endif
+#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qwindow_p.h>
#include <qpa/qwindowsysteminterface_p.h>
@@ -291,7 +292,7 @@
QTouchDevice *touchDevice = QIOSIntegration::instance()->touchDevice();
QTouchDevice::Capabilities touchCapabilities = touchDevice->capabilities();
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_9_0) {
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9)) {
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
touchCapabilities |= QTouchDevice::Pressure;
else
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index 246c959fd3..dc7ea08dc5 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -414,7 +414,7 @@ QRegion QLinuxFbScreen::doRedraw()
mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
for (const QRect &rect : touched)
- mBlitter->drawImage(rect, *mScreenImage, rect);
+ mBlitter->drawImage(rect, mScreenImage, rect);
return touched;
}
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 9da3d6811b..0b052adf0f 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -7,8 +7,6 @@ QT += \
# Uncomment this to build with support for IMF once it becomes available in the BBNDK
#CONFIG += qqnx_imf
-CONFIG += qqnx_screeneventthread
-
# Uncomment these to enable debugging output for various aspects of the plugin
#DEFINES += QQNXBUFFER_DEBUG
#DEFINES += QQNXBUTTON_DEBUG
@@ -47,7 +45,8 @@ SOURCES = main.cpp \
qqnxservices.cpp \
qqnxcursor.cpp \
qqnxrasterwindow.cpp \
- qqnxglobal.cpp
+ qqnxglobal.cpp \
+ qqnxscreeneventthread.cpp
HEADERS = main.h \
qqnxbuffer.h \
@@ -67,13 +66,8 @@ HEADERS = main.h \
qqnxrasterwindow.h \
qqnxscreeneventfilter.h \
qqnxglobal.h \
- qqnxlgmon.h
-
-CONFIG(qqnx_screeneventthread) {
- DEFINES += QQNX_SCREENEVENTTHREAD
- SOURCES += qqnxscreeneventthread.cpp
- HEADERS += qqnxscreeneventthread.h
-}
+ qqnxlgmon.h \
+ qqnxscreeneventthread.h
LIBS += -lscreen
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 7229d7d2a8..eee0581709 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -40,9 +40,7 @@
#include "qqnxglobal.h"
#include "qqnxintegration.h"
-#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
-#endif
#include "qqnxnativeinterface.h"
#include "qqnxrasterbackingstore.h"
#include "qqnxscreen.h"
@@ -125,9 +123,7 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
QQnxIntegration::QQnxIntegration(const QStringList &paramList)
: QPlatformIntegration()
-#if defined(QQNX_SCREENEVENTTHREAD)
, m_screenEventThread(0)
-#endif
, m_navigatorEventHandler(new QQnxNavigatorEventHandler())
, m_virtualKeyboard(0)
#if defined(QQNX_PPS)
@@ -169,10 +165,8 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#endif
// Create/start event thread
-#if defined(QQNX_SCREENEVENTTHREAD)
m_screenEventThread = new QQnxScreenEventThread(ms_screenContext, m_screenEventHandler);
m_screenEventThread->start();
-#endif
#if defined(QQNX_PPS)
// Create/start the keyboard class.
@@ -235,10 +229,8 @@ QQnxIntegration::~QQnxIntegration()
#endif
delete m_navigatorEventHandler;
-#if defined(QQNX_SCREENEVENTTHREAD)
// Stop/destroy screen event thread
delete m_screenEventThread;
-#endif
// In case the event-dispatcher was never transferred to QCoreApplication
delete m_eventDispatcher;
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index f543b0d102..3b43837dec 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -48,9 +48,7 @@
QT_BEGIN_NAMESPACE
-#if defined(QQNX_SCREENEVENTTHREAD)
class QQnxScreenEventThread;
-#endif
class QQnxFileDialogHelper;
class QQnxNativeInterface;
class QQnxWindow;
@@ -142,9 +140,7 @@ private:
static void removeWindow(screen_window_t qnxWindow);
static screen_context_t ms_screenContext;
-#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_screenEventThread;
-#endif
QQnxNavigatorEventHandler *m_navigatorEventHandler;
QQnxAbstractVirtualKeyboard *m_virtualKeyboard;
#if defined(QQNX_PPS)
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index beda6e1a49..5d230e2145 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -40,9 +40,7 @@
#include "qqnxglobal.h"
#include "qqnxscreeneventhandler.h"
-#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
-#endif
#include "qqnxintegration.h"
#include "qqnxkeytranslator.h"
#include "qqnxscreen.h"
@@ -67,9 +65,7 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration)
, m_lastButtonState(Qt::NoButton)
, m_lastMouseWindow(0)
, m_touchDevice(0)
-#if defined(QQNX_SCREENEVENTTHREAD)
, m_eventThread(0)
-#endif
, m_focusLostTimer(-1)
{
// Create a touch device
@@ -198,7 +194,6 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie
}
}
-#if defined(QQNX_SCREENEVENTTHREAD)
void QQnxScreenEventHandler::setScreenEventThread(QQnxScreenEventThread *eventThread)
{
m_eventThread = eventThread;
@@ -233,7 +228,6 @@ void QQnxScreenEventHandler::processEventsFromScreenThread()
m_eventThread->unlock();
}
-#endif
void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event)
{
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
index 6b234e8d8f..78b089764f 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
@@ -48,9 +48,7 @@ QT_BEGIN_NAMESPACE
class QQnxIntegration;
class QQnxScreenEventFilter;
-#if defined(QQNX_SCREENEVENTTHREAD)
class QQnxScreenEventThread;
-#endif
class QQnxScreenEventHandler : public QObject
{
@@ -66,9 +64,7 @@ public:
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
-#if defined(QQNX_SCREENEVENTTHREAD)
void setScreenEventThread(QQnxScreenEventThread *eventThread);
-#endif
Q_SIGNALS:
void newWindowCreated(void *window);
@@ -77,10 +73,8 @@ Q_SIGNALS:
protected:
void timerEvent(QTimerEvent *event);
-#if defined(QQNX_SCREENEVENTTHREAD)
private Q_SLOTS:
void processEventsFromScreenThread();
-#endif
private:
void handleKeyboardEvent(screen_event_t event);
@@ -105,9 +99,7 @@ private:
QTouchDevice *m_touchDevice;
QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints];
QList<QQnxScreenEventFilter*> m_eventFilters;
-#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_eventThread;
-#endif
int m_focusLostTimer;
};
diff --git a/src/plugins/platforms/vnc/qvncscreen.cpp b/src/plugins/platforms/vnc/qvncscreen.cpp
index 34def45767..91a8933dba 100644
--- a/src/plugins/platforms/vnc/qvncscreen.cpp
+++ b/src/plugins/platforms/vnc/qvncscreen.cpp
@@ -150,10 +150,10 @@ QPixmap QVncScreen::grabWindow(WId wid, int x, int y, int width, int height) con
{
if (!wid) {
if (width < 0)
- width = mScreenImage->width() - x;
+ width = mScreenImage.width() - x;
if (height < 0)
- height = mScreenImage->height() - y;
- return QPixmap::fromImage(*mScreenImage).copy(x, y, width, height);
+ height = mScreenImage.height() - y;
+ return QPixmap::fromImage(mScreenImage).copy(x, y, width, height);
}
QFbWindow *window = windowForId(wid);
@@ -165,7 +165,7 @@ QPixmap QVncScreen::grabWindow(WId wid, int x, int y, int width, int height) con
height = geom.height() - y;
QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height));
rect &= window->geometry();
- return QPixmap::fromImage(*mScreenImage).copy(rect);
+ return QPixmap::fromImage(mScreenImage).copy(rect);
}
return QPixmap();
@@ -183,5 +183,10 @@ bool QVNCScreen::swapBytes() const
}
#endif
+QFbScreen::Flags QVncScreen::flags() const
+{
+ return QFbScreen::DontForceFirstWindowToFullScreen;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/vnc/qvncscreen.h b/src/plugins/platforms/vnc/qvncscreen.h
index 785abd6dc2..4b7171b5a9 100644
--- a/src/plugins/platforms/vnc/qvncscreen.h
+++ b/src/plugins/platforms/vnc/qvncscreen.h
@@ -64,12 +64,14 @@ public:
QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
QRegion doRedraw() Q_DECL_OVERRIDE;
- QImage *image() const { return mScreenImage; }
+ QImage *image() { return &mScreenImage; }
void enableClientCursor(QVncClient *client);
void disableClientCursor(QVncClient *client);
QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
+ Flags flags() const Q_DECL_OVERRIDE;
+
void clearDirty() { dirtyRegion = QRegion(); }
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index 9803dedb1e..06d481b3af 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -1052,11 +1052,24 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accValue(VARIANT varID, BS
return S_FALSE;
}
-HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accValue(VARIANT, BSTR)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accValue(VARIANT, BSTR value)
{
QAccessibleInterface *accessible = accessibleInterface();
accessibleDebugClientCalls(accessible);
- return DISP_E_MEMBERNOTFOUND;
+
+ if (!accessible || !accessible->isValid()) {
+ return E_FAIL;
+ }
+
+ QString qstrValue = QString::fromWCharArray(value);
+
+ if (accessible->valueInterface()) {
+ accessible->valueInterface()->setCurrentValue(qstrValue);
+ } else {
+ accessible->setText(QAccessible::Value, qstrValue);
+ }
+
+ return S_OK;
}
// moz: [important]
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 1a03df6ac2..40d4cb1497 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -68,6 +68,7 @@
#include <QtCore/QHash>
#include <QtCore/QStringList>
#include <QtCore/QDebug>
+#include <QtCore/QOperatingSystemVersion>
#include <QtCore/QSysInfo>
#include <QtCore/QScopedArrayPointer>
#include <QtCore/private/qsystemlibrary_p.h>
@@ -185,7 +186,7 @@ QWindowsShcoreDLL::QWindowsShcoreDLL()
void QWindowsShcoreDLL::init()
{
- if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS8_1)
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1)
return;
QSystemLibrary library(QStringLiteral("SHCore"));
getProcessDpiAwareness = (GetProcessDpiAwareness)library.resolve("GetProcessDpiAwareness");
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 26a5131927..9519b509bc 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -190,6 +190,20 @@ static inline Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState)
return modifiers;
}
+static inline Qt::MouseButtons toQtMouseButtons(DWORD keyState)
+{
+ Qt::MouseButtons buttons = Qt::NoButton;
+
+ if (keyState & MK_LBUTTON)
+ buttons |= Qt::LeftButton;
+ if (keyState & MK_RBUTTON)
+ buttons |= Qt::RightButton;
+ if (keyState & MK_MBUTTON)
+ buttons |= Qt::MidButton;
+
+ return buttons;
+}
+
/*!
\class QWindowsOleDropSource
\brief Implementation of IDropSource
@@ -405,16 +419,7 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
break;
}
- // grfKeyState is broken on CE & some Windows XP versions,
- // therefore we need to check the state manually
- if ((GetAsyncKeyState(VK_LBUTTON) == 0)
- && (GetAsyncKeyState(VK_MBUTTON) == 0)
- && (GetAsyncKeyState(VK_RBUTTON) == 0)) {
- hr = ResultFromScode(DRAGDROP_S_DROP);
- break;
- }
-
- const Qt::MouseButtons buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
+ const Qt::MouseButtons buttons = toQtMouseButtons(grfKeyState);
if (m_currentButtons == Qt::NoButton) {
m_currentButtons = buttons;
} else {
@@ -538,7 +543,7 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
QWindowsDrag *windowsDrag = QWindowsDrag::instance();
const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState);
- QGuiApplicationPrivate::mouse_buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
+ QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(grfKeyState);
const QPlatformDragQtResponse response =
QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index a9b061ad73..2d9a683da6 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -114,6 +114,35 @@ static QByteArray debugWinExStyle(DWORD exStyle)
return rc;
}
+static QByteArray debugWinSwpPos(UINT flags)
+{
+ QByteArray rc = "0x";
+ rc += QByteArray::number(flags, 16);
+ if (flags & SWP_FRAMECHANGED)
+ rc += " SWP_FRAMECHANGED";
+ if (flags & SWP_HIDEWINDOW)
+ rc += " SWP_HIDEWINDOW";
+ if (flags & SWP_NOACTIVATE)
+ rc += " SWP_NOACTIVATE";
+ if (flags & SWP_NOCOPYBITS)
+ rc += " SWP_NOCOPYBITS";
+ if (flags & SWP_NOMOVE)
+ rc += " SWP_NOMOVE";
+ if (flags & SWP_NOOWNERZORDER)
+ rc += " SWP_NOOWNERZORDER";
+ if (flags & SWP_NOREDRAW)
+ rc += " SWP_NOREDRAW";
+ if (flags & SWP_NOSENDCHANGING)
+ rc += " SWP_NOSENDCHANGING";
+ if (flags & SWP_NOSIZE)
+ rc += " SWP_NOSIZE";
+ if (flags & SWP_NOZORDER)
+ rc += " SWP_NOZORDER";
+ if (flags & SWP_SHOWWINDOW)
+ rc += " SWP_SHOWWINDOW";
+ return rc;
+}
+
static inline QSize qSizeOfRect(const RECT &rect)
{
return QSize(rect.right -rect.left, rect.bottom - rect.top);
@@ -137,8 +166,9 @@ QDebug operator<<(QDebug d, const RECT &r)
{
QDebugStateSaver saver(d);
d.nospace();
- d << "RECT: left/top=" << r.left << ',' << r.top
- << " right/bottom=" << r.right << ',' << r.bottom;
+ d << "RECT(left=" << r.left << ", top=" << r.top
+ << ", right=" << r.right << ", bottom=" << r.bottom
+ << " (" << r.right - r.left << 'x' << r.bottom - r.top << "))";
return d;
}
@@ -148,12 +178,23 @@ QDebug operator<<(QDebug d, const POINT &p)
return d;
}
+QDebug operator<<(QDebug d, const WINDOWPOS &wp)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d.noquote();
+ d << "WINDOWPOS(flags=" << debugWinSwpPos(wp.flags) << ", hwnd="
+ << wp.hwnd << ", hwndInsertAfter=" << wp.hwndInsertAfter << ", x=" << wp.x
+ << ", y=" << wp.y << ", cx=" << wp.cx << ", cy=" << wp.cy << ')';
+ return d;
+}
+
QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
{
QDebugStateSaver saver(d);
d.nospace();
- d << "NCCALCSIZE_PARAMS " << qrectFromRECT(p.rgrc[0])
- << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' << qrectFromRECT(p.rgrc[2]);
+ d << "NCCALCSIZE_PARAMS(rgrc=[" << p.rgrc[0] << ' ' << p.rgrc[1] << ' '
+ << p.rgrc[2] << "], lppos=" << *p.lppos << ')';
return d;
}
@@ -173,6 +214,7 @@ QDebug operator<<(QDebug d, const WINDOWPLACEMENT &wp)
{
QDebugStateSaver saver(d);
d.nospace();
+ d.noquote();
d << "WINDOWPLACEMENT(flags=0x" << hex << wp.flags << dec << ", showCmd="
<< wp.showCmd << ", ptMinPosition=" << wp.ptMinPosition << ", ptMaxPosition=" << wp.ptMaxPosition
<< ", rcNormalPosition=" << wp.rcNormalPosition;
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 924f242e6e..90b0940813 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -357,6 +357,7 @@ QDebug operator<<(QDebug d, const POINT &);
QDebug operator<<(QDebug d, const MINMAXINFO &i);
QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p);
QDebug operator<<(QDebug d, const WINDOWPLACEMENT &);
+QDebug operator<<(QDebug d, const WINDOWPOS &);
#endif // !QT_NO_DEBUG_STREAM
// ---------- QWindowsGeometryHint inline functions.
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index d97e49309f..5071cd8e21 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -97,5 +97,5 @@ RESOURCES += $$PWD/openglblacklists.qrc
qtConfig(accessibility): include($$PWD/accessible/accessible.pri)
-DEFINES *= LIBEGL_NAME=$${LIBEGL_NAME}
-DEFINES *= LIBGLESV2_NAME=$${LIBGLESV2_NAME}
+DEFINES *= LIBEGL_NAME=$${LIBQTANGLE_NAME}
+DEFINES *= LIBGLESV2_NAME=$${LIBQTANGLE_NAME}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 7bd233f387..57ce357a17 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -131,7 +131,7 @@ typedef struct qt_xcb_ge_event_t {
static inline bool isXIEvent(xcb_generic_event_t *event, int opCode)
{
- qt_xcb_ge_event_t *e = (qt_xcb_ge_event_t *)event;
+ qt_xcb_ge_event_t *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
return e->extension == opCode;
}
#endif // XCB_USE_XINPUT2
@@ -251,7 +251,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
// Find a fake screen
const auto scrs = virtualDesktop->screens();
for (QPlatformScreen *scr : scrs) {
- QXcbScreen *xcbScreen = (QXcbScreen *)scr;
+ QXcbScreen *xcbScreen = static_cast<QXcbScreen *>(scr);
if (xcbScreen->output() == XCB_NONE) {
screen = xcbScreen;
break;
@@ -377,7 +377,7 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen)
// When primary screen is removed, set the new primary screen
// which belongs to the primary virtual desktop.
if (screen->isPrimary()) {
- QXcbScreen *newPrimary = (QXcbScreen *)virtualDesktop->screens().at(0);
+ QXcbScreen *newPrimary = static_cast<QXcbScreen *>(virtualDesktop->screens().at(0));
newPrimary->setPrimary(true);
const int idx = m_screens.indexOf(newPrimary);
if (idx > 0)
@@ -711,7 +711,7 @@ QXcbConnection::~QXcbConnection()
delete m_glIntegration;
#ifdef XCB_USE_XLIB
- XCloseDisplay((Display *)m_xlib_display);
+ XCloseDisplay(static_cast<Display *>(m_xlib_display));
#else
xcb_disconnect(xcb_connection());
#endif
@@ -754,7 +754,7 @@ QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
{ \
- event_t *e = (event_t *)event; \
+ event_t *e = reinterpret_cast<event_t *>(event); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->windowMember)) { \
handled = eventListener->handleGenericEvent(event, &result); \
if (!handled) \
@@ -765,7 +765,7 @@ break;
#define HANDLE_KEYBOARD_EVENT(event_t, handler) \
{ \
- event_t *e = (event_t *)event; \
+ event_t *e = reinterpret_cast<event_t *>(event); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \
handled = eventListener->handleGenericEvent(event, &result); \
if (!handled) \
@@ -1184,11 +1184,11 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state);
HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
case XCB_MAPPING_NOTIFY:
- m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
+ m_keyboard->handleMappingNotifyEvent(reinterpret_cast<xcb_mapping_notify_event_t *>(event));
break;
case XCB_SELECTION_REQUEST:
{
- xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event;
+ xcb_selection_request_event_t *sr = reinterpret_cast<xcb_selection_request_event_t *>(event);
#ifndef QT_NO_DRAGANDDROP
if (sr->selection == atom(QXcbAtom::XdndSelection))
m_drag->handleSelectionRequest(sr);
@@ -1202,19 +1202,19 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
break;
}
case XCB_SELECTION_CLEAR:
- setTime(((xcb_selection_clear_event_t *)event)->time);
+ setTime((reinterpret_cast<xcb_selection_clear_event_t *>(event))->time);
#ifndef QT_NO_CLIPBOARD
- m_clipboard->handleSelectionClearRequest((xcb_selection_clear_event_t *)event);
+ m_clipboard->handleSelectionClearRequest(reinterpret_cast<xcb_selection_clear_event_t *>(event));
#endif
handled = true;
break;
case XCB_SELECTION_NOTIFY:
- setTime(((xcb_selection_notify_event_t *)event)->time);
+ setTime((reinterpret_cast<xcb_selection_notify_event_t *>(event))->time);
handled = false;
break;
case XCB_PROPERTY_NOTIFY:
{
- xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
if (pn->atom == atom(QXcbAtom::_NET_WORKAREA)) {
QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(pn->window);
if (virtualDesktop)
@@ -1239,7 +1239,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
if (!handled) {
if (response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
- xcb_xfixes_selection_notify_event_t *notify_event = (xcb_xfixes_selection_notify_event_t *)event;
+ xcb_xfixes_selection_notify_event_t *notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event);
setTime(notify_event->timestamp);
#ifndef QT_NO_CLIPBOARD
m_clipboard->handleXFixesSelectionRequest(notify_event);
@@ -1249,10 +1249,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
handled = true;
} else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) {
- updateScreens((xcb_randr_notify_event_t *)event);
+ updateScreens(reinterpret_cast<xcb_randr_notify_event_t *>(event));
handled = true;
} else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
- xcb_randr_screen_change_notify_event_t *change_event = (xcb_randr_screen_change_notify_event_t *)event;
+ xcb_randr_screen_change_notify_event_t *change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
for (QXcbScreen *s : qAsConst(m_screens)) {
if (s->root() == change_event->root )
s->handleScreenChange(change_event);
@@ -1361,7 +1361,7 @@ void QXcbEventReader::run()
void QXcbEventReader::addEvent(xcb_generic_event_t *event)
{
if ((event->response_type & ~0x80) == XCB_CLIENT_MESSAGE
- && ((xcb_client_message_event_t *)event)->type == m_connection->atom(QXcbAtom::_QT_CLOSE_CONNECTION))
+ && (reinterpret_cast<xcb_client_message_event_t *>(event))->type == m_connection->atom(QXcbAtom::_QT_CLOSE_CONNECTION))
m_connection = 0;
m_events << event;
}
@@ -1427,7 +1427,7 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
event.type = atom(a);
event.data.data32[0] = id;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, reinterpret_cast<const char *>(&event)));
Q_XCB_CALL(xcb_destroy_window(m_connection, eventListener));
xcb_flush(xcb_connection());
}
@@ -1447,7 +1447,7 @@ namespace
if ((event->response_type & ~0x80) != type) {
return false;
} else {
- xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
if ((pn->window == window) && (pn->atom == atom))
return true;
}
@@ -1475,7 +1475,7 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
event = checkEvent(checker);
}
- xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
xcb_timestamp_t timestamp = pn->time;
free(event);
@@ -1499,7 +1499,8 @@ xcb_window_t QXcbConnection::getQtSelectionOwner()
{
if (!m_qtSelectionOwner) {
xcb_screen_t *xcbScreen = primaryVirtualDesktop()->screen();
- int x = 0, y = 0, w = 3, h = 3;
+ int16_t x = 0, y = 0;
+ uint16_t w = 3, h = 3;
m_qtSelectionOwner = xcb_generate_id(xcb_connection());
Q_XCB_CALL(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT, // depth -- same as root
@@ -1688,7 +1689,7 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex,
for (int j = nextIndex; j < eventqueue->size(); ++j) {
xcb_generic_event_t *next = eventqueue->at(j);
if (isValid(next) && next->response_type == XCB_CONFIGURE_NOTIFY
- && ((xcb_configure_notify_event_t *)next)->event == ((xcb_configure_notify_event_t*)event)->event)
+ && reinterpret_cast<xcb_configure_notify_event_t *>(next)->event == reinterpret_cast<xcb_configure_notify_event_t *>(event)->event)
{
return true;
}
@@ -1717,7 +1718,7 @@ void QXcbConnection::processXcbEvents()
(*eventqueue)[i] = 0;
if (!(event->response_type & ~0x80)) {
- handleXcbError((xcb_generic_error_t *)event);
+ handleXcbError(reinterpret_cast<xcb_generic_error_t *>(event));
continue;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index f6ba828a15..c9fc27997b 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -694,7 +694,7 @@ Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_MOVABLE_TYPE);
#endif
#endif
-#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
+#define DISPLAY_FROM_XCB(object) (reinterpret_cast<Display *>(object->connection()->xlib_display()))
#define CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(object) ((XVisualInfo *)(object->connection()->createVisualInfoForDefaultVisualId()))
template<typename T>