diff options
-rw-r--r-- | .builds/archlinux.yml | 10 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | include/types/wlr_data_device.h | 3 | ||||
-rw-r--r-- | include/types/wlr_tablet_v2.h | 4 | ||||
-rw-r--r-- | include/wlr/render/wlr_renderer.h | 5 | ||||
-rw-r--r-- | include/wlr/types/wlr_compositor.h | 4 | ||||
-rw-r--r-- | include/wlr/types/wlr_data_device.h | 13 | ||||
-rw-r--r-- | include/wlr/types/wlr_output.h | 6 | ||||
-rw-r--r-- | render/wlr_renderer.c | 9 | ||||
-rw-r--r-- | types/data_device/wlr_data_device.c | 33 | ||||
-rw-r--r-- | types/data_device/wlr_data_offer.c | 120 | ||||
-rw-r--r-- | types/data_device/wlr_data_source.c | 35 | ||||
-rw-r--r-- | types/data_device/wlr_drag.c | 46 | ||||
-rw-r--r-- | types/tablet_v2/wlr_tablet_v2.c | 45 | ||||
-rw-r--r-- | types/wlr_output.c | 15 | ||||
-rw-r--r-- | types/wlr_screencopy_v1.c | 2 | ||||
-rw-r--r-- | types/wlr_surface.c | 12 | ||||
-rw-r--r-- | types/wlr_text_input_v3.c | 2 |
18 files changed, 176 insertions, 190 deletions
diff --git a/.builds/archlinux.yml b/.builds/archlinux.yml index 4b3e197d..2a4b5fc0 100644 --- a/.builds/archlinux.yml +++ b/.builds/archlinux.yml @@ -15,14 +15,12 @@ sources: - https://github.com/swaywm/wlroots tasks: - setup: | - mkdir wlroots/build-{gcc,clang} - cd wlroots/build-gcc - CC=gcc meson .. - cd ../build-clang - CC=clang meson .. + cd wlroots + CC=gcc meson build-gcc + CC=clang meson build-clang - gcc: | cd wlroots/build-gcc ninja - clang: | cd wlroots/build-clang - ninja scan-build + ninja @@ -1,7 +1,7 @@ # wlroots Pluggable, composable, unopinionated modules for building a -[Wayland](http://wayland.freedesktop.org/) compositor; or about 40,000 lines of +[Wayland](http://wayland.freedesktop.org/) compositor; or about 50,000 lines of code you were going to write anyway. - wlroots provides backends that abstract the underlying display and input diff --git a/include/types/wlr_data_device.h b/include/types/wlr_data_device.h index 388e91a5..376c5f09 100644 --- a/include/types/wlr_data_device.h +++ b/include/types/wlr_data_device.h @@ -19,6 +19,7 @@ extern const struct wlr_surface_role drag_icon_surface_role; struct wlr_data_offer *data_offer_create(struct wl_client *client, struct wlr_data_source *source, uint32_t version); void data_offer_update_action(struct wlr_data_offer *offer); +void data_offer_destroy(struct wlr_data_offer *offer); struct wlr_client_data_source *client_data_source_create( struct wl_client *client, uint32_t version, uint32_t id, @@ -26,7 +27,7 @@ struct wlr_client_data_source *client_data_source_create( struct wlr_client_data_source *client_data_source_from_resource( struct wl_resource *resource); struct wlr_data_offer *data_source_send_offer(struct wlr_data_source *source, - struct wlr_seat_client *target); + struct wl_resource *device_resource); void data_source_notify_finish(struct wlr_data_source *source); bool seat_client_start_drag(struct wlr_seat_client *client, diff --git a/include/types/wlr_tablet_v2.h b/include/types/wlr_tablet_v2.h index 4b9e727d..becde596 100644 --- a/include/types/wlr_tablet_v2.h +++ b/include/types/wlr_tablet_v2.h @@ -6,7 +6,7 @@ #include <wlr/types/wlr_tablet_v2.h> struct wlr_tablet_seat_v2 { - struct wl_list link; + struct wl_list link; // wlr_tablet_manager_v2::seats struct wlr_seat *wlr_seat; struct wlr_tablet_manager_v2 *manager; @@ -14,7 +14,7 @@ struct wlr_tablet_seat_v2 { struct wl_list tools; struct wl_list pads; - struct wl_list clients; //wlr_tablet_seat_v2_client::link; + struct wl_list clients; // wlr_tablet_seat_v2_client::link struct wl_listener seat_destroy; }; diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h index 02b4a11e..9c031b7f 100644 --- a/include/wlr/render/wlr_renderer.h +++ b/include/wlr/render/wlr_renderer.h @@ -97,11 +97,6 @@ int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *renderer, int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *renderer, int format, uint64_t **modifiers); /** - * Get the preferred format for reading pixels. - */ -bool wlr_renderer_preferred_read_format(struct wlr_renderer *renderer, - enum wl_shm_format *fmt); -/** * Reads out of pixels of the currently bound surface into data. `stride` is in * bytes. * diff --git a/include/wlr/types/wlr_compositor.h b/include/wlr/types/wlr_compositor.h index 1772e54b..36b9e83f 100644 --- a/include/wlr/types/wlr_compositor.h +++ b/include/wlr/types/wlr_compositor.h @@ -43,6 +43,10 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display, bool wlr_surface_is_subsurface(struct wlr_surface *surface); +/** + * Get a subsurface from a surface. Can return NULL if the subsurface has been + * destroyed. + */ struct wlr_subsurface *wlr_subsurface_from_wlr_surface( struct wlr_surface *surface); diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index 9ce8f400..9c4ce995 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -12,14 +12,14 @@ #include <wayland-server.h> #include <wlr/types/wlr_seat.h> -extern const struct -wlr_pointer_grab_interface wlr_data_device_pointer_drag_interface; +extern const struct wlr_pointer_grab_interface + wlr_data_device_pointer_drag_interface; -extern const struct -wlr_keyboard_grab_interface wlr_data_device_keyboard_drag_interface; +extern const struct wlr_keyboard_grab_interface + wlr_data_device_keyboard_drag_interface; -extern const struct -wlr_touch_grab_interface wlr_data_device_touch_drag_interface; +extern const struct wlr_touch_grab_interface + wlr_data_device_touch_drag_interface; struct wlr_data_device_manager { struct wl_global *global; @@ -72,7 +72,6 @@ struct wlr_data_source { // source status bool accepted; - struct wlr_data_offer *offer; // drag'n'drop status enum wl_data_device_manager_dnd_action current_dnd_action; diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 557a3895..6d38152a 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -193,6 +193,12 @@ void wlr_output_effective_resolution(struct wlr_output *output, */ bool wlr_output_make_current(struct wlr_output *output, int *buffer_age); /** + * Get the preferred format for reading pixels. + * This function might change the current rendering context. + */ +bool wlr_output_preferred_read_format(struct wlr_output *output, + enum wl_shm_format *fmt); +/** * Swaps the output buffers. If the time of the frame isn't known, set `when` to * NULL. If the compositor doesn't support damage tracking, set `damage` to * NULL. diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index ca1a337d..58731d7f 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -139,15 +139,6 @@ int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *r, int format, return r->impl->get_dmabuf_modifiers(r, format, modifiers); } -bool wlr_renderer_preferred_read_format(struct wlr_renderer *r, - enum wl_shm_format *fmt) { - if (!r->impl->preferred_read_format || !r->impl->read_pixels) { - return false; - } - *fmt = r->impl->preferred_read_format(r); - return true; -} - bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt, uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, diff --git a/types/data_device/wlr_data_device.c b/types/data_device/wlr_data_device.c index a50f0b4a..f868ea37 100644 --- a/types/data_device/wlr_data_device.c +++ b/types/data_device/wlr_data_device.c @@ -94,25 +94,24 @@ static void data_device_handle_resource_destroy(struct wl_resource *resource) { void wlr_seat_client_send_selection(struct wlr_seat_client *seat_client) { - if (wl_list_empty(&seat_client->data_devices)) { - return; + struct wlr_data_source *source = seat_client->seat->selection_source; + if (source != NULL) { + source->accepted = false; } - if (seat_client->seat->selection_source) { - struct wlr_data_offer *offer = data_source_send_offer( - seat_client->seat->selection_source, seat_client); - if (offer == NULL) { - return; - } - - struct wl_resource *resource; - wl_resource_for_each(resource, &seat_client->data_devices) { - wl_data_device_send_selection(resource, offer->resource); - } - } else { - struct wl_resource *resource; - wl_resource_for_each(resource, &seat_client->data_devices) { - wl_data_device_send_selection(resource, NULL); + struct wl_resource *device_resource; + wl_resource_for_each(device_resource, &seat_client->data_devices) { + if (source != NULL) { + struct wlr_data_offer *offer = + data_source_send_offer(source, device_resource); + if (offer == NULL) { + wl_client_post_no_memory(seat_client->client); + return; + } + + wl_data_device_send_selection(device_resource, offer->resource); + } else { + wl_data_device_send_selection(device_resource, NULL); } } } diff --git a/types/data_device/wlr_data_offer.c b/types/data_device/wlr_data_offer.c index 9847e07c..b8cec091 100644 --- a/types/data_device/wlr_data_offer.c +++ b/types/data_device/wlr_data_offer.c @@ -55,15 +55,10 @@ static uint32_t data_offer_choose_action(struct wlr_data_offer *offer) { } void data_offer_update_action(struct wlr_data_offer *offer) { - if (!offer->source) { - return; - } - uint32_t action = data_offer_choose_action(offer); if (offer->source->current_dnd_action == action) { return; } - offer->source->current_dnd_action = action; if (offer->in_ask) { @@ -78,50 +73,77 @@ void data_offer_update_action(struct wlr_data_offer *offer) { } } -static void data_offer_accept(struct wl_client *client, +static void data_offer_handle_accept(struct wl_client *client, struct wl_resource *resource, uint32_t serial, const char *mime_type) { struct wlr_data_offer *offer = data_offer_from_resource(resource); - - if (!offer->source || offer != offer->source->offer) { + if (offer == NULL) { return; } - // TODO check that client is currently focused by the input device - wlr_data_source_accept(offer->source, serial, mime_type); } -static void data_offer_receive(struct wl_client *client, +static void data_offer_handle_receive(struct wl_client *client, struct wl_resource *resource, const char *mime_type, int32_t fd) { struct wlr_data_offer *offer = data_offer_from_resource(resource); - - if (offer->source && offer == offer->source->offer) { - wlr_data_source_send(offer->source, mime_type, fd); - } else { + if (offer == NULL) { close(fd); + return; } + + wlr_data_source_send(offer->source, mime_type, fd); } -static void data_offer_destroy(struct wl_client *client, +static void data_offer_dnd_finish(struct wlr_data_offer *offer) { + struct wlr_data_source *source = offer->source; + if (source->actions < 0) { + return; + } + + if (offer->in_ask) { + wlr_data_source_dnd_action(source, source->current_dnd_action); + } + + wlr_data_source_dnd_finish(source); +} + +static void data_offer_handle_destroy(struct wl_client *client, struct wl_resource *resource) { + struct wlr_data_offer *offer = data_offer_from_resource(resource); + if (offer == NULL) { + goto out; + } + + // If the drag destination has version < 3, wl_data_offer.finish + // won't be called, so do this here as a safety net, because + // we still want the version >= 3 drag source to be happy. + if (wl_resource_get_version(offer->resource) < + WL_DATA_OFFER_ACTION_SINCE_VERSION) { + data_offer_dnd_finish(offer); + } + +out: wl_resource_destroy(resource); } -static void data_offer_finish(struct wl_client *client, +static void data_offer_handle_finish(struct wl_client *client, struct wl_resource *resource) { struct wlr_data_offer *offer = data_offer_from_resource(resource); - - if (!offer->source || offer->source->offer != offer) { + if (offer == NULL) { return; } - data_source_notify_finish(offer->source); + data_offer_dnd_finish(offer); + data_offer_destroy(offer); } -static void data_offer_set_actions(struct wl_client *client, +static void data_offer_handle_set_actions(struct wl_client *client, struct wl_resource *resource, uint32_t actions, uint32_t preferred_action) { struct wlr_data_offer *offer = data_offer_from_resource(resource); + if (offer == NULL) { + return; + } if (actions & ~DATA_DEVICE_ALL_ACTIONS) { wl_resource_post_error(offer->resource, @@ -144,52 +166,36 @@ static void data_offer_set_actions(struct wl_client *client, data_offer_update_action(offer); } -static void data_offer_handle_resource_destroy(struct wl_resource *resource) { - struct wlr_data_offer *offer = data_offer_from_resource(resource); - - if (!offer->source) { - goto out; +void data_offer_destroy(struct wlr_data_offer *offer) { + if (offer == NULL) { + return; } wl_list_remove(&offer->source_destroy.link); - if (offer->source->offer != offer) { - goto out; - } - - // If the drag destination has version < 3, wl_data_offer.finish - // won't be called, so do this here as a safety net, because - // we still want the version >= 3 drag source to be happy. - if (wl_resource_get_version(offer->resource) < - WL_DATA_OFFER_ACTION_SINCE_VERSION) { - data_source_notify_finish(offer->source); - offer->source->offer = NULL; - } else if (offer->source->impl->dnd_finish) { - // source->cancel can free the source - offer->source->offer = NULL; - wlr_data_source_cancel(offer->source); - } else { - offer->source->offer = NULL; - } - -out: + // Make the resource inert + wl_resource_set_user_data(offer->resource, NULL); free(offer); } static const struct wl_data_offer_interface data_offer_impl = { - .accept = data_offer_accept, - .receive = data_offer_receive, - .destroy = data_offer_destroy, - .finish = data_offer_finish, - .set_actions = data_offer_set_actions, + .accept = data_offer_handle_accept, + .receive = data_offer_handle_receive, + .destroy = data_offer_handle_destroy, + .finish = data_offer_handle_finish, + .set_actions = data_offer_handle_set_actions, }; -static void handle_offer_source_destroyed(struct wl_listener *listener, +static void data_offer_handle_resource_destroy(struct wl_resource *resource) { + struct wlr_data_offer *offer = data_offer_from_resource(resource); + data_offer_destroy(offer); +} + +static void data_offer_handle_source_destroy(struct wl_listener *listener, void *data) { struct wlr_data_offer *offer = wl_container_of(listener, offer, source_destroy); - - offer->source = NULL; + data_offer_destroy(offer); } struct wlr_data_offer *data_offer_create(struct wl_client *client, @@ -200,8 +206,8 @@ struct wlr_data_offer *data_offer_create(struct wl_client *client, } offer->source = source; - offer->resource = wl_resource_create(client, - &wl_data_offer_interface, version, 0); + offer->resource = + wl_resource_create(client, &wl_data_offer_interface, version, 0); if (offer->resource == NULL) { free(offer); return NULL; @@ -209,7 +215,7 @@ struct wlr_data_offer *data_offer_create(struct wl_client *client, wl_resource_set_implementation(offer->resource, &data_offer_impl, offer, data_offer_handle_resource_destroy); - offer->source_destroy.notify = handle_offer_source_destroyed; + offer->source_destroy.notify = data_offer_handle_source_destroy; wl_signal_add(&source->events.destroy, &offer->source_destroy); return offer; diff --git a/types/data_device/wlr_data_source.c b/types/data_device/wlr_data_source.c index 64db3a70..413f461a 100644 --- a/types/data_device/wlr_data_source.c +++ b/types/data_device/wlr_data_source.c @@ -11,47 +11,22 @@ #include "types/wlr_data_device.h" #include "util/signal.h" -void data_source_notify_finish(struct wlr_data_source *source) { - assert(source->offer); - if (source->actions < 0) { - return; - } - - if (source->offer->in_ask) { - wlr_data_source_dnd_action(source, source->current_dnd_action); - } - - source->offer = NULL; - wlr_data_source_dnd_finish(source); -} - struct wlr_data_offer *data_source_send_offer(struct wlr_data_source *source, - struct wlr_seat_client *target) { - if (wl_list_empty(&target->data_devices)) { - return NULL; - } - - uint32_t version = wl_resource_get_version( - wl_resource_from_link(target->data_devices.next)); - - struct wlr_data_offer *offer = - data_offer_create(target->client, source, version); + struct wl_resource *device_resource) { + struct wl_client *client = wl_resource_get_client(device_resource); + uint32_t version = wl_resource_get_version(device_resource); + struct wlr_data_offer *offer = data_offer_create(client, source, version); if (offer == NULL) { return NULL; } - struct wl_resource *target_resource; - wl_resource_for_each(target_resource, &target->data_devices) { - wl_data_device_send_data_offer(target_resource, offer->resource); - } + wl_data_device_send_data_offer(device_resource, offer->resource); char **p; wl_array_for_each(p, &source->mime_types) { wl_data_offer_send_offer(offer->resource, *p); } - source->offer = offer; - source->accepted = false; return offer; } diff --git a/types/data_device/wlr_drag.c b/types/data_device/wlr_drag.c index 8ed6e034..8e737597 100644 --- a/types/data_device/wlr_drag.c +++ b/types/data_device/wlr_drag.c @@ -47,25 +47,27 @@ static void drag_set_focus(struct wlr_drag *drag, return; } - if (drag->source && drag->source->offer) { - // unlink the offer from the source - wl_list_remove(&drag->source->offer->source_destroy.link); - drag->source->offer->source = NULL; - drag->source->offer = NULL; - } - struct wlr_seat_client *focus_client = wlr_seat_client_for_wl_client( drag->seat_client->seat, wl_resource_get_client(surface->resource)); if (!focus_client) { return; } - struct wl_resource *offer_resource = NULL; - if (drag->source) { + if (drag->source != NULL) { drag->source->accepted = false; - struct wlr_data_offer *offer = data_source_send_offer(drag->source, - focus_client); - if (offer != NULL) { + + uint32_t serial = + wl_display_next_serial(drag->seat_client->seat->display); + + struct wl_resource *device_resource; + wl_resource_for_each(device_resource, &focus_client->data_devices) { + struct wlr_data_offer *offer = + data_source_send_offer(drag->source, device_resource); + if (offer == NULL) { + wl_resource_post_no_memory(device_resource); + return; + } + data_offer_update_action(offer); if (wl_resource_get_version(offer->resource) >= @@ -74,18 +76,10 @@ static void drag_set_focus(struct wlr_drag *drag, drag->source->actions); } - offer_resource = offer->resource; - } - } - - if (!wl_list_empty(&focus_client->data_devices)) { - uint32_t serial = - wl_display_next_serial(drag->seat_client->seat->display); - struct wl_resource *resource; - wl_resource_for_each(resource, &focus_client->data_devices) { - wl_data_device_send_enter(resource, serial, surface->resource, + wl_data_device_send_enter(device_resource, serial, + surface->resource, wl_fixed_from_double(sx), wl_fixed_from_double(sy), - offer_resource); + offer->resource); } } @@ -174,12 +168,6 @@ static uint32_t drag_handle_pointer_button(struct wlr_seat_pointer_grab *grab, } wlr_data_source_dnd_drop(drag->source); - if (drag->source->offer != NULL) { - drag->source->offer->in_ask = - drag->source->current_dnd_action == - WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; - } - struct wlr_drag_drop_event event = { .drag = drag, .time = time, diff --git a/types/tablet_v2/wlr_tablet_v2.c b/types/tablet_v2/wlr_tablet_v2.c index 7f3d5f30..a1cace93 100644 --- a/types/tablet_v2/wlr_tablet_v2.c +++ b/types/tablet_v2/wlr_tablet_v2.c @@ -27,20 +27,22 @@ struct wlr_tablet_manager_client_v2 { struct wl_list tablet_seats; // wlr_tablet_seat_client_v2::link }; -static void handle_wlr_seat_destroy(struct wl_listener *listener, void *data) { - struct wlr_tablet_seat_v2 *seat = - wl_container_of(listener, seat, seat_destroy); - +static void tablet_seat_destroy(struct wlr_tablet_seat_v2 *seat) { wl_list_remove(&seat->link); wl_list_remove(&seat->seat_destroy.link); - struct wlr_tablet_seat_client_v2 *client; - struct wlr_tablet_seat_client_v2 *tmp; - wl_list_for_each_safe(client, tmp, &seat->clients, seat_link) { + struct wlr_tablet_seat_client_v2 *client, *client_tmp; + wl_list_for_each_safe(client, client_tmp, &seat->clients, seat_link) { tablet_seat_client_v2_destroy(client->resource); } } +static void handle_wlr_seat_destroy(struct wl_listener *listener, void *data) { + struct wlr_tablet_seat_v2 *seat = + wl_container_of(listener, seat, seat_destroy); + tablet_seat_destroy(seat); +} + static struct wlr_tablet_seat_v2 *create_tablet_seat( struct wlr_tablet_manager_v2 *manager, struct wlr_seat *wlr_seat) { @@ -79,13 +81,13 @@ struct wlr_tablet_seat_v2 *get_or_create_tablet_seat( return create_tablet_seat(manager, wlr_seat); } -static void tablet_seat_destroy(struct wl_client *client, +static void tablet_seat_handle_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); } static struct zwp_tablet_seat_v2_interface seat_impl = { - .destroy = tablet_seat_destroy, + .destroy = tablet_seat_handle_destroy, }; struct wlr_tablet_seat_client_v2 *tablet_seat_client_from_resource( @@ -138,12 +140,13 @@ static void tablet_manager_destroy(struct wl_client *client, wl_resource_destroy(resource); } -static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource(struct wl_resource *resource); +static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource( + struct wl_resource *resource); static void get_tablet_seat(struct wl_client *wl_client, struct wl_resource *resource, - uint32_t id, struct wl_resource *seat_resource) -{ - struct wlr_tablet_manager_client_v2 *manager = tablet_manager_client_from_resource(resource); + uint32_t id, struct wl_resource *seat_resource) { + struct wlr_tablet_manager_client_v2 *manager = + tablet_manager_client_from_resource(resource); if (!manager) { /* Inert manager, just set up the resource for later * destruction, without allocations or advertising things @@ -214,7 +217,7 @@ static struct zwp_tablet_manager_v2_interface manager_impl = { .destroy = tablet_manager_destroy, }; -static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource ( +static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource( struct wl_resource *resource) { assert(wl_resource_instance_of(resource, &zwp_tablet_manager_v2_interface, &manager_impl)); @@ -222,7 +225,8 @@ static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource } static void wlr_tablet_manager_v2_destroy(struct wl_resource *resource) { - struct wlr_tablet_manager_client_v2 *client = tablet_manager_client_from_resource(resource); + struct wlr_tablet_manager_client_v2 *client = + tablet_manager_client_from_resource(resource); if (!client) { return; } @@ -275,11 +279,14 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) { } void wlr_tablet_v2_destroy(struct wlr_tablet_manager_v2 *manager) { - struct wlr_tablet_manager_client_v2 *tmp; - struct wlr_tablet_manager_client_v2 *pos; + struct wlr_tablet_manager_client_v2 *client, *client_tmp; + wl_list_for_each_safe(client, client_tmp, &manager->clients, link) { + wlr_tablet_manager_v2_destroy(client->resource); + } - wl_list_for_each_safe(pos, tmp, &manager->clients, link) { - wlr_tablet_manager_v2_destroy(pos->resource); + struct wlr_tablet_seat_v2 *seat, *seat_tmp; + wl_list_for_each_safe(seat, seat_tmp, &manager->seats, link) { + tablet_seat_destroy(seat); } wlr_signal_emit_safe(&manager->events.destroy, manager); diff --git a/types/wlr_output.c b/types/wlr_output.c index 71cb3eba..dc8e34b8 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -6,6 +6,7 @@ #include <time.h> #include <wayland-server.h> #include <wlr/interfaces/wlr_output.h> +#include <wlr/render/interface.h> #include <wlr/render/wlr_renderer.h> #include <wlr/types/wlr_box.h> #include <wlr/types/wlr_matrix.h> @@ -339,6 +340,20 @@ bool wlr_output_make_current(struct wlr_output *output, int *buffer_age) { return output->impl->make_current(output, buffer_age); } +bool wlr_output_preferred_read_format(struct wlr_output *output, + enum wl_shm_format *fmt) { + if (!wlr_output_make_current(output, NULL)) { + return false; + } + + struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); + if (!renderer->impl->preferred_read_format || !renderer->impl->read_pixels) { + return false; + } + *fmt = renderer->impl->preferred_read_format(renderer); + return true; +} + bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when, pixman_region32_t *damage) { if (output->frame_pending) { diff --git a/types/wlr_screencopy_v1.c b/types/wlr_screencopy_v1.c index b186b89b..1d8550fe 100644 --- a/types/wlr_screencopy_v1.c +++ b/types/wlr_screencopy_v1.c @@ -219,7 +219,7 @@ static void capture_output(struct wl_client *client, struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); assert(renderer); - if (!wlr_renderer_preferred_read_format(renderer, &frame->format)) { + if (!wlr_output_preferred_read_format(frame->output, &frame->format)) { wlr_log(WLR_ERROR, "Failed to capture output: no read format supported by renderer"); goto error; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index b19387c8..27176ef0 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -376,7 +376,7 @@ static void surface_commit_pending(struct wlr_surface *surface) { } static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) { - while (1) { + while (subsurface != NULL) { if (subsurface->synchronized) { return true; } @@ -436,15 +436,14 @@ static void surface_commit(struct wl_client *client, struct wl_resource *resource) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - if (wlr_surface_is_subsurface(surface)) { - struct wlr_subsurface *subsurface = - wlr_subsurface_from_wlr_surface(surface); + struct wlr_subsurface *subsurface = wlr_surface_is_subsurface(surface) ? + wlr_subsurface_from_wlr_surface(surface) : NULL; + if (subsurface != NULL) { subsurface_commit(subsurface); } else { surface_commit_pending(surface); } - struct wlr_subsurface *subsurface; wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) { subsurface_parent_commit(subsurface, false); } @@ -904,6 +903,9 @@ struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface) { while (wlr_surface_is_subsurface(surface)) { struct wlr_subsurface *subsurface = wlr_subsurface_from_wlr_surface(surface); + if (subsurface == NULL) { + break; + } surface = subsurface->parent; } return surface; diff --git a/types/wlr_text_input_v3.c b/types/wlr_text_input_v3.c index 6ec0762a..e8f7a613 100644 --- a/types/wlr_text_input_v3.c +++ b/types/wlr_text_input_v3.c @@ -176,7 +176,7 @@ static void text_input_commit(struct wl_client *client, text_input->current_serial++; if (text_input->focused_surface == NULL) { - wlr_log(WLR_DEBUG, "Text input commit received without focus\n"); + wlr_log(WLR_DEBUG, "Text input commit received without focus"); } if (!old_enabled && text_input->current_enabled) { |