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:
authorHannah von Reth <hannah.vonreth@owncloud.com>2021-11-17 13:17:58 +0300
committerHannah von Reth <hannah.vonreth@owncloud.com>2021-11-17 17:11:11 +0300
commit53c1ead1d53bfc8d6ae07c5c67053a1797e64f8e (patch)
treea4bc48567c1da0f269a9092890aa4e8c57a69fff
parentcfb5ed05bebc186c009cdffd6f71c71f0a1cfb08 (diff)
Create our own message loop to receive WM_ENDSESSION
This ensures we receive the message even if no window is shown (cherry picked from commit 36311b00be41b1edbe46791f1c44d11f8584c4f8)
-rw-r--r--changelog/unreleased/89795
-rw-r--r--src/gui/guiutility.cpp52
-rw-r--r--src/gui/settingsdialog.cpp17
-rw-r--r--src/gui/settingsdialog.h4
4 files changed, 55 insertions, 23 deletions
diff --git a/changelog/unreleased/8979 b/changelog/unreleased/8979
index 8846fe3e6..6dba41338 100644
--- a/changelog/unreleased/8979
+++ b/changelog/unreleased/8979
@@ -1,6 +1,7 @@
Bugfix: Properly handle Windows log off
-We worked around a Qt bug which prevented the client from properly shutdown
-on Windows logout or during the client update.
+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
diff --git a/src/gui/guiutility.cpp b/src/gui/guiutility.cpp
index ead4a78ad..b8fbaac92 100644
--- a/src/gui/guiutility.cpp
+++ b/src/gui/guiutility.cpp
@@ -22,6 +22,11 @@
#include <QUrlQuery>
#include <QIcon>
+#ifdef Q_OS_WIN
+#include <QThread>
+#include <QTimer>
+#endif
+
#include "theme.h"
#include "common/asserts.h"
@@ -30,6 +35,53 @@ using namespace OCC;
Q_LOGGING_CATEGORY(lcUtility, "gui.utility", QtInfoMsg)
+namespace {
+
+#ifdef Q_OS_WIN
+void watchWM()
+{
+ // Qt only receives window message if a window was displayed at least once
+ // create an invisible window to handle WM_ENDSESSION
+ QThread::create([] {
+ WNDCLASS wc = {};
+ wc.hInstance = GetModuleHandle(nullptr);
+ wc.lpszClassName = L"ocWindowMessageWatcher";
+ wc.lpfnWndProc = [](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -> LRESULT {
+ // qDebug() << MSG { hwnd, msg, wParam, lParam, 0, {} };
+ if (msg == WM_QUERYENDSESSION) {
+ return 1;
+ } else if (msg == WM_ENDSESSION) {
+ qCInfo(OCC::lcUtility) << "Received WM_ENDSESSION quitting";
+ QTimer::singleShot(0, qApp, &QApplication::quit);
+ 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());
+
+ 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);
+ } else {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ })->start();
+}
+Q_COREAPP_STARTUP_FUNCTION(watchWM);
+#endif
+}
+
bool Utility::openBrowser(const QUrl &url, QWidget *errorWidgetParent)
{
if (!QDesktopServices::openUrl(url)) {
diff --git a/src/gui/settingsdialog.cpp b/src/gui/settingsdialog.cpp
index 1b72e2c18..01ebffc9b 100644
--- a/src/gui/settingsdialog.cpp
+++ b/src/gui/settingsdialog.cpp
@@ -326,23 +326,6 @@ void SettingsDialog::setVisible(bool visible)
QMainWindow::setVisible(visible);
}
-#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-
-bool SettingsDialog::nativeEvent(const QByteArray &eventType, void *message, long *result)
-{
- auto msg = reinterpret_cast<MSG *>(message);
- // https://github.com/owncloud/client/issues/8979
- // Qt5 has a bug that Windows already get closed on WM_QUERYENDSESSION
- // so they never receive WM_ENDSESSION
- // Capture the event and go down in style
- if (msg->message == WM_QUERYENDSESSION || msg->message == WM_ENDSESSION) {
- qCInfo(lcApplication) << "Shutting down" << *msg;
- QTimer::singleShot(0, ocApp(), Application::quit);
- }
- return false;
-}
-#endif
-
void SettingsDialog::slotSwitchPage(QAction *action)
{
_ui->stack->setCurrentWidget(_actionGroupWidgets.value(action));
diff --git a/src/gui/settingsdialog.h b/src/gui/settingsdialog.h
index f84734fdd..c96e559e0 100644
--- a/src/gui/settingsdialog.h
+++ b/src/gui/settingsdialog.h
@@ -71,10 +71,6 @@ protected:
void changeEvent(QEvent *) override;
void setVisible(bool visible) override;
-#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
-#endif
-
private slots:
void accountAdded(AccountState *);
void accountRemoved(AccountState *);