summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qaction.cpp6
-rw-r--r--src/gui/kernel/qaction_p.h2
-rw-r--r--src/gui/kernel/qactiongroup_p.h2
-rw-r--r--src/gui/kernel/qcursor.cpp30
-rw-r--r--src/gui/kernel/qdnd_p.h2
-rw-r--r--src/gui/kernel/qdrag.cpp4
-rw-r--r--src/gui/kernel/qevent.cpp95
-rw-r--r--src/gui/kernel/qevent.h17
-rw-r--r--src/gui/kernel/qeventpoint.cpp1
-rw-r--r--src/gui/kernel/qeventpoint.h1
-rw-r--r--src/gui/kernel/qeventpoint_p.h2
-rw-r--r--src/gui/kernel/qgenericpluginfactory.cpp6
-rw-r--r--src/gui/kernel/qguiapplication.cpp217
-rw-r--r--src/gui/kernel/qguiapplication_p.h34
-rw-r--r--src/gui/kernel/qguiapplication_platform.h4
-rw-r--r--src/gui/kernel/qguivariant.cpp3
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp21
-rw-r--r--src/gui/kernel/qinputdevice.cpp28
-rw-r--r--src/gui/kernel/qinternalmimedata.cpp2
-rw-r--r--src/gui/kernel/qkeymapper.cpp74
-rw-r--r--src/gui/kernel/qkeymapper_p.h24
-rw-r--r--src/gui/kernel/qkeysequence.cpp167
-rw-r--r--src/gui/kernel/qkeysequence.h4
-rw-r--r--src/gui/kernel/qkeysequence_p.h8
-rw-r--r--src/gui/kernel/qoffscreensurface.h2
-rw-r--r--src/gui/kernel/qopenglcontext.cpp25
-rw-r--r--src/gui/kernel/qpaintdevicewindow.cpp2
-rw-r--r--src/gui/kernel/qpaintdevicewindow_p.h4
-rw-r--r--src/gui/kernel/qpalette.cpp136
-rw-r--r--src/gui/kernel/qpalette.h5
-rw-r--r--src/gui/kernel/qpalette_p.h77
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp74
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h31
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.cpp4
-rw-r--r--src/gui/kernel/qplatforminputcontext.cpp18
-rw-r--r--src/gui/kernel/qplatforminputcontext.h2
-rw-r--r--src/gui/kernel/qplatforminputcontextfactory.cpp35
-rw-r--r--src/gui/kernel/qplatforminputcontextfactory_p.h3
-rw-r--r--src/gui/kernel/qplatformintegration.cpp23
-rw-r--r--src/gui/kernel/qplatformintegration.h11
-rw-r--r--src/gui/kernel/qplatformintegrationfactory.cpp10
-rw-r--r--src/gui/kernel/qplatformkeymapper.cpp38
-rw-r--r--src/gui/kernel/qplatformkeymapper.h36
-rw-r--r--src/gui/kernel/qplatformscreen.cpp11
-rw-r--r--src/gui/kernel/qplatformscreen.h3
-rw-r--r--src/gui/kernel/qplatformscreen_p.h33
-rw-r--r--src/gui/kernel/qplatformservices.cpp2
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon.h3
-rw-r--r--src/gui/kernel/qplatformtheme.cpp70
-rw-r--r--src/gui/kernel/qplatformtheme.h5
-rw-r--r--src/gui/kernel/qplatformthemefactory.cpp10
-rw-r--r--src/gui/kernel/qplatformwindow.cpp17
-rw-r--r--src/gui/kernel/qplatformwindow_p.h17
-rw-r--r--src/gui/kernel/qpointingdevice.cpp8
-rw-r--r--src/gui/kernel/qpointingdevice.h9
-rw-r--r--src/gui/kernel/qpointingdevice_p.h2
-rw-r--r--src/gui/kernel/qrasterwindow.cpp16
-rw-r--r--src/gui/kernel/qrasterwindow.h1
-rw-r--r--src/gui/kernel/qscreen.cpp94
-rw-r--r--src/gui/kernel/qscreen.h2
-rw-r--r--src/gui/kernel/qscreen_p.h1
-rw-r--r--src/gui/kernel/qscreen_platform.h61
-rw-r--r--src/gui/kernel/qsessionmanager.cpp8
-rw-r--r--src/gui/kernel/qsessionmanager_p.h2
-rw-r--r--src/gui/kernel/qshortcut.cpp2
-rw-r--r--src/gui/kernel/qshortcut_p.h2
-rw-r--r--src/gui/kernel/qshortcutmap.cpp181
-rw-r--r--src/gui/kernel/qshortcutmap_p.h1
-rw-r--r--src/gui/kernel/qsimpledrag.cpp7
-rw-r--r--src/gui/kernel/qstylehints.cpp29
-rw-r--r--src/gui/kernel/qstylehints.h6
-rw-r--r--src/gui/kernel/qstylehints_p.h6
-rw-r--r--src/gui/kernel/qsurface.cpp4
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp2
-rw-r--r--src/gui/kernel/qtestsupport_gui.cpp25
-rw-r--r--src/gui/kernel/qtestsupport_gui.h1
-rw-r--r--src/gui/kernel/qwindow.cpp188
-rw-r--r--src/gui/kernel/qwindow_p.h14
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp153
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h33
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h26
81 files changed, 1507 insertions, 838 deletions
diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp
index 0f389789a1..c67cfd53b1 100644
--- a/src/gui/kernel/qaction.cpp
+++ b/src/gui/kernel/qaction.cpp
@@ -171,9 +171,7 @@ QObject *QActionPrivate::menu() const
Once a QAction has been created, it should be added to the relevant
menu and toolbar, then connected to the slot which will perform
- the action. For example:
-
- \snippet ../widgets/mainwindows/application/mainwindow.cpp 19
+ the action.
Actions are added to widgets using QWidget::addAction() or
QGraphicsWidget::addAction(). Note that an action must be added to a
@@ -186,7 +184,7 @@ QObject *QActionPrivate::menu() const
use as menu items.
- \sa QMenu, QToolBar, {Qt Widgets - Application Example}
+ \sa QMenu, QToolBar
*/
/*!
diff --git a/src/gui/kernel/qaction_p.h b/src/gui/kernel/qaction_p.h
index 8aa75fdf89..e79cc26b4d 100644
--- a/src/gui/kernel/qaction_p.h
+++ b/src/gui/kernel/qaction_p.h
@@ -21,6 +21,8 @@
#if QT_CONFIG(shortcut)
# include <QtGui/private/qshortcutmap_p.h>
#endif
+
+#include <QtCore/qpointer.h>
#include "private/qobject_p.h"
QT_REQUIRE_CONFIG(action);
diff --git a/src/gui/kernel/qactiongroup_p.h b/src/gui/kernel/qactiongroup_p.h
index c7a058a6f2..ba939a2b10 100644
--- a/src/gui/kernel/qactiongroup_p.h
+++ b/src/gui/kernel/qactiongroup_p.h
@@ -21,6 +21,8 @@
#if QT_CONFIG(shortcut)
# include <QtGui/private/qshortcutmap_p.h>
#endif
+
+#include <QtCore/qpointer.h>
#include "private/qobject_p.h"
QT_REQUIRE_CONFIG(action);
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index 3f0cabbcb1..8e7747559a 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -439,8 +439,7 @@ QCursor::QCursor()
QCursor::QCursor(Qt::CursorShape shape)
: d(nullptr)
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
setShape(shape);
}
@@ -498,8 +497,7 @@ bool operator==(const QCursor &lhs, const QCursor &rhs) noexcept
*/
Qt::CursorShape QCursor::shape() const
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
return d->cshape;
}
@@ -512,8 +510,7 @@ Qt::CursorShape QCursor::shape() const
*/
void QCursor::setShape(Qt::CursorShape shape)
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
QCursorData *c = uint(shape) <= Qt::LastCursor ? qt_cursorTable[shape] : nullptr;
if (!c)
c = qt_cursorTable[0];
@@ -547,8 +544,7 @@ void QCursor::setShape(Qt::CursorShape shape)
*/
QBitmap QCursor::bitmap() const
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
if (d->bm)
return *(d->bm);
return QBitmap();
@@ -574,8 +570,7 @@ QBitmap QCursor::bitmap() const
*/
QBitmap QCursor::mask() const
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
if (d->bmm)
return *(d->bmm);
return QBitmap();
@@ -588,8 +583,7 @@ QBitmap QCursor::mask() const
QPixmap QCursor::pixmap() const
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
return d->pixmap;
}
@@ -600,8 +594,7 @@ QPixmap QCursor::pixmap() const
QPoint QCursor::hotSpot() const
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
return QPoint(d->hx, d->hy);
}
@@ -611,8 +604,7 @@ QPoint QCursor::hotSpot() const
QCursor::QCursor(const QCursor &c)
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
d = c.d;
d->ref.ref();
}
@@ -635,8 +627,7 @@ QCursor::~QCursor()
QCursor &QCursor::operator=(const QCursor &c)
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
if (c.d)
c.d->ref.ref();
if (d && !d->ref.deref())
@@ -707,8 +698,7 @@ void QCursorData::initialize()
QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY, qreal devicePixelRatio)
{
- if (!QCursorData::initialized)
- QCursorData::initialize();
+ QCursorData::initialize();
if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
QCursorData *c = qt_cursorTable[0];
diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h
index c863a63620..b5a2e015f4 100644
--- a/src/gui/kernel/qdnd_p.h
+++ b/src/gui/kernel/qdnd_p.h
@@ -27,6 +27,8 @@
#include "private/qobject_p.h"
#include "QtGui/qbackingstore.h"
+#include <QtCore/qpointer.h>
+
QT_REQUIRE_CONFIG(draganddrop);
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp
index 10bf7f33f0..4e707e4915 100644
--- a/src/gui/kernel/qdrag.cpp
+++ b/src/gui/kernel/qdrag.cpp
@@ -9,6 +9,8 @@
#include <qpoint.h>
#include "qdnd_p.h"
+#include <QtCore/qpointer.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -64,7 +66,7 @@ QT_BEGIN_NAMESPACE
required.
\sa {Drag and Drop}, QClipboard, QMimeData, {Draggable Icons Example},
- {Draggable Text Example}, {Drop Site Example}, {Fridge Magnets Example}
+ {Draggable Text Example}, {Drop Site Example}
*/
/*!
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index fe75ec78f7..d8c11d72a6 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qevent.h"
+
#include "qcursor.h"
#include "private/qguiapplication_p.h"
#include "private/qinputdevice_p.h"
@@ -9,6 +10,7 @@
#include "qpa/qplatformintegration.h"
#include "private/qevent_p.h"
#include "private/qeventpoint_p.h"
+
#include "qfile.h"
#include "qhashfunctions.h"
#include "qmetaobject.h"
@@ -16,6 +18,7 @@
#include "qevent_p.h"
#include "qmath.h"
#include "qloggingcategory.h"
+#include "qpointer.h"
#if QT_CONFIG(draganddrop)
#include <qpa/qplatformdrag.h>
@@ -1837,10 +1840,6 @@ Q_IMPL_EVENT_COMMON(QResizeEvent)
special handling, you should reimplement the event handler and
ignore() the event.
- The \l{mainwindows/application#close event handler}{closeEvent() in the
- Application example} shows a close event handler that
- asks whether to save a document before closing.
-
If you want the widget to be deleted when it is closed, create it
with the Qt::WA_DeleteOnClose flag. This is very useful for
independent top-level windows in a multi-window application.
@@ -3594,10 +3593,15 @@ Q_IMPL_EVENT_COMMON(QShowEvent)
\snippet qfileopenevent/Info.plist Custom Info.plist
- The following implementation of a QApplication subclass prints the path to
- the file that was, for example, dropped on the Dock icon of the application.
+ The following implementation of a QApplication subclass shows how to handle
+ QFileOpenEvent to open the file that was, for example, dropped on the Dock
+ icon of the application.
\snippet qfileopenevent/main.cpp QApplication subclass
+
+ Note how \c{QFileOpenEvent::file()} is not guaranteed to be the name of a
+ local file that can be opened using QFile. The contents of the string depend
+ on the source application.
*/
/*!
@@ -3625,19 +3629,23 @@ Q_IMPL_EVENT_COMMON(QFileOpenEvent)
/*!
\fn QString QFileOpenEvent::file() const
- Returns the file that is being opened.
+ Returns the name of the file that the application should open.
+
+ This is not guaranteed to be the path to a local file.
*/
/*!
\fn QUrl QFileOpenEvent::url() const
- Returns the url that is being opened.
+ Returns the url that the application should open.
\since 4.6
*/
+#if QT_DEPRECATED_SINCE(6, 6)
/*!
\fn bool QFileOpenEvent::openFile(QFile &file, QIODevice::OpenMode flags) const
+ \deprecated [6.6] interpret the string returned by file()
Opens a QFile on the \a file referenced by this event in the mode specified
by \a flags. Returns \c true if successful; otherwise returns \c false.
@@ -3652,6 +3660,7 @@ bool QFileOpenEvent::openFile(QFile &file, QIODevice::OpenMode flags) const
file.setFileName(m_file);
return file.open(flags);
}
+#endif
#ifndef QT_NO_TOOLBAR
/*!
@@ -3716,6 +3725,7 @@ QShortcutEvent::QShortcutEvent(const QKeySequence &key, int id, bool ambiguous)
/*!
Constructs a shortcut event for the given \a key press,
associated with the QShortcut \a shortcut.
+ \since 6.5
\a ambiguous specifies whether there is more than one QShortcut
for the same key sequence.
@@ -3761,6 +3771,13 @@ static void formatUnicodeString(QDebug d, const QString &s)
d << Qt::dec << '"';
}
+static QDebug operator<<(QDebug dbg, const QInputMethodEvent::Attribute &attr)
+{
+ dbg << "[type= " << attr.type << ", start=" << attr.start << ", length=" << attr.length
+ << ", value=" << attr.value << ']';
+ return dbg;
+}
+
static inline void formatInputMethodEvent(QDebug d, const QInputMethodEvent *e)
{
d << "QInputMethodEvent(";
@@ -3776,15 +3793,15 @@ static inline void formatInputMethodEvent(QDebug d, const QInputMethodEvent *e)
d << ", replacementStart=" << e->replacementStart() << ", replacementLength="
<< e->replacementLength();
}
- if (const int attributeCount = e->attributes().size()) {
+ const auto attributes = e->attributes();
+ auto it = attributes.cbegin();
+ const auto end = attributes.cend();
+ if (it != end) {
d << ", attributes= {";
- for (int a = 0; a < attributeCount; ++a) {
- const QInputMethodEvent::Attribute &at = e->attributes().at(a);
- if (a)
- d << ',';
- d << "[type= " << at.type << ", start=" << at.start << ", length=" << at.length
- << ", value=" << at.value << ']';
- }
+ d << *it;
+ ++it;
+ for (; it != end; ++it)
+ d << ',' << *it;
d << '}';
}
d << ')';
@@ -4111,6 +4128,10 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
dbg << ", text=" << ke->text();
if (ke->isAutoRepeat())
dbg << ", autorepeat, count=" << ke->count();
+ if (dbg.verbosity() > QDebug::DefaultVerbosity) {
+ dbg << ", nativeScanCode=" << ke->nativeScanCode();
+ dbg << ", nativeVirtualKey=" << ke->nativeVirtualKey();
+ }
dbg << ')';
}
break;
@@ -4457,8 +4478,6 @@ Q_IMPL_EVENT_COMMON(QWindowStateChangeEvent)
*/
/*!
- \deprecated [6.2] Use another constructor.
-
Constructs a QTouchEvent with the given \a eventType, \a device,
\a touchPoints, and current keyboard \a modifiers at the time of the event.
*/
@@ -4738,6 +4757,46 @@ Q_IMPL_EVENT_COMMON(QApplicationStateChangeEvent)
Returns the state of the application.
*/
+/*!
+ \class QChildWindowEvent
+ \inmodule QtGui
+ \since 6.7
+ \brief The QChildWindowEvent class contains event parameters for
+ child window changes.
+
+ \ingroup events
+
+ Child window events are sent to windows when children are
+ added or removed.
+
+ In both cases you can only rely on the child being a QWindow
+ — not any subclass thereof. This is because in the
+ QEvent::ChildWindowAdded case the subclass is not yet fully
+ constructed, and in the QEvent::ChildWindowRemoved case it
+ might have already been destructed.
+*/
+
+/*!
+ Constructs a child window event object of a particular \a type
+ for the \a childWindow.
+
+ \a type can be QEvent::ChildWindowAdded or QEvent::ChildWindowRemoved.
+
+ \sa child()
+*/
+QChildWindowEvent::QChildWindowEvent(Type type, QWindow *childWindow)
+ : QEvent(type), c(childWindow)
+{
+}
+
+Q_IMPL_EVENT_COMMON(QChildWindowEvent)
+
+/*!
+ \fn QWindow *QChildWindowEvent::child() const
+
+ Returns the child window that was added or removed.
+*/
+
QMutableTouchEvent::~QMutableTouchEvent()
= default;
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index a3fd09d9a4..a24f0c471c 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -14,7 +14,6 @@
#include <QtCore/qiodevice.h>
#include <QtCore/qlist.h>
#include <QtCore/qnamespace.h>
-#include <QtCore/qpointer.h>
#include <QtCore/qstring.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
@@ -34,6 +33,7 @@ QT_BEGIN_NAMESPACE
class QFile;
class QAction;
class QMouseEvent;
+template <typename T> class QPointer;
class QPointerEvent;
class QScreen;
#if QT_CONFIG(shortcut)
@@ -71,6 +71,7 @@ protected:
class Q_GUI_EXPORT QPointerEvent : public QInputEvent
{
+ Q_GADGET
Q_DECL_EVENT_COMMON(QPointerEvent)
public:
explicit QPointerEvent(Type type, const QPointingDevice *dev,
@@ -852,7 +853,10 @@ public:
inline QString file() const { return m_file; }
QUrl url() const { return m_url; }
+#if QT_DEPRECATED_SINCE(6, 6)
+ QT_DEPRECATED_VERSION_X_6_6("Interpret the string returned by file()")
bool openFile(QFile &file, QIODevice::OpenMode flags) const;
+#endif
private:
QString m_file;
QUrl m_url;
@@ -1017,6 +1021,17 @@ private:
Qt::ApplicationState m_applicationState;
};
+class Q_GUI_EXPORT QChildWindowEvent : public QEvent
+{
+ Q_DECL_EVENT_COMMON(QChildWindowEvent)
+public:
+ explicit QChildWindowEvent(Type type, QWindow *childWindow);
+ QWindow *child() const { return c; }
+
+private:
+ QWindow *c;
+};
+
QT_END_NAMESPACE
#endif // QEVENT_H
diff --git a/src/gui/kernel/qeventpoint.cpp b/src/gui/kernel/qeventpoint.cpp
index bbb0baee79..66d4f44ea0 100644
--- a/src/gui/kernel/qeventpoint.cpp
+++ b/src/gui/kernel/qeventpoint.cpp
@@ -536,6 +536,7 @@ void QMutableEventPoint::update(const QEventPoint &other, QEventPoint &target)
setEllipseDiameters(target, other.ellipseDiameters());
setRotation(target, other.rotation());
setVelocity(target, other.velocity());
+ setUniqueId(target, other.uniqueId()); // for TUIO
}
/*! \internal
diff --git a/src/gui/kernel/qeventpoint.h b/src/gui/kernel/qeventpoint.h
index 35b8b1f73d..518faecee2 100644
--- a/src/gui/kernel/qeventpoint.h
+++ b/src/gui/kernel/qeventpoint.h
@@ -20,7 +20,6 @@ class Q_GUI_EXPORT QEventPoint
{
Q_GADGET
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
- QDOC_PROPERTY(QPointingDevice *device READ device CONSTANT) // qdoc doesn't know const
Q_PROPERTY(const QPointingDevice *device READ device CONSTANT)
Q_PROPERTY(int id READ id CONSTANT)
Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId CONSTANT)
diff --git a/src/gui/kernel/qeventpoint_p.h b/src/gui/kernel/qeventpoint_p.h
index f70c285e3e..c339c7e3e1 100644
--- a/src/gui/kernel/qeventpoint_p.h
+++ b/src/gui/kernel/qeventpoint_p.h
@@ -17,7 +17,9 @@
#include <QtGui/private/qtguiglobal_p.h>
#include <QtGui/qevent.h>
+
#include <QtCore/qloggingcategory.h>
+#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qgenericpluginfactory.cpp b/src/gui/kernel/qgenericpluginfactory.cpp
index 3155b10456..5ce13ad5e1 100644
--- a/src/gui/kernel/qgenericpluginfactory.cpp
+++ b/src/gui/kernel/qgenericpluginfactory.cpp
@@ -12,7 +12,7 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, gpLoader,
(QGenericPluginFactoryInterface_iid, "/generic"_L1, Qt::CaseInsensitive))
/*!
@@ -34,7 +34,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
*/
QObject *QGenericPluginFactory::create(const QString& key, const QString &specification)
{
- return qLoadPlugin<QObject, QGenericPlugin>(loader(), key.toLower(), specification);
+ return qLoadPlugin<QObject, QGenericPlugin>(gpLoader(), key.toLower(), specification);
}
/*!
@@ -49,7 +49,7 @@ QStringList QGenericPluginFactory::keys()
typedef QMultiMap<int, QString> PluginKeyMap;
typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
- const PluginKeyMap keyMap = loader()->keyMap();
+ const PluginKeyMap keyMap = gpLoader()->keyMap();
const PluginKeyMapConstIterator cend = keyMap.constEnd();
for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it)
if (!list.contains(it.value()))
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 741a02875a..444091afef 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -9,6 +9,7 @@
#include <qpa/qplatformintegrationfactory_p.h>
#include "private/qevent_p.h"
#include "private/qeventpoint_p.h"
+#include "private/qiconloader_p.h"
#include "qfont.h"
#include "qpointingdevice.h"
#include <qpa/qplatformfontdatabase.h>
@@ -16,12 +17,15 @@
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformtheme.h>
#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformkeymapper.h>
#include <QtCore/QAbstractEventDispatcher>
+#include <QtCore/QFileInfo>
#include <QtCore/QStandardPaths>
#include <QtCore/QVariant>
#include <QtCore/private/qcoreapplication_p.h>
#include <QtCore/private/qabstracteventdispatcher_p.h>
+#include <QtCore/private/qminimalflatset_p.h>
#include <QtCore/qmutex.h>
#include <QtCore/private/qthread_p.h>
#include <QtCore/private/qlocking_p.h>
@@ -50,6 +54,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qwindowsysteminterface_p.h>
#include "private/qwindow_p.h"
+#include "private/qicon_p.h"
#include "private/qcursor_p.h"
#if QT_CONFIG(opengl)
# include "private/qopenglcontext_p.h"
@@ -96,12 +101,14 @@
#include <qtgui_tracepoints_p.h>
-#include <ctype.h>
+#include <private/qtools_p.h>
+
#include <limits>
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
+using namespace QtMiscUtils;
// Helper macro for static functions to check on the existence of the application class.
#define CHECK_QAPP_INSTANCE(...) \
@@ -229,7 +236,7 @@ static void initThemeHints()
static bool checkNeedPortalSupport()
{
#if QT_CONFIG(dbus)
- return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, "flatpak-info"_L1).isEmpty() || qEnvironmentVariableIsSet("SNAP");
+ return QFileInfo::exists("/.flatpak-info"_L1) || qEnvironmentVariableIsSet("SNAP");
#else
return false;
#endif // QT_CONFIG(dbus)
@@ -256,20 +263,20 @@ struct QWindowGeometrySpecification
static inline int nextGeometryToken(const QByteArray &a, int &pos, char *op)
{
*op = 0;
- const int size = a.size();
+ const qsizetype size = a.size();
if (pos >= size)
return -1;
*op = a.at(pos);
if (*op == '+' || *op == '-' || *op == 'x')
pos++;
- else if (isdigit(*op))
+ else if (isAsciiDigit(*op))
*op = 'x'; // If it starts with a digit, it is supposed to be a width specification.
else
return -1;
const int numberPos = pos;
- for ( ; pos < size && isdigit(a.at(pos)); ++pos) ;
+ for ( ; pos < size && isAsciiDigit(a.at(pos)); ++pos) ;
bool ok;
const int result = a.mid(numberPos, pos - numberPos).toInt(&ok);
@@ -557,10 +564,12 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
\list
\li \c {altgr}, detect the key \c {AltGr} found on some keyboards as
Qt::GroupSwitchModifier (since Qt 5.12).
- \li \c {darkmode=[1|2]} controls how Qt responds to the activation
+ \li \c {darkmode=[0|1|2]} controls how Qt responds to the activation
of the \e{Dark Mode for applications} introduced in Windows 10
1903 (since Qt 5.15).
+ A value of 0 disables dark mode support.
+
A value of 1 causes Qt to switch the window borders to black
when \e{Dark Mode for applications} is activated and no High
Contrast Theme is in use. This is intended for applications
@@ -579,13 +588,10 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
\c none disables them.
\li \c {fontengine=freetype}, uses the FreeType font engine.
- \li \c {fontengine=directwrite}, uses the experimental DirectWrite
- font database and defaults to using the DirectWrite font
+ \li \c {fontengine=gdi}, uses the legacy GDI-based
+ font database and defaults to using the GDI font
engine (which is otherwise only used for some font types
- or font properties.) This affects font selection and aims
- to provide font naming more consistent with other platforms,
- but does not support all font formats, such as Postscript
- Type-1 or Microsoft FNT fonts.
+ or font properties.) (Since Qt 6.8).
\li \c {menus=[native|none]}, controls the use of native menus.
Native menus are implemented using Win32 API and are simpler than
@@ -599,7 +605,8 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
\li \c {nocolorfonts} Turn off DirectWrite Color fonts
(since Qt 5.8).
- \li \c {nodirectwrite} Turn off DirectWrite fonts (since Qt 5.8).
+ \li \c {nodirectwrite} Turn off DirectWrite fonts (since Qt 5.8). This implicitly
+ also selects the GDI font engine.
\li \c {nomousefromtouch} Ignores mouse events synthesized
from touch events by the operating system.
@@ -749,7 +756,8 @@ QString QGuiApplication::applicationDisplayName()
of unread messages or similar.
The badge will be overlaid on the application's icon in the Dock
- on \macos, the home screen icon on iOS, or the task bar on Windows.
+ on \macos, the home screen icon on iOS, or the task bar on Windows
+ and Linux.
If the number is outside the range supported by the platform, the
number will be clamped to the supported range. If the number does
@@ -770,9 +778,9 @@ void QGuiApplication::setBadgeNumber(qint64 number)
\brief the base name of the desktop entry for this application
\since 5.7
- This is the file name, without the full path, of the desktop entry
- that represents this application according to the freedesktop desktop
- entry specification.
+ This is the file name, without the full path or the trailing ".desktop"
+ extension of the desktop entry that represents this application
+ according to the freedesktop desktop entry specification.
This property gives a precise indication of what desktop entry represents
the application and it is needed by the windowing system to retrieve
@@ -786,6 +794,15 @@ void QGuiApplication::setDesktopFileName(const QString &name)
if (!QGuiApplicationPrivate::desktopFileName)
QGuiApplicationPrivate::desktopFileName = new QString;
*QGuiApplicationPrivate::desktopFileName = name;
+ if (name.endsWith(QLatin1String(".desktop"))) { // ### Qt 7: remove
+ const QString filePath = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, name);
+ if (!filePath.isEmpty()) {
+ qWarning("QGuiApplication::setDesktopFileName: the specified desktop file name "
+ "ends with .desktop. For compatibility reasons, the .desktop suffix will "
+ "be removed. Please specify a desktop file name without .desktop suffix");
+ (*QGuiApplicationPrivate::desktopFileName).chop(8);
+ }
+ }
}
QString QGuiApplication::desktopFileName()
@@ -812,7 +829,7 @@ QWindow *QGuiApplication::modalWindow()
CHECK_QAPP_INSTANCE(nullptr)
if (QGuiApplicationPrivate::self->modalWindowList.isEmpty())
return nullptr;
- return QGuiApplicationPrivate::self->modalWindowList.first();
+ return QGuiApplicationPrivate::self->modalWindowList.constFirst();
}
static void updateBlockedStatusRecursion(QWindow *window, bool shouldBeBlocked)
@@ -946,6 +963,8 @@ bool QGuiApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blocking
/*!
Returns the QWindow that receives events tied to focus,
such as key events.
+
+ \sa QWindow::requestActivate()
*/
QWindow *QGuiApplication::focusWindow()
{
@@ -1175,14 +1194,26 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
\li \c xcb is a plugin for the X11 window system, used on some desktop Linux platforms.
\endlist
+ \note Calling this function without a QGuiApplication will return the default
+ platform name, if available. The default platform name is not affected by the
+ \c{-platform} command line option, or the \c QT_QPA_PLATFORM environment variable.
+
For more information about the platform plugins for embedded Linux devices,
see \l{Qt for Embedded Linux}.
*/
QString QGuiApplication::platformName()
{
- return QGuiApplicationPrivate::platform_name ?
- *QGuiApplicationPrivate::platform_name : QString();
+ if (!QGuiApplication::instance()) {
+#ifdef QT_QPA_DEFAULT_PLATFORM_NAME
+ return QStringLiteral(QT_QPA_DEFAULT_PLATFORM_NAME);
+#else
+ return QString();
+#endif
+ } else {
+ return QGuiApplicationPrivate::platform_name ?
+ *QGuiApplicationPrivate::platform_name : QString();
+ }
}
Q_LOGGING_CATEGORY(lcQpaPluginLoading, "qt.qpa.plugin");
@@ -1217,6 +1248,10 @@ static void init_platform(const QString &pluginNamesWithArguments, const QString
QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath);
if (Q_UNLIKELY(!QGuiApplicationPrivate::platform_integration)) {
if (availablePlugins.contains(name)) {
+ if (name == QStringLiteral("xcb") && QVersionNumber::compare(QLibraryInfo::version(), QVersionNumber(6, 5, 0)) >= 0) {
+ qCWarning(lcQpaPluginLoading).nospace().noquote()
+ << "From 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.";
+ }
qCInfo(lcQpaPluginLoading).nospace().noquote()
<< "Could not load the Qt platform plugin \"" << name << "\" in \""
<< QDir::toNativeSeparators(platformPluginPath) << "\" even though it was found.";
@@ -1305,7 +1340,7 @@ static void init_platform(const QString &pluginNamesWithArguments, const QString
if (!platformArguments.isEmpty()) {
if (QObject *nativeInterface = QGuiApplicationPrivate::platform_integration->nativeInterface()) {
for (const QString &argument : std::as_const(platformArguments)) {
- const int equalsPos = argument.indexOf(u'=');
+ const qsizetype equalsPos = argument.indexOf(u'=');
const QByteArray name =
equalsPos != -1 ? argument.left(equalsPos).toUtf8() : argument.toUtf8();
const QVariant value =
@@ -1325,7 +1360,7 @@ static void init_plugins(const QList<QByteArray> &pluginList)
{
for (int i = 0; i < pluginList.size(); ++i) {
QByteArray pluginSpec = pluginList.at(i);
- int colonPos = pluginSpec.indexOf(':');
+ qsizetype colonPos = pluginSpec.indexOf(':');
QObject *plugin;
if (colonPos < 0)
plugin = QGenericPluginFactory::create(QLatin1StringView(pluginSpec), QString());
@@ -1496,7 +1531,7 @@ void QGuiApplicationPrivate::createPlatformIntegration()
init_platform(QLatin1StringView(platformName), platformPluginPath, platformThemeName, argc, argv);
if (const QPlatformTheme *theme = platformTheme())
- QStyleHintsPrivate::get(QGuiApplication::styleHints())->setAppearance(theme->appearance());
+ QStyleHintsPrivate::get(QGuiApplication::styleHints())->updateColorScheme(theme->colorScheme());
if (!icon.isEmpty())
forcedWindowIcon = QDir::isAbsolutePath(icon) ? QIcon(icon) : QIcon::fromTheme(icon);
@@ -1515,7 +1550,11 @@ void QGuiApplicationPrivate::createEventDispatcher()
if (platform_integration == nullptr)
createPlatformIntegration();
- // The platform integration should not mess with the event dispatcher
+ // The platform integration should not result in creating an event dispatcher
+ Q_ASSERT_X(!threadData.loadRelaxed()->eventDispatcher, "QGuiApplication",
+ "Creating the platform integration resulted in creating an event dispatcher");
+
+ // Nor should it mess with the QCoreApplication's event dispatcher
Q_ASSERT(!eventDispatcher);
eventDispatcher = platform_integration->createEventDispatcher();
@@ -1592,7 +1631,7 @@ void Q_TRACE_INSTRUMENT(qtgui) QGuiApplicationPrivate::init()
++i;
if (argv[i] && *argv[i]) {
session_id = QString::fromLatin1(argv[i]);
- int p = session_id.indexOf(u'_');
+ qsizetype p = session_id.indexOf(u'_');
if (p >= 0) {
session_key = session_id.mid(p +1);
session_id = session_id.left(p);
@@ -1808,7 +1847,7 @@ Qt::KeyboardModifiers QGuiApplication::queryKeyboardModifiers()
{
CHECK_QAPP_INSTANCE(Qt::KeyboardModifiers{})
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
- return pi->queryKeyboardModifiers();
+ return pi->keyMapper()->queryKeyboardModifiers();
}
/*!
@@ -1866,9 +1905,10 @@ QFunctionPointer QGuiApplication::platformFunction(const QByteArray &function)
Generally, no user interaction can take place before calling exec().
- To make your application perform idle processing, e.g., executing a special
- function whenever there are no pending events, use a QTimer with 0 timeout.
- More advanced idle processing schemes can be achieved using processEvents().
+ To make your application perform idle processing, e.g., executing a
+ special function whenever there are no pending events, use a QChronoTimer
+ with 0ns timeout. More advanced idle processing schemes can be achieved
+ using processEvents().
We recommend that you connect clean-up code to the
\l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your
@@ -1958,7 +1998,8 @@ bool QGuiApplication::notify(QObject *object, QEvent *event)
*/
bool QGuiApplication::event(QEvent *e)
{
- if (e->type() == QEvent::LanguageChange) {
+ switch (e->type()) {
+ case QEvent::LanguageChange:
// if the layout direction was set explicitly, then don't override it here
if (layout_direction == Qt::LayoutDirectionAuto)
setLayoutDirection(layout_direction);
@@ -1966,13 +2007,15 @@ bool QGuiApplication::event(QEvent *e)
if (topLevelWindow->flags() != Qt::Desktop)
postEvent(topLevelWindow, new QEvent(QEvent::LanguageChange));
}
- } else if (e->type() == QEvent::ApplicationFontChange ||
- e->type() == QEvent::ApplicationPaletteChange) {
+ break;
+ case QEvent::ApplicationFontChange:
+ case QEvent::ApplicationPaletteChange:
for (auto *topLevelWindow : QGuiApplication::topLevelWindows()) {
if (topLevelWindow->flags() != Qt::Desktop)
postEvent(topLevelWindow, new QEvent(e->type()));
}
- } else if (e->type() == QEvent::Quit) {
+ break;
+ case QEvent::Quit:
// Close open windows. This is done in order to deliver de-expose
// events while the event loop is still running.
for (QWindow *topLevelWindow : QGuiApplication::topLevelWindows()) {
@@ -1984,8 +2027,10 @@ bool QGuiApplication::event(QEvent *e)
return true;
}
}
+ break;
+ default:
+ break;
}
-
return QCoreApplication::event(e);
}
@@ -2043,8 +2088,8 @@ void Q_TRACE_INSTRUMENT(qtgui) QGuiApplicationPrivate::processWindowSystemEvent(
case QWindowSystemInterfacePrivate::Leave:
QGuiApplicationPrivate::processLeaveEvent(static_cast<QWindowSystemInterfacePrivate::LeaveEvent *>(e));
break;
- case QWindowSystemInterfacePrivate::ActivatedWindow:
- QGuiApplicationPrivate::processActivatedEvent(static_cast<QWindowSystemInterfacePrivate::ActivatedWindowEvent *>(e));
+ case QWindowSystemInterfacePrivate::FocusWindow:
+ QGuiApplicationPrivate::processFocusWindowEvent(static_cast<QWindowSystemInterfacePrivate::FocusWindowEvent *>(e));
break;
case QWindowSystemInterfacePrivate::WindowStateChanged:
QGuiApplicationPrivate::processWindowStateChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowStateChangedEvent *>(e));
@@ -2052,6 +2097,9 @@ void Q_TRACE_INSTRUMENT(qtgui) QGuiApplicationPrivate::processWindowSystemEvent(
case QWindowSystemInterfacePrivate::WindowScreenChanged:
QGuiApplicationPrivate::processWindowScreenChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowScreenChangedEvent *>(e));
break;
+ case QWindowSystemInterfacePrivate::WindowDevicePixelRatioChanged:
+ QGuiApplicationPrivate::processWindowDevicePixelRatioChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowDevicePixelRatioChangedEvent *>(e));
+ break;
case QWindowSystemInterfacePrivate::SafeAreaMarginsChanged:
QGuiApplicationPrivate::processSafeAreaMarginsChangedEvent(static_cast<QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *>(e));
break;
@@ -2209,12 +2257,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
qAbs(globalPoint.y() - pressPos.y()) > doubleClickDistance)
mousePressButton = Qt::NoButton;
} else {
+ static unsigned long lastPressTimestamp = 0;
mouse_buttons = e->buttons;
if (mousePress) {
ulong doubleClickInterval = static_cast<ulong>(QGuiApplication::styleHints()->mouseDoubleClickInterval());
- doubleClick = e->timestamp - persistentEPD->eventPoint.pressTimestamp()
+ doubleClick = e->timestamp - lastPressTimestamp
< doubleClickInterval && button == mousePressButton;
mousePressButton = button;
+ lastPressTimestamp = e ->timestamp;
}
}
@@ -2354,6 +2404,7 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
mouse_buttons, e->modifiers, e->phase, e->inverted, e->source, device);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &ev);
+ e->eventAccepted = ev.isAccepted();
#else
Q_UNUSED(e);
#endif // QT_CONFIG(wheelevent)
@@ -2461,10 +2512,10 @@ void QGuiApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::Le
QCoreApplication::sendSpontaneousEvent(e->leave.data(), &event);
}
-void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
+void QGuiApplicationPrivate::processFocusWindowEvent(QWindowSystemInterfacePrivate::FocusWindowEvent *e)
{
QWindow *previous = QGuiApplicationPrivate::focus_window;
- QWindow *newFocus = e->activated.data();
+ QWindow *newFocus = e->focused.data();
if (previous == newFocus)
return;
@@ -2552,28 +2603,28 @@ void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfa
void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *wse)
{
- if (QWindow *window = wse->window.data()) {
- if (window->screen() == wse->screen.data())
- return;
- if (QWindow *topLevelWindow = window->d_func()->topLevelWindow(QWindow::ExcludeTransients)) {
- if (QScreen *screen = wse->screen.data())
- topLevelWindow->d_func()->setTopLevelScreen(screen, false /* recreate */);
- else // Fall back to default behavior, and try to find some appropriate screen
- topLevelWindow->setScreen(nullptr);
- }
+ QWindow *window = wse->window.data();
+ if (!window)
+ return;
- // We may have changed scaling; trigger resize event if needed,
- // except on Windows, where we send resize events during WM_DPICHANGED
- // event handling. FIXME: unify DPI change handling across all platforms.
-#ifndef Q_OS_WIN
- if (window->handle()) {
- QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window));
- processGeometryChangeEvent(&gce);
- }
-#endif
+ if (window->screen() == wse->screen.data())
+ return;
+
+ if (QWindow *topLevelWindow = window->d_func()->topLevelWindow(QWindow::ExcludeTransients)) {
+ if (QScreen *screen = wse->screen.data())
+ topLevelWindow->d_func()->setTopLevelScreen(screen, false /* recreate */);
+ else // Fall back to default behavior, and try to find some appropriate screen
+ topLevelWindow->setScreen(nullptr);
}
}
+void QGuiApplicationPrivate::processWindowDevicePixelRatioChangedEvent(QWindowSystemInterfacePrivate::WindowDevicePixelRatioChangedEvent *wde)
+{
+ if (wde->window.isNull())
+ return;
+ QWindowPrivate::get(wde->window)->updateDevicePixelRatio();
+}
+
void QGuiApplicationPrivate::processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *wse)
{
if (wse->window.isNull())
@@ -2590,31 +2641,33 @@ void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::
if (self)
self->handleThemeChanged();
+ QIconPrivate::clearIconCache();
+
+ QStyleHintsPrivate::get(QGuiApplication::styleHints())->updateColorScheme(colorScheme());
+
QEvent themeChangeEvent(QEvent::ThemeChange);
const QWindowList windows = tce->window ? QWindowList{tce->window} : window_list;
for (auto *window : windows)
QGuiApplication::sendSpontaneousEvent(window, &themeChangeEvent);
-
- QStyleHintsPrivate::get(QGuiApplication::styleHints())->setAppearance(appearance());
}
/*!
\internal
- \brief QGuiApplicationPrivate::appearance
- \return the platform theme's appearance
- or Qt::Appearance::Unknown if a platform theme cannot be established
- Qt::Appearance.
+ \brief QGuiApplicationPrivate::colorScheme
+ \return the platform theme's color scheme
+ or Qt::ColorScheme::Unknown if a platform theme cannot be established
*/
-Qt::Appearance QGuiApplicationPrivate::appearance()
+Qt::ColorScheme QGuiApplicationPrivate::colorScheme()
{
- return platformTheme() ? platformTheme()->appearance()
- : Qt::Appearance::Unknown;
+ return platformTheme() ? platformTheme()->colorScheme()
+ : Qt::ColorScheme::Unknown;
}
void QGuiApplicationPrivate::handleThemeChanged()
{
updatePalette();
+ QIconLoader::instance()->updateSystemTheme();
QAbstractFileIconProviderPrivate::clearIconTypeCache();
if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
@@ -2684,6 +2737,7 @@ void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::Cl
if (e->window.data()->d_func()->blockedByModalWindow && !e->window.data()->d_func()->inClose) {
// a modal window is blocking this window, don't allow close events through, unless they
// originate from a call to QWindow::close.
+ e->eventAccepted = false;
return;
}
@@ -2880,17 +2934,17 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
// Send the TouchCancel to all windows with active touches and clean up.
QTouchEvent touchEvent(QEvent::TouchCancel, device, e->modifiers);
touchEvent.setTimestamp(e->timestamp);
- QSet<QWindow *> windowsNeedingCancel;
+ constexpr qsizetype Prealloc = decltype(devPriv->activePoints)::mapped_container_type::PreallocatedSize;
+ QMinimalVarLengthFlatSet<QWindow *, Prealloc> windowsNeedingCancel;
for (auto &epd : devPriv->activePoints.values()) {
if (QWindow *w = QMutableEventPoint::window(epd.eventPoint))
windowsNeedingCancel.insert(w);
}
- for (QSet<QWindow *>::const_iterator winIt = windowsNeedingCancel.constBegin(),
- winItEnd = windowsNeedingCancel.constEnd(); winIt != winItEnd; ++winIt) {
- QGuiApplication::sendSpontaneousEvent(*winIt, &touchEvent);
- }
+ for (QWindow *w : windowsNeedingCancel)
+ QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
+
if (!self->synthesizedMousePoints.isEmpty() && !e->synthetic()) {
for (QHash<QWindow *, SynthesizedMouseData>::const_iterator synthIt = self->synthesizedMousePoints.constBegin(),
synthItEnd = self->synthesizedMousePoints.constEnd(); synthIt != synthItEnd; ++synthIt) {
@@ -3156,6 +3210,10 @@ void QGuiApplicationPrivate::processScreenLogicalDotsPerInchChange(QWindowSystem
s->d_func()->updateGeometry();
}
+ for (QWindow *window : QGuiApplication::allWindows())
+ if (window->screen() == e->screen)
+ QWindowPrivate::get(window)->updateDevicePixelRatio();
+
resetCachedDevicePixelRatio();
}
@@ -3214,6 +3272,16 @@ void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::E
const bool wasExposed = p->exposed;
p->exposed = e->isExposed && window->screen();
+ // We expect that the platform plugins send DevicePixelRatioChange events.
+ // As a fail-safe make a final check here to make sure the cached DPR value is
+ // always up to date before sending the expose event.
+ if (e->isExposed && !e->region.isEmpty()) {
+ const bool dprWasChanged = QWindowPrivate::get(window)->updateDevicePixelRatio();
+ if (dprWasChanged)
+ qWarning() << "The cached device pixel ratio value was stale on window expose. "
+ << "Please file a QTBUG which explains how to reproduce.";
+ }
+
// We treat expose events for an already exposed window as paint events
if (wasExposed && p->exposed && shouldSynthesizePaintEvents) {
QPaintEvent paintEvent(e->region);
@@ -3439,7 +3507,8 @@ bool QGuiApplicationPrivate::setPalette(const QPalette &palette)
*/
QPalette QGuiApplicationPrivate::basePalette() const
{
- return platformTheme() ? *platformTheme()->palette() : Qt::gray;
+ const auto pf = platformTheme();
+ return pf && pf->palette() ? *pf->palette() : Qt::gray;
}
void QGuiApplicationPrivate::handlePaletteChanged(const char *className)
@@ -3728,6 +3797,8 @@ Qt::ApplicationState QGuiApplication::applicationState()
*/
void QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy policy)
{
+ if (qApp)
+ qWarning("setHighDpiScaleFactorRoundingPolicy must be called before creating the QGuiApplication instance");
QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy = policy;
}
@@ -4318,7 +4389,7 @@ void *QGuiApplication::resolveInterface(const char *name, int revision) const
#if QT_CONFIG(xcb)
QT_NATIVE_INTERFACE_RETURN_IF(QX11Application, platformNativeInterface());
#endif
-#if defined(Q_OS_UNIX)
+#if QT_CONFIG(wayland)
QT_NATIVE_INTERFACE_RETURN_IF(QWaylandApplication, platformNativeInterface());
#endif
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 46bc504f5f..58c3f33394 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -34,6 +34,8 @@
# include "private/qshortcutmap_p.h"
#endif
+#include <QtCore/qpointer.h>
+
#include <memory>
QT_BEGIN_NAMESPACE
@@ -113,9 +115,11 @@ public:
static void processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e);
static void processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e);
- static void processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e);
+ static void processFocusWindowEvent(QWindowSystemInterfacePrivate::FocusWindowEvent *e);
+
static void processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *e);
static void processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *e);
+ static void processWindowDevicePixelRatioChangedEvent(QWindowSystemInterfacePrivate::WindowDevicePixelRatioChangedEvent *e);
static void processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *e);
@@ -206,6 +210,28 @@ public:
constexpr void reset() noexcept { *this = QLastCursorPosition{}; }
+ // QGuiApplicationPrivate::lastCursorPosition is used for mouse-move detection
+ // but even QPointF's qFuzzCompare on doubles is too precise, and causes move-noise
+ // e.g. on macOS (see QTBUG-111170). So we specialize the equality operators here
+ // to use single-point precision.
+ friend constexpr bool operator==(const QLastCursorPosition &p1, const QPointF &p2) noexcept
+ {
+ return qFuzzyCompare(float(p1.x()), float(p2.x()))
+ && qFuzzyCompare(float(p1.y()), float(p2.y()));
+ }
+ friend constexpr bool operator!=(const QLastCursorPosition &p1, const QPointF &p2) noexcept
+ {
+ return !(p1 == p2);
+ }
+ friend constexpr bool operator==(const QPointF &p1, const QLastCursorPosition &p2) noexcept
+ {
+ return p2 == p1;
+ }
+ friend constexpr bool operator!=(const QPointF &p1, const QLastCursorPosition &p2) noexcept
+ {
+ return !(p2 == p1);
+ }
+
private:
QPointF thePoint;
} lastCursorPosition;
@@ -297,6 +323,8 @@ public:
static void updatePalette();
+ static Qt::ColorScheme colorScheme();
+
protected:
virtual void handleThemeChanged();
@@ -313,8 +341,6 @@ private:
friend class QDragManager;
- static Qt::Appearance appearance();
-
static QGuiApplicationPrivate *self;
static int m_fakeMouseSourcePointId;
#ifdef Q_OS_WIN
@@ -397,7 +423,7 @@ struct Q_GUI_EXPORT QWindowsApplication
virtual QVariant gpu() const = 0; // internal, used by qtdiag
virtual QVariant gpuList() const = 0;
- virtual void lightSystemPalette(QPalette &pal) const = 0;
+ virtual void populateLightSystemPalette(QPalette &pal) const = 0;
};
#endif // Q_OS_WIN
diff --git a/src/gui/kernel/qguiapplication_platform.h b/src/gui/kernel/qguiapplication_platform.h
index b6182e42a3..545bf75c84 100644
--- a/src/gui/kernel/qguiapplication_platform.h
+++ b/src/gui/kernel/qguiapplication_platform.h
@@ -23,7 +23,7 @@ typedef struct _XDisplay Display;
struct xcb_connection_t;
#endif
-#if defined(Q_OS_UNIX)
+#if QT_CONFIG(wayland)
struct wl_display;
struct wl_compositor;
struct wl_seat;
@@ -46,7 +46,7 @@ struct Q_GUI_EXPORT QX11Application
};
#endif
-#if defined(Q_OS_UNIX) || defined(Q_CLANG_QDOC)
+#if QT_CONFIG(wayland) || defined(Q_QDOC)
struct Q_GUI_EXPORT QWaylandApplication
{
QT_DECLARE_NATIVE_INTERFACE(QWaylandApplication, 1, QGuiApplication)
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index 4fdc744029..fe72e7782f 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -56,7 +56,8 @@ QT_BEGIN_NAMESPACE
namespace {
-static const struct : QMetaTypeModuleHelper
+// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor): this is not a base class
+static constexpr struct : QMetaTypeModuleHelper
{
#define QT_IMPL_METATYPEINTERFACE_GUI_TYPES(MetaTypeName, MetaTypeId, RealName) \
QT_METATYPE_INTERFACE_INIT(RealName),
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 0f4803d92a..a0e1b48dcb 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -494,7 +494,8 @@ void QHighDpiScaling::updateHighDpiScaling()
qCDebug(lcHighDpi) << "Applying screen factors" << m_screenFactors;
int i = -1;
const auto screens = QGuiApplication::screens();
- for (const auto &[name, factor] : m_screenFactors) {
+ for (const auto &[name, rawFactor]: m_screenFactors) {
+ const qreal factor = roundScaleFactor(rawFactor);
++i;
if (name.isNull()) {
if (i < screens.size())
@@ -540,15 +541,17 @@ void QHighDpiScaling::setGlobalFactor(qreal factor)
if (!QGuiApplication::allWindows().isEmpty())
qWarning("QHighDpiScaling::setFactor: Should only be called when no windows exist.");
+ const auto screens = QGuiApplication::screens();
+
+ std::vector<QScreenPrivate::UpdateEmitter> updateEmitters;
+ for (QScreen *screen : screens)
+ updateEmitters.emplace_back(screen);
+
m_globalScalingActive = !qFuzzyCompare(factor, qreal(1));
m_factor = m_globalScalingActive ? factor : qreal(1);
m_active = m_globalScalingActive || m_screenFactorSet || m_platformPluginDpiScalingActive ;
- const auto screens = QGuiApplication::screens();
for (QScreen *screen : screens)
screen->d_func()->updateGeometry();
-
- // FIXME: The geometry has been updated based on the new scale factor,
- // but we don't emit any geometry change signals for the screens.
}
static const char scaleFactorProperty[] = "_q_scaleFactor";
@@ -565,6 +568,8 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
m_active = true;
}
+ QScreenPrivate::UpdateEmitter updateEmitter(screen);
+
// Prefer associating the factor with screen name over the object
// since the screen object may be deleted on screen disconnects.
const QString name = screen->name();
@@ -573,9 +578,7 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
else
QHighDpiScaling::m_namedScreenScaleFactors.insert(name, factor);
- // hack to force re-evaluation of screen geometry
- if (screen->handle())
- screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor
+ screen->d_func()->updateGeometry();
}
QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
@@ -696,7 +699,7 @@ QVector<QHighDpiScaling::ScreenFactor> QHighDpiScaling::parseScreenScaleFactorsS
// - a semicolon-separated name=factor list: "foo=1.5;bar=2;baz=3"
const auto specs = screenScaleFactors.split(u';');
for (const auto &spec : specs) {
- const int equalsPos = spec.lastIndexOf(u'=');
+ const qsizetype equalsPos = spec.lastIndexOf(u'=');
if (equalsPos == -1) {
// screens in order
bool ok;
diff --git a/src/gui/kernel/qinputdevice.cpp b/src/gui/kernel/qinputdevice.cpp
index b49fe4b15c..f7b216dcf0 100644
--- a/src/gui/kernel/qinputdevice.cpp
+++ b/src/gui/kernel/qinputdevice.cpp
@@ -235,6 +235,13 @@ Q_CONSTINIT static QBasicMutex devicesMutex;
/*!
Returns a list of all registered input devices (keyboards and pointing devices).
+ \note The list of devices is not always complete on all platforms. So far,
+ the most-complete information is available on the \l {Qt for Linux/X11}{X11}
+ platform, at startup and in response to hot-plugging. Most other platforms
+ are only able to provide generic devices of various types, only after receiving
+ events from them; and most platforms do not tell Qt when a device is plugged in,
+ or when it is unplugged at runtime.
+
\note The returned list cannot be used to add new devices. To add a simulated
touch screen for an autotest, QTest::createTouchDevice() can be used.
Platform plugins should call QWindowSystemInterface::registerInputDevice()
@@ -360,19 +367,24 @@ bool QInputDevice::operator==(const QInputDevice &other) const
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QInputDevice *device)
{
- const QInputDevicePrivate *d = QInputDevicePrivate::get(device);
- if (d->pointingDeviceType)
- return operator<<(debug, static_cast<const QPointingDevice *>(device));
QDebugStateSaver saver(debug);
debug.nospace();
debug.noquote();
+
debug << "QInputDevice(";
- if (device) {
- debug << '"' << device->name() << "\", type=" << device->type()
- << Qt::hex << ", ID=" << device->systemId() << ", seat='" << device->seatName() << "'";
- } else {
- debug << '0';
+ if (!device) {
+ debug << "0)";
+ return debug;
}
+
+ const QInputDevicePrivate *d = QInputDevicePrivate::get(device);
+
+ if (d->pointingDeviceType)
+ return operator<<(debug, static_cast<const QPointingDevice *>(device));
+
+ debug << "QInputDevice(";
+ debug << '"' << device->name() << "\", type=" << device->type()
+ << ", ID=" << device->systemId() << ", seat='" << device->seatName() << "'";
debug << ')';
return debug;
}
diff --git a/src/gui/kernel/qinternalmimedata.cpp b/src/gui/kernel/qinternalmimedata.cpp
index 9fd7f89a0f..d33402703e 100644
--- a/src/gui/kernel/qinternalmimedata.cpp
+++ b/src/gui/kernel/qinternalmimedata.cpp
@@ -20,7 +20,7 @@ static QStringList imageMimeFormats(const QList<QByteArray> &imageFormats)
formats.append("image/"_L1 + QLatin1StringView(format.toLower()));
//put png at the front because it is best
- int pngIndex = formats.indexOf("image/png"_L1);
+ const qsizetype pngIndex = formats.indexOf("image/png"_L1);
if (pngIndex != -1 && pngIndex != 0)
formats.move(pngIndex, 0);
diff --git a/src/gui/kernel/qkeymapper.cpp b/src/gui/kernel/qkeymapper.cpp
index aa8eca5214..4ceb508465 100644
--- a/src/gui/kernel/qkeymapper.cpp
+++ b/src/gui/kernel/qkeymapper.cpp
@@ -9,6 +9,7 @@
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformkeymapper.h>
QT_BEGIN_NAMESPACE
@@ -23,8 +24,7 @@ QT_BEGIN_NAMESPACE
/*!
Constructs a new key mapper.
*/
-QKeyMapper::QKeyMapper()
- : QObject(*new QKeyMapperPrivate, nullptr)
+QKeyMapper::QKeyMapper() : QObject()
{
}
@@ -35,34 +35,34 @@ QKeyMapper::~QKeyMapper()
{
}
-static QList<int> extractKeyFromEvent(QKeyEvent *e)
+QList<QKeyCombination> QKeyMapper::possibleKeys(const QKeyEvent *e)
{
- QList<int> result;
- if (e->key() && (e->key() != Qt::Key_unknown))
- result << e->keyCombination().toCombined();
- else if (!e->text().isEmpty())
- result << int(e->text().at(0).unicode() + (int)e->modifiers());
- return result;
-}
+ qCDebug(lcQpaKeyMapper).verbosity(3) << "Computing possible key combinations for" << e;
-QList<int> QKeyMapper::possibleKeys(QKeyEvent *e)
-{
- return instance()->d_func()->possibleKeys(e);
-}
+ const auto *platformIntegration = QGuiApplicationPrivate::platformIntegration();
+ const auto *platformKeyMapper = platformIntegration->keyMapper();
+ QList<QKeyCombination> result = platformKeyMapper->possibleKeyCombinations(e);
-extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // in qapplication_*.cpp
-void QKeyMapper::changeKeyboard()
-{
- // ## TODO: Support KeyboardLayoutChange on QPA
-#if 0
- // inform all toplevel widgets of the change
- QEvent e(QEvent::KeyboardLayoutChange);
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
- qt_sendSpontaneousEvent(w, &e);
+ if (result.isEmpty()) {
+ if (e->key() && (e->key() != Qt::Key_unknown))
+ result << e->keyCombination();
+ else if (!e->text().isEmpty())
+ result << (Qt::Key(e->text().at(0).unicode()) | e->modifiers());
+ }
+
+#if QT_CONFIG(shortcut)
+ if (lcQpaKeyMapper().isDebugEnabled()) {
+ qCDebug(lcQpaKeyMapper) << "Resulting possible key combinations:";
+ for (auto keyCombination : result) {
+ auto keySequence = QKeySequence(keyCombination);
+ qCDebug(lcQpaKeyMapper).verbosity(0) << "\t-"
+ << keyCombination << "/" << keySequence << "/"
+ << qUtf8Printable(keySequence.toString(QKeySequence::NativeText));
+ }
}
#endif
+
+ return result;
}
Q_GLOBAL_STATIC(QKeyMapper, keymapper)
@@ -75,30 +75,6 @@ QKeyMapper *QKeyMapper::instance()
return keymapper();
}
-QKeyMapperPrivate *qt_keymapper_private()
-{
- return QKeyMapper::instance()->d_func();
-}
-
-QKeyMapperPrivate::QKeyMapperPrivate()
-{
- keyboardInputLocale = QLocale::system();
- keyboardInputDirection = keyboardInputLocale.textDirection();
-}
-
-QKeyMapperPrivate::~QKeyMapperPrivate()
-{
-}
-
-QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e)
-{
- QList<int> result = QGuiApplicationPrivate::platformIntegration()->possibleKeys(e);
- if (!result.isEmpty())
- return result;
-
- return extractKeyFromEvent(e);
-}
-
void *QKeyMapper::resolveInterface(const char *name, int revision) const
{
Q_UNUSED(name); Q_UNUSED(revision);
diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h
index 96c5620665..1a6a9a608f 100644
--- a/src/gui/kernel/qkeymapper_p.h
+++ b/src/gui/kernel/qkeymapper_p.h
@@ -25,7 +25,6 @@
QT_BEGIN_NAMESPACE
-class QKeyMapperPrivate;
class Q_GUI_EXPORT QKeyMapper : public QObject
{
Q_OBJECT
@@ -34,35 +33,14 @@ public:
~QKeyMapper();
static QKeyMapper *instance();
- static void changeKeyboard();
- static QList<int> possibleKeys(QKeyEvent *e);
+ static QList<QKeyCombination> possibleKeys(const QKeyEvent *e);
QT_DECLARE_NATIVE_INTERFACE_ACCESSOR(QKeyMapper)
private:
- friend QKeyMapperPrivate *qt_keymapper_private();
- Q_DECLARE_PRIVATE(QKeyMapper)
Q_DISABLE_COPY_MOVE(QKeyMapper)
};
-struct KeyboardLayoutItem;
-class QKeyEvent;
-
-class QKeyMapperPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QKeyMapper)
-public:
- QKeyMapperPrivate();
- ~QKeyMapperPrivate();
-
- QList<int> possibleKeys(QKeyEvent *e);
-
- QLocale keyboardInputLocale;
- Qt::LayoutDirection keyboardInputDirection;
-};
-
-QKeyMapperPrivate *qt_keymapper_private(); // from qkeymapper.cpp
-
// ----------------- QNativeInterface -----------------
namespace QNativeInterface::Private {
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 7085e65ae4..0529d940d2 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -13,7 +13,7 @@
#endif
#include "qvariant.h"
-#if defined(Q_OS_MACOS)
+#if defined(Q_OS_APPLE)
#include <QtCore/private/qcore_mac_p.h>
#endif
@@ -24,11 +24,11 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-#if defined(Q_OS_MACOS) || defined(Q_QDOC)
+#if defined(Q_OS_APPLE) || defined(Q_QDOC)
Q_CONSTINIT static bool qt_sequence_no_mnemonics = true;
-struct MacSpecialKey {
+struct AppleSpecialKey {
int key;
- ushort macSymbol;
+ ushort appleSymbol;
};
// Unicode code points for the glyphs associated with these keys
@@ -38,7 +38,7 @@ static constexpr int kControlUnicode = 0x2303;
static constexpr int kOptionUnicode = 0x2325;
static constexpr int kCommandUnicode = 0x2318;
-static constexpr MacSpecialKey entries[] = {
+static constexpr AppleSpecialKey entries[] = {
{ Qt::Key_Escape, 0x238B },
{ Qt::Key_Tab, 0x21E5 },
{ Qt::Key_Backtab, 0x21E4 },
@@ -63,45 +63,45 @@ static constexpr MacSpecialKey entries[] = {
{ Qt::Key_Eject, 0x23CF },
};
-static constexpr bool operator<(const MacSpecialKey &lhs, const MacSpecialKey &rhs)
+static constexpr bool operator<(const AppleSpecialKey &lhs, const AppleSpecialKey &rhs)
{
return lhs.key < rhs.key;
}
-static constexpr bool operator<(const MacSpecialKey &lhs, int rhs)
+static constexpr bool operator<(const AppleSpecialKey &lhs, int rhs)
{
return lhs.key < rhs;
}
-static constexpr bool operator<(int lhs, const MacSpecialKey &rhs)
+static constexpr bool operator<(int lhs, const AppleSpecialKey &rhs)
{
return lhs < rhs.key;
}
static_assert(q20::is_sorted(std::begin(entries), std::end(entries)));
-QChar qt_macSymbolForQtKey(int key)
+static QChar appleSymbolForQtKey(int key)
{
const auto i = std::lower_bound(std::begin(entries), std::end(entries), key);
if (i == std::end(entries) || key < *i)
return QChar();
- ushort macSymbol = i->macSymbol;
+ ushort appleSymbol = i->appleSymbol;
if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)
- && (macSymbol == kControlUnicode || macSymbol == kCommandUnicode)) {
- if (macSymbol == kControlUnicode)
- macSymbol = kCommandUnicode;
+ && (appleSymbol == kControlUnicode || appleSymbol == kCommandUnicode)) {
+ if (appleSymbol == kControlUnicode)
+ appleSymbol = kCommandUnicode;
else
- macSymbol = kControlUnicode;
+ appleSymbol = kControlUnicode;
}
- return QChar(macSymbol);
+ return QChar(appleSymbol);
}
-static int qtkeyForMacSymbol(const QChar ch)
+static int qtkeyForAppleSymbol(const QChar ch)
{
const ushort unicode = ch.unicode();
- for (const MacSpecialKey &entry : entries) {
- if (entry.macSymbol == unicode) {
+ for (const AppleSpecialKey &entry : entries) {
+ if (entry.appleSymbol == unicode) {
int key = entry.key;
if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)
&& (unicode == kControlUnicode || unicode == kCommandUnicode)) {
@@ -191,7 +191,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
QKeySequence objects can be cast to a QString to obtain a human-readable
translated version of the sequence. Similarly, the toString() function
- produces human-readable strings for use in menus. On \macos, the
+ produces human-readable strings for use in menus. On Apple platforms, the
appropriate symbols are used to describe keyboard shortcuts using special
keys on the Macintosh keyboard.
@@ -199,12 +199,12 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
code point of the character; for example, 'A' gives the same key sequence
as Qt::Key_A.
- \note On \macos, references to "Ctrl", Qt::CTRL, Qt::Key_Control
+ \note On Apple platforms, references to "Ctrl", Qt::CTRL, Qt::Key_Control
and Qt::ControlModifier correspond to the \uicontrol Command keys on the
Macintosh keyboard, and references to "Meta", Qt::META, Qt::Key_Meta and
- Qt::MetaModifier correspond to the \uicontrol Control keys. Developers on
- \macos can use the same shortcut descriptions across all platforms,
- and their applications will automatically work as expected on \macos.
+ Qt::MetaModifier correspond to the \uicontrol Control keys. In effect,
+ developers can use the same shortcut descriptions across all platforms,
+ and their applications will automatically work as expected on Apple platforms.
\section1 Standard Shortcuts
@@ -213,21 +213,21 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
setting up actions in a typical application. The table below shows
some common key sequences that are often used for these standard
shortcuts by applications on four widely-used platforms. Note
- that on \macos, the \uicontrol Ctrl value corresponds to the \uicontrol
+ that on Apple platforms, the \uicontrol Ctrl value corresponds to the \uicontrol
Command keys on the Macintosh keyboard, and the \uicontrol Meta value
corresponds to the \uicontrol Control keys.
\table
- \header \li StandardKey \li Windows \li \macos \li KDE Plasma \li GNOME
+ \header \li StandardKey \li Windows \li Apple platforms \li KDE Plasma \li GNOME
\row \li HelpContents \li F1 \li Ctrl+? \li F1 \li F1
\row \li WhatsThis \li Shift+F1 \li Shift+F1 \li Shift+F1 \li Shift+F1
\row \li Open \li Ctrl+O \li Ctrl+O \li Ctrl+O \li Ctrl+O
\row \li Close \li Ctrl+F4, Ctrl+W \li Ctrl+W, Ctrl+F4 \li Ctrl+W \li Ctrl+W
\row \li Save \li Ctrl+S \li Ctrl+S \li Ctrl+S \li Ctrl+S
\row \li Quit \li \li Ctrl+Q \li Ctrl+Q \li Ctrl+Q
- \row \li SaveAs \li \li Ctrl+Shift+S \li \li Ctrl+Shift+S
+ \row \li SaveAs \li Ctrl+Shift+S \li Ctrl+Shift+S \li Ctrl+Shift+S \li Ctrl+Shift+S
\row \li New \li Ctrl+N \li Ctrl+N \li Ctrl+N \li Ctrl+N
- \row \li Delete \li Del \li Del, Meta+D \li Del, Ctrl+D \li Del, Ctrl+D
+ \row \li Delete \li Del \li Forward Delete, Meta+D \li Del, Ctrl+D \li Del, Ctrl+D
\row \li Cut \li Ctrl+X, Shift+Del \li Ctrl+X, Meta+K \li Ctrl+X, F20, Shift+Del \li Ctrl+X, F20, Shift+Del
\row \li Copy \li Ctrl+C, Ctrl+Ins \li Ctrl+C \li Ctrl+C, F16, Ctrl+Ins \li Ctrl+C, F16, Ctrl+Ins
\row \li Paste \li Ctrl+V, Shift+Ins \li Ctrl+V, Meta+Y \li Ctrl+V, F18, Shift+Ins \li Ctrl+V, F18, Shift+Ins
@@ -287,7 +287,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
\row \li DeleteCompleteLine \li (none) \li (none) \li Ctrl+U \li Ctrl+U
\row \li InsertParagraphSeparator \li Enter \li Enter \li Enter \li Enter
\row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter, Meta+O \li Shift+Enter \li Shift+Enter
- \row \li Backspace \li (none) \li Meta+H \li (none) \li (none)
+ \row \li Backspace \li (none) \li Delete, Meta+H \li (none) \li (none)
\row \li Cancel \li Escape \li Escape, Ctrl+. \li Escape \li Escape
\endtable
@@ -374,7 +374,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
\enum QKeySequence::SequenceFormat
\value NativeText The key sequence as a platform specific string.
- This means that it will be shown translated and on the Mac it will
+ This means that it will be shown translated and on Apple platforms it will
resemble a key sequence from the menu bar. This enum is best used when you
want to display the string to the user.
@@ -710,7 +710,7 @@ static constexpr int numKeyNames = sizeof keyname / sizeof *keyname;
\value InsertLineSeparator Insert a new line.
\value InsertParagraphSeparator Insert a new paragraph.
\value Italic Italic text.
- \value MoveToEndOfBlock Move cursor to end of block. This shortcut is only used on the \macos.
+ \value MoveToEndOfBlock Move cursor to end of block. This shortcut is only used on Apple platforms.
\value MoveToEndOfDocument Move cursor to end of document.
\value MoveToEndOfLine Move cursor to end of line.
\value MoveToNextChar Move cursor to next character.
@@ -721,7 +721,7 @@ static constexpr int numKeyNames = sizeof keyname / sizeof *keyname;
\value MoveToPreviousLine Move cursor to previous line.
\value MoveToPreviousPage Move cursor to previous page.
\value MoveToPreviousWord Move cursor to previous word.
- \value MoveToStartOfBlock Move cursor to start of a block. This shortcut is only used on \macos.
+ \value MoveToStartOfBlock Move cursor to start of a block. This shortcut is only used on Apple platforms.
\value MoveToStartOfDocument Move cursor to start of document.
\value MoveToStartOfLine Move cursor to start of line.
\value New Create new document.
@@ -739,7 +739,7 @@ static constexpr int numKeyNames = sizeof keyname / sizeof *keyname;
\value Save Save document.
\value SelectAll Select all text.
\value Deselect Deselect text. Since 5.1
- \value SelectEndOfBlock Extend selection to the end of a text block. This shortcut is only used on \macos.
+ \value SelectEndOfBlock Extend selection to the end of a text block. This shortcut is only used on Apple platforms.
\value SelectEndOfDocument Extend selection to end of document.
\value SelectEndOfLine Extend selection to end of line.
\value SelectNextChar Extend selection to next character.
@@ -750,7 +750,7 @@ static constexpr int numKeyNames = sizeof keyname / sizeof *keyname;
\value SelectPreviousLine Extend selection to previous line.
\value SelectPreviousPage Extend selection to previous page.
\value SelectPreviousWord Extend selection to previous word.
- \value SelectStartOfBlock Extend selection to the start of a text block. This shortcut is only used on \macos.
+ \value SelectStartOfBlock Extend selection to the start of a text block. This shortcut is only used on Apple platforms.
\value SelectStartOfDocument Extend selection to start of document.
\value SelectStartOfLine Extend selection to start of line.
\value Underline Underline text.
@@ -784,8 +784,8 @@ QKeySequence::QKeySequence(StandardKey key)
{
const QList <QKeySequence> bindings = keyBindings(key);
//pick only the first/primary shortcut from current bindings
- if (bindings.size() > 0) {
- d = bindings.first().d;
+ if (!bindings.isEmpty()) {
+ d = bindings.constFirst().d;
d->ref.ref();
}
else
@@ -931,11 +931,6 @@ bool QKeySequence::isEmpty() const
For example, mnemonic("E&xit") returns \c{Qt::ALT+Qt::Key_X},
mnemonic("&Quit") returns \c{ALT+Key_Q}, and mnemonic("Quit")
returns an empty QKeySequence.
-
- We provide a \l{accelerators.html}{list of common mnemonics}
- in English. At the time of writing, Microsoft and Open Group do
- not appear to have issued equivalent recommendations for other
- languages.
*/
QKeySequence QKeySequence::mnemonic(const QString &text)
{
@@ -945,7 +940,7 @@ QKeySequence QKeySequence::mnemonic(const QString &text)
return ret;
bool found = false;
- int p = 0;
+ qsizetype p = 0;
while (p >= 0) {
p = text.indexOf(u'&', p) + 1;
if (p <= 0 || p >= (int)text.size())
@@ -998,7 +993,7 @@ int QKeySequence::assign(const QString &ks, QKeySequence::SequenceFormat format)
{
QString keyseq = ks;
int n = 0;
- int p = 0, diff = 0;
+ qsizetype p = 0, diff = 0;
// Run through the whole string, but stop
// if we have MaxKeyCount keys before the end.
@@ -1023,7 +1018,7 @@ int QKeySequence::assign(const QString &ks, QKeySequence::SequenceFormat format)
}
QString part = keyseq.left(-1 == p ? keyseq.size() : p - diff);
keyseq = keyseq.right(-1 == p ? 0 : keyseq.size() - (p + 1));
- d->key[n] = QKeySequencePrivate::decodeString(std::move(part), format);
+ d->key[n] = QKeySequencePrivate::decodeString(std::move(part), format).toCombined();
++n;
}
return n;
@@ -1041,15 +1036,7 @@ Q_DECLARE_TYPEINFO(QModifKeyName, Q_RELOCATABLE_TYPE);
Q_GLOBAL_STATIC(QList<QModifKeyName>, globalModifs)
Q_GLOBAL_STATIC(QList<QModifKeyName>, globalPortableModifs)
-/*!
- Constructs a single key from the string \a str.
-*/
-int QKeySequence::decodeString(const QString &str)
-{
- return QKeySequencePrivate::decodeString(str, NativeText);
-}
-
-int QKeySequencePrivate::decodeString(QString accel, QKeySequence::SequenceFormat format)
+QKeyCombination QKeySequencePrivate::decodeString(QString accel, QKeySequence::SequenceFormat format)
{
Q_ASSERT(!accel.isEmpty());
@@ -1061,7 +1048,7 @@ int QKeySequencePrivate::decodeString(QString accel, QKeySequence::SequenceForma
if (nativeText) {
gmodifs = globalModifs();
if (gmodifs->isEmpty()) {
-#if defined(Q_OS_MACOS)
+#if defined(Q_OS_APPLE)
const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
if (dontSwap)
*gmodifs << QModifKeyName(Qt::META, QChar(kCommandUnicode));
@@ -1103,7 +1090,7 @@ int QKeySequencePrivate::decodeString(QString accel, QKeySequence::SequenceForma
modifs += *gmodifs; // Test non-translated ones last
QString sl = accel;
-#if defined(Q_OS_MACOS)
+#if defined(Q_OS_APPLE)
for (int i = 0; i < modifs.size(); ++i) {
const QModifKeyName &mkf = modifs.at(i);
if (sl.contains(mkf.name)) {
@@ -1116,8 +1103,8 @@ int QKeySequencePrivate::decodeString(QString accel, QKeySequence::SequenceForma
return Qt::Key_unknown;
#endif
- int i = 0;
- int lastI = 0;
+ qsizetype i = 0;
+ qsizetype lastI = 0;
while ((i = sl.indexOf(u'+', i + 1)) != -1) {
const QStringView sub = QStringView{sl}.mid(lastI, i - lastI + 1);
// If we get here the shortcuts contains at least one '+'. We break up
@@ -1151,15 +1138,15 @@ int QKeySequencePrivate::decodeString(QString accel, QKeySequence::SequenceForma
lastI = i + 1;
}
- int p = accel.lastIndexOf(u'+', accel.size() - 2); // -2 so that Ctrl++ works
+ qsizetype p = accel.lastIndexOf(u'+', accel.size() - 2); // -2 so that Ctrl++ works
QStringView accelRef(accel);
if (p > 0)
accelRef = accelRef.mid(p + 1);
int fnum = 0;
if (accelRef.size() == 1) {
-#if defined(Q_OS_MACOS)
- int qtKey = qtkeyForMacSymbol(accelRef.at(0));
+#if defined(Q_OS_APPLE)
+ int qtKey = qtkeyForAppleSymbol(accelRef.at(0));
if (qtKey != -1) {
ret |= qtKey;
} else
@@ -1194,17 +1181,7 @@ int QKeySequencePrivate::decodeString(QString accel, QKeySequence::SequenceForma
if (!found)
return Qt::Key_unknown;
}
- return ret;
-}
-
-/*!
- Creates a shortcut string for \a key. For example,
- Qt::CTRL+Qt::Key_O gives "Ctrl+O". The strings, "Ctrl", "Shift", etc. are
- translated (using QObject::tr()) in the "QShortcut" context.
- */
-QString QKeySequence::encodeString(int key)
-{
- return QKeySequencePrivate::encodeString(key, NativeText);
+ return QKeyCombination::fromCombined(ret);
}
static inline void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format)
@@ -1221,20 +1198,24 @@ static inline void addKey(QString &str, const QString &theKey, QKeySequence::Seq
str += theKey;
}
-QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat format)
+QString QKeySequencePrivate::encodeString(QKeyCombination keyCombination, QKeySequence::SequenceFormat format)
{
bool nativeText = (format == QKeySequence::NativeText);
QString s;
+ const auto key = keyCombination.key();
+
// Handle -1 (Invalid Key) and Qt::Key_unknown gracefully
- if (key == -1 || key == Qt::Key_unknown)
+ if (keyCombination.toCombined() == -1 || key == Qt::Key_unknown)
return s;
-#if defined(Q_OS_MACOS)
+ const auto modifiers = keyCombination.keyboardModifiers();
+
+#if defined(Q_OS_APPLE)
if (nativeText) {
- // On OS X the order (by default) is Meta, Alt, Shift, Control.
+ // On Apple platforms the order (by default) is Meta, Alt, Shift, Control.
// If the AA_MacDontSwapCtrlAndMeta is enabled, then the order
- // is Ctrl, Alt, Shift, Meta. The macSymbolForQtKey does this swap
+ // is Ctrl, Alt, Shift, Meta. The appleSymbolForQtKey helper does this swap
// for us, which means that we have to adjust our order here.
// The upshot is a lot more infrastructure to keep the number of
// if tests down and the code relatively clean.
@@ -1253,33 +1234,33 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat
}
for (int i = 0; modifierOrder[i] != 0; ++i) {
- if (key & modifierOrder[i])
- s += qt_macSymbolForQtKey(qtkeyOrder[i]);
+ if (modifiers & modifierOrder[i])
+ s += appleSymbolForQtKey(qtkeyOrder[i]);
}
} else
#endif
{
// On other systems the order is Meta, Control, Alt, Shift
- if ((key & Qt::META) == Qt::META)
+ if (modifiers & Qt::MetaModifier)
s = nativeText ? QCoreApplication::translate("QShortcut", "Meta") : QString::fromLatin1("Meta");
- if ((key & Qt::CTRL) == Qt::CTRL)
+ if (modifiers & Qt::ControlModifier)
addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Ctrl") : QString::fromLatin1("Ctrl"), format);
- if ((key & Qt::ALT) == Qt::ALT)
+ if (modifiers & Qt::AltModifier)
addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Alt") : QString::fromLatin1("Alt"), format);
- if ((key & Qt::SHIFT) == Qt::SHIFT)
+ if (modifiers & Qt::ShiftModifier)
addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Shift") : QString::fromLatin1("Shift"), format);
}
- if ((key & Qt::KeypadModifier) == Qt::KeypadModifier)
+ if (modifiers & Qt::KeypadModifier)
addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Num") : QString::fromLatin1("Num"), format);
- QString p = keyName(key, format);
+ QString keyName = QKeySequencePrivate::keyName(key, format);
-#if defined(Q_OS_MACOS)
+#if defined(Q_OS_APPLE)
if (nativeText)
- s += p;
+ s += keyName;
else
#endif
- addKey(s, p, format);
+ addKey(s, keyName, format);
return s;
}
@@ -1291,10 +1272,9 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat
This static method is used by encodeString() and by the D-Bus menu exporter.
*/
-QString QKeySequencePrivate::keyName(int key, QKeySequence::SequenceFormat format)
+QString QKeySequencePrivate::keyName(Qt::Key key, QKeySequence::SequenceFormat format)
{
bool nativeText = (format == QKeySequence::NativeText);
- key &= ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier);
QString p;
if (key && key < Qt::Key_Escape && key != Qt::Key_Space) {
@@ -1309,9 +1289,9 @@ QString QKeySequencePrivate::keyName(int key, QKeySequence::SequenceFormat forma
: QString::fromLatin1("F%1").arg(key - Qt::Key_F1 + 1);
} else if (key) {
int i=0;
-#if defined(Q_OS_MACOS)
+#if defined(Q_OS_APPLE)
if (nativeText) {
- QChar ch = qt_macSymbolForQtKey(key);
+ QChar ch = appleSymbolForQtKey(key);
if (!ch.isNull())
p = ch;
else
@@ -1319,7 +1299,7 @@ QString QKeySequencePrivate::keyName(int key, QKeySequence::SequenceFormat forma
} else
#endif
{
-#if defined(Q_OS_MACOS)
+#if defined(Q_OS_APPLE)
NonSymbol:
#endif
while (i < numKeyNames) {
@@ -1432,6 +1412,7 @@ bool QKeySequence::operator==(const QKeySequence &other) const
/*!
\since 5.6
+ \relates QKeySequence
Calculates the hash value of \a key, using
\a seed to seed the calculation.
@@ -1508,7 +1489,7 @@ bool QKeySequence::isDetached() const
If the key sequence has no keys, an empty string is returned.
- On \macos, the string returned resembles the sequence that is
+ On Apple platforms, the string returned resembles the sequence that is
shown in the menu bar if \a format is
QKeySequence::NativeText; otherwise, the string uses the
"portable" format, suitable for writing to a file.
@@ -1522,7 +1503,7 @@ QString QKeySequence::toString(SequenceFormat format) const
// look like our latin case on Windows and X11
int end = count();
for (int i = 0; i < end; ++i) {
- finalString += d->encodeString(d->key[i], format);
+ finalString += d->encodeString(QKeyCombination::fromCombined(d->key[i]), format);
finalString += ", "_L1;
}
finalString.truncate(finalString.size() - 2);
diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h
index 44fd1f9cca..4dae26a755 100644
--- a/src/gui/kernel/qkeysequence.h
+++ b/src/gui/kernel/qkeysequence.h
@@ -115,6 +115,7 @@ public:
NativeText,
PortableText
};
+ Q_ENUM(SequenceFormat)
QKeySequence();
QKeySequence(const QString &key, SequenceFormat format = NativeText);
@@ -135,6 +136,7 @@ public:
PartialMatch,
ExactMatch
};
+ Q_ENUM(SequenceMatch);
QString toString(SequenceFormat format = PortableText) const;
static QKeySequence fromString(const QString &str, SequenceFormat format = PortableText);
@@ -165,8 +167,6 @@ public:
bool isDetached() const;
private:
- static int decodeString(const QString &ks);
- static QString encodeString(int key);
int assign(const QString &str);
int assign(const QString &str, SequenceFormat format);
void setKey(QKeyCombination key, int index);
diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h
index 2f9a0b09aa..8b98e3778a 100644
--- a/src/gui/kernel/qkeysequence_p.h
+++ b/src/gui/kernel/qkeysequence_p.h
@@ -35,7 +35,7 @@ struct QKeyBinding
class QKeySequencePrivate
{
public:
- enum { MaxKeyCount = 4 }; // also used in QKeySequenceEdit
+ static constexpr int MaxKeyCount = 4 ; // also used in QKeySequenceEdit
constexpr QKeySequencePrivate() : ref(1), key{} {}
inline QKeySequencePrivate(const QKeySequencePrivate &copy) : ref(1)
{
@@ -44,10 +44,10 @@ public:
}
QAtomicInt ref;
int key[MaxKeyCount];
- static QString encodeString(int key, QKeySequence::SequenceFormat format);
+ static QString encodeString(QKeyCombination keyCombination, QKeySequence::SequenceFormat format);
// used in dbusmenu
- Q_GUI_EXPORT static QString keyName(int key, QKeySequence::SequenceFormat format);
- static int decodeString(QString accel, QKeySequence::SequenceFormat format);
+ Q_GUI_EXPORT static QString keyName(Qt::Key key, QKeySequence::SequenceFormat format);
+ static QKeyCombination decodeString(QString accel, QKeySequence::SequenceFormat format);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qoffscreensurface.h b/src/gui/kernel/qoffscreensurface.h
index 15ad430dae..410b6d2b61 100644
--- a/src/gui/kernel/qoffscreensurface.h
+++ b/src/gui/kernel/qoffscreensurface.h
@@ -8,7 +8,7 @@
#include <QtCore/QObject>
#include <QtCore/qnativeinterface.h>
#include <QtGui/qsurface.h>
-Q_MOC_INCLUDE(<QScreen>)
+Q_MOC_INCLUDE(<QtGui/qscreen.h>)
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index a018f86763..dd41318f72 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -69,6 +69,7 @@ QOpenGLContext *qt_gl_global_share_context()
/*!
\class QOpenGLContext
+ \ingroup painting-3D
\inmodule QtGui
\since 5.0
\brief The QOpenGLContext class represents a native OpenGL context, enabling
@@ -137,6 +138,22 @@ QOpenGLContext *qt_gl_global_share_context()
application is portable between different platforms. However, if you use
QOpenGLFunctions::glBindFramebuffer(), this is done automatically for you.
+ \warning WebAssembly
+
+ We recommend that only one QOpenGLContext is made current with a QSurface,
+ for the entire lifetime of the QSurface. Should more than once context be used,
+ it is important to understand that multiple QOpenGLContext instances may be
+ backed by the same native context underneath with the WebAssembly platform.
+ Therefore, calling makeCurrent() with the same QSurface on two QOpenGLContext
+ objects may not switch to a different native context in the second call. As
+ a result, any OpenGL state changes done after the second makeCurrent() may
+ alter the state of the first QOpenGLContext as well, as they are all backed
+ by the same native context.
+
+ \note This means that when targeting WebAssembly with existing OpenGL-based
+ Qt code, some porting may be required to cater to these limitations.
+
+
\sa QOpenGLFunctions, QOpenGLBuffer, QOpenGLShaderProgram, QOpenGLFramebufferObject
*/
@@ -153,6 +170,9 @@ QOpenGLContext *QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context
qWarning("No QTLS available. currentContext won't work");
return nullptr;
}
+ if (!context)
+ return nullptr;
+
threadContext = new QGuiGLThreadContext;
qwindow_context_storage()->setLocalData(threadContext);
}
@@ -451,6 +471,11 @@ void QOpenGLContext::destroy()
If you wish to make the context current in order to do clean-up, make sure
to only connect to the signal using a direct connection.
+
+ \note In Qt for Python, this signal will not be received when emitted
+ from the destructor of QOpenGLWidget or QOpenGLWindow due to the Python
+ instance already being destroyed. We recommend doing cleanups
+ in QWidget::hideEvent() instead.
*/
/*!
diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp
index bc7ac89b03..9e8c6ae5a8 100644
--- a/src/gui/kernel/qpaintdevicewindow.cpp
+++ b/src/gui/kernel/qpaintdevicewindow.cpp
@@ -171,6 +171,8 @@ bool QPaintDeviceWindow::event(QEvent *event)
auto region = QRect(QPoint(0, 0), size());
d->doFlush(region); // Will end up calling paintEvent
return true;
+ } else if (event->type() == QEvent::Resize) {
+ d->handleResizeEvent();
}
return QWindow::event(event);
diff --git a/src/gui/kernel/qpaintdevicewindow_p.h b/src/gui/kernel/qpaintdevicewindow_p.h
index 32db2cb7a4..85c11cbf91 100644
--- a/src/gui/kernel/qpaintdevicewindow_p.h
+++ b/src/gui/kernel/qpaintdevicewindow_p.h
@@ -31,6 +31,8 @@ public:
QPaintDeviceWindowPrivate();
~QPaintDeviceWindowPrivate() override;
+ virtual void handleResizeEvent() {}
+
virtual void beginPaint(const QRegion &region)
{
Q_UNUSED(region);
@@ -82,7 +84,7 @@ public:
void markWindowAsDirty()
{
Q_Q(QPaintDeviceWindow);
- dirtyRegion += QRect(QPoint(0, 0), q->size());
+ dirtyRegion = QRect(QPoint(0, 0), q->size());
}
private:
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index 4abbcd5e65..256ea52f01 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -1,8 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include "qpalette.h"
-#include "qguiapplication.h"
+#include "qpalette_p.h"
#include "qguiapplication_p.h"
#include "qdatastream.h"
#include "qvariant.h"
@@ -12,60 +11,11 @@
QT_BEGIN_NAMESPACE
-static int qt_palette_count = 1;
-
-static constexpr QPalette::ResolveMask colorRoleOffset(QPalette::ColorGroup colorGroup)
-{
- return qToUnderlying(QPalette::NColorRoles) * qToUnderlying(colorGroup);
-}
-
-static constexpr QPalette::ResolveMask bitPosition(QPalette::ColorGroup colorGroup,
- QPalette::ColorRole colorRole)
-{
- return colorRole + colorRoleOffset(colorGroup);
-}
-
-static_assert(bitPosition(QPalette::ColorGroup(QPalette::NColorGroups - 1),
+static_assert(QPalettePrivate::bitPosition(QPalette::ColorGroup(QPalette::NColorGroups - 1),
QPalette::ColorRole(QPalette::NColorRoles - 1))
< sizeof(QPalette::ResolveMask) * CHAR_BIT,
"The resolve mask type is not wide enough to fit the entire bit mask.");
-class QPalettePrivate
-{
-public:
- class Data : public QSharedData {
- public:
- // Every instance of Data has to have a unique serial number, even
- // if it gets created by copying another - we wouldn't create a copy
- // in the first place if the serial number should be the same!
- Data(const Data &other)
- : QSharedData(other)
- {
- for (int grp = 0; grp < int(QPalette::NColorGroups); grp++) {
- for (int role = 0; role < int(QPalette::NColorRoles); role++)
- br[grp][role] = other.br[grp][role];
- }
- }
- Data() = default;
-
- QBrush br[QPalette::NColorGroups][QPalette::NColorRoles];
- const int ser_no = qt_palette_count++;
- };
-
- QPalettePrivate(const QExplicitlySharedDataPointer<Data> &data)
- : ref(1), data(data)
- { }
- QPalettePrivate()
- : QPalettePrivate(QExplicitlySharedDataPointer<Data>(new Data))
- { }
-
- QAtomicInt ref;
- QPalette::ResolveMask resolveMask = {0};
- static inline int qt_palette_private_count = 0;
- int detach_no = ++qt_palette_private_count;
- QExplicitlySharedDataPointer<Data> data;
-};
-
static QColor qt_mix_colors(QColor a, QColor b)
{
return QColor((a.red() + b.red()) / 2, (a.green() + b.green()) / 2,
@@ -100,6 +50,24 @@ static void qt_placeholder_from_text(QPalette &pal, int alpha = 50)
}
}
+static void qt_ensure_default_accent_color(QPalette &pal)
+{
+ // have a lighter/darker factor handy, depending on dark/light heuristics
+ const int lighter = pal.base().color().lightness() > pal.text().color().lightness() ? 130 : 70;
+
+ // Act only for color groups where no accent color is set
+ for (int i = 0; i < QPalette::NColorGroups; ++i) {
+ const QPalette::ColorGroup group = static_cast<QPalette::ColorGroup>(i);
+ if (!pal.isBrushSet(group, QPalette::Accent)) {
+ // Default to highlight if available, otherwise use a shade of base
+ const QBrush accentBrush = pal.isBrushSet(group, QPalette::Highlight)
+ ? pal.brush(group, QPalette::Highlight)
+ : pal.brush(group, QPalette::Base).color().lighter(lighter);
+ pal.setBrush(group, QPalette::Accent, accentBrush);
+ }
+ }
+}
+
static void qt_palette_from_color(QPalette &pal, const QColor &button)
{
int h, s, v;
@@ -124,6 +92,7 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button)
whiteBrush, buttonBrush, buttonBrush);
qt_placeholder_from_text(pal);
+ qt_ensure_default_accent_color(pal);
}
/*!
@@ -325,6 +294,15 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button)
*/
/*!
+ \fn const QBrush & QPalette::accent() const
+ \since 6.6
+
+ Returns the accent brush of the current color group.
+
+ \sa ColorRole, brush()
+*/
+
+/*!
\fn const QBrush & QPalette::link() const
Returns the unvisited link text brush of the current color group.
@@ -524,6 +502,13 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button)
item. By default, the highlight color is
Qt::darkBlue.
+ \value [since 6.6] Accent
+ A color that typically contrasts or complements
+ Base, Window and Button colors. It usually represents
+ the users' choice of desktop personalisation.
+ Styling of interactive components is a typical use case.
+ Unless explicitly set, it defaults to Highlight.
+
\value HighlightedText A text color that contrasts with \c Highlight.
By default, the highlighted text color is Qt::white.
@@ -613,6 +598,7 @@ QPalette::QPalette(const QBrush &windowText, const QBrush &button,
base, window);
qt_placeholder_from_text(*this);
+ qt_ensure_default_accent_color(*this);
}
@@ -670,6 +656,7 @@ QPalette::QPalette(const QColor &button, const QColor &window)
whiteBrush, baseBrush, windowBrush);
qt_placeholder_from_text(*this);
+ qt_ensure_default_accent_color(*this);
}
/*!
@@ -807,7 +794,7 @@ void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b)
cg = Active;
}
- const auto newResolveMask = d->resolveMask | ResolveMask(1) << bitPosition(cg, cr);
+ const auto newResolveMask = d->resolveMask | ResolveMask(1) << QPalettePrivate::bitPosition(cg, cr);
const auto valueChanged = d->data->br[cg][cr] != b;
if (valueChanged) {
@@ -837,6 +824,10 @@ void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b)
*/
bool QPalette::isBrushSet(ColorGroup cg, ColorRole cr) const
{
+ // NoRole has no resolve mask and should never be set anyway
+ if (cr == NoRole)
+ return false;
+
if (cg == Current)
cg = currentGroup;
@@ -850,7 +841,7 @@ bool QPalette::isBrushSet(ColorGroup cg, ColorRole cr) const
return false;
}
- return d->resolveMask & (ResolveMask(1) << bitPosition(cg, cr));
+ return d->resolveMask & (ResolveMask(1) << QPalettePrivate::bitPosition(cg, cr));
}
/*!
@@ -885,8 +876,11 @@ void QPalette::detach()
Returns \c true (usually quickly) if this palette is equal to \a p;
otherwise returns \c false (slowly).
- \note The current ColorGroup is not taken into account when
- comparing palettes
+ \note The following is not taken into account when comparing palettes:
+ \list
+ \li the \c current ColorGroup
+ \li ColorRole NoRole \since 6.6
+ \endlist
\sa operator!=()
*/
@@ -896,6 +890,9 @@ bool QPalette::operator==(const QPalette &p) const
return true;
for(int grp = 0; grp < (int)NColorGroups; grp++) {
for(int role = 0; role < (int)NColorRoles; role++) {
+ // Dont't verify NoRole, because it has no resolve bit
+ if (role == NoRole)
+ continue;
if (d->data->br[grp][role] != p.d->data->br[grp][role])
return false;
}
@@ -953,7 +950,7 @@ static constexpr QPalette::ResolveMask allResolveMask()
QPalette::ResolveMask mask = {0};
for (int role = 0; role < int(QPalette::NColorRoles); ++role) {
for (int grp = 0; grp < int(QPalette::NColorGroups); ++grp) {
- mask |= (QPalette::ResolveMask(1) << bitPosition(QPalette::ColorGroup(grp), QPalette::ColorRole(role)));
+ mask |= (QPalette::ResolveMask(1) << QPalettePrivate::bitPosition(QPalette::ColorGroup(grp), QPalette::ColorRole(role)));
}
}
return mask;
@@ -979,8 +976,12 @@ QPalette QPalette::resolve(const QPalette &other) const
palette.detach();
for (int role = 0; role < int(NColorRoles); ++role) {
+ // Don't resolve NoRole, its bits are needed for Accent (see bitPosition)
+ if (role == NoRole)
+ continue;
+
for (int grp = 0; grp < int(NColorGroups); ++grp) {
- if (!(d->resolveMask & (ResolveMask(1) << bitPosition(ColorGroup(grp), ColorRole(role))))) {
+ if (!(d->resolveMask & (ResolveMask(1) << QPalettePrivate::bitPosition(ColorGroup(grp), ColorRole(role))))) {
palette.d->data.detach();
palette.d->data->br[grp][role] = other.d->data->br[grp][role];
}
@@ -1054,6 +1055,9 @@ QDataStream &operator<<(QDataStream &s, const QPalette &p)
max = QPalette::AlternateBase + 1;
else if (s.version() <= QDataStream::Qt_5_11)
max = QPalette::ToolTipText + 1;
+ else if (s.version() <= QDataStream::Qt_6_5)
+ max = QPalette::PlaceholderText + 1;
+
for (int r = 0; r < max; r++)
s << p.d->data->br[grp][r];
}
@@ -1097,15 +1101,25 @@ QDataStream &operator>>(QDataStream &s, QPalette &p)
} else if (s.version() <= QDataStream::Qt_5_11) {
p = QPalette();
max = QPalette::ToolTipText + 1;
+ } else if (s.version() <= QDataStream::Qt_6_5) {
+ p = QPalette();
+ max = QPalette::PlaceholderText + 1;
}
+
QBrush tmp;
for(int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) {
+ const QPalette::ColorGroup group = static_cast<QPalette::ColorGroup>(grp);
for(int role = 0; role < max; ++role) {
s >> tmp;
- p.setBrush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role, tmp);
+ p.setBrush(group, (QPalette::ColorRole)role, tmp);
}
+
+ // Accent defaults to Highlight for stream versions that don't have it.
+ if (s.version() < QDataStream::Qt_6_6)
+ p.setBrush(group, QPalette::Accent, p.brush(group, QPalette::Highlight));
}
+
}
return s;
}
@@ -1152,10 +1166,10 @@ void QPalette::setColorGroup(ColorGroup cg, const QBrush &windowText, const QBru
for (int cr = Highlight; cr <= LinkVisited; ++cr) {
if (cg == All) {
for (int group = Active; group < NColorGroups; ++group) {
- d->resolveMask &= ~(ResolveMask(1) << bitPosition(ColorGroup(group), ColorRole(cr)));
+ d->resolveMask &= ~(ResolveMask(1) << QPalettePrivate::bitPosition(ColorGroup(group), ColorRole(cr)));
}
} else {
- d->resolveMask &= ~(ResolveMask(1) << bitPosition(ColorGroup(cg), ColorRole(cr)));
+ d->resolveMask &= ~(ResolveMask(1) << QPalettePrivate::bitPosition(ColorGroup(cg), ColorRole(cr)));
}
}
}
diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h
index 0a6dc0b381..a6162e1090 100644
--- a/src/gui/kernel/qpalette.h
+++ b/src/gui/kernel/qpalette.h
@@ -45,6 +45,7 @@ public:
operator QVariant() const;
// Do not change the order, the serialization format depends on it
+ // Ensure these values are kept in sync with QQuickColorGroup's properties.
enum ColorGroup { Active, Disabled, Inactive, NColorGroups, Current, All, Normal = Active };
Q_ENUM(ColorGroup)
enum ColorRole { WindowText, Button, Light, Midlight, Dark, Mid,
@@ -55,7 +56,8 @@ public:
NoRole,
ToolTipBase, ToolTipText,
PlaceholderText,
- NColorRoles = PlaceholderText + 1,
+ Accent,
+ NColorRoles = Accent + 1,
};
Q_ENUM(ColorRole)
@@ -98,6 +100,7 @@ public:
inline const QBrush &link() const { return brush(Link); }
inline const QBrush &linkVisited() const { return brush(LinkVisited); }
inline const QBrush &placeholderText() const { return brush(PlaceholderText); }
+ inline const QBrush &accent() const { return brush(Accent); }
bool operator==(const QPalette &p) const;
inline bool operator!=(const QPalette &p) const { return !(operator==(p)); }
diff --git a/src/gui/kernel/qpalette_p.h b/src/gui/kernel/qpalette_p.h
new file mode 100644
index 0000000000..ce7c30d66d
--- /dev/null
+++ b/src/gui/kernel/qpalette_p.h
@@ -0,0 +1,77 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPALETTE_P_H
+#define QPALETTE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qpalette.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_GUI_EXPORT QPalettePrivate
+{
+public:
+ class Data : public QSharedData {
+ public:
+ // Every instance of Data has to have a unique serial number, even
+ // if it gets created by copying another - we wouldn't create a copy
+ // in the first place if the serial number should be the same!
+ Data(const Data &other)
+ : QSharedData(other)
+ {
+ for (int grp = 0; grp < int(QPalette::NColorGroups); grp++) {
+ for (int role = 0; role < int(QPalette::NColorRoles); role++)
+ br[grp][role] = other.br[grp][role];
+ }
+ }
+ Data() = default;
+
+ QBrush br[QPalette::NColorGroups][QPalette::NColorRoles];
+ const int ser_no = qt_palette_count++;
+ };
+
+ QPalettePrivate(const QExplicitlySharedDataPointer<Data> &data)
+ : ref(1), data(data)
+ { }
+ QPalettePrivate()
+ : QPalettePrivate(QExplicitlySharedDataPointer<Data>(new Data))
+ { }
+
+ static constexpr QPalette::ResolveMask colorRoleOffset(QPalette::ColorGroup colorGroup)
+ {
+ // Exclude NoRole; that bit is used for Accent
+ return (qToUnderlying(QPalette::NColorRoles) - 1) * qToUnderlying(colorGroup);
+ }
+
+ static constexpr QPalette::ResolveMask bitPosition(QPalette::ColorGroup colorGroup,
+ QPalette::ColorRole colorRole)
+ {
+ // Map Accent into NoRole for resolving purposes
+ if (colorRole == QPalette::Accent)
+ colorRole = QPalette::NoRole;
+
+ return colorRole + colorRoleOffset(colorGroup);
+ }
+
+ QAtomicInt ref;
+ QPalette::ResolveMask resolveMask = {0};
+ static inline int qt_palette_count = 0;
+ static inline int qt_palette_private_count = 0;
+ int detach_no = ++qt_palette_private_count;
+ QExplicitlySharedDataPointer<Data> data;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPALETTE_P_H
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index f1370a07b8..93de7933d4 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -776,7 +776,11 @@ public:
QList<QMessageDialogOptions::CustomButton> customButtons;
int nextCustomButtonId;
QPixmap iconPixmap;
- bool enableSupressionCheckBox = false;
+ QString checkBoxLabel;
+ Qt::CheckState checkBoxState = Qt::Unchecked;
+ int defaultButtonId = 0;
+ int escapeButtonId = 0;
+ QMessageDialogOptions::Options options;
};
QMessageDialogOptions::QMessageDialogOptions(QMessageDialogOptionsPrivate *dd)
@@ -879,9 +883,9 @@ QPlatformDialogHelper::StandardButtons QMessageDialogOptions::standardButtons()
}
int QMessageDialogOptions::addButton(const QString &label, QPlatformDialogHelper::ButtonRole role,
- void *buttonImpl)
+ void *buttonImpl, int buttonId)
{
- const CustomButton b(d->nextCustomButtonId++, label, role, buttonImpl);
+ const CustomButton b(buttonId ? buttonId : d->nextCustomButtonId++, label, role, buttonImpl);
d->customButtons.append(b);
return b.id;
}
@@ -901,22 +905,76 @@ const QList<QMessageDialogOptions::CustomButton> &QMessageDialogOptions::customB
return d->customButtons;
}
+void QMessageDialogOptions::clearCustomButtons()
+{
+ d->customButtons.clear();
+}
+
const QMessageDialogOptions::CustomButton *QMessageDialogOptions::customButton(int id)
{
- int i = d->customButtons.indexOf(CustomButton(id));
+ const int i = int(d->customButtons.indexOf(CustomButton(id)));
return (i < 0 ? nullptr : &d->customButtons.at(i));
}
-void QMessageDialogOptions::setSupressionCheckBoxEnabled(bool enabled)
+void QMessageDialogOptions::setCheckBox(const QString &label, Qt::CheckState state)
+{
+ d->checkBoxLabel = label;
+ d->checkBoxState = state;
+}
+
+QString QMessageDialogOptions::checkBoxLabel() const
{
- d->enableSupressionCheckBox = enabled;
+ return d->checkBoxLabel;
}
-bool QMessageDialogOptions::supressionCheckBoxEnabled() const
+Qt::CheckState QMessageDialogOptions::checkBoxState() const
{
- return d->enableSupressionCheckBox;
+ return d->checkBoxState;
}
+void QMessageDialogOptions::setDefaultButton(int id)
+{
+ d->defaultButtonId = id;
+}
+
+int QMessageDialogOptions::defaultButton() const
+{
+ return d->defaultButtonId;
+}
+
+void QMessageDialogOptions::setEscapeButton(int id)
+{
+ d->escapeButtonId = id;
+}
+
+int QMessageDialogOptions::escapeButton() const
+{
+ return d->escapeButtonId;
+}
+
+void QMessageDialogOptions::setOption(QMessageDialogOptions::Option option, bool on)
+{
+ if (!(d->options & option) != !on)
+ setOptions(d->options ^ option);
+}
+
+bool QMessageDialogOptions::testOption(QMessageDialogOptions::Option option) const
+{
+ return d->options & option;
+}
+
+void QMessageDialogOptions::setOptions(QMessageDialogOptions::Options options)
+{
+ if (options != d->options)
+ d->options = options;
+}
+
+QMessageDialogOptions::Options QMessageDialogOptions::options() const
+{
+ return d->options;
+}
+
+
QPlatformDialogHelper::ButtonRole QPlatformDialogHelper::buttonRole(QPlatformDialogHelper::StandardButton button)
{
switch (button) {
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index 43d3dfe358..0569a7e2f9 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -157,7 +157,8 @@ public:
enum ColorDialogOption {
ShowAlphaChannel = 0x00000001,
NoButtons = 0x00000002,
- DontUseNativeDialog = 0x00000004
+ DontUseNativeDialog = 0x00000004,
+ NoEyeDropperButton = 0x00000008
};
Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption)
@@ -403,6 +404,13 @@ protected:
~QMessageDialogOptions();
public:
+ // Keep in sync with QMessageBox Option
+ enum class Option {
+ DontUseNativeDialog = 0x00000001,
+ };
+ Q_DECLARE_FLAGS(Options, Option);
+ Q_FLAG(Options);
+
// Keep in sync with QMessageBox::Icon
enum StandardIcon { NoIcon, Information, Warning, Critical, Question };
Q_ENUM(StandardIcon)
@@ -428,6 +436,11 @@ public:
void setDetailedText(const QString &text);
QString detailedText() const;
+ void setOption(Option option, bool on = true);
+ bool testOption(Option option) const;
+ void setOptions(Options options);
+ Options options() const;
+
void setStandardButtons(QPlatformDialogHelper::StandardButtons buttons);
QPlatformDialogHelper::StandardButtons standardButtons() const;
@@ -446,13 +459,21 @@ public:
};
int addButton(const QString &label, QPlatformDialogHelper::ButtonRole role,
- void *buttonImpl = nullptr);
+ void *buttonImpl = nullptr, int buttonId = 0);
void removeButton(int id);
const QList<CustomButton> &customButtons();
const CustomButton *customButton(int id);
+ void clearCustomButtons();
+
+ void setCheckBox(const QString &label, Qt::CheckState state);
+ QString checkBoxLabel() const;
+ Qt::CheckState checkBoxState() const;
+
+ void setEscapeButton(int id);
+ int escapeButton() const;
- void setSupressionCheckBoxEnabled(bool enabled);
- bool supressionCheckBoxEnabled() const;
+ void setDefaultButton(int id);
+ int defaultButton() const;
private:
QMessageDialogOptionsPrivate *d;
@@ -467,7 +488,7 @@ public:
Q_SIGNALS:
void clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role);
- void supressionCheckBoxChanged(bool checked);
+ void checkBoxStateChanged(Qt::CheckState state);
private:
QSharedPointer<QMessageDialogOptions> m_options;
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
index 4c2b9e5b39..0ec2308453 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
@@ -179,14 +179,14 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
QRect rect = subRect;
if (rect.isNull() || rect == QRect(QPoint(0,0),size)) {
if (needsRowLength)
- funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.bytesPerLine() / 4);
+ funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, GLint(image.bytesPerLine() / 4));
funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size.width(), size.height(), 0, GL_RGBA, pixelType, image.constBits());
if (needsRowLength)
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} else {
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
// OpenGL 2.1+ or OpenGL ES/3+
- funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.bytesPerLine() / 4);
+ funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, GLint(image.bytesPerLine() / 4));
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()) + rect.x() * 4);
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
diff --git a/src/gui/kernel/qplatforminputcontext.cpp b/src/gui/kernel/qplatforminputcontext.cpp
index b8a53685e5..9d3ee4acb6 100644
--- a/src/gui/kernel/qplatforminputcontext.cpp
+++ b/src/gui/kernel/qplatforminputcontext.cpp
@@ -47,6 +47,11 @@ QT_BEGIN_NAMESPACE
QPlatformInputContext::QPlatformInputContext()
: QObject(*(new QPlatformInputContextPrivate))
{
+ // Delay initialization of cached input direction
+ // until super class has finished constructing.
+ QMetaObject::invokeMethod(this, [this]{
+ m_inputDirection = inputDirection();
+ }, Qt::QueuedConnection);
}
/*!
@@ -95,7 +100,7 @@ void QPlatformInputContext::update(Qt::InputMethodQueries)
}
/*!
- Called when when the word currently being composed in input item is tapped by
+ Called when the word currently being composed in the input item is tapped by
the user. Input methods often use this information to offer more word
suggestions to the user.
*/
@@ -192,22 +197,29 @@ void QPlatformInputContext::emitInputPanelVisibleChanged()
QLocale QPlatformInputContext::locale() const
{
- return qt_keymapper_private()->keyboardInputLocale;
+ return QLocale::system();
}
void QPlatformInputContext::emitLocaleChanged()
{
emit QGuiApplication::inputMethod()->localeChanged();
+
+ // Changing the locale might have updated the input direction
+ emitInputDirectionChanged(inputDirection());
}
Qt::LayoutDirection QPlatformInputContext::inputDirection() const
{
- return qt_keymapper_private()->keyboardInputDirection;
+ return locale().textDirection();
}
void QPlatformInputContext::emitInputDirectionChanged(Qt::LayoutDirection newDirection)
{
+ if (newDirection == m_inputDirection)
+ return;
+
emit QGuiApplication::inputMethod()->inputDirectionChanged(newDirection);
+ m_inputDirection = newDirection;
}
/*!
diff --git a/src/gui/kernel/qplatforminputcontext.h b/src/gui/kernel/qplatforminputcontext.h
index 05d7497f9c..481f97a065 100644
--- a/src/gui/kernel/qplatforminputcontext.h
+++ b/src/gui/kernel/qplatforminputcontext.h
@@ -72,6 +72,8 @@ private:
friend class QGuiApplication;
friend class QGuiApplicationPrivate;
friend class QInputMethod;
+
+ Qt::LayoutDirection m_inputDirection;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatforminputcontextfactory.cpp b/src/gui/kernel/qplatforminputcontextfactory.cpp
index bc1e0cc78f..933d990f7c 100644
--- a/src/gui/kernel/qplatforminputcontextfactory.cpp
+++ b/src/gui/kernel/qplatforminputcontextfactory.cpp
@@ -15,23 +15,46 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
#if QT_CONFIG(settings)
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, icLoader,
(QPlatformInputContextFactoryInterface_iid, "/platforminputcontexts"_L1, Qt::CaseInsensitive))
#endif
QStringList QPlatformInputContextFactory::keys()
{
#if QT_CONFIG(settings)
- return loader()->keyMap().values();
+ return icLoader()->keyMap().values();
#else
return QStringList();
#endif
}
-QString QPlatformInputContextFactory::requested()
+QStringList QPlatformInputContextFactory::requested()
{
- QByteArray env = qgetenv("QT_IM_MODULE");
- return env.isNull() ? QString() : QString::fromLocal8Bit(env);
+ QStringList imList;
+ QByteArray env = qgetenv("QT_IM_MODULES");
+
+ if (!env.isEmpty())
+ imList = QString::fromLocal8Bit(env).split(QChar::fromLatin1(';'), Qt::SkipEmptyParts);
+
+ if (!imList.isEmpty())
+ return imList;
+
+ env = qgetenv("QT_IM_MODULE");
+ if (!env.isEmpty())
+ imList = {QString::fromLocal8Bit(env)};
+
+ return imList;
+}
+
+QPlatformInputContext *QPlatformInputContextFactory::create(const QStringList& keys)
+{
+ for (const QString &key : keys) {
+ auto plugin = create(key);
+ if (plugin)
+ return plugin;
+ }
+
+ return nullptr;
}
QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key)
@@ -42,7 +65,7 @@ QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key)
const QString platform = paramList.takeFirst().toLower();
QPlatformInputContext *ic = qLoadPlugin<QPlatformInputContext, QPlatformInputContextPlugin>
- (loader(), platform, paramList);
+ (icLoader(), platform, paramList);
if (ic && ic->isValid())
return ic;
diff --git a/src/gui/kernel/qplatforminputcontextfactory_p.h b/src/gui/kernel/qplatforminputcontextfactory_p.h
index 4968a51a8b..5f5881c508 100644
--- a/src/gui/kernel/qplatforminputcontextfactory_p.h
+++ b/src/gui/kernel/qplatforminputcontextfactory_p.h
@@ -27,7 +27,8 @@ class Q_GUI_EXPORT QPlatformInputContextFactory
{
public:
static QStringList keys();
- static QString requested();
+ static QStringList requested();
+ static QPlatformInputContext *create(const QStringList &keys);
static QPlatformInputContext *create(const QString &key);
static QPlatformInputContext *create();
};
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index c95742b34d..130b479c64 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -6,6 +6,7 @@
#include <qpa/qplatformfontdatabase.h>
#include <qpa/qplatformclipboard.h>
#include <qpa/qplatformaccessibility.h>
+#include <qpa/qplatformkeymapper.h>
#include <qpa/qplatformtheme.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qpixmap_raster_p.h>
@@ -228,6 +229,11 @@ QPlatformServices *QPlatformIntegration::services() const
\value ScreenWindowGrabbing The platform supports grabbing window on screen.
On Wayland, this capability can be reported as \c false. The default implementation
of hasCapability() returns \c true.
+
+ \value BackingStoreStaticContents The platform backingstore supports static contents.
+ On resize of the backingstore the static contents region is provided, and the backing
+ store is expected to propagate the static content to the resized backing store, without
+ clients needing to repaint the static content region.
*/
/*!
@@ -342,6 +348,21 @@ QPlatformInputContext *QPlatformIntegration::inputContext() const
return nullptr;
}
+/*!
+ Accessor for the platform integration's key mapper.
+
+ Default implementation returns a default QPlatformKeyMapper.
+
+ \sa QPlatformKeyMapper
+*/
+QPlatformKeyMapper *QPlatformIntegration::keyMapper() const
+{
+ static QPlatformKeyMapper *keyMapper = nullptr;
+ if (!keyMapper)
+ keyMapper = new QPlatformKeyMapper;
+ return keyMapper;
+}
+
#if QT_CONFIG(accessibility)
/*!
@@ -416,6 +437,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
return QPlatformTheme::defaultThemeHint(QPlatformTheme::FlickMaximumVelocity);
case FlickDeceleration:
return QPlatformTheme::defaultThemeHint(QPlatformTheme::FlickDeceleration);
+ case UnderlineShortcut:
+ return true;
}
return 0;
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 3d43395767..a18ae821c7 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -33,6 +33,7 @@ class QPlatformOpenGLContext;
class QGuiGLFormat;
class QAbstractEventDispatcher;
class QPlatformInputContext;
+class QPlatformKeyMapper;
class QPlatformAccessibility;
class QPlatformTheme;
class QPlatformDialogHelper;
@@ -98,7 +99,8 @@ public:
MaximizeUsingFullscreenGeometry,
PaintEvents,
RhiBasedRendering,
- ScreenWindowGrabbing // whether QScreen::grabWindow() is supported
+ ScreenWindowGrabbing, // whether QScreen::grabWindow() is supported
+ BackingStoreStaticContents
};
virtual ~QPlatformIntegration() { }
@@ -164,14 +166,19 @@ public:
MouseDoubleClickDistance,
FlickStartDistance,
FlickMaximumVelocity,
- FlickDeceleration
+ FlickDeceleration,
+ UnderlineShortcut,
};
virtual QVariant styleHint(StyleHint hint) const;
virtual Qt::WindowState defaultWindowState(Qt::WindowFlags) const;
+protected:
virtual Qt::KeyboardModifiers queryKeyboardModifiers() const;
virtual QList<int> possibleKeys(const QKeyEvent *) const;
+ friend class QPlatformKeyMapper;
+public:
+ virtual QPlatformKeyMapper *keyMapper() const;
virtual QStringList themeNames() const;
virtual QPlatformTheme *createPlatformTheme(const QString &name) const;
diff --git a/src/gui/kernel/qplatformintegrationfactory.cpp b/src/gui/kernel/qplatformintegrationfactory.cpp
index c1523260c1..d0a5e8871f 100644
--- a/src/gui/kernel/qplatformintegrationfactory.cpp
+++ b/src/gui/kernel/qplatformintegrationfactory.cpp
@@ -14,13 +14,13 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, piLoader,
(QPlatformIntegrationFactoryInterface_iid, "/platforms"_L1, Qt::CaseInsensitive))
QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platform, const QStringList &paramList, int &argc, char **argv, const QString &platformPluginPath)
{
- loader->setExtraSearchPath(platformPluginPath);
- return qLoadPlugin<QPlatformIntegration, QPlatformIntegrationPlugin>(loader(), platform, paramList, argc, argv);
+ piLoader->setExtraSearchPath(platformPluginPath);
+ return qLoadPlugin<QPlatformIntegration, QPlatformIntegrationPlugin>(piLoader(), platform, paramList, argc, argv);
}
/*!
@@ -32,8 +32,8 @@ QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platfor
QStringList QPlatformIntegrationFactory::keys(const QString &platformPluginPath)
{
- loader->setExtraSearchPath(platformPluginPath);
- return loader->keyMap().values();
+ piLoader->setExtraSearchPath(platformPluginPath);
+ return piLoader->keyMap().values();
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformkeymapper.cpp b/src/gui/kernel/qplatformkeymapper.cpp
new file mode 100644
index 0000000000..f54e4ff379
--- /dev/null
+++ b/src/gui/kernel/qplatformkeymapper.cpp
@@ -0,0 +1,38 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qplatformkeymapper.h"
+
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcQpaKeyMapper, "qt.qpa.keymapper")
+
+QPlatformKeyMapper::~QPlatformKeyMapper()
+{
+}
+
+/*
+ Should return a list of possible key combinations for the given key event.
+
+ For example, given a US English keyboard layout, the key event Shift+5
+ can represent both a "Shift+5" key combination, as well as just "%".
+*/
+QList<QKeyCombination> QPlatformKeyMapper::possibleKeyCombinations(const QKeyEvent *event) const
+{
+ auto *platformIntegration = QGuiApplicationPrivate::platformIntegration();
+ QList<int> possibleKeys = platformIntegration->possibleKeys(event);
+ QList<QKeyCombination> combinations;
+ for (int key : possibleKeys)
+ combinations << QKeyCombination::fromCombined(key);
+ return combinations;
+}
+
+Qt::KeyboardModifiers QPlatformKeyMapper::queryKeyboardModifiers() const
+{
+ return QGuiApplicationPrivate::platformIntegration()->queryKeyboardModifiers();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformkeymapper.h b/src/gui/kernel/qplatformkeymapper.h
new file mode 100644
index 0000000000..fb5b0cdb8b
--- /dev/null
+++ b/src/gui/kernel/qplatformkeymapper.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPLATFORMKEYMAPPER_P
+#define QPLATFORMKEYMAPPER_P
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is part of the QPA API and is not meant to be used
+// in applications. Usage of this API may make your code
+// source and binary incompatible with future versions of Qt.
+//
+
+#include <QtGui/qtguiglobal.h>
+#include <QtCore/qloggingcategory.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_EXPORTED_LOGGING_CATEGORY(lcQpaKeyMapper, Q_GUI_EXPORT)
+
+class QKeyEvent;
+
+class Q_GUI_EXPORT QPlatformKeyMapper
+{
+public:
+ virtual ~QPlatformKeyMapper();
+
+ virtual QList<QKeyCombination> possibleKeyCombinations(const QKeyEvent *event) const;
+ virtual Qt::KeyboardModifiers queryKeyboardModifiers() const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPLATFORMKEYMAPPER_P
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index 9e038b4032..0369a0b12a 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -25,10 +25,8 @@ QPlatformScreen::QPlatformScreen()
QPlatformScreen::~QPlatformScreen()
{
Q_D(QPlatformScreen);
- if (d->screen) {
- qWarning("Manually deleting a QPlatformScreen. Call QWindowSystemInterface::handleScreenRemoved instead.");
- delete d->screen;
- }
+ Q_ASSERT_X(!d->screen, "QPlatformScreen",
+ "QPlatformScreens should be removed via QWindowSystemInterface::handleScreenRemoved()");
}
/*!
@@ -56,8 +54,9 @@ QPixmap QPlatformScreen::grabWindow(WId window, int x, int y, int width, int hei
QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const
{
const QWindowList list = QGuiApplication::topLevelWindows();
- for (int i = list.size()-1; i >= 0; --i) {
- QWindow *w = list[i];
+ const auto crend = list.crend();
+ for (auto it = list.crbegin(); it != crend; ++it) {
+ QWindow *w = *it;
if (w->isVisible() && QHighDpi::toNativePixels(w->geometry(), w).contains(pos))
return w;
}
diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h
index 3ef5798aa1..a547a635e9 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -42,6 +42,7 @@ typedef QPair<qreal, qreal> QDpi;
class Q_GUI_EXPORT QPlatformScreen
{
+ Q_GADGET
Q_DECLARE_PRIVATE(QPlatformScreen)
public:
@@ -132,7 +133,7 @@ protected:
QScopedPointer<QPlatformScreenPrivate> d_ptr;
private:
- friend class QScreenPrivate;
+ friend class QScreen;
};
// Qt doesn't currently support running with no platform screen
diff --git a/src/gui/kernel/qplatformscreen_p.h b/src/gui/kernel/qplatformscreen_p.h
index e871fc16c8..345a90845c 100644
--- a/src/gui/kernel/qplatformscreen_p.h
+++ b/src/gui/kernel/qplatformscreen_p.h
@@ -20,14 +20,6 @@
#include <QtCore/qpointer.h>
#include <QtCore/qnativeinterface.h>
-#if defined(Q_OS_WIN32)
-#include <qwindowdefs_win.h>
-#endif
-
-#if defined(Q_OS_UNIX)
-struct wl_output;
-#endif
-
QT_BEGIN_NAMESPACE
class QScreen;
@@ -75,31 +67,6 @@ struct Q_GUI_EXPORT QWebOSScreen
virtual void addFlipListener(void (*callback)()) = 0;
};
#endif
-
-#if defined(Q_OS_WIN32) || defined(Q_QDOC)
-struct Q_GUI_EXPORT QWindowsScreen
-{
- QT_DECLARE_NATIVE_INTERFACE(QWindowsScreen, 1, QScreen)
- virtual HMONITOR handle() const = 0;
-};
-#endif
-
-#if defined(Q_OS_UNIX) || defined(Q_CLANG_QDOC)
-struct Q_GUI_EXPORT QWaylandScreen
-{
- QT_DECLARE_NATIVE_INTERFACE(QWaylandScreen, 1, QScreen)
- virtual wl_output *output() const = 0;
-};
-#endif
-
-#if defined(Q_OS_ANDROID) || defined(Q_QDOC)
-struct Q_GUI_EXPORT QAndroidScreen
-{
- QT_DECLARE_NATIVE_INTERFACE(QAndroidScreen, 1, QScreen)
- virtual int displayId() const = 0;
-};
-#endif
-
} // QNativeInterface::Private
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformservices.cpp b/src/gui/kernel/qplatformservices.cpp
index 1c8062389d..7ff2a6c2f8 100644
--- a/src/gui/kernel/qplatformservices.cpp
+++ b/src/gui/kernel/qplatformservices.cpp
@@ -75,3 +75,5 @@ bool QPlatformServices::hasCapability(Capability capability) const
}
QT_END_NAMESPACE
+
+#include "moc_qplatformservices.cpp"
diff --git a/src/gui/kernel/qplatformsystemtrayicon.h b/src/gui/kernel/qplatformsystemtrayicon.h
index c2c80f9334..76a7ef03d9 100644
--- a/src/gui/kernel/qplatformsystemtrayicon.h
+++ b/src/gui/kernel/qplatformsystemtrayicon.h
@@ -6,6 +6,7 @@
#define QPLATFORMSYSTEMTRAYICON_H
#include <QtGui/qtguiglobal.h>
+#include <qpa/qplatformscreen.h>
#include "QtCore/qobject.h"
#ifndef QT_NO_SYSTEMTRAYICON
@@ -13,7 +14,6 @@
QT_BEGIN_NAMESPACE
class QPlatformMenu;
-class QPlatformScreen;
class QIcon;
class QString;
class QRect;
@@ -21,7 +21,6 @@ class QRect;
class Q_GUI_EXPORT QPlatformSystemTrayIcon : public QObject
{
Q_OBJECT
- Q_MOC_INCLUDE(<qpa/qplatformscreen.h>)
public:
enum ActivationReason {
Unknown,
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 498ecac2cd..48978b849a 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -325,7 +325,7 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Enter, KB_All},
{QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Return, KB_All},
{QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_O, KB_Mac},
- {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, KB_Gnome | KB_Mac},
+ {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, KB_All},
{QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, KB_Mac},
{QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, KB_X11 | KB_Gnome | KB_KDE | KB_Mac},
{QKeySequence::FullScreen, 1, Qt::META | Qt::CTRL | Qt::Key_F, KB_Mac},
@@ -335,6 +335,7 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE},
{QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11},
{QKeySequence::DeleteCompleteLine, 0, Qt::CTRL | Qt::Key_U, KB_X11},
+ {QKeySequence::Backspace, 1, Qt::Key_Backspace, KB_Mac},
{QKeySequence::Backspace, 0, Qt::META | Qt::Key_H, KB_Mac},
{QKeySequence::Cancel, 0, Qt::Key_Escape, KB_All},
{QKeySequence::Cancel, 0, Qt::CTRL | Qt::Key_Period, KB_Mac}
@@ -356,7 +357,7 @@ Q_GUI_EXPORT QPalette qt_fusionPalette()
{
auto theme = QGuiApplicationPrivate::platformTheme();
const bool darkAppearance = theme
- ? theme->appearance() == Qt::Appearance::Dark
+ ? theme->colorScheme() == Qt::ColorScheme::Dark
: false;
const QColor windowText = darkAppearance ? QColor(240, 240, 240) : Qt::black;
const QColor backGround = darkAppearance ? QColor(50, 50, 50) : QColor(239, 239, 239);
@@ -374,6 +375,7 @@ Q_GUI_EXPORT QPalette qt_fusionPalette()
const QColor button = backGround;
const QColor shadow = dark.darker(135);
const QColor disabledShadow = shadow.lighter(150);
+ const QColor disabledHighlight(145, 145, 145);
QColor placeholder = text;
placeholder.setAlpha(128);
@@ -392,7 +394,11 @@ Q_GUI_EXPORT QPalette qt_fusionPalette()
fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, highlight);
fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, highlight);
- fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145));
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, disabledHighlight);
+
+ fusionPalette.setBrush(QPalette::Active, QPalette::Accent, highlight);
+ fusionPalette.setBrush(QPalette::Inactive, QPalette::Accent, highlight);
+ fusionPalette.setBrush(QPalette::Disabled, QPalette::Accent, disabledHighlight);
fusionPalette.setBrush(QPalette::PlaceholderText, placeholder);
@@ -436,9 +442,9 @@ QPlatformDialogHelper *QPlatformTheme::createPlatformDialogHelper(DialogType typ
return nullptr;
}
-Qt::Appearance QPlatformTheme::appearance() const
+Qt::ColorScheme QPlatformTheme::colorScheme() const
{
- return Qt::Appearance::Unknown;
+ return Qt::ColorScheme::Unknown;
}
const QPalette *QPlatformTheme::palette(Palette type) const
@@ -525,6 +531,8 @@ QVariant QPlatformTheme::themeHint(ThemeHint hint) const
return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::FlickMaximumVelocity);
case QPlatformTheme::FlickDeceleration:
return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::FlickDeceleration);
+ case QPlatformTheme::UnderlineShortcut:
+ return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::UnderlineShortcut);
default:
return QPlatformTheme::defaultThemeHint(hint);
}
@@ -630,14 +638,17 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
case FlickMaximumVelocity:
return QVariant(2500);
case FlickDeceleration:
- return QVariant(5000);
+ return QVariant(1500);
case MenuBarFocusOnAltPressRelease:
return false;
case MouseCursorTheme:
return QVariant(QString());
case MouseCursorSize:
return QVariant(QSize(16, 16));
+ case UnderlineShortcut:
+ return true;
}
+
return QVariant();
}
@@ -805,33 +816,38 @@ QString QPlatformTheme::defaultStandardButtonText(int button)
QString QPlatformTheme::removeMnemonics(const QString &original)
{
+ const auto mnemonicInParentheses = [](QStringView text) {
+ /* Format of mnemonics to remove is /\(&[^&]\)/ but accept full-width
+ forms of ( and ) as equivalent, for cross-platform compatibility with
+ MS (and consequent behavior of translators, see QTBUG-110829).
+ */
+ Q_ASSERT(text.size() == 4); // Caller's responsibility.
+ constexpr QChar wideOpen = u'\uff08', wideClose = u'\uff09';
+ if (!text.startsWith(u'(') && !text.startsWith(wideOpen))
+ return false;
+ if (text[1] != u'&' || text[2] == u'&')
+ return false;
+ return text.endsWith(u')') || text.endsWith(wideClose);
+ };
QString returnText(original.size(), u'\0');
int finalDest = 0;
- int currPos = 0;
- int l = original.size();
- while (l) {
- if (original.at(currPos) == u'&') {
- ++currPos;
- --l;
- if (l == 0)
+ QStringView text(original);
+ while (!text.isEmpty()) {
+ if (text.startsWith(u'&')) {
+ text = text.sliced(1);
+ if (text.isEmpty())
break;
- } else if (original.at(currPos) == u'(' && l >= 4 &&
- original.at(currPos + 1) == u'&' &&
- original.at(currPos + 2) != u'&' &&
- original.at(currPos + 3) == u')') {
- /* remove mnemonics its format is "\s*(&X)" */
- int n = 0;
- while (finalDest > n && returnText.at(finalDest - n - 1).isSpace())
- ++n;
- finalDest -= n;
- currPos += 4;
- l -= 4;
+ } else if (text.size() >= 4 && mnemonicInParentheses(text.first(4))) {
+ // Advance over the matched mnemonic:
+ text = text.sliced(4);
+ // Also strip any leading space before it:
+ while (finalDest > 0 && returnText.at(finalDest - 1).isSpace())
+ --finalDest;
continue;
}
- returnText[finalDest] = original.at(currPos);
- ++currPos;
+ returnText[finalDest] = text.front();
+ text = text.sliced(1);
++finalDest;
- --l;
}
returnText.truncate(finalDest);
return returnText;
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 10a3246da8..c0193947b9 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -95,7 +95,8 @@ public:
FlickDeceleration,
MenuBarFocusOnAltPressRelease,
MouseCursorTheme,
- MouseCursorSize
+ MouseCursorSize,
+ UnderlineShortcut,
};
Q_ENUM(ThemeHint)
@@ -293,7 +294,7 @@ public:
virtual QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const;
#endif
- virtual Qt::Appearance appearance() const;
+ virtual Qt::ColorScheme colorScheme() const;
virtual const QPalette *palette(Palette type = SystemPalette) const;
diff --git a/src/gui/kernel/qplatformthemefactory.cpp b/src/gui/kernel/qplatformthemefactory.cpp
index 3d2c170198..beefa1c294 100644
--- a/src/gui/kernel/qplatformthemefactory.cpp
+++ b/src/gui/kernel/qplatformthemefactory.cpp
@@ -16,15 +16,15 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, ptLoader,
(QPlatformThemeFactoryInterface_iid, "/platformthemes"_L1, Qt::CaseInsensitive))
QPlatformTheme *QPlatformThemeFactory::create(const QString& key, const QString &platformPluginPath)
{
QStringList paramList = key.split(u':');
const QString platform = paramList.takeFirst().toLower();
- loader->setExtraSearchPath(platformPluginPath);
- QPlatformTheme *theme = qLoadPlugin<QPlatformTheme, QPlatformThemePlugin>(loader(), platform, paramList);
+ ptLoader->setExtraSearchPath(platformPluginPath);
+ QPlatformTheme *theme = qLoadPlugin<QPlatformTheme, QPlatformThemePlugin>(ptLoader(), platform, paramList);
if (theme)
theme->d_func()->name = key;
return theme;
@@ -38,8 +38,8 @@ QPlatformTheme *QPlatformThemeFactory::create(const QString& key, const QString
*/
QStringList QPlatformThemeFactory::keys(const QString &platformPluginPath)
{
- loader->setExtraSearchPath(platformPluginPath);
- return loader->keyMap().values();
+ ptLoader->setExtraSearchPath(platformPluginPath);
+ return ptLoader->keyMap().values();
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index e2c9fc4141..5c0ae2ee2a 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -370,18 +370,18 @@ void QPlatformWindow::setMask(const QRegion &region)
Reimplement to let Qt be able to request activation/focus for a window
Some window systems will probably not have callbacks for this functionality,
- and then calling QWindowSystemInterface::handleWindowActivated(QWindow *w)
+ and then calling QWindowSystemInterface::handleFocusWindowChanged(QWindow *w)
would be sufficient.
If the window system has some event handling/callbacks then call
- QWindowSystemInterface::handleWindowActivated(QWindow *w) when the window system
+ QWindowSystemInterface::handleFocusWindowChanged(QWindow *w) when the window system
gives the notification.
- Default implementation calls QWindowSystem::handleWindowActivated(QWindow *w)
+ Default implementation calls QWindowSystem::handleFocusWindowChanged(QWindow *w)
*/
void QPlatformWindow::requestActivateWindow()
{
- QWindowSystemInterface::handleWindowActivated(window());
+ QWindowSystemInterface::handleFocusWindowChanged(window());
}
/*!
@@ -778,6 +778,15 @@ void QPlatformWindow::deliverUpdateRequest()
QWindow *w = window();
QWindowPrivate *wp = qt_window_private(w);
+
+ // We expect that the platform plugins send DevicePixelRatioChange events.
+ // As a fail-safe make a final check here to make sure the cached DPR value is
+ // always up to date before delivering the update request.
+ if (wp->updateDevicePixelRatio()) {
+ qWarning() << "The cached device pixel ratio value was stale on window update. "
+ << "Please file a QTBUG which explains how to reproduce.";
+ }
+
wp->updateRequestPending = false;
QEvent request(QEvent::UpdateRequest);
QCoreApplication::sendEvent(w, &request);
diff --git a/src/gui/kernel/qplatformwindow_p.h b/src/gui/kernel/qplatformwindow_p.h
index 65b8b4a2c5..2bbdfd5bf9 100644
--- a/src/gui/kernel/qplatformwindow_p.h
+++ b/src/gui/kernel/qplatformwindow_p.h
@@ -19,9 +19,11 @@
#include <QtCore/qbasictimer.h>
#include <QtCore/qrect.h>
#include <QtCore/qnativeinterface.h>
+#include <QtGui/qwindow.h>
-#if defined(Q_OS_UNIX)
+#if QT_CONFIG(wayland)
#include <any>
+#include <QtCore/qobject.h>
struct wl_surface;
#endif
@@ -41,6 +43,15 @@ public:
namespace QNativeInterface::Private {
+#if defined(Q_OS_WASM) || defined(Q_QDOC)
+struct Q_GUI_EXPORT QWasmWindow
+{
+ QT_DECLARE_NATIVE_INTERFACE(QWasmWindow, 1, QWindow)
+ virtual emscripten::val document() const = 0;
+ virtual emscripten::val clientArea() const = 0;
+};
+#endif
+
#if defined(Q_OS_MACOS) || defined(Q_QDOC)
struct Q_GUI_EXPORT QCocoaWindow
{
@@ -95,7 +106,7 @@ struct Q_GUI_EXPORT QWindowsWindow
};
#endif // Q_OS_WIN
-#if defined(Q_OS_UNIX)
+#if QT_CONFIG(wayland)
struct Q_GUI_EXPORT QWaylandWindow : public QObject
{
Q_OBJECT
@@ -115,6 +126,8 @@ public:
Q_SIGNALS:
void surfaceCreated();
void surfaceDestroyed();
+ void surfaceRoleCreated();
+ void surfaceRoleDestroyed();
void xdgActivationTokenCreated(const QString &token);
protected:
diff --git a/src/gui/kernel/qpointingdevice.cpp b/src/gui/kernel/qpointingdevice.cpp
index f890fc1ca8..c4c1e5fd5c 100644
--- a/src/gui/kernel/qpointingdevice.cpp
+++ b/src/gui/kernel/qpointingdevice.cpp
@@ -564,7 +564,7 @@ bool QPointingDevicePrivate::addPassiveGrabber(const QPointerEvent *event, const
bool QPointingDevicePrivate::setPassiveGrabberContext(QPointingDevicePrivate::EventPointData *epd, QObject *grabber, QObject *context)
{
- int i = epd->passiveGrabbers.indexOf(grabber);
+ qsizetype i = epd->passiveGrabbers.indexOf(grabber);
if (i < 0)
return false;
if (epd->passiveGrabbersContext.size() <= i)
@@ -581,7 +581,7 @@ bool QPointingDevicePrivate::removePassiveGrabber(const QPointerEvent *event, co
qWarning() << "point is not in activePoints" << point;
return false;
}
- int i = persistentPoint->passiveGrabbers.indexOf(grabber);
+ qsizetype i = persistentPoint->passiveGrabbers.indexOf(grabber);
if (i >= 0) {
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
qCDebug(lcPointerGrab) << name << "point" << point.id() << point.state()
@@ -644,7 +644,7 @@ void QPointingDevicePrivate::removeGrabber(QObject *grabber, bool cancel)
cancel ? QPointingDevice::CancelGrabExclusive : QPointingDevice::UngrabExclusive,
nullptr, epd.eventPoint);
}
- int pi = epd.passiveGrabbers.indexOf(grabber);
+ qsizetype pi = epd.passiveGrabbers.indexOf(grabber);
if (pi >= 0) {
qCDebug(lcPointerGrab) << name << "point" << epd.eventPoint.id() << epd.eventPoint.state()
<< ": removing passive grabber" << grabber;
@@ -708,7 +708,7 @@ QDebug operator<<(QDebug debug, const QPointingDevice *device)
if (device) {
debug << '"' << device->name() << "\" ";
QtDebugUtils::formatQEnum(debug, device->type());
- debug << " id=" << Qt::hex << device->systemId() << Qt::dec;
+ debug << " id=" << device->systemId();
if (!device->seatName().isEmpty())
debug << " seat=" << device->seatName();
if (device->pointerType() != QPointingDevice::PointerType::Generic) {
diff --git a/src/gui/kernel/qpointingdevice.h b/src/gui/kernel/qpointingdevice.h
index f1b156bcb6..b8e6460af7 100644
--- a/src/gui/kernel/qpointingdevice.h
+++ b/src/gui/kernel/qpointingdevice.h
@@ -107,12 +107,13 @@ public:
bool operator==(const QPointingDevice &other) const;
Q_SIGNALS:
- void grabChanged(QObject *grabber, QPointingDevice::GrabTransition transition,
- const QPointerEvent *event, const QEventPoint &point)
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
- const
+ void grabChanged(QObject *grabber, GrabTransition transition,
+ const QPointerEvent *event, const QEventPoint &point) const;
+#else
+ void grabChanged(QObject *grabber, QPointingDevice::GrabTransition transition,
+ const QPointerEvent *event, const QEventPoint &point);
#endif
- ;
protected:
QPointingDevice(QPointingDevicePrivate &d, QObject *parent);
diff --git a/src/gui/kernel/qpointingdevice_p.h b/src/gui/kernel/qpointingdevice_p.h
index 403a54dc4f..b2f0574e9b 100644
--- a/src/gui/kernel/qpointingdevice_p.h
+++ b/src/gui/kernel/qpointingdevice_p.h
@@ -20,6 +20,8 @@
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qtguiglobal_p.h>
#include <QtGui/private/qinputdevice_p.h>
+
+#include <QtCore/qpointer.h>
#include <QtCore/private/qflatmap_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qrasterwindow.cpp b/src/gui/kernel/qrasterwindow.cpp
index 19d84c601d..f292344ca1 100644
--- a/src/gui/kernel/qrasterwindow.cpp
+++ b/src/gui/kernel/qrasterwindow.cpp
@@ -34,14 +34,20 @@ class QRasterWindowPrivate : public QPaintDeviceWindowPrivate
{
Q_DECLARE_PUBLIC(QRasterWindow)
public:
+ void handleResizeEvent() override
+ {
+ Q_Q(QRasterWindow);
+ if (backingstore->size() != q->size())
+ markWindowAsDirty();
+ }
+
void beginPaint(const QRegion &region) override
{
Q_Q(QRasterWindow);
const QSize size = q->size();
- if (backingstore->size() != size) {
+ if (backingstore->size() != size)
backingstore->resize(size);
- markWindowAsDirty();
- }
+
backingstore->beginPaint(region);
}
@@ -102,6 +108,10 @@ QPaintDevice *QRasterWindow::redirected(QPoint *) const
return d->backingstore->paintDevice();
}
+void QRasterWindow::resizeEvent(QResizeEvent *)
+{
+}
+
QT_END_NAMESPACE
#include "moc_qrasterwindow.cpp"
diff --git a/src/gui/kernel/qrasterwindow.h b/src/gui/kernel/qrasterwindow.h
index 05d71e1655..986bf6b511 100644
--- a/src/gui/kernel/qrasterwindow.h
+++ b/src/gui/kernel/qrasterwindow.h
@@ -23,6 +23,7 @@ public:
protected:
int metric(PaintDeviceMetric metric) const override;
QPaintDevice *redirected(QPoint *) const override;
+ void resizeEvent(QResizeEvent *event) override;
private:
Q_DISABLE_COPY(QRasterWindow)
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 3932567eae..83641e7676 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -37,29 +37,23 @@ QT_BEGIN_NAMESPACE
\inmodule QtGui
*/
-QScreen::QScreen(QPlatformScreen *screen)
+QScreen::QScreen(QPlatformScreen *platformScreen)
: QObject(*new QScreenPrivate(), nullptr)
{
Q_D(QScreen);
- d->setPlatformScreen(screen);
-}
-
-void QScreenPrivate::setPlatformScreen(QPlatformScreen *screen)
-{
- Q_Q(QScreen);
- platformScreen = screen;
- platformScreen->d_func()->screen = q;
- orientation = platformScreen->orientation();
- logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
+ d->platformScreen = platformScreen;
+ platformScreen->d_func()->screen = this;
- refreshRate = platformScreen->refreshRate();
+ d->orientation = platformScreen->orientation();
+ d->logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
+ d->refreshRate = platformScreen->refreshRate();
// safeguard ourselves against buggy platform behavior...
- if (refreshRate < 1.0)
- refreshRate = 60.0;
+ if (d->refreshRate < 1.0)
+ d->refreshRate = 60.0;
- updateGeometry();
- updatePrimaryOrientation(); // derived from the geometry
+ d->updateGeometry();
+ d->updatePrimaryOrientation(); // derived from the geometry
}
void QScreenPrivate::updateGeometry()
@@ -72,45 +66,13 @@ void QScreenPrivate::updateGeometry()
/*!
Destroys the screen.
+
+ \internal
*/
QScreen::~QScreen()
{
- // Remove screen
- const bool wasPrimary = QGuiApplication::primaryScreen() == this;
- QGuiApplicationPrivate::screen_list.removeOne(this);
- QGuiApplicationPrivate::resetCachedDevicePixelRatio();
-
- if (!qGuiApp)
- return;
-
- QScreen *newPrimaryScreen = QGuiApplication::primaryScreen();
- if (wasPrimary && newPrimaryScreen)
- emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
-
- // Allow clients to manage windows that are affected by the screen going
- // away, before we fall back to moving them to the primary screen.
- emit qApp->screenRemoved(this);
-
- if (QGuiApplication::closingDown())
- return;
-
- bool movingFromVirtualSibling = newPrimaryScreen
- && newPrimaryScreen->handle()->virtualSiblings().contains(handle());
-
- // Move any leftover windows to the primary screen
- const auto allWindows = QGuiApplication::allWindows();
- for (QWindow *window : allWindows) {
- if (!window->isTopLevel() || window->screen() != this)
- continue;
-
- const bool wasVisible = window->isVisible();
- window->setScreen(newPrimaryScreen);
-
- // Re-show window if moved from a virtual sibling screen. Otherwise
- // leave it up to the application developer to show the window.
- if (movingFromVirtualSibling)
- window->setVisible(wasVisible);
- }
+ Q_ASSERT_X(!QGuiApplicationPrivate::screen_list.contains(this), "QScreen",
+ "QScreens should be removed via QWindowSystemInterface::handleScreenRemoved()");
}
/*!
@@ -398,8 +360,11 @@ QList<QScreen *> QScreen::virtualSiblings() const
const QList<QPlatformScreen *> platformScreens = d->platformScreen->virtualSiblings();
QList<QScreen *> screens;
screens.reserve(platformScreens.size());
- for (QPlatformScreen *platformScreen : platformScreens)
- screens << platformScreen->screen();
+ for (QPlatformScreen *platformScreen : platformScreens) {
+ // Only consider platform screens that have been added
+ if (auto *knownScreen = platformScreen->screen())
+ screens << knownScreen;
+ }
return screens;
}
@@ -496,8 +461,8 @@ Qt::ScreenOrientation QScreen::orientation() const
\property QScreen::refreshRate
\brief the approximate vertical refresh rate of the screen in Hz
- \warning Avoid using the screen's refresh rate to drive animations
- via a timer such as QTimer. Instead use QWindow::requestUpdate().
+ \warning Avoid using the screen's refresh rate to drive animations via a
+ timer such as QChronoTimer. Instead use QWindow::requestUpdate().
\sa QWindow::requestUpdate()
*/
@@ -738,8 +703,23 @@ QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height)
result.setDevicePixelRatio(result.devicePixelRatio() * factor);
return result;
}
+
+/*!
+ \fn template <typename QNativeInterface> QNativeInterface *QScreen::nativeInterface() const
+
+ Returns a native interface of the given type for the screen.
+
+ This function provides access to platform specific functionality
+ of QScreen, as defined in the QNativeInterface namespace:
+
+ \annotatedlist native-interfaces-qscreen
+
+ If the requested interface is not available a \nullptr is returned.
+ */
+
void *QScreen::resolveInterface(const char *name, int revision) const
{
+ using namespace QNativeInterface;
using namespace QNativeInterface::Private;
auto *platformScreen = handle();
@@ -767,7 +747,7 @@ void *QScreen::resolveInterface(const char *name, int revision) const
QT_NATIVE_INTERFACE_RETURN_IF(QAndroidScreen, platformScreen);
#endif
-#if defined(Q_OS_UNIX)
+#if QT_CONFIG(wayland)
QT_NATIVE_INTERFACE_RETURN_IF(QWaylandScreen, platformScreen);
#endif
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index d2fc74fbda..9442e7525b 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -147,5 +147,7 @@ Q_GUI_EXPORT QDebug operator<<(QDebug, const QScreen *);
QT_END_NAMESPACE
+#include <QtGui/qscreen_platform.h>
+
#endif // QSCREEN_H
diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h
index b9e726a9dc..964bc1cc58 100644
--- a/src/gui/kernel/qscreen_p.h
+++ b/src/gui/kernel/qscreen_p.h
@@ -40,7 +40,6 @@ class QScreenPrivate : public QObjectPrivate, public QScreenData
{
Q_DECLARE_PUBLIC(QScreen)
public:
- void setPlatformScreen(QPlatformScreen *screen);
void updateGeometry();
void updatePrimaryOrientation();
diff --git a/src/gui/kernel/qscreen_platform.h b/src/gui/kernel/qscreen_platform.h
new file mode 100644
index 0000000000..6f40e9273f
--- /dev/null
+++ b/src/gui/kernel/qscreen_platform.h
@@ -0,0 +1,61 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QSCREEN_PLATFORM_H
+#define QSCREEN_PLATFORM_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is part of the native interface APIs. Usage of
+// this API may make your code source and binary incompatible
+// with future versions of Qt.
+//
+
+#include <QtGui/qtguiglobal.h>
+
+#include <QtCore/qnativeinterface.h>
+#include <QtGui/qguiapplication.h>
+
+#if defined(Q_OS_WIN32)
+#include <QtGui/qwindowdefs_win.h>
+#endif
+
+#if QT_CONFIG(wayland)
+struct wl_output;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace QNativeInterface {
+
+#if defined(Q_OS_WIN32) || defined(Q_QDOC)
+struct Q_GUI_EXPORT QWindowsScreen
+{
+ QT_DECLARE_NATIVE_INTERFACE(QWindowsScreen, 1, QScreen)
+ virtual HMONITOR handle() const = 0;
+};
+#endif
+
+#if QT_CONFIG(wayland) || defined(Q_QDOC)
+struct Q_GUI_EXPORT QWaylandScreen
+{
+ QT_DECLARE_NATIVE_INTERFACE(QWaylandScreen, 1, QScreen)
+ virtual wl_output *output() const = 0;
+};
+#endif
+
+#if defined(Q_OS_ANDROID) || defined(Q_QDOC)
+struct Q_GUI_EXPORT QAndroidScreen
+{
+ QT_DECLARE_NATIVE_INTERFACE(QAndroidScreen, 1, QScreen)
+ virtual int displayId() const = 0;
+};
+#endif
+
+} // namespace QNativeInterface
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/kernel/qsessionmanager.cpp b/src/gui/kernel/qsessionmanager.cpp
index 705866f903..0a1ff95656 100644
--- a/src/gui/kernel/qsessionmanager.cpp
+++ b/src/gui/kernel/qsessionmanager.cpp
@@ -281,10 +281,6 @@ void QSessionManager::setRestartCommand(const QStringList &command)
/*!
Returns the currently set restart command.
- To iterate over the list, you can use the \l foreach pseudo-keyword:
-
- \snippet code/src_gui_kernel_qguiapplication.cpp 3
-
\sa setRestartCommand(), restartHint()
*/
QStringList QSessionManager::restartCommand() const
@@ -307,10 +303,6 @@ void QSessionManager::setDiscardCommand(const QStringList &command)
/*!
Returns the currently set discard command.
- To iterate over the list, you can use the \l foreach pseudo-keyword:
-
- \snippet code/src_gui_kernel_qguiapplication.cpp 4
-
\sa setDiscardCommand(), restartCommand(), setRestartCommand()
*/
QStringList QSessionManager::discardCommand() const
diff --git a/src/gui/kernel/qsessionmanager_p.h b/src/gui/kernel/qsessionmanager_p.h
index 60e20b1747..c98f7a5a1d 100644
--- a/src/gui/kernel/qsessionmanager_p.h
+++ b/src/gui/kernel/qsessionmanager_p.h
@@ -27,7 +27,7 @@ QT_BEGIN_NAMESPACE
class QPlatformSessionManager;
-class QSessionManagerPrivate : public QObjectPrivate
+class Q_GUI_EXPORT QSessionManagerPrivate : public QObjectPrivate
{
public:
QSessionManagerPrivate(const QString &id,
diff --git a/src/gui/kernel/qshortcut.cpp b/src/gui/kernel/qshortcut.cpp
index b10d96237e..3f6822cb03 100644
--- a/src/gui/kernel/qshortcut.cpp
+++ b/src/gui/kernel/qshortcut.cpp
@@ -96,7 +96,7 @@ QT_BEGIN_NAMESPACE
\sa activated()
*/
-static bool simpleContextMatcher(QObject *object, Qt::ShortcutContext context)
+bool QShortcutPrivate::simpleContextMatcher(QObject *object, Qt::ShortcutContext context)
{
auto guiShortcut = qobject_cast<QShortcut *>(object);
if (QGuiApplication::applicationState() != Qt::ApplicationActive || guiShortcut == nullptr)
diff --git a/src/gui/kernel/qshortcut_p.h b/src/gui/kernel/qshortcut_p.h
index a99cca27c1..8ff833d477 100644
--- a/src/gui/kernel/qshortcut_p.h
+++ b/src/gui/kernel/qshortcut_p.h
@@ -43,6 +43,8 @@ public:
virtual QShortcutMap::ContextMatcher contextMatcher() const;
virtual bool handleWhatsThis() { return false; }
+ static bool simpleContextMatcher(QObject *object, Qt::ShortcutContext context);
+
QList<QKeySequence> sc_sequences;
QString sc_whatsthis;
Qt::ShortcutContext sc_context = Qt::WindowShortcut;
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index ed03f00542..800e703ac2 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -29,23 +29,23 @@ Q_LOGGING_CATEGORY(lcShortcutMap, "qt.gui.shortcutmap")
struct QShortcutEntry
{
QShortcutEntry()
- : keyseq(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(nullptr), contextMatcher(nullptr)
+ : keySequence(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(nullptr), contextMatcher(nullptr)
{}
QShortcutEntry(const QKeySequence &k)
- : keyseq(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(nullptr), contextMatcher(nullptr)
+ : keySequence(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(nullptr), contextMatcher(nullptr)
{}
QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i, bool a, QShortcutMap::ContextMatcher m)
- : keyseq(k), context(c), enabled(true), autorepeat(a), id(i), owner(o), contextMatcher(m)
+ : keySequence(k), context(c), enabled(true), autorepeat(a), id(i), owner(o), contextMatcher(m)
{}
bool correctContext() const { return contextMatcher(owner, context); }
bool operator<(const QShortcutEntry &f) const
- { return keyseq < f.keyseq; }
+ { return keySequence < f.keySequence; }
- QKeySequence keyseq;
+ QKeySequence keySequence;
Qt::ShortcutContext context;
bool enabled : 1;
bool autorepeat : 1;
@@ -88,7 +88,7 @@ public:
}
QShortcutMap *q_ptr; // Private's parent
- QList<QShortcutEntry> sequences; // All sequences!
+ QList<QShortcutEntry> shortcuts; // All shortcuts!
int currentId; // Global shortcut ID number
int ambigCount; // Index of last enabled ambiguous dispatch
@@ -120,18 +120,18 @@ QShortcutMap::~QShortcutMap()
Adds a shortcut to the global map.
Returns the id of the newly added shortcut.
*/
-int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context, ContextMatcher matcher)
+int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &keySequence, Qt::ShortcutContext context, ContextMatcher matcher)
{
Q_ASSERT_X(owner, "QShortcutMap::addShortcut", "All shortcuts need an owner");
- Q_ASSERT_X(!key.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map");
+ Q_ASSERT_X(!keySequence.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map");
Q_D(QShortcutMap);
- QShortcutEntry newEntry(owner, key, context, --(d->currentId), true, matcher);
- const auto it = std::upper_bound(d->sequences.begin(), d->sequences.end(), newEntry);
- d->sequences.insert(it, newEntry); // Insert sorted
+ QShortcutEntry newEntry(owner, keySequence, context, --(d->currentId), true, matcher);
+ const auto it = std::upper_bound(d->shortcuts.begin(), d->shortcuts.end(), newEntry);
+ d->shortcuts.insert(it, newEntry); // Insert sorted
qCDebug(lcShortcutMap).nospace()
<< "QShortcutMap::addShortcut(" << owner << ", "
- << key << ", " << context << ") added shortcut with ID " << d->currentId;
+ << keySequence << ", " << context << ") added shortcut with ID " << d->currentId;
return d->currentId;
}
@@ -144,36 +144,36 @@ int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::Short
Returns the number of sequences removed from the map.
*/
-int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key)
+int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &keySequence)
{
Q_D(QShortcutMap);
int itemsRemoved = 0;
bool allOwners = (owner == nullptr);
- bool allKeys = key.isEmpty();
+ bool allKeys = keySequence.isEmpty();
bool allIds = id == 0;
auto debug = qScopeGuard([&](){
qCDebug(lcShortcutMap).nospace()
<< "QShortcutMap::removeShortcut(" << id << ", " << owner << ", "
- << key << ") removed " << itemsRemoved << " shortcuts(s)";
+ << keySequence << ") removed " << itemsRemoved << " shortcuts(s)";
});
// Special case, remove everything
if (allOwners && allKeys && allIds) {
- itemsRemoved = d->sequences.size();
- d->sequences.clear();
+ itemsRemoved = d->shortcuts.size();
+ d->shortcuts.clear();
return itemsRemoved;
}
- int i = d->sequences.size()-1;
+ int i = d->shortcuts.size()-1;
while (i>=0)
{
- const QShortcutEntry &entry = d->sequences.at(i);
+ const QShortcutEntry &entry = d->shortcuts.at(i);
int entryId = entry.id;
if ((allOwners || entry.owner == owner)
&& (allIds || entry.id == id)
- && (allKeys || entry.keyseq == key)) {
- d->sequences.removeAt(i);
+ && (allKeys || entry.keySequence == keySequence)) {
+ d->shortcuts.removeAt(i);
++itemsRemoved;
}
if (id == entryId)
@@ -191,22 +191,22 @@ int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key
are changed.
Returns the number of sequences which are matched in the map.
*/
-int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key)
+int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &keySequence)
{
Q_D(QShortcutMap);
int itemsChanged = 0;
bool allOwners = (owner == nullptr);
- bool allKeys = key.isEmpty();
+ bool allKeys = keySequence.isEmpty();
bool allIds = id == 0;
- int i = d->sequences.size()-1;
+ int i = d->shortcuts.size()-1;
while (i>=0)
{
- QShortcutEntry entry = d->sequences.at(i);
+ QShortcutEntry entry = d->shortcuts.at(i);
if ((allOwners || entry.owner == owner)
&& (allIds || entry.id == id)
- && (allKeys || entry.keyseq == key)) {
- d->sequences[i].enabled = enable;
+ && (allKeys || entry.keySequence == keySequence)) {
+ d->shortcuts[i].enabled = enable;
++itemsChanged;
}
if (id == entry.id)
@@ -215,7 +215,7 @@ int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const
}
qCDebug(lcShortcutMap).nospace()
<< "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", "
- << owner << ", " << key << ") = " << itemsChanged;
+ << owner << ", " << keySequence << ") = " << itemsChanged;
return itemsChanged;
}
@@ -227,22 +227,22 @@ int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const
are changed.
Returns the number of sequences which are matched in the map.
*/
-int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key)
+int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &keySequence)
{
Q_D(QShortcutMap);
int itemsChanged = 0;
bool allOwners = (owner == nullptr);
- bool allKeys = key.isEmpty();
+ bool allKeys = keySequence.isEmpty();
bool allIds = id == 0;
- int i = d->sequences.size()-1;
+ int i = d->shortcuts.size()-1;
while (i>=0)
{
- QShortcutEntry entry = d->sequences.at(i);
+ QShortcutEntry entry = d->shortcuts.at(i);
if ((allOwners || entry.owner == owner)
&& (allIds || entry.id == id)
- && (allKeys || entry.keyseq == key)) {
- d->sequences[i].autorepeat = on;
+ && (allKeys || entry.keySequence == keySequence)) {
+ d->shortcuts[i].autorepeat = on;
++itemsChanged;
}
if (id == entry.id)
@@ -251,7 +251,7 @@ int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const Q
}
qCDebug(lcShortcutMap).nospace()
<< "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", "
- << owner << ", " << key << ") = " << itemsChanged;
+ << owner << ", " << keySequence << ") = " << itemsChanged;
return itemsChanged;
}
@@ -365,11 +365,12 @@ bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const
{
Q_D(const QShortcutMap);
QShortcutEntry entry(seq); // needed for searching
- const auto itEnd = d->sequences.cend();
- auto it = std::lower_bound(d->sequences.cbegin(), itEnd, entry);
+ const auto itEnd = d->shortcuts.cend();
+ auto it = std::lower_bound(d->shortcuts.cbegin(), itEnd, entry);
for (;it != itEnd; ++it) {
- if (matches(entry.keyseq, (*it).keyseq) == QKeySequence::ExactMatch && (*it).correctContext() && (*it).enabled) {
+ if (entry.keySequence.matches(it->keySequence) == QKeySequence::ExactMatch
+ && (*it).correctContext() && (*it).enabled) {
return true;
}
}
@@ -388,11 +389,11 @@ bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const
QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifiers)
{
Q_D(QShortcutMap);
- if (!d->sequences.size())
+ if (!d->shortcuts.size())
return QKeySequence::NoMatch;
createNewSequences(e, d->newEntries, ignoredModifiers);
- qCDebug(lcShortcutMap) << "Possible shortcut key sequences:" << d->newEntries;
+ qCDebug(lcShortcutMap) << "Possible input sequences:" << d->newEntries;
// Should never happen
if (d->newEntries == d->currentSequences) {
@@ -407,26 +408,33 @@ QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifier
bool partialFound = false;
bool identicalDisabledFound = false;
QList<QKeySequence> okEntries;
- int result = QKeySequence::NoMatch;
+ QKeySequence::SequenceMatch result = QKeySequence::NoMatch;
for (int i = d->newEntries.size()-1; i >= 0 ; --i) {
QShortcutEntry entry(d->newEntries.at(i)); // needed for searching
- const auto itEnd = d->sequences.constEnd();
- auto it = std::lower_bound(d->sequences.constBegin(), itEnd, entry);
+ qCDebug(lcShortcutMap) << "Looking for shortcuts matching" << entry.keySequence;
+
+ QKeySequence::SequenceMatch bestMatchForEntry = QKeySequence::NoMatch;
+
+ const auto itEnd = d->shortcuts.constEnd();
+ auto it = std::lower_bound(d->shortcuts.constBegin(), itEnd, entry);
+ for (; it != itEnd; ++it) {
+ QKeySequence::SequenceMatch match = entry.keySequence.matches(it->keySequence);
+ qCDebug(lcShortcutMap) << " -" << match << "for shortcut" << it->keySequence;
- int oneKSResult = QKeySequence::NoMatch;
- int tempRes = QKeySequence::NoMatch;
- do {
- if (it == itEnd)
+ // If we got a valid match, there might still be more keys to check against,
+ // but if we get no match, we know that there are no more possible matches.
+ if (match == QKeySequence::NoMatch)
break;
- tempRes = matches(entry.keyseq, (*it).keyseq);
- oneKSResult = qMax(oneKSResult, tempRes);
- if (tempRes != QKeySequence::NoMatch && (*it).correctContext()) {
- if (tempRes == QKeySequence::ExactMatch) {
+
+ bestMatchForEntry = qMax(bestMatchForEntry, match);
+
+ if ((*it).correctContext()) {
+ if (match == QKeySequence::ExactMatch) {
if ((*it).enabled)
d->identicals.append(&*it);
else
identicalDisabledFound = true;
- } else if (tempRes == QKeySequence::PartialMatch) {
+ } else if (match == QKeySequence::PartialMatch) {
// We don't need partials, if we have identicals
if (d->identicals.size())
break;
@@ -434,20 +442,18 @@ QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifier
// key events when all partials are disabled!
partialFound |= (*it).enabled;
}
+ } else {
+ qCDebug(lcShortcutMap) << " - But context was not correct";
}
- ++it;
- // If we got a valid match on this run, there might still be more keys to check against,
- // so we'll loop once more. If we get NoMatch, there's guaranteed no more possible
- // matches in the shortcutmap.
- } while (tempRes != QKeySequence::NoMatch);
+ }
// If the type of match improves (ergo, NoMatch->Partial, or Partial->Exact), clear the
// previous list. If this match is equal or better than the last match, append to the list
- if (oneKSResult > result) {
+ if (bestMatchForEntry > result) {
okEntries.clear();
qCDebug(lcShortcutMap) << "Found better match (" << d->newEntries << "), clearing key sequence list";
}
- if (oneKSResult && oneKSResult >= result) {
+ if (bestMatchForEntry && bestMatchForEntry >= result) {
okEntries << d->newEntries.at(i);
qCDebug(lcShortcutMap) << "Added ok key sequence" << d->newEntries;
}
@@ -466,7 +472,7 @@ QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifier
if (result != QKeySequence::NoMatch)
d->currentSequences = okEntries;
qCDebug(lcShortcutMap) << "Returning shortcut match == " << result;
- return QKeySequence::SequenceMatch(result);
+ return result;
}
/*! \internal
@@ -487,7 +493,7 @@ void QShortcutMap::clearSequence(QList<QKeySequence> &ksl)
void QShortcutMap::createNewSequences(QKeyEvent *e, QList<QKeySequence> &ksl, int ignoredModifiers)
{
Q_D(QShortcutMap);
- QList<int> possibleKeys = QKeyMapper::possibleKeys(e);
+ QList<QKeyCombination> possibleKeys = QKeyMapper::possibleKeys(e);
qCDebug(lcShortcutMap) << "Creating new sequences for" << e
<< "with ignoredModifiers=" << Qt::KeyboardModifiers(ignoredModifiers);
int pkTotal = possibleKeys.size();
@@ -516,46 +522,13 @@ void QShortcutMap::createNewSequences(QKeyEvent *e, QList<QKeySequence> &ksl, in
curKsl.setKey(QKeyCombination::fromCombined(0), 2);
curKsl.setKey(QKeyCombination::fromCombined(0), 3);
}
- curKsl.setKey(QKeyCombination::fromCombined(possibleKeys.at(pkNum) & ~ignoredModifiers), index);
+ const int key = possibleKeys.at(pkNum).toCombined();
+ curKsl.setKey(QKeyCombination::fromCombined(key & ~ignoredModifiers), index);
}
}
}
/*! \internal
- Basically the same function as QKeySequence::matches(const QKeySequence &seq) const
- only that is specially handles Key_hyphen as Key_Minus, as people mix these up all the time and
- they conceptually the same.
-*/
-QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1,
- const QKeySequence &seq2) const
-{
- uint userN = seq1.count(),
- seqN = seq2.count();
-
- if (userN > seqN)
- return QKeySequence::NoMatch;
-
- // If equal in length, we have a potential ExactMatch sequence,
- // else we already know it can only be partial.
- QKeySequence::SequenceMatch match = (userN == seqN
- ? QKeySequence::ExactMatch
- : QKeySequence::PartialMatch);
-
- for (uint i = 0; i < userN; ++i) {
- int userKey = seq1[i].toCombined(),
- sequenceKey = seq2[i].toCombined();
- if ((userKey & Qt::Key_unknown) == Qt::Key_hyphen)
- userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
- if ((sequenceKey & Qt::Key_unknown) == Qt::Key_hyphen)
- sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
- if (userKey != sequenceKey)
- return QKeySequence::NoMatch;
- }
- return match;
-}
-
-
-/*! \internal
Converts keyboard button states into modifier states
*/
int QShortcutMap::translateModifiers(Qt::KeyboardModifiers modifiers)
@@ -590,7 +563,7 @@ void QShortcutMap::dispatchEvent(QKeyEvent *e)
if (!d->identicals.size())
return;
- const QKeySequence &curKey = d->identicals.at(0)->keyseq;
+ const QKeySequence &curKey = d->identicals.at(0)->keySequence;
if (d->prevSequence != curKey) {
d->ambigCount = 0;
d->prevSequence = curKey;
@@ -621,15 +594,15 @@ void QShortcutMap::dispatchEvent(QKeyEvent *e)
if (ambiguousShortcuts.size() > 1) {
qCDebug(lcShortcutMap) << "The following shortcuts are about to be activated ambiguously:";
for (const QShortcutEntry *entry : std::as_const(ambiguousShortcuts))
- qCDebug(lcShortcutMap).nospace() << "- " << entry->keyseq << " (belonging to " << entry->owner << ")";
+ qCDebug(lcShortcutMap).nospace() << "- " << entry->keySequence << " (belonging to " << entry->owner << ")";
}
qCDebug(lcShortcutMap).nospace()
<< "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\""
- << next->keyseq.toString() << "\", " << next->id << ", "
+ << next->keySequence.toString() << "\", " << next->id << ", "
<< static_cast<bool>(enabledShortcuts>1) << ") to object(" << next->owner << ')';
}
- QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1);
+ QShortcutEvent se(next->keySequence, next->id, enabledShortcuts > 1);
QCoreApplication::sendEvent(const_cast<QObject *>(next->owner), &se);
}
@@ -637,7 +610,7 @@ QList<QKeySequence> QShortcutMap::keySequences(bool getAll) const
{
Q_D(const QShortcutMap);
QList<QKeySequence> keys;
- for (auto sequence : d->sequences) {
+ for (auto sequence : d->shortcuts) {
bool addSequence = false;
if (sequence.enabled) {
if (getAll || sequence.context == Qt::ApplicationShortcut ||
@@ -666,7 +639,7 @@ QList<QKeySequence> QShortcutMap::keySequences(bool getAll) const
}
}
if (addSequence)
- keys << sequence.keyseq;
+ keys << sequence.keySequence;
}
}
return keys;
@@ -681,8 +654,8 @@ QList<QKeySequence> QShortcutMap::keySequences(bool getAll) const
void QShortcutMap::dumpMap() const
{
Q_D(const QShortcutMap);
- for (int i = 0; i < d->sequences.size(); ++i)
- qDebug().nospace() << &(d->sequences.at(i));
+ for (int i = 0; i < d->shortcuts.size(); ++i)
+ qDebug().nospace() << &(d->shortcuts.at(i));
}
#endif
diff --git a/src/gui/kernel/qshortcutmap_p.h b/src/gui/kernel/qshortcutmap_p.h
index 194738f0ac..26d2b5301c 100644
--- a/src/gui/kernel/qshortcutmap_p.h
+++ b/src/gui/kernel/qshortcutmap_p.h
@@ -62,7 +62,6 @@ private:
void dispatchEvent(QKeyEvent *e);
QKeySequence::SequenceMatch find(QKeyEvent *e, int ignoredModifiers = 0);
- QKeySequence::SequenceMatch matches(const QKeySequence &seq1, const QKeySequence &seq2) const;
QList<const QShortcutEntry *> matches() const;
void createNewSequences(QKeyEvent *e, QList<QKeySequence> &ksl, int ignoredModifiers);
void clearSequence(QList<QKeySequence> &ksl);
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index 77cbfd2b96..a90e8dd33c 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -34,9 +34,10 @@ Q_LOGGING_CATEGORY(lcDnd, "qt.gui.dnd")
static QWindow* topLevelAt(const QPoint &pos)
{
- QWindowList list = QGuiApplication::topLevelWindows();
- for (int i = list.size()-1; i >= 0; --i) {
- QWindow *w = list.at(i);
+ const QWindowList list = QGuiApplication::topLevelWindows();
+ const auto crend = list.crend();
+ for (auto it = list.crbegin(); it != crend; ++it) {
+ QWindow *w = *it;
if (w->isVisible() && w->handle() && w->geometry().contains(pos) && !qobject_cast<QShapedPixmapWindow*>(w))
return w;
}
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 5080bd7add..5029701f24 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -122,15 +122,15 @@ int QStyleHints::touchDoubleTapDistance() const
}
/*!
- \property QStyleHints::appearance
- \brief the appearance of the platform theme
- \sa Qt::Appearance
+ \property QStyleHints::colorScheme
+ \brief the color scheme of the platform theme.
+ \sa Qt::ColorScheme
\since 6.5
*/
-Qt::Appearance QStyleHints::appearance() const
+Qt::ColorScheme QStyleHints::colorScheme() const
{
Q_D(const QStyleHints);
- return d->appearance();
+ return d->colorScheme();
}
/*!
@@ -294,6 +294,7 @@ int QStyleHints::keyboardAutoRepeatRate() const
/*!
\property QStyleHints::keyboardAutoRepeatRateF
+ \since 6.5
\brief the rate, in events per second, in which additional repeated key
presses will automatically be generated if a key is being held down.
*/
@@ -594,17 +595,21 @@ int QStyleHints::mouseQuickSelectionThreshold() const
/*!
\internal
- QStyleHintsPrivate::setAppearance - set a new appearance.
- Set \a appearance as the new appearance of the QStyleHints.
- The appearanceChanged signal will be emitted if present and new appearance differ.
+ QStyleHintsPrivate::updateColorScheme - set a new color scheme.
+
+ This function is called by the QPA plugin when the system theme changes. This in
+ turn might be the result of an explicit request of a color scheme via setColorScheme.
+
+ Set \a colorScheme as the new color scheme of the QStyleHints.
+ The colorSchemeChanged signal will be emitted if present and new color scheme differ.
*/
-void QStyleHintsPrivate::setAppearance(Qt::Appearance appearance)
+void QStyleHintsPrivate::updateColorScheme(Qt::ColorScheme colorScheme)
{
- if (m_appearance == appearance)
+ if (m_colorScheme == colorScheme)
return;
- m_appearance = appearance;
+ m_colorScheme = colorScheme;
Q_Q(QStyleHints);
- emit q->appearanceChanged(appearance);
+ emit q->colorSchemeChanged(colorScheme);
}
QStyleHintsPrivate *QStyleHintsPrivate::get(QStyleHints *q)
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index 779bed67d8..969bec4b35 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -52,7 +52,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject
Q_PROPERTY(int mouseDoubleClickDistance READ mouseDoubleClickDistance STORED false CONSTANT
FINAL)
Q_PROPERTY(int touchDoubleTapDistance READ touchDoubleTapDistance STORED false CONSTANT FINAL)
- Q_PROPERTY(Qt::Appearance appearance READ appearance NOTIFY appearanceChanged FINAL)
+ Q_PROPERTY(Qt::ColorScheme colorScheme READ colorScheme NOTIFY colorSchemeChanged FINAL)
public:
void setMouseDoubleClickInterval(int mouseDoubleClickInterval);
@@ -93,7 +93,7 @@ public:
void setWheelScrollLines(int scrollLines);
void setMouseQuickSelectionThreshold(int threshold);
int mouseQuickSelectionThreshold() const;
- Qt::Appearance appearance() const;
+ Qt::ColorScheme colorScheme() const;
Q_SIGNALS:
void cursorFlashTimeChanged(int cursorFlashTime);
@@ -107,7 +107,7 @@ Q_SIGNALS:
void showShortcutsInContextMenusChanged(bool);
void wheelScrollLinesChanged(int scrollLines);
void mouseQuickSelectionThresholdChanged(int threshold);
- void appearanceChanged(Qt::Appearance appearance);
+ void colorSchemeChanged(Qt::ColorScheme colorScheme);
private:
friend class QGuiApplication;
diff --git a/src/gui/kernel/qstylehints_p.h b/src/gui/kernel/qstylehints_p.h
index a93a410987..2b3979512a 100644
--- a/src/gui/kernel/qstylehints_p.h
+++ b/src/gui/kernel/qstylehints_p.h
@@ -40,13 +40,13 @@ public:
int m_mouseDoubleClickDistance = -1;
int m_touchDoubleTapDistance = -1;
- Qt::Appearance appearance() const { return m_appearance; }
- void setAppearance(Qt::Appearance appearance);
+ Qt::ColorScheme colorScheme() const { return m_colorScheme; }
+ void updateColorScheme(Qt::ColorScheme colorScheme);
static QStyleHintsPrivate *get(QStyleHints *q);
private:
- Qt::Appearance m_appearance = Qt::Appearance::Unknown;
+ Qt::ColorScheme m_colorScheme = Qt::ColorScheme::Unknown;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp
index b8083641c2..c00cf55a09 100644
--- a/src/gui/kernel/qsurface.cpp
+++ b/src/gui/kernel/qsurface.cpp
@@ -30,13 +30,12 @@ QT_IMPL_METATYPE_EXTERN_TAGGED(QSurface*, QSurface_ptr)
\value Offscreen The surface is an instance of QOffscreenSurface.
*/
-
/*!
\enum QSurface::SurfaceType
The SurfaceType enum describes what type of surface this is.
- \value RasterSurface The surface is is composed of pixels and can be rendered to using
+ \value RasterSurface The surface is composed of pixels and can be rendered to using
a software rasterizer like Qt's raster paint engine.
\value OpenGLSurface The surface is an OpenGL compatible surface and can be used
in conjunction with QOpenGLContext.
@@ -55,7 +54,6 @@ QT_IMPL_METATYPE_EXTERN_TAGGED(QSurface*, QSurface_ptr)
surface type is only supported on Windows.
*/
-
/*!
\fn QSurfaceFormat QSurface::format() const
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index cc2bbea551..74add6e973 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -765,7 +765,7 @@ Q_GLOBAL_STATIC(QSurfaceFormat, qt_default_surface_format)
question's own setFormat() function. However, it is often more convenient to
set the format for all windows once at the start of the application. It also
guarantees proper behavior in cases where shared contexts are required,
- because settings the format via this function guarantees that all contexts
+ because setting the format via this function guarantees that all contexts
and surfaces, even the ones created internally by Qt, will use the same
format.
diff --git a/src/gui/kernel/qtestsupport_gui.cpp b/src/gui/kernel/qtestsupport_gui.cpp
index 47c69f8b74..869eddce49 100644
--- a/src/gui/kernel/qtestsupport_gui.cpp
+++ b/src/gui/kernel/qtestsupport_gui.cpp
@@ -29,7 +29,7 @@ QT_BEGIN_NAMESPACE
\note Since focus is an exclusive property, \a window may loose its focus to another window at
any time - even after the method has returned \c true.
- \sa qWaitForWindowExposed(), QWindow::isActive()
+ \sa qWaitForWindowExposed(), qWaitForWindowFocused(), QWindow::isActive()
*/
Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
{
@@ -45,6 +45,27 @@ Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
}
/*!
+ \since 6.7
+
+ Returns \c true, if \a window is the focus window within \a timeout. Otherwise returns \c false.
+
+ The method is useful in tests that call QWindow::show() and rely on the window
+ having focus (for receiving keyboard events e.g.) before proceeding.
+
+ \note The method will time out and return \c false if another window prevents \a window from
+ becoming focused.
+
+ \note Since focus is an exclusive property, \a window may loose its focus to another window at
+ any time - even after the method has returned \c true.
+
+ \sa qWaitForWindowExposed(), qWaitForWindowActive(), QGuiApplication::focusWindow()
+*/
+Q_GUI_EXPORT bool QTest::qWaitForWindowFocused(QWindow *window, QDeadlineTimer timeout)
+{
+ return QTest::qWaitFor([&]() { return qGuiApp->focusWindow() == window; }, timeout);
+}
+
+/*!
\since 5.0
Returns \c true, if \a window is exposed within \a timeout milliseconds. Otherwise returns \c false.
@@ -102,7 +123,7 @@ bool QTouchEventSequence::commit(bool processEvents)
{
if (points.isEmpty())
return false;
- QThread::msleep(1);
+ QThread::sleep(std::chrono::milliseconds{1});
bool ret = false;
if (targetWindow)
ret = qt_handleTouchEventv2(targetWindow, device, points.values());
diff --git a/src/gui/kernel/qtestsupport_gui.h b/src/gui/kernel/qtestsupport_gui.h
index e93fd52018..e5b2a88455 100644
--- a/src/gui/kernel/qtestsupport_gui.h
+++ b/src/gui/kernel/qtestsupport_gui.h
@@ -23,6 +23,7 @@ Q_GUI_EXPORT bool qt_handleTouchEventv2(QWindow *w, const QPointingDevice *devic
namespace QTest {
[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowActive(QWindow *window, int timeout = 5000);
+[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowFocused(QWindow *widget, QDeadlineTimer timeout = std::chrono::seconds{5});
[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowExposed(QWindow *window, int timeout = 5000);
Q_GUI_EXPORT QPointingDevice * createTouchDevice(QInputDevice::DeviceType devType = QInputDevice::DeviceType::TouchScreen,
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 1e368914f3..b40fd7e8e8 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -128,7 +128,7 @@ QWindow::QWindow(QScreen *targetScreen)
, QSurface(QSurface::Window)
{
Q_D(QWindow);
- d->init(targetScreen);
+ d->init(nullptr, targetScreen);
}
static QWindow *nonDesktopParent(QWindow *parent)
@@ -169,11 +169,11 @@ QWindow::QWindow(QWindow *parent)
\sa setParent()
*/
QWindow::QWindow(QWindowPrivate &dd, QWindow *parent)
- : QObject(dd, nonDesktopParent(parent))
+ : QObject(dd, nullptr)
, QSurface(QSurface::Window)
{
Q_D(QWindow);
- d->init();
+ d->init(nonDesktopParent(parent));
}
/*!
@@ -183,6 +183,8 @@ QWindow::~QWindow()
{
Q_D(QWindow);
d->destroy();
+ // Decouple from parent before window goes under
+ setParent(nullptr);
QGuiApplicationPrivate::window_list.removeAll(this);
if (!QGuiApplicationPrivate::is_app_closing)
QGuiApplicationPrivate::instance()->modalWindowList.removeOne(this);
@@ -206,15 +208,19 @@ QWindowPrivate::QWindowPrivate()
QWindowPrivate::~QWindowPrivate()
= default;
-void QWindowPrivate::init(QScreen *targetScreen)
+void QWindowPrivate::init(QWindow *parent, QScreen *targetScreen)
{
Q_Q(QWindow);
+ q->QObject::setParent(parent);
+
isWindow = true;
parentWindow = static_cast<QWindow *>(q->QObject::parent());
+ QScreen *connectScreen = targetScreen ? targetScreen : QGuiApplication::primaryScreen();
+
if (!parentWindow)
- connectToScreen(targetScreen ? targetScreen : QGuiApplication::primaryScreen());
+ connectToScreen(connectScreen);
// If your application aborts here, you are probably creating a QWindow
// before the screen list is populated.
@@ -224,6 +230,27 @@ void QWindowPrivate::init(QScreen *targetScreen)
QGuiApplicationPrivate::window_list.prepend(q);
requestedFormat = QSurfaceFormat::defaultFormat();
+ devicePixelRatio = connectScreen->devicePixelRatio();
+
+ QObject::connect(q, &QWindow::screenChanged, q, [q, this](QScreen *){
+ // We may have changed scaling; trigger resize event if needed,
+ // except on Windows, where we send resize events during WM_DPICHANGED
+ // event handling. FIXME: unify DPI change handling across all platforms.
+#ifndef Q_OS_WIN
+ if (q->handle()) {
+ QWindowSystemInterfacePrivate::GeometryChangeEvent gce(q, QHighDpi::fromNativePixels(q->handle()->geometry(), q));
+ QGuiApplicationPrivate::processGeometryChangeEvent(&gce);
+ }
+#else
+ Q_UNUSED(q);
+#endif
+ updateDevicePixelRatio();
+ });
+
+ if (parentWindow) {
+ QChildWindowEvent childAddedEvent(QEvent::ChildWindowAdded, q);
+ QCoreApplication::sendEvent(parentWindow, &childAddedEvent);
+ }
}
/*!
@@ -428,14 +455,14 @@ void QWindowPrivate::updateSiblingPosition(SiblingPosition position)
QObjectList &siblings = q->parent()->d_ptr->children;
- const int siblingCount = siblings.size() - 1;
+ const qsizetype siblingCount = siblings.size() - 1;
if (siblingCount == 0)
return;
- const int currentPosition = siblings.indexOf(q);
+ const qsizetype currentPosition = siblings.indexOf(q);
Q_ASSERT(currentPosition >= 0);
- const int targetPosition = position == PositionTop ? siblingCount : 0;
+ const qsizetype targetPosition = position == PositionTop ? siblingCount : 0;
if (currentPosition == targetPosition)
return;
@@ -494,7 +521,9 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
}
}
-void QWindowPrivate::create(bool recursive, WId nativeHandle)
+static constexpr auto kForeignWindowId = "_q_foreignWinId";
+
+void QWindowPrivate::create(bool recursive)
{
Q_Q(QWindow);
if (platformWindow)
@@ -508,6 +537,13 @@ void QWindowPrivate::create(bool recursive, WId nativeHandle)
if (q->parent())
q->parent()->create();
+ if (platformWindow) {
+ // Creating the parent window will end up creating any child window
+ // that was already visible, via setVisible. If this applies to us,
+ // we will already have a platform window at this point.
+ return;
+ }
+
// QPlatformWindow will poll geometry() during construction below. Set the
// screen here so that high-dpi scaling will use the correct scale factor.
if (q->isTopLevel()) {
@@ -515,6 +551,8 @@ void QWindowPrivate::create(bool recursive, WId nativeHandle)
setTopLevelScreen(screen, false);
}
+ const WId nativeHandle = q->property(kForeignWindowId).value<WId>();
+
QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
platformWindow = nativeHandle ? platformIntegration->createForeignWindow(q, nativeHandle)
: platformIntegration->createPlatformWindow(q);
@@ -550,6 +588,8 @@ void QWindowPrivate::create(bool recursive, WId nativeHandle)
QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
QGuiApplication::sendEvent(q, &e);
+ updateDevicePixelRatio();
+
if (needsUpdate)
q->requestUpdate();
}
@@ -592,7 +632,9 @@ void QWindowPrivate::setMinOrMaxSize(QSize *oldSizeMember, const QSize &size,
// resize window if current size is outside of min and max limits
if (minimumSize.width() <= maximumSize.width()
|| minimumSize.height() <= maximumSize.height()) {
- q->resize(q->geometry().size().expandedTo(minimumSize).boundedTo(maximumSize));
+ const QSize currentSize = q->size();
+ const QSize boundedSize = currentSize.expandedTo(minimumSize).boundedTo(maximumSize);
+ q->resize(boundedSize);
}
}
@@ -682,6 +724,7 @@ void QWindow::create()
Returns the window's platform id.
\note This function will cause the platform window to be created if it is not already.
+ Returns 0, if the platform window creation failed.
For platforms where this id might be useful, the value returned
will uniquely represent the window inside the corresponding screen.
@@ -695,6 +738,9 @@ WId QWindow::winId() const
if (!d->platformWindow)
const_cast<QWindow *>(this)->create();
+ if (!d->platformWindow)
+ return 0;
+
return d->platformWindow->winId();
}
@@ -738,6 +784,10 @@ void QWindow::setParent(QWindow *parent)
return;
}
+ QEvent parentAboutToChangeEvent(QEvent::ParentWindowAboutToChange);
+ QCoreApplication::sendEvent(this, &parentAboutToChangeEvent);
+
+ const auto previousParent = d->parentWindow;
QObject::setParent(parent);
d->parentWindow = parent;
@@ -760,6 +810,19 @@ void QWindow::setParent(QWindow *parent)
}
QGuiApplicationPrivate::updateBlockedStatus(this);
+
+ if (previousParent) {
+ QChildWindowEvent childRemovedEvent(QEvent::ChildWindowRemoved, this);
+ QCoreApplication::sendEvent(previousParent, &childRemovedEvent);
+ }
+
+ if (parent) {
+ QChildWindowEvent childAddedEvent(QEvent::ChildWindowAdded, this);
+ QCoreApplication::sendEvent(parent, &childAddedEvent);
+ }
+
+ QEvent parentChangedEvent(QEvent::ParentWindowChange);
+ QCoreApplication::sendEvent(this, &parentChangedEvent);
}
/*!
@@ -1251,6 +1314,8 @@ bool QWindow::isExposed() const
Typically active windows should appear active from a style perspective.
To get the window that currently has focus, use QGuiApplication::focusWindow().
+
+ \sa requestActivate()
*/
bool QWindow::isActive() const
{
@@ -1324,14 +1389,31 @@ Qt::ScreenOrientation QWindow::contentOrientation() const
qreal QWindow::devicePixelRatio() const
{
Q_D(const QWindow);
+ return d->devicePixelRatio;
+}
+
+/*
+ Updates the cached devicePixelRatio value by polling for a new value.
+ Sends QEvent::DevicePixelRatioChange to the window if the DPR has changed.
+ Returns true if the DPR was changed.
+*/
+bool QWindowPrivate::updateDevicePixelRatio()
+{
+ Q_Q(QWindow);
// If there is no platform window use the associated screen's devicePixelRatio,
// which typically is the primary screen and will be correct for single-display
// systems (a very common case).
- if (!d->platformWindow)
- return screen()->devicePixelRatio();
+ const qreal newDevicePixelRatio = platformWindow ?
+ platformWindow->devicePixelRatio() * QHighDpiScaling::factor(q) : q->screen()->devicePixelRatio();
+
+ if (newDevicePixelRatio == devicePixelRatio)
+ return false;
- return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this);
+ devicePixelRatio = newDevicePixelRatio;
+ QEvent dprChangeEvent(QEvent::DevicePixelRatioChange);
+ QGuiApplication::sendEvent(q, &dprChangeEvent);
+ return true;
}
Qt::WindowState QWindowPrivate::effectiveState(Qt::WindowStates state)
@@ -1602,20 +1684,18 @@ void QWindow::setY(int arg)
\property QWindow::width
\brief the width of the window's geometry
*/
-void QWindow::setWidth(int arg)
+void QWindow::setWidth(int w)
{
- if (width() != arg)
- resize(arg, height());
+ resize(w, height());
}
/*!
\property QWindow::height
\brief the height of the window's geometry
*/
-void QWindow::setHeight(int arg)
+void QWindow::setHeight(int h)
{
- if (height() != arg)
- resize(width(), arg);
+ resize(width(), h);
}
/*!
@@ -1875,6 +1955,10 @@ void QWindow::setFramePosition(const QPoint &point)
For interactively moving windows, see startSystemMove(). For interactively
resizing windows, see startSystemResize().
+ \note Not all windowing systems support setting or querying top level window positions.
+ On such a system, programmatically moving windows may not have any effect, and artificial
+ values may be returned for the current positions, such as \c QPoint(0, 0).
+
\sa position(), startSystemMove()
*/
void QWindow::setPosition(const QPoint &pt)
@@ -1898,6 +1982,10 @@ void QWindow::setPosition(int posx, int posy)
\fn QPoint QWindow::position() const
\brief Returns the position of the window on the desktop excluding any window frame
+ \note Not all windowing systems support setting or querying top level window positions.
+ On such a system, programmatically moving windows may not have any effect, and artificial
+ values may be returned for the current positions, such as \c QPoint(0, 0).
+
\sa setPosition()
*/
@@ -1929,12 +2017,16 @@ void QWindow::resize(int w, int h)
void QWindow::resize(const QSize &newSize)
{
Q_D(QWindow);
+
+ const QSize oldSize = size();
+ if (newSize == oldSize)
+ return;
+
d->positionPolicy = QWindowPrivate::WindowFrameExclusive;
if (d->platformWindow) {
d->platformWindow->setGeometry(
QHighDpi::toNativeWindowGeometry(QRect(position(), newSize), this));
} else {
- const QSize oldSize = d->geometry.size();
d->geometry.setSize(newSize);
if (newSize.width() != oldSize.width())
emit widthChanged(newSize.width());
@@ -1971,6 +2063,16 @@ void QWindowPrivate::destroy()
QObject *object = childrenWindows.at(i);
if (object->isWindowType()) {
QWindow *w = static_cast<QWindow*>(object);
+ auto *childPlatformWindow = w->handle();
+ if (!childPlatformWindow)
+ continue;
+
+ // Decouple the foreign window from this window,
+ // so that destroying our native handle doesn't
+ // bring down the foreign window as well.
+ if (childPlatformWindow->isForeignWindow())
+ childPlatformWindow->setParent(nullptr);
+
qt_window_private(w)->destroy();
}
}
@@ -2143,20 +2245,26 @@ QObject *QWindow::focusObject() const
/*!
Shows the window.
- This is equivalent to calling showFullScreen(), showMaximized(), or showNormal(),
+ For child windows, this is equivalent to calling showNormal().
+ Otherwise, it is equivalent to calling showFullScreen(), showMaximized(), or showNormal(),
depending on the platform's default behavior for the window type and flags.
\sa showFullScreen(), showMaximized(), showNormal(), hide(), QStyleHints::showIsFullScreen(), flags()
*/
void QWindow::show()
{
- Qt::WindowState defaultState = QGuiApplicationPrivate::platformIntegration()->defaultWindowState(d_func()->windowFlags);
- if (defaultState == Qt::WindowFullScreen)
- showFullScreen();
- else if (defaultState == Qt::WindowMaximized)
- showMaximized();
- else
+ if (parent()) {
showNormal();
+ } else {
+ const auto *platformIntegration = QGuiApplicationPrivate::platformIntegration();
+ Qt::WindowState defaultState = platformIntegration->defaultWindowState(d_func()->windowFlags);
+ if (defaultState == Qt::WindowFullScreen)
+ showFullScreen();
+ else if (defaultState == Qt::WindowMaximized)
+ showMaximized();
+ else
+ showNormal();
+ }
}
/*!
@@ -2762,7 +2870,12 @@ QPointF QWindow::mapToGlobal(const QPointF &pos) const
// Map the position (and the window's global position) to native coordinates, perform
// the addition, and then map back to device independent coordinates.
QPointF nativeLocalPos = QHighDpi::toNativeLocalPosition(pos, this);
- QPointF nativeWindowGlobalPos = QHighDpi::toNativeGlobalPosition(QPointF(d->globalPosition()), this);
+ // Get the native window position directly from the platform window
+ // if available (it can be null if the window hasn't been shown yet),
+ // or fall back to scaling the QWindow position.
+ QPointF nativeWindowGlobalPos = d->platformWindow
+ ? d->platformWindow->mapToGlobal(QPoint(0,0)).toPointF()
+ : QHighDpi::toNativeGlobalPosition(QPointF(d->globalPosition()), this);
QPointF nativeGlobalPos = nativeLocalPos + nativeWindowGlobalPos;
QPointF deviceIndependentGlobalPos = QHighDpi::fromNativeGlobalPosition(nativeGlobalPos, this);
return deviceIndependentGlobalPos;
@@ -2800,7 +2913,12 @@ QPointF QWindow::mapFromGlobal(const QPointF &pos) const
// Calculate local position in the native coordinate system. (See comment for the
// corresponding mapToGlobal() code above).
QPointF nativeGlobalPos = QHighDpi::toNativeGlobalPosition(pos, this);
- QPointF nativeWindowGlobalPos = QHighDpi::toNativeGlobalPosition(QPointF(d->globalPosition()), this);
+ // Get the native window position directly from the platform window
+ // if available (it can be null if the window hasn't been shown yet),
+ // or fall back to scaling the QWindow position.
+ QPointF nativeWindowGlobalPos = d->platformWindow
+ ? d->platformWindow->mapToGlobal(QPoint(0,0)).toPointF()
+ : QHighDpi::toNativeGlobalPosition(QPointF(d->globalPosition()), this);
QPointF nativeLocalPos = nativeGlobalPos - nativeWindowGlobalPos;
QPointF deviceIndependentLocalPos = QHighDpi::fromNativeLocalPosition(nativeLocalPos, this);
return deviceIndependentLocalPos;
@@ -2882,7 +3000,11 @@ QWindow *QWindow::fromWinId(WId id)
}
QWindow *window = new QWindow;
- qt_window_private(window)->create(false, id);
+
+ // Persist the winId in a private property so that we
+ // can recreate the window after being destroyed.
+ window->setProperty(kForeignWindowId, id);
+ window->create();
if (!window->handle()) {
delete window;
@@ -3031,10 +3153,14 @@ void *QWindow::resolveInterface(const char *name, int revision) const
QT_NATIVE_INTERFACE_RETURN_IF(QCocoaWindow, platformWindow);
#endif
-#if defined(Q_OS_UNIX)
+#if QT_CONFIG(wayland)
QT_NATIVE_INTERFACE_RETURN_IF(QWaylandWindow, platformWindow);
#endif
+#if defined(Q_OS_WASM)
+ QT_NATIVE_INTERFACE_RETURN_IF(QWasmWindow, platformWindow);
+#endif
+
return nullptr;
}
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index cf6a6934eb..a9716847a1 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -23,7 +23,10 @@
#include <QtCore/private/qobject_p.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qxpfunctional.h>
-#include <QtGui/QIcon>
+#include <QtGui/qicon.h>
+#include <QtGui/qpalette.h>
+
+#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE
@@ -41,7 +44,7 @@ public:
QWindowPrivate();
~QWindowPrivate() override;
- void init(QScreen *targetScreen = nullptr);
+ void init(QWindow *parent, QScreen *targetScreen = nullptr);
#ifndef QT_NO_CURSOR
void setCursor(const QCursor *c = nullptr);
@@ -53,6 +56,7 @@ public:
QWindow *topLevelWindow(QWindow::AncestorMode mode = QWindow::IncludeTransients) const;
virtual QWindow *eventReceiver() { Q_Q(QWindow); return q; }
+ virtual QPalette windowPalette() const { return QPalette(); }
virtual void setVisible(bool visible);
void updateVisibility();
@@ -62,7 +66,7 @@ public:
void updateSiblingPosition(SiblingPosition);
bool windowRecreationRequired(QScreen *newScreen) const;
- void create(bool recursive, WId nativeHandle = 0);
+ void create(bool recursive);
void destroy();
void setTopLevelScreen(QScreen *newScreen, bool recreate);
void connectToScreen(QScreen *topLevelScreen);
@@ -87,6 +91,8 @@ public:
void setAutomaticPositionAndResizeEnabled(bool a)
{ positionAutomatic = resizeAutomatic = a; }
+ bool updateDevicePixelRatio();
+
static QWindowPrivate *get(QWindow *window) { return window->d_func(); }
static Qt::WindowState effectiveState(Qt::WindowStates);
@@ -104,6 +110,7 @@ public:
QString windowFilePath;
QIcon windowIcon;
QRect geometry;
+ qreal devicePixelRatio = 1.0;
Qt::WindowStates windowState = Qt::WindowNoState;
QWindow::Visibility visibility = QWindow::Hidden;
bool resizeEventPending = true;
@@ -138,7 +145,6 @@ public:
bool hasCursor = false;
#endif
- bool compositing = false;
QElapsedTimer lastComposeTime;
#if QT_CONFIG(vulkan)
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 051fe38a48..1875594300 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -138,7 +138,7 @@ static bool handleWindowSystemEvent(Args ...args)
return QWindowSystemHelper<Delivery>::template handleEvent<EventType>(args...);
}
-int QWindowSystemInterfacePrivate::windowSystemEventsQueued()
+qsizetype QWindowSystemInterfacePrivate::windowSystemEventsQueued()
{
return windowSystemEventQueue.count();
}
@@ -240,9 +240,9 @@ void QWindowSystemInterface::handleEnterLeaveEvent(QWindow *enter, QWindow *leav
handleEnterEvent(enter, local, global);
}
-QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowActivated, QWindow *window, Qt::FocusReason r)
+QT_DEFINE_QPA_EVENT_HANDLER(void, handleFocusWindowChanged, QWindow *window, Qt::FocusReason r)
{
- handleWindowSystemEvent<QWindowSystemInterfacePrivate::ActivatedWindowEvent, Delivery>(window, r);
+ handleWindowSystemEvent<QWindowSystemInterfacePrivate::FocusWindowEvent, Delivery>(window, r);
}
QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt::WindowStates newState, int oldState)
@@ -259,6 +259,12 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowScreenChanged, QWindow *window, QS
handleWindowSystemEvent<QWindowSystemInterfacePrivate::WindowScreenChangedEvent, Delivery>(window, screen);
}
+QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowDevicePixelRatioChanged, QWindow *window)
+{
+ handleWindowSystemEvent<QWindowSystemInterfacePrivate::WindowDevicePixelRatioChangedEvent, Delivery>(window);
+}
+
+
QT_DEFINE_QPA_EVENT_HANDLER(void, handleSafeAreaMarginsChanged, QWindow *window)
{
handleWindowSystemEvent<QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent, Delivery>(window);
@@ -383,61 +389,34 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong times
Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
- Q_ASSERT_X(type != QEvent::MouseButtonDblClick && type != QEvent::NonClientAreaMouseButtonDblClick,
- "QWindowSystemInterface::handleMouseEvent",
- "QTBUG-71263: Native double clicks are not implemented.");
- auto localPos = QHighDpi::fromNativeLocalPosition(local, window);
- auto globalPos = QHighDpi::fromNativeGlobalPosition(global, window);
- return handleWindowSystemEvent<QWindowSystemInterfacePrivate::MouseEvent, Delivery>(window,
- timestamp, localPos, globalPos, state, mods, button, type, source, false, device);
-}
+ bool isNonClientArea = {};
-bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window,
- const QPointF &local, const QPointF &global,
- Qt::MouseButtons state,
- Qt::MouseButton button, QEvent::Type type,
- Qt::KeyboardModifiers mods,
- Qt::MouseEventSource source)
-{
- const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- return handleFrameStrutMouseEvent(window, time, local, global, state, button, type, mods, source);
-}
-
-bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, const QPointingDevice *device,
- const QPointF &local, const QPointF &global,
- Qt::MouseButtons state,
- Qt::MouseButton button, QEvent::Type type,
- Qt::KeyboardModifiers mods,
- Qt::MouseEventSource source)
-{
- const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- return handleFrameStrutMouseEvent(window, time, device, local, global, state, button, type, mods, source);
-}
-
-bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp,
- const QPointF &local, const QPointF &global,
- Qt::MouseButtons state,
- Qt::MouseButton button, QEvent::Type type,
- Qt::KeyboardModifiers mods,
- Qt::MouseEventSource source)
-{
- return handleFrameStrutMouseEvent(window, timestamp, QPointingDevice::primaryPointingDevice(),
- local, global, state, button, type, mods, source);
-}
+ switch (type) {
+ case QEvent::MouseButtonDblClick:
+ case QEvent::NonClientAreaMouseButtonDblClick:
+ Q_ASSERT_X(false, "QWindowSystemInterface::handleMouseEvent",
+ "QTBUG-71263: Native double clicks are not implemented.");
+ return false;
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ isNonClientArea = false;
+ break;
+ case QEvent::NonClientAreaMouseMove:
+ case QEvent::NonClientAreaMouseButtonPress:
+ case QEvent::NonClientAreaMouseButtonRelease:
+ isNonClientArea = true;
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
-bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
- const QPointF &local, const QPointF &global,
- Qt::MouseButtons state,
- Qt::MouseButton button, QEvent::Type type,
- Qt::KeyboardModifiers mods,
- Qt::MouseEventSource source)
-{
auto localPos = QHighDpi::fromNativeLocalPosition(local, window);
auto globalPos = QHighDpi::fromNativeGlobalPosition(global, window);
- return handleWindowSystemEvent<QWindowSystemInterfacePrivate::MouseEvent>(window,
- timestamp, localPos, globalPos, state, mods, button, type, source, true, device);
+ return handleWindowSystemEvent<QWindowSystemInterfacePrivate::MouseEvent, Delivery>(window,
+ timestamp, localPos, globalPos, state, mods, button, type, source, isNonClientArea, device);
}
bool QWindowSystemInterface::handleShortcutEvent(QWindow *window, ulong timestamp, int keyCode, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode,
@@ -732,9 +711,9 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, ulong
The screen should be deleted by calling QWindowSystemInterface::handleScreenRemoved().
*/
-void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrimary)
+void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *platformScreen, bool isPrimary)
{
- QScreen *screen = new QScreen(ps);
+ QScreen *screen = new QScreen(platformScreen);
if (isPrimary)
QGuiApplicationPrivate::screen_list.prepend(screen);
@@ -761,9 +740,45 @@ void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrima
*/
void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen)
{
- // Important to keep this order since the QSceen doesn't own the platform screen.
- // The QScreen destructor will take care changing the primary screen, so no need here.
- delete platformScreen->screen();
+ QScreen *screen = platformScreen->screen();
+
+ // Remove screen
+ const bool wasPrimary = QGuiApplication::primaryScreen() == screen;
+ QGuiApplicationPrivate::screen_list.removeOne(screen);
+ QGuiApplicationPrivate::resetCachedDevicePixelRatio();
+
+ if (qGuiApp) {
+ QScreen *newPrimaryScreen = QGuiApplication::primaryScreen();
+ if (wasPrimary && newPrimaryScreen)
+ emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
+
+ // Allow clients to manage windows that are affected by the screen going
+ // away, before we fall back to moving them to the primary screen.
+ emit qApp->screenRemoved(screen);
+
+ if (!QGuiApplication::closingDown()) {
+ bool movingFromVirtualSibling = newPrimaryScreen
+ && newPrimaryScreen->handle()->virtualSiblings().contains(platformScreen);
+
+ // Move any leftover windows to the primary screen
+ const auto allWindows = QGuiApplication::allWindows();
+ for (QWindow *window : allWindows) {
+ if (!window->isTopLevel() || window->screen() != screen)
+ continue;
+
+ const bool wasVisible = window->isVisible();
+ window->setScreen(newPrimaryScreen);
+
+ // Re-show window if moved from a virtual sibling screen. Otherwise
+ // leave it up to the application developer to show the window.
+ if (movingFromVirtualSibling)
+ window->setVisible(wasVisible);
+ }
+ }
+ }
+
+ // Important to keep this order since the QSceen doesn't own the platform screen
+ delete screen;
delete platformScreen;
}
@@ -776,7 +791,7 @@ void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen
void QWindowSystemInterface::handlePrimaryScreenChanged(QPlatformScreen *newPrimary)
{
QScreen *newPrimaryScreen = newPrimary->screen();
- int indexOfScreen = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen);
+ qsizetype indexOfScreen = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen);
Q_ASSERT(indexOfScreen >= 0);
if (indexOfScreen == 0)
return;
@@ -799,6 +814,11 @@ void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const Q
void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY)
{
+ // Keep QHighDpiScaling::m_active in sync with platform screen state, in
+ // order to make scaling calls made during DPI change use the new state.
+ // FIXME: Remove when QHighDpiScaling::m_active has been removed.
+ QHighDpiScaling::updateHighDpiScaling();
+
const QDpi effectiveDpi = QPlatformScreen::overrideDpi(QDpi{dpiX, dpiY});
handleWindowSystemEvent<QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent>(screen,
effectiveDpi.first, effectiveDpi.second);
@@ -1043,7 +1063,7 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo
*/
bool QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
{
- const int count = QWindowSystemInterfacePrivate::windowSystemEventQueue.count();
+ const qsizetype count = QWindowSystemInterfacePrivate::windowSystemEventQueue.count();
if (!count)
return false;
if (!QGuiApplication::instance()) {
@@ -1190,10 +1210,17 @@ Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int
#endif
}
+Q_GUI_EXPORT void qt_handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global,
+ QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods,
+ Qt::ScrollPhase phase)
+{
+ QWindowSystemInterface::handleWheelEvent(window, local, global, pixelDelta, angleDelta, mods, phase);
+}
+
namespace QTest
{
- Q_GUI_EXPORT QPointingDevice * createTouchDevice(QInputDevice::DeviceType devType = QInputDevice::DeviceType::TouchScreen,
- QInputDevice::Capabilities caps = QInputDevice::Capability::Position)
+ Q_GUI_EXPORT QPointingDevice * createTouchDevice(QInputDevice::DeviceType devType,
+ QInputDevice::Capabilities caps)
{
static qint64 nextId = 0x100000000;
QPointingDevice *ret = new QPointingDevice("test touch device"_L1, nextId++,
@@ -1206,7 +1233,7 @@ namespace QTest
Q_GUI_EXPORT bool qt_handleTouchEventv2(QWindow *window, const QPointingDevice *device,
const QList<QEventPoint> &points,
- Qt::KeyboardModifiers mods = Qt::NoModifier)
+ Qt::KeyboardModifiers mods)
{
return QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(window, device,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window), mods);
@@ -1214,7 +1241,7 @@ Q_GUI_EXPORT bool qt_handleTouchEventv2(QWindow *window, const QPointingDevice *
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *window, const QPointingDevice *device,
const QList<QEventPoint> &points,
- Qt::KeyboardModifiers mods = Qt::NoModifier)
+ Qt::KeyboardModifiers mods)
{
qt_handleTouchEventv2(window, device, points, mods);
}
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 004019ae2d..4fc61a475d 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -64,31 +64,6 @@ public:
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
- static bool handleFrameStrutMouseEvent(QWindow *window, const QPointF &local,
- const QPointF &global, Qt::MouseButtons state,
- Qt::MouseButton button, QEvent::Type type,
- Qt::KeyboardModifiers mods = Qt::NoModifier,
- Qt::MouseEventSource source =
- Qt::MouseEventNotSynthesized);
- static bool handleFrameStrutMouseEvent(QWindow *window, const QPointingDevice *device,
- const QPointF &local, const QPointF &global,
- Qt::MouseButtons state,
- Qt::MouseButton button, QEvent::Type type,
- Qt::KeyboardModifiers mods = Qt::NoModifier,
- Qt::MouseEventSource source =
- Qt::MouseEventNotSynthesized);
- static bool handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, const QPointF &local,
- const QPointF &global, Qt::MouseButtons state,
- Qt::MouseButton button, QEvent::Type type,
- Qt::KeyboardModifiers mods = Qt::NoModifier,
- Qt::MouseEventSource source =
- Qt::MouseEventNotSynthesized);
- static bool handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
- const QPointF &local, const QPointF &global, Qt::MouseButtons state,
- Qt::MouseButton button, QEvent::Type type,
- Qt::KeyboardModifiers mods = Qt::NoModifier,
- Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
-
static bool handleShortcutEvent(QWindow *window, ulong timestamp, int k, Qt::KeyboardModifiers mods, quint32 nativeScanCode,
quint32 nativeVirtualKey, quint32 nativeModifiers, const QString & text = QString(), bool autorep = false, ushort count = 1);
@@ -182,8 +157,9 @@ public:
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleLeaveEvent(QWindow *window);
static void handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local = QPointF(), const QPointF& global = QPointF());
+
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
- static void handleWindowActivated(QWindow *window, Qt::FocusReason r = Qt::OtherFocusReason);
+ static void handleFocusWindowChanged(QWindow *window, Qt::FocusReason r = Qt::OtherFocusReason);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleWindowStateChanged(QWindow *window, Qt::WindowStates newState, int oldState = -1);
@@ -191,6 +167,9 @@ public:
static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
+ static void handleWindowDevicePixelRatioChanged(QWindow *window);
+
+ template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleSafeAreaMarginsChanged(QWindow *window);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
@@ -252,6 +231,8 @@ public:
Qt::MouseButtons buttons = {}, int xTilt = 0, int yTilt = 0,
qreal tangentialPressure = 0, qreal rotation = 0, int z = 0,
Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+
+ // The following 4 functions are deprecated (QTBUG-114560)
static bool handleTabletEnterProximityEvent(ulong timestamp, int deviceType, int pointerType, qint64 uid);
static void handleTabletEnterProximityEvent(int deviceType, int pointerType, qint64 uid);
static bool handleTabletLeaveProximityEvent(ulong timestamp, int deviceType, int pointerType, qint64 uid);
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 27aa7dbc57..51ab58fc99 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -40,7 +40,7 @@ public:
GeometryChange = 0x02,
Enter = UserInputEvent | 0x03,
Leave = UserInputEvent | 0x04,
- ActivatedWindow = 0x05,
+ FocusWindow = 0x05,
WindowStateChanged = 0x06,
Mouse = UserInputEvent | 0x07,
Wheel = UserInputEvent | 0x09,
@@ -68,7 +68,8 @@ public:
WindowScreenChanged = 0x21,
SafeAreaMarginsChanged = 0x22,
ApplicationTermination = 0x23,
- Paint = 0x24
+ Paint = 0x24,
+ WindowDevicePixelRatioChanged = 0x25,
};
class WindowSystemEvent {
@@ -124,12 +125,12 @@ public:
QPointer<QWindow> leave;
};
- class ActivatedWindowEvent : public WindowSystemEvent {
+ class FocusWindowEvent : public WindowSystemEvent {
public:
- explicit ActivatedWindowEvent(QWindow *activatedWindow, Qt::FocusReason r)
- : WindowSystemEvent(ActivatedWindow), activated(activatedWindow), reason(r)
+ explicit FocusWindowEvent(QWindow *focusedWindow, Qt::FocusReason r)
+ : WindowSystemEvent(FocusWindow), focused(focusedWindow), reason(r)
{ }
- QPointer<QWindow> activated;
+ QPointer<QWindow> focused;
Qt::FocusReason reason;
};
@@ -154,6 +155,15 @@ public:
QPointer<QScreen> screen;
};
+ class WindowDevicePixelRatioChangedEvent : public WindowSystemEvent {
+ public:
+ WindowDevicePixelRatioChangedEvent(QWindow *w)
+ : WindowSystemEvent(WindowDevicePixelRatioChanged), window(w)
+ { }
+
+ QPointer<QWindow> window;
+ };
+
class SafeAreaMarginsChangedEvent : public WindowSystemEvent {
public:
SafeAreaMarginsChangedEvent(QWindow *w)
@@ -463,7 +473,7 @@ public:
}
void append(WindowSystemEvent *e)
{ const QMutexLocker locker(&mutex); impl.append(e); }
- int count() const
+ qsizetype count() const
{ const QMutexLocker locker(&mutex); return impl.size(); }
WindowSystemEvent *peekAtFirstOfType(EventType t) const
{
@@ -490,7 +500,7 @@ public:
static WindowSystemEventList windowSystemEventQueue;
- static int windowSystemEventsQueued();
+ static qsizetype windowSystemEventsQueued();
static bool nonUserInputEventsQueued();
static WindowSystemEvent *getWindowSystemEvent();
static WindowSystemEvent *getNonUserInputWindowSystemEvent();