diff options
-rw-r--r-- | changelog/9417 | 5 | ||||
-rw-r--r-- | src/gui/guiutility.cpp | 24 | ||||
-rw-r--r-- | src/gui/guiutility.h | 5 | ||||
-rw-r--r-- | src/gui/main.cpp | 10 |
4 files changed, 33 insertions, 11 deletions
diff --git a/changelog/9417 b/changelog/9417 new file mode 100644 index 000000000..61aa80d65 --- /dev/null +++ b/changelog/9417 @@ -0,0 +1,5 @@ +Bugfix: Fix possible crash + +We change the initialisation of a Windows icon to prevent a possible crash. + +https://github.com/owncloud/client/issues/9417 diff --git a/src/gui/guiutility.cpp b/src/gui/guiutility.cpp index 00a9e2e93..830ac71e8 100644 --- a/src/gui/guiutility.cpp +++ b/src/gui/guiutility.cpp @@ -45,30 +45,39 @@ using namespace OCC; Q_LOGGING_CATEGORY(lcUtility, "gui.utility", QtInfoMsg) +#ifdef Q_OS_WIN namespace { -#ifdef Q_OS_WIN // TODO: 2.11 move to the new Platform class struct { HANDLE windowMessageWatcherEvent = CreateEventW(nullptr, true, false, nullptr); bool windowMessageWatcherRun = true; + std::thread *watcherThread = nullptr; } watchWMCtx; +} -void startShutdownWatcher() +void Utility::startShutdownWatcher() { + if (watchWMCtx.watcherThread) { + return; + } // Qt only receives window message if a window was displayed at least once // create an invisible window to handle WM_ENDSESSION // 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([] { + + // ensure to initialise the icon in the main thread + HICON icon = {}; + if (qobject_cast<QGuiApplication *>(qApp)) { + icon = QtWin::toHICON(Theme::instance()->applicationIcon().pixmap(64, 64)); + } + watchWMCtx.watcherThread = new std::thread([icon] { WNDCLASS wc = {}; wc.hInstance = GetModuleHandle(nullptr); wc.lpszClassName = L"ocWindowMessageWatcher"; - if (qobject_cast<QGuiApplication *>(qApp)) { - wc.hIcon = QtWin::toHICON(Theme::instance()->applicationIcon().pixmap(64, 64)); - } + wc.hIcon = icon; wc.lpfnWndProc = [](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -> LRESULT { // qDebug() << MSG { hwnd, msg, wParam, lParam, 0, {} }; if (msg == WM_QUERYENDSESSION) { @@ -116,9 +125,8 @@ void startShutdownWatcher() SetEvent(watchWMCtx.windowMessageWatcherEvent); }); } -Q_COREAPP_STARTUP_FUNCTION(startShutdownWatcher); #endif -} + bool Utility::openBrowser(const QUrl &url, QWidget *errorWidgetParent) { diff --git a/src/gui/guiutility.h b/src/gui/guiutility.h index 141556b3d..964182d7a 100644 --- a/src/gui/guiutility.h +++ b/src/gui/guiutility.h @@ -51,6 +51,11 @@ namespace Utility { QIcon getCoreIcon(const QString &icon_name); +#ifdef Q_OS_WIN + // utility thread that takes care of proper Windows logout handling + void startShutdownWatcher(); +#endif + } // namespace Utility } // namespace OCC diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 2224e6d38..9e164763f 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -22,9 +22,10 @@ #endif #include "application.h" -#include "theme.h" -#include "common/utility.h" #include "cocoainitializer.h" +#include "common/utility.h" +#include "guiutility.h" +#include "theme.h" #include "updater/updater.h" @@ -63,8 +64,11 @@ int main(int argc, char **argv) // though it looks slightly less native. Check here after the // QApplication was constructed, but before any QWidget is // constructed. - if (app.devicePixelRatio() > 1) + if (app.devicePixelRatio() > 1) { QApplication::setStyle(QStringLiteral("fusion")); + } + // TODO: 2.11 move to platform class + Utility::startShutdownWatcher(); #endif // Q_OS_WIN #ifndef Q_OS_WIN |