-
-
Save rhoot/dcead8b195054387c067919fef499c5c to your computer and use it in GitHub Desktop.
Sway VRR cursor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/include/sway/output.h b/include/sway/output.h | |
index 50d90d25..6e9f7aef 100644 | |
--- a/include/sway/output.h | |
+++ b/include/sway/output.h | |
@@ -8,6 +8,7 @@ | |
#include "config.h" | |
#include "sway/tree/node.h" | |
#include "sway/tree/view.h" | |
+#include <pixman.h> | |
struct sway_server; | |
struct sway_container; | |
@@ -58,6 +59,7 @@ struct sway_output { | |
int max_render_time; // In milliseconds | |
struct wl_event_source *repaint_timer; | |
bool gamma_lut_changed; | |
+ pixman_region32_t cursor_damage; | |
}; | |
struct sway_output_non_desktop { | |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c | |
index 476bfd25..759e9cab 100644 | |
--- a/sway/desktop/output.c | |
+++ b/sway/desktop/output.c | |
@@ -571,6 +571,9 @@ static int output_repaint_timer_handler(void *data) { | |
return 0; | |
} | |
+ wlr_damage_ring_add(&output->damage_ring, &output->cursor_damage); | |
+ pixman_region32_clear(&output->cursor_damage); | |
+ | |
struct sway_workspace *workspace = output->current.active_workspace; | |
if (workspace == NULL) { | |
return 0; | |
@@ -601,7 +604,17 @@ static int output_repaint_timer_handler(void *data) { | |
pending.committed |= WLR_OUTPUT_STATE_DAMAGE; | |
get_frame_damage(output, &pending.damage); | |
- if (fullscreen_con && fullscreen_con->view && !debug.noscanout) { | |
+ const bool adaptive_sync = output->wlr_output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED; | |
+ const bool has_fullscreen_view = fullscreen_con && fullscreen_con->view; | |
+ const bool no_cursor_move_frames = output->wlr_output->no_frames_for_cursor_moves; | |
+ | |
+ if (has_fullscreen_view && adaptive_sync && !no_cursor_move_frames) { | |
+ output->wlr_output->no_frames_for_cursor_moves = true; | |
+ } else if ((!has_fullscreen_view || !adaptive_sync) && no_cursor_move_frames) { | |
+ output->wlr_output->no_frames_for_cursor_moves = false; | |
+ } | |
+ | |
+ if (has_fullscreen_view && !debug.noscanout) { | |
// Try to scan-out the fullscreen view | |
static bool last_scanned_out = false; | |
bool scanned_out = | |
@@ -688,9 +701,19 @@ static void handle_damage(struct wl_listener *listener, void *user_data) { | |
struct sway_output *output = | |
wl_container_of(listener, output, damage); | |
struct wlr_output_event_damage *event = user_data; | |
- if (wlr_damage_ring_add(&output->damage_ring, event->damage)) { | |
- wlr_output_schedule_frame(output->wlr_output); | |
+ | |
+ pixman_region32_t clipped; | |
+ pixman_region32_init(&clipped); | |
+ pixman_region32_intersect_rect(&clipped, event->damage, | |
+ 0, 0, output->damage_ring.width, output->damage_ring.height); | |
+ bool intersects = pixman_region32_not_empty(&clipped); | |
+ if (intersects) { | |
+ pixman_region32_union(&output->cursor_damage, &output->cursor_damage, &clipped); | |
+ if (!output->wlr_output->no_frames_for_cursor_moves) { | |
+ wlr_output_schedule_frame(output->wlr_output); | |
+ } | |
} | |
+ pixman_region32_fini(&clipped); | |
} | |
static void handle_frame(struct wl_listener *listener, void *user_data) { | |
diff --git a/sway/tree/output.c b/sway/tree/output.c | |
index eccab2f7..626d81a3 100644 | |
--- a/sway/tree/output.c | |
+++ b/sway/tree/output.c | |
@@ -94,6 +94,7 @@ struct sway_output *output_create(struct wlr_output *wlr_output) { | |
wlr_output->data = output; | |
output->detected_subpixel = wlr_output->subpixel; | |
output->scale_filter = SCALE_FILTER_NEAREST; | |
+ pixman_region32_init(&output->cursor_damage); | |
wl_signal_init(&output->events.disable); | |
@@ -241,6 +242,7 @@ void output_destroy(struct sway_output *output) { | |
list_free(output->workspaces); | |
list_free(output->current.workspaces); | |
wl_event_source_remove(output->repaint_timer); | |
+ pixman_region32_fini(&output->cursor_damage); | |
free(output); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/backend/drm/drm.c b/backend/drm/drm.c | |
index a4853ffa..9ede73bf 100644 | |
--- a/backend/drm/drm.c | |
+++ b/backend/drm/drm.c | |
@@ -976,7 +976,8 @@ static bool drm_connector_set_cursor(struct wlr_output *output, | |
conn->cursor_height = buffer->height; | |
} | |
- wlr_output_update_needs_frame(output); | |
+ if (!output->no_frames_for_cursor_moves) | |
+ wlr_output_update_needs_frame(output); | |
return true; | |
} | |
@@ -1006,7 +1007,8 @@ static bool drm_connector_move_cursor(struct wlr_output *output, | |
conn->cursor_x = box.x; | |
conn->cursor_y = box.y; | |
- wlr_output_update_needs_frame(output); | |
+ if (!output->no_frames_for_cursor_moves) | |
+ wlr_output_update_needs_frame(output); | |
return true; | |
} | |
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h | |
index aa3d7a18..8e321dae 100644 | |
--- a/include/wlr/types/wlr_output.h | |
+++ b/include/wlr/types/wlr_output.h | |
@@ -148,6 +148,7 @@ struct wlr_output { | |
// damage for cursors and fullscreen surface, in output-local coordinates | |
bool frame_pending; | |
float transform_matrix[9]; | |
+ bool no_frames_for_cursor_moves; | |
// true for example with VR headsets | |
bool non_desktop; |
Thank you 🙏
The PKGBUILD for sway-git
has had several updates in the past few days.
Changes to get this to build:
- No need to remove the
autoname-workspaces.py
stuff - Use
$pkgname
instead of$_pkgname
inprepare
Is this gist still relevant?
There's a new approach to this issue here: swaywm/sway#6832 (comment)
Either way this gist can be kept for archival purposes 🙂
Oh thanks for the tip! I was directed to these patches somewhere and wasn't aware there's other work going on.
Glad to help
Also make sure to try it without direct scanout, made a huge difference for me
swaywm/sway#7714 (comment)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@GrabbenD I generally pass
-C
tomakepkg
just to make sure it doesn't have some weird state from a previous build, since it clones a git repo. The packages are fast to build anyway.The way I have it set up is:
Download the PKGBUILDs for
sway-git
andwlroots-git
withyay
:Copy
wlroots.patch
into thewlroots-git
dir thatyay
created, andsway.patch
into thesway-git
dir it created.Update
wlroots-git/PKGBUILD
to make it apply the patch:Click for diff
Update
sway-git/PKGBUILD
to make it apply the patch:Click for diff
Build and install both packages:
I can't really say whether you were using your locally built one or not before honestly. But it makes sense that you'd need to patch wlroots too if you've bundled wlroots into the same package as sway at least. 🤷
Those build errors are entirely unrelated to the patch though. It doesn't modify anything that could cause those errors. It's possible the hashes you picked for wlroots and sway are just incompatible? If you switch to using the
sway-git
andwlroots-git
packages instead they will clone the latestmaster
branch each time you build it, so you never have to update the hashes. Though atm thesway-git
package is broken in AUR, so you'd also have to fix that too:Click to expand
Edit: Actually the first set of errors are related I guess. They imply that you weren't building against the right version of wlroots yeah. If you weren't getting those errors before you must have used the correct version of it before too.