From d8bfd812c3383e24196588f5d3e1de4719fcac02 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 19 May 2015 12:36:55 +0200 Subject: D-Bus system tray icon: submenus can be created after context menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QMenuPrivate::init() calls QPlatformTheme::createPlatformMenu() to create a platform menu, but on Linux, that returns null for now. QSystemTrayIcon::setContextMenu() results in recursive calls to QSystemTrayIconPrivate::addPlatformMenu() which then calls QDBusTrayIcon::createMenu() for the context menu and each submenu. However if a submenu is added afterwards, a corresponding platform menu is not immediately created. Now copyActionToPlatformItem() will detect and create the missing platform submenu, by calling a new method: DBusPlatformMenu::createSubMenu(). This is because there is no way of knowing that it's a tray-specific context menu (which is so far the only case in which we use DBusPlatformMenu). So, QPlatformMenu::createSubMenu() needs to exist as a new QPA interface for this use case. Task-number: QTBUG-45803 Change-Id: Ib319e873082196515ea0580d70d069099cf2c175 Reviewed-by: Jørgen Lind --- src/platformsupport/dbusmenu/qdbusplatformmenu.cpp | 9 ++++++++- src/platformsupport/dbusmenu/qdbusplatformmenu_p.h | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src/platformsupport') diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp index 93c822cefb..a64e107e71 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -75,6 +75,9 @@ void QDBusPlatformMenuItem::setIcon(const QIcon &icon) m_icon = icon; } +/*! + Set a submenu under this menu item. +*/ void QDBusPlatformMenuItem::setMenu(QPlatformMenu *menu) { m_subMenu = static_cast(menu); @@ -242,8 +245,12 @@ const QList QDBusPlatformMenu::items() const QPlatformMenuItem *QDBusPlatformMenu::createMenuItem() const { QDBusPlatformMenuItem *ret = new QDBusPlatformMenuItem(); - ret->setMenu(const_cast(this)); return ret; } +QPlatformMenu *QDBusPlatformMenu::createSubMenu() const +{ + return new QDBusPlatformMenu; +} + QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h index 2519533e32..16bb4f195c 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h @@ -124,7 +124,7 @@ public: quintptr tag()const Q_DECL_OVERRIDE { return m_tag; } void setTag(quintptr tag) Q_DECL_OVERRIDE; - const QString text() { return m_text; } + const QString text() const { return m_text; } void setText(const QString &text) Q_DECL_OVERRIDE; void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; void setEnabled(bool enabled) Q_DECL_OVERRIDE; @@ -150,6 +150,7 @@ public: const QList items() const; QPlatformMenuItem *createMenuItem() const Q_DECL_OVERRIDE; + QPlatformMenu *createSubMenu() const Q_DECL_OVERRIDE; bool operator==(const QDBusPlatformMenu& other) { return m_tag == other.m_tag; } @@ -175,6 +176,7 @@ private: uint m_revision; QHash m_itemsByTag; QList m_items; + QDBusPlatformMenuItem *m_containingMenuItem; static QList m_topLevelMenus; }; -- cgit v1.2.3 From 78e335408303380310dd59fab421e495cf517ead Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 1 Jun 2015 11:44:37 +0200 Subject: Clip QOpenGLWidget and QQuickWidget correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce support for the widgets' clipRect(). Right now render-to-texture widgets in scroll areas placed close to each other result in broken (non-existent) clipping. Similarly, stack-on-top widgets fail to clip when placed inside a scroll area. This is now corrected and the qopenglwidget example is enhanced to utilize a scroll area. Task-number: QTBUG-45860 Change-Id: I859a63d61a50d64ba9e87244f83c5969dce12337 Reviewed-by: Jørgen Lind --- .../platformcompositor/qopenglcompositor.cpp | 31 +++++++++++++++++++--- .../qopenglcompositorbackingstore.cpp | 3 ++- 2 files changed, 29 insertions(+), 5 deletions(-) (limited to 'src/platformsupport') diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp index 3fd6c999a2..2e386532e2 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp @@ -169,6 +169,29 @@ struct BlendStateBinder bool m_blend; }; +static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) +{ + return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1, + topLeftRect.width(), topLeftRect.height()); +} + +static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter) +{ + const QRect rectInWindow = textures->geometry(idx); + QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); + const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); + + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(clippedRectInWindow, targetWindowRect); + const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect, rectInWindow.size(), + QOpenGLTextureBlitter::OriginBottomLeft); + + blitter->blit(textures->textureId(idx), target, source); +} + void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) { const QPlatformTextureList *textures = window->textures(); @@ -181,7 +204,6 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) for (int i = 0; i < textures->count(); ++i) { uint textureId = textures->textureId(i); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); const float opacity = window->sourceWindow()->opacity(); if (opacity != currentOpacity) { currentOpacity = opacity; @@ -191,24 +213,25 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) if (textures->count() > 1 && i == textures->count() - 1) { // Backingstore for a widget with QOpenGLWidget subwidgets blend.set(true); + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); } else if (textures->count() == 1) { // A regular QWidget window const bool translucent = window->sourceWindow()->requestedFormat().alphaBufferSize() > 0; blend.set(translucent); + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); } else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { // Texture from an FBO belonging to a QOpenGLWidget blend.set(false); - m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft); + clippedBlit(textures, i, targetWindowRect, &m_blitter); } } for (int i = 0; i < textures->count(); ++i) { if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); blend.set(true); - m_blitter.blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); + clippedBlit(textures, i, targetWindowRect, &m_blitter); } } diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 3caec468a6..4cf64e61da 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -175,7 +175,8 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi m_textures->clear(); for (int i = 0; i < textures->count(); ++i) - m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), textures->flags(i)); + m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), + textures->clipRect(i), textures->flags(i)); updateTexture(); m_textures->appendTexture(Q_NULLPTR, m_bsTexture, window->geometry()); -- cgit v1.2.3 From 0e1b4e896fba50ce6603bc323b2940e6859e7421 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 1 Jun 2015 15:23:19 +0200 Subject: Avoid QWidget dependency in QtGui MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not a real dependency as all we need is to store a pointer, but better not to use the name QWidget at all. Change-Id: I30ef1dd44ac7e42c1b9c84675f94088b8c516076 Reviewed-by: Jørgen Lind --- .../platformcompositor/qopenglcompositorbackingstore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/platformsupport') diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 4cf64e61da..8ce1ed2d2b 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -175,7 +175,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi m_textures->clear(); for (int i = 0; i < textures->count(); ++i) - m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), + m_textures->appendTexture(textures->source(i), textures->textureId(i), textures->geometry(i), textures->clipRect(i), textures->flags(i)); updateTexture(); -- cgit v1.2.3