From d725a54bd8fa09991e3c45276c773ec1ed35c34a Mon Sep 17 00:00:00 2001 From: Javier Feliz Date: Thu, 28 Aug 2025 13:02:00 -0400 Subject: [PATCH] Filtering and launching --- lib/ui/AppListModel.cpp | 65 +++++++++++++++++++++++++++++++++++++++-- lib/ui/AppListModel.hpp | 12 ++++++++ ui/Main.qml | 12 ++++++-- 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/lib/ui/AppListModel.cpp b/lib/ui/AppListModel.cpp index f317bf5..64bb535 100644 --- a/lib/ui/AppListModel.cpp +++ b/lib/ui/AppListModel.cpp @@ -1,5 +1,7 @@ #include "AppListModel.hpp" #include +#include +#include AppListModel::AppListModel(QObject *parent) : QAbstractListModel(parent) @@ -10,15 +12,16 @@ AppListModel::AppListModel(QObject *parent) int AppListModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return m_apps ? static_cast(m_apps->size()) : 0; + return static_cast(m_filteredIndexes.size()); } QVariant AppListModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || !m_apps || index.row() >= static_cast(m_apps->size())) + if (!index.isValid() || !m_apps || index.row() >= static_cast(m_filteredIndexes.size())) return QVariant(); - const dmenu::DesktopEntry &app = (*m_apps)[index.row()]; + int appIndex = m_filteredIndexes[index.row()]; + const dmenu::DesktopEntry &app = (*m_apps)[appIndex]; switch (role) { case NameRole: @@ -45,5 +48,61 @@ void AppListModel::loadApps() { beginResetModel(); m_apps = dmenu::get_dmenu_app_data(); + updateFilteredApps(); endResetModel(); +} + +void AppListModel::launchApp(int index) +{ + if (!m_apps || index < 0 || index >= static_cast(m_filteredIndexes.size())) + return; + + int appIndex = m_filteredIndexes[index]; + const dmenu::DesktopEntry &app = (*m_apps)[appIndex]; + + // Parse exec command (remove %f, %u, %F, %U field codes if present) + QString command = QString::fromStdString(app.exec); + QRegularExpression fieldCodes("%[fuFU]"); + command = command.replace(fieldCodes, "").trimmed(); + + qDebug() << "Launching:" << command; + + // Use nohup and redirect output to /dev/null for proper detachment + QString detachedCommand = QString("nohup %1 >/dev/null 2>&1 &").arg(command); + QProcess::startDetached("/bin/sh", QStringList() << "-c" << detachedCommand); +} + +QString AppListModel::searchText() const +{ + return m_searchText; +} + +void AppListModel::setSearchText(const QString &searchText) +{ + if (m_searchText == searchText) + return; + + m_searchText = searchText; + emit searchTextChanged(); + + beginResetModel(); + updateFilteredApps(); + endResetModel(); +} + +void AppListModel::updateFilteredApps() +{ + m_filteredIndexes.clear(); + + if (!m_apps) + return; + + for (size_t i = 0; i < m_apps->size(); ++i) { + const dmenu::DesktopEntry &app = (*m_apps)[i]; + + if (m_searchText.isEmpty() || + QString::fromStdString(app.name).contains(m_searchText, Qt::CaseInsensitive)) { + m_filteredIndexes.push_back(static_cast(i)); + } + } } \ No newline at end of file diff --git a/lib/ui/AppListModel.hpp b/lib/ui/AppListModel.hpp index a76a440..ea56f09 100644 --- a/lib/ui/AppListModel.hpp +++ b/lib/ui/AppListModel.hpp @@ -10,6 +10,7 @@ class AppListModel : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(QString searchText READ searchText WRITE setSearchText NOTIFY searchTextChanged) public: enum AppRoles { @@ -25,7 +26,18 @@ public: QHash roleNames() const override; Q_INVOKABLE void loadApps(); + Q_INVOKABLE void launchApp(int index); + + QString searchText() const; + void setSearchText(const QString &searchText); + +signals: + void searchTextChanged(); private: + void updateFilteredApps(); + dmenu::DEVec m_apps; + std::vector m_filteredIndexes; + QString m_searchText; }; \ No newline at end of file diff --git a/ui/Main.qml b/ui/Main.qml index 1387784..99ea55f 100644 --- a/ui/Main.qml +++ b/ui/Main.qml @@ -40,12 +40,19 @@ ApplicationWindow { placeholderText: "Type to search applications..." selectByMouse: true focus: true + text: appModel.searchText + + onTextChanged: { + appModel.searchText = text + listView.currentIndex = 0 + } Keys.onDownPressed: listView.incrementCurrentIndex() Keys.onUpPressed: listView.decrementCurrentIndex() Keys.onReturnPressed: { if (listView.currentItem) { - console.log("Selected:", appModel.data(appModel.index(listView.currentIndex, 0), Qt.UserRole + 2)) + appModel.launchApp(listView.currentIndex) + Qt.quit() } } } @@ -105,7 +112,8 @@ ApplicationWindow { onClicked: { listView.currentIndex = index - console.log("Clicked:", model.exec) + appModel.launchApp(index) + Qt.quit() } } }