mirror of
https://codeberg.org/dwl/dwl-patches.git
synced 2025-10-27 02:04:16 +00:00
update tearing
This commit is contained in:
parent
f4a18a4bcc
commit
33bf4e208e
@ -1,17 +1,17 @@
|
|||||||
### Description
|
### Description
|
||||||
This patch adds support for tearing protocol. To get it working `export WLR_DRM_NO_ATOMIC=1` is probably required.
|
This patch adds support for tearing protocol. To get it working `export WLR_DRM_NO_ATOMIC=1` is probably required.
|
||||||
Setting `ForceTearingRule` is also probably required since surfaces always receive presentation hint 0 (VSYNC) as far as i can tell.
|
Some apps would send ASYNC hint and tearing will "just work", otherwise it's possible to force specified clients to tear with a rule.
|
||||||
|
|
||||||
Set rules in the config.h (exact string match):
|
Set rules in the config.h (exact string match):
|
||||||
```
|
```
|
||||||
static const ForceTearingRule force_tearing[] = {
|
static const ForceTearingRule force_tearing[] = {
|
||||||
{.title = "", .appid = "oni.exe"},
|
|
||||||
{.title = "", .appid = "hl_linux"},
|
{.title = "", .appid = "hl_linux"},
|
||||||
{.title = "", .appid = "steam_app_210970"},
|
{.title = "Warcraft III", .appid = ""},
|
||||||
|
{.title = "", .appid = "gamescope"},
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
### Download
|
### Download
|
||||||
- [git branch](https://codeberg.org/korei999/dwl/src/branch/tearing)
|
- [git branch](https://codeberg.org/korei999/dwl/src/branch/tearing)
|
||||||
- [2024-08-15](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/tearing/tearing.patch)
|
- [2024-09-18](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/tearing/tearing.patch)
|
||||||
### Authors
|
### Authors
|
||||||
- [korei999](https://codeberg.org/korei999)
|
- [korei999](https://codeberg.org/korei999)
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
From d8856938de1e41b820c5e7b27d317a305c1b0ab8 Mon Sep 17 00:00:00 2001
|
From 66b2e1646bee8502a3715403c165015bd019438c Mon Sep 17 00:00:00 2001
|
||||||
From: korei999 <ju7t1xe@gmail.com>
|
From: korei999 <ju7t1xe@gmail.com>
|
||||||
Date: Thu, 15 Aug 2024 01:25:59 +0300
|
Date: Wed, 18 Sep 2024 20:11:22 +0300
|
||||||
Subject: [PATCH] implement tearing protocol
|
Subject: [PATCH] implement tearing protocol
|
||||||
|
|
||||||
---
|
---
|
||||||
Makefile | 5 +-
|
Makefile | 5 +-
|
||||||
config.def.h | 5 ++
|
config.def.h | 8 +++
|
||||||
dwl.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++----
|
dwl.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++----
|
||||||
3 files changed, 173 insertions(+), 15 deletions(-)
|
3 files changed, 182 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
diff --git a/Makefile b/Makefile
|
diff --git a/Makefile b/Makefile
|
||||||
index 8db7409..6edc7d7 100644
|
index 8db7409..6edc7d7 100644
|
||||||
@ -33,23 +33,26 @@ index 8db7409..6edc7d7 100644
|
|||||||
config.h:
|
config.h:
|
||||||
cp config.def.h $@
|
cp config.def.h $@
|
||||||
diff --git a/config.def.h b/config.def.h
|
diff --git a/config.def.h b/config.def.h
|
||||||
index 22d2171..c928330 100644
|
index 22d2171..52d38d3 100644
|
||||||
--- a/config.def.h
|
--- a/config.def.h
|
||||||
+++ b/config.def.h
|
+++ b/config.def.h
|
||||||
@@ -28,6 +28,11 @@ static const Rule rules[] = {
|
@@ -28,6 +28,14 @@ static const Rule rules[] = {
|
||||||
{ "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
|
{ "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
+/* tearing */
|
||||||
|
+static int tearing_allowed = 1;
|
||||||
+static const ForceTearingRule force_tearing[] = {
|
+static const ForceTearingRule force_tearing[] = {
|
||||||
+ {.title = "", .appid = "oni.exe"},
|
|
||||||
+ {.title = "", .appid = "hl_linux"},
|
+ {.title = "", .appid = "hl_linux"},
|
||||||
|
+ {.title = "Warcraft III", .appid = ""},
|
||||||
|
+ {.title = "", .appid = "gamescope"},
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
/* layout(s) */
|
/* layout(s) */
|
||||||
static const Layout layouts[] = {
|
static const Layout layouts[] = {
|
||||||
/* symbol arrange function */
|
/* symbol arrange function */
|
||||||
diff --git a/dwl.c b/dwl.c
|
diff --git a/dwl.c b/dwl.c
|
||||||
index 8a587d1..5546e26 100644
|
index dc0c861..44be1bf 100644
|
||||||
--- a/dwl.c
|
--- a/dwl.c
|
||||||
+++ b/dwl.c
|
+++ b/dwl.c
|
||||||
@@ -51,6 +51,7 @@
|
@@ -51,6 +51,7 @@
|
||||||
@ -72,7 +75,7 @@ index 8a587d1..5546e26 100644
|
|||||||
typedef union {
|
typedef union {
|
||||||
int i;
|
int i;
|
||||||
uint32_t ui;
|
uint32_t ui;
|
||||||
@@ -142,6 +148,7 @@ typedef struct {
|
@@ -143,6 +149,7 @@ typedef struct {
|
||||||
uint32_t tags;
|
uint32_t tags;
|
||||||
int isfloating, isurgent, isfullscreen;
|
int isfloating, isurgent, isfullscreen;
|
||||||
uint32_t resize; /* configure serial of a pending resize */
|
uint32_t resize; /* configure serial of a pending resize */
|
||||||
@ -100,15 +103,7 @@ index 8a587d1..5546e26 100644
|
|||||||
/* function declarations */
|
/* function declarations */
|
||||||
static void applybounds(Client *c, struct wlr_box *bbox);
|
static void applybounds(Client *c, struct wlr_box *bbox);
|
||||||
static void applyrules(Client *c);
|
static void applyrules(Client *c);
|
||||||
@@ -256,6 +276,7 @@ static void chvt(const Arg *arg);
|
@@ -293,6 +313,9 @@ static Client *focustop(Monitor *m);
|
||||||
static void checkidleinhibitor(struct wlr_surface *exclude);
|
|
||||||
static void cleanup(void);
|
|
||||||
static void cleanupmon(struct wl_listener *listener, void *data);
|
|
||||||
+static bool clientcantear(Client* c);
|
|
||||||
static void closemon(Monitor *m);
|
|
||||||
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
|
|
||||||
static void commitnotify(struct wl_listener *listener, void *data);
|
|
||||||
@@ -293,6 +314,9 @@ static Client *focustop(Monitor *m);
|
|
||||||
static void fullscreennotify(struct wl_listener *listener, void *data);
|
static void fullscreennotify(struct wl_listener *listener, void *data);
|
||||||
static void gpureset(struct wl_listener *listener, void *data);
|
static void gpureset(struct wl_listener *listener, void *data);
|
||||||
static void handlesig(int signo);
|
static void handlesig(int signo);
|
||||||
@ -118,15 +113,15 @@ index 8a587d1..5546e26 100644
|
|||||||
static void incnmaster(const Arg *arg);
|
static void incnmaster(const Arg *arg);
|
||||||
static void inputdevice(struct wl_listener *listener, void *data);
|
static void inputdevice(struct wl_listener *listener, void *data);
|
||||||
static int keybinding(uint32_t mods, xkb_keysym_t sym);
|
static int keybinding(uint32_t mods, xkb_keysym_t sym);
|
||||||
@@ -309,6 +333,7 @@ static void motionnotify(uint32_t time, struct wlr_input_device *device, double
|
@@ -309,6 +332,7 @@ static void motionnotify(uint32_t time, struct wlr_input_device *device, double
|
||||||
double sy, double sx_unaccel, double sy_unaccel);
|
double sy, double sx_unaccel, double sy_unaccel);
|
||||||
static void motionrelative(struct wl_listener *listener, void *data);
|
static void motionrelative(struct wl_listener *listener, void *data);
|
||||||
static void moveresize(const Arg *arg);
|
static void moveresize(const Arg *arg);
|
||||||
+static bool moncantear(Monitor* m);
|
+static int moncantear(Monitor* m);
|
||||||
static void outputmgrapply(struct wl_listener *listener, void *data);
|
static void outputmgrapply(struct wl_listener *listener, void *data);
|
||||||
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
|
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
|
||||||
static void outputmgrtest(struct wl_listener *listener, void *data);
|
static void outputmgrtest(struct wl_listener *listener, void *data);
|
||||||
@@ -323,6 +348,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data);
|
@@ -323,6 +347,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data);
|
||||||
static void requestmonstate(struct wl_listener *listener, void *data);
|
static void requestmonstate(struct wl_listener *listener, void *data);
|
||||||
static void resize(Client *c, struct wlr_box geo, int interact);
|
static void resize(Client *c, struct wlr_box geo, int interact);
|
||||||
static void run(char *startup_cmd);
|
static void run(char *startup_cmd);
|
||||||
@ -134,7 +129,7 @@ index 8a587d1..5546e26 100644
|
|||||||
static void setcursor(struct wl_listener *listener, void *data);
|
static void setcursor(struct wl_listener *listener, void *data);
|
||||||
static void setcursorshape(struct wl_listener *listener, void *data);
|
static void setcursorshape(struct wl_listener *listener, void *data);
|
||||||
static void setfloating(Client *c, int floating);
|
static void setfloating(Client *c, int floating);
|
||||||
@@ -400,6 +426,10 @@ static struct wlr_scene_rect *locked_bg;
|
@@ -400,6 +425,10 @@ static struct wlr_scene_rect *locked_bg;
|
||||||
static struct wlr_session_lock_v1 *cur_lock;
|
static struct wlr_session_lock_v1 *cur_lock;
|
||||||
static struct wl_listener lock_listener = {.notify = locksession};
|
static struct wl_listener lock_listener = {.notify = locksession};
|
||||||
|
|
||||||
@ -145,41 +140,7 @@ index 8a587d1..5546e26 100644
|
|||||||
static struct wlr_seat *seat;
|
static struct wlr_seat *seat;
|
||||||
static KeyboardGroup *kb_group;
|
static KeyboardGroup *kb_group;
|
||||||
static unsigned int cursor_mode;
|
static unsigned int cursor_mode;
|
||||||
@@ -722,6 +752,33 @@ cleanupmon(struct wl_listener *listener, void *data)
|
@@ -1510,6 +1539,69 @@ handlesig(int signo)
|
||||||
free(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
+bool
|
|
||||||
+clientcantear(Client* c)
|
|
||||||
+{
|
|
||||||
+ bool res = false;
|
|
||||||
+ const char* appid = client_get_appid(c);
|
|
||||||
+ const char* title = client_get_title(c);
|
|
||||||
+
|
|
||||||
+ switch (c->tearing_hint) {
|
|
||||||
+ case WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC:
|
|
||||||
+ res = false;
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC:
|
|
||||||
+ return true;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ for (unsigned i = 0; i < LENGTH(force_tearing); i++) {
|
|
||||||
+ if (strcmp(force_tearing[i].appid, appid) == 0)
|
|
||||||
+ return true;
|
|
||||||
+
|
|
||||||
+ if (strcmp(force_tearing[i].title, title) == 0)
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return res;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
closemon(Monitor *m)
|
|
||||||
{
|
|
||||||
@@ -1512,6 +1569,61 @@ handlesig(int signo)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,18 +151,27 @@ index 8a587d1..5546e26 100644
|
|||||||
+ struct TearingController *controller = wl_container_of(listener, controller, set_hint);
|
+ struct TearingController *controller = wl_container_of(listener, controller, set_hint);
|
||||||
+
|
+
|
||||||
+ struct wlr_xdg_surface *surface = wlr_xdg_surface_try_from_wlr_surface(controller->tearing_control->surface);
|
+ struct wlr_xdg_surface *surface = wlr_xdg_surface_try_from_wlr_surface(controller->tearing_control->surface);
|
||||||
|
+#ifdef XWAYLAND
|
||||||
|
+ struct wlr_xwayland_surface *xsurface = wlr_xwayland_surface_try_from_wlr_surface(controller->tearing_control->surface);
|
||||||
|
+#endif
|
||||||
+
|
+
|
||||||
+ /* FIXME: broken appearantly */
|
|
||||||
+ wl_list_for_each(i, &fstack, flink) {
|
+ wl_list_for_each(i, &fstack, flink) {
|
||||||
+ if (VISIBLEON(i, selmon))
|
+ if (i->surface.xdg == surface
|
||||||
+ if (i->surface.xdg == surface) {
|
+#ifdef XWAYLAND
|
||||||
|
+ || i->surface.xwayland == xsurface
|
||||||
|
+#endif
|
||||||
|
+ ) {
|
||||||
+ c = i;
|
+ c = i;
|
||||||
+ break;
|
+ break;
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (c) {
|
+ if (c) {
|
||||||
+ fprintf(stderr, "FOUND\n");
|
+ enum wp_tearing_control_v1_presentation_hint hint = controller->tearing_control->current;
|
||||||
|
+ fprintf(
|
||||||
|
+ stderr, "TEARING: found surface: %p(appid: '%s', title: '%s'), hint: %d(%s)\n",
|
||||||
|
+ (void*)c, client_get_appid(c), client_get_title(c), hint, hint ? "ASYNC" : "VSYNC"
|
||||||
|
+ );
|
||||||
+ c->tearing_hint = controller->tearing_control->current;
|
+ c->tearing_hint = controller->tearing_control->current;
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
@ -210,6 +180,9 @@ index 8a587d1..5546e26 100644
|
|||||||
+handletearingcontrollerdestroy(struct wl_listener *listener, void *data)
|
+handletearingcontrollerdestroy(struct wl_listener *listener, void *data)
|
||||||
+{
|
+{
|
||||||
+ struct TearingController *controller = wl_container_of(listener, controller, destroy);
|
+ struct TearingController *controller = wl_container_of(listener, controller, destroy);
|
||||||
|
+
|
||||||
|
+ wl_list_remove(&controller->set_hint.link);
|
||||||
|
+ wl_list_remove(&controller->destroy.link);
|
||||||
+ wl_list_remove(&controller->link);
|
+ wl_list_remove(&controller->link);
|
||||||
+ free(controller);
|
+ free(controller);
|
||||||
+}
|
+}
|
||||||
@ -218,47 +191,83 @@ index 8a587d1..5546e26 100644
|
|||||||
+handlenewtearinghint(struct wl_listener *listener, void *data)
|
+handlenewtearinghint(struct wl_listener *listener, void *data)
|
||||||
+{
|
+{
|
||||||
+ struct wlr_tearing_control_v1 *tearing_control = data;
|
+ 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(tearing_control_v1, tearing_control->surface);
|
|
||||||
+ struct TearingController *controller = calloc(1, sizeof(struct TearingController));
|
+ struct TearingController *controller = calloc(1, sizeof(struct TearingController));
|
||||||
+
|
+
|
||||||
+ fprintf(stderr, "New presentation hint %d received for surface %p\n\n", hint, (void*)tearing_control->surface);
|
+ if (!controller)
|
||||||
+
|
|
||||||
+ if (!controller) {
|
|
||||||
+ fprintf(stderr, "!controller\n");
|
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
|
||||||
+
|
+
|
||||||
+ controller->tearing_control = tearing_control;
|
+ controller->tearing_control = tearing_control;
|
||||||
+ controller->set_hint.notify = handletearingcontrollersethint;
|
+ controller->set_hint.notify = handletearingcontrollersethint;
|
||||||
+ wl_signal_add(&tearing_control->events.set_hint, &controller->set_hint);
|
+ wl_signal_add(&tearing_control->events.set_hint, &controller->set_hint);
|
||||||
|
+
|
||||||
+ controller->destroy.notify = handletearingcontrollerdestroy;
|
+ controller->destroy.notify = handletearingcontrollerdestroy;
|
||||||
+ wl_signal_add(&tearing_control->events.destroy, &controller->destroy);
|
+ wl_signal_add(&tearing_control->events.destroy, &controller->destroy);
|
||||||
+ wl_list_init(&controller->link);
|
|
||||||
+
|
+
|
||||||
|
+ wl_list_init(&controller->link);
|
||||||
+ wl_list_insert(&tearing_controllers, &controller->link);
|
+ wl_list_insert(&tearing_controllers, &controller->link);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
void
|
void
|
||||||
incnmaster(const Arg *arg)
|
incnmaster(const Arg *arg)
|
||||||
{
|
{
|
||||||
@@ -1924,6 +2036,16 @@ moveresize(const Arg *arg)
|
@@ -1677,6 +1769,33 @@ locksession(struct wl_listener *listener, void *data)
|
||||||
|
wlr_session_lock_v1_send_locked(session_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline void
|
||||||
|
+forcetearingrule(Client *c)
|
||||||
|
+{
|
||||||
|
+ int success = 0;
|
||||||
|
+ const char* appid = client_get_appid(c);
|
||||||
|
+ const char* title = client_get_title(c);
|
||||||
|
+
|
||||||
|
+ for (unsigned i = 0; i < LENGTH(force_tearing); i++) {
|
||||||
|
+ if (appid)
|
||||||
|
+ if (strcmp(force_tearing[i].appid, appid) == 0) {
|
||||||
|
+ success = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (title)
|
||||||
|
+ if (strcmp(force_tearing[i].title, title) == 0) {
|
||||||
|
+ success = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (success) {
|
||||||
|
+ c->tearing_hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
|
||||||
|
+ fprintf(stderr, "tearing forced for: appid: '%s', title: '%s'\n", appid, title);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
mapnotify(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
@@ -1686,6 +1805,8 @@ mapnotify(struct wl_listener *listener, void *data)
|
||||||
|
Monitor *m;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
+ forcetearingrule(c);
|
||||||
|
+
|
||||||
|
/* Create scene tree for this client and its border */
|
||||||
|
c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]);
|
||||||
|
/* Enabled later by a call to arrange() */
|
||||||
|
@@ -1924,6 +2045,13 @@ moveresize(const Arg *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+bool
|
+int
|
||||||
+moncantear(Monitor* m)
|
+moncantear(Monitor* m)
|
||||||
+{
|
+{
|
||||||
+ Client *c = focustop(m);
|
+ Client *c = focustop(m);
|
||||||
+ if (c && c->isfullscreen && clientcantear(c))
|
+ return (c && c->isfullscreen && c->tearing_hint); /* 1 == ASYNC */
|
||||||
+ return true;
|
|
||||||
+
|
|
||||||
+ return false;
|
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
void
|
void
|
||||||
outputmgrapply(struct wl_listener *listener, void *data)
|
outputmgrapply(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
@@ -2093,27 +2215,40 @@ quit(const Arg *arg)
|
@@ -2093,27 +2221,40 @@ quit(const Arg *arg)
|
||||||
void
|
void
|
||||||
rendermon(struct wl_listener *listener, void *data)
|
rendermon(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
@ -288,7 +297,7 @@ index 8a587d1..5546e26 100644
|
|||||||
+ goto skip;
|
+ goto skip;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (moncantear(m)) {
|
+ if (tearing_allowed && moncantear(m)) {
|
||||||
+ pending.tearing_page_flip = true;
|
+ pending.tearing_page_flip = true;
|
||||||
+
|
+
|
||||||
+ if (!wlr_output_test_state(m->wlr_output, &pending)) {
|
+ if (!wlr_output_test_state(m->wlr_output, &pending)) {
|
||||||
@ -313,7 +322,7 @@ index 8a587d1..5546e26 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2237,6 +2372,16 @@ run(char *startup_cmd)
|
@@ -2237,6 +2378,16 @@ run(char *startup_cmd)
|
||||||
wl_display_run(dpy);
|
wl_display_run(dpy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +339,7 @@ index 8a587d1..5546e26 100644
|
|||||||
void
|
void
|
||||||
setcursor(struct wl_listener *listener, void *data)
|
setcursor(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
@@ -2584,6 +2729,11 @@ setup(void)
|
@@ -2584,6 +2735,11 @@ setup(void)
|
||||||
LISTEN_STATIC(&output_mgr->events.apply, outputmgrapply);
|
LISTEN_STATIC(&output_mgr->events.apply, outputmgrapply);
|
||||||
LISTEN_STATIC(&output_mgr->events.test, outputmgrtest);
|
LISTEN_STATIC(&output_mgr->events.test, outputmgrtest);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user