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:
parent
496f288b46
commit
f05d863cb9
5 changed files with 31 additions and 22 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -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
34
src/x.c
|
@ -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) {
|
||||
|
|
4
src/x.h
4
src/x.h
|
@ -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 *);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue