From 5aac9a28bb9f257c5e1c737bdaa8709be3edbf89 Mon Sep 17 00:00:00 2001 From: Alan Griffiths Date: Fri, 23 Mar 2018 11:33:04 +0000 Subject: [PATCH 1/5] Sequence xdg-top-level and xdg-surface configure events correctly. --- src/server/frontend_wayland/wl_surface_role.h | 2 +- src/server/frontend_wayland/xdg_shell_v6.cpp | 29 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/server/frontend_wayland/wl_surface_role.h b/src/server/frontend_wayland/wl_surface_role.h index 2cde49121f9..b8fc989d2a4 100644 --- a/src/server/frontend_wayland/wl_surface_role.h +++ b/src/server/frontend_wayland/wl_surface_role.h @@ -81,12 +81,12 @@ class WlAbstractMirWindow : public WlSurfaceRole geometry::Size window_size(); shell::SurfaceSpecification& spec(); + void commit(WlSurfaceState const& state) override; private: std::unique_ptr pending_changes; bool buffer_list_needs_refresh = true; - void commit(WlSurfaceState const& state) override; void visiblity(bool visible) override; }; diff --git a/src/server/frontend_wayland/xdg_shell_v6.cpp b/src/server/frontend_wayland/xdg_shell_v6.cpp index 69f85a255f9..29f23669d6d 100644 --- a/src/server/frontend_wayland/xdg_shell_v6.cpp +++ b/src/server/frontend_wayland/xdg_shell_v6.cpp @@ -57,12 +57,14 @@ class XdgSurfaceV6 : wayland::XdgSurfaceV6, WlAbstractMirWindow void get_popup(uint32_t id, struct wl_resource* parent, struct wl_resource* positioner) override; void set_window_geometry(int32_t x, int32_t y, int32_t width, int32_t height) override; void ack_configure(uint32_t serial) override; + void commit(WlSurfaceState const& state) override; void set_parent(optional_value parent_id); void set_title(std::string const& title); void move(struct wl_resource* seat, uint32_t serial); void resize(struct wl_resource* /*seat*/, uint32_t /*serial*/, uint32_t edges); void set_notify_resize(std::function notify_resize); + void on_next_commit(std::function deferred); void set_max_size(int32_t width, int32_t height); void set_min_size(int32_t width, int32_t height); void set_maximized(); @@ -75,6 +77,7 @@ class XdgSurfaceV6 : wayland::XdgSurfaceV6, WlAbstractMirWindow struct wl_resource* const parent; std::shared_ptr const shell; std::shared_ptr const sink; + std::function commit_action{[]{}}; }; class XdgSurfaceV6EventSink : public BasicSurfaceEventSink @@ -433,6 +436,20 @@ void mf::XdgSurfaceV6::unset_maximized() } } +void mir::frontend::XdgSurfaceV6::on_next_commit(std::function deferred) +{ + commit_action = deferred; +} + +void mir::frontend::XdgSurfaceV6::commit(mir::frontend::WlSurfaceState const& state) +{ + WlAbstractMirWindow::commit(state); + auto const serial = wl_display_next_serial(wl_client_get_display(client)); + commit_action(); + commit_action = []{}; + zxdg_surface_v6_send_configure(event_sink, serial); +} + // XdgSurfaceV6EventSink mf::XdgSurfaceV6EventSink::XdgSurfaceV6EventSink(WlSeat* seat, wl_client* client, wl_resource* target, @@ -440,8 +457,6 @@ mf::XdgSurfaceV6EventSink::XdgSurfaceV6EventSink(WlSeat* seat, wl_client* client : BasicSurfaceEventSink(seat, client, target, event_sink), destroyed{destroyed} { - auto const serial = wl_display_next_serial(wl_client_get_display(client)); - post_configure(serial); } void mf::XdgSurfaceV6EventSink::send_resize(geometry::Size const& new_size) const @@ -490,6 +505,8 @@ mf::XdgToplevelV6::XdgToplevelV6(struct wl_client* client, struct wl_resource* p self->set_notify_resize( [this](geom::Size const& new_size, MirWindowState state, bool active) { + this->self->on_next_commit([]{}); + wl_array states; wl_array_init(&states); @@ -521,6 +538,14 @@ mf::XdgToplevelV6::XdgToplevelV6(struct wl_client* client, struct wl_resource* p wl_array_release(&states); }); + + self->on_next_commit([resource=this->resource] + { + wl_array states; + wl_array_init(&states); + zxdg_toplevel_v6_send_configure(resource, 0, 0, &states); + wl_array_release(&states); + }); } void mf::XdgToplevelV6::destroy() From 7373b7bf18c9009031359a0ac04ed800f6098195 Mon Sep 17 00:00:00 2001 From: Alan Griffiths Date: Fri, 23 Mar 2018 13:36:23 +0000 Subject: [PATCH 2/5] Don't send too many zxdg_surface_v6 "configure" events. --- src/server/frontend_wayland/xdg_shell_v6.cpp | 29 ++++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/server/frontend_wayland/xdg_shell_v6.cpp b/src/server/frontend_wayland/xdg_shell_v6.cpp index 29f23669d6d..317431cf019 100644 --- a/src/server/frontend_wayland/xdg_shell_v6.cpp +++ b/src/server/frontend_wayland/xdg_shell_v6.cpp @@ -65,6 +65,7 @@ class XdgSurfaceV6 : wayland::XdgSurfaceV6, WlAbstractMirWindow void resize(struct wl_resource* /*seat*/, uint32_t /*serial*/, uint32_t edges); void set_notify_resize(std::function notify_resize); void on_next_commit(std::function deferred); + void clear_on_next_commit(); void set_max_size(int32_t width, int32_t height); void set_min_size(int32_t width, int32_t height); void set_maximized(); @@ -94,8 +95,6 @@ class XdgSurfaceV6EventSink : public BasicSurfaceEventSink [](auto, auto, auto){}; private: - void post_configure(int serial) const; - std::shared_ptr const destroyed; }; @@ -436,18 +435,26 @@ void mf::XdgSurfaceV6::unset_maximized() } } +void mir::frontend::XdgSurfaceV6::clear_on_next_commit() +{ + commit_action = []{}; +} + void mir::frontend::XdgSurfaceV6::on_next_commit(std::function deferred) { - commit_action = deferred; + commit_action = [this, deferred] + { + deferred(); + auto const serial = wl_display_next_serial(wl_client_get_display(client)); + zxdg_surface_v6_send_configure(event_sink, serial); + }; } void mir::frontend::XdgSurfaceV6::commit(mir::frontend::WlSurfaceState const& state) { WlAbstractMirWindow::commit(state); - auto const serial = wl_display_next_serial(wl_client_get_display(client)); commit_action(); commit_action = []{}; - zxdg_surface_v6_send_configure(event_sink, serial); } // XdgSurfaceV6EventSink @@ -469,14 +476,6 @@ void mf::XdgSurfaceV6EventSink::send_resize(geometry::Size const& new_size) cons })); } -void mf::XdgSurfaceV6EventSink::post_configure(int serial) const -{ - seat->spawn(run_unless(destroyed, [event_sink= event_sink, serial]() - { - zxdg_surface_v6_send_configure(event_sink, serial); - })); -} - // XdgPopupV6 mf::XdgPopupV6::XdgPopupV6(struct wl_client* client, struct wl_resource* parent, uint32_t id) @@ -505,7 +504,7 @@ mf::XdgToplevelV6::XdgToplevelV6(struct wl_client* client, struct wl_resource* p self->set_notify_resize( [this](geom::Size const& new_size, MirWindowState state, bool active) { - this->self->on_next_commit([]{}); + this->self->clear_on_next_commit(); wl_array states; wl_array_init(&states); @@ -539,7 +538,7 @@ mf::XdgToplevelV6::XdgToplevelV6(struct wl_client* client, struct wl_resource* p wl_array_release(&states); }); - self->on_next_commit([resource=this->resource] + self->on_next_commit([resource=this->resource, self] { wl_array states; wl_array_init(&states); From fa87114cef115eadb9852c3b97a4515dcac65a09 Mon Sep 17 00:00:00 2001 From: Alan Griffiths Date: Fri, 23 Mar 2018 14:59:05 +0000 Subject: [PATCH 3/5] Better names --- src/server/frontend_wayland/xdg_shell_v6.cpp | 37 ++++++++++---------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/server/frontend_wayland/xdg_shell_v6.cpp b/src/server/frontend_wayland/xdg_shell_v6.cpp index 317431cf019..30ff022188c 100644 --- a/src/server/frontend_wayland/xdg_shell_v6.cpp +++ b/src/server/frontend_wayland/xdg_shell_v6.cpp @@ -64,8 +64,8 @@ class XdgSurfaceV6 : wayland::XdgSurfaceV6, WlAbstractMirWindow void move(struct wl_resource* seat, uint32_t serial); void resize(struct wl_resource* /*seat*/, uint32_t /*serial*/, uint32_t edges); void set_notify_resize(std::function notify_resize); - void on_next_commit(std::function deferred); - void clear_on_next_commit(); + void set_next_commit_action(std::function action); + void clear_next_commit_action(); void set_max_size(int32_t width, int32_t height); void set_min_size(int32_t width, int32_t height); void set_maximized(); @@ -78,7 +78,7 @@ class XdgSurfaceV6 : wayland::XdgSurfaceV6, WlAbstractMirWindow struct wl_resource* const parent; std::shared_ptr const shell; std::shared_ptr const sink; - std::function commit_action{[]{}}; + std::function next_commit_action{[]{}}; }; class XdgSurfaceV6EventSink : public BasicSurfaceEventSink @@ -435,16 +435,16 @@ void mf::XdgSurfaceV6::unset_maximized() } } -void mir::frontend::XdgSurfaceV6::clear_on_next_commit() +void mir::frontend::XdgSurfaceV6::clear_next_commit_action() { - commit_action = []{}; + next_commit_action = []{}; } -void mir::frontend::XdgSurfaceV6::on_next_commit(std::function deferred) +void mir::frontend::XdgSurfaceV6::set_next_commit_action(std::function action) { - commit_action = [this, deferred] + next_commit_action = [this, action] { - deferred(); + action(); auto const serial = wl_display_next_serial(wl_client_get_display(client)); zxdg_surface_v6_send_configure(event_sink, serial); }; @@ -453,8 +453,8 @@ void mir::frontend::XdgSurfaceV6::on_next_commit(std::function deferred) void mir::frontend::XdgSurfaceV6::commit(mir::frontend::WlSurfaceState const& state) { WlAbstractMirWindow::commit(state); - commit_action(); - commit_action = []{}; + next_commit_action(); + clear_next_commit_action(); } // XdgSurfaceV6EventSink @@ -504,7 +504,7 @@ mf::XdgToplevelV6::XdgToplevelV6(struct wl_client* client, struct wl_resource* p self->set_notify_resize( [this](geom::Size const& new_size, MirWindowState state, bool active) { - this->self->clear_on_next_commit(); + this->self->clear_next_commit_action(); wl_array states; wl_array_init(&states); @@ -538,13 +538,14 @@ mf::XdgToplevelV6::XdgToplevelV6(struct wl_client* client, struct wl_resource* p wl_array_release(&states); }); - self->on_next_commit([resource=this->resource, self] - { - wl_array states; - wl_array_init(&states); - zxdg_toplevel_v6_send_configure(resource, 0, 0, &states); - wl_array_release(&states); - }); + self->set_next_commit_action( + [resource = this->resource, self] + { + wl_array states; + wl_array_init(&states); + zxdg_toplevel_v6_send_configure(resource, 0, 0, &states); + wl_array_release(&states); + }); } void mf::XdgToplevelV6::destroy() From 2a030b792f44c755bbb83f15dc4ac28774df5a4a Mon Sep 17 00:00:00 2001 From: Alan Griffiths Date: Fri, 23 Mar 2018 17:29:43 +0000 Subject: [PATCH 4/5] Fix menus --- src/server/frontend_wayland/xdg_shell_v6.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/server/frontend_wayland/xdg_shell_v6.cpp b/src/server/frontend_wayland/xdg_shell_v6.cpp index 30ff022188c..4b96a9afd1b 100644 --- a/src/server/frontend_wayland/xdg_shell_v6.cpp +++ b/src/server/frontend_wayland/xdg_shell_v6.cpp @@ -101,7 +101,7 @@ class XdgSurfaceV6EventSink : public BasicSurfaceEventSink class XdgPopupV6 : wayland::XdgPopupV6 { public: - XdgPopupV6(struct wl_client* client, struct wl_resource* parent, uint32_t id); + XdgPopupV6(struct wl_client* client, struct wl_resource* parent, uint32_t id, XdgSurfaceV6* self); void grab(struct wl_resource* seat, uint32_t serial) override; void destroy() override; @@ -244,7 +244,7 @@ void mf::XdgSurfaceV6::get_popup(uint32_t id, struct wl_resource* parent, struct params->aux_rect_placement_offset_y = pos->aux_rect_placement_offset_y; params->placement_hints = mir_placement_hints_slide_any; - new XdgPopupV6{client, parent, id}; + new XdgPopupV6{client, parent, id, this}; surface->set_role(this); } @@ -478,9 +478,13 @@ void mf::XdgSurfaceV6EventSink::send_resize(geometry::Size const& new_size) cons // XdgPopupV6 -mf::XdgPopupV6::XdgPopupV6(struct wl_client* client, struct wl_resource* parent, uint32_t id) +mf::XdgPopupV6::XdgPopupV6(struct wl_client* client, struct wl_resource* parent, uint32_t id, XdgSurfaceV6* self) : wayland::XdgPopupV6(client, parent, id) -{} +{ + // TODO Make this readable!!! This "works" by exploiting the non-obvious side-effect + // of causing a zxdg_surface_v6_send_configure() event to become pending. + self->set_next_commit_action([]{}); +} void mf::XdgPopupV6::grab(struct wl_resource* seat, uint32_t serial) { From a9f044c64101692ebf1b5d95d6643a246bce6245 Mon Sep 17 00:00:00 2001 From: Alan Griffiths Date: Fri, 23 Mar 2018 17:31:22 +0000 Subject: [PATCH 5/5] Remove workaround --- .../frontend_wayland/wl_surface_role.cpp | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/server/frontend_wayland/wl_surface_role.cpp b/src/server/frontend_wayland/wl_surface_role.cpp index ed59a9af58a..d409390084f 100644 --- a/src/server/frontend_wayland/wl_surface_role.cpp +++ b/src/server/frontend_wayland/wl_surface_role.cpp @@ -139,27 +139,7 @@ void WlAbstractMirWindow::commit(WlSurfaceState const& state) geometry::Size WlAbstractMirWindow::window_size() { - if (window_size_.is_set()) - { - return window_size_.value(); - } - else - { - auto buffer_size = surface->buffer_size(); - - // Sometimes, when using xdg-shell, qterminal creates an insanely tall buffer - const auto max_allowed_buffer_height = geometry::Height{10000}; - const auto corrected_buffer_height = geometry::Height{1000}; - - if (buffer_size.height > max_allowed_buffer_height) - { - log_warning("Insane buffer height sanitized: buffer_size.height = %d (was %d)", - corrected_buffer_height.as_int(), buffer_size.height.as_int()); - buffer_size.height = corrected_buffer_height; - } - - return buffer_size; - } + return window_size_.is_set()? window_size_.value() : surface->buffer_size(); } void WlAbstractMirWindow::visiblity(bool visible)