From cbecc5cbaed6b30c995d2c245def458e383b4e38 Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Sat, 13 Nov 2021 09:08:14 +0300 Subject: container: fix surface_is_popup() --- sway/tree/container.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index 6a01eab3..943d3d53 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -382,19 +382,17 @@ struct sway_container *tiling_container_at(struct sway_node *parent, } static bool surface_is_popup(struct wlr_surface *surface) { - if (wlr_surface_is_xdg_surface(surface)) { - struct wlr_xdg_surface *xdg_surface = - wlr_xdg_surface_from_wlr_surface(surface); - while (xdg_surface && xdg_surface->role != WLR_XDG_SURFACE_ROLE_NONE) { - if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { - return true; - } - xdg_surface = xdg_surface->toplevel->parent; + while (!wlr_surface_is_xdg_surface(surface)) { + if (!wlr_surface_is_subsurface(surface)) { + return false; } - return false; + struct wlr_subsurface *subsurface = + wlr_subsurface_from_wlr_surface(surface); + surface = subsurface->parent; } - - return false; + struct wlr_xdg_surface *xdg_surface = + wlr_xdg_surface_from_wlr_surface(surface); + return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP; } struct sway_container *container_at(struct sway_workspace *workspace, -- cgit v1.2.3 From 5865af75cf8029cc703cda36b68daafcb658c97b Mon Sep 17 00:00:00 2001 From: Simon Zeni Date: Mon, 15 Nov 2021 13:32:52 -0500 Subject: sway: create wlr_renderer and wlr_allocator wlroots now required the compositor to create its own wlr_renderer and wlr_allocator to initialize the wlr_output --- sway/tree/container.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index 943d3d53..eb88b47e 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -547,8 +547,7 @@ static void render_titlebar_text_texture(struct sway_output *output, cairo_surface_flush(surface); unsigned char *data = cairo_image_surface_get_data(surface); int stride = cairo_image_surface_get_stride(surface); - struct wlr_renderer *renderer = wlr_backend_get_renderer( - output->wlr_output->backend); + struct wlr_renderer *renderer = output->wlr_output->renderer; *texture = wlr_texture_from_pixels( renderer, DRM_FORMAT_ARGB8888, stride, width, height, data); cairo_surface_destroy(surface); -- cgit v1.2.3 From f7725011efd3bc2762a0d1002ea5071470962213 Mon Sep 17 00:00:00 2001 From: Vsevolod Date: Fri, 10 Dec 2021 17:09:29 +0200 Subject: Add focused_tab_title --- sway/tree/container.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index eb88b47e..0284c9a5 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -64,6 +64,7 @@ void container_destroy(struct sway_container *con) { wlr_texture_destroy(con->title_focused_inactive); wlr_texture_destroy(con->title_unfocused); wlr_texture_destroy(con->title_urgent); + wlr_texture_destroy(con->title_focused_tab_title); list_free(con->pending.children); list_free(con->current.children); list_free(con->outputs); @@ -73,6 +74,7 @@ void container_destroy(struct sway_container *con) { wlr_texture_destroy(con->marks_focused_inactive); wlr_texture_destroy(con->marks_unfocused); wlr_texture_destroy(con->marks_urgent); + wlr_texture_destroy(con->marks_focused_tab_title); if (con->view) { if (con->view->container == con) { @@ -582,6 +584,8 @@ void container_update_title_textures(struct sway_container *container) { &config->border_colors.unfocused); update_title_texture(container, &container->title_urgent, &config->border_colors.urgent); + update_title_texture(container, &container->title_focused_tab_title, + &config->border_colors.focused_tab_title); container_damage_whole(container); } @@ -1635,6 +1639,8 @@ void container_update_marks_textures(struct sway_container *con) { &config->border_colors.unfocused); update_marks_texture(con, &con->marks_urgent, &config->border_colors.urgent); + update_marks_texture(con, &con->marks_focused_tab_title, + &config->border_colors.focused_tab_title); container_damage_whole(con); } -- cgit v1.2.3 From 4732325f591455f1e4bdcb35652505a8a636663a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 7 Jun 2021 18:58:20 +0200 Subject: Add support for linux-dmabuf surface hints References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/1376 --- sway/tree/container.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index 0284c9a5..132b6819 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -5,8 +5,12 @@ #include #include #include +#include #include +#include #include +#include +#include "linux-dmabuf-unstable-v1-protocol.h" #include "cairo_util.h" #include "pango.h" #include "sway/config.h" @@ -1051,6 +1055,16 @@ 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; @@ -1062,6 +1076,75 @@ static void set_fullscreen(struct sway_container *con, bool enable) { con->view->foreign_toplevel, enable); } } + + if (!server.linux_dmabuf_v1 || !con->view->surface) { + return; + } + if (!enable) { + wlr_linux_dmabuf_v1_set_surface_feedback(server.linux_dmabuf_v1, + con->view->surface, NULL); + return; + } + + if (!con->pending.workspace || !con->pending.workspace->output) { + return; + } + + 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]), + }; + wlr_linux_dmabuf_v1_set_surface_feedback(server.linux_dmabuf_v1, + con->view->surface, &feedback); + + wlr_drm_format_set_finish(&scanout_formats); } static void container_fullscreen_workspace(struct sway_container *con) { -- cgit v1.2.3 From d7867d41c25e0a027a9900f3dde565c6caaa4890 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 21 Dec 2021 12:05:05 +0100 Subject: Add cairo_image_surface_create error handling cairo_image_surface_create can fail, e.g. when running out of memory or when the size is too big. Avoid crashing in this case. Closes: https://github.com/swaywm/sway/issues/6531 (cherry picked from commit 59aebaa5f9f3afe9cdfbb0d37c4dc631690da3b9) --- sway/tree/container.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index 132b6819..e5149fb6 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -536,6 +536,13 @@ static void render_titlebar_text_texture(struct sway_output *output, cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height); + cairo_status_t status = cairo_surface_status(surface); + if (status != CAIRO_STATUS_SUCCESS) { + sway_log(SWAY_ERROR, "cairo_image_surface_create failed: %s", + cairo_status_to_string(status)); + return; + } + cairo_t *cairo = cairo_create(surface); cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); cairo_set_font_options(cairo, fo); -- cgit v1.2.3 From 828a9a3cfbb14388c13007bbbbcdd7f1ed164eb1 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Tue, 19 Oct 2021 07:54:36 +0200 Subject: container: Fix crash when view unmaps + maps quickly Followup on 4e4898e90f. If a view quickly maps and unmaps repeatedly, there will be multiple destroyed containers with same view in a single transaction. Each of these containers will then try to destroy this view, resulting in use after free. The container should only destroy the view if the view still belongs to the container. Simple reproducer: couple XMapWindow + XUnmapWindow in a loop followed by XDestroyWindow. See #6605 (cherry picked from commit f92329701b0983ec41fec29d3abc5c751cbe4a28) --- sway/tree/container.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index e5149fb6..79e04ec0 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -80,10 +80,8 @@ void container_destroy(struct sway_container *con) { wlr_texture_destroy(con->marks_urgent); wlr_texture_destroy(con->marks_focused_tab_title); - if (con->view) { - if (con->view->container == con) { - con->view->container = NULL; - } + if (con->view && con->view->container == con) { + con->view->container = NULL; if (con->view->destroying) { view_destroy(con->view); } -- cgit v1.2.3