diff --git a/include/labwc.h b/include/labwc.h index cdb4e42f..ef7ec75d 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -369,6 +369,7 @@ struct output { struct wl_list link; /* server.outputs */ struct server *server; struct wlr_output *wlr_output; + struct wlr_output_state pending; struct wlr_scene_output *scene_output; struct wlr_scene_tree *layer_tree[LAB_NR_LAYERS]; struct wlr_scene_tree *layer_popup_tree; diff --git a/include/output-state.h b/include/output-state.h new file mode 100644 index 00000000..0b90081a --- /dev/null +++ b/include/output-state.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_OUTPUT_STATE_H +#define LABWC_OUTPUT_STATE_H + +#include + +struct output; +struct wlr_output; + +void output_state_init(struct output *output); + +/* Forward port of removed functions */ + +bool wlr_output_test(struct wlr_output *wlr_output); + +bool wlr_output_commit(struct wlr_output *wlr_output); + +void wlr_output_enable(struct wlr_output *wlr_output, bool enabled); + +void wlr_output_set_mode(struct wlr_output *wlr_output, + struct wlr_output_mode *mode); + +void wlr_output_set_custom_mode(struct wlr_output *wlr_output, + int32_t width, int32_t height, int32_t refresh); + +void wlr_output_set_scale(struct wlr_output *wlr_output, float scale); + +void wlr_output_set_transform(struct wlr_output *wlr_output, + enum wl_output_transform transform); + +void wlr_output_enable_adaptive_sync(struct wlr_output *wlr_output, + bool enabled); + +#endif // LABWC_OUTPUT_STATE_H diff --git a/src/common/scene-helpers.c b/src/common/scene-helpers.c index 55b44930..fb627719 100644 --- a/src/common/scene-helpers.c +++ b/src/common/scene-helpers.c @@ -5,7 +5,9 @@ #include #include #include "common/scene-helpers.h" +#include "labwc.h" #include "magnifier.h" +#include "output-state.h" struct wlr_surface * lab_wlr_surface_from_node(struct wlr_scene_node *node) @@ -57,7 +59,7 @@ lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output, */ if (!wlr_output->needs_frame && !pixman_region32_not_empty( &scene_output->damage_ring.current) && !wants_magnification) { - return false; + return true; } if (!wlr_scene_output_build_state(scene_output, state, NULL)) { @@ -71,7 +73,7 @@ lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output, magnify(output, state->buffer, &additional_damage); } - if (state == &wlr_output->pending) { + if (state == &output->pending) { if (!wlr_output_commit(wlr_output)) { wlr_log(WLR_INFO, "Failed to commit output %s", wlr_output->name); diff --git a/src/meson.build b/src/meson.build index bc69eec4..9676bec1 100644 --- a/src/meson.build +++ b/src/meson.build @@ -15,6 +15,7 @@ labwc_sources = files( 'osd.c', 'osd-field.c', 'output.c', + 'output-state.c', 'output-virtual.c', 'overlay.c', 'placement.c', diff --git a/src/output-state.c b/src/output-state.c new file mode 100644 index 00000000..602149a2 --- /dev/null +++ b/src/output-state.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include "labwc.h" +#include "output-state.h" + +void +output_state_init(struct output *output) +{ + wlr_output_state_init(&output->pending); + + /* + * As there is no direct way to convert an existing output + * configuration to an output_state we first convert it + * to a temporary output-management config and then apply + * it to an empty wlr_output_state. + */ + struct wlr_output_configuration_v1 *backup_config = + wlr_output_configuration_v1_create(); + struct wlr_output_configuration_head_v1 *backup_head = + wlr_output_configuration_head_v1_create( + backup_config, output->wlr_output); + + wlr_output_head_v1_state_apply(&backup_head->state, &output->pending); + wlr_output_configuration_v1_destroy(backup_config); +} + +bool +wlr_output_test(struct wlr_output *wlr_output) +{ + struct output *output = wlr_output->data; + return wlr_output_test_state(wlr_output, &output->pending); +} + +bool +wlr_output_commit(struct wlr_output *wlr_output) +{ + struct output *output = wlr_output->data; + bool committed = wlr_output_commit_state(wlr_output, &output->pending); + if (committed) { + wlr_output_state_finish(&output->pending); + wlr_output_state_init(&output->pending); + } else { + wlr_log(WLR_ERROR, "Failed to commit frame"); + } + return committed; +} + +void +wlr_output_enable(struct wlr_output *wlr_output, bool enabled) +{ + struct output *output = wlr_output->data; + wlr_output_state_set_enabled(&output->pending, enabled); +} + +void +wlr_output_set_mode(struct wlr_output *wlr_output, struct wlr_output_mode *mode) +{ + struct output *output = wlr_output->data; + wlr_output_state_set_mode(&output->pending, mode); +} + +void +wlr_output_set_custom_mode(struct wlr_output *wlr_output, + int32_t width, int32_t height, int32_t refresh) +{ + struct output *output = wlr_output->data; + wlr_output_state_set_custom_mode(&output->pending, width, height, refresh); +} + +void +wlr_output_set_scale(struct wlr_output *wlr_output, float scale) +{ + struct output *output = wlr_output->data; + wlr_output_state_set_scale(&output->pending, scale); +} + +void +wlr_output_set_transform(struct wlr_output *wlr_output, + enum wl_output_transform transform) +{ + struct output *output = wlr_output->data; + wlr_output_state_set_transform(&output->pending, transform); +} + +void +wlr_output_enable_adaptive_sync(struct wlr_output *wlr_output, bool enabled) +{ + struct output *output = wlr_output->data; + wlr_output_state_set_adaptive_sync_enabled(&output->pending, enabled); +} diff --git a/src/output.c b/src/output.c index 38de88de..8ca93c47 100644 --- a/src/output.c +++ b/src/output.c @@ -24,6 +24,7 @@ #include "labwc.h" #include "layers.h" #include "node.h" +#include "output-state.h" #include "output-virtual.h" #include "regions.h" #include "view.h" @@ -111,11 +112,11 @@ output_frame_notify(struct wl_listener *listener, void *data) */ output_apply_gamma(output); } else { - output->wlr_output->pending.tearing_page_flip = + output->pending.tearing_page_flip = get_tearing_preference(output); lab_wlr_scene_output_commit(output->scene_output, - &output->wlr_output->pending); + &output->pending); } struct timespec now = { 0 }; @@ -158,6 +159,8 @@ output_destroy_notify(struct wl_listener *listener, void *data) } } + wlr_output_state_finish(&output->pending); + /* * Ensure that we don't accidentally try to dereference * the output pointer in some output event handler like @@ -299,6 +302,12 @@ new_output_notify(struct wl_listener *listener, void *data) return; } + output = znew(*output); + output->wlr_output = wlr_output; + wlr_output->data = output; + output->server = server; + output_state_init(output); + wlr_log(WLR_DEBUG, "enable output"); wlr_output_enable(wlr_output, true); @@ -311,7 +320,9 @@ new_output_notify(struct wl_listener *listener, void *data) wlr_log(WLR_DEBUG, "set preferred mode"); /* The mode is a tuple of (width, height, refresh rate). */ preferred_mode = wlr_output_preferred_mode(wlr_output); - wlr_output_set_mode(wlr_output, preferred_mode); + if (preferred_mode) { + wlr_output_set_mode(wlr_output, preferred_mode); + } } /* @@ -341,10 +352,6 @@ new_output_notify(struct wl_listener *listener, void *data) wlr_output_commit(wlr_output); - output = znew(*output); - output->wlr_output = wlr_output; - wlr_output->data = output; - output->server = server; wlr_output_effective_resolution(wlr_output, &output->usable_area.width, &output->usable_area.height); wl_list_insert(&server->outputs, &output->link); @@ -923,9 +930,6 @@ handle_output_power_manager_set_mode(struct wl_listener *listener, void *data) break; case ZWLR_OUTPUT_POWER_V1_MODE_ON: wlr_output_enable(event->output, true); - if (!wlr_output_test(event->output)) { - wlr_output_rollback(event->output); - } wlr_output_commit(event->output); /* * Re-set the cursor image so that the cursor diff --git a/src/server.c b/src/server.c index f784774d..f380b9cd 100644 --- a/src/server.c +++ b/src/server.c @@ -29,6 +29,7 @@ #include "labwc.h" #include "layers.h" #include "menu/menu.h" +#include "output-state.h" #include "output-virtual.h" #include "regions.h" #include "resize-indicator.h" diff --git a/src/view.c b/src/view.c index 481ec195..3486b19e 100644 --- a/src/view.c +++ b/src/view.c @@ -12,6 +12,7 @@ #include "labwc.h" #include "menu/menu.h" #include "osd.h" +#include "output-state.h" #include "placement.h" #include "regions.h" #include "resize-indicator.h" diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 4c83edb0..e967b9d3 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 98c708618ec09907748082850b2d4340fc63055e +revision = cca2bfbe92205260c75a82ad6b6a7c5bae1599de [provide] dependency_names = wlroots