Bug#1107346: unblock: kf6-kwindowsystem/6.13.0-2
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: kf6-kwindowsystem@packages.debian.org, Debian Qt/KDE Maintainers <debian-qt-kde@lists.debian.org>
Control: affects -1 + src:kf6-kwindowsystem
User: release.debian.org@packages.debian.org
Usertags: unblock
Dear Release Team,
please unblock package kf6-kwindowsystem.
[ Reason ]
It contains the following changes:
* Backport upstream commits:
- Ensure portal file picker is modal to fix various UX issues.
(kde#493647)
[ Tests ]
Tested locally.
[ Risks ]
Only backport of upstream commits that apply cleanly. Further fixes can
easily be backported or the changes reverted.
[ Checklist ]
[x] all changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in testing
Thanks!
unblock kf6-kwindowsystem/6.13.0-2
diff -Nru kf6-kwindowsystem-6.13.0/debian/changelog kf6-kwindowsystem-6.13.0/debian/changelog
--- kf6-kwindowsystem-6.13.0/debian/changelog 2025-04-12 19:33:33.000000000 +0200
+++ kf6-kwindowsystem-6.13.0/debian/changelog 2025-05-17 01:16:58.000000000 +0200
@@ -1,3 +1,12 @@
+kf6-kwindowsystem (6.13.0-2) unstable; urgency=medium
+
+ [ Aurélien COUDERC ]
+ * Backport upstream commits:
+ - Ensure portal file picker is modal to fix various UX issues.
+ (kde#493647)
+
+ -- Aurélien COUDERC <coucouf@debian.org> Sat, 17 May 2025 01:16:58 +0200
+
kf6-kwindowsystem (6.13.0-1) unstable; urgency=medium
[ Patrick Franz ]
diff -Nru kf6-kwindowsystem-6.13.0/debian/patches/series kf6-kwindowsystem-6.13.0/debian/patches/series
--- kf6-kwindowsystem-6.13.0/debian/patches/series 1970-01-01 01:00:00.000000000 +0100
+++ kf6-kwindowsystem-6.13.0/debian/patches/series 2025-05-13 18:33:02.000000000 +0200
@@ -0,0 +1 @@
+upstream_daa3cda4_Wayland-Set-XDG-dialog-modal-in-setMainWindow-when-applicable.patch
diff -Nru kf6-kwindowsystem-6.13.0/debian/patches/upstream_daa3cda4_Wayland-Set-XDG-dialog-modal-in-setMainWindow-when-applicable.patch kf6-kwindowsystem-6.13.0/debian/patches/upstream_daa3cda4_Wayland-Set-XDG-dialog-modal-in-setMainWindow-when-applicable.patch
--- kf6-kwindowsystem-6.13.0/debian/patches/upstream_daa3cda4_Wayland-Set-XDG-dialog-modal-in-setMainWindow-when-applicable.patch 1970-01-01 01:00:00.000000000 +0100
+++ kf6-kwindowsystem-6.13.0/debian/patches/upstream_daa3cda4_Wayland-Set-XDG-dialog-modal-in-setMainWindow-when-applicable.patch 2025-05-13 18:33:02.000000000 +0200
@@ -0,0 +1,218 @@
+From daa3cda4d4831b692f504f98aa6eeddabceb64a1 Mon Sep 17 00:00:00 2001
+From: Kai Uwe Broulik <kde@privat.broulik.de>
+Date: Sun, 6 Apr 2025 16:51:36 +0200
+Subject: [PATCH] Wayland: Set XDG dialog modal in setMainWindow when
+ applicable
+
+Before Qt 6.10, Qt's built-in XDG Dialog support only sets modal when
+it has an in-process transient parent. It wouldn't know that we'll be
+setting a parent through XDG Foreign afterwards.
+
+Have setMainWindow check for Qt version and window modality and use
+XDG Dialog to make the parent-child relationship modal.
+
+BUG: 493647
+---
+ src/platforms/wayland/CMakeLists.txt | 3 ++
+ src/platforms/wayland/surfacehelper.h | 15 ++++++
+ src/platforms/wayland/waylandxdgdialogv1.cpp | 48 ++++++++++++++++++++
+ src/platforms/wayland/waylandxdgdialogv1_p.h | 36 +++++++++++++++
+ src/platforms/wayland/windowsystem.cpp | 15 ++++++
+ 5 files changed, 117 insertions(+)
+ create mode 100644 src/platforms/wayland/waylandxdgdialogv1.cpp
+ create mode 100644 src/platforms/wayland/waylandxdgdialogv1_p.h
+
+diff --git a/src/platforms/wayland/CMakeLists.txt b/src/platforms/wayland/CMakeLists.txt
+index 545f920c..26ff123b 100644
+--- a/src/platforms/wayland/CMakeLists.txt
++++ b/src/platforms/wayland/CMakeLists.txt
+@@ -6,6 +6,7 @@ set(wayland_plugin_SRCS
+ windowshadow.cpp
+ windowsystem.cpp
+ waylandxdgactivationv1.cpp
++ waylandxdgdialogv1.cpp
+ waylandxdgforeignv2.cpp
+ plugin.h
+ windoweffects.h
+@@ -23,6 +24,8 @@ qt6_generate_wayland_protocol_client_sources(KF6WindowSystemKWaylandPlugin
+ FILES
+ ${WaylandProtocols_DATADIR}/staging/xdg-activation/xdg-activation-v1.xml
+ ${WaylandProtocols_DATADIR}/unstable/xdg-foreign/xdg-foreign-unstable-v2.xml
++ ${WaylandProtocols_DATADIR}/staging/xdg-dialog/xdg-dialog-v1.xml
++ ${WaylandProtocols_DATADIR}/stable/xdg-shell/xdg-shell.xml
+ ${PLASMA_WAYLAND_PROTOCOLS_DIR}/blur.xml
+ ${PLASMA_WAYLAND_PROTOCOLS_DIR}/contrast.xml
+ ${PLASMA_WAYLAND_PROTOCOLS_DIR}/slide.xml
+diff --git a/src/platforms/wayland/surfacehelper.h b/src/platforms/wayland/surfacehelper.h
+index ba2f7cb5..3cc22e45 100644
+--- a/src/platforms/wayland/surfacehelper.h
++++ b/src/platforms/wayland/surfacehelper.h
+@@ -14,6 +14,7 @@
+ #include <qpa/qplatformnativeinterface.h>
+
+ struct wl_surface;
++struct xdg_toplevel;
+
+ inline wl_surface *surfaceForWindow(QWindow *window)
+ {
+@@ -38,3 +39,17 @@ inline wl_surface *surfaceForWindow(QWindow *window)
+
+ return reinterpret_cast<wl_surface *>(native->nativeResourceForWindow(QByteArrayLiteral("surface"), window));
+ }
++
++inline xdg_toplevel *xdgToplevelForWindow(QWindow *window)
++{
++ if (!window) {
++ return nullptr;
++ }
++
++ QPlatformNativeInterface *native = qGuiApp->platformNativeInterface();
++ if (!native) {
++ return nullptr;
++ }
++
++ return reinterpret_cast<xdg_toplevel *>(native->nativeResourceForWindow(QByteArrayLiteral("xdg_toplevel"), window));
++}
+diff --git a/src/platforms/wayland/waylandxdgdialogv1.cpp b/src/platforms/wayland/waylandxdgdialogv1.cpp
+new file mode 100644
+index 00000000..828786ab
+--- /dev/null
++++ b/src/platforms/wayland/waylandxdgdialogv1.cpp
+@@ -0,0 +1,48 @@
++/*
++ SPDX-FileCopyrightText: 2025 Kai Uwe Broulik <kde@broulik.de>
++
++ SPDX-License-Identifier: LGPL-2.0-or-later
++*/
++
++#include "waylandxdgdialogv1_p.h"
++
++#include <QGuiApplication>
++
++WaylandXdgDialogV1::WaylandXdgDialogV1(::xdg_dialog_v1 *object)
++ : QObject()
++ , QtWayland::xdg_dialog_v1(object)
++{
++}
++
++WaylandXdgDialogV1::~WaylandXdgDialogV1()
++{
++ if (qGuiApp) {
++ destroy();
++ }
++}
++
++WaylandXdgDialogWmV1::WaylandXdgDialogWmV1()
++ : QWaylandClientExtensionTemplate<WaylandXdgDialogWmV1>(1)
++{
++ initialize();
++}
++
++WaylandXdgDialogWmV1::~WaylandXdgDialogWmV1()
++{
++ if (qGuiApp && isActive()) {
++ destroy();
++ }
++}
++
++WaylandXdgDialogWmV1 &WaylandXdgDialogWmV1::self()
++{
++ static WaylandXdgDialogWmV1 s_instance;
++ return s_instance;
++}
++
++WaylandXdgDialogV1 *WaylandXdgDialogWmV1::getDialog(struct ::xdg_toplevel *toplevel)
++{
++ return new WaylandXdgDialogV1(get_xdg_dialog(toplevel));
++}
++
++#include "moc_waylandxdgdialogv1_p.cpp"
+diff --git a/src/platforms/wayland/waylandxdgdialogv1_p.h b/src/platforms/wayland/waylandxdgdialogv1_p.h
+new file mode 100644
+index 00000000..9ec7c2bf
+--- /dev/null
++++ b/src/platforms/wayland/waylandxdgdialogv1_p.h
+@@ -0,0 +1,36 @@
++/*
++ SPDX-FileCopyrightText: 2025 Kai Uwe Broulik <kde@broulik.de>
++
++ SPDX-License-Identifier: LGPL-2.0-or-later
++*/
++
++#ifndef WAYLANDXDGDIALOGV1_P_H
++#define WAYLANDXDGDIALOGV1_P_H
++
++#include "qwayland-xdg-dialog-v1.h"
++
++#include <QObject>
++#include <QtWaylandClient/QWaylandClientExtension>
++
++class WaylandXdgDialogV1 : public QObject, public QtWayland::xdg_dialog_v1
++{
++ Q_OBJECT
++public:
++ explicit WaylandXdgDialogV1(::xdg_dialog_v1 *object);
++ ~WaylandXdgDialogV1() override;
++};
++
++class WaylandXdgDialogWmV1 : public QWaylandClientExtensionTemplate<WaylandXdgDialogWmV1>, public QtWayland::xdg_wm_dialog_v1
++{
++public:
++ ~WaylandXdgDialogWmV1() override;
++
++ static WaylandXdgDialogWmV1 &self();
++
++ WaylandXdgDialogV1 *getDialog(struct ::xdg_toplevel *toplevel);
++
++private:
++ WaylandXdgDialogWmV1();
++};
++
++#endif // WAYLANDXDGDIALOGV1_P_H
+diff --git a/src/platforms/wayland/windowsystem.cpp b/src/platforms/wayland/windowsystem.cpp
+index e027bf96..bc44af0b 100644
+--- a/src/platforms/wayland/windowsystem.cpp
++++ b/src/platforms/wayland/windowsystem.cpp
+@@ -8,6 +8,7 @@
+ #include "logging.h"
+ #include "surfacehelper.h"
+ #include "waylandxdgactivationv1_p.h"
++#include "waylandxdgdialogv1_p.h"
+ #include "waylandxdgforeignv2_p.h"
+
+ #include <KWaylandExtras>
+@@ -16,10 +17,12 @@
+ #include "qwayland-plasma-window-management.h"
+ #include <QEvent>
+ #include <QGuiApplication>
++#include <QLibraryInfo>
+ #include <QPixmap>
+ #include <QPoint>
+ #include <QString>
+ #include <QTimer>
++#include <QVersionNumber>
+ #include <QWaylandClientExtensionTemplate>
+ #include <QWindow>
+ #include <qpa/qplatformnativeinterface.h>
+@@ -284,6 +287,18 @@ void WindowSystem::doSetMainWindow(QWindow *window, const QString &handle)
+ connect(imported, &QObject::destroyed, waylandWindow, [waylandWindow] {
+ waylandWindow->setProperty(c_kdeXdgForeignImportedProperty, QVariant());
+ });
++
++ // Before Qt 6.10, Qt sets XDG Dialog modal only when it has a transient parent.
++ if (window->modality() != Qt::NonModal && QLibraryInfo::version() < QVersionNumber(6, 10, 0)) {
++ auto &xdgDialog = WaylandXdgDialogWmV1::self();
++ if (xdgDialog.isActive()) {
++ if (auto *xdgToplevel = xdgToplevelForWindow(window)) {
++ auto *dialog = xdgDialog.getDialog(xdgToplevel);
++ dialog->set_modal();
++ dialog->setParent(waylandWindow);
++ }
++ }
++ }
+ }
+
+ #include "moc_windowsystem.cpp"
+--
+GitLab
+
Reply to: