From 15219459baed09d03d17a12c72302595c135fd53 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Wed, 28 Dec 2022 13:43:04 -0700 Subject: [PATCH] Add a background tab action to the context menu. https://redmine.stoutner.com/issues/949 --- src/helpers/UserAgentHelper.cpp | 12 ++--- src/interceptors/UrlRequestInterceptor.cpp | 57 +++++++++++----------- src/widgets/PrivacyWebEngineView.cpp | 41 ++++++++++++++-- src/widgets/PrivacyWebEngineView.h | 1 + src/widgets/TabWidget.cpp | 9 ++-- src/widgets/TabWidget.h | 2 +- 6 files changed, 79 insertions(+), 43 deletions(-) diff --git a/src/helpers/UserAgentHelper.cpp b/src/helpers/UserAgentHelper.cpp index 14a71e2..63baca9 100644 --- a/src/helpers/UserAgentHelper.cpp +++ b/src/helpers/UserAgentHelper.cpp @@ -49,12 +49,12 @@ const QString UserAgentHelper::SAFARI_MACOS_TRANSLATED = i18n("Safari on macOS") // Define the public user agent constants. const QString UserAgentHelper::PRIVACY_BROWSER_USER_AGENT = QStringLiteral("PrivacyBrowser/1.0"); -const QString UserAgentHelper::FIREFOX_LINUX_USER_AGENT = QStringLiteral("Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"); -const QString UserAgentHelper::CHROMIUM_LINUX_USER_AGENT = QStringLiteral("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36"); -const QString UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0"); -const QString UserAgentHelper::CHROME_WINDOWS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36"); -const QString UserAgentHelper::EDGE_WINDOWS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71"); -const QString UserAgentHelper::SAFARI_MACOS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15"); +const QString UserAgentHelper::FIREFOX_LINUX_USER_AGENT = QStringLiteral("Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0"); +const QString UserAgentHelper::CHROMIUM_LINUX_USER_AGENT = QStringLiteral("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"); +const QString UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0"); +const QString UserAgentHelper::CHROME_WINDOWS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"); +const QString UserAgentHelper::EDGE_WINDOWS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54"); +const QString UserAgentHelper::SAFARI_MACOS_USER_AGENT = QStringLiteral("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15"); // Construct the class. UserAgentHelper::UserAgentHelper() {}; diff --git a/src/interceptors/UrlRequestInterceptor.cpp b/src/interceptors/UrlRequestInterceptor.cpp index 6348898..83f1045 100644 --- a/src/interceptors/UrlRequestInterceptor.cpp +++ b/src/interceptors/UrlRequestInterceptor.cpp @@ -31,34 +31,6 @@ UrlRequestInterceptor::UrlRequestInterceptor(QObject *parentObjectPointer) : QWe void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &urlRequestInfo) { - // Handle the request according to the navigation type. - switch (urlRequestInfo.navigationType()) - { - case QWebEngineUrlRequestInfo::NavigationTypeLink: - case QWebEngineUrlRequestInfo::NavigationTypeTyped: - case QWebEngineUrlRequestInfo::NavigationTypeBackForward: - case QWebEngineUrlRequestInfo::NavigationTypeRedirect: - { - // Only check the hosts if the main URL is changing. - if (urlRequestInfo.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame) - { - // Get the hosts. - QString requestingHost = urlRequestInfo.initiator().host(); - QString requestedHost = urlRequestInfo.requestUrl().host(); - - // Reapply the domain settings if the host is changing. - if (requestingHost != requestedHost) - emit applyDomainSettings(requestedHost); - } - - break; - } - - default: - // Do nothing. - break; - } - // Handle the request according to the resource type. switch (urlRequestInfo.resourceType()) { @@ -96,4 +68,33 @@ void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &urlReques break; } } + + // Handle the request according to the navigation type. + switch (urlRequestInfo.navigationType()) + { + case QWebEngineUrlRequestInfo::NavigationTypeLink: + case QWebEngineUrlRequestInfo::NavigationTypeTyped: + case QWebEngineUrlRequestInfo::NavigationTypeBackForward: + // case QWebEngineUrlRequestInfo::NavigationTypeReload: This can be uncommented once https://redmine.stoutner.com/issues/821 has been fixed. + case QWebEngineUrlRequestInfo::NavigationTypeRedirect: + { + // Only check the hosts if the main URL is changing. + if (urlRequestInfo.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame) + { + // Get the hosts. + QString requestingHost = urlRequestInfo.initiator().host(); + QString requestedHost = urlRequestInfo.requestUrl().host(); + + // Reapply the domain settings if the host is changing. + if (requestingHost != requestedHost) + emit applyDomainSettings(requestedHost); + } + + break; + } + + default: + // Do nothing. + break; + } } diff --git a/src/widgets/PrivacyWebEngineView.cpp b/src/widgets/PrivacyWebEngineView.cpp index 10a3a47..d7b3f8c 100644 --- a/src/widgets/PrivacyWebEngineView.cpp +++ b/src/widgets/PrivacyWebEngineView.cpp @@ -22,6 +22,10 @@ #include "databases/CookiesDatabase.h" #include "windows/BrowserWindow.h" +// Qt toolkit headers. +#include +#include + // Construct the class. PrivacyWebEngineView::PrivacyWebEngineView() : QWebEngineView(nullptr) {} @@ -40,19 +44,40 @@ void PrivacyWebEngineView::addCookieToList(const QNetworkCookie &cookie) const emit updateCookiesAction(cookieListPointer->size()); } +void PrivacyWebEngineView::contextMenuEvent(QContextMenuEvent *contextMenuEvent) { + // Get a handle for the + QWebEnginePage *webEnginePagePointer = page(); + + // Get a handle for the menu. + QMenu *contextMenu = webEnginePagePointer->createStandardContextMenu(); + + // Get the list of context menu actions. + const QList contextMenuActionsList = contextMenu->actions(); + + // Add the open link in new background tab action if the context menu already contains the open link in new window action. + if (contextMenuActionsList.contains(webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewWindow))) + contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewWindow), webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewBackgroundTab)); + + // Display the menu using the location in the context menu event. + contextMenu->popup(contextMenuEvent->globalPos()); +} + QWebEngineView* PrivacyWebEngineView::createWindow(QWebEnginePage::WebWindowType webWindowType) { // Get a handle for the browser window. BrowserWindow *browserWindowPointer = qobject_cast(window()); // Create the requsted window type. - switch (webWindowType) { - case QWebEnginePage::WebBrowserTab: { + switch (webWindowType) + { + case QWebEnginePage::WebBrowserTab: + { // Create the new tab and return the privacy WebEngine view pointer. `true` removes the focus from the blank URL line edit. // The new privacy WebEngine view pointer is returned so it can be populated with the link from the context menu. return browserWindowPointer->tabWidgetPointer->addTab(true); } - case QWebEnginePage::WebBrowserWindow: { + case QWebEnginePage::WebBrowserWindow: + { // Create a new browser window. BrowserWindow *newBrowserWindowPointer = new BrowserWindow(); @@ -63,7 +88,15 @@ QWebEngineView* PrivacyWebEngineView::createWindow(QWebEnginePage::WebWindowType return newBrowserWindowPointer->tabWidgetPointer->loadBlankInitialWebsite(); } - default: { + case QWebEnginePage::WebBrowserBackgroundTab: + { + // Create the new tab and return the privacy WebEngine view pointer. `false` does not clear the URL line edit. `true` creates a background tab. + // The new privacy WebEngine view pointer is returned so it can be populated with the link from the context menu. + return browserWindowPointer->tabWidgetPointer->addTab(false, true); + } + + default: + { // Return an null pointer for opening a background tab and opening a web dialog. return nullptr; } diff --git a/src/widgets/PrivacyWebEngineView.h b/src/widgets/PrivacyWebEngineView.h index c227f42..31319da 100644 --- a/src/widgets/PrivacyWebEngineView.h +++ b/src/widgets/PrivacyWebEngineView.h @@ -54,6 +54,7 @@ public Q_SLOTS: protected: // The protected functions. + void contextMenuEvent(QContextMenuEvent *contextMenuEvent) override; QWebEngineView* createWindow(QWebEnginePage::WebWindowType webWindowType) override; }; #endif diff --git a/src/widgets/TabWidget.cpp b/src/widgets/TabWidget.cpp index ff8563c..bd62f83 100644 --- a/src/widgets/TabWidget.cpp +++ b/src/widgets/TabWidget.cpp @@ -141,7 +141,7 @@ void TabWidget::addFirstTab() tabWidgetPointer->currentWidget()->setFocus(); } -PrivacyWebEngineView* TabWidget::addTab(const bool focusNewWebEngineView) +PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const bool backgroundTab) { // Create a privacy WebEngine view. PrivacyWebEngineView *privacyWebEngineViewPointer = new PrivacyWebEngineView(); @@ -337,11 +337,12 @@ PrivacyWebEngineView* TabWidget::addTab(const bool focusNewWebEngineView) // Populate the zoom factor. This is necessary if a URL is being loaded, like a local URL, that does not trigger `applyDomainSettings()`. privacyWebEngineViewPointer->setZoomFactor(Settings::zoomFactor()); - // Move to the new tab. - tabWidgetPointer->setCurrentIndex(newTabIndex); + // Move to the new tab if it is not a background tab. + if (!backgroundTab) + tabWidgetPointer->setCurrentIndex(newTabIndex); // Clear the URL line edit focus so that it populates correctly when opening a new tab from the context menu. - if (focusNewWebEngineView) + if (removeUrlLineEditFocus) emit clearUrlLineEditFocus(); // Return the privacy WebEngine view pointer. diff --git a/src/widgets/TabWidget.h b/src/widgets/TabWidget.h index bd857b0..246daa4 100644 --- a/src/widgets/TabWidget.h +++ b/src/widgets/TabWidget.h @@ -91,7 +91,7 @@ signals: public Q_SLOTS: // The public slots. void addCookieToStore(QNetworkCookie cookie, QWebEngineCookieStore *webEngineCookieStorePointer = nullptr) const; - PrivacyWebEngineView* addTab(const bool focusNewWebEngineView=false); + PrivacyWebEngineView* addTab(const bool removeUrlLineEditFocus=false, const bool backgroundTab=false); void applyApplicationSettings(); void applyDomainSettingsAndReload(); void applyDomainSettingsWithoutReloading(const QString &hostname); -- 2.45.2