Control: tags -1 moreinfo

On 2025-06-06 00:45:10 +0200, Aurélien COUDERC wrote:
> Package: release.debian.org
> Severity: normal
> X-Debbugs-Cc: kf6-...@packages.debian.org, Debian Qt/KDE Maintainers 
> <debian-qt-...@lists.debian.org>
> Control: affects -1 + src:kf6-kio
> User: release.debian....@packages.debian.org
> Usertags: unblock
> 
> Dear Release Team,
> 
> please unblock package kf6-kio.
> 
> [ Reason ]
> It contains the following changes:
> * Backport upstream commits:
>   - Show single-click selection emblem in open/save dialogs when using
>   single-click mouse mode. (kde#185793)
>   - When saving a file, don’t override user provided filename with folder
>   name when navigating inside a folder with the keyboard. (kde#502794)
>   - Fix actions described by D-Bus activatable desktop files not being
>   triggered when there’s no Exec key.
>   - Inhibit suspend while there’s a file copy job running. (kde#362542)
>     - Update symbols accordingly.

This change removes a symbol. Why is it save to do that?

Cheers

>   - Show busy indictor while emptying the trash.
>   - Fix keyboard navigation unexpectedly switching to file name input when
>   navigating the files panel in save dialogs. (kde#466206)
>   - Fix excessive I/O when hovering over a folder showing thumbnails of its
>   contents.
>   - Fix incorrect usage percentage in Properties dialog for virtual
>   filesystems.
>   - Fix opening the “Advanced Options” window from the file properties dialog
>   freezing Plasma completely until it’s closed. (kde#504608)
> 
> 
> [ Tests ]
> Upstream testsuite passes in sbuild.
> Each changes tested but this one for which I don’t have a test case and
> only non-regression was tested:
> - Fix actions described by D-Bus activatable desktop files not being
> triggered when there’s no Exec key.
> 
> 
> [ 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-kio/6.13.0-4

> diff -Nru kf6-kio-6.13.0/debian/changelog kf6-kio-6.13.0/debian/changelog
> --- kf6-kio-6.13.0/debian/changelog   2025-04-25 22:41:52.000000000 +0200
> +++ kf6-kio-6.13.0/debian/changelog   2025-05-20 08:47:36.000000000 +0200
> @@ -1,3 +1,27 @@
> +kf6-kio (6.13.0-4) unstable; urgency=medium
> +
> +  [ Aurélien COUDERC ]
> +  * Backport upstream commits:
> +    - Show single-click selection emblem in open/save dialogs when using
> +    single-click mouse mode. (kde#185793)
> +    - When saving a file, don’t override user provided filename with folder
> +    name when navigating inside a folder with the keyboard. (kde#502794)
> +    - Fix actions described by D-Bus activatable desktop files not being
> +    triggered when there’s no Exec key.
> +    - Inhibit suspend while there’s a file copy job running. (kde#362542)
> +      - Update symbols accordingly.
> +    - Show busy indictor while emptying the trash.
> +    - Fix keyboard navigation unexpectedly switching to file name input when
> +    navigating the files panel in save dialogs. (kde#466206)
> +    - Fix excessive I/O when hovering over a folder showing thumbnails of its
> +    contents.
> +    - Fix incorrect usage percentage in Properties dialog for virtual
> +    filesystems.
> +    - Fix opening the “Advanced Options” window from the file properties 
> dialog
> +    freezing Plasma completely until it’s closed. (kde#504608)
> +
> + -- Aurélien COUDERC <couc...@debian.org>  Tue, 20 May 2025 08:47:36 +0200
> +
>  kf6-kio (6.13.0-3) unstable; urgency=medium
>  
>    [ Patrick Franz ]
> diff -Nru kf6-kio-6.13.0/debian/libkf6kiocore6.symbols 
> kf6-kio-6.13.0/debian/libkf6kiocore6.symbols
> --- kf6-kio-6.13.0/debian/libkf6kiocore6.symbols      2025-04-23 
> 19:07:08.000000000 +0200
> +++ kf6-kio-6.13.0/debian/libkf6kiocore6.symbols      2025-05-20 
> 08:47:36.000000000 +0200
> @@ -279,8 +279,11 @@
>   _ZN3KIO10JobPrivate12emitMountingEPNS_3JobERK7QStringS5_@Base 6.0.0
>   _ZN3KIO10JobPrivate12emitRenamingEPNS_3JobERK4QUrlS5_@Base 6.0.0
>   _ZN3KIO10JobPrivate14emitUnmountingEPNS_3JobERK7QString@Base 6.0.0
> + (arch=amd64)_ZN3KIO10JobPrivate14inhibitSuspendERK7QString@Base 6.13.0
>   _ZN3KIO10JobPrivate15emitCreatingDirEPNS_3JobERK4QUrl@Base 6.0.0
> + (arch=amd64)_ZN3KIO10JobPrivate16doInhibitSuspendEv@Base 6.13.0
>   _ZN3KIO10JobPrivate16emitTransferringEPNS_3JobERK4QUrl@Base 6.0.0
> + (arch=amd64)_ZN3KIO10JobPrivate16uninhibitSuspendEv@Base 6.13.0
>   _ZN3KIO10JobPrivate22privilegeOperationDataEv@Base 6.0.0
>   _ZN3KIO10JobPrivateD0Ev@Base 6.0.0
>   _ZN3KIO10JobPrivateD1Ev@Base 6.0.0
> diff -Nru kf6-kio-6.13.0/debian/libkf6kiofilewidgets6.symbols 
> kf6-kio-6.13.0/debian/libkf6kiofilewidgets6.symbols
> --- kf6-kio-6.13.0/debian/libkf6kiofilewidgets6.symbols       2025-04-23 
> 19:14:52.000000000 +0200
> +++ kf6-kio-6.13.0/debian/libkf6kiofilewidgets6.symbols       2025-05-20 
> 08:47:36.000000000 +0200
> @@ -104,6 +104,7 @@
>   _ZN12KDirOperator17updateSortActionsEv@Base 6.0.0
>   _ZN12KDirOperator17updateViewActionsEv@Base 6.0.0
>   _ZN12KDirOperator18setShowHiddenFilesEb@Base 6.0.0
> + _ZN12KDirOperator18usingKeyNavigationEv@Base 6.13.0
>   _ZN12KDirOperator19checkPreviewSupportEv@Base 6.0.0
>   _ZN12KDirOperator19setSupportedSchemesERK5QListI7QStringE@Base 6.0.0
>   _ZN12KDirOperator19showOpenWithActionsEb@Base 6.0.0
> diff -Nru kf6-kio-6.13.0/debian/libkf6kiogui6.symbols 
> kf6-kio-6.13.0/debian/libkf6kiogui6.symbols
> --- kf6-kio-6.13.0/debian/libkf6kiogui6.symbols       2024-12-08 
> 05:08:50.000000000 +0100
> +++ kf6-kio-6.13.0/debian/libkf6kiogui6.symbols       2025-05-20 
> 08:47:36.000000000 +0200
> @@ -1,4 +1,4 @@
> -# SymbolsHelper-Confirmed: 6.8.0 amd64
> +# SymbolsHelper-Confirmed: 6.13.0 amd64
>  libKF6KIOGui.so.6 libkf6kiogui6 #MINVER#
>  * Build-Depends-Package: libkf6kio-dev
>   
> (arch=linux-any)_ZGVZN9QMetaType21registerConverterImplI5QListI11ExecCommandE9QIterableI13QMetaSequenceEEEbSt8functionIFbPKvPvEES_S_E10unregister@Base
>  6.0.0
> @@ -31,7 +31,7 @@
>   _ZN14KProcessRunner14escapeUnitNameERK7QString@Base 6.0.0
>   
> _ZN14KProcessRunner14fromExecutableERK7QStringRK5QListIS0_ES2_RK10QByteArrayS2_RK19QProcessEnvironment@Base
>  6.0.0
>   _ZN14KProcessRunner14processStartedEx@Base 6.0.0
> - 
> _ZN14KProcessRunner15fromApplicationERK28QExplicitlySharedDataPointerI8KServiceERK7QStringRK5QListI4QUrlE6QFlagsIN3KIO22ApplicationLauncherJob7RunFlagEES7_RK10QByteArray@Base
>  6.0.0
> + 
> _ZN14KProcessRunner15fromApplicationERK28QExplicitlySharedDataPointerI8KServiceERK7QStringRK5QListI4QUrlES7_6QFlagsIN3KIO22ApplicationLauncherJob7RunFlagEES7_RK10QByteArray@Base
>  6.13.0
>   _ZN14KProcessRunner16emitDelayedErrorERK7QString@Base 6.0.0
>   _ZN14KProcessRunner16staticMetaObjectE@Base 6.0.0
>   
> _ZN14KProcessRunner19initFromDesktopNameERK7QStringS2_RK10QByteArrayS2_RK19QProcessEnvironment@Base
>  6.0.0
> diff -Nru kf6-kio-6.13.0/debian/libkf6kiowidgets6.symbols 
> kf6-kio-6.13.0/debian/libkf6kiowidgets6.symbols
> --- kf6-kio-6.13.0/debian/libkf6kiowidgets6.symbols   2024-09-08 
> 09:38:40.000000000 +0200
> +++ kf6-kio-6.13.0/debian/libkf6kiowidgets6.symbols   2025-05-20 
> 08:47:36.000000000 +0200
> @@ -1,4 +1,4 @@
> -# SymbolsHelper-Confirmed: 6.0.0 amd64 armel armhf riscv64
> +# SymbolsHelper-Confirmed: 6.13.0 amd64
>  libKF6KIOWidgets.so.6 libkf6kiowidgets6 #MINVER#, kio6
>  * Build-Depends-Package: libkf6kio-dev
>   
> _ZGVZN9QMetaType21registerConverterImplI5QListI4QUrlE9QIterableI13QMetaSequenceEEEbSt8functionIFbPKvPvEES_S_E10unregister@Base
>  6.0.0
> @@ -164,6 +164,7 @@
>   _ZN17KFileItemDelegate18setShowInformationENS_11InformationE@Base 6.0.0
>   _ZN17KFileItemDelegate18setShowInformationERK5QListINS_11InformationEE@Base 
> 6.0.0
>   _ZN17KFileItemDelegate22setJobTransfersVisibleEb@Base 6.0.0
> + _ZN17KFileItemDelegate22setSelectionEmblemRectE5QRecti@Base 6.13.0
>   _ZN17KFileItemDelegate24setShowToolTipWhenElidedEb@Base 6.0.0
>   _ZN17KFileItemDelegate5shapeERK20QStyleOptionViewItemRK11QModelIndex@Base 
> 6.0.0
>   
> _ZN17KFileItemDelegate9helpEventEP10QHelpEventP17QAbstractItemViewRK20QStyleOptionViewItemRK11QModelIndex@Base
>  6.0.0
> @@ -330,6 +331,7 @@
>   _ZN3KIO16DeleteOrTrashJob11qt_metacastEPKc@Base 6.0.0
>   _ZN3KIO16DeleteOrTrashJob16staticMetaObjectE@Base 6.0.0
>   _ZN3KIO16DeleteOrTrashJob5startEv@Base 6.0.0
> + _ZN3KIO16DeleteOrTrashJob7startedEv@Base 6.13.0
>   
> _ZN3KIO16DeleteOrTrashJobC1ERK5QListI4QUrlENS_22AskUserActionInterface12DeletionTypeENS6_16ConfirmationTypeEP7QObject@Base
>  6.0.0
>   
> _ZN3KIO16DeleteOrTrashJobC2ERK5QListI4QUrlENS_22AskUserActionInterface12DeletionTypeENS6_16ConfirmationTypeEP7QObject@Base
>  6.0.0
>   _ZN3KIO16DeleteOrTrashJobD0Ev@Base 6.0.0
> @@ -489,10 +491,13 @@
>   _ZNK17KFileItemDelegate12shadowOffsetEv@Base 6.0.0
>   _ZNK17KFileItemDelegate13setEditorDataEP7QWidgetRK11QModelIndex@Base 6.0.0
>   _ZNK17KFileItemDelegate15showInformationEv@Base 6.0.0
> + 
> _ZNK17KFileItemDelegate19drawSelectionEmblemE20QStyleOptionViewItemP8QPainterRK11QModelIndex@Base
>  6.13.0
>   _ZNK17KFileItemDelegate19jobTransfersVisibleEv@Base 6.0.0
> + _ZNK17KFileItemDelegate19selectionEmblemRectEv@Base 6.13.0
>   
> _ZNK17KFileItemDelegate20updateEditorGeometryEP7QWidgetRK20QStyleOptionViewItemRK11QModelIndex@Base
>  6.0.0
>   _ZNK17KFileItemDelegate21showToolTipWhenElidedEv@Base 6.0.0
>   
> _ZNK17KFileItemDelegate5paintEP8QPainterRK20QStyleOptionViewItemRK11QModelIndex@Base
>  6.0.0
> + _ZNK17KFileItemDelegate8fileItemERK11QModelIndex@Base 6.13.0
>   
> _ZNK17KFileItemDelegate8iconRectERK20QStyleOptionViewItemRK11QModelIndex@Base 
> 6.0.0
>   
> _ZNK17KFileItemDelegate8sizeHintERK20QStyleOptionViewItemRK11QModelIndex@Base 
> 6.0.0
>   _ZNK17KFileItemDelegate8wrapModeEv@Base 6.0.0
> diff -Nru kf6-kio-6.13.0/debian/patches/series 
> kf6-kio-6.13.0/debian/patches/series
> --- kf6-kio-6.13.0/debian/patches/series      2025-04-23 19:10:13.000000000 
> +0200
> +++ kf6-kio-6.13.0/debian/patches/series      2025-05-20 08:47:36.000000000 
> +0200
> @@ -1,6 +1,17 @@
> -# fixed in 6.14
> -upstream_KUrlNavigatorButton.patch
> -
>  report_error_removing_dirs
>  hurd_disable_unimplemented.diff
>  Use-CXX_FLAGS-for-moc_predefs.h.patch
> +
> +upstream_d8441b7b_Show-single-click-selection-emblem-when-using-single-click-mouse-mode.patch
> +# fixed in 6.14
> +upstream_KUrlNavigatorButton.patch
> +upstream_cd0810f8_KFileWidget-Do-not-override-filename-with-folder-name-if-edited.patch
> +upstream_31806c51_KProcessRunner-Fix-launching-actions-without-executable.patch
> +upstream_3c3d5904_core-Add-infrastructure-for-inhibiting-suspend-in-jobs.patch
> +upstream_60191c04_CopyJob-Inhibit-suspend-during-copy-operation.patch
> +upstream_17cd1c9b_DeleteOrTrashJob-Add-started-signal.patch
> +upstream_3e6175e4_KFilePlacesView-Show-busy-indicator-while-emptying-trash.patch
> +upstream_719e0b00_KFileWidget-Fix-key-navigation-escaping-in-save-dialogs.patch
> +upstream_c747fa0f_Avoid-unnecessary-sequencing-jobs-in-PreviewGenerator.patch
> +upstream_81ca0e2c_Fix-incorrect-usage-percentage-in-Properties-dialog-for-virtual-filesystems.patch
> +upstream_9143fc2a_Fix-dialog-modality-settings.patch
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_17cd1c9b_DeleteOrTrashJob-Add-started-signal.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_17cd1c9b_DeleteOrTrashJob-Add-started-signal.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_17cd1c9b_DeleteOrTrashJob-Add-started-signal.patch
>  1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_17cd1c9b_DeleteOrTrashJob-Add-started-signal.patch
>  2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,50 @@
> +From 17cd1c9bb99c4043018eda7b1a789af98b29f2b4 Mon Sep 17 00:00:00 2001
> +From: Kai Uwe Broulik <k...@privat.broulik.de>
> +Date: Thu, 1 May 2025 19:01:23 +0200
> +Subject: [PATCH] DeleteOrTrashJob: Add started signal
> +
> +It's emitted when the user has confirmed emptying trash and
> +it will actually commence emptying it.
> +---
> + src/widgets/deleteortrashjob.cpp |  2 ++
> + src/widgets/deleteortrashjob.h   | 11 +++++++++++
> + 2 files changed, 13 insertions(+)
> +
> +diff --git a/src/widgets/deleteortrashjob.cpp 
> b/src/widgets/deleteortrashjob.cpp
> +index 1f182c99c..1af01a236 100644
> +--- a/src/widgets/deleteortrashjob.cpp
> ++++ b/src/widgets/deleteortrashjob.cpp
> +@@ -87,6 +87,8 @@ void DeleteOrTrashJobPrivate::slotAskUser(bool 
> allowDelete, const QList<QUrl> &u
> +         // show the "File is too large to Trash" error message
> +         job->uiDelegate()->setAutoErrorHandlingEnabled(false);
> +         q->addSubjob(job);
> ++
> ++        Q_EMIT q->started();
> +     }
> + }
> + 
> +diff --git a/src/widgets/deleteortrashjob.h b/src/widgets/deleteortrashjob.h
> +index dfcc6c8ee..486a1be70 100644
> +--- a/src/widgets/deleteortrashjob.h
> ++++ b/src/widgets/deleteortrashjob.h
> +@@ -74,6 +74,17 @@ public:
> +      */
> +     void start() override;
> + 
> ++Q_SIGNALS:
> ++    /**
> ++     * Emitted when the actual delete or trash job has been started.
> ++     *
> ++     * This can be used to display a busy indicator after the user has 
> confirmed
> ++     * this operation.
> ++     *
> ++     * @since 6.15
> ++     */
> ++    void started();
> ++
> + private:
> +     void slotResult(KJob *job) override;
> + 
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_31806c51_KProcessRunner-Fix-launching-actions-without-executable.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_31806c51_KProcessRunner-Fix-launching-actions-without-executable.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_31806c51_KProcessRunner-Fix-launching-actions-without-executable.patch
>      1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_31806c51_KProcessRunner-Fix-launching-actions-without-executable.patch
>      2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,108 @@
> +From 31806c5180eb7cd1ad2f354eafd84f8fc490eae2 Mon Sep 17 00:00:00 2001
> +From: =?UTF-8?q?Ball=C3=B3=20Gy=C3=B6rgy?= <ballog...@gmail.com>
> +Date: Fri, 4 Apr 2025 08:08:31 +0200
> +Subject: [PATCH] KProcessRunner: Fix launching actions without executable
> +
> +If D-Bus activation is possible, it's not needed to have an executable,
> +since everything is done via D-Bus. Therefore look for the matching action
> +name instead of the exec value when launching an action. The specification
> +allows to omit the "Exec" key if "DBusActivatable" is true.
> +
> +Most applications specify the Exec parameter for compatibility reasons, but
> +if the action's "Exec" line got removed from a D-Bus activatable desktop
> +file, then KIO just activates the application rather than calling the
> +requested action. This change fixes that issue.
> +---
> + src/gui/applicationlauncherjob.cpp | 7 +++++--
> + src/gui/kprocessrunner.cpp         | 8 ++++++--
> + src/gui/kprocessrunner_p.h         | 1 +
> + 3 files changed, 12 insertions(+), 4 deletions(-)
> +
> +diff --git a/src/gui/applicationlauncherjob.cpp 
> b/src/gui/applicationlauncherjob.cpp
> +index 463cec1be..f3cafafc8 100644
> +--- a/src/gui/applicationlauncherjob.cpp
> ++++ b/src/gui/applicationlauncherjob.cpp
> +@@ -49,6 +49,7 @@ public:
> +     KService::Ptr m_service;
> +     QString m_serviceEntryPath;
> +     QList<QUrl> m_urls;
> ++    QString m_actionName;
> +     KIO::ApplicationLauncherJob::RunFlags m_runFlags;
> +     QString m_suggestedFileName;
> +     QString m_mimeTypeName;
> +@@ -75,6 +76,7 @@ KIO::ApplicationLauncherJob::ApplicationLauncherJob(const 
> KServiceAction &servic
> +     Q_ASSERT(d->m_service);
> +     d->m_service.detach();
> +     d->m_service->setExec(serviceAction.exec());
> ++    d->m_actionName = serviceAction.name();
> + }
> + KIO::ApplicationLauncherJob::ApplicationLauncherJob(const 
> KDesktopFileAction &desktopFileAction, QObject *parent)
> +     : ApplicationLauncherJob(KService::Ptr(new 
> KService(desktopFileAction.desktopFilePath())), parent)
> +@@ -82,6 +84,7 @@ KIO::ApplicationLauncherJob::ApplicationLauncherJob(const 
> KDesktopFileAction &de
> +     Q_ASSERT(d->m_service);
> +     d->m_service.detach();
> +     d->m_service->setExec(desktopFileAction.exec());
> ++    d->m_actionName = desktopFileAction.name();
> + }
> + 
> + KIO::ApplicationLauncherJob::ApplicationLauncherJob(QObject *parent)
> +@@ -196,7 +199,7 @@ void 
> KIO::ApplicationLauncherJob::proceedAfterSecurityChecks()
> +         d->m_processRunners.reserve(d->m_numProcessesPending);
> +         for (int i = 1; i < d->m_urls.count(); ++i) {
> +             auto *processRunner =
> +-                KProcessRunner::fromApplication(d->m_service, 
> d->m_serviceEntryPath, {d->m_urls.at(i)}, d->m_runFlags, 
> d->m_suggestedFileName, QByteArray{});
> ++                KProcessRunner::fromApplication(d->m_service, 
> d->m_serviceEntryPath, {d->m_urls.at(i)}, d->m_actionName, d->m_runFlags, 
> d->m_suggestedFileName, QByteArray{});
> +             d->m_processRunners.push_back(processRunner);
> +             connect(processRunner, &KProcessRunner::processStarted, this, 
> [this](qint64 pid) {
> +                 d->slotStarted(pid);
> +@@ -208,7 +211,7 @@ void 
> KIO::ApplicationLauncherJob::proceedAfterSecurityChecks()
> +     }
> + 
> +     auto *processRunner =
> +-        KProcessRunner::fromApplication(d->m_service, 
> d->m_serviceEntryPath, d->m_urls, d->m_runFlags, d->m_suggestedFileName, 
> d->m_startupId);
> ++        KProcessRunner::fromApplication(d->m_service, 
> d->m_serviceEntryPath, d->m_urls, d->m_actionName, d->m_runFlags, 
> d->m_suggestedFileName, d->m_startupId);
> +     d->m_processRunners.push_back(processRunner);
> +     connect(processRunner, &KProcessRunner::error, this, [this](const 
> QString &errorText) {
> +         setError(KJob::UserDefinedError);
> +diff --git a/src/gui/kprocessrunner.cpp b/src/gui/kprocessrunner.cpp
> +index 64fa3afb2..00f7811e8 100644
> +--- a/src/gui/kprocessrunner.cpp
> ++++ b/src/gui/kprocessrunner.cpp
> +@@ -88,6 +88,7 @@ static void modifyEnv(KProcess &process, 
> QProcessEnvironment mod)
> + KProcessRunner *KProcessRunner::fromApplication(const KService::Ptr 
> &service,
> +                                                 const QString 
> &serviceEntryPath,
> +                                                 const QList<QUrl> &urls,
> ++                                                const QString &actionName,
> +                                                 
> KIO::ApplicationLauncherJob::RunFlags flags,
> +                                                 const QString 
> &suggestedFileName,
> +                                                 const QByteArray &asn)
> +@@ -103,9 +104,12 @@ KProcessRunner *KProcessRunner::fromApplication(const 
> KService::Ptr &service,
> +     const bool notYetSupportedOpenActivationNeeded = !urls.isEmpty();
> +     if (!notYetSupportedOpenActivationNeeded && 
> DBusActivationRunner::activationPossible(service, flags, suggestedFileName)) {
> +         const auto actions = service->actions();
> +-        auto action = std::find_if(actions.cbegin(), actions.cend(), 
> [service](const KServiceAction &action) {
> +-            return action.exec() == service->exec();
> ++        auto action = std::find_if(actions.cbegin(), actions.cend(), 
> [actionName](const KServiceAction &action) {
> ++            return action.name() == actionName;
> +         });
> ++        if (!actionName.isEmpty() && action == actions.cend()) {
> ++            qCWarning(KIO_GUI) << "Requested action" << actionName << 
> "cannot be found for" << service->name();
> ++        }
> +         instance = new DBusActivationRunner(action != actions.cend() ? 
> action->name() : QString());
> +     } else {
> +         instance = makeInstance();
> +diff --git a/src/gui/kprocessrunner_p.h b/src/gui/kprocessrunner_p.h
> +index 63e517d37..7f084a49e 100644
> +--- a/src/gui/kprocessrunner_p.h
> ++++ b/src/gui/kprocessrunner_p.h
> +@@ -59,6 +59,7 @@ public:
> +     static KProcessRunner *fromApplication(const KService::Ptr &service,
> +                                            const QString &serviceEntryPath,
> +                                            const QList<QUrl> &urls,
> ++                                           const QString &actionName = {},
> +                                            
> KIO::ApplicationLauncherJob::RunFlags flags = {},
> +                                            const QString &suggestedFileName 
> = {},
> +                                            const QByteArray &asn = {});
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_3c3d5904_core-Add-infrastructure-for-inhibiting-suspend-in-jobs.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_3c3d5904_core-Add-infrastructure-for-inhibiting-suspend-in-jobs.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_3c3d5904_core-Add-infrastructure-for-inhibiting-suspend-in-jobs.patch
>       1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_3c3d5904_core-Add-infrastructure-for-inhibiting-suspend-in-jobs.patch
>       2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,594 @@
> +From 3c3d590472b1878660ae55f0f7c1bed5600ebb65 Mon Sep 17 00:00:00 2001
> +From: Kai Uwe Broulik <k...@privat.broulik.de>
> +Date: Sun, 20 Apr 2025 12:48:26 +0200
> +Subject: [PATCH] core: Add infrastructure for inhibiting suspend in jobs
> +
> +This calls the freedesktop Inhibit interface on DBus which will
> +inhibit suspend (but not display power management/screensaver).
> +When inside a sandbox it instead calls the XDG Desktop Portal
> +Inhibit interface.
> +
> +When a job is destroyed or gets suspended, the inhibition is lifted.
> +When a job is resumed, `doInhibitSuspend` is called again to re-instate
> +the inhibition.
> +
> +It is the job's responsibility to call `doInhibitSuspend` at
> +the appropriate time (e.g. in doStart/slotStart).
> +---
> + src/core/CMakeLists.txt                       |   5 +
> + src/core/config-kiocore.h.cmake               |   2 +
> + src/core/job.cpp                              | 139 +++++++++++++-
> + src/core/job_p.h                              |  16 ++
> + ...rg.freedesktop.PowerManagement.Inhibit.xml |  20 ++
> + src/core/org.freedesktop.portal.Inhibit.xml   | 173 ++++++++++++++++++
> + src/core/org.freedesktop.portal.Request.xml   |  93 ++++++++++
> + 7 files changed, 446 insertions(+), 2 deletions(-)
> + create mode 100644 src/core/org.freedesktop.PowerManagement.Inhibit.xml
> + create mode 100644 src/core/org.freedesktop.portal.Inhibit.xml
> + create mode 100644 src/core/org.freedesktop.portal.Request.xml
> +
> +diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
> +index 1dacfa081..599e001f9 100644
> +--- a/src/core/CMakeLists.txt
> ++++ b/src/core/CMakeLists.txt
> +@@ -164,6 +164,11 @@ if (HAVE_QTDBUS)
> +             PROPERTIES INCLUDE authinfo.h
> +     )
> +     qt_add_dbus_interface(kiocore_dbus_SRCS org.kde.KPasswdServer.xml 
> kpasswdserver_interface)
> ++
> ++    qt_add_dbus_interface(kiocore_dbus_SRCS 
> org.freedesktop.PowerManagement.Inhibit.xml inhibit_interface)
> ++
> ++    qt_add_dbus_interface(kiocore_dbus_SRCS 
> org.freedesktop.portal.Inhibit.xml portal_inhibit_interface)
> ++    qt_add_dbus_interface(kiocore_dbus_SRCS 
> org.freedesktop.portal.Request.xml portal_request_interface)
> + endif()
> + 
> + target_sources(KF6KIOCore PRIVATE
> +diff --git a/src/core/config-kiocore.h.cmake 
> b/src/core/config-kiocore.h.cmake
> +index 1f0bc42f2..bd9e7582a 100644
> +--- a/src/core/config-kiocore.h.cmake
> ++++ b/src/core/config-kiocore.h.cmake
> +@@ -7,6 +7,8 @@
> + /* Defined if sys/acl.h exists */
> + #cmakedefine01 HAVE_SYS_ACL_H
> + 
> ++#cmakedefine01 HAVE_QTDBUS
> ++
> + #define KDE_INSTALL_FULL_LIBEXECDIR_KF "${KDE_INSTALL_FULL_LIBEXECDIR_KF}"
> + 
> + #define KDE_INSTALL_FULL_KIO_PLUGINDIR 
> "${KDE_INSTALL_FULL_PLUGINDIR}/kf6/kio/"
> +diff --git a/src/core/job.cpp b/src/core/job.cpp
> +index e8360d468..4eb037816 100644
> +--- a/src/core/job.cpp
> ++++ b/src/core/job.cpp
> +@@ -13,13 +13,30 @@
> + #include <time.h>
> + 
> + #include <KLocalizedString>
> ++#include <KSandbox>
> + #include <KStringHandler>
> + 
> ++#include "kiocoredebug.h"
> + #include "worker_p.h"
> + #include <kio/jobuidelegateextension.h>
> + 
> ++#if HAVE_QTDBUS
> ++#include <QDBusConnection>
> ++#include <QDBusPendingCallWatcher>
> ++
> ++#include "inhibit_interface.h"
> ++#include "portal_inhibit_interface.h"
> ++#include "portal_request_interface.h"
> ++#endif
> ++
> + using namespace KIO;
> + 
> ++static constexpr QLatin1String 
> g_portalServiceName{"org.freedesktop.portal.Desktop"};
> ++static constexpr QLatin1String 
> g_portalInhibitObjectPath{"/org/freedesktop/portal/desktop"};
> ++
> ++static constexpr QLatin1String 
> g_inhibitServiceName{"org.freedesktop.PowerManagement.Inhibit"};
> ++static constexpr QLatin1String 
> g_inhibitObjectPath{"/org/freedesktop/PowerManagement/Inhibit"};
> ++
> + Job::Job()
> +     : KCompositeJob(nullptr)
> +     , d_ptr(new JobPrivate)
> +@@ -89,9 +106,127 @@ static QString url_description_string(const QUrl &url)
> + }
> + 
> + KIO::JobPrivate::~JobPrivate()
> ++{
> ++    uninhibitSuspend();
> ++}
> ++
> ++void JobPrivate::doInhibitSuspend()
> + {
> + }
> + 
> ++void JobPrivate::inhibitSuspend(const QString &reason)
> ++{
> ++#if HAVE_QTDBUS
> ++    if (KSandbox::isInside()) {
> ++        Q_ASSERT(m_portalInhibitionRequest.path().isEmpty());
> ++
> ++        org::freedesktop::portal::Inhibit 
> inhibitInterface{g_portalServiceName, g_portalInhibitObjectPath, 
> QDBusConnection::sessionBus()};
> ++        QVariantMap args;
> ++        if (!reason.isEmpty()) {
> ++            args.insert(QStringLiteral("reason"), reason);
> ++        }
> ++        auto call = inhibitInterface.Inhibit(QString() /* TODO window. */, 
> 4 /* Suspend */, args);
> ++        // This is not parented to the job, so we can properly clean up the 
> inhibiton
> ++        // should the job finish before the inhibition has been processed.
> ++        auto *watcher = new QDBusPendingCallWatcher(call);
> ++        QPointer<Job> guard(q_ptr);
> ++        QObject::connect(watcher, &QDBusPendingCallWatcher::finished, 
> watcher, [this, guard, watcher, reason] {
> ++            QDBusPendingReply<QDBusObjectPath> reply = *watcher;
> ++
> ++            if (reply.isError()) {
> ++                qCWarning(KIO_CORE).nospace() << "Failed to inhibit suspend 
> with reason " << reason << ": " << reply.error().message();
> ++            } else {
> ++                const QDBusObjectPath requestPath = reply.value();
> ++
> ++                // By the time the inhibition returned, the job was already 
> gone. Uninhibit again.
> ++                if (!guard) {
> ++                    org::freedesktop::portal::Request 
> requestInterface{g_portalServiceName, requestPath.path(), 
> QDBusConnection::sessionBus()};
> ++                    requestInterface.Close();
> ++                } else {
> ++                    m_portalInhibitionRequest = requestPath;
> ++                }
> ++            }
> ++
> ++            watcher->deleteLater();
> ++        });
> ++    } else {
> ++        Q_ASSERT(!m_inhibitionCookie);
> ++
> ++        QString appName = q_ptr->property("desktopFileName").toString();
> ++        if (appName.isEmpty()) {
> ++            // desktopFileName is in QGuiApplication but we're in KIO Core 
> here.
> ++            appName = 
> QCoreApplication::instance()->property("desktopFileName").toString();
> ++        }
> ++        if (appName.isEmpty()) {
> ++            appName = QCoreApplication::applicationName();
> ++        }
> ++
> ++        org::freedesktop::PowerManagement::Inhibit 
> inhibitInterface{g_inhibitServiceName, g_inhibitObjectPath, 
> QDBusConnection::sessionBus()};
> ++        auto call = inhibitInterface.Inhibit(appName, reason);
> ++        auto *watcher = new QDBusPendingCallWatcher(call);
> ++        QPointer<Job> guard(q_ptr);
> ++        QObject::connect(watcher, &QDBusPendingCallWatcher::finished, 
> watcher, [this, guard, watcher, appName, reason] {
> ++            QDBusPendingReply<uint> reply = *watcher;
> ++
> ++            if (reply.isError()) {
> ++                qCWarning(KIO_CORE).nospace() << "Failed to inhibit suspend 
> for " << appName << " with reason " << reason << ": " << 
> reply.error().message();
> ++            } else {
> ++                const uint cookie = reply.value();
> ++
> ++                if (!guard) {
> ++                    org::freedesktop::PowerManagement::Inhibit 
> inhibitInterface{g_inhibitServiceName, g_inhibitObjectPath, 
> QDBusConnection::sessionBus()};
> ++                    inhibitInterface.UnInhibit(cookie);
> ++                } else {
> ++                    m_inhibitionCookie = cookie;
> ++                }
> ++            }
> ++
> ++            watcher->deleteLater();
> ++        });
> ++    }
> ++#else
> ++    Q_UNUSED(reason)
> ++#endif
> ++}
> ++
> ++void JobPrivate::uninhibitSuspend()
> ++{
> ++#if HAVE_QTDBUS
> ++    if (!m_portalInhibitionRequest.path().isEmpty()) {
> ++        org::freedesktop::portal::Request 
> requestInterface{g_portalServiceName, m_portalInhibitionRequest.path(), 
> QDBusConnection::sessionBus()};
> ++        auto call = requestInterface.Close();
> ++        auto *watcher = new QDBusPendingCallWatcher(call, q_ptr);
> ++        QObject::connect(watcher, &QDBusPendingCallWatcher::finished, 
> q_ptr, [this, watcher] {
> ++            QDBusPendingReply<> reply = *watcher;
> ++
> ++            if (reply.isError()) {
> ++                qCWarning(KIO_CORE) << "Failed to uninhibit suspend:" << 
> reply.error().message();
> ++            } else {
> ++                m_portalInhibitionRequest = QDBusObjectPath();
> ++            }
> ++
> ++            watcher->deleteLater();
> ++        });
> ++    } else if (m_inhibitionCookie) {
> ++        org::freedesktop::PowerManagement::Inhibit 
> inhibitInterface{g_inhibitServiceName, g_inhibitObjectPath, 
> QDBusConnection::sessionBus()};
> ++        const int cookie = *m_inhibitionCookie;
> ++        auto call = inhibitInterface.UnInhibit(cookie);
> ++        auto *watcher = new QDBusPendingCallWatcher(call, q_ptr);
> ++        QObject::connect(watcher, &QDBusPendingCallWatcher::finished, 
> q_ptr, [this, watcher, cookie] {
> ++            QDBusPendingReply<> reply = *watcher;
> ++
> ++            if (reply.isError()) {
> ++                qCWarning(KIO_CORE).nospace() << "Failed to uninhibit 
> suspend for cookie" << cookie << ": " << reply.error().message();
> ++            } else {
> ++                m_inhibitionCookie.reset();
> ++            }
> ++
> ++            watcher->deleteLater();
> ++        });
> ++    }
> ++#endif
> ++}
> ++
> + void JobPrivate::emitMoving(KIO::Job *job, const QUrl &src, const QUrl 
> &dest)
> + {
> +     static const QString s_title = i18nc("@title job", "Moving");
> +@@ -172,7 +307,7 @@ bool Job::doSuspend()
> +             return false;
> +         }
> +     }
> +-
> ++    d_ptr->uninhibitSuspend();
> +     return true;
> + }
> + 
> +@@ -183,7 +318,7 @@ bool Job::doResume()
> +             return false;
> +         }
> +     }
> +-
> ++    d_ptr->doInhibitSuspend();
> +     return true;
> + }
> + 
> +diff --git a/src/core/job_p.h b/src/core/job_p.h
> +index e9eab0cf6..e8191198c 100644
> +--- a/src/core/job_p.h
> ++++ b/src/core/job_p.h
> +@@ -12,6 +12,8 @@
> + #ifndef KIO_JOB_P_H
> + #define KIO_JOB_P_H
> + 
> ++#include "config-kiocore.h"
> ++
> + #include "commands_p.h"
> + #include "global.h"
> + #include "jobtracker.h"
> +@@ -26,6 +28,12 @@
> + #include <kio/jobuidelegateextension.h>
> + #include <kio/jobuidelegatefactory.h>
> + 
> ++#if HAVE_QTDBUS
> ++#include <QDBusObjectPath>
> ++
> ++#include <optional>
> ++#endif
> ++
> + /* clang-format off */
> + #define KIO_ARGS \
> +     QByteArray packedArgs; \
> +@@ -84,6 +92,10 @@ public:
> +     MetaData m_outgoingMetaData;
> +     JobUiDelegateExtension *m_uiDelegateExtension;
> +     Job *q_ptr;
> ++#if HAVE_QTDBUS
> ++    std::optional<uint> m_inhibitionCookie; // fdo.
> ++    QDBusObjectPath m_portalInhibitionRequest; // portal.
> ++#endif
> +     // For privilege operation
> +     bool m_privilegeExecutionEnabled;
> +     QString m_title, m_message;
> +@@ -92,6 +104,10 @@ public:
> +     QByteArray privilegeOperationData();
> +     void slotSpeed(KJob *job, unsigned long speed);
> + 
> ++    void inhibitSuspend(const QString &reason);
> ++    void uninhibitSuspend();
> ++    virtual void doInhibitSuspend();
> ++
> +     static void emitMoving(KIO::Job *, const QUrl &src, const QUrl &dest);
> +     static void emitRenaming(KIO::Job *, const QUrl &src, const QUrl &dest);
> +     static void emitCopying(KIO::Job *, const QUrl &src, const QUrl &dest);
> +diff --git a/src/core/org.freedesktop.PowerManagement.Inhibit.xml 
> b/src/core/org.freedesktop.PowerManagement.Inhibit.xml
> +new file mode 100644
> +index 000000000..21dfce8c7
> +--- /dev/null
> ++++ b/src/core/org.freedesktop.PowerManagement.Inhibit.xml
> +@@ -0,0 +1,20 @@
> ++<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 
> 1.0//EN"
> ++"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
> ++<node>
> ++  <interface name="org.freedesktop.PowerManagement.Inhibit">
> ++    <method name="Inhibit">
> ++      <arg direction="in" type="s" name="application"/>
> ++      <arg direction="in" type="s" name="reason"/>
> ++      <arg direction="out" type="u" name="cookie"/>
> ++    </method>
> ++    <method name="UnInhibit">
> ++      <arg direction="in" type="u" name="cookie"/>
> ++    </method>
> ++    <signal name="HasInhibitChanged">
> ++      <arg direction="out" type="b" name="has_inhibit"/>
> ++    </signal>
> ++    <method name="HasInhibit">
> ++      <arg direction="out" type="b" name="has_inhibit"/>
> ++    </method>
> ++  </interface>
> ++</node>
> +diff --git a/src/core/org.freedesktop.portal.Inhibit.xml 
> b/src/core/org.freedesktop.portal.Inhibit.xml
> +new file mode 100644
> +index 000000000..1ae413e18
> +--- /dev/null
> ++++ b/src/core/org.freedesktop.portal.Inhibit.xml
> +@@ -0,0 +1,173 @@
> ++<?xml version="1.0"?>
> ++<!--
> ++ Copyright (C) 2016 Red Hat, Inc.
> ++
> ++ SPDX-License-Identifier: LGPL-2.1-or-later
> ++
> ++ This library is free software; you can redistribute it and/or
> ++ modify it under the terms of the GNU Lesser General Public
> ++ License as published by the Free Software Foundation; either
> ++ version 2.1 of the License, or (at your option) any later version.
> ++
> ++ This library is distributed in the hope that it will be useful,
> ++ but WITHOUT ANY WARRANTY; without even the implied warranty of
> ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> ++ Lesser General Public License for more details.
> ++
> ++ You should have received a copy of the GNU Lesser General Public
> ++ License along with this library. If not, see 
> <http://www.gnu.org/licenses/>.
> ++
> ++ Author: Matthias Clasen <mcla...@redhat.com>
> ++-->
> ++
> ++<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd";>
> ++  <!--
> ++      org.freedesktop.portal.Inhibit:
> ++      @short_description: Portal for inhibiting session transitions
> ++
> ++      This simple interface lets sandboxed applications inhibit the user
> ++      session from ending, suspending, idling or getting switched away.
> ++
> ++      This documentation describes version 3 of this interface.
> ++  -->
> ++  <interface name="org.freedesktop.portal.Inhibit">
> ++    <!--
> ++        Inhibit:
> ++        @window: Identifier for the window
> ++        @flags: Flags identifying what is inhibited
> ++        @options: Vardict with optional further information
> ++        @handle: Object path for the :ref:`org.freedesktop.portal.Request` 
> object representing this call
> ++
> ++        Inhibits a session status changes. To remove the inhibition,
> ++        call :ref:`org.freedesktop.portal.Request.Close` on the returned
> ++        handle.
> ++
> ++        The flags determine what changes are inhibited:
> ++
> ++        - ``1``: Logout
> ++        - ``2``: User Switch
> ++        - ``4``: Suspend
> ++        - ``8``: Idle
> ++
> ++        Supported keys in the @options vardict include:
> ++
> ++        * ``handle_token`` (``s``)
> ++
> ++          A string that will be used as the last element of the @handle. 
> Must be a valid
> ++          object path element. See the 
> :ref:`org.freedesktop.portal.Request` documentation for
> ++          more information about the @handle.
> ++
> ++        * ``reason`` (``s``)
> ++
> ++          User-visible reason for the inhibition.
> ++    -->
> ++    <method name="Inhibit">
> ++      <arg type="s" name="window" direction="in"/>
> ++      <arg type="u" name="flags" direction="in"/>
> ++      <annotation name="org.qtproject.QtDBus.QtTypeName.In2" 
> value="QVariantMap"/>
> ++      <arg type="a{sv}" name="options" direction="in"/>
> ++      <arg type="o" name="handle" direction="out"/>
> ++    </method>
> ++
> ++    <!--
> ++        CreateMonitor:
> ++        @window: the parent window
> ++        @options: Vardict with optional further information
> ++        @handle: Object path for the :ref:`org.freedesktop.portal.Request` 
> object representing this call
> ++
> ++        Creates a monitoring session. While this session is
> ++        active, the caller will receive StateChanged signals
> ++        with updates on the session state.
> ++
> ++        A successfully created session can at any time be closed using
> ++        org.freedesktop.portal.Session::Close, or may at any time be closed
> ++        by the portal implementation, which will be signalled via
> ++        :ref:`org.freedesktop.portal.Session::Closed`.
> ++
> ++        Supported keys in the @options vardict include:
> ++
> ++        * ``handle_token`` (``s``)
> ++
> ++          A string that will be used as the last element of the @handle. 
> Must be a valid
> ++          object path element. See the 
> :ref:`org.freedesktop.portal.Request` documentation for
> ++          more information about the @handle.
> ++
> ++        * ``session_handle_token`` (``s``)
> ++
> ++          A string that will be used as the last element of the session 
> handle. Must be a valid
> ++          object path element. See the 
> :ref:`org.freedesktop.portal.Session` documentation for
> ++          more information about the session handle.
> ++
> ++        The following results get returned via the 
> :ref:`org.freedesktop.portal.Request::Response` signal:
> ++
> ++        * ``session_handle`` (``s``)
> ++
> ++          The session handle. An object path for the
> ++          :ref:`org.freedesktop.portal.Session` object representing the 
> created
> ++          session.
> ++
> ++          .. note::
> ++            The ``session_handle`` is an object path that was erroneously 
> implemented
> ++            as ``s``. For backwards compatibility it will remain this type.
> ++
> ++        This method was added in version 2 of this interface.
> ++    -->
> ++    <method name="CreateMonitor">
> ++      <arg type="s" name="window" direction="in"/>
> ++      <annotation name="org.qtproject.QtDBus.QtTypeName.In1" 
> value="QVariantMap"/>
> ++      <arg type="a{sv}" name="options" direction="in"/>
> ++      <arg type="o" name="handle" direction="out"/>
> ++    </method>
> ++
> ++    <!--
> ++        StateChanged:
> ++        @session_handle: Object path for the 
> :ref:`org.freedesktop.portal.Session` object
> ++        @state: Vardict with information about the session state
> ++
> ++        The StateChanged signal is sent to active monitoring sessions when
> ++        the session state changes.
> ++
> ++        When the session state changes to 'Query End', clients with active 
> monitoring
> ++        sessions are expected to respond by calling
> ++        org.freedesktop.portal.Inhibit.QueryEndResponse() within a second
> ++        of receiving the StateChanged signal. They may call 
> org.freedesktop.portal.Inhibit.Inhibit()
> ++        first to inhibit logout, to prevent the session from proceeding to 
> the Ending state.
> ++
> ++        The following information may get returned in the @state vardict:
> ++
> ++        * ``screensaver-active`` (``b``)
> ++
> ++          Whether the screensaver is active.
> ++
> ++        * ``session-state`` (``u``)
> ++
> ++          The state of the session. This member is new in version 3.
> ++
> ++          - ``1``: Running
> ++          - ``2``: Query End
> ++          - ``3``: Ending
> ++
> ++    -->
> ++    <signal name="StateChanged">
> ++      <arg type="o" name="session_handle" direction="out"/>
> ++      <annotation name="org.qtproject.QtDBus.QtTypeName.Out1" 
> value="QVariantMap"/>
> ++      <arg type="a{sv}" name="state" direction="out"/>
> ++    </signal>
> ++
> ++    <!--
> ++      QueryEndResponse:
> ++      @session_handle: Object path for the 
> :ref:`org.freedesktop.portal.Session` object
> ++
> ++      Acknowledges that the caller received the 
> #org.freedesktop.portal.Inhibit::StateChanged
> ++      signal. This method should be called within one second or receiving a 
> StateChanged
> ++      signal with the 'Query End' state.
> ++
> ++      Since version 3.
> ++    -->
> ++    <method name="QueryEndResponse">
> ++      <arg type="o" name="session_handle" direction="in"/>
> ++    </method>
> ++
> ++    <property name="version" type="u" access="read"/>
> ++  </interface>
> ++</node>
> +diff --git a/src/core/org.freedesktop.portal.Request.xml 
> b/src/core/org.freedesktop.portal.Request.xml
> +new file mode 100644
> +index 000000000..e8a26484e
> +--- /dev/null
> ++++ b/src/core/org.freedesktop.portal.Request.xml
> +@@ -0,0 +1,93 @@
> ++<?xml version="1.0"?>
> ++<!--
> ++ Copyright (C) 2015 Red Hat, Inc.
> ++
> ++ SPDX-License-Identifier: LGPL-2.1-or-later
> ++
> ++ This library is free software; you can redistribute it and/or
> ++ modify it under the terms of the GNU Lesser General Public
> ++ License as published by the Free Software Foundation; either
> ++ version 2.1 of the License, or (at your option) any later version.
> ++
> ++ This library is distributed in the hope that it will be useful,
> ++ but WITHOUT ANY WARRANTY; without even the implied warranty of
> ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> ++ Lesser General Public License for more details.
> ++
> ++ You should have received a copy of the GNU Lesser General Public
> ++ License along with this library. If not, see 
> <http://www.gnu.org/licenses/>.
> ++
> ++ Author: Alexander Larsson <al...@redhat.com>
> ++-->
> ++
> ++<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd";>
> ++  <!--
> ++      org.freedesktop.portal.Request:
> ++      @short_description: Shared request interface
> ++
> ++      The Request interface is shared by all portal interfaces. When a
> ++      portal method is called, the reply includes a handle (i.e. object 
> path)
> ++      for a Request object, which will stay alive for the duration of the
> ++      user interaction related to the method call.
> ++
> ++      The portal indicates that a portal request interaction is over by
> ++      emitting the #org.freedesktop.portal.Request::Response signal on the
> ++      Request object.
> ++
> ++      The application can abort the interaction calling
> ++      org.freedesktop.portal.Request.Close() on the Request object.
> ++
> ++      Since version 0.9 of xdg-desktop-portal, the handle will be of the 
> form
> ++
> ++      ::
> ++
> ++        /org/freedesktop/portal/desktop/request/SENDER/TOKEN
> ++
> ++
> ++      where ``SENDER`` is the callers unique name, with the initial ``':'`` 
> removed and
> ++      all ``'.'`` replaced by ``'_'``, and ``TOKEN`` is a unique token that 
> the caller provided
> ++      with the handle_token key in the options vardict.
> ++
> ++      This change was made to let applications subscribe to the Response 
> signal before
> ++      making the initial portal call, thereby avoiding a race condition. It 
> is recommended
> ++      that the caller should verify that the returned handle is what it 
> expected, and update
> ++      its signal subscription if it isn't. This ensures that applications 
> will work with both
> ++      old and new versions of xdg-desktop-portal.
> ++
> ++      The token that the caller provides should be unique and not 
> guessable. To avoid clashes
> ++      with calls made from unrelated libraries, it is a good idea to use a 
> per-library prefix
> ++      combined with a random number.
> ++  -->
> ++  <interface name="org.freedesktop.portal.Request">
> ++
> ++    <!--
> ++        Close:
> ++
> ++        Closes the portal request to which this object refers and ends all
> ++        related user interaction (dialogs, etc).
> ++
> ++        A Response signal will not be emitted in this case.
> ++    -->
> ++    <method name="Close">
> ++    </method>
> ++
> ++    <!--
> ++        Response:
> ++        @response: Numeric response
> ++        @results: Vardict with results. The keys and values in the vardict 
> depend on the request.
> ++
> ++        Emitted when the user interaction for a portal request is over.
> ++
> ++        The @response indicates how the user interaction ended:
> ++
> ++        - 0: Success, the request is carried out
> ++        - 1: The user cancelled the interaction
> ++        - 2: The user interaction was ended in some other way
> ++    -->
> ++    <signal name="Response">
> ++      <arg type="u" name="response"/>
> ++      <annotation name="org.qtproject.QtDBus.QtTypeName.Out1" 
> value="QVariantMap"/>
> ++      <arg type="a{sv}" name="results"/>
> ++    </signal>
> ++  </interface>
> ++</node>
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_3e6175e4_KFilePlacesView-Show-busy-indicator-while-emptying-trash.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_3e6175e4_KFilePlacesView-Show-busy-indicator-while-emptying-trash.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_3e6175e4_KFilePlacesView-Show-busy-indicator-while-emptying-trash.patch
>     1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_3e6175e4_KFilePlacesView-Show-busy-indicator-while-emptying-trash.patch
>     2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,151 @@
> +From 3e6175e4cf2898a0b9a15c6218765f6e8d7fd57c Mon Sep 17 00:00:00 2001
> +From: Kai Uwe Broulik <k...@privat.broulik.de>
> +Date: Thu, 1 May 2025 19:02:48 +0200
> +Subject: [PATCH] KFilePlacesView: Show busy indicator while emptying trash
> +
> +Provide some feedback to the user in case it's taking a bit.
> +---
> + src/filewidgets/kfileplacesview.cpp | 49 +++++++++++++++++++++++------
> + src/filewidgets/kfileplacesview_p.h |  4 +++
> + 2 files changed, 43 insertions(+), 10 deletions(-)
> +
> +diff --git a/src/filewidgets/kfileplacesview.cpp 
> b/src/filewidgets/kfileplacesview.cpp
> +index d2488ec32..30ca95f22 100644
> +--- a/src/filewidgets/kfileplacesview.cpp
> ++++ b/src/filewidgets/kfileplacesview.cpp
> +@@ -154,7 +154,8 @@ void KFilePlacesViewDelegate::paint(QPainter *painter, 
> const QStyleOptionViewIte
> +     QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, 
> &opt, painter);
> + 
> +     const auto accessibility = placesModel->deviceAccessibility(index);
> +-    const bool isBusy = (accessibility == KFilePlacesModel::SetupInProgress 
> || accessibility == KFilePlacesModel::TeardownInProgress);
> ++    const bool isBusy = (accessibility == KFilePlacesModel::SetupInProgress 
> || accessibility == KFilePlacesModel::TeardownInProgress)
> ++        || (m_emptyingTrashIndex.isValid() && m_emptyingTrashIndex == 
> index);
> + 
> +     QIcon actionIcon;
> +     if (isBusy) {
> +@@ -458,6 +459,16 @@ void KFilePlacesViewDelegate::setHoveredAction(const 
> QModelIndex &index)
> +     m_hoveredAction = index;
> + }
> + 
> ++QModelIndex KFilePlacesViewDelegate::emptyingTrashIndex() const
> ++{
> ++    return m_emptyingTrashIndex;
> ++}
> ++
> ++void KFilePlacesViewDelegate::setEmptyingTrashIndex(const QModelIndex 
> &index)
> ++{
> ++    m_emptyingTrashIndex = index;
> ++}
> ++
> + bool KFilePlacesViewDelegate::pointIsHeaderArea(const QPoint &pos) const
> + {
> +     // we only accept drag events starting from item body, ignore drag 
> request from header
> +@@ -769,9 +780,11 @@ public:
> +     void itemAppearUpdate(qreal value);
> +     void itemDisappearUpdate(qreal value);
> +     void enableSmoothItemResizing();
> +-    void slotEmptyTrash();
> ++    void slotEmptyTrash(const QModelIndex &index);
> + 
> +     void deviceBusyAnimationValueChanged(const QVariant &value);
> ++    void startOrStopBusyAnimation();
> ++    void setEmptyingTrashIndex(const QModelIndex &index);
> + 
> +     KFilePlacesView *const q;
> + 
> +@@ -1123,8 +1136,9 @@ void KFilePlacesViewPrivate::writeConfig()
> +     cg.sync();
> + }
> + 
> +-void KFilePlacesViewPrivate::slotEmptyTrash()
> ++void KFilePlacesViewPrivate::slotEmptyTrash(const QModelIndex &index)
> + {
> ++    QPersistentModelIndex persistentIndex(index);
> +     auto *parentWindow = q->window();
> + 
> +     using AskIface = KIO::AskUserActionInterface;
> +@@ -1132,9 +1146,26 @@ void KFilePlacesViewPrivate::slotEmptyTrash()
> +                                                     AskIface::EmptyTrash,
> +                                                     
> AskIface::DefaultConfirmation,
> +                                                     parentWindow);
> ++    QObject::connect(emptyTrashJob, &KIO::DeleteOrTrashJob::started, q, 
> [this, persistentIndex] {
> ++        m_delegate->setEmptyingTrashIndex(persistentIndex);
> ++        startOrStopBusyAnimation();
> ++    });
> ++    QObject::connect(emptyTrashJob, &KJob::finished, q, [this] {
> ++        m_delegate->setEmptyingTrashIndex({});
> ++        startOrStopBusyAnimation();
> ++    });
> +     emptyTrashJob->start();
> + }
> + 
> ++void KFilePlacesViewPrivate::startOrStopBusyAnimation()
> ++{
> ++    if (!m_busyDevices.isEmpty() || 
> m_delegate->emptyingTrashIndex().isValid()) {
> ++        m_deviceBusyAnimation.start();
> ++    } else {
> ++        m_deviceBusyAnimation.stop();
> ++    }
> ++}
> ++
> + void KFilePlacesView::contextMenuEvent(QContextMenuEvent *event)
> + {
> +     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel 
> *>(model());
> +@@ -1327,7 +1358,7 @@ void 
> KFilePlacesView::contextMenuEvent(QContextMenuEvent *event)
> + 
> +     if (result) {
> +         if (result == emptyTrash) {
> +-            d->slotEmptyTrash();
> ++            d->slotEmptyTrash(index);
> + 
> +         } else if (result == eject) {
> +             placesModel->requestEject(index);
> +@@ -2136,6 +2167,9 @@ void 
> KFilePlacesViewPrivate::deviceBusyAnimationValueChanged(const QVariant &val
> +     for (const auto &idx : std::as_const(m_busyDevices)) {
> +         q->update(idx);
> +     }
> ++    if (m_delegate->emptyingTrashIndex().isValid()) {
> ++        q->update(m_delegate->emptyingTrashIndex());
> ++    }
> + }
> + 
> + void KFilePlacesView::dataChanged(const QModelIndex &topLeft, const 
> QModelIndex &bottomRight, const QList<int> &roles)
> +@@ -2156,12 +2190,7 @@ void KFilePlacesView::dataChanged(const QModelIndex 
> &topLeft, const QModelIndex
> +         }
> + 
> +         d->m_busyDevices = busyDevices;
> +-
> +-        if (busyDevices.isEmpty()) {
> +-            d->m_deviceBusyAnimation.stop();
> +-        } else {
> +-            d->m_deviceBusyAnimation.start();
> +-        }
> ++        d->startOrStopBusyAnimation();
> +     }
> + }
> + 
> +diff --git a/src/filewidgets/kfileplacesview_p.h 
> b/src/filewidgets/kfileplacesview_p.h
> +index 694d555e0..b51516dce 100644
> +--- a/src/filewidgets/kfileplacesview_p.h
> ++++ b/src/filewidgets/kfileplacesview_p.h
> +@@ -58,6 +58,9 @@ public:
> +     void setHoveredHeaderArea(const QModelIndex &index);
> +     void setHoveredAction(const QModelIndex &index);
> + 
> ++    QModelIndex emptyingTrashIndex() const;
> ++    void setEmptyingTrashIndex(const QModelIndex &index);
> ++
> +     qreal contentsOpacity(const QModelIndex &index) const;
> + 
> +     bool pointIsHeaderArea(const QPoint &pos) const;
> +@@ -100,6 +103,7 @@ private:
> +     qreal m_disappearingOpacity;
> + 
> +     qreal m_busyAnimationRotation = 0.0;
> ++    QPersistentModelIndex m_emptyingTrashIndex;
> + 
> +     bool m_showHoverIndication;
> +     QPersistentModelIndex m_hoveredHeaderArea;
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_60191c04_CopyJob-Inhibit-suspend-during-copy-operation.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_60191c04_CopyJob-Inhibit-suspend-during-copy-operation.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_60191c04_CopyJob-Inhibit-suspend-during-copy-operation.patch
>        1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_60191c04_CopyJob-Inhibit-suspend-during-copy-operation.patch
>        2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,75 @@
> +From 60191c0473a96c41279519845030efa12fdd0bb4 Mon Sep 17 00:00:00 2001
> +From: Kai Uwe Broulik <k...@privat.broulik.de>
> +Date: Sun, 20 Apr 2025 12:48:58 +0200
> +Subject: [PATCH] CopyJob: Inhibit suspend during copy operation
> +
> +Avoids the system going to sleep during a lengthy copy operation.
> +
> +BUG: 362542
> +---
> + src/core/copyjob.cpp | 21 +++++++++++++++++++++
> + 1 file changed, 21 insertions(+)
> +
> +diff --git a/src/core/copyjob.cpp b/src/core/copyjob.cpp
> +index d1e3eef61..21e1ff487 100644
> +--- a/src/core/copyjob.cpp
> ++++ b/src/core/copyjob.cpp
> +@@ -57,6 +57,7 @@
> + #include <KFileUtils>
> + #include <KIO/FileSystemFreeSpaceJob>
> + 
> ++#include <chrono>
> + #include <list>
> + #include <set>
> + 
> +@@ -65,6 +66,7 @@ Q_DECLARE_LOGGING_CATEGORY(KIO_COPYJOB_DEBUG)
> + Q_LOGGING_CATEGORY(KIO_COPYJOB_DEBUG, "kf.kio.core.copyjob", QtWarningMsg)
> + 
> + using namespace KIO;
> ++using namespace std::literals::chrono_literals;
> + 
> + // this will update the report dialog with 5 Hz, I think this is fast 
> enough, aleXXX
> + static constexpr int s_reportTimeout = 200;
> +@@ -399,6 +401,8 @@ public:
> + 
> +     void slotReport();
> + 
> ++    void doInhibitSuspend() override;
> ++
> +     Q_DECLARE_PUBLIC(CopyJob)
> + 
> +     static inline CopyJob *newJob(const QList<QUrl> &src, const QUrl &dest, 
> CopyJob::CopyMode mode, bool asMethod, JobFlags flags)
> +@@ -493,6 +497,11 @@ void CopyJobPrivate::slotStart()
> +         }
> +     }
> + 
> ++    // Avoid DBus traffic for short-lived jobs.
> ++    QTimer::singleShot(10s, q, [this] {
> ++        doInhibitSuspend();
> ++    });
> ++
> +     /**
> +        We call the functions directly instead of using signals.
> +        Calling a function via a signal takes approx. 65 times the time
> +@@ -736,6 +745,18 @@ bool CopyJob::doResume()
> +     return Job::doResume();
> + }
> + 
> ++void CopyJobPrivate::doInhibitSuspend()
> ++{
> ++    QString reason;
> ++    if (m_mode == CopyJob::Move) {
> ++        reason = i18nc("Reason why standby is blocked", "Files are being 
> moved");
> ++    } else {
> ++        reason = i18nc("Reason why standby is blocked", "Files are being 
> copied");
> ++    }
> ++
> ++    inhibitSuspend(reason);
> ++}
> ++
> + void CopyJobPrivate::slotReport()
> + {
> +     Q_Q(CopyJob);
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_719e0b00_KFileWidget-Fix-key-navigation-escaping-in-save-dialogs.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_719e0b00_KFileWidget-Fix-key-navigation-escaping-in-save-dialogs.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_719e0b00_KFileWidget-Fix-key-navigation-escaping-in-save-dialogs.patch
>      1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_719e0b00_KFileWidget-Fix-key-navigation-escaping-in-save-dialogs.patch
>      2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,143 @@
> +From 719e0b0031155ef83a2cf71d6d24114dea181353 Mon Sep 17 00:00:00 2001
> +From: Akseli Lahtinen <akse...@akselmo.dev>
> +Date: Wed, 7 May 2025 16:35:19 +0300
> +Subject: [PATCH] KFileWidget: Fix key navigation escaping in save dialogs
> +
> +In save dialogs the keyboard navigation would escape during file
> +highlighting, since the fileHighlight sets the focus for fileName bar
> +for mouse operations.
> +
> +This makes sure the user has to press Tab to explicitly escape the
> +keyboard navigation mode. For clicking the items, it should not affect
> +at all.
> +
> +CCBUG: 466206
> +FIXED-IN: 6.14
> +(cherry picked from commit 8e4e84f045b7459c0b02b1b1b51a9df73cea068a)
> +---
> + src/filewidgets/kdiroperator.cpp | 21 +++++++++++++++++++++
> + src/filewidgets/kdiroperator.h   |  7 +++++++
> + src/filewidgets/kfilewidget.cpp  |  8 ++++----
> + 3 files changed, 32 insertions(+), 4 deletions(-)
> +
> +diff --git a/src/filewidgets/kdiroperator.cpp 
> b/src/filewidgets/kdiroperator.cpp
> +index e1d3afeea..4a2e400c7 100644
> +--- a/src/filewidgets/kdiroperator.cpp
> ++++ b/src/filewidgets/kdiroperator.cpp
> +@@ -221,6 +221,7 @@ public:
> +     bool m_showOpenWithActions = false;
> +     bool m_isTouchEvent = false;
> +     bool m_isTouchDrag = false;
> ++    bool m_keyNavigation = false;
> + 
> +     QList<QUrl> m_itemsToBeSetAsCurrent;
> +     QStringList m_supportedSchemes;
> +@@ -1244,6 +1245,11 @@ void KDirOperator::showOpenWithActions(bool enable)
> +     d->m_showOpenWithActions = enable;
> + }
> + 
> ++bool KDirOperator::usingKeyNavigation()
> ++{
> ++    return d->m_keyNavigation;
> ++}
> ++
> + void KDirOperator::changeEvent(QEvent *event)
> + {
> +     QWidget::changeEvent(event);
> +@@ -1429,6 +1435,19 @@ bool KDirOperator::eventFilter(QObject *watched, 
> QEvent *event)
> +                 return true;
> +             }
> +         }
> ++        // Only use tab key to escape the view navigation
> ++        if (evt->key() == Qt::Key_Tab) {
> ++            d->m_keyNavigation = false;
> ++            d->slotSelectionChanged();
> ++            // When saving we need to return here,
> ++            // otherwise we skip over the next item with our tab press
> ++            // since we focus on that item in slotSelectionChanged
> ++            if (d->m_isSaving) {
> ++                return true;
> ++            }
> ++        } else {
> ++            d->m_keyNavigation = true;
> ++        }
> +         break;
> +     }
> +     case QEvent::Resize: {
> +@@ -1833,6 +1852,7 @@ void KDirOperator::selectFile(const KFileItem &item)
> +     QApplication::restoreOverrideCursor();
> + 
> +     Q_EMIT fileSelected(item);
> ++    d->m_keyNavigation = false;
> + }
> + 
> + void KDirOperator::highlightFile(const KFileItem &item)
> +@@ -1842,6 +1862,7 @@ void KDirOperator::highlightFile(const KFileItem &item)
> +     }
> + 
> +     Q_EMIT fileHighlighted(item);
> ++    d->m_keyNavigation = false;
> + }
> + 
> + void KDirOperator::setCurrentItem(const QUrl &url)
> +diff --git a/src/filewidgets/kdiroperator.h b/src/filewidgets/kdiroperator.h
> +index c34880564..71a20ed2e 100644
> +--- a/src/filewidgets/kdiroperator.h
> ++++ b/src/filewidgets/kdiroperator.h
> +@@ -744,6 +744,13 @@ public:
> +      */
> +     void showOpenWithActions(bool enable);
> + 
> ++    /*!
> ++     * @returns true if the user was using keys to navigate.
> ++     *
> ++     * \since 6.14
> ++     */
> ++    bool usingKeyNavigation();
> ++
> + protected:
> +     /**
> +      * A view factory for creating predefined fileviews. Called internally 
> by setView,
> +diff --git a/src/filewidgets/kfilewidget.cpp 
> b/src/filewidgets/kfilewidget.cpp
> +index 5175a085a..017e65d1e 100644
> +--- a/src/filewidgets/kfilewidget.cpp
> ++++ b/src/filewidgets/kfilewidget.cpp
> +@@ -168,7 +168,7 @@ public:
> +     void enterUrl(const QString &);
> +     void locationAccepted(const QString &);
> +     void slotFilterChanged();
> +-    void fileHighlighted(const KFileItem &);
> ++    void fileHighlighted(const KFileItem &, bool);
> +     void fileSelected(const KFileItem &);
> +     void slotLoadingFinished();
> +     void togglePlacesPanel(bool show, QObject *sender = nullptr);
> +@@ -894,7 +894,7 @@ void KFileWidget::accept()
> +     d->m_ops->close();
> + }
> + 
> +-void KFileWidgetPrivate::fileHighlighted(const KFileItem &i)
> ++void KFileWidgetPrivate::fileHighlighted(const KFileItem &i, bool 
> isKeyNavigation)
> + {
> +     if ((m_locationEdit->hasFocus() && 
> !m_locationEdit->currentText().isEmpty())) { // don't disturb
> +         return;
> +@@ -933,7 +933,7 @@ void KFileWidgetPrivate::fileHighlighted(const KFileItem 
> &i)
> +     // rename it if desired
> +     // Note that double-clicking will override this and overwrite 
> regardless of
> +     // single/double click mouse setting (see slotViewDoubleClicked() )
> +-    if (m_operationMode == KFileWidget::Saving) {
> ++    if (!isKeyNavigation && m_operationMode == KFileWidget::Saving) {
> +         m_locationEdit->setFocus();
> +     }
> + }
> +@@ -1100,7 +1100,7 @@ void KFileWidgetPrivate::initDirOpWidgets()
> +         urlEntered(url);
> +     });
> +     q->connect(m_ops, &KDirOperator::fileHighlighted, q, [this](const 
> KFileItem &item) {
> +-        fileHighlighted(item);
> ++        fileHighlighted(item, m_ops->usingKeyNavigation());
> +     });
> +     q->connect(m_ops, &KDirOperator::fileSelected, q, [this](const 
> KFileItem &item) {
> +         fileSelected(item);
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_81ca0e2c_Fix-incorrect-usage-percentage-in-Properties-dialog-for-virtual-filesystems.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_81ca0e2c_Fix-incorrect-usage-percentage-in-Properties-dialog-for-virtual-filesystems.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_81ca0e2c_Fix-incorrect-usage-percentage-in-Properties-dialog-for-virtual-filesystems.patch
>  1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_81ca0e2c_Fix-incorrect-usage-percentage-in-Properties-dialog-for-virtual-filesystems.patch
>  2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,30 @@
> +From 81ca0e2c50dc02873f04dfc6266ae4e4b88607a7 Mon Sep 17 00:00:00 2001
> +From: =?UTF-8?q?Efe=20=C3=87iftci?= <efecif...@gmail.com>
> +Date: Fri, 16 May 2025 20:50:21 +0300
> +Subject: [PATCH] Fix incorrect usage percentage in Properties dialog for
> + virtual filesystems
> +
> +The Properties dialog for filesystems such as `/proc/` or `/sys/` shows an
> +incorrect usage percentage (i.e., "-2,147,483,648% used"). This commit fixes
> +that issue by avoiding a divbyzero: if the `size` variable is `0`, the
> +`percentUsed` variable is set to `0`.
> +---
> + src/widgets/kpropertiesdialogbuiltin_p.cpp | 2 +-
> + 1 file changed, 1 insertion(+), 1 deletion(-)
> +
> +diff --git a/src/widgets/kpropertiesdialogbuiltin_p.cpp 
> b/src/widgets/kpropertiesdialogbuiltin_p.cpp
> +index 45091fe755..919c044c4c 100644
> +--- a/src/widgets/kpropertiesdialogbuiltin_p.cpp
> ++++ b/src/widgets/kpropertiesdialogbuiltin_p.cpp
> +@@ -664,7 +664,7 @@ void KFilePropsPlugin::slotFreeSpaceResult(KJob *_job)
> +         const qint64 size = job->size();
> +         const qint64 available = job->availableSize();
> +         const quint64 used = size - available;
> +-        const int percentUsed = qRound(100.0 * qreal(used) / qreal(size));
> ++        const int percentUsed = (size == 0) ? 0 : qRound(100.0 * 
> qreal(used) / qreal(size));
> + 
> +         d->m_ui->capacityBar->setText(i18nc("Available space out of total 
> partition size (percent used)",
> +                                             "%1 free of %2 (%3% used)",
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_9143fc2a_Fix-dialog-modality-settings.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_9143fc2a_Fix-dialog-modality-settings.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_9143fc2a_Fix-dialog-modality-settings.patch
>         1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_9143fc2a_Fix-dialog-modality-settings.patch
>         2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,38 @@
> +From 9143fc2a5962d190e36f6e99d9ca1c02506097a5 Mon Sep 17 00:00:00 2001
> +From: Akseli Lahtinen <akse...@akselmo.dev>
> +Date: Thu, 22 May 2025 17:35:24 +0300
> +Subject: [PATCH] Fix dialog modality settings
> +
> +By default all dialogs are ApplicationModal, thus they block clicking
> +on any other app while the dialog is open.
> +
> +Set them to WindowModal so they only block the parent window.
> +
> +BUG: 504608
> +---
> + src/widgets/kpropertiesdialogbuiltin_p.cpp | 2 ++
> + 1 file changed, 2 insertions(+)
> +
> +diff --git a/src/widgets/kpropertiesdialogbuiltin_p.cpp 
> b/src/widgets/kpropertiesdialogbuiltin_p.cpp
> +index 919c044c4c..a21330d0b2 100644
> +--- a/src/widgets/kpropertiesdialogbuiltin_p.cpp
> ++++ b/src/widgets/kpropertiesdialogbuiltin_p.cpp
> +@@ -1354,6 +1354,7 @@ void 
> KFilePermissionsPropsPlugin::slotShowAdvancedPermissions()
> + {
> +     bool isDir = (d->pmode == PermissionsOnlyDirs) || (d->pmode == 
> PermissionsMixed);
> +     QDialog dlg(properties);
> ++    dlg.setWindowModality(Qt::WindowModal);
> +     dlg.setModal(true);
> +     dlg.setWindowTitle(i18n("Advanced Permissions"));
> + 
> +@@ -2880,6 +2881,7 @@ void KDesktopPropsPlugin::slotAdvanced()
> + {
> +     auto *dlg = new QDialog(d->m_frame);
> +     dlg->setObjectName(QStringLiteral("KPropertiesDesktopAdv"));
> ++    dlg->setWindowModality(Qt::WindowModal);
> +     dlg->setModal(true);
> +     dlg->setAttribute(Qt::WA_DeleteOnClose);
> +     dlg->setWindowTitle(i18n("Advanced Options for %1", 
> properties->url().fileName()));
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_c747fa0f_Avoid-unnecessary-sequencing-jobs-in-PreviewGenerator.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_c747fa0f_Avoid-unnecessary-sequencing-jobs-in-PreviewGenerator.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_c747fa0f_Avoid-unnecessary-sequencing-jobs-in-PreviewGenerator.patch
>        1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_c747fa0f_Avoid-unnecessary-sequencing-jobs-in-PreviewGenerator.patch
>        2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,138 @@
> +From c747fa0f4143ee730cefd6cd26d14c09e89cf3ef Mon Sep 17 00:00:00 2001
> +From: Akseli Lahtinen <akse...@akselmo.dev>
> +Date: Tue, 13 May 2025 13:01:07 +0300
> +Subject: [PATCH] Avoid unnecessary sequencing jobs in PreviewGenerator
> +
> +Currently we keep constantly asking if the current item has sequences
> +support or not.
> +
> +By sequences we mean things like hovering mouse over a folder thumbnail
> +and it goes through the files in it.
> +
> +This MR will always run for the first sequence (the initial thumbnail)
> +but for the rest, then toggles a flag for the node with
> +Qt::DecorationPropertyRole. If the propertyrole is false, it skips any
> +further updates to avoid any unnecessary previewjob runs.
> +---
> + src/filewidgets/kfilepreviewgenerator.cpp |  5 +++++
> + src/gui/previewjob.cpp                    |  2 ++
> + src/widgets/delegateanimationhandler.cpp  |  7 +++++--
> + src/widgets/kdirmodel.cpp                 | 24 +++++++++++++++++++++++
> + src/widgets/kdirmodel.h                   |  1 +
> + 5 files changed, 37 insertions(+), 2 deletions(-)
> +
> +diff --git a/src/filewidgets/kfilepreviewgenerator.cpp 
> b/src/filewidgets/kfilepreviewgenerator.cpp
> +index 019124c618..639221fbe5 100644
> +--- a/src/filewidgets/kfilepreviewgenerator.cpp
> ++++ b/src/filewidgets/kfilepreviewgenerator.cpp
> +@@ -1015,6 +1015,11 @@ void 
> KFilePreviewGeneratorPrivate::startPreviewJob(const KFileItemList &items, i
> + 
> +     q->connect(job, &KIO::PreviewJob::gotPreview, q, [this, job](const 
> KFileItem &item, const QPixmap &pixmap) {
> +         addToPreviewQueue(item, pixmap, job);
> ++        m_dirModel->setData(m_dirModel->indexForItem(item), 
> job->handlesSequences(), KDirModel::HandleSequencesRole);
> ++    });
> ++
> ++    q->connect(job, &KIO::PreviewJob::failed, q, [this, job](const 
> KFileItem &item) {
> ++        m_dirModel->setData(m_dirModel->indexForItem(item), 
> job->handlesSequences(), KDirModel::HandleSequencesRole);
> +     });
> + 
> +     q->connect(job, &KIO::PreviewJob::finished, q, [this, job]() {
> +diff --git a/src/gui/previewjob.cpp b/src/gui/previewjob.cpp
> +index bca18c9907..4d0ed030df 100644
> +--- a/src/gui/previewjob.cpp
> ++++ b/src/gui/previewjob.cpp
> +@@ -410,6 +410,8 @@ void PreviewJobPrivate::startPreview()
> +             item.standardThumbnailer = plugin.description() == 
> QStringLiteral("standardthumbnailer");
> +             item.plugin = plugin;
> +             items.push_back(item);
> ++            bool handlesSequencesValue = 
> item.plugin.value(QStringLiteral("HandleSequences"), false);
> ++            
> thumbnailWorkerMetaData.insert(QStringLiteral("handlesSequences"), 
> QString::number(handlesSequencesValue));
> + 
> +             if (!bNeedCache && bSave && 
> plugin.value(QStringLiteral("CacheThumbnail"), true)) {
> +                 const QUrl url = fileItem.targetUrl();
> +diff --git a/src/widgets/delegateanimationhandler.cpp 
> b/src/widgets/delegateanimationhandler.cpp
> +index 9d8f81beb8..741416a944 100644
> +--- a/src/widgets/delegateanimationhandler.cpp
> ++++ b/src/widgets/delegateanimationhandler.cpp
> +@@ -200,8 +200,11 @@ void DelegateAnimationHandler::sequenceTimerTimeout()
> +     KDirModel *dirModel = dynamic_cast<KDirModel *>(model);
> +     if (dirModel) {
> +         // qDebug() << "requesting" << currentSequenceIndex;
> +-        dirModel->requestSequenceIcon(index, currentSequenceIndex);
> +-        iconSequenceTimer.start(); // Some upper-bound interval is needed, 
> in case items are not generated
> ++        // Only request sequence icons for items that have them
> ++        if (dirModel->data(index, KDirModel::HandleSequencesRole).toBool()) 
> {
> ++            dirModel->requestSequenceIcon(index, currentSequenceIndex);
> ++            iconSequenceTimer.start(); // Some upper-bound interval is 
> needed, in case items are not generated
> ++        }
> +     }
> + }
> + 
> +diff --git a/src/widgets/kdirmodel.cpp b/src/widgets/kdirmodel.cpp
> +index 281a8a69e4..aa73a7f776 100644
> +--- a/src/widgets/kdirmodel.cpp
> ++++ b/src/widgets/kdirmodel.cpp
> +@@ -101,10 +101,21 @@ public:
> +         m_preview = icn;
> +     }
> + 
> ++    bool previewHandlesSequences()
> ++    {
> ++        return m_previewHandlesSequences;
> ++    }
> ++
> ++    void setPreviewHandlesSequences(bool handlesSequences)
> ++    {
> ++        m_previewHandlesSequences = handlesSequences;
> ++    }
> ++
> + private:
> +     KFileItem m_item;
> +     KDirModelDirNode *const m_parent;
> +     QIcon m_preview;
> ++    bool m_previewHandlesSequences = true; // First sequence is always 
> allowed
> + };
> + 
> + // Specialization for directory nodes
> +@@ -915,6 +926,11 @@ QVariant KDirModel::data(const QModelIndex &index, int 
> role) const
> +                 }
> +             }
> +             break;
> ++        case HandleSequencesRole:
> ++            if (index.column() == Name) {
> ++                return node->previewHandlesSequences();
> ++            }
> ++            break;
> +         case Qt::TextAlignmentRole:
> +             if (index.column() == Size) {
> +                 // use a right alignment for L2R and R2L languages
> +@@ -1034,6 +1050,14 @@ bool KDirModel::setData(const QModelIndex &index, 
> const QVariant &value, int rol
> +             return true;
> +         }
> +         break;
> ++    case HandleSequencesRole:
> ++        if (index.column() == Name) {
> ++            KDirModelNode *node = static_cast<KDirModelNode 
> *>(index.internalPointer());
> ++            Q_ASSERT(node);
> ++            node->setPreviewHandlesSequences(value.toBool());
> ++            return true;
> ++        }
> ++        break;
> +     default:
> +         break;
> +     }
> +diff --git a/src/widgets/kdirmodel.h b/src/widgets/kdirmodel.h
> +index 64d315c43b..bf5a72c28c 100644
> +--- a/src/widgets/kdirmodel.h
> ++++ b/src/widgets/kdirmodel.h
> +@@ -180,6 +180,7 @@ public:
> +         FileItemRole = 0x07A263FF, ///< returns the KFileItem for a given 
> index. roleName is "fileItem".
> +         ChildCountRole = 0x2C4D0A40, ///< returns the number of items in a 
> directory, or ChildCountUnknown. roleName is "childCount".
> +         HasJobRole = 0x01E555A5, ///< returns whether or not there is a job 
> on an item (file/directory). roleName is "hasJob".
> ++        HandleSequencesRole = 0x1E642272,
> +     };
> + 
> +     /**
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_cd0810f8_KFileWidget-Do-not-override-filename-with-folder-name-if-edited.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_cd0810f8_KFileWidget-Do-not-override-filename-with-folder-name-if-edited.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_cd0810f8_KFileWidget-Do-not-override-filename-with-folder-name-if-edited.patch
>      1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_cd0810f8_KFileWidget-Do-not-override-filename-with-folder-name-if-edited.patch
>      2025-05-20 08:47:36.000000000 +0200
> @@ -0,0 +1,150 @@
> +From cd0810f82d9fce629fa27e2a1d330fbcc8d2edf6 Mon Sep 17 00:00:00 2001
> +From: Akseli Lahtinen <akse...@akselmo.dev>
> +Date: Thu, 17 Apr 2025 08:43:26 +0000
> +Subject: [PATCH] KFileWidget: Do not override filename with folder name if
> + edited
> +
> +If the filename input has been modified, do not override it with
> +the name of the folder when selecting a folder.
> +
> +BUG: 502794
> +FIXED-IN: 6.14
> +---
> + autotests/kfilewidgettest.cpp   | 85 +++++++++++++++++++++++++++++++++
> + src/filewidgets/kdiroperator.h  |  1 +
> + src/filewidgets/kfilewidget.cpp |  4 ++
> + 3 files changed, 90 insertions(+)
> +
> +diff --git a/autotests/kfilewidgettest.cpp b/autotests/kfilewidgettest.cpp
> +index cd04b57c4..e0ff3945d 100644
> +--- a/autotests/kfilewidgettest.cpp
> ++++ b/autotests/kfilewidgettest.cpp
> +@@ -87,6 +87,8 @@ private Q_SLOTS:
> +     void testTokenizeForSave_data();
> +     void testTokenizeForSave();
> +     void testThumbnailPreviewSetting();
> ++    void testReplaceLocationEditFilename_data();
> ++    void testReplaceLocationEditFilename();
> + };
> + 
> + void KFileWidgetTest::initTestCase()
> +@@ -932,6 +934,89 @@ void KFileWidgetTest::testThumbnailPreviewSetting()
> +     fwPreviewFalse.cancelButton()->click();
> + }
> + 
> ++struct LocationTestItem {
> ++    bool dir;
> ++    QString name;
> ++};
> ++
> ++void KFileWidgetTest::testReplaceLocationEditFilename_data()
> ++{
> ++    QTest::addColumn<LocationTestItem>("initialItem");
> ++    QTest::addColumn<LocationTestItem>("selectedItem");
> ++    QTest::addColumn<QString>("lineEditTextResult");
> ++    QTest::addColumn<bool>("overrideModifiedText");
> ++
> ++    QTest::newRow("replace-dir-with-dir") << LocationTestItem(true, 
> "folder1") << LocationTestItem(true, "folder2") << "" << false;
> ++    QTest::newRow("replace-dir-with-file") << LocationTestItem(true, 
> "folder1") << LocationTestItem(false, "file1") << "file1" << true;
> ++    QTest::newRow("replace-file-with-file") << LocationTestItem(false, 
> "file1") << LocationTestItem(false, "file2") << "file2" << true;
> ++    QTest::newRow("replace-file-with-dir") << LocationTestItem(false, 
> "file1") << LocationTestItem(true, "folder1") << "file1" << false;
> ++}
> ++
> ++// BUG: 502794
> ++// Test that we don't override file names with folder names
> ++void KFileWidgetTest::testReplaceLocationEditFilename()
> ++{
> ++    QFETCH(LocationTestItem, initialItem);
> ++    QFETCH(LocationTestItem, selectedItem);
> ++    QFETCH(QString, lineEditTextResult);
> ++    QFETCH(bool, overrideModifiedText);
> ++
> ++    // Setup - Create folders/files in temp dir
> ++    QTemporaryDir tempDir;
> ++    const QString tempDirPath = tempDir.path();
> ++    QUrl tempDirUrl = QUrl::fromLocalFile(tempDirPath);
> ++    QUrl replacedUrl = QUrl::fromLocalFile(tempDirPath + QLatin1Char('/') + 
> initialItem.name);
> ++    QUrl selectedUrl = QUrl::fromLocalFile(tempDirPath + QLatin1Char('/') + 
> selectedItem.name);
> ++
> ++    auto createTestItem = [tempDirUrl](LocationTestItem item, const QUrl 
> &url) {
> ++        if (item.dir) {
> ++            QDir(tempDirUrl.toLocalFile()).mkdir(url.toLocalFile());
> ++            QVERIFY(QDir(url.toLocalFile()).exists());
> ++        } else {
> ++            QFile file(url.toLocalFile());
> ++            if (!file.open(QIODevice::WriteOnly)) {
> ++                qFatal("Couldn't create %s", qPrintable(url.toLocalFile()));
> ++            }
> ++            file.write(QByteArray("Test file"));
> ++            file.close();
> ++            QVERIFY(file.exists());
> ++        }
> ++    };
> ++
> ++    createTestItem(initialItem, replacedUrl);
> ++    createTestItem(selectedItem, selectedUrl);
> ++
> ++    // Open the filewidget in tempdir
> ++    KFileWidget fw(tempDirUrl);
> ++    fw.setOperationMode(KFileWidget::Saving);
> ++
> ++    // Highlight the item, then another
> ++    auto highlightItem = [&fw](QUrl url) {
> ++        KFileItem fileItem(url);
> ++        QSignalSpy fileHighlightedSpy(fw.dirOperator(), 
> &KDirOperator::fileHighlighted);
> ++        fw.dirOperator()->highlightFile(fileItem);
> ++        fileHighlightedSpy.wait(500);
> ++        QVERIFY(fileHighlightedSpy.count());
> ++    };
> ++
> ++    highlightItem(replacedUrl);
> ++    highlightItem(selectedUrl);
> ++
> ++    // Compare that we have the wanted result when selecting items
> ++    QCOMPARE(fw.locationEdit()->lineEdit()->text(), lineEditTextResult);
> ++
> ++    // Make sure we don't overwrite any text user has modified in some cases
> ++    const QString modifiedText("New Filename.txt");
> ++    fw.locationEdit()->setEditText(modifiedText);
> ++    highlightItem(selectedUrl);
> ++
> ++    if (overrideModifiedText) {
> ++        QCOMPARE(fw.locationEdit()->lineEdit()->text(), lineEditTextResult);
> ++    } else {
> ++        QCOMPARE(fw.locationEdit()->lineEdit()->text(), modifiedText);
> ++    }
> ++}
> ++
> + QTEST_MAIN(KFileWidgetTest)
> + 
> + #include "kfilewidgettest.moc"
> +diff --git a/src/filewidgets/kdiroperator.h b/src/filewidgets/kdiroperator.h
> +index 6013a39cc..818432141 100644
> +--- a/src/filewidgets/kdiroperator.h
> ++++ b/src/filewidgets/kdiroperator.h
> +@@ -1042,6 +1042,7 @@ private:
> +     KIOFILEWIDGETS_NO_EXPORT void setViewInternal(QAbstractItemView *view);
> + 
> +     friend class KDirOperatorPrivate;
> ++    friend class KFileWidgetTest; // For testing
> +     std::unique_ptr<KDirOperatorPrivate> d;
> + };
> + 
> +diff --git a/src/filewidgets/kfilewidget.cpp 
> b/src/filewidgets/kfilewidget.cpp
> +index 064efc3b3..d5afb9de3 100644
> +--- a/src/filewidgets/kfilewidget.cpp
> ++++ b/src/filewidgets/kfilewidget.cpp
> +@@ -900,6 +900,10 @@ void KFileWidgetPrivate::fileHighlighted(const 
> KFileItem &i, bool isKeyNavigatio
> +         return;
> +     }
> + 
> ++    if (!i.isNull() && i.isDir() && !(m_ops->mode() & KFile::Directory)) {
> ++        return;
> ++    }
> ++
> +     const bool modified = m_locationEdit->lineEdit()->isModified();
> + 
> +     if (!(m_ops->mode() & KFile::Files)) {
> +-- 
> +GitLab
> +
> diff -Nru 
> kf6-kio-6.13.0/debian/patches/upstream_d8441b7b_Show-single-click-selection-emblem-when-using-single-click-mouse-mode.patch
>  
> kf6-kio-6.13.0/debian/patches/upstream_d8441b7b_Show-single-click-selection-emblem-when-using-single-click-mouse-mode.patch
> --- 
> kf6-kio-6.13.0/debian/patches/upstream_d8441b7b_Show-single-click-selection-emblem-when-using-single-click-mouse-mode.patch
>        1970-01-01 01:00:00.000000000 +0100
> +++ 
> kf6-kio-6.13.0/debian/patches/upstream_d8441b7b_Show-single-click-selection-emblem-when-using-single-click-mouse-mode.patch
>        2025-05-16 22:07:04.000000000 +0200
> @@ -0,0 +1,587 @@
> +From d8441b7b5b2c8ebda18f5bde01f77ae802f4f48e Mon Sep 17 00:00:00 2001
> +From: Akseli Lahtinen <akse...@akselmo.dev>
> +Date: Wed, 9 Apr 2025 07:57:20 +0000
> +Subject: [PATCH] Show single-click selection emblem when using single-click
> + mouse mode
> +
> +In open/save dialog, we had no way to select items when using single-click 
> mouse mode. (Except holding down control key).
> +
> +This adds the same emblem that Dolphin uses for its selections.
> +
> +It is shown in both treeviews and listviews, but only when single-click mode 
> is active and the filewidget allows selecting multiple items.
> +
> +BUG: 185793
> +FIXED-IN: 6.14
> +---
> + src/filewidgets/CMakeLists.txt               |  1 +
> + src/filewidgets/kdiroperator.cpp             | 13 ++--
> + src/filewidgets/kdiroperatordetailview.cpp   | 31 +++++++++-
> + src/filewidgets/kdiroperatordetailview_p.h   |  7 ++-
> + src/filewidgets/kdiroperatoriconview.cpp     | 33 +++++++++-
> + src/filewidgets/kdiroperatoriconview_p.h     |  9 ++-
> + src/filewidgets/kfileitemselectionemblem.cpp | 63 ++++++++++++++++++++
> + src/filewidgets/kfileitemselectionemblem.h   | 39 ++++++++++++
> + src/widgets/kfileitemdelegate.cpp            | 58 ++++++++++++++++++
> + src/widgets/kfileitemdelegate.h              | 15 +++++
> + 10 files changed, 259 insertions(+), 10 deletions(-)
> + create mode 100644 src/filewidgets/kfileitemselectionemblem.cpp
> + create mode 100644 src/filewidgets/kfileitemselectionemblem.h
> +
> +diff --git a/src/filewidgets/CMakeLists.txt b/src/filewidgets/CMakeLists.txt
> +index e5fc87f75..cf4520191 100644
> +--- a/src/filewidgets/CMakeLists.txt
> ++++ b/src/filewidgets/CMakeLists.txt
> +@@ -22,6 +22,7 @@ target_sources(KF6KIOFileWidgets PRIVATE
> +   kdiroperatoriconview.cpp
> +   kdirsortfilterproxymodel.cpp #used in combination with kdirmodel.cpp
> +   kencodingfiledialog.cpp
> ++  kfileitemselectionemblem.cpp
> +   kfilebookmarkhandler.cpp
> +   kfilecopytomenu.cpp
> +   kfilecustomdialog.cpp
> +diff --git a/src/filewidgets/kdiroperator.cpp 
> b/src/filewidgets/kdiroperator.cpp
> +index d2d8a5513..e1d3afeea 100644
> +--- a/src/filewidgets/kdiroperator.cpp
> ++++ b/src/filewidgets/kdiroperator.cpp
> +@@ -17,6 +17,7 @@
> + #include "kdiroperatoriconview_p.h"
> + #include "kdirsortfilterproxymodel.h"
> + #include "kfileitem.h"
> ++#include "kfileitemselectionemblem.h"
> + #include "kfilemetapreview_p.h"
> + #include "knewfilemenu.h"
> + #include "kpreviewwidgetbase.h"
> +@@ -1260,9 +1261,13 @@ bool KDirOperator::eventFilter(QObject *watched, 
> QEvent *event)
> +         if (d->m_isTouchEvent) {
> +             return true;
> +         }
> +-        if (d->m_preview && !d->m_preview->isHidden()) {
> +-            const QModelIndex hoveredIndex = 
> d->m_itemView->indexAt(d->m_itemView->viewport()->mapFromGlobal(QCursor::pos()));
> + 
> ++        const QModelIndex hoveredIndex = 
> d->m_itemView->indexAt(d->m_itemView->viewport()->mapFromGlobal(QCursor::pos()));
> ++        if (hoveredIndex.isValid()) {
> ++            KFileItemSelectionEmblem(d->m_itemView, hoveredIndex, 
> this).updateSelectionEmblemRectForIndex(iconSize());
> ++        }
> ++
> ++        if (d->m_preview && !d->m_preview->isHidden()) {
> +             if (d->m_lastHoveredIndex == hoveredIndex) {
> +                 return QWidget::eventFilter(watched, event);
> +             }
> +@@ -1510,11 +1515,11 @@ QAbstractItemView *KDirOperator::createView(QWidget 
> *parent, KFile::FileView vie
> + {
> +     QAbstractItemView *itemView = nullptr;
> +     if (KFile::isDetailView(viewKind) || KFile::isTreeView(viewKind) || 
> KFile::isDetailTreeView(viewKind)) {
> +-        KDirOperatorDetailView *detailView = new 
> KDirOperatorDetailView(parent);
> ++        KDirOperatorDetailView *detailView = new 
> KDirOperatorDetailView(this, parent);
> +         detailView->setViewMode(viewKind);
> +         itemView = detailView;
> +     } else {
> +-        itemView = new KDirOperatorIconView(parent, decorationPosition());
> ++        itemView = new KDirOperatorIconView(this, parent, 
> decorationPosition());
> +     }
> + 
> +     return itemView;
> +diff --git a/src/filewidgets/kdiroperatordetailview.cpp 
> b/src/filewidgets/kdiroperatordetailview.cpp
> +index 8bbd3e42c..b693e6d9d 100644
> +--- a/src/filewidgets/kdiroperatordetailview.cpp
> ++++ b/src/filewidgets/kdiroperatordetailview.cpp
> +@@ -5,6 +5,7 @@
> + */
> + 
> + #include "kdiroperatordetailview_p.h"
> ++#include "kfileitemselectionemblem.h"
> + 
> + #include <kdirlister.h>
> + #include <kdirmodel.h>
> +@@ -17,9 +18,11 @@
> + #include <QMimeData>
> + #include <QScrollBar>
> + 
> +-KDirOperatorDetailView::KDirOperatorDetailView(QWidget *parent)
> ++KDirOperatorDetailView::KDirOperatorDetailView(KDirOperator *dirOperator, 
> QWidget *parent)
> +     : QTreeView(parent)
> +     , m_hideDetailColumns(false)
> ++    , m_isEmblemClicked(false)
> ++    , m_dirOperator(dirOperator)
> + {
> +     setRootIsDecorated(false);
> +     setSortingEnabled(true);
> +@@ -115,9 +118,15 @@ void 
> KDirOperatorDetailView::dragEnterEvent(QDragEnterEvent *event)
> + 
> + void KDirOperatorDetailView::mousePressEvent(QMouseEvent *event)
> + {
> ++    const QModelIndex index = indexAt(event->pos());
> ++    // When selection emblem is clicked, select it and don't do anything 
> else
> ++    m_isEmblemClicked = KFileItemSelectionEmblem(this, index, 
> m_dirOperator).handleMousePressEvent(event->pos());
> ++    if (m_isEmblemClicked) {
> ++        return;
> ++    }
> ++
> +     QTreeView::mousePressEvent(event);
> + 
> +-    const QModelIndex index = indexAt(event->pos());
> +     if (!index.isValid() || (index.column() != KDirModel::Name)) {
> +         const Qt::KeyboardModifiers modifiers = 
> QApplication::keyboardModifiers();
> +         if (!(modifiers & Qt::ShiftModifier) && !(modifiers & 
> Qt::ControlModifier)) {
> +@@ -126,6 +135,24 @@ void 
> KDirOperatorDetailView::mousePressEvent(QMouseEvent *event)
> +     }
> + }
> + 
> ++void KDirOperatorDetailView::mouseMoveEvent(QMouseEvent *event)
> ++{
> ++    // Disallow selection dragging when emblem is clicked
> ++    if (m_isEmblemClicked) {
> ++        return;
> ++    }
> ++    QTreeView::mouseMoveEvent(event);
> ++}
> ++
> ++void KDirOperatorDetailView::mouseReleaseEvent(QMouseEvent *event)
> ++{
> ++    // Reset the emblem selection
> ++    if (m_isEmblemClicked) {
> ++        m_isEmblemClicked = false;
> ++    }
> ++    QTreeView::mouseReleaseEvent(event);
> ++}
> ++
> + void KDirOperatorDetailView::currentChanged(const QModelIndex &current, 
> const QModelIndex &previous)
> + {
> +     QTreeView::currentChanged(current, previous);
> +diff --git a/src/filewidgets/kdiroperatordetailview_p.h 
> b/src/filewidgets/kdiroperatordetailview_p.h
> +index f30ab9482..df45142d4 100644
> +--- a/src/filewidgets/kdiroperatordetailview_p.h
> ++++ b/src/filewidgets/kdiroperatordetailview_p.h
> +@@ -7,6 +7,7 @@
> + #ifndef KDIROPERATORDETAILVIEW_P_H
> + #define KDIROPERATORDETAILVIEW_P_H
> + 
> ++#include <KDirOperator>
> + #include <QTreeView>
> + 
> + #include <kfile.h>
> +@@ -22,7 +23,7 @@ class KDirOperatorDetailView : public QTreeView
> +     Q_OBJECT
> + 
> + public:
> +-    explicit KDirOperatorDetailView(QWidget *parent = nullptr);
> ++    explicit KDirOperatorDetailView(KDirOperator *dirOperator, QWidget 
> *parent = nullptr);
> +     ~KDirOperatorDetailView() override;
> + 
> +     /**
> +@@ -36,10 +37,14 @@ protected:
> +     bool event(QEvent *event) override;
> +     void dragEnterEvent(QDragEnterEvent *event) override;
> +     void mousePressEvent(QMouseEvent *event) override;
> ++    void mouseMoveEvent(QMouseEvent *event) override;
> ++    void mouseReleaseEvent(QMouseEvent *event) override;
> +     void currentChanged(const QModelIndex &current, const QModelIndex 
> &previous) override;
> + 
> + private:
> +     bool m_hideDetailColumns;
> ++    bool m_isEmblemClicked;
> ++    KDirOperator *m_dirOperator;
> + };
> + 
> + #endif
> +diff --git a/src/filewidgets/kdiroperatoriconview.cpp 
> b/src/filewidgets/kdiroperatoriconview.cpp
> +index ace0c0098..9180ea1ed 100644
> +--- a/src/filewidgets/kdiroperatoriconview.cpp
> ++++ b/src/filewidgets/kdiroperatoriconview.cpp
> +@@ -6,6 +6,7 @@
> + */
> + 
> + #include "kdiroperatoriconview_p.h"
> ++#include "kfileitemselectionemblem.h"
> + 
> + #include <QApplication>
> + #include <QDragEnterEvent>
> +@@ -15,8 +16,10 @@
> + #include <KFileItemDelegate>
> + #include <KIconLoader>
> + 
> +-KDirOperatorIconView::KDirOperatorIconView(QWidget *parent, 
> QStyleOptionViewItem::Position aDecorationPosition)
> ++KDirOperatorIconView::KDirOperatorIconView(KDirOperator *dirOperator, 
> QWidget *parent, QStyleOptionViewItem::Position aDecorationPosition)
> +     : QListView(parent)
> ++    , m_isEmblemClicked(false)
> ++    , m_dirOperator(dirOperator)
> + {
> +     setViewMode(QListView::IconMode);
> +     setResizeMode(QListView::Adjust);
> +@@ -74,7 +77,15 @@ void KDirOperatorIconView::dragEnterEvent(QDragEnterEvent 
> *event)
> + 
> + void KDirOperatorIconView::mousePressEvent(QMouseEvent *event)
> + {
> +-    if (!indexAt(event->pos()).isValid()) {
> ++    const QModelIndex index = indexAt(event->pos());
> ++
> ++    // When selection emblem is clicked, select it and don't do anything 
> else
> ++    m_isEmblemClicked = KFileItemSelectionEmblem(this, index, 
> m_dirOperator).handleMousePressEvent(event->pos());
> ++    if (m_isEmblemClicked) {
> ++        return;
> ++    }
> ++
> ++    if (!index.isValid()) {
> +         const Qt::KeyboardModifiers modifiers = 
> QApplication::keyboardModifiers();
> +         if (!(modifiers & Qt::ShiftModifier) && !(modifiers & 
> Qt::ControlModifier)) {
> +             clearSelection();
> +@@ -84,6 +95,24 @@ void KDirOperatorIconView::mousePressEvent(QMouseEvent 
> *event)
> +     QListView::mousePressEvent(event);
> + }
> + 
> ++void KDirOperatorIconView::mouseMoveEvent(QMouseEvent *event)
> ++{
> ++    // Disallow selection dragging when emblem is clicked
> ++    if (m_isEmblemClicked) {
> ++        return;
> ++    }
> ++    QListView::mouseMoveEvent(event);
> ++}
> ++
> ++void KDirOperatorIconView::mouseReleaseEvent(QMouseEvent *event)
> ++{
> ++    // Reset the emblem selection
> ++    if (m_isEmblemClicked) {
> ++        m_isEmblemClicked = false;
> ++    }
> ++    QListView::mouseReleaseEvent(event);
> ++}
> ++
> + void KDirOperatorIconView::wheelEvent(QWheelEvent *event)
> + {
> +     QListView::wheelEvent(event);
> +diff --git a/src/filewidgets/kdiroperatoriconview_p.h 
> b/src/filewidgets/kdiroperatoriconview_p.h
> +index c4ab96738..f1caba9e0 100644
> +--- a/src/filewidgets/kdiroperatoriconview_p.h
> ++++ b/src/filewidgets/kdiroperatoriconview_p.h
> +@@ -8,6 +8,7 @@
> + #ifndef KDIROPERATORICONVIEW_P_H
> + #define KDIROPERATORICONVIEW_P_H
> + 
> ++#include <KDirOperator>
> + #include <QListView>
> + 
> + /**
> +@@ -18,7 +19,9 @@ class KDirOperatorIconView : public QListView
> + {
> +     Q_OBJECT
> + public:
> +-    KDirOperatorIconView(QWidget *parent = nullptr, 
> QStyleOptionViewItem::Position decorationPosition = 
> QStyleOptionViewItem::Position::Top);
> ++    KDirOperatorIconView(KDirOperator *dirOperator,
> ++                         QWidget *parent = nullptr,
> ++                         QStyleOptionViewItem::Position decorationPosition 
> = QStyleOptionViewItem::Position::Top);
> +     ~KDirOperatorIconView() override;
> +     void setDecorationPosition(QStyleOptionViewItem::Position 
> decorationPosition);
> + 
> +@@ -26,6 +29,8 @@ protected:
> +     void initViewItemOption(QStyleOptionViewItem *option) const override;
> +     void dragEnterEvent(QDragEnterEvent *event) override;
> +     void mousePressEvent(QMouseEvent *event) override;
> ++    void mouseMoveEvent(QMouseEvent *event) override;
> ++    void mouseReleaseEvent(QMouseEvent *event) override;
> +     void wheelEvent(QWheelEvent *event) override;
> +     void resizeEvent(QResizeEvent *event) override;
> + 
> +@@ -34,6 +39,8 @@ protected
> + 
> + private:
> +     QStyleOptionViewItem::Position decorationPosition;
> ++    bool m_isEmblemClicked;
> ++    KDirOperator *m_dirOperator;
> + };
> + 
> + #endif // KDIROPERATORICONVIEW_P_H
> +diff --git a/src/filewidgets/kfileitemselectionemblem.cpp 
> b/src/filewidgets/kfileitemselectionemblem.cpp
> +new file mode 100644
> +index 000000000..566dee306
> +--- /dev/null
> ++++ b/src/filewidgets/kfileitemselectionemblem.cpp
> +@@ -0,0 +1,63 @@
> ++/*
> ++    SPDX-FileCopyrightText: 2025 Akseli Lahtinen <akse...@akselmo.dev>
> ++
> ++    SPDX-License-Identifier: LGPL-2.0-or-later
> ++*/
> ++
> ++#include "kfileitemselectionemblem.h"
> ++#include "kfileitemdelegate.h"
> ++
> ++#include <QAbstractItemDelegate>
> ++#include <QAbstractItemView>
> ++#include <QApplication>
> ++#include <QModelIndex>
> ++#include <QPoint>
> ++
> ++KFileItemSelectionEmblem::KFileItemSelectionEmblem(QAbstractItemView 
> *itemView, QModelIndex index, KDirOperator *dirOperator)
> ++{
> ++    m_itemView = itemView;
> ++    m_index = index;
> ++    m_fileItemDelegate = fileItemDelegate();
> ++    m_dirOperator = dirOperator;
> ++    m_fileItem = m_fileItemDelegate->fileItem(m_index);
> ++}
> ++
> ++KFileItemSelectionEmblem::~KFileItemSelectionEmblem()
> ++{
> ++}
> ++
> ++bool KFileItemSelectionEmblem::isEmblemEnabled()
> ++{
> ++    if (m_itemView->selectionMode() == QAbstractItemView::ExtendedSelection 
> && qApp->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)) {
> ++        if (m_fileItem.isDir()) {
> ++            return m_dirOperator->isSelected(m_fileItem);
> ++        }
> ++        return true;
> ++    }
> ++    return false;
> ++}
> ++
> ++KFileItemDelegate *KFileItemSelectionEmblem::fileItemDelegate()
> ++{
> ++    auto itemDelegate = m_itemView->itemDelegateForIndex(m_index);
> ++    if (itemDelegate) {
> ++        return qobject_cast<KFileItemDelegate *>(itemDelegate);
> ++    }
> ++    return nullptr;
> ++}
> ++
> ++void KFileItemSelectionEmblem::updateSelectionEmblemRectForIndex(const int 
> iconSize)
> ++{
> ++    if (isEmblemEnabled() && m_fileItemDelegate) {
> ++        
> m_fileItemDelegate->setSelectionEmblemRect(m_itemView->visualRect(m_index), 
> iconSize);
> ++    }
> ++}
> ++
> ++bool KFileItemSelectionEmblem::handleMousePressEvent(const QPoint mousePos)
> ++{
> ++    if (isEmblemEnabled() && m_fileItemDelegate && 
> m_fileItemDelegate->selectionEmblemRect().contains(mousePos)) {
> ++        m_itemView->selectionModel()->select(m_index, 
> QItemSelectionModel::Toggle);
> ++        return true;
> ++    }
> ++    return false;
> ++}
> +diff --git a/src/filewidgets/kfileitemselectionemblem.h 
> b/src/filewidgets/kfileitemselectionemblem.h
> +new file mode 100644
> +index 000000000..4bfd78a8b
> +--- /dev/null
> ++++ b/src/filewidgets/kfileitemselectionemblem.h
> +@@ -0,0 +1,39 @@
> ++/*
> ++    SPDX-FileCopyrightText: 2025 Akseli Lahtinen <akse...@akselmo.dev>
> ++
> ++    SPDX-License-Identifier: LGPL-2.0-or-later
> ++*/
> ++
> ++#ifndef KFILEITEMSELECTIONEMBLEM_H
> ++#define KFILEITEMSELECTIONEMBLEM_H
> ++
> ++#include <KDirOperator>
> ++#include <QAbstractItemView>
> ++#include <QModelIndex>
> ++
> ++class KFileItem;
> ++class KFileItemDelegate;
> ++class QPoint;
> ++
> ++class KFileItemSelectionEmblem
> ++{
> ++public:
> ++    KFileItemSelectionEmblem(QAbstractItemView *itemView, QModelIndex 
> index, KDirOperator *dirOperator);
> ++    ~KFileItemSelectionEmblem();
> ++
> ++    void updateSelectionEmblemRectForIndex(const int iconSize);
> ++    bool handleMousePressEvent(const QPoint mousePos);
> ++    bool isEmblemEnabled();
> ++
> ++private:
> ++    KFileItemDelegate *fileItemDelegate();
> ++
> ++    QAbstractItemView *m_itemView;
> ++    QModelIndex m_index;
> ++    KDirOperator *m_dirOperator;
> ++    KFileItemDelegate *m_fileItemDelegate;
> ++    KFileItem m_fileItem;
> ++    bool m_isDir;
> ++};
> ++
> ++#endif
> +diff --git a/src/widgets/kfileitemdelegate.cpp 
> b/src/widgets/kfileitemdelegate.cpp
> +index c00c69523..83acd9910 100644
> +--- a/src/widgets/kfileitemdelegate.cpp
> ++++ b/src/widgets/kfileitemdelegate.cpp
> +@@ -101,6 +101,7 @@ public:
> +     void gotNewIcon(const QModelIndex &index);
> + 
> +     void paintJobTransfers(QPainter *painter, const qreal 
> &jobAnimationAngle, const QPoint &iconPos, const QStyleOptionViewItem &opt);
> ++    int scaledEmblemSize(int iconSize) const;
> + 
> + public:
> +     KFileItemDelegate::InformationList informationList;
> +@@ -112,6 +113,7 @@ public:
> +     QTextOption::WrapMode wrapMode;
> +     bool jobTransfersVisible;
> +     QIcon downArrowIcon;
> ++    QRect emblemRect;
> + 
> + private:
> +     KIO::DelegateAnimationHandler *animationHandler;
> +@@ -128,6 +130,7 @@ KFileItemDelegate::Private::Private(KFileItemDelegate 
> *parent)
> +     , showToolTipWhenElided(true)
> +     , wrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere)
> +     , jobTransfersVisible(false)
> ++    , emblemRect(QRect())
> +     , animationHandler(new KIO::DelegateAnimationHandler(parent))
> +     , activeMargins(nullptr)
> + {
> +@@ -1153,6 +1156,7 @@ void KFileItemDelegate::paint(QPainter *painter, const 
> QStyleOptionViewItem &opt
> +     QPixmap icon = opt.icon.pixmap(opt.decorationSize, iconMode, iconState);
> + 
> +     const KFileItem fileItem = d->fileItem(index);
> ++    const bool isDir = fileItem.isDir();
> +     if (fileItem.isHidden()) {
> +         KIconEffect::semiTransparent(icon);
> +     }
> +@@ -1176,6 +1180,7 @@ void KFileItemDelegate::paint(QPainter *painter, const 
> QStyleOptionViewItem &opt
> +                     pixmap = d->transition(fadeFromPixmap, pixmap, 
> state->fadeProgress());
> +                 }
> +                 painter->drawPixmap(option.rect.topLeft(), pixmap);
> ++                drawSelectionEmblem(option, painter, index);
> +                 if (d->jobTransfersVisible && index.column() == 0) {
> +                     if (index.data(KDirModel::HasJobRole).toBool()) {
> +                         d->paintJobTransfers(painter, 
> state->jobAnimationAngle(), iconPos, opt);
> +@@ -1251,6 +1256,7 @@ void KFileItemDelegate::paint(QPainter *painter, const 
> QStyleOptionViewItem &opt
> +         p.setRenderHint(QPainter::Antialiasing);
> +         style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, 
> opt.widget);
> +         p.drawPixmap(iconPos, icon);
> ++        drawSelectionEmblem(option, painter, index);
> +         d->drawTextItems(&p, labelLayout, labelColor, infoLayout, 
> infoColor, textBoundingRect);
> +         d->drawFocusRect(&p, opt, focusRect);
> +         p.end();
> +@@ -1263,6 +1269,7 @@ void KFileItemDelegate::paint(QPainter *painter, const 
> QStyleOptionViewItem &opt
> +         p.setRenderHint(QPainter::Antialiasing);
> +         style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, 
> opt.widget);
> +         p.drawPixmap(iconPos, icon);
> ++        drawSelectionEmblem(option, painter, index);
> +         d->drawTextItems(&p, labelLayout, labelColor, infoLayout, 
> infoColor, textBoundingRect);
> +         d->drawFocusRect(&p, opt, focusRect);
> +         p.end();
> +@@ -1282,6 +1289,7 @@ void KFileItemDelegate::paint(QPainter *painter, const 
> QStyleOptionViewItem &opt
> +         }
> + 
> +         painter->drawPixmap(option.rect.topLeft(), pixmap);
> ++        drawSelectionEmblem(option, painter, index);
> +         painter->setRenderHint(QPainter::Antialiasing);
> +         if (d->jobTransfersVisible && index.column() == 0) {
> +             if (index.data(KDirModel::HasJobRole).toBool()) {
> +@@ -1306,6 +1314,7 @@ void KFileItemDelegate::paint(QPainter *painter, const 
> QStyleOptionViewItem &opt
> + 
> +     d->drawTextItems(painter, labelLayout, labelColor, infoLayout, 
> infoColor, textBoundingRect);
> +     d->drawFocusRect(painter, opt, focusRect);
> ++    drawSelectionEmblem(option, painter, index);
> + 
> +     if (d->jobTransfersVisible && index.column() == 0 && state) {
> +         if (index.data(KDirModel::HasJobRole).toBool()) {
> +@@ -1315,6 +1324,33 @@ void KFileItemDelegate::paint(QPainter *painter, 
> const QStyleOptionViewItem &opt
> +     painter->restore();
> + }
> + 
> ++void KFileItemDelegate::drawSelectionEmblem(QStyleOptionViewItem option, 
> QPainter *painter, const QModelIndex &index) const
> ++{
> ++    if (index.column() != 0 || 
> !qApp->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)) {
> ++        return;
> ++    }
> ++    const auto state = option.state;
> ++    if ((state & QStyle::State_MouseOver && !fileItem(index).isDir()) || 
> (state & QStyle::State_Selected)) {
> ++        const QString selectionEmblem = state & QStyle::State_Selected ? 
> QStringLiteral("emblem-remove") : QStringLiteral("emblem-added");
> ++        const auto emblem = 
> QIcon::fromTheme(selectionEmblem).pixmap(d->emblemRect.size(), state & 
> QStyle::State_MouseOver ? QIcon::Active : QIcon::Disabled);
> ++
> ++        painter->drawPixmap(d->emblemRect.topLeft(), emblem);
> ++    }
> ++}
> ++
> ++int KFileItemDelegate::Private::scaledEmblemSize(int iconSize) const
> ++{
> ++    if (iconSize <= KIconLoader::SizeSmallMedium) {
> ++        return KIconLoader::SizeSmall;
> ++    } else if (iconSize <= KIconLoader::SizeHuge) {
> ++        return KIconLoader::SizeSmallMedium;
> ++    } else if (iconSize <= KIconLoader::SizeEnormous) {
> ++        return KIconLoader::SizeMedium;
> ++    }
> ++
> ++    return KIconLoader::SizeHuge;
> ++}
> ++
> + QWidget *KFileItemDelegate::createEditor(QWidget *parent, const 
> QStyleOptionViewItem &option, const QModelIndex &index) const
> + {
> +     QStyleOptionViewItem opt(option);
> +@@ -1551,4 +1587,26 @@ bool KFileItemDelegate::eventFilter(QObject *object, 
> QEvent *event)
> +     } // switch (event->type())
> + }
> + 
> ++void KFileItemDelegate::setSelectionEmblemRect(QRect rect, int iconSize)
> ++{
> ++    const auto emblemSize = d->scaledEmblemSize(iconSize);
> ++
> ++    // With small icons, try to center the emblem on top of the icon
> ++    if (iconSize <= KIconLoader::SizeSmallMedium) {
> ++        d->emblemRect = QRect(rect.topLeft().x() + emblemSize / 4, 
> rect.topLeft().y() + emblemSize / 4, emblemSize, emblemSize);
> ++    } else {
> ++        d->emblemRect = QRect(rect.topLeft().x(), rect.topLeft().y(), 
> emblemSize, emblemSize);
> ++    }
> ++}
> ++
> ++QRect KFileItemDelegate::selectionEmblemRect() const
> ++{
> ++    return d->emblemRect;
> ++}
> ++
> ++KFileItem KFileItemDelegate::fileItem(const QModelIndex &index) const
> ++{
> ++    return d->fileItem(index);
> ++}
> ++
> + #include "moc_kfileitemdelegate.cpp"
> +diff --git a/src/widgets/kfileitemdelegate.h 
> b/src/widgets/kfileitemdelegate.h
> +index b4dd7eb05..83ecfe405 100644
> +--- a/src/widgets/kfileitemdelegate.h
> ++++ b/src/widgets/kfileitemdelegate.h
> +@@ -9,6 +9,7 @@
> + #define KFILEITEMDELEGATE_H
> + 
> + #include "kiowidgets_export.h"
> ++#include <KFileItem>
> + #include <QAbstractItemDelegate>
> + #include <QTextOption>
> + 
> +@@ -398,6 +399,18 @@ public:
> +      */
> +     bool eventFilter(QObject *object, QEvent *event) override;
> + 
> ++    /**
> ++     * @return The rectangle where selectionEmblem is being drawn
> ++     */
> ++    QRect selectionEmblemRect() const;
> ++
> ++    /**
> ++     * Set the rectangle where selectionEmblem should be drawn in.
> ++     */
> ++    void setSelectionEmblemRect(QRect rect, int iconSize);
> ++
> ++    KFileItem fileItem(const QModelIndex &index) const;
> ++
> + public Q_SLOTS:
> +     /**
> +      * Reimplemented from @ref QAbstractItemDelegate.
> +@@ -414,6 +427,8 @@ private:
> +     class Private;
> +     std::unique_ptr<Private> const d; /// @internal
> +     Q_DISABLE_COPY(KFileItemDelegate)
> ++
> ++    void drawSelectionEmblem(QStyleOptionViewItem option, QPainter 
> *painter, const QModelIndex &index) const;
> + };
> + 
> + #endif // KFILEITEMDELEGATE_H
> +-- 
> +GitLab
> +


-- 
Sebastian Ramacher

Reply via email to