From 7d0351b41195671263a92997caab620c763d9d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baltaz=C3=A1r=20Radics?= Date: Mon, 6 Feb 2023 10:52:51 +0100 Subject: [PATCH 1/7] ipc: add ability to subscribe to output event --- sway/ipc-server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 2941ee76b..9692a77fd 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -739,6 +739,8 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt const char *event_type = json_object_get_string(json_object_array_get_idx(request, i)); if (strcmp(event_type, "workspace") == 0) { client->subscribed_events |= event_mask(IPC_EVENT_WORKSPACE); + } else if (strcmp(event_type, "output") == 0) { + client->subscribed_events |= event_mask(IPC_EVENT_OUTPUT); } else if (strcmp(event_type, "barconfig_update") == 0) { client->subscribed_events |= event_mask(IPC_EVENT_BARCONFIG_UPDATE); } else if (strcmp(event_type, "bar_state_update") == 0) { From b4ce0a30c1d8d7f2af82f4da5858c1379f8399a1 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 7 Feb 2023 19:25:38 +0100 Subject: [PATCH 2/7] Use wlr_linux_dmabuf_feedback_v1_init_with_options() References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3933 Closes: https://github.com/swaywm/sway/issues/7436 Closes: https://github.com/swaywm/sway/pull/7437 --- sway/tree/container.c | 72 +++++-------------------------------------- 1 file changed, 8 insertions(+), 64 deletions(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index dbe880287..fa76dd6aa 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -3,14 +3,10 @@ #include #include #include -#include -#include -#include #include #include #include #include -#include #include "linux-dmabuf-unstable-v1-protocol.h" #include "cairo_util.h" #include "pango.h" @@ -1060,16 +1056,6 @@ void container_end_mouse_operation(struct sway_container *container) { } } -static bool devid_from_fd(int fd, dev_t *devid) { - struct stat stat; - if (fstat(fd, &stat) != 0) { - sway_log_errno(SWAY_ERROR, "fstat failed"); - return false; - } - *devid = stat.st_rdev; - return true; -} - static void set_fullscreen(struct sway_container *con, bool enable) { if (!con->view) { return; @@ -1096,60 +1082,18 @@ static void set_fullscreen(struct sway_container *con, bool enable) { } struct sway_output *output = con->pending.workspace->output; - struct wlr_output *wlr_output = output->wlr_output; - // TODO: add wlroots helpers for all of this stuff - - const struct wlr_drm_format_set *renderer_formats = - wlr_renderer_get_dmabuf_texture_formats(server.renderer); - assert(renderer_formats); - - int renderer_drm_fd = wlr_renderer_get_drm_fd(server.renderer); - int backend_drm_fd = wlr_backend_get_drm_fd(wlr_output->backend); - if (renderer_drm_fd < 0 || backend_drm_fd < 0) { - return; - } - - dev_t render_dev, scanout_dev; - if (!devid_from_fd(renderer_drm_fd, &render_dev) || - !devid_from_fd(backend_drm_fd, &scanout_dev)) { - return; - } - - const struct wlr_drm_format_set *output_formats = - wlr_output_get_primary_formats(output->wlr_output, - WLR_BUFFER_CAP_DMABUF); - if (!output_formats) { - return; - } - - struct wlr_drm_format_set scanout_formats = {0}; - if (!wlr_drm_format_set_intersect(&scanout_formats, - output_formats, renderer_formats)) { - return; - } - - struct wlr_linux_dmabuf_feedback_v1_tranche tranches[] = { - { - .target_device = scanout_dev, - .flags = ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT, - .formats = &scanout_formats, - }, - { - .target_device = render_dev, - .formats = renderer_formats, - }, - }; - - const struct wlr_linux_dmabuf_feedback_v1 feedback = { - .main_device = render_dev, - .tranches = tranches, - .tranches_len = sizeof(tranches) / sizeof(tranches[0]), + const struct wlr_linux_dmabuf_feedback_v1_init_options options = { + .main_renderer = server.renderer, + .scanout_primary_output = output->wlr_output, }; + struct wlr_linux_dmabuf_feedback_v1 feedback = {0}; + if (!wlr_linux_dmabuf_feedback_v1_init_with_options(&feedback, &options)) { + return; + } wlr_linux_dmabuf_v1_set_surface_feedback(server.linux_dmabuf_v1, con->view->surface, &feedback); - - wlr_drm_format_set_finish(&scanout_formats); + wlr_linux_dmabuf_feedback_v1_finish(&feedback); } static void container_fullscreen_workspace(struct sway_container *con) { From 1b27e8c8fdc413a061e8b003bcabfb7b789c6a90 Mon Sep 17 00:00:00 2001 From: Ronan Pigott Date: Thu, 9 Feb 2023 11:39:46 -0700 Subject: [PATCH 3/7] xdg-activation: fix urgency when the client does not specify a seat xdg-activation is now too strict in only allowing tokens with a seat to activate a surface. Clients may rely on this behavior for urgency hints. The seat argument is still useful in case the client does provide a seat so we can activate it on the desired seat. Fixes: 842609da6432 (view: make request_activate take a seat, 2022-11-30) --- sway/xdg_activation_v1.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sway/xdg_activation_v1.c b/sway/xdg_activation_v1.c index 614f51cdc..e97989c83 100644 --- a/sway/xdg_activation_v1.c +++ b/sway/xdg_activation_v1.c @@ -33,11 +33,8 @@ void xdg_activation_v1_handle_request_activate(struct wl_listener *listener, } struct wlr_seat *wlr_seat = event->token->seat; - // The requesting seat may have been destroyed. - if (wlr_seat) { - struct sway_seat *seat = wlr_seat->data; - view_request_activate(view, seat); - } + struct sway_seat *seat = wlr_seat ? wlr_seat->data : NULL; + view_request_activate(view, seat); } void xdg_activation_v1_handle_new_token(struct wl_listener *listener, void *data) { From fadfbe8dbae4b3a840cc05fcfe67d74f5050a878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Adamczak?= <14021+czak@users.noreply.github.com> Date: Sun, 5 Feb 2023 14:54:09 +0100 Subject: [PATCH 4/7] Correct window_rect.y with hide_edge_borders With `hide_edge_borders both` (or at least `vertical`), `window_rect.y` will equal `border_thickness` for SOME windows, but it will be 0 for windows adjacent to top screen edge. Therefore setting it to `border_thickness` is not sufficient. This commit changes it to the actual y offset of content into the container. --- sway/ipc-json.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 8aa9557e9..51e6a9951 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -577,7 +577,7 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object struct wlr_box window_box = { c->pending.content_x - c->pending.x, - (c->current.border == B_PIXEL) ? c->current.border_thickness : 0, + (c->current.border == B_PIXEL) ? c->pending.content_y - c->pending.y : 0, c->pending.content_width, c->pending.content_height }; From 8e4b6595786edf307623b9f1fcf3c7e5c8fa3833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Adamczak?= <14021+czak@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:13:54 +0100 Subject: [PATCH 5/7] Clarify documentation for window_rect --- sway/sway-ipc.7.scd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd index 2e903988d..42aaaab67 100644 --- a/sway/sway-ipc.7.scd +++ b/sway/sway-ipc.7.scd @@ -337,8 +337,9 @@ node and will have the following properties: this, but borders are included. |- window_rect : object -: The geometry of the contents inside the node. The window decorations are - excluded from this calculation, but borders are included. +: The geometry of the content inside the node. These coordinates are relative + to the node itself. Window decorations and borders are outside the + _window_rect_ |- deco_rect : object : The geometry of the decorations for the node relative to the parent node From 1cab17ada243385798b3340f88144f64ac33ee63 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 8 Feb 2023 15:25:14 +0100 Subject: [PATCH 6/7] Introduce surface_{enter,leave}_output() We can centralize all output-related surface events from there. --- include/sway/surface.h | 5 +++++ sway/desktop/layer_shell.c | 6 +++--- sway/desktop/surface.c | 11 +++++++++++ sway/lock.c | 3 ++- sway/tree/container.c | 13 +++++++------ sway/tree/view.c | 3 ++- 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/include/sway/surface.h b/include/sway/surface.h index fb1cd7758..506818976 100644 --- a/include/sway/surface.h +++ b/include/sway/surface.h @@ -15,4 +15,9 @@ struct sway_surface { struct wl_event_source *frame_done_timer; }; +void surface_enter_output(struct wlr_surface *surface, + struct sway_output *output); +void surface_leave_output(struct wlr_surface *surface, + struct sway_output *output); + #endif diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 6e3cc0e2b..795eb4cd7 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c @@ -13,6 +13,7 @@ #include "sway/layers.h" #include "sway/output.h" #include "sway/server.h" +#include "sway/surface.h" #include "sway/tree/arrange.h" #include "sway/tree/workspace.h" @@ -382,8 +383,7 @@ static void handle_map(struct wl_listener *listener, void *data) { struct sway_output *output = wlr_output->data; output_damage_surface(output, sway_layer->geo.x, sway_layer->geo.y, sway_layer->layer_surface->surface, true); - wlr_surface_send_enter(sway_layer->layer_surface->surface, - sway_layer->layer_surface->output); + surface_enter_output(sway_layer->layer_surface->surface, output); cursor_rebase_all(); } @@ -510,7 +510,7 @@ static void popup_handle_map(struct wl_listener *listener, void *data) { struct sway_layer_surface *layer = popup_get_layer(popup); struct wlr_output *wlr_output = layer->layer_surface->output; sway_assert(wlr_output, "wlr_layer_surface_v1 has null output"); - wlr_surface_send_enter(popup->wlr_popup->base->surface, wlr_output); + surface_enter_output(popup->wlr_popup->base->surface, wlr_output->data); popup_damage(popup, true); } diff --git a/sway/desktop/surface.c b/sway/desktop/surface.c index 1d7b536da..a5a189172 100644 --- a/sway/desktop/surface.c +++ b/sway/desktop/surface.c @@ -4,6 +4,7 @@ #include #include "sway/server.h" #include "sway/surface.h" +#include "sway/output.h" static void handle_destroy(struct wl_listener *listener, void *data) { struct sway_surface *surface = wl_container_of(listener, surface, destroy); @@ -44,3 +45,13 @@ void handle_compositor_new_surface(struct wl_listener *listener, void *data) { wl_resource_post_no_memory(wlr_surface->resource); } } + +void surface_enter_output(struct wlr_surface *surface, + struct sway_output *output) { + wlr_surface_send_enter(surface, output->wlr_output); +} + +void surface_leave_output(struct wlr_surface *surface, + struct sway_output *output) { + wlr_surface_send_leave(surface, output->wlr_output); +} diff --git a/sway/lock.c b/sway/lock.c index 96af19c4a..6d9e991b3 100644 --- a/sway/lock.c +++ b/sway/lock.c @@ -5,6 +5,7 @@ #include "sway/input/seat.h" #include "sway/output.h" #include "sway/server.h" +#include "sway/surface.h" struct sway_session_lock_surface { struct wlr_session_lock_surface_v1 *lock_surface; @@ -31,7 +32,7 @@ static void handle_surface_map(struct wl_listener *listener, void *data) { if (server.session_lock.focused == NULL) { set_lock_focused_surface(surf->surface); } - wlr_surface_send_enter(surf->surface, surf->output->wlr_output); + surface_enter_output(surf->surface, surf->output); output_damage_whole(surf->output); } diff --git a/sway/tree/container.c b/sway/tree/container.c index fa76dd6aa..207010814 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -18,6 +18,7 @@ #include "sway/ipc-server.h" #include "sway/output.h" #include "sway/server.h" +#include "sway/surface.h" #include "sway/tree/arrange.h" #include "sway/tree/view.h" #include "sway/tree/workspace.h" @@ -1265,14 +1266,14 @@ bool container_is_fullscreen_or_child(struct sway_container *container) { static void surface_send_enter_iterator(struct wlr_surface *surface, int x, int y, void *data) { - struct wlr_output *wlr_output = data; - wlr_surface_send_enter(surface, wlr_output); + struct sway_output *output = data; + surface_enter_output(surface, output); } static void surface_send_leave_iterator(struct wlr_surface *surface, int x, int y, void *data) { - struct wlr_output *wlr_output = data; - wlr_surface_send_leave(surface, wlr_output); + struct sway_output *output = data; + surface_leave_output(surface, output); } void container_discover_outputs(struct sway_container *con) { @@ -1298,7 +1299,7 @@ void container_discover_outputs(struct sway_container *con) { sway_log(SWAY_DEBUG, "Container %p entered output %p", con, output); if (con->view) { view_for_each_surface(con->view, - surface_send_enter_iterator, output->wlr_output); + surface_send_enter_iterator, output); if (con->view->foreign_toplevel) { wlr_foreign_toplevel_handle_v1_output_enter( con->view->foreign_toplevel, output->wlr_output); @@ -1310,7 +1311,7 @@ void container_discover_outputs(struct sway_container *con) { sway_log(SWAY_DEBUG, "Container %p left output %p", con, output); if (con->view) { view_for_each_surface(con->view, - surface_send_leave_iterator, output->wlr_output); + surface_send_leave_iterator, output); if (con->view->foreign_toplevel) { wlr_foreign_toplevel_handle_v1_output_leave( con->view->foreign_toplevel, output->wlr_output); diff --git a/sway/tree/view.c b/sway/tree/view.c index ba3ef4891..fcb78de36 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -25,6 +25,7 @@ #include "sway/output.h" #include "sway/input/seat.h" #include "sway/server.h" +#include "sway/surface.h" #include "sway/tree/arrange.h" #include "sway/tree/container.h" #include "sway/tree/view.h" @@ -1148,7 +1149,7 @@ void view_child_init(struct sway_view_child *child, if (container != NULL) { struct sway_workspace *workspace = container->pending.workspace; if (workspace) { - wlr_surface_send_enter(child->surface, workspace->output->wlr_output); + surface_enter_output(child->surface, workspace->output); } } From 9162b536f69cb69466fb4fcfa24d282fa54b122b Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 10 Feb 2023 18:07:26 +0100 Subject: [PATCH 7/7] Add support for fractional-scale-v1 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3511 --- sway/desktop/surface.c | 14 ++++++++++++++ sway/server.c | 2 ++ 2 files changed, 16 insertions(+) diff --git a/sway/desktop/surface.c b/sway/desktop/surface.c index a5a189172..949cfdc26 100644 --- a/sway/desktop/surface.c +++ b/sway/desktop/surface.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "sway/server.h" #include "sway/surface.h" #include "sway/output.h" @@ -46,12 +47,25 @@ void handle_compositor_new_surface(struct wl_listener *listener, void *data) { } } +static void surface_update_outputs(struct wlr_surface *surface) { + float scale = 1; + struct wlr_surface_output *surface_output; + wl_list_for_each(surface_output, &surface->current_outputs, link) { + if (surface_output->output->scale > scale) { + scale = surface_output->output->scale; + } + } + wlr_fractional_scale_v1_notify_scale(surface, scale); +} + void surface_enter_output(struct wlr_surface *surface, struct sway_output *output) { wlr_surface_send_enter(surface, output->wlr_output); + surface_update_outputs(surface); } void surface_leave_output(struct wlr_surface *surface, struct sway_output *output) { wlr_surface_send_leave(surface, output->wlr_output); + surface_update_outputs(surface); } diff --git a/sway/server.c b/sway/server.c index 1ff0b461f..244c7aec8 100644 --- a/sway/server.c +++ b/sway/server.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -214,6 +215,7 @@ bool server_init(struct sway_server *server) { wlr_single_pixel_buffer_manager_v1_create(server->wl_display); server->content_type_manager_v1 = wlr_content_type_manager_v1_create(server->wl_display, 1); + wlr_fractional_scale_manager_v1_create(server->wl_display, 1); struct wlr_xdg_foreign_registry *foreign_registry = wlr_xdg_foreign_registry_create(server->wl_display);