Skip to content

Commit 94ad783

Browse files
committed
fix: add wait mechanism for app icons
1. Implemented a pending check mechanism for app icons with absolute paths 2. When an app is added, check if the icon file exists immediately 3. If the file is missing, place the app in a pending queue and start a 1-second timer 4. Periodically check pending items to see if the icon file has become available 5. Added a 60-second timeout to force processing if files never appear 6. This resolves race conditions where app registration happens before icon data is fully synchronized to disk or mounted Log: Added delayed loading mechanism for application icons to handle temporary file unavailability Influence: 1. Install an application where the icon file exists immediately; verify the icon displays instantly 2. Install an application where the icon file is missing at first but appears within 60 seconds; verify the icon displays once the file is detected 3. Install an application with a non-existent icon path; verify the application is processed after the 60-second timeout 4. Test adding multiple applications with delayed icons simultaneously 5. Verify system resource usage and memory cleanup when the timer stops PMS: BUG-347859
1 parent b178a28 commit 94ad783

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

src/ddeintegration/appmgr.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@ AppMgr::AppMgr(QObject *parent)
127127
, m_objectManager(new AppManager1ApplicationObjectManager("org.desktopspec.ApplicationManager1",
128128
"/org/desktopspec/ApplicationManager1",
129129
QDBusConnection::sessionBus(), this))
130+
, m_checkTimer(new QTimer(this))
131+
, m_checkCount(0)
130132
{
133+
m_checkTimer->setInterval(3000); // 3 second interval
134+
connect(m_checkTimer, &QTimer::timeout, this, &AppMgr::checkPendingAppItems);
131135
initObjectManager();
132136
}
133137

@@ -430,6 +434,8 @@ void AppMgr::initObjectManager()
430434
qWarning() << "App already exists for the path:" << key;
431435
return;
432436
}
437+
// Reset check count when new app is added
438+
m_checkCount = 0;
433439
if (auto appItem = parseDBus2AppItem(interfacesAndProperties)) {
434440
qCDebug(logDdeIntegration) << "App item added, desktopId" << appItem->id;
435441
watchingAppItemAdded(key, appItem);
@@ -503,6 +509,22 @@ void AppMgr::fetchAppItems()
503509

504510
void AppMgr::watchingAppItemAdded(const QString &key, AppItem *appItem)
505511
{
512+
// Check if iconName is an absolute path and if the file exists
513+
if (isAbsolutePathIcon(appItem->iconName)) {
514+
QFileInfo fileInfo(appItem->iconName);
515+
if (!fileInfo.exists()) {
516+
// File doesn't exist, add to pending container
517+
m_pendingAppItems[key] = appItem;
518+
519+
// Start timer if not already running
520+
if (!m_checkTimer->isActive()) {
521+
m_checkTimer->start();
522+
}
523+
return;
524+
}
525+
}
526+
527+
// Icon exists or is a system icon, proceed with normal logic
506528
m_appItems[key] = appItem;
507529
watchingAppItemPropertyChanged(key, appItem);
508530
Q_EMIT changed();
@@ -527,6 +549,69 @@ void AppMgr::watchingAppItemRemoved(const QString &key)
527549
Q_EMIT changed();
528550
}
529551

552+
void AppMgr::checkPendingAppItems()
553+
{
554+
m_checkCount++;
555+
if (m_pendingAppItems.isEmpty()) {
556+
m_checkTimer->stop();
557+
return;
558+
}
559+
560+
QList<QPair<QString, AppItem *>> itemsToProcess;
561+
562+
// Check all pending items
563+
for (auto it = m_pendingAppItems.begin(); it != m_pendingAppItems.end(); ) {
564+
const QString &key = it.key();
565+
AppItem *appItem = it.value();
566+
567+
if (isAbsolutePathIcon(appItem->iconName)) {
568+
QFileInfo fileInfo(appItem->iconName);
569+
if (fileInfo.exists()) {
570+
// File now exists, add to main container
571+
itemsToProcess.append(qMakePair(key, appItem));
572+
it = m_pendingAppItems.erase(it);
573+
continue;
574+
}
575+
}
576+
++it;
577+
}
578+
579+
// Process items whose icons now exist
580+
for (const auto &itemPair : itemsToProcess) {
581+
const QString &key = itemPair.first;
582+
AppItem *appItem = itemPair.second;
583+
584+
m_appItems[key] = appItem;
585+
watchingAppItemPropertyChanged(key, appItem);
586+
Q_EMIT changed();
587+
}
588+
589+
// Check if timeout reached (60 seconds)
590+
if (m_checkCount >= 20 && !m_pendingAppItems.isEmpty()) {
591+
// Force process all remaining pending items
592+
for (auto it = m_pendingAppItems.begin(); it != m_pendingAppItems.end(); ) {
593+
const QString &key = it.key();
594+
AppItem *appItem = it.value();
595+
596+
m_appItems[key] = appItem;
597+
watchingAppItemPropertyChanged(key, appItem);
598+
Q_EMIT changed();
599+
600+
it = m_pendingAppItems.erase(it);
601+
}
602+
603+
m_checkTimer->stop();
604+
} else if (m_pendingAppItems.isEmpty()) {
605+
m_checkTimer->stop();
606+
}
607+
}
608+
609+
bool AppMgr::isAbsolutePathIcon(const QString &iconName) const
610+
{
611+
// Check if the icon name is an absolute path (starts with /)
612+
return iconName.startsWith('/');
613+
}
614+
530615
AppMgr *AppMgr::instance() {
531616
static AppMgr gInstance;
532617
return &gInstance;

src/ddeintegration/appmgr.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <QMap>
88
#include <QObject>
99
#include <QPointer>
10+
#include <QTimer>
11+
#include <QFileInfo>
1012
#include <dtkcore_global.h>
1113

1214
DCORE_BEGIN_NAMESPACE
@@ -56,15 +58,22 @@ class AppMgr : public QObject
5658
void changed();
5759
void itemDataChanged(const QString &id);
5860

61+
private slots:
62+
void checkPendingAppItems();
63+
5964
private:
6065
void initObjectManager();
6166
void fetchAppItems();
6267
void watchingAppItemAdded(const QString &key, AppMgr::AppItem *appItem);
6368
void watchingAppItemRemoved(const QString &key);
6469
void watchingAppItemPropertyChanged(const QString &key, AppMgr::AppItem *appItem);
6570
void updateAppsLaunchedTimes(const QVariantMap &appsLaunchedTimes);
71+
bool isAbsolutePathIcon(const QString &iconName) const;
6672

6773
private:
6874
__AppManager1ApplicationObjectManager *m_objectManager;
6975
QMap<QString, AppMgr::AppItem *> m_appItems;
76+
QMap<QString, AppMgr::AppItem *> m_pendingAppItems;
77+
QTimer *m_checkTimer;
78+
int m_checkCount;
7079
};

0 commit comments

Comments
 (0)