mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:37:44 +00:00
Ladybird+LibWebView+WebContent: Make the screenshot IPCs async
These IPCs are different than other IPCs in that we can't just set up a callback function to be invoked when WebContent sends us the screenshot data. There are multiple places that would set that callback, and they would step on each other's toes. Instead, the screenshot APIs on ViewImplementation now return a Promise which callers can interact with to receive the screenshot (or an error).
This commit is contained in:
parent
93db790974
commit
d8fa226a8f
13 changed files with 121 additions and 47 deletions
|
@ -254,10 +254,13 @@ void InspectorClient::context_menu_screenshot_dom_node()
|
|||
{
|
||||
VERIFY(m_context_menu_data.has_value());
|
||||
|
||||
if (auto result = m_content_web_view.take_dom_node_screenshot(m_context_menu_data->dom_node_id); result.is_error())
|
||||
append_console_warning(MUST(String::formatted("Warning: {}", result.error())));
|
||||
else
|
||||
append_console_message(MUST(String::formatted("Screenshot saved to: {}", result.value())));
|
||||
m_content_web_view.take_dom_node_screenshot(m_context_menu_data->dom_node_id)
|
||||
->when_resolved([this](auto const& path) {
|
||||
append_console_message(MUST(String::formatted("Screenshot saved to: {}", path)));
|
||||
})
|
||||
.when_rejected([this](auto const& error) {
|
||||
append_console_warning(MUST(String::formatted("Warning: {}", error)));
|
||||
});
|
||||
|
||||
m_context_menu_data.clear();
|
||||
}
|
||||
|
|
|
@ -370,27 +370,65 @@ static ErrorOr<LexicalPath> save_screenshot(Gfx::ShareableBitmap const& bitmap)
|
|||
return path;
|
||||
}
|
||||
|
||||
ErrorOr<LexicalPath> ViewImplementation::take_screenshot(ScreenshotType type)
|
||||
NonnullRefPtr<Core::Promise<LexicalPath>> ViewImplementation::take_screenshot(ScreenshotType type)
|
||||
{
|
||||
auto promise = Core::Promise<LexicalPath>::construct();
|
||||
|
||||
if (m_pending_screenshot) {
|
||||
// For simplicitly, only allow taking one screenshot at a time for now. Revisit if we need
|
||||
// to allow spamming screenshot requests for some reason.
|
||||
promise->reject(Error::from_string_literal("A screenshot request is already in progress"));
|
||||
return promise;
|
||||
}
|
||||
|
||||
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();
|
||||
if (auto* visible_bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr()) {
|
||||
if (auto result = save_screenshot(visible_bitmap->to_shareable_bitmap()); result.is_error())
|
||||
promise->reject(result.release_error());
|
||||
else
|
||||
promise->resolve(result.release_value());
|
||||
}
|
||||
break;
|
||||
|
||||
case ScreenshotType::Full:
|
||||
bitmap = client().take_document_screenshot();
|
||||
m_pending_screenshot = promise;
|
||||
client().async_take_document_screenshot();
|
||||
break;
|
||||
}
|
||||
|
||||
return save_screenshot(bitmap);
|
||||
return promise;
|
||||
}
|
||||
|
||||
ErrorOr<LexicalPath> ViewImplementation::take_dom_node_screenshot(i32 node_id)
|
||||
NonnullRefPtr<Core::Promise<LexicalPath>> ViewImplementation::take_dom_node_screenshot(i32 node_id)
|
||||
{
|
||||
auto bitmap = client().take_dom_node_screenshot(node_id);
|
||||
return save_screenshot(bitmap);
|
||||
auto promise = Core::Promise<LexicalPath>::construct();
|
||||
|
||||
if (m_pending_screenshot) {
|
||||
// For simplicitly, only allow taking one screenshot at a time for now. Revisit if we need
|
||||
// to allow spamming screenshot requests for some reason.
|
||||
promise->reject(Error::from_string_literal("A screenshot request is already in progress"));
|
||||
return promise;
|
||||
}
|
||||
|
||||
m_pending_screenshot = promise;
|
||||
client().async_take_dom_node_screenshot(node_id);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
void ViewImplementation::did_receive_screenshot(Badge<WebContentClient>, Gfx::ShareableBitmap const& screenshot)
|
||||
{
|
||||
VERIFY(m_pending_screenshot);
|
||||
|
||||
if (auto result = save_screenshot(screenshot); result.is_error())
|
||||
m_pending_screenshot->reject(result.release_error());
|
||||
else
|
||||
m_pending_screenshot->resolve(result.release_value());
|
||||
|
||||
m_pending_screenshot = nullptr;
|
||||
}
|
||||
|
||||
ErrorOr<LexicalPath> ViewImplementation::dump_gc_graph()
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <AK/Function.h>
|
||||
#include <AK/LexicalPath.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/Promise.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
#include <LibGfx/StandardCursor.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
@ -95,8 +96,9 @@ public:
|
|||
Visible,
|
||||
Full,
|
||||
};
|
||||
ErrorOr<LexicalPath> take_screenshot(ScreenshotType);
|
||||
ErrorOr<LexicalPath> take_dom_node_screenshot(i32);
|
||||
NonnullRefPtr<Core::Promise<LexicalPath>> take_screenshot(ScreenshotType);
|
||||
NonnullRefPtr<Core::Promise<LexicalPath>> take_dom_node_screenshot(i32);
|
||||
virtual void did_receive_screenshot(Badge<WebContentClient>, Gfx::ShareableBitmap const&);
|
||||
|
||||
ErrorOr<LexicalPath> dump_gc_graph();
|
||||
|
||||
|
@ -229,6 +231,8 @@ protected:
|
|||
|
||||
size_t m_crash_count = 0;
|
||||
RefPtr<Core::Timer> m_repeated_crash_timer;
|
||||
|
||||
RefPtr<Core::Promise<LexicalPath>> m_pending_screenshot;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -231,6 +231,11 @@ void WebContentClient::did_get_dom_node_html(String const& html)
|
|||
m_view.on_received_dom_node_html(html);
|
||||
}
|
||||
|
||||
void WebContentClient::did_take_screenshot(Gfx::ShareableBitmap const& screenshot)
|
||||
{
|
||||
m_view.did_receive_screenshot({}, screenshot);
|
||||
}
|
||||
|
||||
void WebContentClient::did_output_js_console_message(i32 message_index)
|
||||
{
|
||||
if (m_view.on_received_console_message)
|
||||
|
|
|
@ -58,6 +58,7 @@ private:
|
|||
virtual void did_get_hovered_node_id(i32 node_id) override;
|
||||
virtual void did_finish_editing_dom_node(Optional<i32> const& node_id) override;
|
||||
virtual void did_get_dom_node_html(String const& html) override;
|
||||
virtual void did_take_screenshot(Gfx::ShareableBitmap const& screenshot) override;
|
||||
virtual void did_output_js_console_message(i32 message_index) override;
|
||||
virtual void did_get_js_console_messages(i32 start_index, Vector<ByteString> const& message_types, Vector<ByteString> const& messages) override;
|
||||
virtual void did_change_favicon(Gfx::ShareableBitmap const&) override;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue