mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-03-06 01:40:52 -05:00
backend/x11: listen to _NET_WM_STATE changes for determining hidden
Some window managers don't unmap windows when they're hidden. Also check the _NET_WM_STATE property for _NET_WM_STATE_HIDDEN. This way if the window is hidden or unmapped, then we won't send updates.
This commit is contained in:
parent
04d448317a
commit
df8d12fa03
3 changed files with 48 additions and 4 deletions
|
|
@ -131,9 +131,47 @@ static void handle_x11_event(struct wlr_x11_backend *x11,
|
||||||
struct wlr_x11_output *output =
|
struct wlr_x11_output *output =
|
||||||
get_x11_output_from_window_id(x11, ev->window);
|
get_x11_output_from_window_id(x11, ev->window);
|
||||||
if (output != NULL) {
|
if (output != NULL) {
|
||||||
wlr_log(WLR_DEBUG, "Window mapped, resuming updates");
|
wlr_log(WLR_DEBUG, "Window mapped%s", !output->hidden ? ", resuming updates" : "");
|
||||||
output->mapped = true;
|
output->mapped = true;
|
||||||
wlr_output_send_frame(&output->wlr_output);
|
if (!output->hidden) {
|
||||||
|
wlr_output_send_frame(&output->wlr_output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XCB_PROPERTY_NOTIFY: {
|
||||||
|
xcb_property_notify_event_t *ev = (xcb_property_notify_event_t *)event;
|
||||||
|
struct wlr_x11_output *output =
|
||||||
|
get_x11_output_from_window_id(x11, ev->window);
|
||||||
|
if (output == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ev->atom == x11->atoms.net_wm_state) {
|
||||||
|
xcb_get_property_cookie_t cookie =
|
||||||
|
xcb_get_property(x11->xcb, false, ev->window,
|
||||||
|
ev->atom, XCB_ATOM_ATOM, 0, 32);
|
||||||
|
xcb_get_property_reply_t *reply =
|
||||||
|
xcb_get_property_reply(x11->xcb, cookie, NULL);
|
||||||
|
if (reply->type != XCB_ATOM_ATOM) {
|
||||||
|
free(reply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xcb_atom_t *atoms = xcb_get_property_value(reply);
|
||||||
|
bool was_hidden = output->hidden;
|
||||||
|
output->hidden = false;
|
||||||
|
for (int i = 0; i < xcb_get_property_value_length(reply); i++) {
|
||||||
|
if (atoms[i] == x11->atoms.net_wm_state_hidden) {
|
||||||
|
wlr_log(WLR_DEBUG, "Window hidden, stopping updates");
|
||||||
|
output->hidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(reply);
|
||||||
|
if (was_hidden && !output->hidden) {
|
||||||
|
wlr_log(WLR_DEBUG, "Window no longer hidden%s", output->mapped ? ", resuming updates" : "");
|
||||||
|
if (output->mapped) {
|
||||||
|
wlr_output_send_frame(&output->wlr_output);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -432,6 +470,8 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
||||||
} atom[] = {
|
} atom[] = {
|
||||||
{ .name = "WM_PROTOCOLS", .atom = &x11->atoms.wm_protocols },
|
{ .name = "WM_PROTOCOLS", .atom = &x11->atoms.wm_protocols },
|
||||||
{ .name = "WM_DELETE_WINDOW", .atom = &x11->atoms.wm_delete_window },
|
{ .name = "WM_DELETE_WINDOW", .atom = &x11->atoms.wm_delete_window },
|
||||||
|
{ .name = "_NET_WM_STATE", .atom = &x11->atoms.net_wm_state },
|
||||||
|
{ .name = "_NET_WM_STATE_HIDDEN", .atom = &x11->atoms.net_wm_state_hidden },
|
||||||
{ .name = "_NET_WM_NAME", .atom = &x11->atoms.net_wm_name },
|
{ .name = "_NET_WM_NAME", .atom = &x11->atoms.net_wm_name },
|
||||||
{ .name = "UTF8_STRING", .atom = &x11->atoms.utf8_string },
|
{ .name = "UTF8_STRING", .atom = &x11->atoms.utf8_string },
|
||||||
{ .name = "_VARIABLE_REFRESH", .atom = &x11->atoms.variable_refresh },
|
{ .name = "_VARIABLE_REFRESH", .atom = &x11->atoms.variable_refresh },
|
||||||
|
|
|
||||||
|
|
@ -560,7 +560,8 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) {
|
||||||
XCB_CW_COLORMAP | XCB_CW_CURSOR;
|
XCB_CW_COLORMAP | XCB_CW_CURSOR;
|
||||||
uint32_t values[] = {
|
uint32_t values[] = {
|
||||||
0,
|
0,
|
||||||
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY,
|
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
||||||
|
XCB_EVENT_MASK_PROPERTY_CHANGE,
|
||||||
x11->colormap,
|
x11->colormap,
|
||||||
x11->transparent_cursor,
|
x11->transparent_cursor,
|
||||||
};
|
};
|
||||||
|
|
@ -742,7 +743,7 @@ void handle_x11_present_event(struct wlr_x11_backend *x11,
|
||||||
};
|
};
|
||||||
wlr_output_send_present(&output->wlr_output, &present_event);
|
wlr_output_send_present(&output->wlr_output, &present_event);
|
||||||
|
|
||||||
if (output->mapped)
|
if (output->mapped && !output->hidden)
|
||||||
wlr_output_send_frame(&output->wlr_output);
|
wlr_output_send_frame(&output->wlr_output);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ struct wlr_x11_output {
|
||||||
|
|
||||||
uint64_t last_msc;
|
uint64_t last_msc;
|
||||||
bool mapped;
|
bool mapped;
|
||||||
|
bool hidden;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wlr_swapchain *swapchain;
|
struct wlr_swapchain *swapchain;
|
||||||
|
|
@ -99,6 +100,8 @@ struct wlr_x11_backend {
|
||||||
xcb_atom_t wm_protocols;
|
xcb_atom_t wm_protocols;
|
||||||
xcb_atom_t wm_delete_window;
|
xcb_atom_t wm_delete_window;
|
||||||
xcb_atom_t net_wm_name;
|
xcb_atom_t net_wm_name;
|
||||||
|
xcb_atom_t net_wm_state;
|
||||||
|
xcb_atom_t net_wm_state_hidden;
|
||||||
xcb_atom_t utf8_string;
|
xcb_atom_t utf8_string;
|
||||||
xcb_atom_t variable_refresh;
|
xcb_atom_t variable_refresh;
|
||||||
} atoms;
|
} atoms;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue