mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 19:17:41 +00:00
Browser+Ladybird+LibWebView: Move some common functions to LibWebView
The implementations of handle_web_content_process_crash and take_screenshot are exactly the same across Browser and Ladybird. Let's reduce some code duplication and move them to LibWebView.
This commit is contained in:
parent
5312a140fe
commit
d8b14da380
12 changed files with 90 additions and 188 deletions
|
@ -9,12 +9,8 @@
|
||||||
#include "BrowserWindow.h"
|
#include "BrowserWindow.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
#include <AK/LexicalPath.h>
|
|
||||||
#include <Browser/History.h>
|
#include <Browser/History.h>
|
||||||
#include <LibCore/DateTime.h>
|
|
||||||
#include <LibCore/StandardPaths.h>
|
|
||||||
#include <LibGfx/ImageFormats/BMPWriter.h>
|
#include <LibGfx/ImageFormats/BMPWriter.h>
|
||||||
#include <LibGfx/ImageFormats/PNGWriter.h>
|
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
|
@ -191,7 +187,7 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::
|
||||||
auto* take_visible_screenshot_action = new QAction("Take &Visible Screenshot", this);
|
auto* take_visible_screenshot_action = new QAction("Take &Visible Screenshot", this);
|
||||||
take_visible_screenshot_action->setIcon(QIcon(QString("%1/res/icons/16x16/filetype-image.png").arg(s_serenity_resource_root.characters())));
|
take_visible_screenshot_action->setIcon(QIcon(QString("%1/res/icons/16x16/filetype-image.png").arg(s_serenity_resource_root.characters())));
|
||||||
QObject::connect(take_visible_screenshot_action, &QAction::triggered, this, [this]() {
|
QObject::connect(take_visible_screenshot_action, &QAction::triggered, this, [this]() {
|
||||||
if (auto result = take_screenshot(ScreenshotType::Visible); result.is_error()) {
|
if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Visible); result.is_error()) {
|
||||||
auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors();
|
auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors();
|
||||||
QMessageBox::warning(this, "Ladybird", qstring_from_ak_string(error));
|
QMessageBox::warning(this, "Ladybird", qstring_from_ak_string(error));
|
||||||
}
|
}
|
||||||
|
@ -200,7 +196,7 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::
|
||||||
auto* take_full_screenshot_action = new QAction("Take &Full Screenshot", this);
|
auto* take_full_screenshot_action = new QAction("Take &Full Screenshot", this);
|
||||||
take_full_screenshot_action->setIcon(QIcon(QString("%1/res/icons/16x16/filetype-image.png").arg(s_serenity_resource_root.characters())));
|
take_full_screenshot_action->setIcon(QIcon(QString("%1/res/icons/16x16/filetype-image.png").arg(s_serenity_resource_root.characters())));
|
||||||
QObject::connect(take_full_screenshot_action, &QAction::triggered, this, [this]() {
|
QObject::connect(take_full_screenshot_action, &QAction::triggered, this, [this]() {
|
||||||
if (auto result = take_screenshot(ScreenshotType::Full); result.is_error()) {
|
if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Full); result.is_error()) {
|
||||||
auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors();
|
auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors();
|
||||||
QMessageBox::warning(this, "Ladybird", qstring_from_ak_string(error));
|
QMessageBox::warning(this, "Ladybird", qstring_from_ak_string(error));
|
||||||
}
|
}
|
||||||
|
@ -450,33 +446,6 @@ void Tab::copy_link_url(URL const& url)
|
||||||
clipboard->setText(qstring_from_ak_deprecated_string(url.to_deprecated_string()));
|
clipboard->setText(qstring_from_ak_deprecated_string(url.to_deprecated_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> Tab::take_screenshot(ScreenshotType type)
|
|
||||||
{
|
|
||||||
Gfx::ShareableBitmap bitmap;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case ScreenshotType::Visible:
|
|
||||||
bitmap = view().take_screenshot();
|
|
||||||
break;
|
|
||||||
case ScreenshotType::Full:
|
|
||||||
bitmap = view().take_document_screenshot();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bitmap.is_valid())
|
|
||||||
return Error::from_string_view("Failed to take a screenshot of the current tab"sv);
|
|
||||||
|
|
||||||
LexicalPath path { Core::StandardPaths::downloads_directory() };
|
|
||||||
path = path.append(TRY(Core::DateTime::now().to_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv)));
|
|
||||||
|
|
||||||
auto encoded = TRY(Gfx::PNGWriter::encode(*bitmap.bitmap()));
|
|
||||||
|
|
||||||
auto screenshot_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write));
|
|
||||||
TRY(screenshot_file->write_until_depleted(encoded));
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Tab::location_edit_return_pressed()
|
void Tab::location_edit_return_pressed()
|
||||||
{
|
{
|
||||||
navigate(m_location_edit->text());
|
navigate(m_location_edit->text());
|
||||||
|
|
|
@ -60,12 +60,6 @@ private:
|
||||||
void open_link_in_new_tab(URL const&);
|
void open_link_in_new_tab(URL const&);
|
||||||
void copy_link_url(URL const&);
|
void copy_link_url(URL const&);
|
||||||
|
|
||||||
enum class ScreenshotType {
|
|
||||||
Visible,
|
|
||||||
Full,
|
|
||||||
};
|
|
||||||
ErrorOr<void> take_screenshot(ScreenshotType);
|
|
||||||
|
|
||||||
QBoxLayout* m_layout;
|
QBoxLayout* m_layout;
|
||||||
QToolBar* m_toolbar { nullptr };
|
QToolBar* m_toolbar { nullptr };
|
||||||
QToolButton* m_reset_zoom_button { nullptr };
|
QToolButton* m_reset_zoom_button { nullptr };
|
||||||
|
|
|
@ -637,43 +637,6 @@ void WebContentView::create_client(WebView::EnableCallgrindProfiling enable_call
|
||||||
client().async_connect_to_webdriver(m_webdriver_content_ipc_path);
|
client().async_connect_to_webdriver(m_webdriver_content_ipc_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::ShareableBitmap WebContentView::take_screenshot() const
|
|
||||||
{
|
|
||||||
if (auto* bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr())
|
|
||||||
return bitmap->to_shareable_bitmap();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Gfx::ShareableBitmap WebContentView::take_document_screenshot()
|
|
||||||
{
|
|
||||||
return client().take_document_screenshot();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebContentView::handle_web_content_process_crash()
|
|
||||||
{
|
|
||||||
dbgln("WebContent process crashed!");
|
|
||||||
create_client();
|
|
||||||
VERIFY(m_client_state.client);
|
|
||||||
|
|
||||||
// Don't keep a stale backup bitmap around.
|
|
||||||
m_backup_bitmap = nullptr;
|
|
||||||
|
|
||||||
handle_resize();
|
|
||||||
StringBuilder builder;
|
|
||||||
builder.append("<html><head><title>Crashed: "sv);
|
|
||||||
builder.append(escape_html_entities(m_url.to_deprecated_string()));
|
|
||||||
builder.append("</title></head><body>"sv);
|
|
||||||
builder.append("<h1>Web page crashed"sv);
|
|
||||||
if (!m_url.host().is_empty()) {
|
|
||||||
builder.appendff(" on {}", escape_html_entities(m_url.host()));
|
|
||||||
}
|
|
||||||
builder.append("</h1>"sv);
|
|
||||||
auto escaped_url = escape_html_entities(m_url.to_deprecated_string());
|
|
||||||
builder.appendff("The web page <a href=\"{}\">{}</a> has crashed.<br><br>You can reload the page to try again.", escaped_url, escaped_url);
|
|
||||||
builder.append("</body></html>"sv);
|
|
||||||
load_html(builder.to_deprecated_string(), m_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebContentView::notify_server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize size)
|
void WebContentView::notify_server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize size)
|
||||||
{
|
{
|
||||||
if (m_client_state.back_bitmap.id == bitmap_id) {
|
if (m_client_state.back_bitmap.id == bitmap_id) {
|
||||||
|
|
|
@ -113,9 +113,6 @@ public:
|
||||||
Gfx::IntPoint to_content(Gfx::IntPoint) const;
|
Gfx::IntPoint to_content(Gfx::IntPoint) const;
|
||||||
Gfx::IntPoint to_widget(Gfx::IntPoint) const;
|
Gfx::IntPoint to_widget(Gfx::IntPoint) const;
|
||||||
|
|
||||||
Gfx::ShareableBitmap take_screenshot() const;
|
|
||||||
Gfx::ShareableBitmap take_document_screenshot();
|
|
||||||
|
|
||||||
enum class PaletteMode {
|
enum class PaletteMode {
|
||||||
Default,
|
Default,
|
||||||
Dark,
|
Dark,
|
||||||
|
@ -223,7 +220,5 @@ private:
|
||||||
|
|
||||||
Gfx::IntRect m_viewport_rect;
|
Gfx::IntRect m_viewport_rect;
|
||||||
|
|
||||||
void handle_web_content_process_crash();
|
|
||||||
|
|
||||||
StringView m_webdriver_content_ipc_path;
|
StringView m_webdriver_content_ipc_path;
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
#include "CookieJar.h"
|
#include "CookieJar.h"
|
||||||
#include "InspectorWidget.h"
|
#include "InspectorWidget.h"
|
||||||
#include "Tab.h"
|
#include "Tab.h"
|
||||||
#include <AK/LexicalPath.h>
|
|
||||||
#include <Applications/Browser/BrowserWindowGML.h>
|
#include <Applications/Browser/BrowserWindowGML.h>
|
||||||
#include <LibConfig/Client.h>
|
#include <LibConfig/Client.h>
|
||||||
#include <LibCore/DateTime.h>
|
|
||||||
#include <LibCore/StandardPaths.h>
|
#include <LibCore/StandardPaths.h>
|
||||||
#include <LibGUI/Application.h>
|
#include <LibGUI/Application.h>
|
||||||
#include <LibGUI/Clipboard.h>
|
#include <LibGUI/Clipboard.h>
|
||||||
|
@ -32,7 +30,6 @@
|
||||||
#include <LibGUI/TabWidget.h>
|
#include <LibGUI/TabWidget.h>
|
||||||
#include <LibGUI/ToolbarContainer.h>
|
#include <LibGUI/ToolbarContainer.h>
|
||||||
#include <LibGUI/Widget.h>
|
#include <LibGUI/Widget.h>
|
||||||
#include <LibGfx/ImageFormats/PNGWriter.h>
|
|
||||||
#include <LibJS/Interpreter.h>
|
#include <LibJS/Interpreter.h>
|
||||||
#include <LibWeb/CSS/PreferredColorScheme.h>
|
#include <LibWeb/CSS/PreferredColorScheme.h>
|
||||||
#include <LibWeb/Dump.h>
|
#include <LibWeb/Dump.h>
|
||||||
|
@ -259,22 +256,6 @@ void BrowserWindow::build_menus()
|
||||||
this);
|
this);
|
||||||
m_inspect_dom_node_action->set_status_tip("Open inspector for this element");
|
m_inspect_dom_node_action->set_status_tip("Open inspector for this element");
|
||||||
|
|
||||||
m_take_visible_screenshot_action = GUI::Action::create(
|
|
||||||
"Take &Visible Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) {
|
|
||||||
if (auto result = take_screenshot(ScreenshotType::Visible); result.is_error())
|
|
||||||
GUI::MessageBox::show_error(this, DeprecatedString::formatted("{}", result.error()));
|
|
||||||
},
|
|
||||||
this);
|
|
||||||
m_take_visible_screenshot_action->set_status_tip("Save a screenshot of the visible portion of the current tab to the Downloads directory"sv);
|
|
||||||
|
|
||||||
m_take_full_screenshot_action = GUI::Action::create(
|
|
||||||
"Take &Full Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) {
|
|
||||||
if (auto result = take_screenshot(ScreenshotType::Full); result.is_error())
|
|
||||||
GUI::MessageBox::show_error(this, DeprecatedString::formatted("{}", result.error()));
|
|
||||||
},
|
|
||||||
this);
|
|
||||||
m_take_full_screenshot_action->set_status_tip("Save a screenshot of the entirety of the current tab to the Downloads directory"sv);
|
|
||||||
|
|
||||||
auto& inspect_menu = add_menu("&Inspect"_string.release_value_but_fixme_should_propagate_errors());
|
auto& inspect_menu = add_menu("&Inspect"_string.release_value_but_fixme_should_propagate_errors());
|
||||||
inspect_menu.add_action(*m_view_source_action);
|
inspect_menu.add_action(*m_view_source_action);
|
||||||
inspect_menu.add_action(*m_inspect_dom_tree_action);
|
inspect_menu.add_action(*m_inspect_dom_tree_action);
|
||||||
|
@ -655,10 +636,6 @@ Tab& BrowserWindow::create_new_tab(URL url, Web::HTML::ActivateTab activate)
|
||||||
return active_tab().view().get_session_storage_entries();
|
return active_tab().view().get_session_storage_entries();
|
||||||
};
|
};
|
||||||
|
|
||||||
new_tab.on_take_screenshot = [this]() {
|
|
||||||
return active_tab().view().take_screenshot();
|
|
||||||
};
|
|
||||||
|
|
||||||
new_tab.load(url);
|
new_tab.load(url);
|
||||||
|
|
||||||
dbgln_if(SPAM_DEBUG, "Added new tab {:p}, loading {}", &new_tab, url);
|
dbgln_if(SPAM_DEBUG, "Added new tab {:p}, loading {}", &new_tab, url);
|
||||||
|
@ -776,36 +753,6 @@ void BrowserWindow::event(Core::Event& event)
|
||||||
Window::event(event);
|
Window::event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> BrowserWindow::take_screenshot(ScreenshotType type)
|
|
||||||
{
|
|
||||||
if (!active_tab().on_take_screenshot)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
Gfx::ShareableBitmap bitmap;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case ScreenshotType::Visible:
|
|
||||||
bitmap = active_tab().on_take_screenshot();
|
|
||||||
break;
|
|
||||||
case ScreenshotType::Full:
|
|
||||||
bitmap = active_tab().view().take_document_screenshot();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bitmap.is_valid())
|
|
||||||
return Error::from_string_view("Failed to take a screenshot of the current tab"sv);
|
|
||||||
|
|
||||||
LexicalPath path { Core::StandardPaths::downloads_directory() };
|
|
||||||
path = path.append(Core::DateTime::now().to_deprecated_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv));
|
|
||||||
|
|
||||||
auto encoded = TRY(Gfx::PNGWriter::encode(*bitmap.bitmap()));
|
|
||||||
|
|
||||||
auto screenshot_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write));
|
|
||||||
TRY(screenshot_file->write_until_depleted(encoded));
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowserWindow::update_displayed_zoom_level()
|
void BrowserWindow::update_displayed_zoom_level()
|
||||||
{
|
{
|
||||||
VERIFY(m_zoom_menu);
|
VERIFY(m_zoom_menu);
|
||||||
|
|
|
@ -41,8 +41,6 @@ public:
|
||||||
GUI::Action& view_source_action() { return *m_view_source_action; }
|
GUI::Action& view_source_action() { return *m_view_source_action; }
|
||||||
GUI::Action& inspect_dom_tree_action() { return *m_inspect_dom_tree_action; }
|
GUI::Action& inspect_dom_tree_action() { return *m_inspect_dom_tree_action; }
|
||||||
GUI::Action& inspect_dom_node_action() { return *m_inspect_dom_node_action; }
|
GUI::Action& inspect_dom_node_action() { return *m_inspect_dom_node_action; }
|
||||||
GUI::Action& take_visible_screenshot_action() { return *m_take_visible_screenshot_action; }
|
|
||||||
GUI::Action& take_full_screenshot_action() { return *m_take_full_screenshot_action; }
|
|
||||||
|
|
||||||
void content_filters_changed();
|
void content_filters_changed();
|
||||||
void autoplay_allowlist_changed();
|
void autoplay_allowlist_changed();
|
||||||
|
@ -65,12 +63,6 @@ private:
|
||||||
|
|
||||||
void update_displayed_zoom_level();
|
void update_displayed_zoom_level();
|
||||||
|
|
||||||
enum class ScreenshotType {
|
|
||||||
Visible,
|
|
||||||
Full,
|
|
||||||
};
|
|
||||||
ErrorOr<void> take_screenshot(ScreenshotType);
|
|
||||||
|
|
||||||
RefPtr<GUI::Action> m_go_back_action;
|
RefPtr<GUI::Action> m_go_back_action;
|
||||||
RefPtr<GUI::Action> m_go_forward_action;
|
RefPtr<GUI::Action> m_go_forward_action;
|
||||||
RefPtr<GUI::Action> m_go_home_action;
|
RefPtr<GUI::Action> m_go_home_action;
|
||||||
|
@ -80,8 +72,6 @@ private:
|
||||||
RefPtr<GUI::Action> m_view_source_action;
|
RefPtr<GUI::Action> m_view_source_action;
|
||||||
RefPtr<GUI::Action> m_inspect_dom_tree_action;
|
RefPtr<GUI::Action> m_inspect_dom_tree_action;
|
||||||
RefPtr<GUI::Action> m_inspect_dom_node_action;
|
RefPtr<GUI::Action> m_inspect_dom_node_action;
|
||||||
RefPtr<GUI::Action> m_take_visible_screenshot_action;
|
|
||||||
RefPtr<GUI::Action> m_take_full_screenshot_action;
|
|
||||||
|
|
||||||
RefPtr<GUI::Menu> m_zoom_menu;
|
RefPtr<GUI::Menu> m_zoom_menu;
|
||||||
|
|
||||||
|
|
|
@ -554,6 +554,26 @@ Tab::Tab(BrowserWindow& window)
|
||||||
on_tab_close_other_request(*this);
|
on_tab_close_other_request(*this);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
auto take_visible_screenshot_action = GUI::Action::create(
|
||||||
|
"Take &Visible Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) {
|
||||||
|
if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Visible); result.is_error()) {
|
||||||
|
auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors();
|
||||||
|
GUI::MessageBox::show_error(&this->window(), error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
this);
|
||||||
|
take_visible_screenshot_action->set_status_tip("Save a screenshot of the visible portion of the current tab to the Downloads directory"sv);
|
||||||
|
|
||||||
|
auto take_full_screenshot_action = GUI::Action::create(
|
||||||
|
"Take &Full Screenshot"sv, g_icon_bag.filetype_image, [this](auto&) {
|
||||||
|
if (auto result = view().take_screenshot(WebView::ViewImplementation::ScreenshotType::Full); result.is_error()) {
|
||||||
|
auto error = String::formatted("{}", result.error()).release_value_but_fixme_should_propagate_errors();
|
||||||
|
GUI::MessageBox::show_error(&this->window(), error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
this);
|
||||||
|
take_full_screenshot_action->set_status_tip("Save a screenshot of the entirety of the current tab to the Downloads directory"sv);
|
||||||
|
|
||||||
m_page_context_menu = GUI::Menu::construct();
|
m_page_context_menu = GUI::Menu::construct();
|
||||||
m_page_context_menu->add_action(window.go_back_action());
|
m_page_context_menu->add_action(window.go_back_action());
|
||||||
m_page_context_menu->add_action(window.go_forward_action());
|
m_page_context_menu->add_action(window.go_forward_action());
|
||||||
|
@ -562,8 +582,8 @@ Tab::Tab(BrowserWindow& window)
|
||||||
m_page_context_menu->add_action(window.copy_selection_action());
|
m_page_context_menu->add_action(window.copy_selection_action());
|
||||||
m_page_context_menu->add_action(window.select_all_action());
|
m_page_context_menu->add_action(window.select_all_action());
|
||||||
m_page_context_menu->add_separator();
|
m_page_context_menu->add_separator();
|
||||||
m_page_context_menu->add_action(window.take_visible_screenshot_action());
|
m_page_context_menu->add_action(move(take_visible_screenshot_action));
|
||||||
m_page_context_menu->add_action(window.take_full_screenshot_action());
|
m_page_context_menu->add_action(move(take_full_screenshot_action));
|
||||||
m_page_context_menu->add_separator();
|
m_page_context_menu->add_separator();
|
||||||
m_page_context_menu->add_action(window.view_source_action());
|
m_page_context_menu->add_action(window.view_source_action());
|
||||||
m_page_context_menu->add_action(window.inspect_dom_tree_action());
|
m_page_context_menu->add_action(window.inspect_dom_tree_action());
|
||||||
|
|
|
@ -77,7 +77,6 @@ public:
|
||||||
Function<Vector<Web::Cookie::Cookie>()> on_get_cookies_entries;
|
Function<Vector<Web::Cookie::Cookie>()> on_get_cookies_entries;
|
||||||
Function<OrderedHashMap<DeprecatedString, DeprecatedString>()> on_get_local_storage_entries;
|
Function<OrderedHashMap<DeprecatedString, DeprecatedString>()> on_get_local_storage_entries;
|
||||||
Function<OrderedHashMap<DeprecatedString, DeprecatedString>()> on_get_session_storage_entries;
|
Function<OrderedHashMap<DeprecatedString, DeprecatedString>()> on_get_session_storage_entries;
|
||||||
Function<Gfx::ShareableBitmap()> on_take_screenshot;
|
|
||||||
|
|
||||||
void enable_webdriver_mode();
|
void enable_webdriver_mode();
|
||||||
|
|
||||||
|
|
|
@ -35,30 +35,6 @@ OutOfProcessWebView::OutOfProcessWebView()
|
||||||
|
|
||||||
OutOfProcessWebView::~OutOfProcessWebView() = default;
|
OutOfProcessWebView::~OutOfProcessWebView() = default;
|
||||||
|
|
||||||
void OutOfProcessWebView::handle_web_content_process_crash()
|
|
||||||
{
|
|
||||||
create_client();
|
|
||||||
VERIFY(m_client_state.client);
|
|
||||||
|
|
||||||
// Don't keep a stale backup bitmap around.
|
|
||||||
m_backup_bitmap = nullptr;
|
|
||||||
|
|
||||||
handle_resize();
|
|
||||||
StringBuilder builder;
|
|
||||||
builder.append("<html><head><title>Crashed: "sv);
|
|
||||||
builder.append(escape_html_entities(m_url.to_deprecated_string()));
|
|
||||||
builder.append("</title></head><body>"sv);
|
|
||||||
builder.append("<h1>Web page crashed"sv);
|
|
||||||
if (!m_url.host().is_empty()) {
|
|
||||||
builder.appendff(" on {}", escape_html_entities(m_url.host()));
|
|
||||||
}
|
|
||||||
builder.append("</h1>"sv);
|
|
||||||
auto escaped_url = escape_html_entities(m_url.to_deprecated_string());
|
|
||||||
builder.appendff("The web page <a href=\"{}\">{}</a> has crashed.<br><br>You can reload the page to try again.", escaped_url, escaped_url);
|
|
||||||
builder.append("</body></html>"sv);
|
|
||||||
load_html(builder.to_deprecated_string(), m_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutOfProcessWebView::create_client(EnableCallgrindProfiling)
|
void OutOfProcessWebView::create_client(EnableCallgrindProfiling)
|
||||||
{
|
{
|
||||||
m_client_state = {};
|
m_client_state = {};
|
||||||
|
@ -591,18 +567,6 @@ void OutOfProcessWebView::set_window_size(Gfx::IntSize size)
|
||||||
client().async_set_window_size(size);
|
client().async_set_window_size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::ShareableBitmap OutOfProcessWebView::take_screenshot() const
|
|
||||||
{
|
|
||||||
if (auto* bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr())
|
|
||||||
return bitmap->to_shareable_bitmap();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Gfx::ShareableBitmap OutOfProcessWebView::take_document_screenshot()
|
|
||||||
{
|
|
||||||
return client().take_document_screenshot();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutOfProcessWebView::focusin_event(GUI::FocusEvent&)
|
void OutOfProcessWebView::focusin_event(GUI::FocusEvent&)
|
||||||
{
|
{
|
||||||
client().async_set_has_focus(true);
|
client().async_set_has_focus(true);
|
||||||
|
|
|
@ -53,9 +53,6 @@ public:
|
||||||
|
|
||||||
void set_system_visibility_state(bool visible);
|
void set_system_visibility_state(bool visible);
|
||||||
|
|
||||||
Gfx::ShareableBitmap take_screenshot() const;
|
|
||||||
Gfx::ShareableBitmap take_document_screenshot();
|
|
||||||
|
|
||||||
// This is a hint that tells OOPWV that the content will scale to the viewport size.
|
// This is a hint that tells OOPWV that the content will scale to the viewport size.
|
||||||
// In practice, this means that OOPWV may render scaled stale versions of the content while resizing.
|
// In practice, this means that OOPWV may render scaled stale versions of the content while resizing.
|
||||||
void set_content_scales_to_viewport(bool);
|
void set_content_scales_to_viewport(bool);
|
||||||
|
@ -183,8 +180,6 @@ private:
|
||||||
|
|
||||||
virtual Gfx::IntRect viewport_rect() const override;
|
virtual Gfx::IntRect viewport_rect() const override;
|
||||||
|
|
||||||
void handle_web_content_process_crash();
|
|
||||||
|
|
||||||
using InputEvent = Variant<GUI::KeyEvent, GUI::MouseEvent>;
|
using InputEvent = Variant<GUI::KeyEvent, GUI::MouseEvent>;
|
||||||
void enqueue_input_event(InputEvent const&);
|
void enqueue_input_event(InputEvent const&);
|
||||||
void process_next_input_event();
|
void process_next_input_event();
|
||||||
|
|
|
@ -5,7 +5,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Error.h>
|
#include <AK/Error.h>
|
||||||
|
#include <AK/LexicalPath.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
#include <LibCore/DateTime.h>
|
||||||
|
#include <LibCore/StandardPaths.h>
|
||||||
|
#include <LibGfx/ImageFormats/PNGWriter.h>
|
||||||
#include <LibWebView/ViewImplementation.h>
|
#include <LibWebView/ViewImplementation.h>
|
||||||
|
|
||||||
namespace WebView {
|
namespace WebView {
|
||||||
|
@ -286,4 +290,58 @@ void ViewImplementation::request_repaint()
|
||||||
client().async_paint(viewport_rect(), m_client_state.back_bitmap.id);
|
client().async_paint(viewport_rect(), m_client_state.back_bitmap.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewImplementation::handle_web_content_process_crash()
|
||||||
|
{
|
||||||
|
dbgln("WebContent process crashed!");
|
||||||
|
|
||||||
|
create_client();
|
||||||
|
VERIFY(m_client_state.client);
|
||||||
|
|
||||||
|
// Don't keep a stale backup bitmap around.
|
||||||
|
m_backup_bitmap = nullptr;
|
||||||
|
|
||||||
|
handle_resize();
|
||||||
|
StringBuilder builder;
|
||||||
|
builder.append("<html><head><title>Crashed: "sv);
|
||||||
|
builder.append(escape_html_entities(m_url.to_deprecated_string()));
|
||||||
|
builder.append("</title></head><body>"sv);
|
||||||
|
builder.append("<h1>Web page crashed"sv);
|
||||||
|
if (!m_url.host().is_empty()) {
|
||||||
|
builder.appendff(" on {}", escape_html_entities(m_url.host()));
|
||||||
|
}
|
||||||
|
builder.append("</h1>"sv);
|
||||||
|
auto escaped_url = escape_html_entities(m_url.to_deprecated_string());
|
||||||
|
builder.appendff("The web page <a href=\"{}\">{}</a> has crashed.<br><br>You can reload the page to try again.", escaped_url, escaped_url);
|
||||||
|
builder.append("</body></html>"sv);
|
||||||
|
load_html(builder.to_deprecated_string(), m_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<void> ViewImplementation::take_screenshot(ScreenshotType type)
|
||||||
|
{
|
||||||
|
Gfx::ShareableBitmap bitmap;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case ScreenshotType::Visible:
|
||||||
|
if (auto* visible_bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr())
|
||||||
|
bitmap = visible_bitmap->to_shareable_bitmap();
|
||||||
|
break;
|
||||||
|
case ScreenshotType::Full:
|
||||||
|
bitmap = client().take_document_screenshot();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bitmap.is_valid())
|
||||||
|
return Error::from_string_view("Failed to take a screenshot of the current tab"sv);
|
||||||
|
|
||||||
|
LexicalPath path { Core::StandardPaths::downloads_directory() };
|
||||||
|
path = path.append(TRY(Core::DateTime::now().to_string("screenshot-%Y-%m-%d-%H-%M-%S.png"sv)));
|
||||||
|
|
||||||
|
auto encoded = TRY(Gfx::PNGWriter::encode(*bitmap.bitmap()));
|
||||||
|
|
||||||
|
auto screenshot_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write));
|
||||||
|
TRY(screenshot_file->write_until_depleted(encoded));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,12 @@ public:
|
||||||
void toggle_video_loop_state();
|
void toggle_video_loop_state();
|
||||||
void toggle_video_controls_state();
|
void toggle_video_controls_state();
|
||||||
|
|
||||||
|
enum class ScreenshotType {
|
||||||
|
Visible,
|
||||||
|
Full,
|
||||||
|
};
|
||||||
|
ErrorOr<void> take_screenshot(ScreenshotType);
|
||||||
|
|
||||||
virtual void notify_server_did_layout(Badge<WebContentClient>, Gfx::IntSize content_size) = 0;
|
virtual void notify_server_did_layout(Badge<WebContentClient>, Gfx::IntSize content_size) = 0;
|
||||||
virtual void notify_server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize) = 0;
|
virtual void notify_server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize) = 0;
|
||||||
virtual void notify_server_did_invalidate_content_rect(Badge<WebContentClient>, Gfx::IntRect const&) = 0;
|
virtual void notify_server_did_invalidate_content_rect(Badge<WebContentClient>, Gfx::IntRect const&) = 0;
|
||||||
|
@ -157,6 +163,8 @@ protected:
|
||||||
ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, EnableCallgrindProfiling = EnableCallgrindProfiling::No, IsLayoutTestMode = IsLayoutTestMode::No);
|
ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, EnableCallgrindProfiling = EnableCallgrindProfiling::No, IsLayoutTestMode = IsLayoutTestMode::No);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void handle_web_content_process_crash();
|
||||||
|
|
||||||
struct SharedBitmap {
|
struct SharedBitmap {
|
||||||
i32 id { -1 };
|
i32 id { -1 };
|
||||||
i32 pending_paints { 0 };
|
i32 pending_paints { 0 };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue