aboutsummaryrefslogtreecommitdiff
path: root/libs/uibase/src/taskprogressmanager.cpp
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
commit7ee008e150bc5bcf76082d726f719ee0fdfda982 (patch)
tree27fb39be241fdb5ac2734c574de678977d1856d0 /libs/uibase/src/taskprogressmanager.cpp
Fluorine Manager: full Linux port of Mod Organizer 2
Complete native Linux port with FUSE-based virtual filesystem, Proton/umu-run integration, and Flatpak packaging. Key features: - FUSE VFS replacing Windows USVFS (in-process + standalone helper for Flatpak) - Proton/GE-Proton/umu-run launcher with env var forwarding - Flatpak support (sandbox-aware VFS, NXM handler, umu-run) - Wine prefix management UI - Case-insensitive path resolution for Linux filesystems - QSettings-safe INI handling (avoids Bethesda INI corruption) - Portable instance support with auto-generated launcher scripts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/uibase/src/taskprogressmanager.cpp')
-rw-r--r--libs/uibase/src/taskprogressmanager.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/libs/uibase/src/taskprogressmanager.cpp b/libs/uibase/src/taskprogressmanager.cpp
new file mode 100644
index 0000000..3bcffb0
--- /dev/null
+++ b/libs/uibase/src/taskprogressmanager.cpp
@@ -0,0 +1,125 @@
+#include <uibase/taskprogressmanager.h>
+#include <uibase/log.h>
+#include <uibase/utility.h>
+#include <QApplication>
+#include <QMainWindow>
+#include <QWidget>
+
+namespace MOBase
+{
+
+TaskProgressManager& TaskProgressManager::instance()
+{
+ static TaskProgressManager s_Instance;
+ return s_Instance;
+}
+
+void TaskProgressManager::forgetMe(quint32 id)
+{
+ if (m_Taskbar == nullptr) {
+ return;
+ }
+ auto iter = m_Percentages.find(id);
+ if (iter != m_Percentages.end()) {
+ m_Percentages.erase(iter);
+ }
+ showProgress();
+}
+
+void TaskProgressManager::updateProgress(quint32 id, qint64 value, qint64 max)
+{
+ QMutexLocker lock(&m_Mutex);
+ if (m_Taskbar == nullptr) {
+ return;
+ }
+
+ if (value == max) {
+ auto iter = m_Percentages.find(id);
+ if (iter != m_Percentages.end()) {
+ m_Percentages.erase(iter);
+ }
+ } else {
+ m_Percentages[id] = std::make_pair(QTime::currentTime(), (value * 100) / max);
+ }
+
+ showProgress();
+}
+
+quint32 TaskProgressManager::getId()
+{
+ QMutexLocker lock(&m_Mutex);
+ return m_NextId++;
+}
+
+void TaskProgressManager::showProgress()
+{
+#ifdef _WIN32
+ if (!m_Percentages.empty()) {
+ m_Taskbar->SetProgressState(m_WinId, TBPF_NORMAL);
+
+ QTime now = QTime::currentTime();
+ unsigned long long total = 0;
+ unsigned long long count = 0;
+
+ for (auto iter = m_Percentages.begin(); iter != m_Percentages.end();) {
+ if (iter->second.first.secsTo(now) < 15) {
+ total += static_cast<unsigned long long>(iter->second.second);
+ ++iter;
+ ++count;
+ } else {
+ log::debug("no progress in 15 seconds ({})", iter->second.first.secsTo(now));
+ iter = m_Percentages.erase(iter);
+ }
+ }
+
+ m_Taskbar->SetProgressValue(m_WinId, total, count * 100);
+ } else {
+ m_Taskbar->SetProgressState(m_WinId, TBPF_NOPROGRESS);
+ }
+#else
+ // On Linux, taskbar progress is not supported in this implementation.
+ // Could integrate with D-Bus com.canonical.Unity.LauncherEntry or similar.
+ (void)m_Percentages;
+#endif
+}
+
+bool TaskProgressManager::tryCreateTaskbar()
+{
+#ifdef _WIN32
+ // try to find our main window
+ for (QWidget* widget : QApplication::topLevelWidgets()) {
+ QMainWindow* mainWin = qobject_cast<QMainWindow*>(widget);
+ if (mainWin != nullptr) {
+ m_WinId = reinterpret_cast<HWND>(mainWin->winId());
+ }
+ }
+
+ HRESULT result = 0;
+ if (m_WinId != nullptr) {
+ result = CoCreateInstance(CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(&m_Taskbar));
+ if (result == S_OK) {
+ return true;
+ }
+ }
+
+ m_Taskbar = nullptr;
+
+ if (m_CreateTries-- > 0) {
+ QTimer::singleShot(1000, this, SLOT(tryCreateTaskbar()));
+ } else {
+ log::warn("failed to create taskbar connection");
+ }
+ return false;
+#else
+ // On Linux, no Windows taskbar API
+ m_Taskbar = nullptr;
+ return false;
+#endif
+}
+
+TaskProgressManager::TaskProgressManager()
+ : m_NextId(1), m_CreateTries(10), m_WinId(nullptr), m_Taskbar(nullptr)
+{}
+
+} // namespace MOBase