1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2025-04-07 17:44:04 -04:00

core: make monitor updates async

Moving it out of the X critical section.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-06-27 13:43:22 +01:00
parent 496f288b46
commit f05d863cb9
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4
5 changed files with 31 additions and 22 deletions

View file

@ -834,9 +834,9 @@ void ev_handle(session_t *ps, xcb_generic_event_t *ev) {
ev_shape_notify(ps, (xcb_shape_notify_event_t *)ev);
break;
}
if (ps->randr_exists &&
if (ps->randr_exists && ps->o.crop_shadow_to_monitor &&
ev->response_type == (ps->randr_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY)) {
set_root_flags(ps, ROOT_FLAGS_SCREEN_CHANGE);
x_update_monitors_async(&ps->c, &ps->monitors);
break;
}
if (ps->damage_event + XCB_DAMAGE_NOTIFY == ev->response_type) {

View file

@ -734,13 +734,6 @@ static void configure_root(session_t *ps) {
}
static void handle_root_flags(session_t *ps) {
if ((ps->root_flags & ROOT_FLAGS_SCREEN_CHANGE) != 0) {
if (ps->o.crop_shadow_to_monitor && ps->randr_exists) {
x_update_monitors(&ps->c, &ps->monitors);
}
ps->root_flags &= ~(uint64_t)ROOT_FLAGS_SCREEN_CHANGE;
}
if ((ps->root_flags & ROOT_FLAGS_CONFIGURED) != 0) {
configure_root(ps);
ps->root_flags &= ~(uint64_t)ROOT_FLAGS_CONFIGURED;
@ -2330,7 +2323,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
if (ps->randr_exists && ps->o.crop_shadow_to_monitor) {
xcb_randr_select_input(ps->c.c, ps->c.screen_info->root,
XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
x_update_monitors(&ps->c, &ps->monitors);
x_update_monitors_async(&ps->c, &ps->monitors);
}
{

View file

@ -25,8 +25,6 @@
#include "x.h"
enum root_flags {
ROOT_FLAGS_SCREEN_CHANGE = 1, // Received RandR screen change notify, we
// use this to track refresh rate changes
ROOT_FLAGS_CONFIGURED = 2 // Received configure notify on the root window
};

34
src/x.c
View file

@ -904,25 +904,43 @@ struct xvisual_info x_get_visual_info(struct x_connection *c, xcb_visualid_t vis
};
}
void x_update_monitors(struct x_connection *c, struct x_monitors *m) {
x_free_monitor_info(m);
struct x_update_monitors_request {
struct x_async_request_base base;
struct x_monitors *monitors;
};
xcb_randr_get_monitors_reply_t *r = xcb_randr_get_monitors_reply(
c->c, xcb_randr_get_monitors(c->c, c->screen_info->root, true), NULL);
if (!r) {
static void x_handle_update_monitors_reply(struct x_connection * /*c*/,
struct x_async_request_base *req_base,
xcb_raw_generic_event_t *reply_or_error) {
auto m = ((struct x_update_monitors_request *)req_base)->monitors;
free(req_base);
if (reply_or_error->response_type == 0) {
log_warn("Failed to get monitor information using RandR: %s",
x_strerror((xcb_generic_error_t *)reply_or_error));
return;
}
m->count = xcb_randr_get_monitors_monitors_length(r);
x_free_monitor_info(m);
auto reply = (xcb_randr_get_monitors_reply_t *)reply_or_error;
m->count = xcb_randr_get_monitors_monitors_length(reply);
m->regions = ccalloc(m->count, region_t);
xcb_randr_monitor_info_iterator_t monitor_info_it =
xcb_randr_get_monitors_monitors_iterator(r);
xcb_randr_get_monitors_monitors_iterator(reply);
for (int i = 0; monitor_info_it.rem; xcb_randr_monitor_info_next(&monitor_info_it)) {
xcb_randr_monitor_info_t *mi = monitor_info_it.data;
pixman_region32_init_rect(&m->regions[i++], mi->x, mi->y, mi->width, mi->height);
}
}
free(r);
void x_update_monitors_async(struct x_connection *c, struct x_monitors *m) {
auto req = ccalloc(1, struct x_update_monitors_request);
req->base.callback = x_handle_update_monitors_reply;
req->base.sequence = xcb_randr_get_monitors(c->c, c->screen_info->root, 1).sequence;
req->monitors = m;
x_await_request(c, &req->base);
}
void x_free_monitor_info(struct x_monitors *m) {

View file

@ -419,8 +419,8 @@ xcb_visualid_t x_get_visual_for_depth(xcb_screen_t *screen, uint8_t depth);
xcb_render_pictformat_t
x_get_pictfmt_for_standard(struct x_connection *c, xcb_pict_standard_t std);
/// Populates a `struct x_monitors` with the current monitor configuration.
void x_update_monitors(struct x_connection *, struct x_monitors *);
/// Populates a `struct x_monitors` with the current monitor configuration asynchronously.
void x_update_monitors_async(struct x_connection *, struct x_monitors *);
/// Free memory allocated for a `struct x_monitors`.
void x_free_monitor_info(struct x_monitors *);