1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2024-11-03 04:33:49 -05:00

atom: cache result of get_atom

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-05-06 00:34:08 +01:00
parent 6d6d658b5c
commit 54aa6f2858
No known key found for this signature in database
GPG key ID: 37C999F617EA1A47
10 changed files with 159 additions and 134 deletions

37
src/atom.c Normal file
View file

@ -0,0 +1,37 @@
#include <xcb/xcb.h>
#include "atom.h"
#include "common.h"
#include "utils.h"
/**
* Wrapper of XInternAtom() for convenience.
*/
static inline void *atom_getter(void *ud, const char *atom_name, int *err) {
xcb_connection_t *c = ud;
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(
c, xcb_intern_atom(c, 0, to_u16_checked(strlen(atom_name)), atom_name), NULL);
xcb_atom_t atom = XCB_NONE;
if (reply) {
log_debug("Atom %s is %d", atom_name, reply->atom);
atom = reply->atom;
free(reply);
} else {
log_error("Failed to intern atoms");
*err = 1;
}
return (void *)(intptr_t)atom;
}
/**
* Fetch all required atoms and save them to a session.
*/
struct atom *init_atoms(xcb_connection_t *c) {
auto atoms = ccalloc(1, struct atom);
atoms->c = new_cache((void *)c, atom_getter, NULL);
#define ATOM_GET(x) atoms->a##x = (xcb_atom_t)(intptr_t)cache_get(atoms->c, #x, NULL)
LIST_APPLY(ATOM_GET, SEP_COLON, ATOM_LIST);
#undef ATOM_GET
return atoms;
}

51
src/atom.h Normal file
View file

@ -0,0 +1,51 @@
#include <xcb/xcb.h>
#include "meta.h"
#include "cache.h"
// Splitted into 2 lists because of the limitation of our macros
#define ATOM_LIST \
_NET_WM_WINDOW_OPACITY, \
_NET_FRAME_EXTENTS, \
WM_STATE, \
_NET_WM_NAME, \
_NET_WM_PID, \
WM_NAME, \
WM_CLASS, \
WM_TRANSIENT_FOR, \
WM_WINDOW_ROLE, \
WM_CLIENT_LEADER, \
_NET_ACTIVE_WINDOW, \
_COMPTON_SHADOW, \
_NET_WM_WINDOW_TYPE, \
_NET_WM_WINDOW_TYPE_DESKTOP, \
_NET_WM_WINDOW_TYPE_DOCK, \
_NET_WM_WINDOW_TYPE_TOOLBAR, \
_NET_WM_WINDOW_TYPE_MENU, \
_NET_WM_WINDOW_TYPE_UTILITY, \
_NET_WM_WINDOW_TYPE_SPLASH, \
_NET_WM_WINDOW_TYPE_DIALOG, \
_NET_WM_WINDOW_TYPE_NORMAL, \
_NET_WM_WINDOW_TYPE_DROPDOWN_MENU, \
_NET_WM_WINDOW_TYPE_POPUP_MENU, \
_NET_WM_WINDOW_TYPE_TOOLTIP, \
_NET_WM_WINDOW_TYPE_NOTIFICATION, \
_NET_WM_WINDOW_TYPE_COMBO, \
_NET_WM_WINDOW_TYPE_DND
#define ATOM_DEF(x) xcb_atom_t a##x
struct atom {
struct cache *c;
LIST_APPLY(ATOM_DEF, SEP_COLON, ATOM_LIST);
};
struct atom *init_atoms(xcb_connection_t *);
static inline xcb_atom_t get_atom(struct atom *a, const char *key) {
return (xcb_atom_t)(intptr_t)cache_get(a->c, key, NULL);
}
static inline void destroy_atoms(struct atom *a) {
cache_free(a->c);
}

View file

@ -40,6 +40,7 @@
#include "utils.h" #include "utils.h"
#include "win.h" #include "win.h"
#include "x.h" #include "x.h"
#include "atom.h"
#include "c2.h" #include "c2.h"
@ -983,7 +984,7 @@ static bool c2_l_postprocess(session_t *ps, c2_l_t *pleaf) {
// Get target atom if it's not a predefined one // Get target atom if it's not a predefined one
if (pleaf->predef == C2_L_PUNDEFINED) { if (pleaf->predef == C2_L_PUNDEFINED) {
pleaf->tgtatom = get_atom(ps, pleaf->tgt); pleaf->tgtatom = get_atom(ps->atoms, pleaf->tgt);
if (!pleaf->tgtatom) { if (!pleaf->tgtatom) {
log_error("Failed to get atom for target \"%s\".", pleaf->tgt); log_error("Failed to get atom for target \"%s\".", pleaf->tgt);
return false; return false;

View file

@ -122,6 +122,7 @@
// === Types === // === Types ===
typedef struct glx_fbconfig glx_fbconfig_t; typedef struct glx_fbconfig glx_fbconfig_t;
struct atom;
/// Structure representing needed window updates. /// Structure representing needed window updates.
typedef struct { typedef struct {
@ -494,31 +495,7 @@ typedef struct session {
bool xrfilter_convolution_exists; bool xrfilter_convolution_exists;
// === Atoms === // === Atoms ===
/// Atom of property <code>_NET_WM_OPACITY</code>. struct atom *atoms;
xcb_atom_t atom_opacity;
/// Atom of <code>_NET_FRAME_EXTENTS</code>.
xcb_atom_t atom_frame_extents;
/// Property atom to identify top-level frame window. Currently
/// <code>WM_STATE</code>.
xcb_atom_t atom_client;
/// Atom of property <code>WM_NAME</code>.
xcb_atom_t atom_name;
/// Atom of property <code>_NET_WM_NAME</code>.
xcb_atom_t atom_name_ewmh;
/// Atom of property <code>WM_CLASS</code>.
xcb_atom_t atom_class;
/// Atom of property <code>WM_WINDOW_ROLE</code>.
xcb_atom_t atom_role;
/// Atom of property <code>WM_TRANSIENT_FOR</code>.
xcb_atom_t atom_transient;
/// Atom of property <code>WM_CLIENT_LEADER</code>.
xcb_atom_t atom_client_leader;
/// Atom of property <code>_NET_ACTIVE_WINDOW</code>.
xcb_atom_t atom_ewmh_active_win;
/// Atom of property <code>_COMPTON_SHADOW</code>.
xcb_atom_t atom_compton_shadow;
/// Atom of property <code>_NET_WM_WINDOW_TYPE</code>.
xcb_atom_t atom_win_type;
/// Array of atoms of all possible window types. /// Array of atoms of all possible window types.
xcb_atom_t atoms_wintypes[NUM_WINTYPES]; xcb_atom_t atoms_wintypes[NUM_WINTYPES];
/// Linked list of additional atoms to track. /// Linked list of additional atoms to track.
@ -714,24 +691,6 @@ _Noreturn static inline void die(const char *msg) {
exit(1); exit(1);
} }
/**
* Wrapper of XInternAtom() for convenience.
*/
static inline xcb_atom_t get_atom(session_t *ps, const char *atom_name) {
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(
ps->c,
xcb_intern_atom(ps->c, 0, to_u16_checked(strlen(atom_name)), atom_name), NULL);
xcb_atom_t atom = XCB_NONE;
if (reply) {
log_debug("Atom %s is %d", atom_name, reply->atom);
atom = reply->atom;
free(reply);
} else
die("Failed to intern atoms, bail out");
return atom;
}
/** /**
* Return the painting target window. * Return the painting target window.
*/ */

View file

@ -49,6 +49,7 @@
#ifdef CONFIG_DBUS #ifdef CONFIG_DBUS
#include "dbus.h" #include "dbus.h"
#endif #endif
#include "atom.h"
#include "event.h" #include "event.h"
#include "list.h" #include "list.h"
#include "options.h" #include "options.h"
@ -350,7 +351,7 @@ struct managed_win *recheck_focus(session_t *ps) {
* Look for the client window of a particular window. * Look for the client window of a particular window.
*/ */
xcb_window_t find_client_win(session_t *ps, xcb_window_t w) { xcb_window_t find_client_win(session_t *ps, xcb_window_t w) {
if (wid_has_prop(ps, w, ps->atom_client)) { if (wid_has_prop(ps, w, ps->atoms->aWM_STATE)) {
return w; return w;
} }
@ -871,7 +872,7 @@ void opts_set_no_fading_openclose(session_t *ps, bool newval) {
*/ */
void update_ewmh_active_win(session_t *ps) { void update_ewmh_active_win(session_t *ps) {
// Search for the window // Search for the window
xcb_window_t wid = wid_get_prop_window(ps, ps->root, ps->atom_ewmh_active_win); xcb_window_t wid = wid_get_prop_window(ps, ps->root, ps->atoms->a_NET_ACTIVE_WINDOW);
auto w = find_win_all(ps, wid); auto w = find_win_all(ps, wid);
// Mark the window focused. No need to unfocus the previous one. // Mark the window focused. No need to unfocus the previous one.
@ -919,12 +920,12 @@ static bool register_cm(session_t *ps) {
{ {
auto pid = getpid(); auto pid = getpid();
xcb_change_property(ps->c, XCB_PROP_MODE_REPLACE, ps->reg_win, xcb_change_property(ps->c, XCB_PROP_MODE_REPLACE, ps->reg_win,
get_atom(ps, "_NET_WM_PID"), XCB_ATOM_CARDINAL, 32, 1, ps->atoms->a_NET_WM_PID, XCB_ATOM_CARDINAL,
&pid); 32, 1, &pid);
} }
// Set COMPTON_VERSION // Set COMPTON_VERSION
if (!wid_set_text_prop(ps, ps->reg_win, get_atom(ps, "COMPTON_VERSION"), if (!wid_set_text_prop(ps, ps->reg_win, get_atom(ps->atoms, "COMPTON_VERSION"),
COMPTON_VERSION)) { COMPTON_VERSION)) {
log_error("Failed to set COMPTON_VERSION."); log_error("Failed to set COMPTON_VERSION.");
} }
@ -943,7 +944,7 @@ static bool register_cm(session_t *ps) {
auto buf = ccalloc(len, char); auto buf = ccalloc(len, char);
snprintf(buf, len, REGISTER_PROP "%d", ps->scr); snprintf(buf, len, REGISTER_PROP "%d", ps->scr);
buf[len - 1] = '\0'; buf[len - 1] = '\0';
atom = get_atom(ps, buf); atom = get_atom(ps->atoms, buf);
free(buf); free(buf);
xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply( xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(
@ -980,43 +981,6 @@ static inline bool write_pid(session_t *ps) {
return true; return true;
} }
/**
* Fetch all required atoms and save them to a session.
*/
static void init_atoms(session_t *ps) {
ps->atom_opacity = get_atom(ps, "_NET_WM_WINDOW_OPACITY");
ps->atom_frame_extents = get_atom(ps, "_NET_FRAME_EXTENTS");
ps->atom_client = get_atom(ps, "WM_STATE");
ps->atom_name = XCB_ATOM_WM_NAME;
ps->atom_name_ewmh = get_atom(ps, "_NET_WM_NAME");
ps->atom_class = XCB_ATOM_WM_CLASS;
ps->atom_role = get_atom(ps, "WM_WINDOW_ROLE");
ps->atom_transient = XCB_ATOM_WM_TRANSIENT_FOR;
ps->atom_client_leader = get_atom(ps, "WM_CLIENT_LEADER");
ps->atom_ewmh_active_win = get_atom(ps, "_NET_ACTIVE_WINDOW");
ps->atom_compton_shadow = get_atom(ps, "_COMPTON_SHADOW");
ps->atom_win_type = get_atom(ps, "_NET_WM_WINDOW_TYPE");
ps->atoms_wintypes[WINTYPE_UNKNOWN] = 0;
ps->atoms_wintypes[WINTYPE_DESKTOP] = get_atom(ps, "_NET_WM_WINDOW_TYPE_DESKTOP");
ps->atoms_wintypes[WINTYPE_DOCK] = get_atom(ps, "_NET_WM_WINDOW_TYPE_DOCK");
ps->atoms_wintypes[WINTYPE_TOOLBAR] = get_atom(ps, "_NET_WM_WINDOW_TYPE_TOOLBAR");
ps->atoms_wintypes[WINTYPE_MENU] = get_atom(ps, "_NET_WM_WINDOW_TYPE_MENU");
ps->atoms_wintypes[WINTYPE_UTILITY] = get_atom(ps, "_NET_WM_WINDOW_TYPE_UTILITY");
ps->atoms_wintypes[WINTYPE_SPLASH] = get_atom(ps, "_NET_WM_WINDOW_TYPE_SPLASH");
ps->atoms_wintypes[WINTYPE_DIALOG] = get_atom(ps, "_NET_WM_WINDOW_TYPE_DIALOG");
ps->atoms_wintypes[WINTYPE_NORMAL] = get_atom(ps, "_NET_WM_WINDOW_TYPE_NORMAL");
ps->atoms_wintypes[WINTYPE_DROPDOWN_MENU] =
get_atom(ps, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
ps->atoms_wintypes[WINTYPE_POPUP_MENU] =
get_atom(ps, "_NET_WM_WINDOW_TYPE_POPUP_MENU");
ps->atoms_wintypes[WINTYPE_TOOLTIP] = get_atom(ps, "_NET_WM_WINDOW_TYPE_TOOLTIP");
ps->atoms_wintypes[WINTYPE_NOTIFY] =
get_atom(ps, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
ps->atoms_wintypes[WINTYPE_COMBO] = get_atom(ps, "_NET_WM_WINDOW_TYPE_COMBO");
ps->atoms_wintypes[WINTYPE_DND] = get_atom(ps, "_NET_WM_WINDOW_TYPE_DND");
}
/** /**
* Update refresh rate info with X Randr extension. * Update refresh rate info with X Randr extension.
*/ */
@ -1594,17 +1558,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
#endif #endif
.xrfilter_convolution_exists = false, .xrfilter_convolution_exists = false,
.atom_opacity = XCB_NONE,
.atom_frame_extents = XCB_NONE,
.atom_client = XCB_NONE,
.atom_name = XCB_NONE,
.atom_name_ewmh = XCB_NONE,
.atom_class = XCB_NONE,
.atom_role = XCB_NONE,
.atom_transient = XCB_NONE,
.atom_ewmh_active_win = XCB_NONE,
.atom_compton_shadow = XCB_NONE,
.atom_win_type = XCB_NONE,
.atoms_wintypes = {0}, .atoms_wintypes = {0},
.track_atom_lst = NULL, .track_atom_lst = NULL,
@ -1756,6 +1709,26 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
} }
} }
ps->atoms = init_atoms(ps->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
// Get needed atoms for c2 condition lists // Get needed atoms for c2 condition lists
if (!(c2_list_postprocess(ps, ps->o.unredir_if_possible_blacklist) && if (!(c2_list_postprocess(ps, ps->o.unredir_if_possible_blacklist) &&
c2_list_postprocess(ps, ps->o.paint_blacklist) && c2_list_postprocess(ps, ps->o.paint_blacklist) &&
@ -1910,8 +1883,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
if (!ps->reg_win && !register_cm(ps)) if (!ps->reg_win && !register_cm(ps))
exit(1); exit(1);
init_atoms(ps);
{ {
xcb_render_create_picture_value_list_t pa = { xcb_render_create_picture_value_list_t pa = {
.subwindowmode = IncludeInferiors, .subwindowmode = IncludeInferiors,
@ -2173,6 +2144,7 @@ static void session_destroy(session_t *ps) {
x_sync(ps->c); x_sync(ps->c);
ev_io_stop(ps->loop, &ps->xiow); ev_io_stop(ps->loop, &ps->xiow);
free_conv(ps->gaussian_map); free_conv(ps->gaussian_map);
destroy_atoms(ps->atoms);
#ifdef DEBUG_XRC #ifdef DEBUG_XRC
// Report about resource leakage // Report about resource leakage

View file

@ -4,6 +4,7 @@
#include <X11/Xlibint.h> #include <X11/Xlibint.h>
#include <X11/extensions/sync.h> #include <X11/extensions/sync.h>
#include "atom.h"
#include "common.h" #include "common.h"
#include "compiler.h" #include "compiler.h"
#include "compton.h" #include "compton.h"
@ -319,7 +320,7 @@ static inline void ev_reparent_notify(session_t *ps, xcb_reparent_notify_event_t
if (w_top && if (w_top &&
(!w_top->client_win || w_top->client_win == w_top->base.id)) { (!w_top->client_win || w_top->client_win == w_top->base.id)) {
// If it has WM_STATE, mark it the client window // If it has WM_STATE, mark it the client window
if (wid_has_prop(ps, ev->window, ps->atom_client)) { if (wid_has_prop(ps, ev->window, ps->atoms->aWM_STATE)) {
w_top->wmwin = false; w_top->wmwin = false;
win_unmark_client(ps, w_top); win_unmark_client(ps, w_top);
win_mark_client(ps, w_top, ev->window); win_mark_client(ps, w_top, ev->window);
@ -401,7 +402,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
if (ps->root == ev->window) { if (ps->root == ev->window) {
if (ps->o.track_focus && ps->o.use_ewmh_active_win && if (ps->o.track_focus && ps->o.use_ewmh_active_win &&
ps->atom_ewmh_active_win == ev->atom) { ps->atoms->a_NET_ACTIVE_WINDOW == ev->atom) {
update_ewmh_active_win(ps); update_ewmh_active_win(ps);
} else { } else {
// Destroy the root "image" if the wallpaper probably changed // Destroy the root "image" if the wallpaper probably changed
@ -415,7 +416,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
} }
// If WM_STATE changes // If WM_STATE changes
if (ev->atom == ps->atom_client) { if (ev->atom == ps->atoms->aWM_STATE) {
// Check whether it could be a client window // Check whether it could be a client window
if (!find_toplevel(ps, ev->window)) { if (!find_toplevel(ps, ev->window)) {
// Reset event mask anyway // Reset event mask anyway
@ -427,7 +428,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
// Initialize client_win as early as possible // Initialize client_win as early as possible
if (w_top && if (w_top &&
(!w_top->client_win || w_top->client_win == w_top->base.id) && (!w_top->client_win || w_top->client_win == w_top->base.id) &&
wid_has_prop(ps, ev->window, ps->atom_client)) { wid_has_prop(ps, ev->window, ps->atoms->aWM_STATE)) {
w_top->wmwin = false; w_top->wmwin = false;
win_unmark_client(ps, w_top); win_unmark_client(ps, w_top);
win_mark_client(ps, w_top, ev->window); win_mark_client(ps, w_top, ev->window);
@ -437,14 +438,14 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
// If _NET_WM_WINDOW_TYPE changes... God knows why this would happen, but // If _NET_WM_WINDOW_TYPE changes... God knows why this would happen, but
// there are always some stupid applications. (#144) // there are always some stupid applications. (#144)
if (ev->atom == ps->atom_win_type) { if (ev->atom == ps->atoms->a_NET_WM_WINDOW_TYPE) {
struct managed_win *w = NULL; struct managed_win *w = NULL;
if ((w = find_toplevel(ps, ev->window))) if ((w = find_toplevel(ps, ev->window)))
win_update_wintype(ps, w); win_update_wintype(ps, w);
} }
// If _NET_WM_OPACITY changes // If _NET_WM_OPACITY changes
if (ev->atom == ps->atom_opacity) { if (ev->atom == ps->atoms->a_NET_WM_WINDOW_OPACITY) {
auto w = find_managed_win(ps, ev->window) ?: find_toplevel(ps, ev->window); auto w = find_managed_win(ps, ev->window) ?: find_toplevel(ps, ev->window);
if (w) { if (w) {
win_update_opacity_prop(ps, w); win_update_opacity_prop(ps, w);
@ -459,7 +460,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
} }
// If frame extents property changes // If frame extents property changes
if (ps->o.frame_opacity > 0 && ev->atom == ps->atom_frame_extents) { if (ps->o.frame_opacity > 0 && ev->atom == ps->atoms->a_NET_FRAME_EXTENTS) {
auto w = find_toplevel(ps, ev->window); auto w = find_toplevel(ps, ev->window);
if (w) { if (w) {
win_update_frame_extents(ps, w, ev->window); win_update_frame_extents(ps, w, ev->window);
@ -469,7 +470,8 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
} }
// If name changes // If name changes
if (ps->o.track_wdata && (ps->atom_name == ev->atom || ps->atom_name_ewmh == ev->atom)) { if (ps->o.track_wdata &&
(ps->atoms->aWM_NAME == ev->atom || ps->atoms->a_NET_WM_NAME == ev->atom)) {
auto w = find_toplevel(ps, ev->window); auto w = find_toplevel(ps, ev->window);
if (w && 1 == win_get_name(ps, w)) { if (w && 1 == win_get_name(ps, w)) {
win_on_factor_change(ps, w); win_on_factor_change(ps, w);
@ -477,7 +479,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
} }
// If class changes // If class changes
if (ps->o.track_wdata && ps->atom_class == ev->atom) { if (ps->o.track_wdata && ps->atoms->aWM_CLASS == ev->atom) {
auto w = find_toplevel(ps, ev->window); auto w = find_toplevel(ps, ev->window);
if (w) { if (w) {
win_get_class(ps, w); win_get_class(ps, w);
@ -486,7 +488,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
} }
// If role changes // If role changes
if (ps->o.track_wdata && ps->atom_role == ev->atom) { if (ps->o.track_wdata && ps->atoms->aWM_WINDOW_ROLE== ev->atom) {
auto w = find_toplevel(ps, ev->window); auto w = find_toplevel(ps, ev->window);
if (w && 1 == win_get_role(ps, w)) { if (w && 1 == win_get_role(ps, w)) {
win_on_factor_change(ps, w); win_on_factor_change(ps, w);
@ -494,7 +496,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
} }
// If _COMPTON_SHADOW changes // If _COMPTON_SHADOW changes
if (ps->o.respect_prop_shadow && ps->atom_compton_shadow == ev->atom) { if (ps->o.respect_prop_shadow && ps->atoms->a_COMPTON_SHADOW == ev->atom) {
auto w = find_managed_win(ps, ev->window); auto w = find_managed_win(ps, ev->window);
if (w) { if (w) {
win_update_prop_shadow(ps, w); win_update_prop_shadow(ps, w);
@ -502,8 +504,8 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
} }
// If a leader property changes // If a leader property changes
if ((ps->o.detect_transient && ps->atom_transient == ev->atom) || if ((ps->o.detect_transient && ps->atoms->aWM_TRANSIENT_FOR == ev->atom) ||
(ps->o.detect_client_leader && ps->atom_client_leader == ev->atom)) { (ps->o.detect_client_leader && ps->atoms->aWM_CLIENT_LEADER == ev->atom)) {
auto w = find_toplevel(ps, ev->window); auto w = find_toplevel(ps, ev->window);
if (w) { if (w) {
win_update_leader(ps, w); win_update_leader(ps, w);

View file

@ -10,7 +10,7 @@ base_deps = [
srcs = [ files('compton.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'vsync.c', 'utils.c', srcs = [ files('compton.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'vsync.c', 'utils.c',
'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c', 'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c',
'options.c', 'event.c', 'cache.c') ] 'options.c', 'event.c', 'cache.c', 'atom.c') ]
compton_inc = include_directories('.') compton_inc = include_directories('.')
cflags = [] cflags = []

View file

@ -14,6 +14,7 @@
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/xcb_renderutil.h> #include <xcb/xcb_renderutil.h>
#include "atom.h"
#include "backend/backend.h" #include "backend/backend.h"
#include "c2.h" #include "c2.h"
#include "common.h" #include "common.h"
@ -65,12 +66,12 @@ static inline void clear_cache_win_leaders(session_t *ps) {
static inline void wid_set_opacity_prop(session_t *ps, xcb_window_t wid, opacity_t val) { static inline void wid_set_opacity_prop(session_t *ps, xcb_window_t wid, opacity_t val) {
const uint32_t v = val; const uint32_t v = val;
xcb_change_property(ps->c, XCB_PROP_MODE_REPLACE, wid, ps->atom_opacity, xcb_change_property(ps->c, XCB_PROP_MODE_REPLACE, wid,
XCB_ATOM_CARDINAL, 32, 1, &v); ps->atoms->a_NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1, &v);
} }
static inline void wid_rm_opacity_prop(session_t *ps, xcb_window_t wid) { static inline void wid_rm_opacity_prop(session_t *ps, xcb_window_t wid) {
xcb_delete_property(ps->c, wid, ps->atom_opacity); xcb_delete_property(ps->c, wid, ps->atoms->a_NET_WM_WINDOW_OPACITY);
} }
/** /**
@ -297,7 +298,7 @@ int win_get_name(session_t *ps, struct managed_win *w) {
if (!w->client_win) if (!w->client_win)
return 0; return 0;
if (!(wid_get_text_prop(ps, w->client_win, ps->atom_name_ewmh, &strlst, &nstr))) { if (!(wid_get_text_prop(ps, w->client_win, ps->atoms->a_NET_WM_NAME, &strlst, &nstr))) {
log_trace("(%#010x): _NET_WM_NAME unset, falling back to WM_NAME.", log_trace("(%#010x): _NET_WM_NAME unset, falling back to WM_NAME.",
w->client_win); w->client_win);
@ -333,7 +334,7 @@ int win_get_role(session_t *ps, struct managed_win *w) {
char **strlst = NULL; char **strlst = NULL;
int nstr = 0; int nstr = 0;
if (!wid_get_text_prop(ps, w->client_win, ps->atom_role, &strlst, &nstr)) if (!wid_get_text_prop(ps, w->client_win, ps->atoms->aWM_WINDOW_ROLE, &strlst, &nstr))
return -1; return -1;
int ret = 0; int ret = 0;
@ -371,7 +372,8 @@ static inline bool win_bounding_shaped(const session_t *ps, xcb_window_t wid) {
} }
static wintype_t wid_get_prop_wintype(session_t *ps, xcb_window_t wid) { static wintype_t wid_get_prop_wintype(session_t *ps, xcb_window_t wid) {
winprop_t prop = wid_get_prop(ps, wid, ps->atom_win_type, 32L, XCB_ATOM_ATOM, 32); winprop_t prop =
wid_get_prop(ps, wid, ps->atoms->a_NET_WM_WINDOW_TYPE, 32L, XCB_ATOM_ATOM, 32);
for (unsigned i = 0; i < prop.nitems; ++i) { for (unsigned i = 0; i < prop.nitems; ++i) {
for (wintype_t j = 1; j < NUM_WINTYPES; ++j) { for (wintype_t j = 1; j < NUM_WINTYPES; ++j) {
@ -392,7 +394,8 @@ wid_get_opacity_prop(session_t *ps, xcb_window_t wid, opacity_t def, opacity_t *
bool ret = false; bool ret = false;
*out = def; *out = def;
winprop_t prop = wid_get_prop(ps, wid, ps->atom_opacity, 1L, XCB_ATOM_CARDINAL, 32); winprop_t prop = wid_get_prop(ps, wid, ps->atoms->a_NET_WM_WINDOW_OPACITY, 1L,
XCB_ATOM_CARDINAL, 32);
if (prop.nitems) { if (prop.nitems) {
*out = *prop.c32; *out = *prop.c32;
@ -519,8 +522,8 @@ bool win_should_fade(session_t *ps, const struct managed_win *w) {
* The property must be set on the outermost window, usually the WM frame. * The property must be set on the outermost window, usually the WM frame.
*/ */
void win_update_prop_shadow_raw(session_t *ps, struct managed_win *w) { void win_update_prop_shadow_raw(session_t *ps, struct managed_win *w) {
winprop_t prop = winprop_t prop = wid_get_prop(ps, w->base.id, ps->atoms->a_COMPTON_SHADOW, 1,
wid_get_prop(ps, w->base.id, ps->atom_compton_shadow, 1, XCB_ATOM_CARDINAL, 32); XCB_ATOM_CARDINAL, 32);
if (!prop.nitems) { if (!prop.nitems) {
w->prop_shadow = -1; w->prop_shadow = -1;
@ -809,7 +812,7 @@ void win_update_wintype(session_t *ps, struct managed_win *w) {
// _NET_WM_WINDOW_TYPE_NORMAL, otherwise as _NET_WM_WINDOW_TYPE_DIALOG. // _NET_WM_WINDOW_TYPE_NORMAL, otherwise as _NET_WM_WINDOW_TYPE_DIALOG.
if (WINTYPE_UNKNOWN == w->window_type) { if (WINTYPE_UNKNOWN == w->window_type) {
if (w->a.override_redirect || if (w->a.override_redirect ||
!wid_has_prop(ps, w->client_win, ps->atom_transient)) !wid_has_prop(ps, w->client_win, ps->atoms->aWM_TRANSIENT_FOR))
w->window_type = WINTYPE_NORMAL; w->window_type = WINTYPE_NORMAL;
else else
w->window_type = WINTYPE_DIALOG; w->window_type = WINTYPE_DIALOG;
@ -1228,10 +1231,10 @@ void win_update_leader(session_t *ps, struct managed_win *w) {
// Read the leader properties // Read the leader properties
if (ps->o.detect_transient && !leader) if (ps->o.detect_transient && !leader)
leader = wid_get_prop_window(ps, w->client_win, ps->atom_transient); leader = wid_get_prop_window(ps, w->client_win, ps->atoms->aWM_TRANSIENT_FOR);
if (ps->o.detect_client_leader && !leader) if (ps->o.detect_client_leader && !leader)
leader = wid_get_prop_window(ps, w->client_win, ps->atom_client_leader); leader = wid_get_prop_window(ps, w->client_win, ps->atoms->aWM_CLIENT_LEADER);
win_set_leader(ps, w, leader); win_set_leader(ps, w, leader);
@ -1284,7 +1287,7 @@ bool win_get_class(session_t *ps, struct managed_win *w) {
w->class_general = NULL; w->class_general = NULL;
// Retrieve the property string list // Retrieve the property string list
if (!wid_get_text_prop(ps, w->client_win, ps->atom_class, &strlst, &nstr)) if (!wid_get_text_prop(ps, w->client_win, ps->atoms->aWM_CLASS, &strlst, &nstr))
return false; return false;
// Copy the strings if successful // Copy the strings if successful
@ -1486,8 +1489,8 @@ void win_update_opacity_prop(session_t *ps, struct managed_win *w) {
* Retrieve frame extents from a window. * Retrieve frame extents from a window.
*/ */
void win_update_frame_extents(session_t *ps, struct managed_win *w, xcb_window_t client) { void win_update_frame_extents(session_t *ps, struct managed_win *w, xcb_window_t client) {
winprop_t prop = winprop_t prop = wid_get_prop(ps, client, ps->atoms->a_NET_FRAME_EXTENTS, 4L,
wid_get_prop(ps, client, ps->atom_frame_extents, 4L, XCB_ATOM_CARDINAL, 32); XCB_ATOM_CARDINAL, 32);
if (prop.nitems == 4) { if (prop.nitems == 4) {
const int32_t extents[4] = { const int32_t extents[4] = {
@ -1686,8 +1689,7 @@ void restack_above(session_t *ps, struct win *w, xcb_window_t below) {
HASH_FIND_INT(ps->windows, &below, tmp_w); HASH_FIND_INT(ps->windows, &below, tmp_w);
if (!tmp_w) { if (!tmp_w) {
log_error("(%#010x, %#010x): Failed to found new below " log_error("Failed to found new below window %#010x.", below);
"window.", w->id, below);
return; return;
} }

View file

@ -62,7 +62,7 @@ typedef enum {
WINTYPE_DROPDOWN_MENU, WINTYPE_DROPDOWN_MENU,
WINTYPE_POPUP_MENU, WINTYPE_POPUP_MENU,
WINTYPE_TOOLTIP, WINTYPE_TOOLTIP,
WINTYPE_NOTIFY, WINTYPE_NOTIFICATION,
WINTYPE_COMBO, WINTYPE_COMBO,
WINTYPE_DND, WINTYPE_DND,
NUM_WINTYPES NUM_WINTYPES

View file

@ -20,6 +20,7 @@
#include "log.h" #include "log.h"
#include "region.h" #include "region.h"
#include "utils.h" #include "utils.h"
#include "atom.h"
#include "x.h" #include "x.h"
/** /**
@ -456,7 +457,7 @@ xcb_pixmap_t x_get_root_back_pixmap(session_t *ps) {
// Get the values of background attributes // Get the values of background attributes
for (int p = 0; background_props_str[p]; p++) { for (int p = 0; background_props_str[p]; p++) {
xcb_atom_t prop_atom = get_atom(ps, background_props_str[p]); xcb_atom_t prop_atom = get_atom(ps->atoms, background_props_str[p]);
winprop_t prop = winprop_t prop =
wid_get_prop(ps, ps->root, prop_atom, 1, XCB_ATOM_PIXMAP, 32); wid_get_prop(ps, ps->root, prop_atom, 1, XCB_ATOM_PIXMAP, 32);
if (prop.nitems) { if (prop.nitems) {
@ -472,7 +473,7 @@ xcb_pixmap_t x_get_root_back_pixmap(session_t *ps) {
bool x_is_root_back_pixmap_atom(session_t *ps, xcb_atom_t atom) { bool x_is_root_back_pixmap_atom(session_t *ps, xcb_atom_t atom) {
for (int p = 0; background_props_str[p]; p++) { for (int p = 0; background_props_str[p]; p++) {
xcb_atom_t prop_atom = get_atom(ps, background_props_str[p]); xcb_atom_t prop_atom = get_atom(ps->atoms, background_props_str[p]);
if (prop_atom == atom) if (prop_atom == atom)
return true; return true;
} }