Skip to content

Commit c286385

Browse files
jsm222probonopd
andauthored
Add menus recursivly (submenus) in the search menu (#91)
* Add menus recursivly (submenus) in the sarch menu requires to switch from the application window and back again atm.. * Add libXcomposite * Do only include leafs in search and improve first search * Do not call last on an empty list * Refactor to avoid to much recursion. Co-authored-by: probonopd <probonopd@users.noreply.github.com>
1 parent 6c65b60 commit c286385

File tree

7 files changed

+42
-29
lines changed

7 files changed

+42
-29
lines changed

src/actionsearch/actionsearch.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ void ActionSearch::update(QMenuBar *menu)
1616
{
1717
for (auto menuAction: menu->actions())
1818
{
19-
readMenuActions(menuAction->menu());
19+
QStringList names;
20+
readMenuActions(menuAction->menu(),names);
21+
2022
}
2123
}
2224

@@ -27,7 +29,7 @@ void ActionSearch::execute(QString actionName)
2729
}
2830
}
2931

30-
void ActionSearch::readMenuActions(QMenu* menu)
32+
void ActionSearch::readMenuActions(QMenu* menu,QStringList names)
3133
{
3234
// See https://doc.qt.io/qt-5/qaction.html#menu
3335
// If a QAction does not have menu in it, then
@@ -36,29 +38,30 @@ void ActionSearch::readMenuActions(QMenu* menu)
3638
if (!menu)
3739
return;
3840

39-
QString menuName = menu->title().replace("&", "");
40-
41-
41+
names << menu->title();
4242
for (auto action: menu->actions())
4343
{
44+
4445
if (action->menu() != NULL)
4546
{
46-
readMenuActions(action->menu());
47-
continue;
47+
48+
readMenuActions(action->menu(),names);
4849
}
4950

51+
5052
QString actionName = action->text().replace("&", "");
51-
if (!actionName.isEmpty() && action->isEnabled())
53+
if (!actionName.isEmpty() && action->isEnabled() && !action->menu())
5254
{
53-
// TODO: we might want to have a multilevel menuName
54-
// actionName += "\n(" + menuName +")";
55-
actionName = menuName + "" + actionName;
55+
actionName = names.join("") + "" + actionName;
56+
5657
if (action->shortcut().toString() != "") {
5758
actionName = actionName + " (" + action->shortcut().toString() +")";
5859
}
5960
actions.insert(actionName, action);
6061
}
6162

6263
}
64+
names.clear();
65+
6366
}
6467

src/actionsearch/actionsearch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class ActionSearch
2020
private:
2121
QMenuBar* menuBar;
2222

23-
void readMenuActions(QMenu* menu);
23+
void readMenuActions(QMenu* menu, QStringList names);
2424

2525
QHash<QString, QAction*> actions{}; // std::unordered_map
2626
};

src/appmenu/appmenumodel.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include <QDBusConnectionInterface>
3434
#include <QDBusServiceWatcher>
3535
#include <QGuiApplication>
36-
36+
#include <QTimer>
3737
#include <QDebug>
3838

3939
#include "dbusmenuimporter.h"
@@ -99,6 +99,7 @@ AppMenuModel::AppMenuModel(QObject *parent)
9999
if (serviceName == m_serviceName) {
100100
setMenuAvailable(false);
101101
emit modelNeedsUpdate();
102+
emit menuParsed();
102103
}
103104
});
104105
}
@@ -302,6 +303,7 @@ void AppMenuModel::onActiveWindowChanged(WId id)
302303
if (!id) {
303304
setMenuAvailable(false);
304305
emit modelNeedsUpdate();
306+
emit menuParsed();
305307
return;
306308
}
307309

@@ -401,6 +403,7 @@ void AppMenuModel::onActiveWindowChanged(WId id)
401403
// rekols: 切换到桌面时要隐藏menubar
402404
setMenuAvailable(false);
403405
emit modelNeedsUpdate();
406+
emit menuParsed();
404407
return;
405408
}
406409

@@ -431,8 +434,11 @@ void AppMenuModel::onActiveWindowChanged(WId id)
431434
m_delayedMenuWindowId = id;
432435

433436
//no menu found, set it to unavailable
437+
434438
setMenuAvailable(false);
435439
emit modelNeedsUpdate();
440+
emit menuParsed();
441+
436442
}
437443
}
438444

