File: upstream_73875471_applets-appmenu-Fix-displaying-menu-of-the-previous-active-window.patch

package info (click to toggle)
plasma-workspace 4%3A6.3.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 104,900 kB
  • sloc: cpp: 125,434; xml: 31,579; python: 3,976; perl: 572; sh: 234; javascript: 74; ruby: 39; ansic: 13; makefile: 9
file content (165 lines) | stat: -rw-r--r-- 6,431 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
From 7387547112e1a00aca294861abee666de3fbd68f Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Fri, 18 Apr 2025 22:39:46 +0300
Subject: [PATCH] applets/appmenu: Fix displaying menu of the previous active
 window

We need to break the DBusMenuImporter::menuUpdated() signal connection
when the active window changes. Otherwise, it's possible that the
menuUpdated signal will be emitted and the menu will be marked as
available.

BUG: 473714
---
 applets/appmenu/plugin/appmenumodel.cpp | 115 +++++++++++++-----------
 1 file changed, 63 insertions(+), 52 deletions(-)

diff --git a/applets/appmenu/plugin/appmenumodel.cpp b/applets/appmenu/plugin/appmenumodel.cpp
index 04834b6fab6..db3b351405f 100644
--- a/applets/appmenu/plugin/appmenumodel.cpp
+++ b/applets/appmenu/plugin/appmenumodel.cpp
@@ -202,16 +202,7 @@ void AppMenuModel::onActiveWindowChanged()
     const QModelIndex activeTaskIndex = m_tasksModel->activeTask();
     const QString objectPath = m_tasksModel->data(activeTaskIndex, TaskManager::AbstractTasksModel::ApplicationMenuObjectPath).toString();
     const QString serviceName = m_tasksModel->data(activeTaskIndex, TaskManager::AbstractTasksModel::ApplicationMenuServiceName).toString();
-
-    if (!objectPath.isEmpty() && !serviceName.isEmpty()) {
-        setMenuAvailable(true);
-        updateApplicationMenu(serviceName, objectPath);
-        setVisible(true);
-        Q_EMIT modelNeedsUpdate();
-    } else {
-        setMenuAvailable(false);
-        setVisible(false);
-    }
+    updateApplicationMenu(serviceName, objectPath);
 }
 
 QHash<int, QByteArray> AppMenuModel::roleNames() const
@@ -282,61 +273,81 @@ void AppMenuModel::updateApplicationMenu(const QString &serviceName, const QStri
         return;
     }
 
-    m_serviceName = serviceName;
-    m_serviceWatcher->setWatchedServices(QStringList({m_serviceName}));
-
-    m_menuObjectPath = menuObjectPath;
+    if (serviceName.isEmpty() || menuObjectPath.isEmpty()) {
+        setMenuAvailable(false);
+        setVisible(false);
 
-    if (m_importer) {
-        m_importer->deleteLater();
-    }
+        m_serviceName = QString();
+        m_menuObjectPath = QString();
+        m_serviceWatcher->setWatchedServices({});
 
-    m_importer = new KDBusMenuImporter(serviceName, menuObjectPath, this);
-    QMetaObject::invokeMethod(m_importer, "updateMenu", Qt::QueuedConnection);
+        if (m_importer) {
+            m_importer->disconnect(this);
+            m_importer->deleteLater();
+            m_importer = nullptr;
+        }
+    } else {
+        m_serviceName = serviceName;
+        m_menuObjectPath = menuObjectPath;
+        m_serviceWatcher->setWatchedServices(QStringList({m_serviceName}));
 
-    connect(m_importer.data(), &DBusMenuImporter::menuUpdated, this, [=, this](QMenu *menu) {
-        m_menu = m_importer->menu();
-        if (m_menu.isNull() || menu != m_menu) {
-            return;
+        if (m_importer) {
+            m_importer->disconnect(this);
+            m_importer->deleteLater();
         }
 
-        // cache first layer of sub menus, which we'll be popping up
-        const auto actions = m_menu->actions();
-        for (QAction *a : actions) {
-            // signal dataChanged when the action changes
-            connect(a, &QAction::changed, this, [this, a] {
-                if (m_menuAvailable && m_menu) {
-                    const int actionIdx = m_menu->actions().indexOf(a);
-                    if (actionIdx > -1) {
-                        const QModelIndex modelIdx = index(actionIdx, 0);
-                        Q_EMIT dataChanged(modelIdx, modelIdx);
+        m_importer = new KDBusMenuImporter(serviceName, menuObjectPath, this);
+        QMetaObject::invokeMethod(m_importer, "updateMenu", Qt::QueuedConnection);
+
+        connect(m_importer.data(), &DBusMenuImporter::menuUpdated, this, [=, this](QMenu *menu) {
+            m_menu = m_importer->menu();
+            if (m_menu.isNull() || menu != m_menu) {
+                return;
+            }
+
+            // cache first layer of sub menus, which we'll be popping up
+            const auto actions = m_menu->actions();
+            for (QAction *a : actions) {
+                // signal dataChanged when the action changes
+                connect(a, &QAction::changed, this, [this, a] {
+                    if (m_menuAvailable && m_menu) {
+                        const int actionIdx = m_menu->actions().indexOf(a);
+                        if (actionIdx > -1) {
+                            const QModelIndex modelIdx = index(actionIdx, 0);
+                            Q_EMIT dataChanged(modelIdx, modelIdx);
+                        }
                     }
+                });
+
+                connect(a, &QAction::destroyed, this, &AppMenuModel::modelNeedsUpdate);
+
+                if (a->menu()) {
+                    m_importer->updateMenu(a->menu());
                 }
-            });
+            }
 
-            connect(a, &QAction::destroyed, this, &AppMenuModel::modelNeedsUpdate);
+            setMenuAvailable(true);
+            Q_EMIT modelNeedsUpdate();
+        });
 
-            if (a->menu()) {
-                m_importer->updateMenu(a->menu());
+        connect(m_importer.data(), &DBusMenuImporter::actionActivationRequested, this, [this](QAction *action) {
+            // TODO submenus
+            if (!m_menuAvailable || !m_menu) {
+                return;
             }
-        }
 
-        setMenuAvailable(true);
-        Q_EMIT modelNeedsUpdate();
-    });
+            const auto actions = m_menu->actions();
+            auto it = std::find(actions.begin(), actions.end(), action);
+            if (it != actions.end()) {
+                Q_EMIT requestActivateIndex(it - actions.begin());
+            }
+        });
 
-    connect(m_importer.data(), &DBusMenuImporter::actionActivationRequested, this, [this](QAction *action) {
-        // TODO submenus
-        if (!m_menuAvailable || !m_menu) {
-            return;
-        }
+        setMenuAvailable(true);
+        setVisible(true);
 
-        const auto actions = m_menu->actions();
-        auto it = std::find(actions.begin(), actions.end(), action);
-        if (it != actions.end()) {
-            Q_EMIT requestActivateIndex(it - actions.begin());
-        }
-    });
+        Q_EMIT modelNeedsUpdate();
+    }
 }
 
 #include "moc_appmenumodel.cpp"
-- 
GitLab