mirror of
https://github.com/swaywm/sway.git
synced 2026-04-06 07:15:44 -04:00
Add support for tearing-control-v1
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3871 Adds option to allow tearing per output, as well as an option to force enable or disable tearing for a specific application using a window rule. Only works with fullscreen applications.
This commit is contained in:
parent
b881c2e84c
commit
9a1c411abd
20 changed files with 243 additions and 3 deletions
|
|
@ -232,6 +232,23 @@ static void output_configure_scene(struct sway_output *output,
|
|||
}
|
||||
}
|
||||
|
||||
static bool output_can_tear(struct sway_output *output) {
|
||||
struct sway_workspace *workspace = output->current.active_workspace;
|
||||
if (!workspace) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sway_container *fullscreen_con = root->fullscreen_global;
|
||||
if (!fullscreen_con) {
|
||||
fullscreen_con = workspace->current.fullscreen;
|
||||
}
|
||||
if (fullscreen_con && fullscreen_con->view) {
|
||||
return (output->allow_tearing && view_can_tear(fullscreen_con->view));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int output_repaint_timer_handler(void *data) {
|
||||
struct sway_output *output = data;
|
||||
|
||||
|
|
@ -275,6 +292,17 @@ static int output_repaint_timer_handler(void *data) {
|
|||
wlr_output_state_set_gamma_lut(&pending, 0, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (output_can_tear(output)) {
|
||||
pending.tearing_page_flip = true;
|
||||
|
||||
if (!wlr_output_test_state(output->wlr_output, &pending)) {
|
||||
sway_log(SWAY_DEBUG, "Output test failed on '%s', retrying without tearing page-flip",
|
||||
output->wlr_output->name);
|
||||
|
||||
pending.tearing_page_flip = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wlr_output_commit_state(output->wlr_output, &pending)) {
|
||||
sway_log(SWAY_ERROR, "Page-flip failed on output %s", output->wlr_output->name);
|
||||
|
|
|
|||
62
sway/desktop/tearing.c
Normal file
62
sway/desktop/tearing.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_tearing_control_v1.h>
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/output.h"
|
||||
#include "log.h"
|
||||
|
||||
struct sway_tearing_controller {
|
||||
struct wlr_tearing_control_v1 *tearing_control;
|
||||
struct wl_listener set_hint;
|
||||
struct wl_listener destroy;
|
||||
|
||||
struct wl_list link; // sway_server::tearing_controllers
|
||||
};
|
||||
|
||||
static void handle_tearing_controller_set_hint(struct wl_listener *listener,
|
||||
void *data) {
|
||||
struct sway_tearing_controller *controller =
|
||||
wl_container_of(listener, controller, set_hint);
|
||||
|
||||
struct sway_view *view = view_from_wlr_surface(
|
||||
controller->tearing_control->surface);
|
||||
if (view) {
|
||||
view->tearing_hint = controller->tearing_control->current;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_tearing_controller_destroy(struct wl_listener *listener,
|
||||
void *data) {
|
||||
struct sway_tearing_controller *controller =
|
||||
wl_container_of(listener, controller, destroy);
|
||||
wl_list_remove(&controller->link);
|
||||
free(controller);
|
||||
}
|
||||
|
||||
void handle_new_tearing_hint(struct wl_listener *listener,
|
||||
void *data) {
|
||||
struct sway_server *server =
|
||||
wl_container_of(listener, server, tearing_control_new_object);
|
||||
struct wlr_tearing_control_v1 *tearing_control = data;
|
||||
|
||||
enum wp_tearing_control_v1_presentation_hint hint =
|
||||
wlr_tearing_control_manager_v1_surface_hint_from_surface(
|
||||
server->tearing_control_v1, tearing_control->surface);
|
||||
sway_log(SWAY_DEBUG, "New presentation hint %d received for surface %p",
|
||||
hint, tearing_control->surface);
|
||||
|
||||
struct sway_tearing_controller *controller =
|
||||
calloc(1, sizeof(struct sway_tearing_controller));
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
||||
controller->tearing_control = tearing_control;
|
||||
controller->set_hint.notify = handle_tearing_controller_set_hint;
|
||||
wl_signal_add(&tearing_control->events.set_hint, &controller->set_hint);
|
||||
controller->destroy.notify = handle_tearing_controller_destroy;
|
||||
wl_signal_add(&tearing_control->events.destroy, &controller->destroy);
|
||||
wl_list_init(&controller->link);
|
||||
|
||||
wl_list_insert(&server->tearing_controllers, &controller->link);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue