Compare commits

...

9 commits

Author SHA1 Message Date
Simon Ser
f0ae9dffdb build: bump version to 0.18.3 2025-10-23 12:00:25 +02:00
Simon Ser
1cd9d3bec5 ci: fix VKMS lookup after faux bus migration
VKMS has been migrated to the new faux bus. This causes breakage
in CI, because we used the platform bus to find the right device.

udev hasn't been updated yet to support the faux bus, so just use
sysfs instead.

(cherry picked from commit 03e7966650)
2025-10-21 21:31:04 -04:00
DreamMaoMao
de06f60a29 render/pass: Ensure the precision is consistent during comparison
(cherry picked from commit a08acfcee0)
2025-10-21 22:25:46 +00:00
Alistair Buxton
d8f110c5bc Fix Meson version required for C23 support
Attempting to build with Meson 1.3.2 (current version in Ubuntu 24.04 LTS) gives the following error:

    meson.build:1:0: ERROR: Unknown C std ['c23'].

This is because C23 support was not added until Meson 1.4.0.

See:

https://github.com/mesonbuild/meson/blob/1.3.2/mesonbuild/compilers/c.py#L59
https://github.com/mesonbuild/meson/blob/1.4.0/mesonbuild/compilers/c.py#L49
(cherry picked from commit 71cc47b859)
2025-10-21 22:25:46 +00:00
M Stoeckl
f02d3ef28b wlr_cursor: use default shape if requested shape missing
(cherry picked from commit b97106ddcb)
2025-10-21 22:25:46 +00:00
Simon Ser
38f18cd684 backend/drm: fix enabling an output with a custom mode set
Since 5567aefb1c ("backend/drm: Don't add pollute fixed modes
list with custom modes"), when a custom mode is set on an output,
current_mode will be NULL.

Instead of checking current_mode, check width/height.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3946
(cherry picked from commit 94cb8e2bc7)
2025-10-21 22:25:46 +00:00
Simon Ser
bcba7cb12b backend/drm: handle custom modes in connect_drm_connector()
On startup, some connectors might be already lit up with a custom
mode. We weren't correctly populating the current output state in
this case.

(cherry picked from commit ca1f9f86e6)
2025-10-21 22:25:46 +00:00
liupeng
1a6702938d screencopy-v1: drop output_enable listener
(cherry picked from commit 31f9d6bb97)
2025-10-21 22:25:46 +00:00
Kenny Levinsen
f57e7e40d3 scene/surface: Do not use buffer dimensions for clip
The surface's buffer dimensions were used to scale the clip's x/y
offset. If a surface had a larger buffer than src_box, the calculations
to scale the x/y portion of the clip would be incorrect, yielding
graphical glitches.

This was noticed with Chromium in sway, which during resize uses a
viewport with a src_box to avoid immediate buffer reallocation. While
the viewport was in use, the surface would be shifted so that too much
content was cropped in the upper left, and damage glitching was visible
in the lower right.

Use the buffer source box dimensions instead.

(cherry picked from commit dc7dba8b1f)
2025-10-21 22:25:46 +00:00
8 changed files with 47 additions and 42 deletions

View file

@ -41,9 +41,10 @@ tasks:
cd wlroots/build-gcc/tinywl
sudo modprobe vkms
udevadm settle
card="/dev/dri/$(ls /sys/devices/faux/vkms/drm/ | grep ^card)"
export WLR_BACKENDS=drm
export WLR_RENDERER=pixman
export WLR_DRM_DEVICES=/dev/dri/by-path/platform-vkms-card
export WLR_DRM_DEVICES="$card"
export UBSAN_OPTIONS=halt_on_error=1
sudo chmod ugo+rw /dev/dri/by-path/platform-vkms-card
sudo chmod ugo+rw "$card"
sudo -E seatd-launch -- ./tinywl -s 'kill $PPID' || [ $? = 143 ]

View file

@ -796,13 +796,12 @@ static bool drm_connector_prepare(struct wlr_drm_connector_state *conn_state, bo
return false;
}
if ((state->committed & WLR_OUTPUT_STATE_ENABLED) && state->enabled) {
if (output->current_mode == NULL &&
!(state->committed & WLR_OUTPUT_STATE_MODE)) {
wlr_drm_conn_log(conn, WLR_DEBUG,
"Can't enable an output without a mode");
return false;
}
if ((state->committed & WLR_OUTPUT_STATE_ENABLED) && state->enabled &&
output->width == 0 && output->height == 0 &&
!(state->committed & WLR_OUTPUT_STATE_MODE)) {
wlr_drm_conn_log(conn, WLR_DEBUG,
"Can't enable an output without a mode");
return false;
}
if ((state->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) &&
@ -1582,6 +1581,7 @@ static bool connect_drm_connector(struct wlr_drm_connector *wlr_conn,
wlr_log(WLR_INFO, "Detected modes:");
bool found_current_mode = false;
for (int i = 0; i < drm_conn->count_modes; ++i) {
if (drm_conn->modes[i].flags & DRM_MODE_FLAG_INTERLACE) {
continue;
@ -1600,14 +1600,7 @@ static bool connect_drm_connector(struct wlr_drm_connector *wlr_conn,
if (current_modeinfo != NULL && memcmp(&mode->drm_mode,
current_modeinfo, sizeof(*current_modeinfo)) == 0) {
wlr_output_state_set_mode(&state, &mode->wlr_mode);
uint64_t mode_id = 0;
get_drm_prop(drm->fd, wlr_conn->crtc->id,
wlr_conn->crtc->props.mode_id, &mode_id);
wlr_conn->crtc->own_mode_id = false;
wlr_conn->crtc->mode_id = mode_id;
wlr_conn->refresh = calculate_refresh_rate(current_modeinfo);
found_current_mode = true;
}
wlr_log(WLR_INFO, " %"PRId32"x%"PRId32" @ %.3f Hz %s",
@ -1618,6 +1611,23 @@ static bool connect_drm_connector(struct wlr_drm_connector *wlr_conn,
wl_list_insert(modes.prev, &mode->wlr_mode.link);
}
if (current_modeinfo != NULL) {
int32_t refresh = calculate_refresh_rate(current_modeinfo);
if (!found_current_mode) {
wlr_output_state_set_custom_mode(&state,
current_modeinfo->hdisplay, current_modeinfo->vdisplay, refresh);
}
uint64_t mode_id = 0;
get_drm_prop(drm->fd, wlr_conn->crtc->id,
wlr_conn->crtc->props.mode_id, &mode_id);
wlr_conn->crtc->own_mode_id = false;
wlr_conn->crtc->mode_id = mode_id;
wlr_conn->refresh = refresh;
}
free(current_modeinfo);
wlr_output_init(output, &drm->backend, &output_impl, drm->session->event_loop, &state);

View file

@ -52,7 +52,6 @@ struct wlr_screencopy_frame_v1 {
struct wlr_output *output;
struct wl_listener output_commit;
struct wl_listener output_destroy;
struct wl_listener output_enable;
void *data;
};

View file

@ -1,11 +1,11 @@
project(
'wlroots',
'c',
version: '0.18.2',
version: '0.18.3',
license: 'MIT',
meson_version: '>=0.59.0',
default_options: [
'c_std=' + (meson.version().version_compare('>=1.3.0') ? 'c23,c11' : 'c11'),
'c_std=' + (meson.version().version_compare('>=1.4.0') ? 'c23,c11' : 'c11'),
'warning_level=2',
'werror=true',
],

View file

@ -21,8 +21,8 @@ void wlr_render_pass_add_texture(struct wlr_render_pass *render_pass,
if (!wlr_fbox_empty(&options->src_box)) {
const struct wlr_fbox *box = &options->src_box;
assert(box->x >= 0 && box->y >= 0 &&
box->x + box->width <= options->texture->width &&
box->y + box->height <= options->texture->height);
(uint32_t)(box->x + box->width) <= options->texture->width &&
(uint32_t)(box->y + box->height) <= options->texture->height);
}
render_pass->impl->add_texture(render_pass, options);

View file

@ -128,8 +128,8 @@ static void surface_reconfigure(struct wlr_scene_surface *scene_surface) {
buffer_width, buffer_height);
wlr_output_transform_coords(state->transform, &buffer_width, &buffer_height);
src_box.x += (double)(clip->x * buffer_width) / state->width;
src_box.y += (double)(clip->y * buffer_height) / state->height;
src_box.x += (double)(clip->x * src_box.width) / state->width;
src_box.y += (double)(clip->y * src_box.height) / state->height;
src_box.width *= (double)width / state->width;
src_box.height *= (double)height / state->height;

View file

@ -574,9 +574,15 @@ static void cursor_output_cursor_update(struct wlr_cursor_output_cursor *output_
wlr_xcursor_manager_load(manager, scale);
struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor(manager, name, scale);
if (xcursor == NULL) {
wlr_log(WLR_DEBUG, "XCursor theme is missing '%s' cursor", name);
wlr_output_cursor_set_buffer(output_cursor->output_cursor, NULL, 0, 0);
return;
/* Try the default cursor: better the wrong image than an invisible
* (and therefore practically unusable) cursor */
wlr_log(WLR_DEBUG, "XCursor theme is missing '%s' cursor, falling back to 'default'", name);
xcursor = wlr_xcursor_manager_get_xcursor(manager, "default", scale);
if (xcursor == NULL) {
wlr_log(WLR_DEBUG, "XCursor theme is missing a 'default' cursor");
wlr_output_cursor_set_buffer(output_cursor->output_cursor, NULL, 0, 0);
return;
}
}
output_cursor->xcursor = xcursor;

View file

@ -146,7 +146,6 @@ static void frame_destroy(struct wlr_screencopy_frame_v1 *frame) {
wl_list_remove(&frame->link);
wl_list_remove(&frame->output_commit.link);
wl_list_remove(&frame->output_destroy.link);
wl_list_remove(&frame->output_enable.link);
// Make the frame resource inert
wl_resource_set_user_data(frame->resource, NULL);
wlr_buffer_unlock(frame->buffer);
@ -286,6 +285,10 @@ static void frame_handle_output_commit(struct wl_listener *listener,
struct wlr_output_event_commit *event = data;
struct wlr_output *output = frame->output;
if (event->state->committed & WLR_OUTPUT_STATE_ENABLED && !output->enabled) {
goto err;
}
if (!(event->state->committed & WLR_OUTPUT_STATE_BUFFER)) {
return;
}
@ -338,16 +341,6 @@ err:
frame_destroy(frame);
}
static void frame_handle_output_enable(struct wl_listener *listener,
void *data) {
struct wlr_screencopy_frame_v1 *frame =
wl_container_of(listener, frame, output_enable);
if (!frame->output->enabled) {
zwlr_screencopy_frame_v1_send_failed(frame->resource);
frame_destroy(frame);
}
}
static void frame_handle_output_destroy(struct wl_listener *listener,
void *data) {
struct wlr_screencopy_frame_v1 *frame =
@ -439,9 +432,6 @@ static void frame_handle_copy(struct wl_client *wl_client,
wl_signal_add(&output->events.commit, &frame->output_commit);
frame->output_commit.notify = frame_handle_output_commit;
wl_signal_add(&output->events.destroy, &frame->output_enable);
frame->output_enable.notify = frame_handle_output_enable;
// Request a frame because we can't assume that the current front buffer is still usable. It may
// have been released already, and we shouldn't lock it here because compositors want to render
// into the least damaged buffer.
@ -526,7 +516,6 @@ static void capture_output(struct wl_client *wl_client,
wl_list_insert(&client->manager->frames, &frame->link);
wl_list_init(&frame->output_commit.link);
wl_list_init(&frame->output_enable.link);
wl_signal_add(&output->events.destroy, &frame->output_destroy);
frame->output_destroy.notify = frame_handle_output_destroy;