@@ -522,18 +528,21 @@ void AppMenuModel::updateApplicationMenu(const QString &serviceName, const QStri
522528
}
523529

524530
m_importer = new KDBusMenuImporter(serviceName, menuObjectPath, this);
531+
if(serviceName =="org.kde.plasma.gmenu_dbusmenu_proxy") {
532+
QTimer::singleShot(200,this, [=](){m_importer->updateMenu();});
533+
} else {
525534
QMetaObject::invokeMethod(m_importer, "updateMenu", Qt::QueuedConnection);
535+
}
526536

537+
m_menu = m_importer->menu();
527538

528539
connect(m_importer.data(), &DBusMenuImporter::menuUpdated, this, [=](QMenu *menu) {
529-
m_menu = m_importer->menu();
540+
for (QAction *a : menu->actions()) {
530541

531-
if (m_menu.isNull() || menu != m_menu) {
532-
return;
533-
}
542+
if(a->menu()) {
543+
m_importer->updateMenu(a->menu());
534544

535-
//cache first layer of sub menus, which we'll be popping up
536-
for (QAction *a : m_menu->actions()) {
545+
}
537546
// signal dataChanged when the action changes
538547
connect(a, &QAction::changed, this, [this, a] {
539548
if (m_menuAvailable && m_menu)
@@ -544,19 +553,18 @@ void AppMenuModel::updateApplicationMenu(const QString &serviceName, const QStri
544553
const QModelIndex modelIdx = index(actionIdx, 0);
545554
emit dataChanged(modelIdx, modelIdx);
546555
}
547-
emit modelNeedsUpdate();
548556
}
549557
});
550558

551559
connect(a, &QAction::destroyed, this, &AppMenuModel::modelNeedsUpdate);
552560

553-
if (a->menu()) {
554-
m_importer->updateMenu(a->menu());
555-
}
556561
}
557-
558-
setMenuAvailable(true);
559-
emit modelNeedsUpdate();
562+
563+
564+
if(m_menu && !m_menu->actions().isEmpty() && m_menu->actions().last() == menu->menuAction()) {
565+
setMenuAvailable(true);
566+
emit menuParsed();
567+
}
560568
});
561569

562570
connect(m_importer.data(), &DBusMenuImporter::actionActivationRequested, this, [this](QAction * action) {

src/appmenu/appmenumodel.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#include <KWindowSystem>
2929
#include <QPointer>
3030
#include <QRect>
31-
31+
#include <QTimer>
3232
class QMenu;
3333
class QAction;
3434
class QModelIndex;
@@ -104,6 +104,7 @@ private Q_SLOTS:
104104
signals:
105105
void menuAvailableChanged();
106106
void modelNeedsUpdate();
107+
void menuParsed();
107108
void filterByActiveChanged();
108109
void filterChildrenChanged();
109110
void visibleChanged();

src/appmenu/dbusmenuimporter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ void DBusMenuImporter::updateMenu(QMenu *menu)
506506
d->sendEvent(id, QStringLiteral("opened"));
507507
}
508508

509+
509510
void DBusMenuImporter::slotAboutToShowDBusCallFinished(QDBusPendingCallWatcher *watcher)
510511
{
511512
int id = watcher->property(DBUSMENU_PROPERTY_ID).toInt();

src/appmenu/dbusmenuimporter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class DBusMenuImporter : public QObject
5454
* The menu created from listening to the DBusMenuExporter over DBus
5555
*/
5656
QMenu *menu() const;
57-
57+
bool m_done;
5858
public Q_SLOTS:
5959
/**
6060
* Load the menu

src/appmenuwidget.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ AppMenuWidget::AppMenuWidget(QWidget *parent)
372372
menuImporter->connectToBus();
373373

374374
m_appMenuModel = new AppMenuModel(this);
375-
connect(m_appMenuModel, &AppMenuModel::modelNeedsUpdate, this, &AppMenuWidget::updateMenu);
375+
connect(m_appMenuModel, &AppMenuModel::menuParsed, this, &AppMenuWidget::updateMenu);
376376

377377
connect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged, this, &AppMenuWidget::delayUpdateActiveWindow);
378378
connect(KWindowSystem::self(), static_cast<void (KWindowSystem::*)(WId, NET::Properties, NET::Properties2)>(&KWindowSystem::windowChanged),

0 commit comments

Comments
 (0)