diff options
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r-- | src/widgets/kernel/qaction.cpp | 45 | ||||
-rw-r--r-- | src/widgets/kernel/qaction.h | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qaction_p.h | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qboxlayout.cpp | 28 | ||||
-rw-r--r-- | src/widgets/kernel/qopenglwidget.cpp | 84 | ||||
-rw-r--r-- | src/widgets/kernel/qopenglwidget.h | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 20 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 8 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetbackingstore.cpp | 4 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 28 | ||||
-rw-r--r-- | src/widgets/kernel/qwindowcontainer.cpp | 13 |
11 files changed, 168 insertions, 71 deletions
diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index 4582a55394..130c354132 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) { @@ -1276,8 +1278,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(); } } @@ -1292,6 +1293,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 97948a2457..d211016931 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 8ee71a5ff0..6813ca08f6 100644 --- a/src/widgets/kernel/qaction_p.h +++ b/src/widgets/kernel/qaction_p.h @@ -105,7 +105,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/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/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 23948892f0..e401444e6e 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(); } @@ -581,6 +582,7 @@ public: void recreateFbo(); GLuint textureId() const Q_DECL_OVERRIDE; + QPlatformTextureList::Flags textureListFlags() Q_DECL_OVERRIDE; void initialize(); void invokeUserPaint(); @@ -611,6 +613,7 @@ public: QOpenGLWidget::UpdateBehavior updateBehavior; int requestedSamples; bool inPaintGL; + GLenum textureFormat; }; void QOpenGLWidgetPaintDevicePrivate::beginPaint() @@ -668,6 +671,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); @@ -717,12 +749,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); @@ -781,7 +817,9 @@ void QOpenGLWidgetPrivate::initialize() return; } - // Propagate settings that make sense only for the tlw. + // 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. QSurfaceFormat tlwFormat = tlw->windowHandle()->format(); if (requestedFormat.swapInterval() != tlwFormat.swapInterval()) { // Most platforms will pick up the changed swap interval on the next @@ -1004,7 +1042,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"); @@ -1037,6 +1074,47 @@ QSurfaceFormat QOpenGLWidget::format() const } /*! + Sets a custom internal texture format. + + 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. 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 b166cfe271..1452bb36ae 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" @@ -3038,17 +3037,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) @@ -3090,19 +3078,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; diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 68e063c25a..858328e618 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -69,6 +69,7 @@ #include "QtWidgets/qgraphicsscene.h" #include "QtWidgets/qgraphicsview.h" #include <private/qgesture_p.h> +#include <qpa/qplatformbackingstore.h> QT_BEGIN_NAMESPACE @@ -81,7 +82,6 @@ class QWidgetBackingStore; class QGraphicsProxyWidget; class QWidgetItemV2; class QOpenGLContext; -class QPlatformTextureList; class QStyle; @@ -630,6 +630,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() { } diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 781ad9600d..4421218d1d 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -945,9 +945,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); } diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 31f2d672bb..44fd4b6a80 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -726,8 +726,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() { @@ -738,7 +736,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; @@ -930,30 +928,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 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; } |