| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  |  * Copyright (c) 2022-2023, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |  * Copyright (c) 2022, Matthew Costa <ucosty@gmail.com> | 
					
						
							| 
									
										
										
										
											2022-07-14 06:08:30 +02:00
										 |  |  |  * Copyright (c) 2022, Filiph Sandström <filiph.sandstrom@filfatstudios.com> | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  |  * Copyright (c) 2023, Linus Groh <linusg@serenityos.org> | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-03 21:26:51 +02:00
										 |  |  | #include "BrowserWindow.h"
 | 
					
						
							| 
									
										
										
										
											2024-04-26 18:53:55 -06:00
										 |  |  | #include "Application.h"
 | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  | #include "Icon.h"
 | 
					
						
							| 
									
										
										
										
											2022-07-14 06:08:30 +02:00
										 |  |  | #include "Settings.h"
 | 
					
						
							|  |  |  | #include "SettingsDialog.h"
 | 
					
						
							| 
									
										
										
										
											2023-08-05 10:42:26 -06:00
										 |  |  | #include "StringUtils.h"
 | 
					
						
							| 
									
										
										
										
											2024-03-26 11:38:12 -06:00
										 |  |  | #include "TaskManagerWindow.h"
 | 
					
						
							| 
									
										
										
										
											2022-10-05 15:23:41 +02:00
										 |  |  | #include "WebContentView.h"
 | 
					
						
							| 
									
										
										
										
											2022-09-13 12:18:32 -04:00
										 |  |  | #include <AK/TypeCasts.h>
 | 
					
						
							| 
									
										
										
										
											2024-04-02 21:24:17 -04:00
										 |  |  | #include <Ladybird/Qt/TabBar.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-05 10:42:26 -06:00
										 |  |  | #include <Ladybird/Utilities.h>
 | 
					
						
							| 
									
										
										
										
											2023-01-12 18:27:34 +00:00
										 |  |  | #include <LibWeb/CSS/PreferredColorScheme.h>
 | 
					
						
							| 
									
										
										
										
											2024-06-13 01:03:56 +02:00
										 |  |  | #include <LibWeb/CSS/PreferredContrast.h>
 | 
					
						
							| 
									
										
										
										
											2024-05-26 11:12:49 -04:00
										 |  |  | #include <LibWeb/Loader/UserAgent.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-31 07:07:07 -04:00
										 |  |  | #include <LibWebView/CookieJar.h>
 | 
					
						
							| 
									
										
										
										
											2023-09-11 17:49:57 +04:00
										 |  |  | #include <LibWebView/UserAgent.h>
 | 
					
						
							| 
									
										
										
										
											2022-07-05 21:10:50 +02:00
										 |  |  | #include <QAction>
 | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  | #include <QActionGroup>
 | 
					
						
							| 
									
										
										
										
											2024-03-26 11:38:12 -06:00
										 |  |  | #include <QApplication>
 | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  | #include <QClipboard>
 | 
					
						
							|  |  |  | #include <QGuiApplication>
 | 
					
						
							| 
									
										
										
										
											2022-09-26 17:57:44 +03:00
										 |  |  | #include <QInputDialog>
 | 
					
						
							| 
									
										
										
										
											2022-07-09 17:46:11 +02:00
										 |  |  | #include <QPlainTextEdit>
 | 
					
						
							| 
									
										
										
										
											2023-09-20 11:32:37 +02:00
										 |  |  | #include <QShortcut>
 | 
					
						
							| 
									
										
										
										
											2023-02-05 03:26:20 +01:00
										 |  |  | #include <QTabBar>
 | 
					
						
							| 
									
										
										
										
											2023-12-13 19:10:05 +01:00
										 |  |  | #include <QWindow>
 | 
					
						
							| 
									
										
										
										
											2022-07-03 21:26:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 11:52:59 -06:00
										 |  |  | namespace Ladybird { | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 16:25:22 +02:00
										 |  |  | static QIcon const& app_icon() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static QIcon icon; | 
					
						
							|  |  |  |     if (icon.isNull()) { | 
					
						
							|  |  |  |         QPixmap pixmap; | 
					
						
							|  |  |  |         pixmap.load(":/Icons/ladybird.png"); | 
					
						
							|  |  |  |         icon = QIcon(pixmap); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return icon; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-07 23:39:25 +01:00
										 |  |  | class HamburgerMenu : public QMenu { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using QMenu::QMenu; | 
					
						
							|  |  |  |     virtual ~HamburgerMenu() override = default; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual void showEvent(QShowEvent*) override | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!isVisible()) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         auto* browser_window = verify_cast<BrowserWindow>(parentWidget()); | 
					
						
							|  |  |  |         if (!browser_window) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         auto* current_tab = browser_window->current_tab(); | 
					
						
							|  |  |  |         if (!current_tab) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         // Ensure the hamburger menu placed within the browser window.
 | 
					
						
							|  |  |  |         auto* hamburger_button = current_tab->hamburger_button(); | 
					
						
							|  |  |  |         auto button_top_right = hamburger_button->mapToGlobal(hamburger_button->rect().bottomRight()); | 
					
						
							|  |  |  |         move(button_top_right - QPoint(rect().width(), 0)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-17 10:34:41 +01:00
										 |  |  | BrowserWindow::BrowserWindow(Vector<URL::URL> const& initial_urls, WebView::CookieJar& cookie_jar, WebContentOptions const& web_content_options, StringView webdriver_content_ipc_path, bool allow_popups, Tab* parent_tab, Optional<u64> page_index) | 
					
						
							| 
									
										
										
										
											2024-04-02 21:38:01 -04:00
										 |  |  |     : m_tabs_container(new TabWidget(this)) | 
					
						
							|  |  |  |     , m_cookie_jar(cookie_jar) | 
					
						
							| 
									
										
										
										
											2023-12-01 12:18:40 -05:00
										 |  |  |     , m_web_content_options(web_content_options) | 
					
						
							| 
									
										
										
										
											2022-12-15 09:18:52 -05:00
										 |  |  |     , m_webdriver_content_ipc_path(webdriver_content_ipc_path) | 
					
						
							| 
									
										
										
										
											2024-06-17 10:34:41 +01:00
										 |  |  |     , m_allow_popups(allow_popups) | 
					
						
							| 
									
										
										
										
											2022-07-03 21:26:51 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-05-27 16:25:22 +02:00
										 |  |  |     setWindowIcon(app_icon()); | 
					
						
							| 
									
										
										
										
											2022-07-12 11:41:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-13 19:10:05 +01:00
										 |  |  |     // Listen for DPI changes
 | 
					
						
							|  |  |  |     m_device_pixel_ratio = devicePixelRatio(); | 
					
						
							|  |  |  |     m_current_screen = screen(); | 
					
						
							| 
									
										
										
										
											2024-01-26 23:14:41 -05:00
										 |  |  |     if (QT_VERSION < QT_VERSION_CHECK(6, 6, 0) || QGuiApplication::platformName() != "wayland") { | 
					
						
							|  |  |  |         setAttribute(Qt::WA_NativeWindow); | 
					
						
							|  |  |  |         setAttribute(Qt::WA_DontCreateNativeAncestors); | 
					
						
							| 
									
										
										
										
											2023-12-13 19:10:05 +01:00
										 |  |  |         QObject::connect(m_current_screen, &QScreen::logicalDotsPerInchChanged, this, &BrowserWindow::device_pixel_ratio_changed); | 
					
						
							| 
									
										
										
										
											2024-01-26 23:14:41 -05:00
										 |  |  |         QObject::connect(windowHandle(), &QWindow::screenChanged, this, [this](QScreen* screen) { | 
					
						
							|  |  |  |             if (m_device_pixel_ratio != devicePixelRatio()) | 
					
						
							|  |  |  |                 device_pixel_ratio_changed(devicePixelRatio()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Listen for logicalDotsPerInchChanged signals on new screen
 | 
					
						
							|  |  |  |             QObject::disconnect(m_current_screen, &QScreen::logicalDotsPerInchChanged, nullptr, nullptr); | 
					
						
							|  |  |  |             m_current_screen = screen; | 
					
						
							|  |  |  |             QObject::connect(m_current_screen, &QScreen::logicalDotsPerInchChanged, this, &BrowserWindow::device_pixel_ratio_changed); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-13 19:10:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-07 23:39:25 +01:00
										 |  |  |     m_hamburger_menu = new HamburgerMenu(this); | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!Settings::the()->show_menubar()) | 
					
						
							|  |  |  |         menuBar()->hide(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QObject::connect(Settings::the(), &Settings::show_menubar_changed, this, [this](bool show_menubar) { | 
					
						
							|  |  |  |         menuBar()->setVisible(show_menubar); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* file_menu = menuBar()->addMenu("&File"); | 
					
						
							| 
									
										
										
										
											2022-07-07 02:55:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-05 07:21:48 -04:00
										 |  |  |     m_new_tab_action = new QAction("New &Tab", this); | 
					
						
							|  |  |  |     m_new_tab_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::AddTab)); | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_menu->addAction(m_new_tab_action); | 
					
						
							|  |  |  |     file_menu->addAction(m_new_tab_action); | 
					
						
							| 
									
										
										
										
											2022-07-07 02:55:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 18:53:55 -06:00
										 |  |  |     m_new_window_action = new QAction("New &Window", this); | 
					
						
							|  |  |  |     m_new_window_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::New)); | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_menu->addAction(m_new_window_action); | 
					
						
							|  |  |  |     file_menu->addAction(m_new_window_action); | 
					
						
							| 
									
										
										
										
											2024-04-26 18:53:55 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-25 03:26:42 +02:00
										 |  |  |     auto* close_current_tab_action = new QAction("&Close Current Tab", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     close_current_tab_action->setIcon(load_icon_from_uri("resource://icons/16x16/close-tab.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-01-12 19:39:07 +01:00
										 |  |  |     close_current_tab_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Close)); | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_menu->addAction(close_current_tab_action); | 
					
						
							|  |  |  |     file_menu->addAction(close_current_tab_action); | 
					
						
							| 
									
										
										
										
											2022-07-19 06:16:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-25 23:47:12 +02:00
										 |  |  |     auto* open_file_action = new QAction("&Open File...", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     open_file_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-folder-open.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-25 23:47:12 +02:00
										 |  |  |     open_file_action->setShortcut(QKeySequence(QKeySequence::StandardKey::Open)); | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_menu->addAction(open_file_action); | 
					
						
							|  |  |  |     file_menu->addAction(open_file_action); | 
					
						
							| 
									
										
										
										
											2023-05-25 23:47:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_menu->addSeparator(); | 
					
						
							| 
									
										
										
										
											2023-05-25 22:35:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     auto* edit_menu = m_hamburger_menu->addMenu("&Edit"); | 
					
						
							|  |  |  |     menuBar()->addMenu(edit_menu); | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_copy_selection_action = new QAction("&Copy", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     m_copy_selection_action->setIcon(load_icon_from_uri("resource://icons/16x16/edit-copy.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  |     m_copy_selection_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Copy)); | 
					
						
							|  |  |  |     edit_menu->addAction(m_copy_selection_action); | 
					
						
							|  |  |  |     QObject::connect(m_copy_selection_action, &QAction::triggered, this, &BrowserWindow::copy_selected_text); | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-22 11:56:49 +01:00
										 |  |  |     m_paste_action = new QAction("&Paste", this); | 
					
						
							|  |  |  |     m_paste_action->setIcon(load_icon_from_uri("resource://icons/16x16/paste.png"sv)); | 
					
						
							|  |  |  |     m_paste_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Paste)); | 
					
						
							|  |  |  |     edit_menu->addAction(m_paste_action); | 
					
						
							|  |  |  |     QObject::connect(m_paste_action, &QAction::triggered, this, &BrowserWindow::paste); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_select_all_action = new QAction("Select &All", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     m_select_all_action->setIcon(load_icon_from_uri("resource://icons/16x16/select-all.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  |     m_select_all_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::SelectAll)); | 
					
						
							|  |  |  |     edit_menu->addAction(m_select_all_action); | 
					
						
							|  |  |  |     QObject::connect(m_select_all_action, &QAction::triggered, this, &BrowserWindow::select_all); | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-25 22:35:27 +02:00
										 |  |  |     edit_menu->addSeparator(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-29 20:12:21 +01:00
										 |  |  |     m_find_in_page_action = new QAction("&Find in Page...", this); | 
					
						
							|  |  |  |     m_find_in_page_action->setIcon(load_icon_from_uri("resource://icons/16x16/find.png"sv)); | 
					
						
							|  |  |  |     m_find_in_page_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Find)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-13 21:09:49 +01:00
										 |  |  |     auto find_previous_shortcuts = QKeySequence::keyBindings(QKeySequence::StandardKey::FindPrevious); | 
					
						
							|  |  |  |     for (auto const& shortcut : find_previous_shortcuts) | 
					
						
							|  |  |  |         new QShortcut(shortcut, this, [this] { | 
					
						
							|  |  |  |             if (m_current_tab) | 
					
						
							|  |  |  |                 m_current_tab->find_previous(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto find_next_shortcuts = QKeySequence::keyBindings(QKeySequence::StandardKey::FindNext); | 
					
						
							|  |  |  |     for (auto const& shortcut : find_next_shortcuts) | 
					
						
							|  |  |  |         new QShortcut(shortcut, this, [this] { | 
					
						
							|  |  |  |             if (m_current_tab) | 
					
						
							|  |  |  |                 m_current_tab->find_next(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-29 20:12:21 +01:00
										 |  |  |     edit_menu->addAction(m_find_in_page_action); | 
					
						
							|  |  |  |     QObject::connect(m_find_in_page_action, &QAction::triggered, this, &BrowserWindow::show_find_in_page); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     edit_menu->addSeparator(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-25 03:23:33 +02:00
										 |  |  |     auto* settings_action = new QAction("&Settings", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     settings_action->setIcon(load_icon_from_uri("resource://icons/16x16/settings.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-25 03:23:33 +02:00
										 |  |  |     settings_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Preferences)); | 
					
						
							|  |  |  |     edit_menu->addAction(settings_action); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     auto* view_menu = m_hamburger_menu->addMenu("&View"); | 
					
						
							|  |  |  |     menuBar()->addMenu(view_menu); | 
					
						
							| 
									
										
										
										
											2022-09-12 09:22:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-01 12:46:24 -06:00
										 |  |  |     auto* open_next_tab_action = new QAction("Open &Next Tab", this); | 
					
						
							| 
									
										
										
										
											2022-09-12 09:22:43 +02:00
										 |  |  |     open_next_tab_action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_PageDown)); | 
					
						
							|  |  |  |     view_menu->addAction(open_next_tab_action); | 
					
						
							|  |  |  |     QObject::connect(open_next_tab_action, &QAction::triggered, this, &BrowserWindow::open_next_tab); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-01 12:46:24 -06:00
										 |  |  |     auto* open_previous_tab_action = new QAction("Open &Previous Tab", this); | 
					
						
							| 
									
										
										
										
											2022-09-12 09:22:43 +02:00
										 |  |  |     open_previous_tab_action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_PageUp)); | 
					
						
							|  |  |  |     view_menu->addAction(open_previous_tab_action); | 
					
						
							|  |  |  |     QObject::connect(open_previous_tab_action, &QAction::triggered, this, &BrowserWindow::open_previous_tab); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  |     view_menu->addSeparator(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  |     m_zoom_menu = view_menu->addMenu("&Zoom"); | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto* zoom_in_action = new QAction("Zoom &In", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     zoom_in_action->setIcon(load_icon_from_uri("resource://icons/16x16/zoom-in.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-01-12 19:52:24 +01:00
										 |  |  |     auto zoom_in_shortcuts = QKeySequence::keyBindings(QKeySequence::StandardKey::ZoomIn); | 
					
						
							| 
									
										
										
										
											2024-06-09 22:52:19 +01:00
										 |  |  |     auto secondary_zoom_shortcut = QKeySequence(Qt::CTRL | Qt::Key_Equal); | 
					
						
							|  |  |  |     if (!zoom_in_shortcuts.contains(secondary_zoom_shortcut)) | 
					
						
							|  |  |  |         zoom_in_shortcuts.append(AK::move(secondary_zoom_shortcut)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 19:52:24 +01:00
										 |  |  |     zoom_in_action->setShortcuts(zoom_in_shortcuts); | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  |     m_zoom_menu->addAction(zoom_in_action); | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  |     QObject::connect(zoom_in_action, &QAction::triggered, this, &BrowserWindow::zoom_in); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* zoom_out_action = new QAction("Zoom &Out", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     zoom_out_action->setIcon(load_icon_from_uri("resource://icons/16x16/zoom-out.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-01-12 19:39:07 +01:00
										 |  |  |     zoom_out_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::ZoomOut)); | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  |     m_zoom_menu->addAction(zoom_out_action); | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  |     QObject::connect(zoom_out_action, &QAction::triggered, this, &BrowserWindow::zoom_out); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* reset_zoom_action = new QAction("&Reset Zoom", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     reset_zoom_action->setIcon(load_icon_from_uri("resource://icons/16x16/zoom-reset.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  |     reset_zoom_action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0)); | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  |     m_zoom_menu->addAction(reset_zoom_action); | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  |     QObject::connect(reset_zoom_action, &QAction::triggered, this, &BrowserWindow::reset_zoom); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view_menu->addSeparator(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  |     auto* color_scheme_menu = view_menu->addMenu("&Color Scheme"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-26 17:28:01 +03:00
										 |  |  |     auto* color_scheme_group = new QActionGroup(this); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-01 12:46:24 -06:00
										 |  |  |     auto* auto_color_scheme = new QAction("&Auto", this); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  |     auto_color_scheme->setCheckable(true); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:28:01 +03:00
										 |  |  |     color_scheme_group->addAction(auto_color_scheme); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  |     color_scheme_menu->addAction(auto_color_scheme); | 
					
						
							|  |  |  |     QObject::connect(auto_color_scheme, &QAction::triggered, this, &BrowserWindow::enable_auto_color_scheme); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-01 12:46:24 -06:00
										 |  |  |     auto* light_color_scheme = new QAction("&Light", this); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  |     light_color_scheme->setCheckable(true); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:28:01 +03:00
										 |  |  |     color_scheme_group->addAction(light_color_scheme); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  |     color_scheme_menu->addAction(light_color_scheme); | 
					
						
							|  |  |  |     QObject::connect(light_color_scheme, &QAction::triggered, this, &BrowserWindow::enable_light_color_scheme); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-01 12:46:24 -06:00
										 |  |  |     auto* dark_color_scheme = new QAction("&Dark", this); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  |     dark_color_scheme->setCheckable(true); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:28:01 +03:00
										 |  |  |     color_scheme_group->addAction(dark_color_scheme); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  |     color_scheme_menu->addAction(dark_color_scheme); | 
					
						
							|  |  |  |     QObject::connect(dark_color_scheme, &QAction::triggered, this, &BrowserWindow::enable_dark_color_scheme); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto_color_scheme->setChecked(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-13 01:03:56 +02:00
										 |  |  |     auto* contrast_menu = view_menu->addMenu("&Contrast"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* contrast_group = new QActionGroup(this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* auto_contrast = new QAction("&Auto", this); | 
					
						
							|  |  |  |     auto_contrast->setCheckable(true); | 
					
						
							|  |  |  |     contrast_group->addAction(auto_contrast); | 
					
						
							|  |  |  |     contrast_menu->addAction(auto_contrast); | 
					
						
							|  |  |  |     QObject::connect(auto_contrast, &QAction::triggered, this, &BrowserWindow::enable_auto_contrast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* less_contrast = new QAction("&Less", this); | 
					
						
							|  |  |  |     less_contrast->setCheckable(true); | 
					
						
							|  |  |  |     contrast_group->addAction(less_contrast); | 
					
						
							|  |  |  |     contrast_menu->addAction(less_contrast); | 
					
						
							|  |  |  |     QObject::connect(less_contrast, &QAction::triggered, this, &BrowserWindow::enable_less_contrast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* more_contrast = new QAction("&More", this); | 
					
						
							|  |  |  |     more_contrast->setCheckable(true); | 
					
						
							|  |  |  |     contrast_group->addAction(more_contrast); | 
					
						
							|  |  |  |     contrast_menu->addAction(more_contrast); | 
					
						
							|  |  |  |     QObject::connect(more_contrast, &QAction::triggered, this, &BrowserWindow::enable_more_contrast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* no_preference_contrast = new QAction("&No Preference", this); | 
					
						
							|  |  |  |     no_preference_contrast->setCheckable(true); | 
					
						
							|  |  |  |     contrast_group->addAction(no_preference_contrast); | 
					
						
							|  |  |  |     contrast_menu->addAction(no_preference_contrast); | 
					
						
							|  |  |  |     QObject::connect(no_preference_contrast, &QAction::triggered, this, &BrowserWindow::enable_no_preference_contrast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto_contrast->setChecked(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     auto* show_menubar = new QAction("Show &Menubar", this); | 
					
						
							|  |  |  |     show_menubar->setCheckable(true); | 
					
						
							|  |  |  |     show_menubar->setChecked(Settings::the()->show_menubar()); | 
					
						
							|  |  |  |     view_menu->addAction(show_menubar); | 
					
						
							|  |  |  |     QObject::connect(show_menubar, &QAction::triggered, this, [](bool checked) { | 
					
						
							|  |  |  |         Settings::the()->set_show_menubar(checked); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* inspect_menu = m_hamburger_menu->addMenu("&Inspect"); | 
					
						
							|  |  |  |     menuBar()->addMenu(inspect_menu); | 
					
						
							| 
									
										
										
										
											2022-07-09 17:46:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_view_source_action = new QAction("View &Source", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     m_view_source_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-html.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  |     m_view_source_action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_U)); | 
					
						
							|  |  |  |     inspect_menu->addAction(m_view_source_action); | 
					
						
							|  |  |  |     QObject::connect(m_view_source_action, &QAction::triggered, this, [this] { | 
					
						
							| 
									
										
										
										
											2022-07-09 17:46:11 +02:00
										 |  |  |         if (m_current_tab) { | 
					
						
							| 
									
										
										
										
											2022-10-05 15:23:41 +02:00
										 |  |  |             m_current_tab->view().get_source(); | 
					
						
							| 
									
										
										
										
											2022-07-09 17:46:11 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 18:07:50 +02:00
										 |  |  |     auto* inspector_action = new QAction("Open &Inspector", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     inspector_action->setIcon(load_icon_from_uri("resource://icons/browser/dom-tree.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-12-02 10:58:17 -05:00
										 |  |  |     inspector_action->setShortcuts({ QKeySequence("Ctrl+Shift+I"), QKeySequence("F12") }); | 
					
						
							| 
									
										
										
										
											2022-09-25 12:17:53 +02:00
										 |  |  |     inspect_menu->addAction(inspector_action); | 
					
						
							|  |  |  |     QObject::connect(inspector_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         if (m_current_tab) { | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  |             m_current_tab->show_inspector_window(); | 
					
						
							| 
									
										
										
										
											2022-09-25 12:17:53 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 11:38:12 -06:00
										 |  |  |     auto* task_manager_action = new QAction("Open Task &Manager", this); | 
					
						
							|  |  |  |     task_manager_action->setIcon(load_icon_from_uri("resource://icons/16x16/app-system-monitor.png"sv)); | 
					
						
							|  |  |  |     task_manager_action->setShortcuts({ QKeySequence("Ctrl+Shift+M") }); | 
					
						
							|  |  |  |     inspect_menu->addAction(task_manager_action); | 
					
						
							| 
									
										
										
										
											2024-04-26 18:53:55 -06:00
										 |  |  |     QObject::connect(task_manager_action, &QAction::triggered, this, [] { | 
					
						
							|  |  |  |         static_cast<Ladybird::Application*>(QApplication::instance())->show_task_manager_window(); | 
					
						
							| 
									
										
										
										
											2024-03-26 11:38:12 -06:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     auto* debug_menu = m_hamburger_menu->addMenu("&Debug"); | 
					
						
							| 
									
										
										
										
											2024-05-06 18:13:54 +01:00
										 |  |  |     menuBar()->addMenu(debug_menu); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-14 20:19:41 +02:00
										 |  |  |     auto* dump_session_history_tree_action = new QAction("Dump Session History Tree", this); | 
					
						
							| 
									
										
										
										
											2024-04-14 02:54:12 +02:00
										 |  |  |     dump_session_history_tree_action->setIcon(load_icon_from_uri("resource://icons/16x16/history.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-08-14 20:19:41 +02:00
										 |  |  |     debug_menu->addAction(dump_session_history_tree_action); | 
					
						
							|  |  |  |     QObject::connect(dump_session_history_tree_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("dump-session-history"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* dump_dom_tree_action = new QAction("Dump &DOM Tree", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     dump_dom_tree_action->setIcon(load_icon_from_uri("resource://icons/browser/dom-tree.png"sv)); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     debug_menu->addAction(dump_dom_tree_action); | 
					
						
							|  |  |  |     QObject::connect(dump_dom_tree_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("dump-dom-tree"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* dump_layout_tree_action = new QAction("Dump &Layout Tree", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     dump_layout_tree_action->setIcon(load_icon_from_uri("resource://icons/16x16/layout.png"sv)); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     debug_menu->addAction(dump_layout_tree_action); | 
					
						
							|  |  |  |     QObject::connect(dump_layout_tree_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("dump-layout-tree"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* dump_paint_tree_action = new QAction("Dump &Paint Tree", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     dump_paint_tree_action->setIcon(load_icon_from_uri("resource://icons/16x16/layout.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-03-18 20:22:58 +01:00
										 |  |  |     debug_menu->addAction(dump_paint_tree_action); | 
					
						
							|  |  |  |     QObject::connect(dump_paint_tree_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("dump-paint-tree"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* dump_stacking_context_tree_action = new QAction("Dump S&tacking Context Tree", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     dump_stacking_context_tree_action->setIcon(load_icon_from_uri("resource://icons/16x16/layers.png"sv)); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     debug_menu->addAction(dump_stacking_context_tree_action); | 
					
						
							|  |  |  |     QObject::connect(dump_stacking_context_tree_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("dump-stacking-context-tree"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* dump_style_sheets_action = new QAction("Dump &Style Sheets", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     dump_style_sheets_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-css.png"sv)); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     debug_menu->addAction(dump_style_sheets_action); | 
					
						
							|  |  |  |     QObject::connect(dump_style_sheets_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("dump-style-sheets"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* dump_styles_action = new QAction("Dump &All Resolved Styles", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     dump_styles_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-css.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-27 15:33:08 +03:30
										 |  |  |     debug_menu->addAction(dump_styles_action); | 
					
						
							|  |  |  |     QObject::connect(dump_styles_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("dump-all-resolved-styles"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* dump_cookies_action = new QAction("Dump C&ookies", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     dump_cookies_action->setIcon(load_icon_from_uri("resource://icons/browser/cookie.png"sv)); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     debug_menu->addAction(dump_cookies_action); | 
					
						
							|  |  |  |     QObject::connect(dump_cookies_action, &QAction::triggered, this, [this] { | 
					
						
							| 
									
										
										
										
											2022-10-11 10:53:28 +02:00
										 |  |  |         m_cookie_jar.dump_cookies(); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* dump_local_storage_action = new QAction("Dump Loc&al Storage", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     dump_local_storage_action->setIcon(load_icon_from_uri("resource://icons/browser/local-storage.png"sv)); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     debug_menu->addAction(dump_local_storage_action); | 
					
						
							|  |  |  |     QObject::connect(dump_local_storage_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("dump-local-storage"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     debug_menu->addSeparator(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 13:28:48 +01:00
										 |  |  |     m_show_line_box_borders_action = new QAction("Show Line Box Borders", this); | 
					
						
							|  |  |  |     m_show_line_box_borders_action->setCheckable(true); | 
					
						
							|  |  |  |     debug_menu->addAction(m_show_line_box_borders_action); | 
					
						
							|  |  |  |     QObject::connect(m_show_line_box_borders_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         bool state = m_show_line_box_borders_action->isChecked(); | 
					
						
							| 
									
										
										
										
											2024-06-05 20:29:12 +01:00
										 |  |  |         for_each_tab([state](auto& tab) { | 
					
						
							|  |  |  |             tab.set_line_box_borders(state); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     debug_menu->addSeparator(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* collect_garbage_action = new QAction("Collect &Garbage", this); | 
					
						
							| 
									
										
										
										
											2022-10-16 15:35:44 +02:00
										 |  |  |     collect_garbage_action->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_G)); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     collect_garbage_action->setIcon(load_icon_from_uri("resource://icons/16x16/trash-can.png"sv)); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     debug_menu->addAction(collect_garbage_action); | 
					
						
							|  |  |  |     QObject::connect(collect_garbage_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("collect-garbage"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-17 15:43:50 +02:00
										 |  |  |     auto* dump_gc_graph_action = new QAction("Dump GC graph", this); | 
					
						
							|  |  |  |     debug_menu->addAction(dump_gc_graph_action); | 
					
						
							|  |  |  |     QObject::connect(dump_gc_graph_action, &QAction::triggered, this, [this] { | 
					
						
							| 
									
										
										
										
											2023-12-12 13:25:06 +01:00
										 |  |  |         if (m_current_tab) { | 
					
						
							|  |  |  |             auto gc_graph_path = m_current_tab->view().dump_gc_graph(); | 
					
						
							|  |  |  |             warnln("\033[33;1mDumped GC-graph into {}" | 
					
						
							|  |  |  |                    "\033[0m", | 
					
						
							|  |  |  |                 gc_graph_path); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-17 15:43:50 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* clear_cache_action = new QAction("Clear &Cache", this); | 
					
						
							|  |  |  |     clear_cache_action->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C)); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     clear_cache_action->setIcon(load_icon_from_uri("resource://icons/browser/clear-cache.png"sv)); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     debug_menu->addAction(clear_cache_action); | 
					
						
							|  |  |  |     QObject::connect(clear_cache_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         debug_request("clear-cache"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-24 03:36:19 +02:00
										 |  |  |     auto* spoof_user_agent_menu = debug_menu->addMenu("Spoof &User Agent"); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     spoof_user_agent_menu->setIcon(load_icon_from_uri("resource://icons/16x16/spoof.png"sv)); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:57:44 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto* user_agent_group = new QActionGroup(this); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:55:47 -05:00
										 |  |  |     auto add_user_agent = [this, &user_agent_group, &spoof_user_agent_menu](auto name, auto const& user_agent) { | 
					
						
							|  |  |  |         auto* action = new QAction(qstring_from_ak_string(name), this); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:57:44 +03:00
										 |  |  |         action->setCheckable(true); | 
					
						
							|  |  |  |         user_agent_group->addAction(action); | 
					
						
							|  |  |  |         spoof_user_agent_menu->addAction(action); | 
					
						
							|  |  |  |         QObject::connect(action, &QAction::triggered, this, [this, user_agent] { | 
					
						
							| 
									
										
										
										
											2024-06-06 00:07:10 +01:00
										 |  |  |             for_each_tab([user_agent](auto& tab) { | 
					
						
							|  |  |  |                 tab.set_user_agent_string(user_agent); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |             set_user_agent_string(user_agent); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:57:44 +03:00
										 |  |  |         }); | 
					
						
							|  |  |  |         return action; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-06 00:07:10 +01:00
										 |  |  |     set_user_agent_string(Web::default_user_agent); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:55:47 -05:00
										 |  |  |     auto* disable_spoofing = add_user_agent("Disabled"sv, Web::default_user_agent); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:57:44 +03:00
										 |  |  |     disable_spoofing->setChecked(true); | 
					
						
							| 
									
										
										
										
											2023-09-11 17:49:57 +04:00
										 |  |  |     for (auto const& user_agent : WebView::user_agents) | 
					
						
							| 
									
										
										
										
											2023-12-16 17:49:34 +03:30
										 |  |  |         add_user_agent(user_agent.key, user_agent.value.to_byte_string()); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:57:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 18:07:50 +02:00
										 |  |  |     auto* custom_user_agent_action = new QAction("Custom...", this); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:57:44 +03:00
										 |  |  |     custom_user_agent_action->setCheckable(true); | 
					
						
							|  |  |  |     user_agent_group->addAction(custom_user_agent_action); | 
					
						
							|  |  |  |     spoof_user_agent_menu->addAction(custom_user_agent_action); | 
					
						
							|  |  |  |     QObject::connect(custom_user_agent_action, &QAction::triggered, this, [this, disable_spoofing] { | 
					
						
							|  |  |  |         auto user_agent = QInputDialog::getText(this, "Custom User Agent", "Enter User Agent:"); | 
					
						
							|  |  |  |         if (!user_agent.isEmpty()) { | 
					
						
							| 
									
										
										
										
											2024-06-06 00:07:10 +01:00
										 |  |  |             auto user_agent_byte_string = ak_byte_string_from_qstring(user_agent); | 
					
						
							|  |  |  |             for_each_tab([&](auto& tab) { | 
					
						
							|  |  |  |                 tab.set_user_agent_string(user_agent_byte_string); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |             set_user_agent_string(user_agent_byte_string); | 
					
						
							| 
									
										
										
										
											2022-09-26 17:57:44 +03:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             disable_spoofing->activate(QAction::Trigger); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     debug_menu->addSeparator(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-05 20:29:12 +01:00
										 |  |  |     m_enable_scripting_action = new QAction("Enable Scripting", this); | 
					
						
							|  |  |  |     m_enable_scripting_action->setCheckable(true); | 
					
						
							|  |  |  |     m_enable_scripting_action->setChecked(true); | 
					
						
							|  |  |  |     debug_menu->addAction(m_enable_scripting_action); | 
					
						
							|  |  |  |     QObject::connect(m_enable_scripting_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         bool state = m_enable_scripting_action->isChecked(); | 
					
						
							|  |  |  |         for_each_tab([state](auto& tab) { | 
					
						
							|  |  |  |             tab.set_scripting(state); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-05 20:29:12 +01:00
										 |  |  |     m_block_pop_ups_action = new QAction("Block Pop-ups", this); | 
					
						
							|  |  |  |     m_block_pop_ups_action->setCheckable(true); | 
					
						
							| 
									
										
										
										
											2024-06-17 10:34:41 +01:00
										 |  |  |     m_block_pop_ups_action->setChecked(!allow_popups); | 
					
						
							| 
									
										
										
										
											2024-06-05 20:29:12 +01:00
										 |  |  |     debug_menu->addAction(m_block_pop_ups_action); | 
					
						
							|  |  |  |     QObject::connect(m_block_pop_ups_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         bool state = m_block_pop_ups_action->isChecked(); | 
					
						
							|  |  |  |         for_each_tab([state](auto& tab) { | 
					
						
							|  |  |  |             tab.set_block_popups(state); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2022-11-15 01:49:05 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-05 20:29:12 +01:00
										 |  |  |     m_enable_same_origin_policy_action = new QAction("Enable Same-Origin Policy", this); | 
					
						
							|  |  |  |     m_enable_same_origin_policy_action->setCheckable(true); | 
					
						
							|  |  |  |     debug_menu->addAction(m_enable_same_origin_policy_action); | 
					
						
							|  |  |  |     QObject::connect(m_enable_same_origin_policy_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         bool state = m_enable_same_origin_policy_action->isChecked(); | 
					
						
							|  |  |  |         for_each_tab([state](auto& tab) { | 
					
						
							|  |  |  |             tab.set_same_origin_policy(state); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     auto* help_menu = m_hamburger_menu->addMenu("&Help"); | 
					
						
							|  |  |  |     menuBar()->addMenu(help_menu); | 
					
						
							| 
									
										
										
										
											2024-05-05 15:40:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto* about_action = new QAction("&About Ladybird", this); | 
					
						
							|  |  |  |     help_menu->addAction(about_action); | 
					
						
							| 
									
										
										
										
											2024-01-12 19:41:26 +01:00
										 |  |  |     QObject::connect(about_action, &QAction::triggered, this, [this] { | 
					
						
							| 
									
										
										
										
											2024-01-30 19:15:55 -07:00
										 |  |  |         new_tab_from_url("about:version"sv, Web::HTML::ActivateTab::Yes); | 
					
						
							| 
									
										
										
										
											2024-01-12 19:41:26 +01:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2024-05-05 15:40:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_menu->addSeparator(); | 
					
						
							|  |  |  |     file_menu->addSeparator(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* quit_action = new QAction("&Quit", this); | 
					
						
							|  |  |  |     quit_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Quit)); | 
					
						
							|  |  |  |     m_hamburger_menu->addAction(quit_action); | 
					
						
							|  |  |  |     file_menu->addAction(quit_action); | 
					
						
							|  |  |  |     QObject::connect(quit_action, &QAction::triggered, this, &QMainWindow::close); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-05 07:21:48 -04:00
										 |  |  |     QObject::connect(m_new_tab_action, &QAction::triggered, this, [this] { | 
					
						
							| 
									
										
										
										
											2024-01-30 19:15:55 -07:00
										 |  |  |         new_tab_from_url(ak_url_from_qstring(Settings::the()->new_tab_page()), Web::HTML::ActivateTab::Yes); | 
					
						
							| 
									
										
										
										
											2023-01-08 11:21:55 +01:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2024-04-26 18:53:55 -06:00
										 |  |  |     QObject::connect(m_new_window_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         auto initial_urls = Vector<URL::URL> { ak_url_from_qstring(Settings::the()->new_tab_page()) }; | 
					
						
							| 
									
										
										
										
											2024-06-17 10:34:41 +01:00
										 |  |  |         (void)static_cast<Ladybird::Application*>(QApplication::instance())->new_window(initial_urls, m_cookie_jar, m_web_content_options, m_webdriver_content_ipc_path, m_allow_popups); | 
					
						
							| 
									
										
										
										
											2024-04-26 18:53:55 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-05-25 23:47:12 +02:00
										 |  |  |     QObject::connect(open_file_action, &QAction::triggered, this, &BrowserWindow::open_file); | 
					
						
							| 
									
										
										
										
											2022-07-14 06:08:30 +02:00
										 |  |  |     QObject::connect(settings_action, &QAction::triggered, this, [this] { | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |         if (!m_settings_dialog) { | 
					
						
							|  |  |  |             m_settings_dialog = new SettingsDialog(this); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_settings_dialog->show(); | 
					
						
							|  |  |  |         m_settings_dialog->setFocus(); | 
					
						
							| 
									
										
										
										
											2022-07-14 06:08:30 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     QObject::connect(m_tabs_container, &QTabWidget::currentChanged, [this](int index) { | 
					
						
							| 
									
										
										
										
											2024-04-27 14:33:09 +01:00
										 |  |  |         auto* tab = verify_cast<Tab>(m_tabs_container->widget(index)); | 
					
						
							|  |  |  |         if (tab) | 
					
						
							|  |  |  |             setWindowTitle(QString("%1 - Ladybird").arg(tab->title())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         set_current_tab(tab); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:36:49 +01:00
										 |  |  |     QObject::connect(m_tabs_container, &QTabWidget::tabCloseRequested, this, &BrowserWindow::close_tab); | 
					
						
							| 
									
										
										
										
											2022-07-19 06:16:46 -04:00
										 |  |  |     QObject::connect(close_current_tab_action, &QAction::triggered, this, &BrowserWindow::close_current_tab); | 
					
						
							| 
									
										
										
										
											2022-07-03 21:26:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_inspect_dom_node_action = new QAction("&Inspect Element", this); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  |     connect(m_inspect_dom_node_action, &QAction::triggered, this, [this] { | 
					
						
							| 
									
										
										
										
											2023-05-13 13:07:12 +01:00
										 |  |  |         if (m_current_tab) | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  |             m_current_tab->show_inspector_window(Tab::InspectorTarget::HoveredElement); | 
					
						
							| 
									
										
										
										
											2023-05-13 13:07:12 +01:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_go_back_action = new QAction("Go Back", this); | 
					
						
							| 
									
										
										
										
											2023-05-13 13:07:12 +01:00
										 |  |  |     connect(m_go_back_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         if (m_current_tab) | 
					
						
							|  |  |  |             m_current_tab->back(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_go_forward_action = new QAction("Go Forward", this); | 
					
						
							| 
									
										
										
										
											2023-05-13 13:07:12 +01:00
										 |  |  |     connect(m_go_forward_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         if (m_current_tab) | 
					
						
							|  |  |  |             m_current_tab->forward(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_reload_action = new QAction("&Reload", this); | 
					
						
							| 
									
										
										
										
											2023-05-13 13:07:12 +01:00
										 |  |  |     connect(m_reload_action, &QAction::triggered, this, [this] { | 
					
						
							|  |  |  |         if (m_current_tab) | 
					
						
							|  |  |  |             m_current_tab->reload(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-13 13:07:12 +01:00
										 |  |  |     m_go_back_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Back)); | 
					
						
							|  |  |  |     m_go_forward_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Forward)); | 
					
						
							|  |  |  |     m_reload_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Refresh)); | 
					
						
							|  |  |  |     m_go_back_action->setEnabled(false); | 
					
						
							|  |  |  |     m_go_forward_action->setEnabled(false); | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     m_reload_action->setEnabled(true); | 
					
						
							| 
									
										
										
										
											2023-05-13 13:07:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-20 11:32:37 +02:00
										 |  |  |     for (int i = 0; i <= 7; ++i) { | 
					
						
							|  |  |  |         new QShortcut(QKeySequence(Qt::CTRL | static_cast<Qt::Key>(Qt::Key_1 + i)), this, [this, i] { | 
					
						
							|  |  |  |             if (m_tabs_container->count() <= 1) | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             m_tabs_container->setCurrentIndex(min(i, m_tabs_container->count() - 1)); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_9), this, [this] { | 
					
						
							|  |  |  |         if (m_tabs_container->count() <= 1) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_tabs_container->setCurrentIndex(m_tabs_container->count() - 1); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 13:27:57 -06:00
										 |  |  |     if (parent_tab) { | 
					
						
							|  |  |  |         new_child_tab(Web::HTML::ActivateTab::Yes, *parent_tab, AK::move(page_index)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         for (size_t i = 0; i < initial_urls.size(); ++i) { | 
					
						
							|  |  |  |             new_tab_from_url(initial_urls[i], (i == 0) ? Web::HTML::ActivateTab::Yes : Web::HTML::ActivateTab::No); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-08 15:59:55 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     setCentralWidget(m_tabs_container); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  |     setContextMenuPolicy(Qt::PreventContextMenu); | 
					
						
							| 
									
										
										
										
											2023-05-08 21:15:35 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  | void BrowserWindow::set_current_tab(Tab* tab) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_current_tab = tab; | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     if (tab) { | 
					
						
							| 
									
										
										
										
											2023-03-29 00:25:42 +01:00
										 |  |  |         update_displayed_zoom_level(); | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |         tab->update_navigation_buttons_state(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 17:49:34 +03:30
										 |  |  | void BrowserWindow::debug_request(ByteString const& request, ByteString const& argument) | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!m_current_tab) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     m_current_tab->debug_request(request, argument); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 16:22:27 +13:00
										 |  |  | Tab& BrowserWindow::new_tab_from_url(URL::URL const& url, Web::HTML::ActivateTab activate_tab) | 
					
						
							| 
									
										
										
										
											2023-08-28 16:14:34 -04:00
										 |  |  | { | 
					
						
							|  |  |  |     auto& tab = create_new_tab(activate_tab); | 
					
						
							|  |  |  |     tab.navigate(url); | 
					
						
							|  |  |  |     return tab; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-30 18:52:59 -07:00
										 |  |  | Tab& BrowserWindow::new_tab_from_content(StringView html, Web::HTML::ActivateTab activate_tab) | 
					
						
							| 
									
										
										
										
											2023-08-28 16:14:34 -04:00
										 |  |  | { | 
					
						
							|  |  |  |     auto& tab = create_new_tab(activate_tab); | 
					
						
							| 
									
										
										
										
											2023-09-17 17:12:17 +02:00
										 |  |  |     tab.load_html(html); | 
					
						
							| 
									
										
										
										
											2023-08-28 16:14:34 -04:00
										 |  |  |     return tab; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 13:27:57 -06:00
										 |  |  | Tab& BrowserWindow::new_child_tab(Web::HTML::ActivateTab activate_tab, Tab& parent, Optional<u64> page_index) | 
					
						
							| 
									
										
										
										
											2024-01-30 20:05:00 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-05-28 13:27:57 -06:00
										 |  |  |     return create_new_tab(activate_tab, parent, page_index); | 
					
						
							| 
									
										
										
										
											2024-01-30 20:05:00 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 13:27:57 -06:00
										 |  |  | Tab& BrowserWindow::create_new_tab(Web::HTML::ActivateTab activate_tab, Tab& parent, Optional<u64> page_index) | 
					
						
							| 
									
										
										
										
											2024-01-30 20:05:00 -07:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!page_index.has_value()) | 
					
						
							|  |  |  |         return create_new_tab(activate_tab); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* tab = new Tab(this, m_web_content_options, m_webdriver_content_ipc_path, parent.view().client(), page_index.value()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 13:27:57 -06:00
										 |  |  |     // FIXME: Merge with other overload
 | 
					
						
							|  |  |  |     if (m_current_tab == nullptr) { | 
					
						
							|  |  |  |         set_current_tab(tab); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-01-30 20:05:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_tabs_container->addTab(tab, "New Tab"); | 
					
						
							|  |  |  |     if (activate_tab == Web::HTML::ActivateTab::Yes) | 
					
						
							|  |  |  |         m_tabs_container->setCurrentWidget(tab); | 
					
						
							|  |  |  |     initialize_tab(tab); | 
					
						
							|  |  |  |     return *tab; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-28 16:14:34 -04:00
										 |  |  | Tab& BrowserWindow::create_new_tab(Web::HTML::ActivateTab activate_tab) | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     auto* tab = new Tab(this, m_web_content_options, m_webdriver_content_ipc_path); | 
					
						
							| 
									
										
										
										
											2022-07-03 21:26:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     if (m_current_tab == nullptr) { | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |         set_current_tab(tab); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-07-03 21:26:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_tabs_container->addTab(tab, "New Tab"); | 
					
						
							| 
									
										
										
										
											2023-03-20 18:39:20 -04:00
										 |  |  |     if (activate_tab == Web::HTML::ActivateTab::Yes) | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |         m_tabs_container->setCurrentWidget(tab); | 
					
						
							| 
									
										
										
										
											2024-01-30 20:05:00 -07:00
										 |  |  |     initialize_tab(tab); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return *tab; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::initialize_tab(Tab* tab) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     QObject::connect(tab, &Tab::title_changed, this, &BrowserWindow::tab_title_changed); | 
					
						
							|  |  |  |     QObject::connect(tab, &Tab::favicon_changed, this, &BrowserWindow::tab_favicon_changed); | 
					
						
							| 
									
										
										
										
											2024-03-28 11:16:10 -04:00
										 |  |  |     QObject::connect(tab, &Tab::audio_play_state_changed, this, &BrowserWindow::tab_audio_play_state_changed); | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     QObject::connect(tab, &Tab::navigation_buttons_state_changed, this, &BrowserWindow::tab_navigation_buttons_state_changed); | 
					
						
							| 
									
										
										
										
											2022-07-12 11:41:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     QObject::connect(&tab->view(), &WebContentView::urls_dropped, this, [this](auto& urls) { | 
					
						
							| 
									
										
										
										
											2023-01-07 17:40:04 +01:00
										 |  |  |         VERIFY(urls.size()); | 
					
						
							| 
									
										
										
										
											2024-01-30 19:15:55 -07:00
										 |  |  |         m_current_tab->navigate(ak_url_from_qurl(urls[0])); | 
					
						
							| 
									
										
										
										
											2023-01-07 17:40:04 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (qsizetype i = 1; i < urls.size(); ++i) | 
					
						
							| 
									
										
										
										
											2024-01-30 19:15:55 -07:00
										 |  |  |             new_tab_from_url(ak_url_from_qurl(urls[i]), Web::HTML::ActivateTab::No); | 
					
						
							| 
									
										
										
										
											2023-01-07 17:40:04 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-30 20:05:00 -07:00
										 |  |  |     tab->view().on_new_web_view = [this, tab](auto activate_tab, Web::HTML::WebViewHints hints, Optional<u64> page_index) { | 
					
						
							| 
									
										
										
										
											2024-05-28 13:27:57 -06:00
										 |  |  |         if (hints.popup) { | 
					
						
							| 
									
										
										
										
											2024-06-17 10:34:41 +01:00
										 |  |  |             auto& window = static_cast<Ladybird::Application*>(QApplication::instance())->new_window({}, m_cookie_jar, m_web_content_options, m_webdriver_content_ipc_path, m_allow_popups, tab, AK::move(page_index)); | 
					
						
							| 
									
										
										
										
											2024-05-28 13:27:57 -06:00
										 |  |  |             window.set_window_rect(hints.screen_x, hints.screen_y, hints.width, hints.height); | 
					
						
							|  |  |  |             return window.current_tab()->view().handle(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         auto& new_tab = new_child_tab(activate_tab, *tab, page_index); | 
					
						
							| 
									
										
										
										
											2024-01-30 20:05:00 -07:00
										 |  |  |         return new_tab.view().handle(); | 
					
						
							| 
									
										
										
										
											2023-03-14 17:19:28 +03:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     tab->view().on_tab_open_request = [this](auto url, auto activate_tab) { | 
					
						
							| 
									
										
										
										
											2024-01-30 19:15:55 -07:00
										 |  |  |         auto& tab = new_tab_from_url(url, activate_tab); | 
					
						
							| 
									
										
										
										
											2023-03-22 21:24:15 -03:00
										 |  |  |         return tab.view().handle(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     tab->view().on_link_click = [this](auto url, auto target, unsigned modifiers) { | 
					
						
							| 
									
										
										
										
											2023-03-22 21:24:15 -03:00
										 |  |  |         // TODO: maybe activate tabs according to some configuration, this is just normal current browser behavior
 | 
					
						
							| 
									
										
										
										
											2024-06-06 13:29:08 -06:00
										 |  |  |         if (modifiers == Web::UIEvents::Mod_Ctrl) { | 
					
						
							| 
									
										
										
										
											2023-03-22 21:24:15 -03:00
										 |  |  |             m_current_tab->view().on_tab_open_request(url, Web::HTML::ActivateTab::No); | 
					
						
							|  |  |  |         } else if (target == "_blank") { | 
					
						
							|  |  |  |             m_current_tab->view().on_tab_open_request(url, Web::HTML::ActivateTab::Yes); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             m_current_tab->view().load(url); | 
					
						
							| 
									
										
										
										
											2023-03-22 21:24:15 -03:00
										 |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     tab->view().on_link_middle_click = [this](auto url, auto target, unsigned modifiers) { | 
					
						
							| 
									
										
										
										
											2024-06-06 13:29:08 -06:00
										 |  |  |         m_current_tab->view().on_link_click(url, target, Web::UIEvents::Mod_Ctrl); | 
					
						
							| 
									
										
										
										
											2023-03-22 21:24:15 -03:00
										 |  |  |         (void)modifiers; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     tab->view().on_get_all_cookies = [this](auto const& url) { | 
					
						
							| 
									
										
										
										
											2022-11-14 17:23:35 -05:00
										 |  |  |         return m_cookie_jar.get_all_cookies(url); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     tab->view().on_get_named_cookie = [this](auto const& url, auto const& name) { | 
					
						
							| 
									
										
										
										
											2022-11-14 17:23:35 -05:00
										 |  |  |         return m_cookie_jar.get_named_cookie(url, name); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 11:10:15 -05:00
										 |  |  |     tab->view().on_get_cookie = [this](auto& url, auto source) { | 
					
						
							| 
									
										
										
										
											2022-10-11 10:53:28 +02:00
										 |  |  |         return m_cookie_jar.get_cookie(url, source); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     tab->view().on_set_cookie = [this](auto& url, auto& cookie, auto source) { | 
					
						
							| 
									
										
										
										
											2022-10-11 10:53:28 +02:00
										 |  |  |         m_cookie_jar.set_cookie(url, cookie, source); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     tab->view().on_update_cookie = [this](auto const& cookie) { | 
					
						
							| 
									
										
										
										
											2022-12-05 10:15:41 -05:00
										 |  |  |         m_cookie_jar.update_cookie(cookie); | 
					
						
							| 
									
										
										
										
											2022-11-14 17:23:35 -05:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-28 11:11:02 -04:00
										 |  |  |     m_tabs_container->setTabIcon(m_tabs_container->indexOf(tab), tab->favicon()); | 
					
						
							| 
									
										
										
										
											2024-04-02 21:35:52 -04:00
										 |  |  |     create_close_button_for_tab(tab); | 
					
						
							| 
									
										
										
										
											2024-03-28 11:11:02 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     tab->focus_location_editor(); | 
					
						
							| 
									
										
										
										
											2024-06-05 20:29:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 13:28:48 +01:00
										 |  |  |     tab->set_line_box_borders(m_show_line_box_borders_action->isChecked()); | 
					
						
							| 
									
										
										
										
											2024-06-05 20:29:12 +01:00
										 |  |  |     tab->set_scripting(m_enable_scripting_action->isChecked()); | 
					
						
							|  |  |  |     tab->set_block_popups(m_block_pop_ups_action->isChecked()); | 
					
						
							|  |  |  |     tab->set_same_origin_policy(m_enable_same_origin_policy_action->isChecked()); | 
					
						
							| 
									
										
										
										
											2024-06-06 00:07:10 +01:00
										 |  |  |     tab->set_user_agent_string(user_agent_string()); | 
					
						
							| 
									
										
										
										
											2022-07-03 21:26:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:52:00 -04:00
										 |  |  | void BrowserWindow::activate_tab(int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_tabs_container->setCurrentIndex(index); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 14:36:49 +01:00
										 |  |  | void BrowserWindow::close_tab(int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto* tab = m_tabs_container->widget(index); | 
					
						
							|  |  |  |     m_tabs_container->removeTab(index); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     tab->deleteLater(); | 
					
						
							| 
									
										
										
										
											2024-04-05 07:36:12 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (m_tabs_container->count() == 0) | 
					
						
							|  |  |  |         close(); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:36:49 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-28 15:07:23 +01:00
										 |  |  | void BrowserWindow::move_tab(int old_index, int new_index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_tabs_container->tabBar()->moveTab(old_index, new_index); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-25 23:47:12 +02:00
										 |  |  | void BrowserWindow::open_file() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_current_tab->open_file(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 06:16:46 -04:00
										 |  |  | void BrowserWindow::close_current_tab() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-08-08 18:42:18 -04:00
										 |  |  |     close_tab(m_tabs_container->currentIndex()); | 
					
						
							| 
									
										
										
										
											2022-07-19 06:16:46 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | int BrowserWindow::tab_index(Tab* tab) | 
					
						
							| 
									
										
										
										
											2022-07-03 21:26:51 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     return m_tabs_container->indexOf(tab); | 
					
						
							| 
									
										
										
										
											2022-07-03 21:26:51 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-07-04 02:11:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-13 19:10:05 +01:00
										 |  |  | void BrowserWindow::device_pixel_ratio_changed(qreal dpi) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_device_pixel_ratio = dpi; | 
					
						
							|  |  |  |     for_each_tab([this](auto& tab) { | 
					
						
							|  |  |  |         tab.view().set_device_pixel_ratio(m_device_pixel_ratio); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | void BrowserWindow::tab_title_changed(int index, QString const& title) | 
					
						
							| 
									
										
										
										
											2022-07-04 02:11:58 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-06-07 16:37:30 -04:00
										 |  |  |     m_tabs_container->setTabText(index, title); | 
					
						
							| 
									
										
										
										
											2024-04-02 21:45:09 -04:00
										 |  |  |     m_tabs_container->setTabToolTip(index, title); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-07 16:37:30 -04:00
										 |  |  |     if (m_tabs_container->currentIndex() == index) | 
					
						
							|  |  |  |         setWindowTitle(QString("%1 - Ladybird").arg(title)); | 
					
						
							| 
									
										
										
										
											2022-07-04 02:11:58 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-07-05 05:53:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-29 19:05:40 +10:00
										 |  |  | void BrowserWindow::tab_favicon_changed(int index, QIcon const& icon) | 
					
						
							| 
									
										
										
										
											2022-07-05 05:53:11 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     m_tabs_container->setTabIcon(index, icon); | 
					
						
							| 
									
										
										
										
											2022-07-05 05:53:11 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-09-12 09:22:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-02 21:35:52 -04:00
										 |  |  | void BrowserWindow::create_close_button_for_tab(Tab* tab) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto index = m_tabs_container->indexOf(tab); | 
					
						
							|  |  |  |     m_tabs_container->setTabIcon(index, tab->favicon()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* button = new TabBarButton(create_tvg_icon_with_theme_colors("close", palette())); | 
					
						
							|  |  |  |     auto position = audio_button_position_for_tab(index) == QTabBar::LeftSide ? QTabBar::RightSide : QTabBar::LeftSide; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     connect(button, &QPushButton::clicked, this, [this, tab]() { | 
					
						
							|  |  |  |         auto index = m_tabs_container->indexOf(tab); | 
					
						
							|  |  |  |         close_tab(index); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_tabs_container->tabBar()->setTabButton(index, position, button); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-28 11:16:10 -04:00
										 |  |  | void BrowserWindow::tab_audio_play_state_changed(int index, Web::HTML::AudioPlayState play_state) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  |     auto* tab = verify_cast<Tab>(m_tabs_container->widget(index)); | 
					
						
							| 
									
										
										
										
											2024-03-30 18:47:50 -04:00
										 |  |  |     auto position = audio_button_position_for_tab(index); | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-28 11:16:10 -04:00
										 |  |  |     switch (play_state) { | 
					
						
							|  |  |  |     case Web::HTML::AudioPlayState::Paused: | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  |         if (tab->view().page_mute_state() == Web::HTML::MuteState::Unmuted) | 
					
						
							| 
									
										
										
										
											2024-03-30 18:47:50 -04:00
										 |  |  |             m_tabs_container->tabBar()->setTabButton(index, position, nullptr); | 
					
						
							| 
									
										
										
										
											2024-03-28 11:16:10 -04:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case Web::HTML::AudioPlayState::Playing: | 
					
						
							| 
									
										
										
										
											2024-04-02 21:24:17 -04:00
										 |  |  |         auto* button = new TabBarButton(icon_for_page_mute_state(*tab)); | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  |         button->setToolTip(tool_tip_for_page_mute_state(*tab)); | 
					
						
							| 
									
										
										
										
											2024-04-02 12:52:03 -04:00
										 |  |  |         button->setObjectName("LadybirdAudioState"); | 
					
						
							| 
									
										
										
										
											2024-03-28 11:16:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 18:47:50 -04:00
										 |  |  |         connect(button, &QPushButton::clicked, this, [this, tab, position]() { | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  |             tab->view().toggle_page_mute_state(); | 
					
						
							|  |  |  |             auto index = tab_index(tab); | 
					
						
							| 
									
										
										
										
											2024-03-30 09:48:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  |             switch (tab->view().audio_play_state()) { | 
					
						
							| 
									
										
										
										
											2024-03-30 09:48:33 -04:00
										 |  |  |             case Web::HTML::AudioPlayState::Paused: | 
					
						
							| 
									
										
										
										
											2024-03-30 18:47:50 -04:00
										 |  |  |                 m_tabs_container->tabBar()->setTabButton(index, position, nullptr); | 
					
						
							| 
									
										
										
										
											2024-03-30 09:48:33 -04:00
										 |  |  |                 break; | 
					
						
							|  |  |  |             case Web::HTML::AudioPlayState::Playing: | 
					
						
							| 
									
										
										
										
											2024-03-30 18:47:50 -04:00
										 |  |  |                 auto* button = m_tabs_container->tabBar()->tabButton(index, position); | 
					
						
							| 
									
										
										
										
											2024-04-02 21:24:17 -04:00
										 |  |  |                 verify_cast<TabBarButton>(button)->setIcon(icon_for_page_mute_state(*tab)); | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  |                 button->setToolTip(tool_tip_for_page_mute_state(*tab)); | 
					
						
							| 
									
										
										
										
											2024-03-30 09:48:33 -04:00
										 |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2024-03-28 11:16:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 18:47:50 -04:00
										 |  |  |         m_tabs_container->tabBar()->setTabButton(index, position, button); | 
					
						
							| 
									
										
										
										
											2024-03-28 11:16:10 -04:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  | void BrowserWindow::tab_navigation_buttons_state_changed(int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto* tab = verify_cast<Tab>(m_tabs_container->widget(index)); | 
					
						
							|  |  |  |     tab->update_navigation_buttons_state(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  | QIcon BrowserWindow::icon_for_page_mute_state(Tab& tab) const | 
					
						
							| 
									
										
										
										
											2024-03-30 09:48:33 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  |     switch (tab.view().page_mute_state()) { | 
					
						
							| 
									
										
										
										
											2024-03-30 09:48:33 -04:00
										 |  |  |     case Web::HTML::MuteState::Muted: | 
					
						
							|  |  |  |         return style()->standardIcon(QStyle::SP_MediaVolumeMuted); | 
					
						
							|  |  |  |     case Web::HTML::MuteState::Unmuted: | 
					
						
							|  |  |  |         return style()->standardIcon(QStyle::SP_MediaVolume); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  | QString BrowserWindow::tool_tip_for_page_mute_state(Tab& tab) const | 
					
						
							| 
									
										
										
										
											2024-03-30 11:10:11 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-30 18:36:26 -04:00
										 |  |  |     switch (tab.view().page_mute_state()) { | 
					
						
							| 
									
										
										
										
											2024-03-30 11:10:11 -04:00
										 |  |  |     case Web::HTML::MuteState::Muted: | 
					
						
							|  |  |  |         return "Unmute tab"; | 
					
						
							|  |  |  |     case Web::HTML::MuteState::Unmuted: | 
					
						
							|  |  |  |         return "Mute tab"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 18:47:50 -04:00
										 |  |  | QTabBar::ButtonPosition BrowserWindow::audio_button_position_for_tab(int tab_index) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-02 12:52:03 -04:00
										 |  |  |     if (auto* button = m_tabs_container->tabBar()->tabButton(tab_index, QTabBar::LeftSide)) { | 
					
						
							|  |  |  |         if (button->objectName() != "LadybirdAudioState") | 
					
						
							|  |  |  |             return QTabBar::RightSide; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 18:47:50 -04:00
										 |  |  |     return QTabBar::LeftSide; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-12 09:22:43 +02:00
										 |  |  | void BrowserWindow::open_next_tab() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_tabs_container->count() <= 1) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto next_index = m_tabs_container->currentIndex() + 1; | 
					
						
							|  |  |  |     if (next_index >= m_tabs_container->count()) | 
					
						
							|  |  |  |         next_index = 0; | 
					
						
							|  |  |  |     m_tabs_container->setCurrentIndex(next_index); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::open_previous_tab() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_tabs_container->count() <= 1) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto next_index = m_tabs_container->currentIndex() - 1; | 
					
						
							|  |  |  |     if (next_index < 0) | 
					
						
							|  |  |  |         next_index = m_tabs_container->count() - 1; | 
					
						
							|  |  |  |     m_tabs_container->setCurrentIndex(next_index); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::enable_auto_color_scheme() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     for_each_tab([](auto& tab) { | 
					
						
							|  |  |  |         tab.view().set_preferred_color_scheme(Web::CSS::PreferredColorScheme::Auto); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::enable_light_color_scheme() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     for_each_tab([](auto& tab) { | 
					
						
							|  |  |  |         tab.view().set_preferred_color_scheme(Web::CSS::PreferredColorScheme::Light); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::enable_dark_color_scheme() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     for_each_tab([](auto& tab) { | 
					
						
							|  |  |  |         tab.view().set_preferred_color_scheme(Web::CSS::PreferredColorScheme::Dark); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-09-19 10:48:02 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-13 01:03:56 +02:00
										 |  |  | void BrowserWindow::enable_auto_contrast() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for_each_tab([](auto& tab) { | 
					
						
							|  |  |  |         tab.view().set_preferred_contrast(Web::CSS::PreferredContrast::Auto); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::enable_less_contrast() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for_each_tab([](auto& tab) { | 
					
						
							|  |  |  |         tab.view().set_preferred_contrast(Web::CSS::PreferredContrast::Less); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::enable_more_contrast() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for_each_tab([](auto& tab) { | 
					
						
							|  |  |  |         tab.view().set_preferred_contrast(Web::CSS::PreferredContrast::More); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::enable_no_preference_contrast() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for_each_tab([](auto& tab) { | 
					
						
							|  |  |  |         tab.view().set_preferred_contrast(Web::CSS::PreferredContrast::NoPreference); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  | void BrowserWindow::zoom_in() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  |     if (!m_current_tab) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     m_current_tab->view().zoom_in(); | 
					
						
							| 
									
										
										
										
											2023-03-29 00:25:42 +01:00
										 |  |  |     update_displayed_zoom_level(); | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::zoom_out() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  |     if (!m_current_tab) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     m_current_tab->view().zoom_out(); | 
					
						
							| 
									
										
										
										
											2023-03-29 00:25:42 +01:00
										 |  |  |     update_displayed_zoom_level(); | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::reset_zoom() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  |     if (!m_current_tab) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     m_current_tab->view().reset_zoom(); | 
					
						
							| 
									
										
										
										
											2023-03-29 00:25:42 +01:00
										 |  |  |     update_displayed_zoom_level(); | 
					
						
							| 
									
										
										
										
											2023-01-12 14:39:53 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-04 13:37:52 +02:00
										 |  |  | void BrowserWindow::update_zoom_menu() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     VERIFY(m_zoom_menu); | 
					
						
							|  |  |  |     auto zoom_level_text = MUST(String::formatted("&Zoom ({}%)", round_to<int>(m_current_tab->view().zoom_level() * 100))); | 
					
						
							|  |  |  |     m_zoom_menu->setTitle(qstring_from_ak_string(zoom_level_text)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  | void BrowserWindow::select_all() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-04-22 21:57:08 -04:00
										 |  |  |     if (!m_current_tab) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-01 07:07:01 -05:00
										 |  |  |     m_current_tab->view().select_all(); | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-29 20:12:21 +01:00
										 |  |  | void BrowserWindow::show_find_in_page() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_current_tab) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_current_tab->show_find_in_page(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-22 11:56:49 +01:00
										 |  |  | void BrowserWindow::paste() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_current_tab) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* clipboard = QGuiApplication::clipboard(); | 
					
						
							|  |  |  |     m_current_tab->view().paste(ak_string_from_qstring(clipboard->text())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-29 00:25:42 +01:00
										 |  |  | void BrowserWindow::update_displayed_zoom_level() | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-08-04 13:37:52 +02:00
										 |  |  |     VERIFY(m_current_tab); | 
					
						
							|  |  |  |     update_zoom_menu(); | 
					
						
							| 
									
										
										
										
											2023-03-29 00:25:42 +01:00
										 |  |  |     m_current_tab->update_reset_zoom_button(); | 
					
						
							| 
									
										
										
										
											2023-03-26 18:56:17 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-28 13:27:57 -06:00
										 |  |  | void BrowserWindow::set_window_rect(Optional<Web::DevicePixels> x, Optional<Web::DevicePixels> y, Optional<Web::DevicePixels> width, Optional<Web::DevicePixels> height) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     x = x.value_or(0); | 
					
						
							|  |  |  |     y = y.value_or(0); | 
					
						
							|  |  |  |     if (!width.has_value() || width.value() == 0) | 
					
						
							|  |  |  |         width = 800; | 
					
						
							|  |  |  |     if (!height.has_value() || height.value() == 0) | 
					
						
							|  |  |  |         height = 600; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setGeometry(x.value().value(), y.value().value(), width.value().value(), height.value().value()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  | void BrowserWindow::copy_selected_text() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-04-22 21:57:08 -04:00
										 |  |  |     if (!m_current_tab) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-01 07:07:01 -05:00
										 |  |  |     auto text = m_current_tab->view().selected_text(); | 
					
						
							| 
									
										
										
										
											2023-04-22 21:57:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto* clipboard = QGuiApplication::clipboard(); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:55:47 -05:00
										 |  |  |     clipboard->setText(qstring_from_ak_string(text)); | 
					
						
							| 
									
										
										
										
											2023-01-11 20:09:52 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2023-02-05 03:26:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 23:14:41 -05:00
										 |  |  | bool BrowserWindow::event(QEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
 | 
					
						
							|  |  |  |     if (event->type() == QEvent::DevicePixelRatioChange) { | 
					
						
							|  |  |  |         if (m_device_pixel_ratio != devicePixelRatio()) | 
					
						
							|  |  |  |             device_pixel_ratio_changed(devicePixelRatio()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 18:53:55 -06:00
										 |  |  |     if (event->type() == QEvent::WindowActivate) | 
					
						
							|  |  |  |         static_cast<Ladybird::Application*>(QApplication::instance())->set_active_window(*this); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 23:14:41 -05:00
										 |  |  |     return QMainWindow::event(event); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-08 23:57:24 +03:00
										 |  |  | void BrowserWindow::resizeEvent(QResizeEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QWidget::resizeEvent(event); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for_each_tab([&](auto& tab) { | 
					
						
							| 
									
										
										
										
											2023-12-14 07:17:00 +01:00
										 |  |  |         tab.view().set_window_size({ frameSize().width() * m_device_pixel_ratio, frameSize().height() * m_device_pixel_ratio }); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-03-08 23:57:24 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void BrowserWindow::moveEvent(QMoveEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QWidget::moveEvent(event); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for_each_tab([&](auto& tab) { | 
					
						
							| 
									
										
										
										
											2023-12-14 07:17:00 +01:00
										 |  |  |         tab.view().set_window_position({ event->pos().x() * m_device_pixel_ratio, event->pos().y() * m_device_pixel_ratio }); | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-03-08 23:57:24 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-30 17:33:04 -05:00
										 |  |  | void BrowserWindow::wheelEvent(QWheelEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if ((event->modifiers() & Qt::ControlModifier) != 0) { | 
					
						
							|  |  |  |         if (event->angleDelta().y() > 0) | 
					
						
							|  |  |  |             zoom_in(); | 
					
						
							|  |  |  |         else if (event->angleDelta().y() < 0) | 
					
						
							|  |  |  |             zoom_out(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-05 03:26:20 +01:00
										 |  |  | bool BrowserWindow::eventFilter(QObject* obj, QEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (event->type() == QEvent::MouseButtonRelease) { | 
					
						
							|  |  |  |         auto const* const mouse_event = static_cast<QMouseEvent*>(event); | 
					
						
							|  |  |  |         if (mouse_event->button() == Qt::MouseButton::MiddleButton) { | 
					
						
							|  |  |  |             if (obj == m_tabs_container) { | 
					
						
							|  |  |  |                 auto const tab_index = m_tabs_container->tabBar()->tabAt(mouse_event->pos()); | 
					
						
							|  |  |  |                 close_tab(tab_index); | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return QMainWindow::eventFilter(obj, event); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-08-02 11:52:59 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 12:23:32 +02:00
										 |  |  | void BrowserWindow::closeEvent(QCloseEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-05-29 19:05:30 +10:00
										 |  |  |     Settings::the()->set_last_position(pos()); | 
					
						
							|  |  |  |     Settings::the()->set_last_size(size()); | 
					
						
							|  |  |  |     Settings::the()->set_is_maximized(isMaximized()); | 
					
						
							| 
									
										
										
										
											2023-08-09 12:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 18:53:55 -06:00
										 |  |  |     QObject::deleteLater(); | 
					
						
							| 
									
										
										
										
											2023-08-09 12:23:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 18:53:55 -06:00
										 |  |  |     QMainWindow::closeEvent(event); | 
					
						
							| 
									
										
										
										
											2024-03-26 11:38:12 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 11:52:59 -06:00
										 |  |  | } |