From 8f61d0ba8c65d77e96fd616180ef147d7bbc20b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D1=83=D1=80=D0=BD=D0=B0=D1=82=20=D0=90=D0=BD=D0=B4?= =?UTF-8?q?=D1=80=D0=B5=D0=B9?= Date: Wed, 10 Jun 2026 05:52:40 +0300 Subject: [PATCH] Fix Windows tray show handling --- Desktop/src/gui/application.cpp | 61 ++++++++++++++++++++++++------ Desktop/src/libsync/filesystem.cpp | 10 ++++- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/Desktop/src/gui/application.cpp b/Desktop/src/gui/application.cpp index 3cfe883e..c19b6cff 100644 --- a/Desktop/src/gui/application.cpp +++ b/Desktop/src/gui/application.cpp @@ -48,8 +48,11 @@ #endif #include +#include #include +#include #include +#include using namespace Qt::Literals::StringLiterals; using namespace OCC; @@ -97,6 +100,32 @@ void setUpInitialSyncFolder(AccountStatePtr accountStatePtr, bool useVfs) Qt::SingleShotConnection); accountStatePtr->account()->spacesManager()->checkReady(); } + +void ensureWindowIntersectsAvailableScreen(QWidget *window) +{ + if (!window) { + return; + } + + const auto frame = window->frameGeometry(); + for (const auto *screen : QGuiApplication::screens()) { + if (screen->availableGeometry().intersects(frame)) { + return; + } + } + + auto *screen = QGuiApplication::screenAt(QCursor::pos()); + if (!screen) { + screen = QGuiApplication::primaryScreen(); + } + if (!screen) { + return; + } + + const auto availableGeometry = screen->availableGeometry(); + window->resize(window->size().boundedTo(availableGeometry.size())); + window->move(availableGeometry.center() - window->rect().center()); +} } QString Application::displayLanguage() const @@ -244,23 +273,33 @@ AccountStatePtr Application::addNewAccount(AccountPtr newAccount) void Application::showSettings() { auto window = ocApp()->settingsDialog(); + ensureWindowIntersectsAvailableScreen(window); + + if (window->windowState().testFlag(Qt::WindowMinimized)) { + window->setWindowState(window->windowState() & ~Qt::WindowMinimized); + } + window->show(); + ensureWindowIntersectsAvailableScreen(window); window->raise(); window->activateWindow(); #if defined(Q_OS_WIN) // Windows disallows raising a Window when you're not the active application. - // Use a common hack to attach to the active application - const auto activeProcessId = GetWindowThreadProcessId(GetForegroundWindow(), nullptr); - if (activeProcessId != qApp->applicationPid()) { - const auto threadId = GetCurrentThreadId(); - // don't step here with a debugger... - if (AttachThreadInput(threadId, activeProcessId, true)) { - const auto hwnd = reinterpret_cast(window->winId()); - SetForegroundWindow(hwnd); - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - AttachThreadInput(threadId, activeProcessId, false); - } + // Use a common hack to attach to the active application. + const auto foregroundWindow = GetForegroundWindow(); + const auto foregroundThreadId = foregroundWindow ? GetWindowThreadProcessId(foregroundWindow, nullptr) : 0; + const auto currentThreadId = GetCurrentThreadId(); + const auto attachedToForegroundThread = + foregroundThreadId != 0 && foregroundThreadId != currentThreadId && AttachThreadInput(currentThreadId, foregroundThreadId, true); + + const auto hwnd = reinterpret_cast(window->winId()); + ShowWindow(hwnd, SW_RESTORE); + SetForegroundWindow(hwnd); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + + if (attachedToForegroundThread) { + AttachThreadInput(currentThreadId, foregroundThreadId, false); } #endif } diff --git a/Desktop/src/libsync/filesystem.cpp b/Desktop/src/libsync/filesystem.cpp index 801e0084..71fa8cf3 100644 --- a/Desktop/src/libsync/filesystem.cpp +++ b/Desktop/src/libsync/filesystem.cpp @@ -27,6 +27,7 @@ #include "csync.h" #include "syncfileitem.h" +#include #include #ifdef Q_OS_WIN32 @@ -74,7 +75,9 @@ time_t FileSystem::fileTimeToTime_t(std::filesystem::file_time_type fileTime) #ifdef HAS_CLOCK_CAST return std::chrono::system_clock::to_time_t(std::chrono::clock_cast(fileTime)); #else - const auto systemTime = std::chrono::time_point_cast(std::chrono::file_clock::to_sys(fileTime)); + const auto fileNow = std::filesystem::file_time_type::clock::now(); + const auto systemNow = std::chrono::system_clock::now(); + const auto systemTime = std::chrono::time_point_cast(systemNow + (fileTime - fileNow)); return std::chrono::system_clock::to_time_t(systemTime); #endif } @@ -83,7 +86,10 @@ std::filesystem::file_time_type FileSystem::time_tToFileTime(time_t fileTime) #ifdef HAS_CLOCK_CAST return std::chrono::clock_cast(std::chrono::system_clock::from_time_t(fileTime)); #else - return std::chrono::file_clock::from_sys(std::chrono::system_clock::from_time_t(fileTime)); + const auto fileNow = std::filesystem::file_time_type::clock::now(); + const auto systemNow = std::chrono::system_clock::now(); + return std::chrono::time_point_cast( + fileNow + (std::chrono::system_clock::from_time_t(fileTime) - systemNow)); #endif }