win: win_update_wintype doesn't need session_t now

It needed session_t to:

1. Get the atom of window types - this is now provided by `struct atom`.
2. Call win_on_factor_change - this is now the caller's responsibility.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-02-19 17:34:07 +00:00
parent d861412e5c
commit c432b9d7d9
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
4 changed files with 36 additions and 44 deletions

View File

@ -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;
}

View File

@ -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.",

View File

@ -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

View File

@ -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;
}