mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
Ladybird: Support multiple browser windows in Qt chrome
This also moves the ownership of the TaskManger to the Application.
This commit is contained in:
parent
2bb0f65309
commit
6b5deb2259
Notes:
sideshowbarker
2024-07-17 00:49:59 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/6b5deb2259 Pull-request: https://github.com/SerenityOS/serenity/pull/24126 Reviewed-by: https://github.com/trflynn89 ✅
5 changed files with 93 additions and 42 deletions
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "Application.h"
|
||||
#include "StringUtils.h"
|
||||
#include "TaskManagerWindow.h"
|
||||
#include <LibWebView/URL.h>
|
||||
#include <QFileOpenEvent>
|
||||
|
||||
|
@ -16,6 +17,11 @@ Application::Application(int& argc, char** argv)
|
|||
{
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
close_task_manager_window();
|
||||
}
|
||||
|
||||
bool Application::event(QEvent* event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
|
@ -37,4 +43,33 @@ bool Application::event(QEvent* event)
|
|||
return QApplication::event(event);
|
||||
}
|
||||
|
||||
void Application::show_task_manager_window()
|
||||
{
|
||||
if (!m_task_manager_window) {
|
||||
m_task_manager_window = new TaskManagerWindow(nullptr);
|
||||
}
|
||||
m_task_manager_window->show();
|
||||
m_task_manager_window->activateWindow();
|
||||
m_task_manager_window->raise();
|
||||
}
|
||||
|
||||
void Application::close_task_manager_window()
|
||||
{
|
||||
if (m_task_manager_window) {
|
||||
m_task_manager_window->close();
|
||||
delete m_task_manager_window;
|
||||
m_task_manager_window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
BrowserWindow& Application::new_window(Vector<URL::URL> const& initial_urls, WebView::CookieJar& cookie_jar, WebContentOptions const& web_content_options, StringView webdriver_content_ipc_path)
|
||||
{
|
||||
auto* window = new BrowserWindow(initial_urls, cookie_jar, web_content_options, webdriver_content_ipc_path);
|
||||
set_active_window(*window);
|
||||
window->show();
|
||||
window->activateWindow();
|
||||
window->raise();
|
||||
return *window;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/HashTable.h>
|
||||
#include <Ladybird/Qt/BrowserWindow.h>
|
||||
#include <LibProtocol/RequestClient.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <QApplication>
|
||||
|
@ -18,11 +20,24 @@ class Application : public QApplication {
|
|||
|
||||
public:
|
||||
Application(int& argc, char** argv);
|
||||
virtual ~Application() override;
|
||||
|
||||
virtual bool event(QEvent* event) override;
|
||||
|
||||
Function<void(URL::URL)> on_open_file;
|
||||
RefPtr<Protocol::RequestClient> request_server_client;
|
||||
|
||||
BrowserWindow& new_window(Vector<URL::URL> const& initial_urls, WebView::CookieJar&, WebContentOptions const&, StringView webdriver_content_ipc_path);
|
||||
|
||||
void show_task_manager_window();
|
||||
void close_task_manager_window();
|
||||
|
||||
BrowserWindow& active_window() { return *m_active_window; }
|
||||
void set_active_window(BrowserWindow& w) { m_active_window = &w; }
|
||||
|
||||
private:
|
||||
TaskManagerWindow* m_task_manager_window { nullptr };
|
||||
BrowserWindow* m_active_window { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
#include "BrowserWindow.h"
|
||||
#include "Application.h"
|
||||
#include "Icon.h"
|
||||
#include "Settings.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
@ -82,6 +83,10 @@ BrowserWindow::BrowserWindow(Vector<URL::URL> const& initial_urls, WebView::Cook
|
|||
m_new_tab_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::AddTab));
|
||||
menu->addAction(m_new_tab_action);
|
||||
|
||||
m_new_window_action = new QAction("New &Window", this);
|
||||
m_new_window_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::New));
|
||||
menu->addAction(m_new_window_action);
|
||||
|
||||
auto* close_current_tab_action = new QAction("&Close Current Tab", this);
|
||||
close_current_tab_action->setIcon(load_icon_from_uri("resource://icons/16x16/close-tab.png"sv));
|
||||
close_current_tab_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Close));
|
||||
|
@ -213,8 +218,8 @@ BrowserWindow::BrowserWindow(Vector<URL::URL> const& initial_urls, WebView::Cook
|
|||
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);
|
||||
QObject::connect(task_manager_action, &QAction::triggered, this, [this] {
|
||||
show_task_manager_window();
|
||||
QObject::connect(task_manager_action, &QAction::triggered, this, [] {
|
||||
static_cast<Ladybird::Application*>(QApplication::instance())->show_task_manager_window();
|
||||
});
|
||||
|
||||
auto* debug_menu = menuBar()->addMenu("&Debug");
|
||||
|
@ -391,6 +396,10 @@ BrowserWindow::BrowserWindow(Vector<URL::URL> const& initial_urls, WebView::Cook
|
|||
QObject::connect(m_new_tab_action, &QAction::triggered, this, [this] {
|
||||
new_tab_from_url(ak_url_from_qstring(Settings::the()->new_tab_page()), Web::HTML::ActivateTab::Yes);
|
||||
});
|
||||
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()) };
|
||||
(void)static_cast<Ladybird::Application*>(QApplication::instance())->new_window(initial_urls, m_cookie_jar, m_web_content_options, m_webdriver_content_ipc_path);
|
||||
});
|
||||
QObject::connect(open_file_action, &QAction::triggered, this, &BrowserWindow::open_file);
|
||||
QObject::connect(settings_action, &QAction::triggered, this, [this] {
|
||||
if (!m_settings_dialog) {
|
||||
|
@ -864,6 +873,9 @@ bool BrowserWindow::event(QEvent* event)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (event->type() == QEvent::WindowActivate)
|
||||
static_cast<Ladybird::Application*>(QApplication::instance())->set_active_window(*this);
|
||||
|
||||
return QMainWindow::event(event);
|
||||
}
|
||||
|
||||
|
@ -917,23 +929,9 @@ void BrowserWindow::closeEvent(QCloseEvent* event)
|
|||
Settings::the()->set_last_size(size());
|
||||
Settings::the()->set_is_maximized(isMaximized());
|
||||
|
||||
QObject::deleteLater();
|
||||
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
void BrowserWindow::show_task_manager_window()
|
||||
{
|
||||
if (!m_task_manager_window) {
|
||||
m_task_manager_window = new TaskManagerWindow(this);
|
||||
}
|
||||
m_task_manager_window->show();
|
||||
m_task_manager_window->activateWindow();
|
||||
m_task_manager_window->raise();
|
||||
}
|
||||
|
||||
void BrowserWindow::close_task_manager_window()
|
||||
{
|
||||
if (m_task_manager_window)
|
||||
m_task_manager_window->close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,6 +57,11 @@ public:
|
|||
return *m_new_tab_action;
|
||||
}
|
||||
|
||||
QAction& new_window_action()
|
||||
{
|
||||
return *m_new_window_action;
|
||||
}
|
||||
|
||||
QAction& copy_selection_action()
|
||||
{
|
||||
return *m_copy_selection_action;
|
||||
|
@ -141,9 +146,6 @@ private:
|
|||
QString tool_tip_for_page_mute_state(Tab&) const;
|
||||
QTabBar::ButtonPosition audio_button_position_for_tab(int tab_index) const;
|
||||
|
||||
void show_task_manager_window();
|
||||
void close_task_manager_window();
|
||||
|
||||
QScreen* m_current_screen;
|
||||
double m_device_pixel_ratio { 0 };
|
||||
|
||||
|
@ -155,6 +157,7 @@ private:
|
|||
QAction* m_go_forward_action { nullptr };
|
||||
QAction* m_reload_action { nullptr };
|
||||
QAction* m_new_tab_action { nullptr };
|
||||
QAction* m_new_window_action { nullptr };
|
||||
QAction* m_copy_selection_action { nullptr };
|
||||
QAction* m_paste_action { nullptr };
|
||||
QAction* m_select_all_action { nullptr };
|
||||
|
@ -163,9 +166,6 @@ private:
|
|||
|
||||
SettingsDialog* m_settings_dialog { nullptr };
|
||||
|
||||
// FIXME: This should be owned at a higher level in case we have multiple browser windows
|
||||
TaskManagerWindow* m_task_manager_window { nullptr };
|
||||
|
||||
WebView::CookieJar& m_cookie_jar;
|
||||
|
||||
WebContentOptions m_web_content_options;
|
||||
|
|
|
@ -103,6 +103,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
bool debug_web_content = false;
|
||||
bool log_all_js_exceptions = false;
|
||||
bool enable_idl_tracing = false;
|
||||
bool new_window = false;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.set_general_help("The Ladybird web browser :^)");
|
||||
|
@ -117,17 +118,29 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
args_parser.add_option(log_all_js_exceptions, "Log all JavaScript exceptions", "log-all-js-exceptions");
|
||||
args_parser.add_option(enable_idl_tracing, "Enable IDL tracing", "enable-idl-tracing");
|
||||
args_parser.add_option(expose_internals_object, "Expose internals object", "expose-internals-object");
|
||||
args_parser.add_option(new_window, "Force opening in a new window", "new-window", 'n');
|
||||
args_parser.parse(arguments);
|
||||
|
||||
WebView::ChromeProcess chrome_process;
|
||||
auto new_window = false;
|
||||
if (TRY(chrome_process.connect(raw_urls, new_window)) == WebView::ChromeProcess::ProcessDisposition::ExitProcess) {
|
||||
outln("Opening in existing process");
|
||||
return 0;
|
||||
}
|
||||
|
||||
chrome_process.on_new_window = [](auto const& urls) {
|
||||
dbgln("asked to open new window with urls: {}", urls);
|
||||
chrome_process.on_new_tab = [&](auto const& raw_urls) {
|
||||
auto& window = app.active_window();
|
||||
auto urls = sanitize_urls(raw_urls);
|
||||
for (size_t i = 0; i < urls.size(); ++i) {
|
||||
window.new_tab_from_url(urls[i], (i == 0) ? Web::HTML::ActivateTab::Yes : Web::HTML::ActivateTab::No);
|
||||
}
|
||||
window.show();
|
||||
window.activateWindow();
|
||||
window.raise();
|
||||
};
|
||||
|
||||
app.on_open_file = [&](auto file_url) {
|
||||
auto& window = app.active_window();
|
||||
window.view().load(file_url);
|
||||
};
|
||||
|
||||
WebView::ProcessManager::initialize();
|
||||
|
@ -171,23 +184,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.expose_internals_object = expose_internals_object ? Ladybird::ExposeInternalsObject::Yes : Ladybird::ExposeInternalsObject::No,
|
||||
};
|
||||
|
||||
Ladybird::BrowserWindow window(sanitize_urls(raw_urls), cookie_jar, web_content_options, webdriver_content_ipc_path);
|
||||
chrome_process.on_new_window = [&](auto const& urls) {
|
||||
app.new_window(sanitize_urls(urls), cookie_jar, web_content_options, webdriver_content_ipc_path);
|
||||
};
|
||||
|
||||
auto& window = app.new_window(sanitize_urls(raw_urls), cookie_jar, web_content_options, webdriver_content_ipc_path);
|
||||
window.setWindowTitle("Ladybird");
|
||||
|
||||
chrome_process.on_new_tab = [&](auto const& raw_urls) {
|
||||
auto urls = sanitize_urls(raw_urls);
|
||||
for (size_t i = 0; i < urls.size(); ++i) {
|
||||
window.new_tab_from_url(urls[i], (i == 0) ? Web::HTML::ActivateTab::Yes : Web::HTML::ActivateTab::No);
|
||||
}
|
||||
window.show();
|
||||
window.activateWindow();
|
||||
window.raise();
|
||||
};
|
||||
|
||||
app.on_open_file = [&](auto file_url) {
|
||||
window.view().load(file_url);
|
||||
};
|
||||
|
||||
if (Ladybird::Settings::the()->is_maximized()) {
|
||||
window.showMaximized();
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue