summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r--src/widgets/kernel/qaction.cpp45
-rw-r--r--src/widgets/kernel/qaction.h3
-rw-r--r--src/widgets/kernel/qaction_p.h3
-rw-r--r--src/widgets/kernel/qapplication.cpp12
-rw-r--r--src/widgets/kernel/qapplication_p.h2
-rw-r--r--src/widgets/kernel/qboxlayout.cpp28
-rw-r--r--src/widgets/kernel/qdesktopwidget.qdoc2
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp10
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp134
-rw-r--r--src/widgets/kernel/qopenglwidget.h3
-rw-r--r--src/widgets/kernel/qwidget.cpp81
-rw-r--r--src/widgets/kernel/qwidget_p.h21
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp26
-rw-r--r--src/widgets/kernel/qwidgetbackingstore_p.h6
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp98
-rw-r--r--src/widgets/kernel/qwidgetwindow_p.h3
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp13
17 files changed, 312 insertions, 178 deletions
diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp
index 002ca68720..a7116b1462 100644
--- a/src/widgets/kernel/qaction.cpp
+++ b/src/widgets/kernel/qaction.cpp
@@ -45,6 +45,7 @@
#include "qapplication.h"
#include "qevent.h"
#include "qlist.h"
+#include "qstylehints.h"
#include <private/qshortcutmap_p.h>
#include <private/qapplication_p.h>
#include <private/qmenu_p.h>
@@ -75,6 +76,7 @@ static QString qt_strippedText(QString s)
QActionPrivate::QActionPrivate() : group(0), enabled(1), forceDisabled(0),
visible(1), forceInvisible(0), checkable(0), checked(0), separator(0), fontSet(false),
iconVisibleInMenu(-1),
+ shortcutVisibleInContextMenu(-1),
menuRole(QAction::TextHeuristicRole),
priority(QAction::NormalPriority)
{
@@ -1278,8 +1280,7 @@ void QAction::setIconVisibleInMenu(bool visible)
d->iconVisibleInMenu = visible;
// Only send data changed if we really need to.
if (oldValue != -1
- || (oldValue == -1
- && visible == !QApplication::instance()->testAttribute(Qt::AA_DontShowIconsInMenus))) {
+ || visible == !QApplication::instance()->testAttribute(Qt::AA_DontShowIconsInMenus)) {
d->sendDataChanged();
}
}
@@ -1294,6 +1295,46 @@ bool QAction::isIconVisibleInMenu() const
return d->iconVisibleInMenu;
}
+/*!
+ \property QAction::shortcutVisibleInContextMenu
+ \brief Whether or not an action should show a shortcut in a context menu
+ \since 5.10
+
+ In some applications, it may make sense to have actions with shortcuts in
+ context menus. If true, the shortcut (if valid) is shown when the action is
+ shown via a context menu, when it is false, it is not shown.
+
+ The default is to follow whether the Qt::AA_DontShowShortcutsInContextMenus attribute
+ is set for the application, falling back to the widget style hint.
+ Explicitly setting this property overrides the presence (or abscence) of the attribute.
+
+ \sa QAction::shortcut, QCoreApplication::setAttribute()
+*/
+void QAction::setShortcutVisibleInContextMenu(bool visible)
+{
+ Q_D(QAction);
+ if (d->shortcutVisibleInContextMenu == -1 || visible != bool(d->shortcutVisibleInContextMenu)) {
+ int oldValue = d->shortcutVisibleInContextMenu;
+ d->shortcutVisibleInContextMenu = visible;
+ // Only send data changed if we really need to.
+ if (oldValue != -1
+ || visible == !QApplication::instance()->testAttribute(Qt::AA_DontShowShortcutsInContextMenus)) {
+ d->sendDataChanged();
+ }
+ }
+}
+
+bool QAction::isShortcutVisibleInContextMenu() const
+{
+ Q_D(const QAction);
+ if (d->shortcutVisibleInContextMenu == -1) {
+ if (QApplication::instance()->testAttribute(Qt::AA_DontShowIconsInMenus))
+ return false;
+ return qApp->styleHints()->showShortcutsInContextMenus();
+ }
+ return d->shortcutVisibleInContextMenu;
+}
+
#ifndef QT_NO_DEBUG_STREAM
Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QAction *action)
{
diff --git a/src/widgets/kernel/qaction.h b/src/widgets/kernel/qaction.h
index 7dc4419d8e..ca127ef51a 100644
--- a/src/widgets/kernel/qaction.h
+++ b/src/widgets/kernel/qaction.h
@@ -80,6 +80,7 @@ class Q_WIDGETS_EXPORT QAction : public QObject
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY changed)
Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
+ Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed)
Q_PROPERTY(Priority priority READ priority WRITE setPriority)
public:
@@ -168,6 +169,8 @@ public:
void setIconVisibleInMenu(bool visible);
bool isIconVisibleInMenu() const;
+ void setShortcutVisibleInContextMenu(bool show);
+ bool isShortcutVisibleInContextMenu() const;
QWidget *parentWidget() const;
diff --git a/src/widgets/kernel/qaction_p.h b/src/widgets/kernel/qaction_p.h
index 45394e0b52..4c1537b63b 100644
--- a/src/widgets/kernel/qaction_p.h
+++ b/src/widgets/kernel/qaction_p.h
@@ -107,7 +107,8 @@ public:
uint separator : 1;
uint fontSet : 1;
- int iconVisibleInMenu : 3; // Only has values -1, 0, and 1
+ int iconVisibleInMenu : 2; // Only has values -1, 0, and 1
+ int shortcutVisibleInContextMenu : 2; // Only has values -1, 0, and 1
QAction::MenuRole menuRole;
QAction::Priority priority;
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 26e9ffbbf0..ee61a25b09 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -1236,7 +1236,7 @@ void QApplication::setStyle(QStyle *style)
Requests a QStyle object for \a style from the QStyleFactory.
The string must be one of the QStyleFactory::keys(), typically one of
- "windows", "fusion", "windowsxp", or "macintosh". Style
+ "windows", "windowsvista", "fusion", or "macintosh". Style
names are case insensitive.
Returns 0 if an unknown \a style is passed, otherwise the QStyle object
@@ -1479,8 +1479,8 @@ void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char*
"selection-background-color" and "alternate-background-color".
\note Some styles do not use the palette for all drawing, for instance, if
- they make use of native theme engines. This is the case for the Windows XP,
- Windows Vista, and \macos styles.
+ they make use of native theme engines. This is the case for the
+ Windows Vista and \macos styles.
\sa QWidget::setPalette(), palette(), QStyle::polish()
*/
@@ -2735,7 +2735,7 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
case enter/leave events are genereated by the underlying windowing system.
*/
extern QPointer<QWidget> qt_last_mouse_receiver;
-extern QWidget *qt_button_down;
+extern Q_WIDGETS_EXPORT QWidget *qt_button_down;
void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
{
#ifndef QT_NO_CURSOR
@@ -2964,6 +2964,9 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
// required in order to support Qt Test synthesized events. Real mouse
// and keyboard state updates from the platform plugin are managed by
// QGuiApplicationPrivate::process(Mouse|Wheel|Key|Touch|Tablet)Event();
+ // ### FIXME: Qt Test should not call qapp->notify(), but rather route
+ // the events through the proper QPA interface. This is required to
+ // properly generate all other events such as enter/leave etc.
switch (e->type()) {
case QEvent::MouseButtonPress:
{
@@ -3760,7 +3763,6 @@ static void grabForPopup(QWidget *popup)
}
}
-extern QWidget *qt_button_down;
extern QWidget *qt_popup_down;
extern bool qt_replay_popup_mouse_event;
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 36de3cacaa..5dca2e85f1 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -92,7 +92,7 @@ extern QClipboard *qt_clipboard;
#endif
typedef QHash<QByteArray, QFont> FontHash;
-FontHash *qt_app_fonts_hash();
+Q_WIDGETS_EXPORT FontHash *qt_app_fonts_hash();
typedef QHash<QByteArray, QPalette> PaletteHash;
PaletteHash *qt_app_palettes_hash();
diff --git a/src/widgets/kernel/qboxlayout.cpp b/src/widgets/kernel/qboxlayout.cpp
index f2e3df5314..588cec2b95 100644
--- a/src/widgets/kernel/qboxlayout.cpp
+++ b/src/widgets/kernel/qboxlayout.cpp
@@ -873,15 +873,9 @@ void QBoxLayout::insertSpacing(int index, int size)
else
b = QLayoutPrivate::createSpacerItem(this, 0, size, QSizePolicy::Minimum, QSizePolicy::Fixed);
- QT_TRY {
- QBoxLayoutItem *it = new QBoxLayoutItem(b);
- it->magic = true;
- d->list.insert(index, it);
-
- } QT_CATCH(...) {
- delete b;
- QT_RETHROW;
- }
+ QBoxLayoutItem *it = new QBoxLayoutItem(b);
+ it->magic = true;
+ d->list.insert(index, it);
invalidate();
}
@@ -985,20 +979,8 @@ void QBoxLayout::insertWidget(int index, QWidget *widget, int stretch,
QWidgetItem *b = QLayoutPrivate::createWidgetItem(this, widget);
b->setAlignment(alignment);
- QBoxLayoutItem *it;
- QT_TRY{
- it = new QBoxLayoutItem(b, stretch);
- } QT_CATCH(...) {
- delete b;
- QT_RETHROW;
- }
-
- QT_TRY{
- d->list.insert(index, it);
- } QT_CATCH(...) {
- delete it;
- QT_RETHROW;
- }
+ QBoxLayoutItem *it = new QBoxLayoutItem(b, stretch);
+ d->list.insert(index, it);
invalidate();
}
diff --git a/src/widgets/kernel/qdesktopwidget.qdoc b/src/widgets/kernel/qdesktopwidget.qdoc
index 27d05ece8c..fdf6a27597 100644
--- a/src/widgets/kernel/qdesktopwidget.qdoc
+++ b/src/widgets/kernel/qdesktopwidget.qdoc
@@ -152,7 +152,7 @@
on \macos, or the task bar on Windows). The default screen is used if
\a screen is -1.
- \sa screenNumber(), screenGeometry()
+ \sa screenNumber(), screenGeometry(), QScreen::availableGeometry()
*/
/*!
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index 2873703cb7..fca36c7472 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -124,7 +124,7 @@ QGestureManager::~QGestureManager()
Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
{
- QGesture *dummy = recognizer->create(0);
+ const QScopedPointer<QGesture> dummy(recognizer->create(nullptr));
if (Q_UNLIKELY(!dummy)) {
qWarning("QGestureManager::registerGestureRecognizer: "
"the recognizer fails to create a gesture object, skipping registration.");
@@ -137,7 +137,6 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r
type = Qt::GestureType(m_lastCustomGestureId);
}
m_recognizers.insertMulti(type, recognizer);
- delete dummy;
return type;
}
@@ -145,10 +144,9 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
{
QList<QGestureRecognizer *> list = m_recognizers.values(type);
while (QGestureRecognizer *recognizer = m_recognizers.take(type)) {
- if (!m_obsoleteGestures.contains(recognizer)) {
- // inserting even an empty QSet will cause the recognizer to be deleted on destruction of the manager
- m_obsoleteGestures.insert(recognizer, QSet<QGesture *>());
- }
+ // ensuring an entry exists causes the recognizer to be deleted on destruction of the manager
+ auto &gestures = m_obsoleteGestures[recognizer];
+ Q_UNUSED(gestures);
}
foreach (QGesture *g, m_gestureToRecognizer.keys()) {
QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 218d3c4a46..5bc408a8cd 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -567,7 +567,8 @@ public:
paintDevice(0),
updateBehavior(QOpenGLWidget::NoPartialUpdate),
requestedSamples(0),
- inPaintGL(false)
+ inPaintGL(false),
+ textureFormat(0)
{
requestedFormat = QSurfaceFormat::defaultFormat();
}
@@ -576,6 +577,7 @@ public:
void recreateFbo();
GLuint textureId() const Q_DECL_OVERRIDE;
+ QPlatformTextureList::Flags textureListFlags() Q_DECL_OVERRIDE;
void initialize();
void invokeUserPaint();
@@ -606,6 +608,7 @@ public:
QOpenGLWidget::UpdateBehavior updateBehavior;
int requestedSamples;
bool inPaintGL;
+ GLenum textureFormat;
};
void QOpenGLWidgetPaintDevicePrivate::beginPaint()
@@ -663,6 +666,35 @@ GLuint QOpenGLWidgetPrivate::textureId() const
return resolvedFbo ? resolvedFbo->texture() : (fbo ? fbo->texture() : 0);
}
+#ifndef GL_SRGB
+#define GL_SRGB 0x8C40
+#endif
+#ifndef GL_SRGB8
+#define GL_SRGB8 0x8C41
+#endif
+#ifndef GL_SRGB_ALPHA
+#define GL_SRGB_ALPHA 0x8C42
+#endif
+#ifndef GL_SRGB8_ALPHA8
+#define GL_SRGB8_ALPHA8 0x8C43
+#endif
+
+QPlatformTextureList::Flags QOpenGLWidgetPrivate::textureListFlags()
+{
+ QPlatformTextureList::Flags flags = QWidgetPrivate::textureListFlags();
+ switch (textureFormat) {
+ case GL_SRGB:
+ case GL_SRGB8:
+ case GL_SRGB_ALPHA:
+ case GL_SRGB8_ALPHA8:
+ flags |= QPlatformTextureList::TextureIsSrgb;
+ break;
+ default:
+ break;
+ }
+ return flags;
+}
+
void QOpenGLWidgetPrivate::reset()
{
Q_Q(QOpenGLWidget);
@@ -712,12 +744,16 @@ void QOpenGLWidgetPrivate::recreateFbo()
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(samples);
+ if (textureFormat)
+ format.setInternalTextureFormat(textureFormat);
const QSize deviceSize = q->size() * q->devicePixelRatioF();
fbo = new QOpenGLFramebufferObject(deviceSize, format);
if (samples > 0)
resolvedFbo = new QOpenGLFramebufferObject(deviceSize);
+ textureFormat = fbo->format().internalTextureFormat();
+
fbo->bind();
context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -755,10 +791,8 @@ void QOpenGLWidgetPrivate::initialize()
// texture usable by the underlying window's backingstore.
QWidget *tlw = q->window();
QOpenGLContext *shareContext = get(tlw)->shareContext();
- if (Q_UNLIKELY(!shareContext)) {
- qWarning("QOpenGLWidget: Cannot be used without a context shared with the toplevel.");
- return;
- }
+ // If shareContext is null, showing content on-screen will not work.
+ // However, offscreen rendering and grabFramebuffer() will stay fully functional.
// Do not include the sample count. Requesting a multisampled context is not necessary
// since we render into an FBO, never to an actual surface. What's more, attempting to
@@ -768,25 +802,31 @@ void QOpenGLWidgetPrivate::initialize()
requestedFormat.setSamples(0);
QScopedPointer<QOpenGLContext> ctx(new QOpenGLContext);
- ctx->setShareContext(shareContext);
ctx->setFormat(requestedFormat);
- ctx->setScreen(shareContext->screen());
+ if (shareContext) {
+ ctx->setShareContext(shareContext);
+ ctx->setScreen(shareContext->screen());
+ }
if (Q_UNLIKELY(!ctx->create())) {
qWarning("QOpenGLWidget: Failed to create context");
return;
}
- // Propagate settings that make sense only for the tlw.
- QSurfaceFormat tlwFormat = tlw->windowHandle()->format();
- if (requestedFormat.swapInterval() != tlwFormat.swapInterval()) {
- // Most platforms will pick up the changed swap interval on the next
- // makeCurrent or swapBuffers.
- tlwFormat.setSwapInterval(requestedFormat.swapInterval());
- tlw->windowHandle()->setFormat(tlwFormat);
- }
- if (requestedFormat.swapBehavior() != tlwFormat.swapBehavior()) {
- tlwFormat.setSwapBehavior(requestedFormat.swapBehavior());
- tlw->windowHandle()->setFormat(tlwFormat);
+ // Propagate settings that make sense only for the tlw. Note that this only
+ // makes sense for properties that get picked up even after the native
+ // window is created.
+ if (tlw->windowHandle()) {
+ QSurfaceFormat tlwFormat = tlw->windowHandle()->format();
+ if (requestedFormat.swapInterval() != tlwFormat.swapInterval()) {
+ // Most platforms will pick up the changed swap interval on the next
+ // makeCurrent or swapBuffers.
+ tlwFormat.setSwapInterval(requestedFormat.swapInterval());
+ tlw->windowHandle()->setFormat(tlwFormat);
+ }
+ if (requestedFormat.swapBehavior() != tlwFormat.swapBehavior()) {
+ tlwFormat.setSwapBehavior(requestedFormat.swapBehavior());
+ tlw->windowHandle()->setFormat(tlwFormat);
+ }
}
// The top-level window's surface is not good enough since it causes way too
@@ -880,9 +920,14 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_
QImage QOpenGLWidgetPrivate::grabFramebuffer()
{
Q_Q(QOpenGLWidget);
+
+ initialize();
if (!initialized)
return QImage();
+ if (!fbo) // could be completely offscreen, without ever getting a resize event
+ recreateFbo();
+
if (!inPaintGL)
render();
@@ -1000,7 +1045,6 @@ QOpenGLWidget::UpdateBehavior QOpenGLWidget::updateBehavior() const
*/
void QOpenGLWidget::setFormat(const QSurfaceFormat &format)
{
- Q_UNUSED(format);
Q_D(QOpenGLWidget);
if (Q_UNLIKELY(d->initialized)) {
qWarning("QOpenGLWidget: Already initialized, setting the format has no effect");
@@ -1033,6 +1077,47 @@ QSurfaceFormat QOpenGLWidget::format() const
}
/*!
+ Sets a custom internal texture format of \a texFormat.
+
+ When working with sRGB framebuffers, it will be necessary to specify a
+ format like \c{GL_SRGB8_ALPHA8}. This can be achieved by calling this
+ function.
+
+ \note This function has no effect if called after the widget has already
+ been shown and thus it performed initialization.
+
+ \note This function will typically have to be used in combination with a
+ QSurfaceFormat::setDefaultFormat() call that sets the color space to
+ QSurfaceFormat::sRGBColorSpace.
+
+ \since 5.10
+ */
+void QOpenGLWidget::setTextureFormat(GLenum texFormat)
+{
+ Q_D(QOpenGLWidget);
+ if (Q_UNLIKELY(d->initialized)) {
+ qWarning("QOpenGLWidget: Already initialized, setting the internal texture format has no effect");
+ return;
+ }
+
+ d->textureFormat = texFormat;
+}
+
+/*!
+ \return the active internal texture format if the widget has already
+ initialized, the requested format if one was set but the widget has not yet
+ been made visible, or 0 if setTextureFormat() was not called and the widget
+ has not yet been made visible.
+
+ \since 5.10
+ */
+GLenum QOpenGLWidget::textureFormat() const
+{
+ Q_D(const QOpenGLWidget);
+ return d->textureFormat;
+}
+
+/*!
\return \e true if the widget and OpenGL resources, like the context, have
been successfully initialized. Note that the return value is always false
until the widget is shown.
@@ -1293,7 +1378,7 @@ int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const
if (window)
return int(window->devicePixelRatio() * devicePixelRatioFScale());
else
- return 1.0;
+ return int(devicePixelRatioFScale());
default:
qWarning("QOpenGLWidget::metric(): unknown metric %d", metric);
return 0;
@@ -1346,7 +1431,14 @@ bool QOpenGLWidget::event(QEvent *e)
break;
// FALLTHROUGH
case QEvent::Show: // reparenting may not lead to a resize so reinitalize on Show too
- if (!d->initialized && !size().isEmpty() && window() && window()->windowHandle()) {
+ if (d->initialized && window()->windowHandle()
+ && d->context->shareContext() != QWidgetPrivate::get(window())->shareContext())
+ {
+ // Special case: did grabFramebuffer() for a hidden widget that then became visible.
+ // Recreate all resources since the context now needs to share with the TLW's.
+ d->reset();
+ }
+ if (!d->initialized && !size().isEmpty() && window()->windowHandle()) {
d->initialize();
if (d->initialized)
d->recreateFbo();
diff --git a/src/widgets/kernel/qopenglwidget.h b/src/widgets/kernel/qopenglwidget.h
index b60d79bedb..c0a6e41522 100644
--- a/src/widgets/kernel/qopenglwidget.h
+++ b/src/widgets/kernel/qopenglwidget.h
@@ -72,6 +72,9 @@ public:
void setFormat(const QSurfaceFormat &format);
QSurfaceFormat format() const;
+ GLenum textureFormat() const;
+ void setTextureFormat(GLenum texFormat);
+
bool isValid() const;
void makeCurrent();
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index d372d69d02..2b4c70ed2b 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -67,7 +67,6 @@
# include <private/qmainwindowlayout_p.h>
#endif
#include <qpa/qplatformwindow.h>
-#include <qpa/qplatformbackingstore.h>
#include "private/qwidgetwindow_p.h"
#include "qpainter.h"
#include "qtooltip.h"
@@ -1424,7 +1423,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
return; // we only care about real toplevels
- QWindow *win = topData()->window;
+ QWidgetWindow *win = topData()->window;
// topData() ensures the extra is created but does not ensure 'window' is non-null
// in case the extra was already valid.
if (!win) {
@@ -1441,7 +1440,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
if (q->testAttribute(Qt::WA_ShowWithoutActivating))
win->setProperty("_q_showWithoutActivating", QVariant(true));
if (q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
- win->setProperty("_q_macAlwaysShowToolWindow", QVariant::fromValue(QVariant(true)));
+ win->setProperty("_q_macAlwaysShowToolWindow", QVariant(true));
setNetWmWindowTypes(true); // do nothing if none of WA_X11NetWmWindowType* is set
win->setFlags(data.window_flags);
fixPosIncludesFrame();
@@ -1525,7 +1524,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
q->setAttribute(Qt::WA_OutsideWSRange, true);
} else if (q->isVisible()) {
// If widget is already shown, set window visible, too
- win->setVisible(true);
+ win->setNativeWindowVisibility(true);
}
}
@@ -2111,14 +2110,15 @@ QRegion QWidgetPrivate::clipRegion() const
return r;
}
-void QWidgetPrivate::setSystemClip(QPaintDevice *paintDevice, const QRegion &region)
+void QWidgetPrivate::setSystemClip(QPaintEngine *paintEngine, qreal devicePixelRatio, const QRegion &region)
{
// Transform the system clip region from device-independent pixels to device pixels
- QPaintEngine *paintEngine = paintDevice->paintEngine();
QTransform scaleTransform;
- const qreal devicePixelRatio = paintDevice->devicePixelRatioF();
scaleTransform.scale(devicePixelRatio, devicePixelRatio);
- paintEngine->d_func()->systemClip = scaleTransform.map(region);
+
+ paintEngine->d_func()->baseSystemClip = region;
+ paintEngine->d_func()->setSystemTransform(scaleTransform);
+
}
#if QT_CONFIG(graphicseffect)
@@ -2647,11 +2647,7 @@ WId QWidget::effectiveWinId() const
QWindow *QWidget::windowHandle() const
{
Q_D(const QWidget);
- QTLWExtra *extra = d->maybeTopData();
- if (extra)
- return extra->window;
-
- return 0;
+ return d->windowHandle();
}
#ifndef QT_NO_STYLE_STYLESHEET
@@ -3046,17 +3042,6 @@ void QWidget::overrideWindowState(Qt::WindowStates newstate)
QApplication::sendEvent(this, &e);
}
-Qt::WindowState effectiveState(Qt::WindowStates state)
-{
- if (state & Qt::WindowMinimized)
- return Qt::WindowMinimized;
- else if (state & Qt::WindowFullScreen)
- return Qt::WindowFullScreen;
- else if (state & Qt::WindowMaximized)
- return Qt::WindowMaximized;
- return Qt::WindowNoState;
-}
-
/*!
\fn void QWidget::setWindowState(Qt::WindowStates windowState)
@@ -3098,19 +3083,17 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
data->window_state = newstate;
data->in_set_window_state = 1;
- Qt::WindowState newEffectiveState = effectiveState(newstate);
- Qt::WindowState oldEffectiveState = effectiveState(oldstate);
- if (isWindow() && newEffectiveState != oldEffectiveState) {
+ if (isWindow()) {
// Ensure the initial size is valid, since we store it as normalGeometry below.
if (!testAttribute(Qt::WA_Resized) && !isVisible())
adjustSize();
d->createTLExtra();
- if (oldEffectiveState == Qt::WindowNoState)
+ if (!(oldstate & (Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen)))
d->topData()->normalGeometry = geometry();
Q_ASSERT(windowHandle());
- windowHandle()->setWindowState(newEffectiveState);
+ windowHandle()->setWindowStates(newstate & ~Qt::WindowActive);
}
data->in_set_window_state = 0;
@@ -4531,7 +4514,7 @@ void QWidget::setForegroundRole(QPalette::ColorRole role)
The default depends on the system environment. QApplication maintains a
system/theme palette which serves as a default for all widgets. There may
also be special palette defaults for certain types of widgets (e.g., on
- Windows XP and Vista, all classes that derive from QMenuBar have a special
+ Windows Vista, all classes that derive from QMenuBar have a special
default palette). You can also define default palettes for widgets
yourself by passing a custom palette and the name of a widget to
QApplication::setPalette(). Finally, the style always has the option of
@@ -4549,8 +4532,8 @@ void QWidget::setForegroundRole(QPalette::ColorRole role)
The current style, which is used to render the content of all standard Qt
widgets, is free to choose colors and brushes from the widget palette, or
in some cases, to ignore the palette (partially, or completely). In
- particular, certain styles like GTK style, Mac style, Windows XP, and
- Vista style, depend on third party APIs to render the content of widgets,
+ particular, certain styles like GTK style, Mac style, and Windows Vista
+ style, depend on third party APIs to render the content of widgets,
and these styles typically do not follow the palette. Because of this,
assigning roles to a widget's palette is not guaranteed to change the
appearance of the widget. Instead, you may choose to apply a \l
@@ -4712,7 +4695,7 @@ void QWidgetPrivate::updateSystemBackground()
The current style, which is used to render the content of all standard Qt
widgets, is free to choose to use the widget font, or in some cases, to
ignore it (partially, or completely). In particular, certain styles like
- GTK style, Mac style, Windows XP, and Vista style, apply special
+ GTK style, Mac style, and Windows Vista style, apply special
modifications to the widget font to match the platform's native look and
feel. Because of this, assigning properties to a widget's font is not
guaranteed to change the appearance of the widget. Instead, you may choose
@@ -5214,6 +5197,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
// Save current system clip, viewport and transform,
const QTransform oldTransform = enginePriv->systemTransform;
const QRegion oldSystemClip = enginePriv->systemClip;
+ const QRegion oldBaseClip = enginePriv->baseSystemClip;
const QRegion oldSystemViewport = enginePriv->systemViewport;
// This ensures that all painting triggered by render() is clipped to the current engine clip.
@@ -5227,9 +5211,8 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
d->render(target, targetOffset, toBePainted, renderFlags);
// Restore system clip, viewport and transform.
- enginePriv->setSystemViewport(oldSystemViewport);
- enginePriv->setSystemTransform(oldTransform);
- enginePriv->systemClip = oldSystemClip;
+ enginePriv->baseSystemClip = oldBaseClip;
+ enginePriv->setSystemTransformAndViewport(oldTransform, oldSystemViewport);
enginePriv->systemStateChanged();
// Restore shared painter.
@@ -5521,12 +5504,12 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
QWidgetPaintContext context(pdev, rgn, offset, flags, sharedPainter, backingStore);
sourced->context = &context;
if (!sharedPainter) {
- setSystemClip(pdev, rgn.translated(offset));
+ setSystemClip(pdev->paintEngine(), pdev->devicePixelRatioF(), rgn.translated(offset));
QPainter p(pdev);
p.translate(offset);
context.painter = &p;
graphicsEffect->draw(&p);
- setSystemClip(pdev, QRegion());
+ setSystemClip(pdev->paintEngine(), 1, QRegion());
} else {
context.painter = sharedPainter;
if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
@@ -5535,7 +5518,9 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
}
sharedPainter->save();
sharedPainter->translate(offset);
+ setSystemClip(sharedPainter->paintEngine(), sharedPainter->device()->devicePixelRatioF(), rgn.translated(offset));
graphicsEffect->draw(sharedPainter);
+ setSystemClip(sharedPainter->paintEngine(), 1, QRegion());
sharedPainter->restore();
}
sourced->context = 0;
@@ -5587,7 +5572,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
#endif
if (sharedPainter)
- setSystemClip(pdev, toBePainted);
+ setSystemClip(pdev->paintEngine(), pdev->devicePixelRatioF(), toBePainted);
else
paintEngine->d_func()->systemRect = q->data->crect;
@@ -5605,7 +5590,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
}
if (!sharedPainter)
- setSystemClip(pdev, toBePainted.translated(offset));
+ setSystemClip(pdev->paintEngine(), pdev->devicePixelRatioF(), toBePainted.translated(offset));
if (!onScreen && !asRoot && !isOpaque && q->testAttribute(Qt::WA_TintedBackground)) {
#ifndef QT_NO_OPENGL
@@ -5675,7 +5660,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
else
paintEngine->d_func()->currentClipDevice = 0;
- setSystemClip(pdev, QRegion());
+ setSystemClip(pdev->paintEngine(), 1, QRegion());
}
q->setAttribute(Qt::WA_WState_InPaintEvent, false);
if (Q_UNLIKELY(q->paintingActive()))
@@ -7977,7 +7962,7 @@ void QWidgetPrivate::show_sys()
{
Q_Q(QWidget);
- QWindow *window = q->windowHandle();
+ QWidgetWindow *window = windowHandle();
if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
invalidateBuffer(q->rect());
@@ -8024,7 +8009,7 @@ void QWidgetPrivate::show_sys()
qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show
#endif
invalidateBuffer(q->rect());
- window->setVisible(true);
+ window->setNativeWindowVisibility(true);
// Was the window moved by the Window system or QPlatformWindow::initialGeometry() ?
if (window->isTopLevel()) {
const QPoint crectTopLeft = q->data->crect.topLeft();
@@ -8116,7 +8101,7 @@ void QWidgetPrivate::hide_sys()
{
Q_Q(QWidget);
- QWindow *window = q->windowHandle();
+ QWidgetWindow *window = windowHandle();
if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
q->setAttribute(Qt::WA_Mapped, false);
@@ -8146,7 +8131,7 @@ void QWidgetPrivate::hide_sys()
}
if (window)
- window->setVisible(false);
+ window->setNativeWindowVisibility(false);
}
/*!
@@ -10023,6 +10008,7 @@ void QWidget::hideEvent(QHideEvent *)
\table
\header \li Platform \li Event Type Identifier \li Message Type \li Result Type
\row \li Windows \li "windows_generic_MSG" \li MSG * \li LRESULT
+ \row \li macOS \li "NSEvent" \li NSEvent * \li
\endtable
*/
@@ -12254,10 +12240,9 @@ QOpenGLContext *QWidgetPrivate::shareContext() const
#ifdef QT_NO_OPENGL
return 0;
#else
- if (Q_UNLIKELY(!extra || !extra->topextra || !extra->topextra->window)) {
- qWarning("Asking for share context for widget that does not have a window handle");
+ if (Q_UNLIKELY(!extra || !extra->topextra || !extra->topextra->window))
return 0;
- }
+
QWidgetPrivate *that = const_cast<QWidgetPrivate *>(this);
if (!extra->topextra->shareContext) {
QOpenGLContext *ctx = new QOpenGLContext;
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index a24d13e0e1..f1eefd68dd 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -73,19 +73,20 @@
#include "QtWidgets/qgraphicsview.h"
#endif
#include <private/qgesture_p.h>
+#include <qpa/qplatformbackingstore.h>
QT_BEGIN_NAMESPACE
// Extra QWidget data
// - to minimize memory usage for members that are seldom used.
// - top-level widgets have extra extra data to reduce cost further
+class QWidgetWindow;
class QPaintEngine;
class QPixmap;
class QWidgetBackingStore;
class QGraphicsProxyWidget;
class QWidgetItemV2;
class QOpenGLContext;
-class QPlatformTextureList;
class QStyle;
@@ -164,7 +165,7 @@ struct QTLWExtra {
QWidgetBackingStoreTracker backingStoreTracker;
QBackingStore *backingStore;
QPainter *sharedPainter;
- QWindow *window;
+ QWidgetWindow *window;
QOpenGLContext *shareContext;
// Implicit pointers (shared_null).
@@ -342,6 +343,7 @@ public:
QPainter *sharedPainter() const;
void setSharedPainter(QPainter *painter);
QWidgetBackingStore *maybeBackingStore() const;
+ QWidgetWindow *windowHandle() const;
void init(QWidget *desktopWidget, Qt::WindowFlags f);
void create_sys(WId window, bool initializeWindow, bool destroyOldWindow);
void createRecursively();
@@ -413,7 +415,7 @@ public:
QRect clipRect() const;
QRegion clipRegion() const;
- void setSystemClip(QPaintDevice *paintDevice, const QRegion &region);
+ void setSystemClip(QPaintEngine *paintEngine, qreal devicePixelRatio, const QRegion &region);
void subtractOpaqueChildren(QRegion &rgn, const QRect &clipRect) const;
void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove = 0,
bool alsoNonOpaque = false) const;
@@ -634,6 +636,12 @@ public:
#ifndef QT_NO_OPENGL
virtual GLuint textureId() const { return 0; }
+ virtual QPlatformTextureList::Flags textureListFlags() {
+ Q_Q(QWidget);
+ return q->testAttribute(Qt::WA_AlwaysStackOnTop)
+ ? QPlatformTextureList::StacksOnTop
+ : QPlatformTextureList::Flags(0);
+ }
virtual QImage grabFramebuffer() { return QImage(); }
virtual void beginBackingStorePainting() { }
virtual void endBackingStorePainting() { }
@@ -985,6 +993,13 @@ inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const
return x ? x->backingStoreTracker.data() : 0;
}
+inline QWidgetWindow *QWidgetPrivate::windowHandle() const
+{
+ if (QTLWExtra *x = maybeTopData())
+ return x->window;
+ return nullptr;
+}
+
QT_END_NAMESPACE
#endif // QWIDGET_P_H
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 57564ce477..bb421927db 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -77,11 +77,10 @@ Q_GLOBAL_STATIC(QPlatformTextureList, qt_dummy_platformTextureList)
/**
* Flushes the contents of the \a backingStore into the screen area of \a widget.
- * \a tlwOffset is the position of the top level widget relative to the window surface.
* \a region is the region to be updated in \a widget coordinates.
*/
void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion &region, QBackingStore *backingStore,
- QWidget *tlw, const QPoint &tlwOffset, QPlatformTextureList *widgetTextures,
+ QWidget *tlw, QPlatformTextureList *widgetTextures,
QWidgetBackingStore *widgetBackingStore)
{
#ifdef QT_NO_OPENGL
@@ -112,7 +111,7 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion &region, QBack
}
}
- QPoint offset = tlwOffset;
+ QPoint offset;
if (widget != tlw)
offset += widget->mapTo(tlw, QPoint());
@@ -288,8 +287,7 @@ void QWidgetBackingStore::unflushPaint(QWidget *widget, const QRegion &rgn)
if (!tlwExtra)
return;
- const QPoint offset = widget->mapTo(tlw, QPoint());
- qt_flush(widget, rgn, tlwExtra->backingStoreTracker->store, tlw, offset, 0, tlw->d_func()->maybeBackingStore());
+ qt_flush(widget, rgn, tlwExtra->backingStoreTracker->store, tlw, 0, tlw->d_func()->maybeBackingStore());
}
#endif // QT_NO_PAINT_DEBUG
@@ -299,7 +297,7 @@ void QWidgetBackingStore::unflushPaint(QWidget *widget, const QRegion &rgn)
*/
bool QWidgetBackingStore::bltRect(const QRect &rect, int dx, int dy, QWidget *widget)
{
- const QPoint pos(tlwOffset + widget->mapTo(tlw, rect.topLeft()));
+ const QPoint pos(widget->mapTo(tlw, rect.topLeft()));
const QRect tlwRect(QRect(pos, rect.size()));
if (dirty.intersects(tlwRect))
return false; // We don't want to scroll junk.
@@ -949,9 +947,7 @@ static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatfo
{
QWidgetPrivate *wd = QWidgetPrivate::get(widget);
if (wd->renderToTexture) {
- QPlatformTextureList::Flags flags = 0;
- if (widget->testAttribute(Qt::WA_AlwaysStackOnTop))
- flags |= QPlatformTextureList::StacksOnTop;
+ QPlatformTextureList::Flags flags = wd->textureListFlags();
const QRect rect(widget->mapTo(tlw, QPoint()), widget->size());
widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags);
}
@@ -1123,7 +1119,7 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
// Nothing to repaint.
if (!isDirty() && store->size().isValid()) {
QPlatformTextureList *tl = widgetTexturesFor(tlw, exposedWidget);
- qt_flush(exposedWidget, tl ? QRegion() : exposedRegion, store, tlw, tlwOffset, tl, this);
+ qt_flush(exposedWidget, tl ? QRegion() : exposedRegion, store, tlw, tl, this);
return;
}
@@ -1369,7 +1365,7 @@ void QWidgetBackingStore::doSync()
QRegion toBePainted(wd->dirty);
resetWidget(w);
- QPoint offset(tlwOffset);
+ QPoint offset;
if (w != tlw)
offset += w->mapTo(tlw, QPoint());
wd->drawWidget(store->paintDevice(), toBePainted, offset, flags, 0, this);
@@ -1378,7 +1374,7 @@ void QWidgetBackingStore::doSync()
// Paint the rest with composition.
if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
const int flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
- tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, tlwOffset, flags, 0, this);
+ tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, 0, this);
}
endPaint(toClean, store, &beginPaintInfo);
@@ -1397,7 +1393,7 @@ void QWidgetBackingStore::flush(QWidget *widget)
// Flush the region in dirtyOnScreen.
if (!dirtyOnScreen.isEmpty()) {
QWidget *target = widget ? widget : tlw;
- qt_flush(target, dirtyOnScreen, store, tlw, tlwOffset, widgetTexturesFor(tlw, tlw), this);
+ qt_flush(target, dirtyOnScreen, store, tlw, widgetTexturesFor(tlw, tlw), this);
dirtyOnScreen = QRegion();
flushed = true;
}
@@ -1409,7 +1405,7 @@ void QWidgetBackingStore::flush(QWidget *widget)
QPlatformTextureList *tl = widgetTexturesFor(tlw, tlw);
if (tl) {
QWidget *target = widget ? widget : tlw;
- qt_flush(target, QRegion(), store, tlw, tlwOffset, tl, this);
+ qt_flush(target, QRegion(), store, tlw, tl, this);
}
}
#endif
@@ -1423,7 +1419,7 @@ void QWidgetBackingStore::flush(QWidget *widget)
QWidgetPrivate *wd = w->d_func();
Q_ASSERT(wd->needsFlush);
QPlatformTextureList *widgetTexturesForNative = wd->textureChildSeen ? widgetTexturesFor(tlw, w) : 0;
- qt_flush(w, *wd->needsFlush, store, tlw, tlwOffset, widgetTexturesForNative, this);
+ qt_flush(w, *wd->needsFlush, store, tlw, widgetTexturesForNative, this);
*wd->needsFlush = QRegion();
}
dirtyOnScreenWidgets->clear();
diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h
index fa51cb71de..53ccda850a 100644
--- a/src/widgets/kernel/qwidgetbackingstore_p.h
+++ b/src/widgets/kernel/qwidgetbackingstore_p.h
@@ -111,8 +111,6 @@ public:
void sync();
void flush(QWidget *widget = 0);
- inline QPoint topLevelOffset() const { return tlwOffset; }
-
QBackingStore *backingStore() const { return store; }
inline bool isDirty() const
@@ -138,8 +136,6 @@ private:
QBackingStore *store;
uint updateRequestSent : 1;
- QPoint tlwOffset;
-
QPlatformTextureListWatcher *textureListWatcher;
QElapsedTimer perfTime;
int perfFrames;
@@ -149,7 +145,7 @@ private:
static bool flushPaint(QWidget *widget, const QRegion &rgn);
static void unflushPaint(QWidget *widget, const QRegion &rgn);
static void qt_flush(QWidget *widget, const QRegion &region, QBackingStore *backingStore,
- QWidget *tlw, const QPoint &tlwOffset,
+ QWidget *tlw,
QPlatformTextureList *widgetTextures,
QWidgetBackingStore *widgetBackingStore);
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index abaebad821..d5d4ae844b 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets();
-QWidget *qt_button_down = 0; // widget got last button-down
+Q_WIDGETS_EXPORT QWidget *qt_button_down = 0; // widget got last button-down
// popup control
QWidget *qt_popup_down = 0; // popup that contains the pressed widget
@@ -69,6 +69,15 @@ class QWidgetWindowPrivate : public QWindowPrivate
{
Q_DECLARE_PUBLIC(QWidgetWindow)
public:
+ void setVisible(bool visible) override
+ {
+ Q_Q(QWidgetWindow);
+ if (QWidget *widget = q->widget())
+ widget->setVisible(visible);
+ else
+ QWindowPrivate::setVisible(visible);
+ }
+
QWindow *eventReceiver() Q_DECL_OVERRIDE {
Q_Q(QWidgetWindow);
QWindow *w = q;
@@ -168,6 +177,15 @@ QObject *QWidgetWindow::focusObject() const
return widget;
}
+void QWidgetWindow::setNativeWindowVisibility(bool visible)
+{
+ Q_D(QWidgetWindow);
+ // Call base class setVisible() implementation to run the QWindow
+ // visibility logic. Don't call QWidgetWindowPrivate::setVisible()
+ // since that will recurse back into QWidget code.
+ d->QWindowPrivate::setVisible(visible);
+}
+
static inline bool shouldBePropagatedToWidget(QEvent *event)
{
switch (event->type()) {
@@ -194,7 +212,7 @@ bool QWidgetWindow::event(QEvent *event)
// generated before WA_DontShowOnScreen was set
if (!shouldBePropagatedToWidget(event))
return true;
- return QCoreApplication::sendEvent(m_widget, event);
+ return QCoreApplication::forwardEvent(m_widget, event);
}
switch (event->type()) {
@@ -226,7 +244,7 @@ bool QWidgetWindow::event(QEvent *event)
if (QApplicationPrivate::focus_widget->testAttribute(Qt::WA_InputMethodEnabled))
QGuiApplication::inputMethod()->commit();
- QGuiApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, event);
+ QGuiApplication::forwardEvent(QApplicationPrivate::focus_widget, event);
}
return true;
@@ -295,7 +313,7 @@ bool QWidgetWindow::event(QEvent *event)
case QEvent::ThemeChange: {
QEvent widgetEvent(QEvent::ThemeChange);
- QGuiApplication::sendSpontaneousEvent(m_widget, &widgetEvent);
+ QCoreApplication::forwardEvent(m_widget, &widgetEvent, event);
}
return true;
@@ -333,7 +351,7 @@ bool QWidgetWindow::event(QEvent *event)
break;
}
- if (shouldBePropagatedToWidget(event) && QCoreApplication::sendEvent(m_widget, event))
+ if (shouldBePropagatedToWidget(event) && QCoreApplication::forwardEvent(m_widget, event))
return true;
return QWindow::event(event);
@@ -442,7 +460,7 @@ void QWidgetWindow::handleFocusInEvent(QFocusEvent *e)
void QWidgetWindow::handleNonClientAreaMouseEvent(QMouseEvent *e)
{
- QApplication::sendSpontaneousEvent(m_widget, e);
+ QApplication::forwardEvent(m_widget, e);
}
void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
@@ -567,13 +585,13 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
} else if (event->type() == contextMenuTrigger
&& event->button() == Qt::RightButton
&& (openPopupCount == oldOpenPopupCount)) {
- QWidget *popupEvent = activePopupWidget;
+ QWidget *receiver = activePopupWidget;
if (qt_button_down)
- popupEvent = qt_button_down;
+ receiver = qt_button_down;
else if(popupChild)
- popupEvent = popupChild;
+ receiver = popupChild;
QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
- QApplication::sendSpontaneousEvent(popupEvent, &e);
+ QApplication::forwardEvent(receiver, &e, event);
}
#else
Q_UNUSED(contextMenuTrigger)
@@ -626,7 +644,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
if (event->type() == contextMenuTrigger && event->button() == Qt::RightButton
&& m_widget->rect().contains(event->pos())) {
QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
- QGuiApplication::sendSpontaneousEvent(receiver, &e);
+ QGuiApplication::forwardEvent(receiver, &e, event);
}
#endif
}
@@ -658,7 +676,7 @@ void QWidgetWindow::handleKeyEvent(QKeyEvent *event)
}
if (!receiver)
receiver = focusObject();
- QGuiApplication::sendSpontaneousEvent(receiver, event);
+ QGuiApplication::forwardEvent(receiver, event);
}
bool QWidgetWindow::updateSize()
@@ -730,8 +748,6 @@ void QWidgetWindow::repaintWindow()
QWidgetBackingStore::UpdateNow, QWidgetBackingStore::BufferInvalid);
}
-Qt::WindowState effectiveState(Qt::WindowStates state);
-
// Store normal geometry used for saving application settings.
void QWidgetWindow::updateNormalGeometry()
{
@@ -742,7 +758,7 @@ void QWidgetWindow::updateNormalGeometry()
QRect normalGeometry;
if (const QPlatformWindow *pw = handle())
normalGeometry = QHighDpi::fromNativePixels(pw->normalGeometry(), this);
- if (!normalGeometry.isValid() && effectiveState(m_widget->windowState()) == Qt::WindowNoState)
+ if (!normalGeometry.isValid() && !(m_widget->windowState() & ~Qt::WindowActive))
normalGeometry = m_widget->geometry();
if (normalGeometry.isValid())
tle->normalGeometry = normalGeometry;
@@ -751,7 +767,7 @@ void QWidgetWindow::updateNormalGeometry()
void QWidgetWindow::handleMoveEvent(QMoveEvent *event)
{
if (updatePos())
- QGuiApplication::sendSpontaneousEvent(m_widget, event);
+ QGuiApplication::forwardEvent(m_widget, event);
}
void QWidgetWindow::handleResizeEvent(QResizeEvent *event)
@@ -759,7 +775,7 @@ void QWidgetWindow::handleResizeEvent(QResizeEvent *event)
QSize oldSize = m_widget->data->crect.size();
if (updateSize()) {
- QGuiApplication::sendSpontaneousEvent(m_widget, event);
+ QGuiApplication::forwardEvent(m_widget, event);
if (m_widget->d_func()->paintOnScreen()) {
QRegion updateRegion(geometry());
@@ -805,7 +821,7 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
QPoint mapped = widget->mapFrom(rootWidget, pos);
QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted());
- QGuiApplication::sendSpontaneousEvent(widget, &translated);
+ QGuiApplication::forwardEvent(widget, &translated, event);
}
#endif // QT_CONFIG(wheelevent)
@@ -832,7 +848,7 @@ void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event)
translated.accept();
translated.setDropAction(event->dropAction());
}
- QGuiApplication::sendSpontaneousEvent(widget, &translated);
+ QGuiApplication::forwardEvent(widget, &translated, event);
if (translated.isAccepted()) {
event->accept();
} else {
@@ -844,7 +860,7 @@ void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event)
// Target widget changed: Send DragLeave to previous, DragEnter to new if there is any
if (m_dragTarget.data()) {
QDragLeaveEvent le;
- QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), &le);
+ QGuiApplication::forwardEvent(m_dragTarget.data(), &le, event);
m_dragTarget = 0;
}
if (!widget) {
@@ -854,7 +870,7 @@ void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event)
m_dragTarget = widget;
const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
QDragEnterEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
- QGuiApplication::sendSpontaneousEvent(widget, &translated);
+ QGuiApplication::forwardEvent(widget, &translated, event);
if (translated.isAccepted()) {
event->accept();
} else {
@@ -866,7 +882,7 @@ void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event)
void QWidgetWindow::handleDragLeaveEvent(QDragLeaveEvent *event)
{
if (m_dragTarget)
- QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), event);
+ QGuiApplication::forwardEvent(m_dragTarget.data(), event);
m_dragTarget = 0;
}
@@ -879,7 +895,7 @@ void QWidgetWindow::handleDropEvent(QDropEvent *event)
}
const QPoint mapped = m_dragTarget.data()->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
QDropEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
- QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), &translated);
+ QGuiApplication::forwardEvent(m_dragTarget.data(), &translated, event);
if (translated.isAccepted())
event->accept();
event->setDropAction(translated.dropAction());
@@ -902,7 +918,7 @@ void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
// ... and they haven't been shown by this function yet - show it.
wPriv->showChildren(true);
QShowEvent showEvent;
- QCoreApplication::sendSpontaneousEvent(m_widget, &showEvent);
+ QCoreApplication::forwardEvent(m_widget, &showEvent, event);
wPriv->childrenShownByExpose = true;
}
} else {
@@ -914,7 +930,7 @@ void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
// and then, the QPA can send next expose event with null exposed region (not exposed).
wPriv->hideChildren(true);
QHideEvent hideEvent;
- QCoreApplication::sendSpontaneousEvent(m_widget, &hideEvent);
+ QCoreApplication::forwardEvent(m_widget, &hideEvent, event);
wPriv->childrenShownByExpose = false;
}
}
@@ -934,30 +950,18 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event
// QWindow does currently not know 'active'.
Qt::WindowStates eventState = event->oldState();
Qt::WindowStates widgetState = m_widget->windowState();
+ Qt::WindowStates windowState = windowStates();
if (widgetState & Qt::WindowActive)
eventState |= Qt::WindowActive;
// Determine the new widget state, remember maximized/full screen
// during minimized.
- switch (windowState()) {
- case Qt::WindowNoState:
- widgetState &= ~(Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen);
- break;
- case Qt::WindowMinimized:
+ if (windowState & Qt::WindowMinimized) {
widgetState |= Qt::WindowMinimized;
- break;
- case Qt::WindowMaximized:
- updateNormalGeometry();
- widgetState |= Qt::WindowMaximized;
- widgetState &= ~(Qt::WindowMinimized | Qt::WindowFullScreen);
- break;
- case Qt::WindowFullScreen:
- updateNormalGeometry();
- widgetState |= Qt::WindowFullScreen;
- widgetState &= ~(Qt::WindowMinimized);
- break;
- case Qt::WindowActive: // Not handled by QWindow
- break;
+ } else {
+ widgetState = windowState | (widgetState & Qt::WindowActive);
+ if (windowState) // Maximized or FullScreen
+ updateNormalGeometry();
}
// Sent event if the state changed (that is, it is not triggered by
@@ -965,7 +969,7 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event
if (widgetState != Qt::WindowStates::Int(m_widget->data->window_state)) {
m_widget->data->window_state = uint(widgetState);
QWindowStateChangeEvent widgetEvent(eventState);
- QGuiApplication::sendSpontaneousEvent(m_widget, &widgetEvent);
+ QGuiApplication::forwardEvent(m_widget, &widgetEvent, event);
}
}
@@ -997,7 +1001,7 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
event->pressure(), event->xTilt(), event->yTilt(), event->tangentialPressure(),
event->rotation(), event->z(), event->modifiers(), event->uniqueId(), event->button(), event->buttons());
ev.setTimestamp(event->timestamp());
- QGuiApplication::sendSpontaneousEvent(widget, &ev);
+ QGuiApplication::forwardEvent(widget, &ev, event);
event->setAccepted(ev.isAccepted());
}
@@ -1021,7 +1025,7 @@ void QWidgetWindow::handleGestureEvent(QNativeGestureEvent *e)
if (!receiver)
receiver = m_widget; // last resort
- QApplication::sendSpontaneousEvent(receiver, e);
+ QApplication::forwardEvent(receiver, e);
}
#endif // QT_NO_GESTURES
@@ -1049,7 +1053,7 @@ void QWidgetWindow::handleContextMenuEvent(QContextMenuEvent *e)
QPoint pos = fw->inputMethodQuery(Qt::ImMicroFocus).toRect().center();
QContextMenuEvent widgetEvent(QContextMenuEvent::Keyboard, pos, fw->mapToGlobal(pos),
e->modifiers());
- QGuiApplication::sendSpontaneousEvent(fw, &widgetEvent);
+ QGuiApplication::forwardEvent(fw, &widgetEvent, e);
}
}
#endif // QT_NO_CONTEXTMENU
diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h
index 50a2cfd57c..be3f808a22 100644
--- a/src/widgets/kernel/qwidgetwindow_p.h
+++ b/src/widgets/kernel/qwidgetwindow_p.h
@@ -63,10 +63,12 @@ QT_BEGIN_NAMESPACE
class QCloseEvent;
class QMoveEvent;
+class QWidgetWindowPrivate;
class QWidgetWindow : public QWindow
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QWidgetWindow)
public:
QWidgetWindow(QWidget *widget);
~QWidgetWindow();
@@ -77,6 +79,7 @@ public:
#endif
QObject *focusObject() const Q_DECL_OVERRIDE;
+ void setNativeWindowVisibility(bool visible);
protected:
bool event(QEvent *) Q_DECL_OVERRIDE;
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index 7ae63e54b3..a17c69c5ce 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -337,6 +337,19 @@ bool QWindowContainer::event(QEvent *e)
e->accept();
return true;
#endif
+
+ case QEvent::Paint:
+ {
+ static bool needsPunch = !QGuiApplicationPrivate::platformIntegration()->hasCapability(
+ QPlatformIntegration::TopStackedNativeChildWindows);
+ if (needsPunch) {
+ QPainter p(this);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(rect(), Qt::transparent);
+ }
+ break;
+ }
+
default:
break;
}