mirror of
https://github.com/yshui/picom.git
synced 2024-10-27 05:24:17 -04:00
win: cache the EWMH fullscreen property
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
84b9ff3148
commit
613d179f2d
3 changed files with 46 additions and 30 deletions
|
@ -565,6 +565,13 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
|||
}
|
||||
}
|
||||
|
||||
if (!ps->o.no_ewmh_fullscreen && ev->atom == ps->atoms->a_NET_WM_STATE) {
|
||||
auto w = find_toplevel(ps, ev->window);
|
||||
if (w) {
|
||||
win_set_property_stale(w, ev->atom);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for other atoms we are tracking
|
||||
for (latom_t *platom = ps->track_atom_lst; platom; platom = platom->next) {
|
||||
if (platom->atom == ev->atom) {
|
||||
|
|
67
src/win.c
67
src/win.c
|
@ -73,6 +73,11 @@ static void
|
|||
win_update_frame_extents(session_t *ps, struct managed_win *w, xcb_window_t client);
|
||||
static void win_update_prop_shadow_raw(session_t *ps, struct managed_win *w);
|
||||
static void win_update_prop_shadow(session_t *ps, struct managed_win *w);
|
||||
/**
|
||||
* Update window EWMH fullscreen state.
|
||||
*/
|
||||
bool win_update_prop_fullscreen(struct x_connection *c, const struct atom *atoms,
|
||||
struct managed_win *w);
|
||||
/**
|
||||
* Update leader of a window.
|
||||
*/
|
||||
|
@ -457,6 +462,12 @@ static void win_update_properties(session_t *ps, struct managed_win *w) {
|
|||
win_update_prop_shadow(ps, w);
|
||||
}
|
||||
|
||||
if (win_fetch_and_unset_property_stale(w, ps->atoms->a_NET_WM_STATE)) {
|
||||
if (win_update_prop_fullscreen(&ps->c, ps->atoms, w)) {
|
||||
win_set_flags(w, WIN_FLAGS_FACTOR_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
if (win_fetch_and_unset_property_stale(w, ps->atoms->aWM_CLIENT_LEADER) ||
|
||||
win_fetch_and_unset_property_stale(w, ps->atoms->aWM_TRANSIENT_FOR)) {
|
||||
win_update_leader(ps, w);
|
||||
|
@ -1012,6 +1023,30 @@ void win_update_prop_shadow(session_t *ps, struct managed_win *w) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update window EWMH fullscreen state.
|
||||
*/
|
||||
bool win_update_prop_fullscreen(struct x_connection *c, const struct atom *atoms,
|
||||
struct managed_win *w) {
|
||||
auto prop = x_get_prop(c, w->client_win, atoms->a_NET_WM_STATE, 12, XCB_ATOM_ATOM, 0);
|
||||
if (!prop.nitems) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_fullscreen = false;
|
||||
for (uint32_t i = 0; i < prop.nitems; i++) {
|
||||
if (prop.atom[i] == atoms->a_NET_WM_STATE_FULLSCREEN) {
|
||||
is_fullscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free_winprop(&prop);
|
||||
|
||||
bool changed = w->is_ewmh_fullscreen != is_fullscreen;
|
||||
w->is_ewmh_fullscreen = is_fullscreen;
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void win_determine_clip_shadow_above(session_t *ps, struct managed_win *w) {
|
||||
bool should_crop = (ps->o.wintype_option[w->window_type].clip_shadow_above ||
|
||||
c2_match(ps, w, ps->o.shadow_clip_list, NULL));
|
||||
|
@ -1723,6 +1758,7 @@ struct win *fill_win(session_t *ps, struct win *w) {
|
|||
ps->atoms->a_NET_WM_NAME, ps->atoms->aWM_CLASS,
|
||||
ps->atoms->aWM_WINDOW_ROLE, ps->atoms->a_COMPTON_SHADOW,
|
||||
ps->atoms->aWM_CLIENT_LEADER, ps->atoms->aWM_TRANSIENT_FOR,
|
||||
ps->atoms->a_NET_WM_STATE,
|
||||
};
|
||||
win_set_properties_stale(new, init_stale_props, ARR_SIZE(init_stale_props));
|
||||
|
||||
|
@ -2717,34 +2753,6 @@ static inline bool rect_is_fullscreen(const session_t *ps, int x, int y, int wid
|
|||
return (x <= 0 && y <= 0 && (x + wid) >= ps->root_width && (y + hei) >= ps->root_height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a window is full-screen using EWMH
|
||||
*
|
||||
* TODO(yshui) cache this property
|
||||
*/
|
||||
static inline bool
|
||||
win_is_fullscreen_xcb(xcb_connection_t *c, const struct atom *a, const xcb_window_t w) {
|
||||
xcb_get_property_cookie_t prop =
|
||||
xcb_get_property(c, 0, w, a->a_NET_WM_STATE, XCB_ATOM_ATOM, 0, 12);
|
||||
xcb_get_property_reply_t *reply = xcb_get_property_reply(c, prop, NULL);
|
||||
if (!reply) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reply->length) {
|
||||
xcb_atom_t *val = xcb_get_property_value(reply);
|
||||
for (uint32_t i = 0; i < reply->length; i++) {
|
||||
if (val[i] != a->a_NET_WM_STATE_FULLSCREEN) {
|
||||
continue;
|
||||
}
|
||||
free(reply);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
free(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Set flags on a window. Some sanity checks are performed
|
||||
void win_set_flags(struct managed_win *w, uint64_t flags) {
|
||||
log_debug("Set flags %" PRIu64 " to window %#010x (%s)", flags, w->base.id, w->name);
|
||||
|
@ -2830,8 +2838,7 @@ bool win_check_flags_all(struct managed_win *w, uint64_t flags) {
|
|||
* It's not using w->border_size for performance measures.
|
||||
*/
|
||||
bool win_is_fullscreen(const session_t *ps, const struct managed_win *w) {
|
||||
if (!ps->o.no_ewmh_fullscreen &&
|
||||
win_is_fullscreen_xcb(ps->c.c, ps->atoms, w->client_win)) {
|
||||
if (!ps->o.no_ewmh_fullscreen && w->is_ewmh_fullscreen) {
|
||||
return true;
|
||||
}
|
||||
return rect_is_fullscreen(ps, w->g.x, w->g.y, w->widthb, w->heightb) &&
|
||||
|
|
|
@ -199,6 +199,8 @@ struct managed_win {
|
|||
char *class_general;
|
||||
/// <code>WM_WINDOW_ROLE</code> value of the window.
|
||||
char *role;
|
||||
/// Whether the window sets the EWMH fullscreen property.
|
||||
bool is_ewmh_fullscreen;
|
||||
|
||||
// Opacity-related members
|
||||
/// Current window opacity.
|
||||
|
|
Loading…
Reference in a new issue