Fix Windows tray show handling

This commit is contained in:
Курнат Андрей
2026-06-10 05:52:40 +03:00
parent d64957dfcd
commit 8f61d0ba8c
2 changed files with 58 additions and 13 deletions
+50 -11
View File
@@ -48,8 +48,11 @@
#endif
#include <QApplication>
#include <QCursor>
#include <QDesktopServices>
#include <QGuiApplication>
#include <QMenuBar>
#include <QScreen>
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<HWND>(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<HWND>(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
}
+8 -2
View File
@@ -27,6 +27,7 @@
#include "csync.h"
#include "syncfileitem.h"
#include <chrono>
#include <sys/stat.h>
#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<std::chrono::system_clock>(fileTime));
#else
const auto systemTime = std::chrono::time_point_cast<std::chrono::system_clock::duration>(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<std::chrono::system_clock::duration>(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::file_clock>(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<std::filesystem::file_time_type::duration>(
fileNow + (std::chrono::system_clock::from_time_t(fileTime) - systemNow));
#endif
}