diff --git a/src/common.h b/src/common.h index a8ddfb32..7e09487f 100644 --- a/src/common.h +++ b/src/common.h @@ -376,8 +376,6 @@ typedef struct session { // === Atoms === struct atom *atoms; - /// Array of atoms of all possible window types. - xcb_atom_t atoms_wintypes[NUM_WINTYPES]; #ifdef CONFIG_DBUS // === DBus related === @@ -478,10 +476,9 @@ static inline bool bkend_use_glx(session_t *ps) { * @param atom atom of property to check * @return true if it has the attribute, false otherwise */ -static inline bool wid_has_prop(const session_t *ps, xcb_window_t w, xcb_atom_t atom) { +static inline bool wid_has_prop(xcb_connection_t *c, xcb_window_t w, xcb_atom_t atom) { auto r = xcb_get_property_reply( - ps->c.c, - xcb_get_property(ps->c.c, 0, w, atom, XCB_GET_PROPERTY_TYPE_ANY, 0, 0), NULL); + c, xcb_get_property(c, 0, w, atom, XCB_GET_PROPERTY_TYPE_ANY, 0, 0), NULL); if (!r) { return false; } diff --git a/src/event.c b/src/event.c index b015eeab..88d2b598 100644 --- a/src/event.c +++ b/src/event.c @@ -360,7 +360,7 @@ static inline void ev_reparent_notify(session_t *ps, xcb_reparent_notify_event_t // Reset event mask in case something wrong happens uint32_t evmask = determine_evmask(ps, ev->window, WIN_EVMODE_UNKNOWN); - if (!wid_has_prop(ps, ev->window, ps->atoms->aWM_STATE)) { + if (!wid_has_prop(ps->c.c, ev->window, ps->atoms->aWM_STATE)) { log_debug("Window %#010x doesn't have WM_STATE property, it is " "probably not a client window. But we will listen for " "property change in case it gains one.", diff --git a/src/picom.c b/src/picom.c index 1f2421aa..4a3eb893 100644 --- a/src/picom.c +++ b/src/picom.c @@ -85,10 +85,22 @@ static void unredirect(session_t *ps); // === Global constants === /// Name strings for window types. -const char *const WINTYPES[NUM_WINTYPES] = { - "unknown", "desktop", "dock", "toolbar", "menu", - "utility", "splash", "dialog", "normal", "dropdown_menu", - "popup_menu", "tooltip", "notification", "combo", "dnd", +const char *const WINTYPES[] = { + [WINTYPE_UNKNOWN] = "unknown", + [WINTYPE_DESKTOP] = "desktop", + [WINTYPE_DOCK] = "dock", + [WINTYPE_TOOLBAR] = "toolbar", + [WINTYPE_MENU] = "menu", + [WINTYPE_UTILITY] = "utility", + [WINTYPE_SPLASH] = "splash", + [WINTYPE_DIALOG] = "dialog", + [WINTYPE_NORMAL] = "normal", + [WINTYPE_DROPDOWN_MENU] = "dropdown_menu", + [WINTYPE_POPUP_MENU] = "popup_menu", + [WINTYPE_TOOLTIP] = "tooltip", + [WINTYPE_NOTIFICATION] = "notification", + [WINTYPE_COMBO] = "combo", + [WINTYPE_DND] = "dnd", }; // clang-format off @@ -2066,8 +2078,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy, .glx_error = 0, .xrfilter_convolution_exists = false, - .atoms_wintypes = {0}, - #ifdef CONFIG_DBUS .dbus_data = NULL, #endif @@ -2242,25 +2252,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy, } ps->atoms = init_atoms(ps->c.c); - ps->atoms_wintypes[WINTYPE_UNKNOWN] = 0; -#define SET_WM_TYPE_ATOM(x) \ - ps->atoms_wintypes[WINTYPE_##x] = ps->atoms->a_NET_WM_WINDOW_TYPE_##x - SET_WM_TYPE_ATOM(DESKTOP); - SET_WM_TYPE_ATOM(DOCK); - SET_WM_TYPE_ATOM(TOOLBAR); - SET_WM_TYPE_ATOM(MENU); - SET_WM_TYPE_ATOM(UTILITY); - SET_WM_TYPE_ATOM(SPLASH); - SET_WM_TYPE_ATOM(DIALOG); - SET_WM_TYPE_ATOM(NORMAL); - SET_WM_TYPE_ATOM(DROPDOWN_MENU); - SET_WM_TYPE_ATOM(POPUP_MENU); - SET_WM_TYPE_ATOM(TOOLTIP); - SET_WM_TYPE_ATOM(NOTIFICATION); - SET_WM_TYPE_ATOM(COMBO); - SET_WM_TYPE_ATOM(DND); -#undef SET_WM_TYPE_ATOM - ps->c2_state = c2_state_new(ps->atoms); // Get needed atoms for c2 condition lists diff --git a/src/win.c b/src/win.c index 47a95f10..1d1a1a3a 100644 --- a/src/win.c +++ b/src/win.c @@ -60,7 +60,8 @@ static const double ROUNDED_PERCENT = 0.05; static bool win_update_class(struct x_connection *c, struct atom *atoms, struct managed_win *w); static int win_update_role(struct x_connection *c, struct atom *atoms, struct managed_win *w); -static void win_update_wintype(session_t *ps, struct managed_win *w); +static bool +win_update_wintype(struct x_connection *c, struct atom *atoms, struct managed_win *w); static int win_update_name(struct x_connection *c, struct atom *atoms, struct managed_win *w); /** * Reread opacity property of a window. @@ -418,7 +419,9 @@ static void win_clear_all_properties_stale(struct managed_win *w); /// Might set WIN_FLAGS_FACTOR_CHANGED static void win_update_properties(session_t *ps, struct managed_win *w) { if (win_fetch_and_unset_property_stale(w, ps->atoms->a_NET_WM_WINDOW_TYPE)) { - win_update_wintype(ps, w); + if (win_update_wintype(&ps->c, ps->atoms, w)) { + win_set_flags(w, WIN_FLAGS_FACTOR_CHANGED); + } } if (win_fetch_and_unset_property_stale(w, ps->atoms->a_NET_WM_WINDOW_OPACITY)) { @@ -709,13 +712,15 @@ static inline bool win_bounding_shaped(const session_t *ps, xcb_window_t wid) { return false; } -static wintype_t wid_get_prop_wintype(session_t *ps, xcb_window_t wid) { +static wintype_t +wid_get_prop_wintype(struct x_connection *c, struct atom *atoms, xcb_window_t wid) { winprop_t prop = - x_get_prop(&ps->c, wid, ps->atoms->a_NET_WM_WINDOW_TYPE, 32L, XCB_ATOM_ATOM, 32); + x_get_prop(c, wid, atoms->a_NET_WM_WINDOW_TYPE, 32L, XCB_ATOM_ATOM, 32); for (unsigned i = 0; i < prop.nitems; ++i) { for (wintype_t j = 1; j < NUM_WINTYPES; ++j) { - if (ps->atoms_wintypes[j] == (xcb_atom_t)prop.p32[i]) { + if (get_atom_cached(atoms, WINTYPES[j], strlen(WINTYPES[j])) == + (xcb_atom_t)prop.p32[i]) { free_winprop(&prop); return j; } @@ -1286,27 +1291,26 @@ void win_on_win_size_change(session_t *ps, struct managed_win *w) { /** * Update window type. */ -void win_update_wintype(session_t *ps, struct managed_win *w) { +static bool +win_update_wintype(struct x_connection *c, struct atom *atoms, struct managed_win *w) { const wintype_t wtype_old = w->window_type; // Detect window type here - w->window_type = wid_get_prop_wintype(ps, w->client_win); + w->window_type = wid_get_prop_wintype(c, atoms, w->client_win); // Conform to EWMH standard, if _NET_WM_WINDOW_TYPE is not present, take // override-redirect windows or windows without WM_TRANSIENT_FOR as // _NET_WM_WINDOW_TYPE_NORMAL, otherwise as _NET_WM_WINDOW_TYPE_DIALOG. if (WINTYPE_UNKNOWN == w->window_type) { if (w->a.override_redirect || - !wid_has_prop(ps, w->client_win, ps->atoms->aWM_TRANSIENT_FOR)) { + !wid_has_prop(c->c, w->client_win, atoms->aWM_TRANSIENT_FOR)) { w->window_type = WINTYPE_NORMAL; } else { w->window_type = WINTYPE_DIALOG; } } - if (w->window_type != wtype_old) { - win_on_factor_change(ps, w); - } + return w->window_type != wtype_old; } /** @@ -1334,7 +1338,7 @@ void win_mark_client(session_t *ps, struct managed_win *w, xcb_window_t client) free(e); } - win_update_wintype(ps, w); + win_update_wintype(&ps->c, ps->atoms, w); // Get frame widths. The window is in damaged area already. win_update_frame_extents(ps, w, client); @@ -1386,7 +1390,7 @@ void win_unmark_client(session_t *ps, struct managed_win *w) { * Look for the client window of a particular window. */ static xcb_window_t find_client_win(session_t *ps, xcb_window_t w) { - if (wid_has_prop(ps, w, ps->atoms->aWM_STATE)) { + if (wid_has_prop(ps->c.c, w, ps->atoms->aWM_STATE)) { return w; }