Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelog/unreleased/89791
-rw-r--r--src/gui/CMakeLists.txt5
-rw-r--r--src/gui/guiutility.cpp72
3 files changed, 60 insertions, 18 deletions
diff --git a/changelog/unreleased/8979 b/changelog/unreleased/8979
index 6dba41338..9116eedbe 100644
--- a/changelog/unreleased/8979
+++ b/changelog/unreleased/8979
@@ -5,3 +5,4 @@ We now ensure that we receive the window messages dispatched by the system.
https://github.com/owncloud/client/issues/8979
https://github.com/owncloud/client/pull/9142
https://github.com/owncloud/client/pull/9220
+https://github.com/owncloud/client/pull/9227
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 714417848..95ac47a57 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -2,6 +2,10 @@ include(ECMAddAppIcon)
find_package(Qt5 REQUIRED COMPONENTS Widgets)
+#if (WIN32)
+# find_package(Qt5 REQUIRED COMPONENTS WinExtras)
+#endif()
+
add_subdirectory(updater)
set(client_UI_SRCS
@@ -169,6 +173,7 @@ elseif( WIN32 )
target_sources(owncloudCore PRIVATE
folderwatcher_win.cpp
navigationpanehelper.cpp)
+# target_link_libraries(owncloudCore PUBLIC Qt5::WinExtras)
elseif(UNIX AND NOT APPLE )
## handle DBUS for Fdo notifications
find_package(Qt5 COMPONENTS DBus)
diff --git a/src/gui/guiutility.cpp b/src/gui/guiutility.cpp
index b8fbaac92..8414d0c5c 100644
--- a/src/gui/guiutility.cpp
+++ b/src/gui/guiutility.cpp
@@ -23,8 +23,15 @@
#include <QIcon>
#ifdef Q_OS_WIN
-#include <QThread>
-#include <QTimer>
+#include <QMetaMethod>
+
+#include <chrono>
+#include <thread>
+
+using namespace std::chrono;
+using namespace std::chrono_literals;
+
+#include "version.h"
#endif
#include "theme.h"
@@ -38,47 +45,76 @@ Q_LOGGING_CATEGORY(lcUtility, "gui.utility", QtInfoMsg)
namespace {
#ifdef Q_OS_WIN
-void watchWM()
+// TODO: 2.11 move to the new Platform class
+struct
+{
+ HANDLE windowMessageWatcherEvent = CreateEventW(nullptr, true, false, L"watchWMEvent");
+ bool windowMessageWatcherRun = true;
+} watchWMCtx;
+
+void startShutdownWatcher()
{
// Qt only receives window message if a window was displayed at least once
// create an invisible window to handle WM_ENDSESSION
- QThread::create([] {
+ // We also block a system shutdown until we are properly shutdown our selfs
+ // In the unlikely case that we require more than 5s Windows will require a fullscreen message
+ // with our icon, title and the reason why we are blocking the shutdown.
+ new std::thread([] {
WNDCLASS wc = {};
wc.hInstance = GetModuleHandle(nullptr);
wc.lpszClassName = L"ocWindowMessageWatcher";
+#if MIRALL_VERSION_MINOR > 9
+// TODO: for now we won't display a proper icon
+#error "Please add the QtWinExtras dependency"
+ wc.hIcon = QtWin::toHICON(Theme::instance()->applicationIcon().pixmap(64, 64));
+#endif
wc.lpfnWndProc = [](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -> LRESULT {
// qDebug() << MSG { hwnd, msg, wParam, lParam, 0, {} };
if (msg == WM_QUERYENDSESSION) {
+ qCDebug(OCC::lcUtility) << "Received WM_QUERYENDSESSION";
return 1;
} else if (msg == WM_ENDSESSION) {
- qCInfo(OCC::lcUtility) << "Received WM_ENDSESSION quitting";
- QTimer::singleShot(0, qApp, &QApplication::quit);
+ qCDebug(OCC::lcUtility) << "Received WM_ENDSESSION quitting";
+ QMetaObject::invokeMethod(qApp, &QApplication::quit);
+ QElapsedTimer shutdownTimer;
+ if (lParam == ENDSESSION_LOGOFF) {
+ // block the windows shutdown until we are done
+ const QString description = QApplication::translate("Utility", "Shutting down %1").arg(Theme::instance()->appNameGUI());
+ OC_ASSERT(ShutdownBlockReasonCreate(hwnd, reinterpret_cast<const wchar_t *>(description.utf16())));
+ }
+ WaitForSingleObject(watchWMCtx.windowMessageWatcherEvent, INFINITE);
+ if (lParam == ENDSESSION_LOGOFF) {
+ OC_ASSERT(ShutdownBlockReasonDestroy(hwnd));
+ }
+ qCInfo(OCC::lcUtility) << "WM_ENDSESSION successfully shut down" << shutdownTimer.elapsed();
+ watchWMCtx.windowMessageWatcherRun = false;
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
};
-
OC_ASSERT(RegisterClass(&wc));
- auto window = CreateWindowW(wc.lpszClassName, L"watcher", WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, wc.hInstance, nullptr);
- OC_ASSERT_X(window, Utility::formatWinError(GetLastError()).toUtf8().constData());
+ auto watcherWindow = CreateWindowW(wc.lpszClassName, reinterpret_cast<const wchar_t *>(Theme::instance()->appNameGUI().utf16()),
+ WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, wc.hInstance, nullptr);
+ OC_ASSERT_X(watcherWindow, Utility::formatWinError(GetLastError()).toUtf8().constData());
- bool run = true;
- QObject::connect(qApp, &QApplication::aboutToQuit, [&run] {
- run = false;
- });
MSG msg;
- while (run) {
- if (!PeekMessageW(&msg, window, 0, 0, PM_REMOVE)) {
- QThread::msleep(100);
+ while (watchWMCtx.windowMessageWatcherRun) {
+ if (!PeekMessageW(&msg, watcherWindow, 0, 0, PM_REMOVE)) {
+ std::this_thread::sleep_for(100ms);
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
- })->start();
+ });
+
+ qAddPostRoutine([] {
+ qCDebug(OCC::lcUtility) << "app closed";
+ SetEvent(watchWMCtx.windowMessageWatcherEvent);
+ });
}
-Q_COREAPP_STARTUP_FUNCTION(watchWM);
+Q_COREAPP_STARTUP_FUNCTION(startShutdownWatcher);
#endif
}