From bdf68135020174387c6afc2af739b0e896aa7cf4 Mon Sep 17 00:00:00 2001 From: Jeff Zignego Date: Mon, 28 Feb 2022 15:33:56 -0600 Subject: [PATCH] src/mainwindow.cpp: don't draw on screen until ready The OS signal handler can't be installed until after the Qt event loop starts since it eventually calls `QApplication::exit(0);`, and that will cleanup anything we draw on the screen. Thus we don't want to connect any slots that touch the what's in focus or draw on the screen until the OS signal handler is ready. `mainwindow->init()` is called in `src/main.cpp` before `app.exec()`, thus we don't want to connect any slots that draw on screen in `mainwindow->init()`. Instead, `mainwindow->init()` will connect the `setupWindow()` slot, to the the `signalHandlerInstalled` Qt signal emitted by `this->handler`. At that point the OS signal handler has been installed and it is safe to draw on the screen. --- src/mainwindow.cpp | 50 +++++++++++++++++++++++++++++---------------- src/mainwindow.h | 5 +++-- src/unixsignals.cpp | 2 ++ src/unixsignals.h | 1 + 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 98d7245..2e5788b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -116,7 +116,7 @@ void MainWindow::init(AnyOption *opts) setMinimumHeight(minimalHeight); } - hiddenCurdor = new QCursor(Qt::BlankCursor); + hiddenCursor = new QCursor(Qt::BlankCursor); qDebug() << "Application icon: " << qwkSettings->getQString("application/icon"); setWindowIcon(QIcon( @@ -302,6 +302,29 @@ void MainWindow::init(AnyOption *opts) qwkSettings->getBool("security/local_content_can_access_remote_urls") ); + QNetworkConfigurationManager manager; + QNetworkConfiguration cfg = manager.defaultConfiguration(); + + n_session = new QNetworkSession(cfg); + connect(n_session, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(networkStateChanged(QNetworkSession::State))); + n_session->open(); + + connect(this->handler, SIGNAL(signalHandlerInstalled()), this, SLOT(setupWindow())); +} + +/* The OS signal handler can't be installed until after the Qt event loop + * starts since it eventually calls `QApplication::exit(0);`, and that will + * cleanup anything we draw on the screen. Thus we don't want to connect any + * slots that touch the what's in focus or draw on the screen until the OS + * signal handler is ready. `this->init()` is called in `src/main.cpp` before + * `app.exec()`, thus we don't do any of this in `this->init()`. Instead, + * `this->init()` will connect this slot, `this->setupWindow()`, to the the + * `signalHandlerInstalled` Qt signal emitted by `this->handler`. At that point + * the OS signal handler has been installed and it is safe to draw on the + * screen. + */ +void MainWindow::setupWindow() +{ connect(view->page()->mainFrame(), SIGNAL(titleChanged(QString)), SLOT(adjustTitle(QString))); connect(view->page()->mainFrame(), SIGNAL(loadStarted()), SLOT(startLoading())); connect(view->page()->mainFrame(), SIGNAL(urlChanged(const QUrl &)), SLOT(urlChanged(const QUrl &))); @@ -311,34 +334,21 @@ void MainWindow::init(AnyOption *opts) connect(view, SIGNAL(qwkNetworkError(QNetworkReply::NetworkError,QString)), SLOT(handleQwkNetworkError(QNetworkReply::NetworkError,QString))); connect(view, SIGNAL(qwkNetworkReplyUrl(QUrl)), SLOT(handleQwkNetworkReplyUrl(QUrl))); - QNetworkConfigurationManager manager; - QNetworkConfiguration cfg = manager.defaultConfiguration(); - - n_session = new QNetworkSession(cfg); - connect(n_session, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(networkStateChanged(QNetworkSession::State))); - n_session->open(); - QDesktopWidget *desktop = QApplication::desktop(); connect(desktop, SIGNAL(resized(int)), SLOT(desktopResized(int))); - // Window show, start events loop - show(); - - view->setFocusPolicy(Qt::StrongFocus); - if (qwkSettings->getBool("view/hide_mouse_cursor")) { QApplication::setOverrideCursor(Qt::BlankCursor); - view->setCursor(*hiddenCurdor); - QApplication::processEvents(); //process events to force cursor update before press + view->setCursor(*hiddenCursor); } - int delay_resize = 1; + int delay_resize = 0; if (qwkSettings->getBool("view/startup_resize_delayed")) { delay_resize = qwkSettings->getUInt("view/startup_resize_delay"); } delayedResize->singleShot(delay_resize, this, SLOT(delayedWindowResize())); - int delay_load = 1; + int delay_load = 0; if (qwkSettings->getBool("browser/startup_load_delayed")) { delay_load = qwkSettings->getUInt("browser/startup_load_delay"); } @@ -361,9 +371,11 @@ void MainWindow::delayedWindowResize() showMaximized(); } else if (qwkSettings->getBool("view/fixed-size")) { centerFixedSizeWindow(); + } else { + show(); } - QApplication::processEvents(); //process events to force update + QApplication::processEvents(); //process events to force update } void MainWindow::resizeEvent(QResizeEvent* event) @@ -629,6 +641,8 @@ void MainWindow::desktopResized(int p) showMaximized(); } else if (qwkSettings->getBool("view/fixed-size")) { centerFixedSizeWindow(); + } else { + show(); } } diff --git a/src/mainwindow.h b/src/mainwindow.h index 01ccbb8..7ceb554 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -87,6 +87,8 @@ protected slots: void desktopResized(int p); + void setupWindow(); + void delayedWindowResize(); void delayedPageLoad(); void delayedPageReload(); @@ -106,7 +108,6 @@ protected slots: void unixSignalUsr2(); protected: - void centerFixedSizeWindow(); void attachJavascripts(); void attachStyles(); @@ -127,7 +128,7 @@ protected slots: QNetworkDiskCache *diskCache; QWebInspector *inspector; - QCursor *hiddenCurdor; + QCursor *hiddenCursor; QKeyEvent *eventExit; AnyOption *cmdopts; diff --git a/src/unixsignals.cpp b/src/unixsignals.cpp index 13bed56..63d2688 100644 --- a/src/unixsignals.cpp +++ b/src/unixsignals.cpp @@ -98,6 +98,8 @@ void UnixSignals::start() #else qWarning("No signal USR2 defined"); #endif + + emit signalHandlerInstalled(); } void UnixSignals::stop() diff --git a/src/unixsignals.h b/src/unixsignals.h index 576d311..3b20ba7 100644 --- a/src/unixsignals.h +++ b/src/unixsignals.h @@ -25,6 +25,7 @@ class UnixSignals : public QObject static SocketPair sockPair; Q_SIGNALS: + void signalHandlerInstalled(); void sigBREAK(); void sigTERM(); void sigHUP();