aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-09-14 01:57:00 +0200
committerdec05eba <dec05eba@protonmail.com>2024-09-14 02:27:48 +0200
commit714561987e264c5f3e9fb01d9ebbf545225b35b7 (patch)
tree94fc3c271516b873d2f0b3c463fa81c590e849bd
parent8acb34638212ab8dba0d48a57dd40721203a7a44 (diff)
Properly damage if moving cursor
Only damage if cursor is inside the target area
-rw-r--r--include/cursor.h2
-rw-r--r--include/damage.h8
-rw-r--r--include/egl.h2
-rw-r--r--src/capture/kms.c2
-rw-r--r--src/capture/xcomposite.c2
-rw-r--r--src/cursor.c2
-rw-r--r--src/damage.c70
-rw-r--r--src/egl.c2
-rw-r--r--src/main.cpp5
9 files changed, 79 insertions, 16 deletions
diff --git a/include/cursor.h b/include/cursor.h
index 2f26dfd..323d098 100644
--- a/include/cursor.h
+++ b/include/cursor.h
@@ -24,7 +24,7 @@ int gsr_cursor_init(gsr_cursor *self, gsr_egl *egl, Display *display);
void gsr_cursor_deinit(gsr_cursor *self);
/* Returns true if the cursor image has updated or if the cursor has moved */
-bool gsr_cursor_update(gsr_cursor *self, XEvent *xev);
+bool gsr_cursor_on_event(gsr_cursor *self, XEvent *xev);
void gsr_cursor_tick(gsr_cursor *self, Window relative_to);
#endif /* GSR_CURSOR_H */
diff --git a/include/damage.h b/include/damage.h
index 68cd0d2..2bf43d7 100644
--- a/include/damage.h
+++ b/include/damage.h
@@ -21,13 +21,16 @@ typedef struct {
int damage_event;
int damage_error;
- uint64_t window;
uint64_t damage;
bool damaged;
int randr_event;
int randr_error;
+ uint64_t window;
+ //vec2i window_pos;
+ vec2i window_size;
+
vec2i cursor_position; /* Relative to |window| */
gsr_monitor monitor;
char monitor_name[32];
@@ -38,7 +41,8 @@ void gsr_damage_deinit(gsr_damage *self);
bool gsr_damage_set_target_window(gsr_damage *self, uint64_t window);
bool gsr_damage_set_target_monitor(gsr_damage *self, const char *monitor_name);
-void gsr_damage_update(gsr_damage *self, XEvent *xev);
+void gsr_damage_on_event(gsr_damage *self, XEvent *xev);
+void gsr_damage_tick(gsr_damage *self);
/* Also returns true if damage tracking is not available */
bool gsr_damage_is_damaged(gsr_damage *self);
void gsr_damage_clear(gsr_damage *self);
diff --git a/include/egl.h b/include/egl.h
index 9e50ad0..61890b4 100644
--- a/include/egl.h
+++ b/include/egl.h
@@ -314,7 +314,7 @@ bool gsr_egl_load(gsr_egl *self, Display *dpy, bool wayland, bool is_monitor_cap
void gsr_egl_unload(gsr_egl *self);
/* Returns true if an event is available */
-bool gsr_egl_update(gsr_egl *self);
+bool gsr_egl_process_event(gsr_egl *self);
/* Does opengl swap with egl or glx, depending on which one is active */
void gsr_egl_swap_buffers(gsr_egl *self);
diff --git a/src/capture/kms.c b/src/capture/kms.c
index 9ba4bd2..9287a8b 100644
--- a/src/capture/kms.c
+++ b/src/capture/kms.c
@@ -203,7 +203,7 @@ static void gsr_capture_kms_on_event(gsr_capture *cap, gsr_egl *egl) {
return;
XEvent *xev = gsr_egl_get_event_data(egl);
- gsr_cursor_update(&self->x11_cursor, xev);
+ gsr_cursor_on_event(&self->x11_cursor, xev);
}
static float monitor_rotation_to_radians(gsr_monitor_rotation rot) {
diff --git a/src/capture/xcomposite.c b/src/capture/xcomposite.c
index e99cabf..1b6021b 100644
--- a/src/capture/xcomposite.c
+++ b/src/capture/xcomposite.c
@@ -230,7 +230,7 @@ static void gsr_capture_xcomposite_on_event(gsr_capture *cap, gsr_egl *egl) {
}
}
- gsr_cursor_update(&self->cursor, xev);
+ gsr_cursor_on_event(&self->cursor, xev);
}
static bool gsr_capture_xcomposite_should_stop(gsr_capture *cap, bool *err) {
diff --git a/src/cursor.c b/src/cursor.c
index ffa1562..b1cc397 100644
--- a/src/cursor.c
+++ b/src/cursor.c
@@ -155,7 +155,7 @@ void gsr_cursor_deinit(gsr_cursor *self) {
self->egl = NULL;
}
-bool gsr_cursor_update(gsr_cursor *self, XEvent *xev) {
+bool gsr_cursor_on_event(gsr_cursor *self, XEvent *xev) {
bool updated = false;
XGenericEventCookie *cookie = (XGenericEventCookie*)&xev->xcookie;
const Bool got_event_data = XGetEventData(self->display, cookie);
diff --git a/src/damage.c b/src/damage.c
index 2eda5d7..168ed6b 100644
--- a/src/damage.c
+++ b/src/damage.c
@@ -84,7 +84,26 @@ bool gsr_damage_set_target_window(gsr_damage *self, uint64_t window) {
self->damage = None;
}
+ if(self->window)
+ XSelectInput(self->egl->x11.dpy, self->window, 0);
+
self->window = window;
+ XSelectInput(self->egl->x11.dpy, self->window, StructureNotifyMask | ExposureMask);
+
+ XWindowAttributes win_attr;
+ win_attr.x = 0;
+ win_attr.y = 0;
+ win_attr.width = 0;
+ win_attr.height = 0;
+ if(!XGetWindowAttributes(self->egl->x11.dpy, self->window, &win_attr))
+ fprintf(stderr, "gsr warning: gsr_damage_set_target_window failed: failed to get window attributes: %ld\n", (long)self->window);
+
+ //self->window_pos.x = win_attr.x;
+ //self->window_pos.y = win_attr.y;
+
+ self->window_size.x = win_attr.width;
+ self->window_size.y = win_attr.height;
+
self->damage = XDamageCreate(self->egl->x11.dpy, window, XDamageReportNonEmpty);
if(self->damage) {
XDamageSubtract(self->egl->x11.dpy, self->damage, None, None);
@@ -114,6 +133,9 @@ bool gsr_damage_set_target_monitor(gsr_damage *self, const char *monitor_name) {
if(!get_monitor_by_name(self->egl, GSR_CONNECTION_X11, monitor_name, &self->monitor))
fprintf(stderr, "gsr warning: gsr_damage_set_target_monitor: failed to find monitor: %s\n", monitor_name);
+ if(self->window)
+ XSelectInput(self->egl->x11.dpy, self->window, 0);
+
self->window = DefaultRootWindow(self->egl->x11.dpy);
self->damage = XDamageCreate(self->egl->x11.dpy, self->window, XDamageReportNonEmpty);
if(self->damage) {
@@ -221,22 +243,53 @@ static void gsr_damage_on_damage_event(gsr_damage *self, XEvent *xev) {
XFlush(self->egl->x11.dpy);
}
-static void gsr_damage_update_cursor(gsr_damage *self) {
- Window dummy_window;
+static void gsr_damage_on_event_cursor(gsr_damage *self) {
+ Window root_return = None;
+ Window child_return = None;
int dummy_i;
unsigned int dummy_u;
vec2i cursor_position = {0, 0};
- XQueryPointer(self->egl->x11.dpy, self->window, &dummy_window, &dummy_window, &dummy_i, &dummy_i, &cursor_position.x, &cursor_position.y, &dummy_u);
+ XQueryPointer(self->egl->x11.dpy, self->window, &root_return, &child_return, &dummy_i, &dummy_i, &cursor_position.x, &cursor_position.y, &dummy_u);
if(cursor_position.x != self->cursor_position.x || cursor_position.y != self->cursor_position.y) {
self->cursor_position = cursor_position;
- self->damaged = true;
+ const gsr_rectangle cursor_region = { self->cursor_position, {64, 64} }; // TODO: Track cursor size
+ switch(self->track_type) {
+ case GSR_DAMAGE_TRACK_NONE: {
+ self->damaged = true;
+ break;
+ }
+ case GSR_DAMAGE_TRACK_WINDOW: {
+ const gsr_rectangle window_region = { (vec2i){0, 0}, self->window_size };
+ self->damaged = self->window_size.x == 0 || rectangles_intersect(window_region, cursor_region);
+ break;
+ }
+ case GSR_DAMAGE_TRACK_MONITOR: {
+ const gsr_rectangle monitor_region = { self->monitor.pos, self->monitor.size };
+ self->damaged = self->monitor.monitor_identifier == 0 || rectangles_intersect(monitor_region, cursor_region);
+ break;
+ }
+ }
}
}
-void gsr_damage_update(gsr_damage *self, XEvent *xev) {
+static void gsr_damage_on_window_configure_notify(gsr_damage *self, XEvent *xev) {
+ if(xev->xconfigure.window != self->window)
+ return;
+
+ //self->window_pos.x = xev->xconfigure.x;
+ //self->window_pos.y = xev->xconfigure.y;
+
+ self->window_size.x = xev->xconfigure.width;
+ self->window_size.y = xev->xconfigure.height;
+}
+
+void gsr_damage_on_event(gsr_damage *self, XEvent *xev) {
if(self->damage_event == 0 || self->track_type == GSR_DAMAGE_TRACK_NONE)
return;
+ if(self->track_type == GSR_DAMAGE_TRACK_WINDOW && xev->type == ConfigureNotify)
+ gsr_damage_on_window_configure_notify(self, xev);
+
if(self->randr_event) {
if(xev->type == self->randr_event + RRScreenChangeNotify)
XRRUpdateConfiguration(xev);
@@ -247,9 +300,14 @@ void gsr_damage_update(gsr_damage *self, XEvent *xev) {
if(self->damage_event && xev->type == self->damage_event + XDamageNotify)
gsr_damage_on_damage_event(self, xev);
+}
+
+void gsr_damage_tick(gsr_damage *self) {
+ if(self->damage_event == 0 || self->track_type == GSR_DAMAGE_TRACK_NONE)
+ return;
if(self->track_cursor && !self->damaged)
- gsr_damage_update_cursor(self);
+ gsr_damage_on_event_cursor(self);
}
bool gsr_damage_is_damaged(gsr_damage *self) {
diff --git a/src/egl.c b/src/egl.c
index ea69796..b4e3902 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -676,7 +676,7 @@ void gsr_egl_unload(gsr_egl *self) {
memset(self, 0, sizeof(gsr_egl));
}
-bool gsr_egl_update(gsr_egl *self) {
+bool gsr_egl_process_event(gsr_egl *self) {
switch(gsr_egl_get_display_server(self)) {
case GSR_DISPLAY_SERVER_X11: {
if(XPending(self->x11.dpy)) {
diff --git a/src/main.cpp b/src/main.cpp
index 2cefd0a..2c302ab 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3318,10 +3318,11 @@ int main(int argc, char **argv) {
while(running) {
const double frame_start = clock_get_monotonic_seconds();
- while(gsr_egl_update(&egl)) {
+ while(gsr_egl_process_event(&egl)) {
gsr_capture_on_event(capture, &egl);
- gsr_damage_update(&damage, gsr_egl_get_event_data(&egl));
+ gsr_damage_on_event(&damage, gsr_egl_get_event_data(&egl));
}
+ gsr_damage_tick(&damage);
gsr_capture_tick(capture, video_codec_context);
if(!is_monitor_capture) {