diff --git a/src/appdata/data-provider-manager.h b/src/appdata/data-provider-manager.h index 2a22665..584bfe0 100644 --- a/src/appdata/data-provider-manager.h +++ b/src/appdata/data-provider-manager.h @@ -59,7 +59,7 @@ Q_SIGNALS: void pluginChanged(const QString &id, PluginGroup::Group group); void dataChanged(QVector data, DataUpdateMode::Mode mode, quint32 index); void labelChanged(); - void toUpdate(); + void toUpdate(bool isShowed); private: DataProviderManager(); diff --git a/src/appdata/data-provider-plugin-iface.h b/src/appdata/data-provider-plugin-iface.h index 3b28c1e..07aa1df 100644 --- a/src/appdata/data-provider-plugin-iface.h +++ b/src/appdata/data-provider-plugin-iface.h @@ -80,7 +80,7 @@ public: virtual void forceUpdate(QString &key) {}; public Q_SLOTS: - virtual void update() {}; + virtual void update(bool isShowed) {}; Q_SIGNALS: /** diff --git a/src/appdata/plugin/all-app-data-provider.cpp b/src/appdata/plugin/all-app-data-provider.cpp index a9e2ead..3cbaabd 100644 --- a/src/appdata/plugin/all-app-data-provider.cpp +++ b/src/appdata/plugin/all-app-data-provider.cpp @@ -83,21 +83,33 @@ void AllAppDataProvider::forceUpdate() sendData(); } -void AllAppDataProvider::update() +void AllAppDataProvider::update(bool isShowed) { - bool isRecentDataChanged = false; - { - QMutexLocker locker(&m_mutex); - for (DataEntity & appdata : m_appData) { - bool info = appdata.isRecentInstall(); - setRecentState(appdata); - if (appdata.isRecentInstall() != info) { - isRecentDataChanged = true; + m_windowStatus = isShowed; + if (isShowed) { + m_timer->blockSignals(true); + bool isRecentDataChanged = false; + { + QMutexLocker locker(&m_mutex); + for (DataEntity &appdata : m_appData) { + bool info = appdata.isRecentInstall(); + setRecentState(appdata); + if (appdata.isRecentInstall() != info) { + isRecentDataChanged = true; + break; + } } } - } - if (isRecentDataChanged) { - sendData(); + if (isRecentDataChanged) { + std::sort(m_appData.begin(), m_appData.end(), appDataSort); + sendData(); + } + } else { + m_timer->blockSignals(false); + if (m_updateStatus) { + reloadAppData(); + m_updateStatus = false; + } } } @@ -117,11 +129,13 @@ void AllAppDataProvider::reloadAppData() continue; } setRecentState(app); + setSortPriority(app); appData.append(app); } std::sort(appData.begin(), appData.end(), appDataSort); m_appData.swap(appData); + updateTimer(); } void AllAppDataProvider::reloadFolderData() @@ -163,6 +177,7 @@ void AllAppDataProvider::updateData(const QList &apps) if (appdata.id() == app.id()) { appdata = app; setRecentState(appdata); + setSortPriority(appdata); break; } } @@ -186,6 +201,22 @@ void AllAppDataProvider::updateFolderData(QStringList &idList) AppFolderHelper::instance()->forceSync(); } +void AllAppDataProvider::updateTimer() +{ + if (m_timer == nullptr) { + m_timer = new QTimer(this); + m_timer->setInterval(3600000*48); + connect(m_timer, &QTimer::timeout, this, [this]{ + if (m_windowStatus) { + m_updateStatus = true; + } else { + reloadAppData(); + } + }); + } + m_timer->start(); +} + bool AllAppDataProvider::appDataSort(const DataEntity &a, const DataEntity &b) { if ((a.top() != 0) && (b.top() != 0)) { @@ -206,10 +237,10 @@ bool AllAppDataProvider::appDataSort(const DataEntity &a, const DataEntity &b) } else if (b.isRecentInstall()) { return false; } else { - if (a.launchTimes() == b.launchTimes()) { + if (a.priority() == b.priority()) { return letterSort(a.firstLetter(), b.firstLetter()); } else { - return a.launchTimes() > b.launchTimes(); + return a.priority() > b.priority(); } } } else { @@ -217,13 +248,32 @@ bool AllAppDataProvider::appDataSort(const DataEntity &a, const DataEntity &b) } } +void AllAppDataProvider::setSortPriority(DataEntity &app) +{ + QDateTime installTime = QDateTime::fromString(app.insertTime(), "yyyy-MM-dd hh:mm:ss"); + if (installTime.isValid()) { + qint64 appTime = installTime.secsTo(QDateTime::currentDateTime()); + if (appTime <= 3600*240) { + appTime = appTime / (3600*24); + double priority = app.launchTimes() * (-0.4 * (appTime^2) + 100); + app.setPriority(priority); + return; + } else { + appTime = appTime / (3600*24); + double priority = app.launchTimes() * (240 / (appTime - 6)); + app.setPriority(priority); + return; + } + } +} + void AllAppDataProvider::setRecentState(DataEntity &app) { if (!UserConfig::instance()->isPreInstalledApps(app.id())) { if (app.launched() == 0) { QDateTime installTime = QDateTime::fromString(app.insertTime(), "yyyy-MM-dd hh:mm:ss"); if (installTime.isValid()) { - int appTime = installTime.secsTo(QDateTime::currentDateTime()); + qint64 appTime = installTime.secsTo(QDateTime::currentDateTime()); if ((appTime >= 0 ) && (appTime <= 3600*48)) { app.setRecentInstall(true); return; @@ -260,6 +310,7 @@ void AllAppDataProvider::onAppAdded(const QList& apps) QMutexLocker locker(&m_mutex); for (auto app : apps) { setRecentState(app); + setSortPriority(app); m_appData.append(app); } std::sort(m_appData.begin(), m_appData.end(), appDataSort); diff --git a/src/appdata/plugin/all-app-data-provider.h b/src/appdata/plugin/all-app-data-provider.h index f6b3ccd..a187272 100644 --- a/src/appdata/plugin/all-app-data-provider.h +++ b/src/appdata/plugin/all-app-data-provider.h @@ -22,6 +22,7 @@ #include "data-provider-plugin-iface.h" #include #include +#include namespace UkuiMenu { @@ -40,7 +41,7 @@ public: void forceUpdate() override; public Q_SLOTS: - void update() override; + void update(bool isShowed) override; private Q_SLOTS: void onAppAdded(const QList& apps); @@ -57,14 +58,19 @@ private: void mergeData(QVector &data); void updateData(const QList& apps); void updateFolderData(QStringList& idList); + void updateTimer(); static bool appDataSort(const DataEntity &a, const DataEntity &b); + static void setSortPriority(DataEntity &app); static void setRecentState(DataEntity &app); static bool letterSort(const QString &a, const QString &b); private: + QTimer *m_timer = nullptr; QMutex m_mutex; QVector m_appData; QVector m_folderData; + bool m_updateStatus = false; + bool m_windowStatus = false; }; } // UkuiMenu diff --git a/src/data-entity.cpp b/src/data-entity.cpp index 28cab5c..b41b02a 100644 --- a/src/data-entity.cpp +++ b/src/data-entity.cpp @@ -33,6 +33,7 @@ public: int top{0}; // 置顶状态及序号 int favorite{0}; // 收藏状态及序号 int launchTimes{0}; // 启动次数 + double priority{0}; DataType::Type type {DataType::Normal}; QString id; // 应用可执行文件路径 QString icon; @@ -112,6 +113,16 @@ void DataEntity::setLaunchTimes(int launchTimes) d->launchTimes = launchTimes; } +double DataEntity::priority() const +{ + return d->priority; +} + +void DataEntity::setPriority(double priority) +{ + d->priority = priority; +} + QString DataEntity::insertTime() const { return d->insertTime; diff --git a/src/data-entity.h b/src/data-entity.h index 875694c..eba255d 100644 --- a/src/data-entity.h +++ b/src/data-entity.h @@ -89,6 +89,9 @@ public: int launchTimes() const; void setLaunchTimes(int launchTimes); + double priority() const; + void setPriority(double priority); + QString insertTime() const; void setInsertTime(const QString& insertTime); diff --git a/src/ukui-menu-application.cpp b/src/ukui-menu-application.cpp index 1195efc..8b6bc3a 100644 --- a/src/ukui-menu-application.cpp +++ b/src/ukui-menu-application.cpp @@ -115,6 +115,14 @@ void UkuiMenuApplication::loadMenuUI() const QUrl url(QStringLiteral("qrc:/qml/main.qml")); m_mainWindow = new MenuWindow(m_engine, nullptr); m_mainWindow->setSource(url); + connect(m_mainWindow, &QQuickView::activeFocusItemChanged, m_mainWindow, [this] { + if (m_mainWindow->activeFocusItem()) { + return; + } + + execCommand(Hide); + DataProviderManager::instance()->toUpdate(false); + }); } void UkuiMenuApplication::initDbusService() @@ -136,16 +144,12 @@ void UkuiMenuApplication::execCommand(Command command) case Active: { if (m_mainWindow) { m_mainWindow->setVisible(!m_mainWindow->isVisible()); - if (m_mainWindow->isVisible()) { - DataProviderManager::instance()->toUpdate(); - } } break; } case Show: { if (m_mainWindow) { m_mainWindow->setVisible(true); - DataProviderManager::instance()->toUpdate(); } break; } @@ -166,6 +170,8 @@ void UkuiMenuApplication::execCommand(Command command) default: break; } + bool isShowed = m_mainWindow->isVisible(); + DataProviderManager::instance()->toUpdate(isShowed); } UkuiMenuApplication::~UkuiMenuApplication() diff --git a/src/windows/menu-main-window.cpp b/src/windows/menu-main-window.cpp index e440b03..2bb8d60 100644 --- a/src/windows/menu-main-window.cpp +++ b/src/windows/menu-main-window.cpp @@ -399,7 +399,6 @@ void MenuWindow::init() // 访问窗口api rootContext()->setContextProperty("mainWindow", this); - connect(this, &QQuickView::activeFocusItemChanged, this, &MenuWindow::onActiveFocusItemChanged); connect(m_geometryHelper, &WindowGeometryHelper::geometryChanged, this, [this] { QEvent event(QEvent::Move); @@ -526,15 +525,6 @@ void MenuWindow::showEvent(QShowEvent *event) QQuickView::showEvent(event); } -void MenuWindow::onActiveFocusItemChanged() -{ - if (activeFocusItem()) { - return; - } - - setVisible(false); -} - bool MenuWindow::effectEnabled() const { return GlobalSetting::instance()->get(GlobalSetting::EffectEnabled).toBool(); diff --git a/src/windows/menu-main-window.h b/src/windows/menu-main-window.h index a15403b..2399530 100644 --- a/src/windows/menu-main-window.h +++ b/src/windows/menu-main-window.h @@ -133,9 +133,6 @@ Q_SIGNALS: void beforeFullScreenExited(); void panelPosChanged(); -private Q_SLOTS: - void onActiveFocusItemChanged(); - protected: void exposeEvent(QExposeEvent *event) override; void focusOutEvent(QFocusEvent *event) override;