From: Soren Stoutner Date: Thu, 30 Jan 2025 21:33:46 +0000 (-0700) Subject: Open _blank targets in the current tab. https://redmine.stoutner.com/issues/967 X-Git-Tag: v0.8~2 X-Git-Url: https://gitweb.stoutner.com/?a=commitdiff_plain;h=777231460c54f358be428f7a44fe2f503d6971d8;p=PrivacyBrowserPC.git Open _blank targets in the current tab. https://redmine.stoutner.com/issues/967 --- diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 9eaebbb..b2b02ea 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -1,19 +1,20 @@ -# Copyright 2022-2024 Soren Stoutner . +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: 2022-2025 Soren Stoutner # -# This file is part of Privacy Browser PC . +# This file is part of Privacy Browser PC . # -# Privacy Browser PC is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. # -# Privacy Browser PC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. # -# You should have received a copy of the GNU General Public License -# along with Privacy Browser PC. If not, see . +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . # List the sources to include in the executable. @@ -23,5 +24,6 @@ target_sources(privacybrowser PRIVATE PrivacyWebEnginePage.cpp PrivacyWebEngineView.cpp TabWidget.cpp + TemporaryWebEngineView.cpp UrlLineEdit.cpp ) diff --git a/src/widgets/PrivacyWebEngineView.cpp b/src/widgets/PrivacyWebEngineView.cpp index 5a103ff..298cdb9 100644 --- a/src/widgets/PrivacyWebEngineView.cpp +++ b/src/widgets/PrivacyWebEngineView.cpp @@ -22,6 +22,7 @@ #include "PrivacyWebEngineView.h" #include "PrivacyWebEnginePage.h" #include "Settings.h" +#include "TemporaryWebEngineView.h" #include "ui_HttpAuthenticationDialog.h" #include "databases/CookiesDatabase.h" #include "databases/DomainsDatabase.h" @@ -30,7 +31,7 @@ #include "interceptors/UrlRequestInterceptor.h" #include "windows/BrowserWindow.h" -// Qt toolkit headers. +// Qt framework headers. #include #include @@ -314,8 +315,14 @@ void PrivacyWebEngineView::contextMenuEvent(QContextMenuEvent *contextMenuEvent) // 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))) { + // Create a manual open in new tab action. + QAction *manualOpenLinkInNewTabActionPointer = new QAction(i18nc("Open link in new tab action", "Open link in new tab"), contextMenu); + + // Connect the actions. + connect(manualOpenLinkInNewTabActionPointer, SIGNAL(triggered()), this, SLOT(manualOpenInNewTab())); + // Move the open in new tab action above the back action. - contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewTab)); + contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), manualOpenLinkInNewTabActionPointer); // Add the open link in background tab action above the back action. contextMenu->insertAction(webEnginePagePointer->action(QWebEnginePage::Back), webEnginePagePointer->action(QWebEnginePage::OpenLinkInNewBackgroundTab)); @@ -374,9 +381,25 @@ QWebEngineView* PrivacyWebEngineView::createWindow(QWebEnginePage::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. `true` adds the new tab adjacent to the current 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(true, true); + if (manuallyOpeninginNewTab) + { + // Reset the manually opening in new tab flag. + manuallyOpeninginNewTab = false; + + // Create the new tab and return the privacy WebEngine view pointer. `true` removes the focus from the blank URL line edit. `true` adds the new tab adjacent to the current 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(true, true); + } + else + { + // The web page is trying to automatically open a new tab by setting the target to be "_blank". Create a temporary WebEngine view and open it there. + // The URL cannot be loaded into this privacy WebEngine view because it will clear the web history. + // But the temporary WebEngine will capture the URL and then pass it back to this privacy WebEngine view. + TemporaryWebEngineView *temporaryWebEngineViewPointer = new TemporaryWebEngineView(this); + + // Return the temporary WebEngine view. + return temporaryWebEngineViewPointer; + } } case QWebEnginePage::WebBrowserWindow: @@ -428,6 +451,15 @@ void PrivacyWebEngineView::handleAuthenticationRequest(const QUrl &requestUrl, Q } } +void PrivacyWebEngineView::manualOpenInNewTab() +{ + // Set the manually opening in new tab flag. + manuallyOpeninginNewTab = true; + + // Open the url in a new tab. + triggerPageAction(QWebEnginePage::OpenLinkInNewTab); +} + void PrivacyWebEngineView::openWithChromium() const { // Open the current URL in Chromium diff --git a/src/widgets/PrivacyWebEngineView.h b/src/widgets/PrivacyWebEngineView.h index bf0323e..984d972 100644 --- a/src/widgets/PrivacyWebEngineView.h +++ b/src/widgets/PrivacyWebEngineView.h @@ -26,7 +26,7 @@ // KDE framework headers. #include -// Qt toolkit headers. +// Qt framework headers. #include #include #include @@ -90,6 +90,7 @@ private Q_SLOTS: void clearRequestsList(); void displayHttpPingDialog(const QString &httpPingUrl) const; void handleAuthenticationRequest(const QUrl &requestUrl, QAuthenticator *authenticatorPointer); + void manualOpenInNewTab(); void openWithChromium() const; void openWithFirefox() const; void saveHoveredLink(const QString &hoveredLink); @@ -99,6 +100,7 @@ private Q_SLOTS: private: // The private variables. QString hoveredLinkString; + bool manuallyOpeninginNewTab = false; KLineEdit *passwordLineEditPointer; KLineEdit *usernameLineEditPointer; QWebEngineProfile *webEngineProfilePointer; diff --git a/src/widgets/TemporaryWebEngineView.cpp b/src/widgets/TemporaryWebEngineView.cpp new file mode 100644 index 0000000..a95b555 --- /dev/null +++ b/src/widgets/TemporaryWebEngineView.cpp @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2025 Soren Stoutner + * + * This file is part of Privacy Browser PC . + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +// Application headers. +#include "PrivacyWebEnginePage.h" +#include "TemporaryWebEngineView.h" + +// Construct the class. +TemporaryWebEngineView::TemporaryWebEngineView(PrivacyWebEngineView *mainPrivacyWebEngineViewPointer) : QWebEngineView() +{ + // Create a WebEngine page using the same profile as the main privacy WebEngine, which is required in Qt 6. + // Sharing a profile somehow causes the URL to load in the main privacy WebEngine view. + PrivacyWebEnginePage *privacyWebEnginePagePointer = new PrivacyWebEnginePage(mainPrivacyWebEngineViewPointer->page()->profile()); + + // Set the WebEngine page. + setPage(privacyWebEnginePagePointer); + + // Connect the load started signal. + connect(this, SIGNAL(urlChanged(const QUrl&)), this, SLOT(stopLoadingUrl())); +} + +void TemporaryWebEngineView::stopLoadingUrl() +{ + // Stop loading the URL. + stop(); + + // Load the URL in the main privacy WebEngine view. + // For some reason, the URL already gets loaded there, possibly because they share a profile. + //mainPrivacyWebEngineViewPointer->load(url) + + // Destroy the temporary WebEngine view. + destroy(); +} diff --git a/src/widgets/TemporaryWebEngineView.h b/src/widgets/TemporaryWebEngineView.h new file mode 100644 index 0000000..df57283 --- /dev/null +++ b/src/widgets/TemporaryWebEngineView.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2025 Soren Stoutner + * + * This file is part of Privacy Browser PC . + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef TEMPORARY_WEBENGINE_VIEW_H +#define TEMPORARY_WEBENGINE_VIEW_H + +// Application headers. +#include "PrivacyWebEngineView.h" + +// Qt framework headers. +#include + +class TemporaryWebEngineView : public QWebEngineView +{ + // Include the Q_OBJECT macro. + Q_OBJECT + +public: + // The standard constructor. + explicit TemporaryWebEngineView(PrivacyWebEngineView *mainPrivacyWebEngineViewPointer); + +private Q_SLOTS: + // The private slots. + void stopLoadingUrl(); +}; +#endif