mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-16 23:39:44 +00:00
LibWeb+WebContent+WebDriver+UI: Make window rect updates asynchronous
It's currently possible for window size/position updates to hang, as the underlying IPCs are synchronous. This updates the WebDriver endpoint to be async, to unblock the WebContent process while the update is ongoing. The UI process is now responsible for informing WebContent when the update is complete.
This commit is contained in:
parent
42984a10e9
commit
fa83cc722c
Notes:
github-actions[bot]
2024-10-29 11:04:46 +00:00
Author: https://github.com/trflynn89
Commit: fa83cc722c
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2028
Reviewed-by: https://github.com/tcl3 ✅
22 changed files with 94 additions and 43 deletions
|
@ -1007,26 +1007,26 @@ static void copy_data_to_clipboard(StringView data, NSPasteboardType pasteboard_
|
||||||
m_web_view_bridge->on_reposition_window = [weak_self](auto position) {
|
m_web_view_bridge->on_reposition_window = [weak_self](auto position) {
|
||||||
LadybirdWebView* self = weak_self;
|
LadybirdWebView* self = weak_self;
|
||||||
if (self == nil) {
|
if (self == nil) {
|
||||||
return Gfx::IntPoint {};
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
position = Ladybird::compute_origin_relative_to_window([self window], position);
|
position = Ladybird::compute_origin_relative_to_window([self window], position);
|
||||||
[[self window] setFrameOrigin:Ladybird::gfx_point_to_ns_point(position)];
|
[[self window] setFrameOrigin:Ladybird::gfx_point_to_ns_point(position)];
|
||||||
|
|
||||||
position = Ladybird::ns_point_to_gfx_point([[self window] frame].origin);
|
m_web_view_bridge->did_update_window_rect();
|
||||||
return Ladybird::compute_origin_relative_to_window([self window], position);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
m_web_view_bridge->on_resize_window = [weak_self](auto size) {
|
m_web_view_bridge->on_resize_window = [weak_self](auto size) {
|
||||||
LadybirdWebView* self = weak_self;
|
LadybirdWebView* self = weak_self;
|
||||||
if (self == nil) {
|
if (self == nil) {
|
||||||
return Gfx::IntSize {};
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto frame = [[self window] frame];
|
auto frame = [[self window] frame];
|
||||||
frame.size = Ladybird::gfx_size_to_ns_size(size);
|
frame.size = Ladybird::gfx_size_to_ns_size(size);
|
||||||
[[self window] setFrame:frame display:YES];
|
[[self window] setFrame:frame display:YES];
|
||||||
|
|
||||||
return Ladybird::ns_size_to_gfx_size([[self window] frame].size);
|
m_web_view_bridge->did_update_window_rect();
|
||||||
};
|
};
|
||||||
|
|
||||||
m_web_view_bridge->on_maximize_window = [weak_self]() {
|
m_web_view_bridge->on_maximize_window = [weak_self]() {
|
||||||
|
|
|
@ -354,12 +354,12 @@ Tab::Tab(BrowserWindow* window, RefPtr<WebView::WebContentClient> parent_client,
|
||||||
|
|
||||||
view().on_reposition_window = [this](auto const& position) {
|
view().on_reposition_window = [this](auto const& position) {
|
||||||
m_window->move(position.x(), position.y());
|
m_window->move(position.x(), position.y());
|
||||||
return Gfx::IntPoint { m_window->x(), m_window->y() };
|
view().did_update_window_rect();
|
||||||
};
|
};
|
||||||
|
|
||||||
view().on_resize_window = [this](auto const& size) {
|
view().on_resize_window = [this](auto const& size) {
|
||||||
m_window->resize(size.width(), size.height());
|
m_window->resize(size.width(), size.height());
|
||||||
return Gfx::IntSize { m_window->width(), m_window->height() };
|
view().did_update_window_rect();
|
||||||
};
|
};
|
||||||
|
|
||||||
view().on_maximize_window = [this]() {
|
view().on_maximize_window = [this]() {
|
||||||
|
|
|
@ -48,6 +48,7 @@ void Page::visit_edges(JS::Cell::Visitor& visitor)
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
visitor.visit(m_top_level_traversable);
|
visitor.visit(m_top_level_traversable);
|
||||||
visitor.visit(m_client);
|
visitor.visit(m_client);
|
||||||
|
visitor.visit(m_window_rect_observer);
|
||||||
visitor.visit(m_on_pending_dialog_closed);
|
visitor.visit(m_on_pending_dialog_closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +255,12 @@ JS::NonnullGCPtr<HTML::TraversableNavigable> Page::top_level_traversable() const
|
||||||
return *m_top_level_traversable;
|
return *m_top_level_traversable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Page::did_update_window_rect()
|
||||||
|
{
|
||||||
|
if (m_window_rect_observer)
|
||||||
|
m_window_rect_observer->function()({ window_position(), window_size() });
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ResponseType>
|
template<typename ResponseType>
|
||||||
static ResponseType spin_event_loop_until_dialog_closed(PageClient& client, Optional<ResponseType>& response, SourceLocation location = SourceLocation::current())
|
static ResponseType spin_event_loop_until_dialog_closed(PageClient& client, Optional<ResponseType>& response, SourceLocation location = SourceLocation::current())
|
||||||
{
|
{
|
||||||
|
|
|
@ -127,6 +127,9 @@ public:
|
||||||
DevicePixelSize window_size() const { return m_window_size; }
|
DevicePixelSize window_size() const { return m_window_size; }
|
||||||
void set_window_size(DevicePixelSize size) { m_window_size = size; }
|
void set_window_size(DevicePixelSize size) { m_window_size = size; }
|
||||||
|
|
||||||
|
void did_update_window_rect();
|
||||||
|
void set_window_rect_observer(JS::GCPtr<JS::HeapFunction<void(DevicePixelRect)>> window_rect_observer) { m_window_rect_observer = window_rect_observer; }
|
||||||
|
|
||||||
void did_request_alert(String const& message);
|
void did_request_alert(String const& message);
|
||||||
void alert_closed();
|
void alert_closed();
|
||||||
|
|
||||||
|
@ -245,6 +248,7 @@ private:
|
||||||
|
|
||||||
DevicePixelPoint m_window_position {};
|
DevicePixelPoint m_window_position {};
|
||||||
DevicePixelSize m_window_size {};
|
DevicePixelSize m_window_size {};
|
||||||
|
JS::GCPtr<JS::HeapFunction<void(DevicePixelRect)>> m_window_rect_observer;
|
||||||
|
|
||||||
PendingDialog m_pending_dialog { PendingDialog::None };
|
PendingDialog m_pending_dialog { PendingDialog::None };
|
||||||
Optional<String> m_pending_dialog_text;
|
Optional<String> m_pending_dialog_text;
|
||||||
|
@ -310,8 +314,8 @@ public:
|
||||||
virtual void page_did_request_navigate_back() { }
|
virtual void page_did_request_navigate_back() { }
|
||||||
virtual void page_did_request_navigate_forward() { }
|
virtual void page_did_request_navigate_forward() { }
|
||||||
virtual void page_did_request_refresh() { }
|
virtual void page_did_request_refresh() { }
|
||||||
virtual Gfx::IntSize page_did_request_resize_window(Gfx::IntSize) { return {}; }
|
virtual void page_did_request_resize_window(Gfx::IntSize) { }
|
||||||
virtual Gfx::IntPoint page_did_request_reposition_window(Gfx::IntPoint) { return {}; }
|
virtual void page_did_request_reposition_window(Gfx::IntPoint) { }
|
||||||
virtual void page_did_request_restore_window() { }
|
virtual void page_did_request_restore_window() { }
|
||||||
virtual Gfx::IntRect page_did_request_maximize_window() { return {}; }
|
virtual Gfx::IntRect page_did_request_maximize_window() { return {}; }
|
||||||
virtual Gfx::IntRect page_did_request_minimize_window() { return {}; }
|
virtual Gfx::IntRect page_did_request_minimize_window() { return {}; }
|
||||||
|
|
|
@ -87,6 +87,11 @@ void ViewImplementation::set_window_size(Gfx::IntSize size)
|
||||||
client().async_set_window_size(m_client_state.page_index, size.to_type<Web::DevicePixels>());
|
client().async_set_window_size(m_client_state.page_index, size.to_type<Web::DevicePixels>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewImplementation::did_update_window_rect()
|
||||||
|
{
|
||||||
|
client().async_did_update_window_rect(m_client_state.page_index);
|
||||||
|
}
|
||||||
|
|
||||||
void ViewImplementation::load(URL::URL const& url)
|
void ViewImplementation::load(URL::URL const& url)
|
||||||
{
|
{
|
||||||
m_url = url;
|
m_url = url;
|
||||||
|
|
|
@ -52,6 +52,7 @@ public:
|
||||||
|
|
||||||
void set_window_position(Gfx::IntPoint);
|
void set_window_position(Gfx::IntPoint);
|
||||||
void set_window_size(Gfx::IntSize);
|
void set_window_size(Gfx::IntSize);
|
||||||
|
void did_update_window_rect();
|
||||||
|
|
||||||
void load(URL::URL const&);
|
void load(URL::URL const&);
|
||||||
void load_html(StringView);
|
void load_html(StringView);
|
||||||
|
@ -202,8 +203,8 @@ public:
|
||||||
Function<void(i32 start_index, Vector<ByteString> const& message_types, Vector<ByteString> const& messages)> on_received_console_messages;
|
Function<void(i32 start_index, Vector<ByteString> const& message_types, Vector<ByteString> const& messages)> on_received_console_messages;
|
||||||
Function<void(i32 count_waiting)> on_resource_status_change;
|
Function<void(i32 count_waiting)> on_resource_status_change;
|
||||||
Function<void()> on_restore_window;
|
Function<void()> on_restore_window;
|
||||||
Function<Gfx::IntPoint(Gfx::IntPoint)> on_reposition_window;
|
Function<void(Gfx::IntPoint)> on_reposition_window;
|
||||||
Function<Gfx::IntSize(Gfx::IntSize)> on_resize_window;
|
Function<void(Gfx::IntSize)> on_resize_window;
|
||||||
Function<Gfx::IntRect()> on_maximize_window;
|
Function<Gfx::IntRect()> on_maximize_window;
|
||||||
Function<Gfx::IntRect()> on_minimize_window;
|
Function<Gfx::IntRect()> on_minimize_window;
|
||||||
Function<Gfx::IntRect()> on_fullscreen_window;
|
Function<Gfx::IntRect()> on_fullscreen_window;
|
||||||
|
|
|
@ -492,24 +492,20 @@ void WebContentClient::did_request_restore_window(u64 page_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Messages::WebContentClient::DidRequestRepositionWindowResponse WebContentClient::did_request_reposition_window(u64 page_id, Gfx::IntPoint position)
|
void WebContentClient::did_request_reposition_window(u64 page_id, Gfx::IntPoint position)
|
||||||
{
|
{
|
||||||
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||||
if (view->on_reposition_window)
|
if (view->on_reposition_window)
|
||||||
return view->on_reposition_window(position);
|
view->on_reposition_window(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Gfx::IntPoint {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Messages::WebContentClient::DidRequestResizeWindowResponse WebContentClient::did_request_resize_window(u64 page_id, Gfx::IntSize size)
|
void WebContentClient::did_request_resize_window(u64 page_id, Gfx::IntSize size)
|
||||||
{
|
{
|
||||||
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||||
if (view->on_resize_window)
|
if (view->on_resize_window)
|
||||||
return view->on_resize_window(size);
|
view->on_resize_window(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Gfx::IntSize {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Messages::WebContentClient::DidRequestMaximizeWindowResponse WebContentClient::did_request_maximize_window(u64 page_id)
|
Messages::WebContentClient::DidRequestMaximizeWindowResponse WebContentClient::did_request_maximize_window(u64 page_id)
|
||||||
|
|
|
@ -100,8 +100,8 @@ private:
|
||||||
virtual void did_close_browsing_context(u64 page_id) override;
|
virtual void did_close_browsing_context(u64 page_id) override;
|
||||||
virtual void did_update_resource_count(u64 page_id, i32 count_waiting) override;
|
virtual void did_update_resource_count(u64 page_id, i32 count_waiting) override;
|
||||||
virtual void did_request_restore_window(u64 page_id) override;
|
virtual void did_request_restore_window(u64 page_id) override;
|
||||||
virtual Messages::WebContentClient::DidRequestRepositionWindowResponse did_request_reposition_window(u64 page_id, Gfx::IntPoint) override;
|
virtual void did_request_reposition_window(u64 page_id, Gfx::IntPoint) override;
|
||||||
virtual Messages::WebContentClient::DidRequestResizeWindowResponse did_request_resize_window(u64 page_id, Gfx::IntSize) override;
|
virtual void did_request_resize_window(u64 page_id, Gfx::IntSize) override;
|
||||||
virtual Messages::WebContentClient::DidRequestMaximizeWindowResponse did_request_maximize_window(u64 page_id) override;
|
virtual Messages::WebContentClient::DidRequestMaximizeWindowResponse did_request_maximize_window(u64 page_id) override;
|
||||||
virtual Messages::WebContentClient::DidRequestMinimizeWindowResponse did_request_minimize_window(u64 page_id) override;
|
virtual Messages::WebContentClient::DidRequestMinimizeWindowResponse did_request_minimize_window(u64 page_id) override;
|
||||||
virtual Messages::WebContentClient::DidRequestFullscreenWindowResponse did_request_fullscreen_window(u64 page_id) override;
|
virtual Messages::WebContentClient::DidRequestFullscreenWindowResponse did_request_fullscreen_window(u64 page_id) override;
|
||||||
|
|
|
@ -1082,6 +1082,12 @@ void ConnectionFromClient::set_window_size(u64 page_id, Web::DevicePixelSize siz
|
||||||
page->set_window_size(size);
|
page->set_window_size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnectionFromClient::did_update_window_rect(u64 page_id)
|
||||||
|
{
|
||||||
|
if (auto page = this->page(page_id); page.has_value())
|
||||||
|
page->page().did_update_window_rect();
|
||||||
|
}
|
||||||
|
|
||||||
Messages::WebContentServer::GetLocalStorageEntriesResponse ConnectionFromClient::get_local_storage_entries(u64 page_id)
|
Messages::WebContentServer::GetLocalStorageEntriesResponse ConnectionFromClient::get_local_storage_entries(u64 page_id)
|
||||||
{
|
{
|
||||||
auto page = this->page(page_id);
|
auto page = this->page(page_id);
|
||||||
|
|
|
@ -103,6 +103,7 @@ private:
|
||||||
virtual void set_device_pixels_per_css_pixel(u64 page_id, float) override;
|
virtual void set_device_pixels_per_css_pixel(u64 page_id, float) override;
|
||||||
virtual void set_window_position(u64 page_id, Web::DevicePixelPoint) override;
|
virtual void set_window_position(u64 page_id, Web::DevicePixelPoint) override;
|
||||||
virtual void set_window_size(u64 page_id, Web::DevicePixelSize) override;
|
virtual void set_window_size(u64 page_id, Web::DevicePixelSize) override;
|
||||||
|
virtual void did_update_window_rect(u64 page_id) override;
|
||||||
virtual void handle_file_return(u64 page_id, i32 error, Optional<IPC::File> const& file, i32 request_id) override;
|
virtual void handle_file_return(u64 page_id, i32 error, Optional<IPC::File> const& file, i32 request_id) override;
|
||||||
virtual void set_system_visibility_state(u64 page_id, bool visible) override;
|
virtual void set_system_visibility_state(u64 page_id, bool visible) override;
|
||||||
|
|
||||||
|
|
|
@ -261,14 +261,14 @@ void PageClient::page_did_request_refresh()
|
||||||
client().async_did_request_refresh(m_id);
|
client().async_did_request_refresh(m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::IntSize PageClient::page_did_request_resize_window(Gfx::IntSize size)
|
void PageClient::page_did_request_resize_window(Gfx::IntSize size)
|
||||||
{
|
{
|
||||||
return client().did_request_resize_window(m_id, size);
|
client().async_did_request_resize_window(m_id, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::IntPoint PageClient::page_did_request_reposition_window(Gfx::IntPoint position)
|
void PageClient::page_did_request_reposition_window(Gfx::IntPoint position)
|
||||||
{
|
{
|
||||||
return client().did_request_reposition_window(m_id, position);
|
client().async_did_request_reposition_window(m_id, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageClient::page_did_request_restore_window()
|
void PageClient::page_did_request_restore_window()
|
||||||
|
|
|
@ -112,8 +112,8 @@ private:
|
||||||
virtual void page_did_request_navigate_back() override;
|
virtual void page_did_request_navigate_back() override;
|
||||||
virtual void page_did_request_navigate_forward() override;
|
virtual void page_did_request_navigate_forward() override;
|
||||||
virtual void page_did_request_refresh() override;
|
virtual void page_did_request_refresh() override;
|
||||||
virtual Gfx::IntSize page_did_request_resize_window(Gfx::IntSize) override;
|
virtual void page_did_request_resize_window(Gfx::IntSize) override;
|
||||||
virtual Gfx::IntPoint page_did_request_reposition_window(Gfx::IntPoint) override;
|
virtual void page_did_request_reposition_window(Gfx::IntPoint) override;
|
||||||
virtual void page_did_request_restore_window() override;
|
virtual void page_did_request_restore_window() override;
|
||||||
virtual Gfx::IntRect page_did_request_maximize_window() override;
|
virtual Gfx::IntRect page_did_request_maximize_window() override;
|
||||||
virtual Gfx::IntRect page_did_request_minimize_window() override;
|
virtual Gfx::IntRect page_did_request_minimize_window() override;
|
||||||
|
|
|
@ -77,8 +77,8 @@ endpoint WebContentClient
|
||||||
did_request_activate_tab(u64 page_id) =|
|
did_request_activate_tab(u64 page_id) =|
|
||||||
did_close_browsing_context(u64 page_id) =|
|
did_close_browsing_context(u64 page_id) =|
|
||||||
did_request_restore_window(u64 page_id) =|
|
did_request_restore_window(u64 page_id) =|
|
||||||
did_request_reposition_window(u64 page_id, Gfx::IntPoint position) => (Gfx::IntPoint window_position)
|
did_request_reposition_window(u64 page_id, Gfx::IntPoint position) =|
|
||||||
did_request_resize_window(u64 page_id, Gfx::IntSize size) => (Gfx::IntSize window_size)
|
did_request_resize_window(u64 page_id, Gfx::IntSize size) =|
|
||||||
did_request_maximize_window(u64 page_id) => (Gfx::IntRect window_rect)
|
did_request_maximize_window(u64 page_id) => (Gfx::IntRect window_rect)
|
||||||
did_request_minimize_window(u64 page_id) => (Gfx::IntRect window_rect)
|
did_request_minimize_window(u64 page_id) => (Gfx::IntRect window_rect)
|
||||||
did_request_fullscreen_window(u64 page_id) => (Gfx::IntRect window_rect)
|
did_request_fullscreen_window(u64 page_id) => (Gfx::IntRect window_rect)
|
||||||
|
|
|
@ -90,6 +90,7 @@ endpoint WebContentServer
|
||||||
|
|
||||||
set_window_position(u64 page_id, Web::DevicePixelPoint position) =|
|
set_window_position(u64 page_id, Web::DevicePixelPoint position) =|
|
||||||
set_window_size(u64 page_id, Web::DevicePixelSize size) =|
|
set_window_size(u64 page_id, Web::DevicePixelSize size) =|
|
||||||
|
did_update_window_rect(u64 page_id) =|
|
||||||
|
|
||||||
get_local_storage_entries(u64 page_id) => (OrderedHashMap<String, String> entries)
|
get_local_storage_entries(u64 page_id) => (OrderedHashMap<String, String> entries)
|
||||||
get_session_storage_entries(u64 page_id) => (OrderedHashMap<String, String> entries)
|
get_session_storage_entries(u64 page_id) => (OrderedHashMap<String, String> entries)
|
||||||
|
|
|
@ -647,10 +647,11 @@ Messages::WebDriverClient::SetWindowRectResponse WebDriverConnection::set_window
|
||||||
|
|
||||||
auto const& properties = payload.as_object();
|
auto const& properties = payload.as_object();
|
||||||
|
|
||||||
auto resolve_property = [](auto name, auto const& property, i32 min, i32 max) -> ErrorOr<Optional<i32>, Web::WebDriver::Error> {
|
auto resolve_property = [](auto name, auto const& property, double min, double max) -> ErrorOr<Optional<double>, Web::WebDriver::Error> {
|
||||||
if (property.is_null())
|
if (property.is_null())
|
||||||
return Optional<i32> {};
|
return OptionalNone {};
|
||||||
auto value = property.template get_integer<i32>();
|
|
||||||
|
auto value = property.get_double_with_precision_loss();
|
||||||
if (!value.has_value())
|
if (!value.has_value())
|
||||||
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not a Number", name));
|
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not a Number", name));
|
||||||
if (*value < min)
|
if (*value < min)
|
||||||
|
@ -694,29 +695,28 @@ Messages::WebDriverClient::SetWindowRectResponse WebDriverConnection::set_window
|
||||||
// 11. Restore the window.
|
// 11. Restore the window.
|
||||||
restore_the_window();
|
restore_the_window();
|
||||||
|
|
||||||
Gfx::IntRect window_rect;
|
auto& page = current_top_level_browsing_context()->page();
|
||||||
|
|
||||||
// 11. If width and height are not null:
|
// 11. If width and height are not null:
|
||||||
if (width.has_value() && height.has_value()) {
|
if (width.has_value() && height.has_value()) {
|
||||||
// a. Set the width, in CSS pixels, of the operating system window containing the current top-level browsing context, including any browser chrome and externally drawn window decorations to a value that is as close as possible to width.
|
// a. Set the width, in CSS pixels, of the operating system window containing the current top-level browsing context, including any browser chrome and externally drawn window decorations to a value that is as close as possible to width.
|
||||||
// b. Set the height, in CSS pixels, of the operating system window containing the current top-level browsing context, including any browser chrome and externally drawn window decorations to a value that is as close as possible to height.
|
// b. Set the height, in CSS pixels, of the operating system window containing the current top-level browsing context, including any browser chrome and externally drawn window decorations to a value that is as close as possible to height.
|
||||||
auto size = current_top_level_browsing_context()->page().client().page_did_request_resize_window({ *width, *height });
|
page.client().page_did_request_resize_window({ *width, *height });
|
||||||
window_rect.set_size(size);
|
++m_pending_window_rect_requests;
|
||||||
} else {
|
|
||||||
window_rect.set_size(current_top_level_browsing_context()->page().window_size().to_type<int>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12. If x and y are not null:
|
// 12. If x and y are not null:
|
||||||
if (x.has_value() && y.has_value()) {
|
if (x.has_value() && y.has_value()) {
|
||||||
// a. Run the implementation-specific steps to set the position of the operating system level window containing the current top-level browsing context to the position given by the x and y coordinates.
|
// a. Run the implementation-specific steps to set the position of the operating system level window containing the current top-level browsing context to the position given by the x and y coordinates.
|
||||||
auto position = current_top_level_browsing_context()->page().client().page_did_request_reposition_window({ *x, *y });
|
page.client().page_did_request_reposition_window({ *x, *y });
|
||||||
window_rect.set_location(position);
|
++m_pending_window_rect_requests;
|
||||||
} else {
|
|
||||||
window_rect.set_location(current_top_level_browsing_context()->page().window_position().to_type<int>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_pending_window_rect_requests == 0)
|
||||||
|
async_window_rect_updated(serialize_rect(compute_window_rect(page)));
|
||||||
|
|
||||||
// 14. Return success with data set to the WindowRect object for the current top-level browsing context.
|
// 14. Return success with data set to the WindowRect object for the current top-level browsing context.
|
||||||
return serialize_rect(window_rect);
|
return JsonValue {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11.8.3 Maximize Window, https://w3c.github.io/webdriver/#dfn-maximize-window
|
// 11.8.3 Maximize Window, https://w3c.github.io/webdriver/#dfn-maximize-window
|
||||||
|
@ -2340,9 +2340,19 @@ void WebDriverConnection::set_current_top_level_browsing_context(Web::HTML::Brow
|
||||||
// 1. Assert: context is a top-level browsing context.
|
// 1. Assert: context is a top-level browsing context.
|
||||||
VERIFY(browsing_context.is_top_level());
|
VERIFY(browsing_context.is_top_level());
|
||||||
|
|
||||||
|
if (m_current_top_level_browsing_context)
|
||||||
|
m_current_top_level_browsing_context->page().set_window_rect_observer({});
|
||||||
|
|
||||||
// 2. Set session's current top-level browsing context to context.
|
// 2. Set session's current top-level browsing context to context.
|
||||||
m_current_top_level_browsing_context = browsing_context;
|
m_current_top_level_browsing_context = browsing_context;
|
||||||
|
|
||||||
|
if (m_current_top_level_browsing_context) {
|
||||||
|
m_current_top_level_browsing_context->page().set_window_rect_observer(JS::create_heap_function(m_current_top_level_browsing_context->heap(), [this](Web::DevicePixelRect rect) {
|
||||||
|
if (m_pending_window_rect_requests > 0 && --m_pending_window_rect_requests == 0)
|
||||||
|
async_window_rect_updated(serialize_rect(rect.to_type<int>()));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Set the current browsing context with session and context.
|
// 3. Set the current browsing context with session and context.
|
||||||
set_current_browsing_context(browsing_context);
|
set_current_browsing_context(browsing_context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,8 @@ private:
|
||||||
// https://w3c.github.io/webdriver/#dfn-current-top-level-browsing-context
|
// https://w3c.github.io/webdriver/#dfn-current-top-level-browsing-context
|
||||||
JS::GCPtr<Web::HTML::BrowsingContext> m_current_top_level_browsing_context;
|
JS::GCPtr<Web::HTML::BrowsingContext> m_current_top_level_browsing_context;
|
||||||
|
|
||||||
|
size_t m_pending_window_rect_requests { 0 };
|
||||||
|
|
||||||
JS::GCPtr<JS::Cell> m_action_executor;
|
JS::GCPtr<JS::Cell> m_action_executor;
|
||||||
|
|
||||||
JS::GCPtr<Web::DOM::DocumentObserver> m_document_observer;
|
JS::GCPtr<Web::DOM::DocumentObserver> m_document_observer;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
endpoint WebDriverServer {
|
endpoint WebDriverServer {
|
||||||
navigation_complete(Web::WebDriver::Response response) =|
|
navigation_complete(Web::WebDriver::Response response) =|
|
||||||
|
window_rect_updated(Web::WebDriver::Response response) =|
|
||||||
script_executed(Web::WebDriver::Response response) =|
|
script_executed(Web::WebDriver::Response response) =|
|
||||||
actions_performed(Web::WebDriver::Response response) =|
|
actions_performed(Web::WebDriver::Response response) =|
|
||||||
dialog_closed(Web::WebDriver::Response response) =|
|
dialog_closed(Web::WebDriver::Response response) =|
|
||||||
|
|
|
@ -397,7 +397,7 @@ Web::WebDriver::Response Client::set_window_rect(Web::WebDriver::Parameters para
|
||||||
{
|
{
|
||||||
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/window/rect");
|
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/window/rect");
|
||||||
auto session = TRY(find_session_with_id(parameters[0]));
|
auto session = TRY(find_session_with_id(parameters[0]));
|
||||||
return session->web_content_connection().set_window_rect(payload);
|
return session->set_window_rect(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11.8.3 Maximize Window, https://w3c.github.io/webdriver/#dfn-maximize-window
|
// 11.8.3 Maximize Window, https://w3c.github.io/webdriver/#dfn-maximize-window
|
||||||
|
|
|
@ -209,6 +209,13 @@ Web::WebDriver::Response Session::navigate_to(JsonValue payload) const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Web::WebDriver::Response Session::set_window_rect(JsonValue payload) const
|
||||||
|
{
|
||||||
|
return perform_async_action(web_content_connection().on_window_rect_updated, [&]() {
|
||||||
|
return web_content_connection().set_window_rect(move(payload));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Web::WebDriver::Response Session::execute_script(JsonValue payload, ScriptMode mode) const
|
Web::WebDriver::Response Session::execute_script(JsonValue payload, ScriptMode mode) const
|
||||||
{
|
{
|
||||||
return perform_async_action(web_content_connection().on_script_executed, [&]() {
|
return perform_async_action(web_content_connection().on_script_executed, [&]() {
|
||||||
|
|
|
@ -65,6 +65,8 @@ public:
|
||||||
};
|
};
|
||||||
Web::WebDriver::Response execute_script(JsonValue, ScriptMode) const;
|
Web::WebDriver::Response execute_script(JsonValue, ScriptMode) const;
|
||||||
|
|
||||||
|
Web::WebDriver::Response set_window_rect(JsonValue) const;
|
||||||
|
|
||||||
Web::WebDriver::Response element_click(String) const;
|
Web::WebDriver::Response element_click(String) const;
|
||||||
Web::WebDriver::Response element_send_keys(String, JsonValue) const;
|
Web::WebDriver::Response element_send_keys(String, JsonValue) const;
|
||||||
Web::WebDriver::Response perform_actions(JsonValue) const;
|
Web::WebDriver::Response perform_actions(JsonValue) const;
|
||||||
|
|
|
@ -26,6 +26,12 @@ void WebContentConnection::navigation_complete(Web::WebDriver::Response const& r
|
||||||
on_navigation_complete(response);
|
on_navigation_complete(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContentConnection::window_rect_updated(Web::WebDriver::Response const& response)
|
||||||
|
{
|
||||||
|
if (on_window_rect_updated)
|
||||||
|
on_window_rect_updated(response);
|
||||||
|
}
|
||||||
|
|
||||||
void WebContentConnection::script_executed(Web::WebDriver::Response const& response)
|
void WebContentConnection::script_executed(Web::WebDriver::Response const& response)
|
||||||
{
|
{
|
||||||
if (on_script_executed)
|
if (on_script_executed)
|
||||||
|
|
|
@ -23,6 +23,7 @@ public:
|
||||||
|
|
||||||
Function<void()> on_close;
|
Function<void()> on_close;
|
||||||
Function<void(Web::WebDriver::Response)> on_navigation_complete;
|
Function<void(Web::WebDriver::Response)> on_navigation_complete;
|
||||||
|
Function<void(Web::WebDriver::Response)> on_window_rect_updated;
|
||||||
Function<void(Web::WebDriver::Response)> on_script_executed;
|
Function<void(Web::WebDriver::Response)> on_script_executed;
|
||||||
Function<void(Web::WebDriver::Response)> on_actions_performed;
|
Function<void(Web::WebDriver::Response)> on_actions_performed;
|
||||||
Function<void(Web::WebDriver::Response)> on_dialog_closed;
|
Function<void(Web::WebDriver::Response)> on_dialog_closed;
|
||||||
|
@ -31,6 +32,7 @@ private:
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
||||||
virtual void navigation_complete(Web::WebDriver::Response const&) override;
|
virtual void navigation_complete(Web::WebDriver::Response const&) override;
|
||||||
|
virtual void window_rect_updated(Web::WebDriver::Response const&) override;
|
||||||
virtual void script_executed(Web::WebDriver::Response const&) override;
|
virtual void script_executed(Web::WebDriver::Response const&) override;
|
||||||
virtual void actions_performed(Web::WebDriver::Response const&) override;
|
virtual void actions_performed(Web::WebDriver::Response const&) override;
|
||||||
virtual void dialog_closed(Web::WebDriver::Response const&) override;
|
virtual void dialog_closed(Web::WebDriver::Response const&) override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue