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:
parent
6d6d658b5c
commit
54aa6f2858
10 changed files with 159 additions and 134 deletions
37
src/atom.c
Normal file
37
src/atom.c
Normal 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
51
src/atom.h
Normal 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);
|
||||||
|
}
|
3
src/c2.c
3
src/c2.c
|
@ -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;
|
||||||
|
|
45
src/common.h
45
src/common.h
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
28
src/event.c
28
src/event.c
|
@ -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);
|
||||||
|
|
|
@ -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 = []
|
||||||
|
|
36
src/win.c
36
src/win.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
5
src/x.c
5
src/x.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue