Bug fix #77 incorrect border_width handling & #73 window data issue

- (Hopefully) fix all incorrect handling of w->a.border_width in compton
  (#77). Thanks to baskerville for reporting.

- Attempt to fix #73 by correcting a mistake that window data is fetched
  from the wrong function. Thanks to zakkak.

- Add git commit/tag detection to Makefile for automatic versioning.

- Change -lGL linking order, to fix a segmentation fault caused by
  something in nvidia-drivers under FreeBSD, mentioned in #74. Thanks
  for the report from DachiChang.

- Link to -levent_core instead of -levent in Makefile. We might move to
  libev soon, though.

- Increase SWOPTI_TOLERANCE to handle the extraordinary delay of
  kqueue() under FreeBSD. Thanks for DachiChang's report.

- Add helper function dump_drawable() for debugging.

- Replace XInternAtom() calls with get_atom().

- Remove -lrt as it's unneeded.
This commit is contained in:
Richard Grenville 2013-01-09 20:25:01 +08:00
parent 3521f10a97
commit 7188054825
3 changed files with 87 additions and 68 deletions

View File

@ -8,7 +8,7 @@ BINDIR ?= $(PREFIX)/bin
MANDIR ?= $(PREFIX)/share/man/man1 MANDIR ?= $(PREFIX)/share/man/man1
PACKAGES = x11 xcomposite xfixes xdamage xrender xext xrandr PACKAGES = x11 xcomposite xfixes xdamage xrender xext xrandr
LIBS = -lm -lrt LIBS = -lm
INCS = INCS =
# === Configuration flags === # === Configuration flags ===
@ -22,11 +22,11 @@ ifeq "$(shell pkg-config --modversion --print-errors libevent)" ""
CFG += -DCONFIG_LIBEVENT_LEGACY CFG += -DCONFIG_LIBEVENT_LEGACY
LIBS += -levent LIBS += -levent
else else
# Using pkg-config for linking with libevent will result in linking with # Using pkg-config --libs for linking with libevent will result in
# libevent.so instead of the smaller libevent_core.so. But FreeBSD keeps # linking with libevent.so instead of the smaller libevent_core.so.
# libevent2 .so files at a separate place, and we must learn it from # FreeBSD keeps libevent2 .so files at a separate place, and we must
# pkg-config. # learn it from pkg-config.
LIBS += $(shell pkg-config --libs libevent) LIBS += $(shell pkg-config --libs-only-L libevent) -levent_core
INCS += $(shell pkg-config --cflags libevent) INCS += $(shell pkg-config --cflags libevent)
endif endif
@ -58,7 +58,7 @@ endif
# ==== OpenGL VSync ==== # ==== OpenGL VSync ====
ifeq "$(NO_VSYNC_OPENGL)" "" ifeq "$(NO_VSYNC_OPENGL)" ""
CFG += -DCONFIG_VSYNC_OPENGL CFG += -DCONFIG_VSYNC_OPENGL
LIBS += -lGL LIBS := -lGL $(LIBS)
endif endif
# ==== D-Bus ==== # ==== D-Bus ====
@ -68,7 +68,7 @@ endif
# endif # endif
# === Version string === # === Version string ===
COMPTON_VERSION ?= git-$(shell git describe --always) COMPTON_VERSION ?= git-$(shell git describe --always --dirty)-$(shell git log -1 --date=short --pretty=format:%cd)
CFG += -DCOMPTON_VERSION="\"$(COMPTON_VERSION)\"" CFG += -DCOMPTON_VERSION="\"$(COMPTON_VERSION)\""
LDFLAGS ?= -Wl,-O1 -Wl,--as-needed LDFLAGS ?= -Wl,-O1 -Wl,--as-needed

View File

@ -939,7 +939,7 @@ root_tile_f(session_t *ps) {
// Get the values of background attributes // Get the values of background attributes
for (p = 0; background_props_str[p]; p++) { for (p = 0; background_props_str[p]; p++) {
winprop_t prop = wid_get_prop(ps, ps->root, winprop_t prop = wid_get_prop(ps, ps->root,
XInternAtom(ps->dpy, background_props_str[p], false), get_atom(ps, background_props_str[p]),
1L, XA_PIXMAP, 32); 1L, XA_PIXMAP, 32);
if (prop.nitems) { if (prop.nitems) {
pixmap = *prop.data.p32; pixmap = *prop.data.p32;
@ -1517,10 +1517,11 @@ win_paint_win(session_t *ps, win *w, Picture tgt_buffer) {
tgt_buffer, 0, 0, 0, 0, x, y, wid, hei); tgt_buffer, 0, 0, 0, 0, x, y, wid, hei);
} }
else { else {
int t = w->top_width; // Painting parameters
int l = w->left_width; const int t = w->a.border_width + w->top_width;
int b = w->bottom_width; const int l = w->a.border_width + w->left_width;
int r = w->right_width; const int b = w->a.border_width + w->bottom_width;
const int r = w->a.border_width + w->right_width;
#define COMP_BDR(cx, cy, cwid, chei) \ #define COMP_BDR(cx, cy, cwid, chei) \
XRenderComposite(ps->dpy, PictOpOver, w->picture, w->frame_alpha_pict, \ XRenderComposite(ps->dpy, PictOpOver, w->picture, w->frame_alpha_pict, \
@ -1895,13 +1896,6 @@ map_win(session_t *ps, Window id) {
// Detect if the window is shaped or has rounded corners // Detect if the window is shaped or has rounded corners
win_update_shape_raw(ps, w); win_update_shape_raw(ps, w);
// Get window name and class if we are tracking them
if (ps->o.track_wdata) {
win_get_name(ps, w);
win_get_class(ps, w);
win_get_role(ps, w);
}
// Occasionally compton does not seem able to get a FocusIn event from // Occasionally compton does not seem able to get a FocusIn event from
// a window just mapped. I suspect it's a timing issue again when the // a window just mapped. I suspect it's a timing issue again when the
// XSelectInput() is called too late. We have to recheck the focused // XSelectInput() is called too late. We have to recheck the focused
@ -2287,6 +2281,14 @@ win_mark_client(session_t *ps, win *w, Window client) {
if (ps->o.track_leader) if (ps->o.track_leader)
win_update_leader(ps, w); win_update_leader(ps, w);
// Get window name and class if we are tracking them
if (ps->o.track_wdata) {
win_get_name(ps, w);
win_get_class(ps, w);
win_get_role(ps, w);
}
// Update window focus state
win_update_focused(ps, w); win_update_focused(ps, w);
} }
@ -2586,7 +2588,8 @@ configure_win(session_t *ps, XConfigureEvent *ce) {
// If window geometry did not change, don't free extents here // If window geometry did not change, don't free extents here
if (w->a.x != ce->x || w->a.y != ce->y if (w->a.x != ce->x || w->a.y != ce->y
|| w->a.width != ce->width || w->a.height != ce->height) { || w->a.width != ce->width || w->a.height != ce->height
|| w->a.border_width != ce->border_width) {
free_region(ps, &w->extents); free_region(ps, &w->extents);
free_region(ps, &w->border_size); free_region(ps, &w->border_size);
} }
@ -2594,7 +2597,8 @@ configure_win(session_t *ps, XConfigureEvent *ce) {
w->a.x = ce->x; w->a.x = ce->x;
w->a.y = ce->y; w->a.y = ce->y;
if (w->a.width != ce->width || w->a.height != ce->height) { if (w->a.width != ce->width || w->a.height != ce->height
|| w->a.border_width != ce->border_width) {
free_pixmap(ps, &w->pixmap); free_pixmap(ps, &w->pixmap);
free_picture(ps, &w->picture); free_picture(ps, &w->picture);
} }
@ -3415,8 +3419,7 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) {
else { else {
// Destroy the root "image" if the wallpaper probably changed // Destroy the root "image" if the wallpaper probably changed
for (int p = 0; background_props_str[p]; p++) { for (int p = 0; background_props_str[p]; p++) {
if (ev->atom == if (ev->atom == get_atom(ps, background_props_str[p])) {
XInternAtom(ps->dpy, background_props_str[p], false)) {
root_damaged(ps); root_damaged(ps);
break; break;
} }
@ -3911,7 +3914,7 @@ register_cm(session_t *ps, bool want_glxct) {
buf = malloc(len); buf = malloc(len);
snprintf(buf, len, REGISTER_PROP"%d", ps->scr); snprintf(buf, len, REGISTER_PROP"%d", ps->scr);
a = XInternAtom(ps->dpy, buf, false); a = get_atom(ps, buf);
free(buf); free(buf);
XSetSelectionOwner(ps->dpy, a, ps->reg_win, 0); XSetSelectionOwner(ps->dpy, a, ps->reg_win, 0);
@ -4598,49 +4601,48 @@ get_cfg(session_t *ps, int argc, char *const *argv) {
*/ */
static void static void
init_atoms(session_t *ps) { init_atoms(session_t *ps) {
ps->atom_opacity = XInternAtom(ps->dpy, "_NET_WM_WINDOW_OPACITY", False); ps->atom_opacity = get_atom(ps, "_NET_WM_WINDOW_OPACITY");
ps->atom_frame_extents = XInternAtom(ps->dpy, "_NET_FRAME_EXTENTS", False); ps->atom_frame_extents = get_atom(ps, "_NET_FRAME_EXTENTS");
ps->atom_client = XInternAtom(ps->dpy, "WM_STATE", False); ps->atom_client = get_atom(ps, "WM_STATE");
ps->atom_name = XA_WM_NAME; ps->atom_name = XA_WM_NAME;
ps->atom_name_ewmh = XInternAtom(ps->dpy, "_NET_WM_NAME", False); ps->atom_name_ewmh = get_atom(ps, "_NET_WM_NAME");
ps->atom_class = XA_WM_CLASS; ps->atom_class = XA_WM_CLASS;
ps->atom_role = XInternAtom(ps->dpy, "WM_WINDOW_ROLE", False); ps->atom_role = get_atom(ps, "WM_WINDOW_ROLE");
ps->atom_transient = XA_WM_TRANSIENT_FOR; ps->atom_transient = XA_WM_TRANSIENT_FOR;
ps->atom_client_leader = XInternAtom(ps->dpy, "WM_CLIENT_LEADER", False); ps->atom_client_leader = get_atom(ps, "WM_CLIENT_LEADER");
ps->atom_ewmh_active_win = XInternAtom(ps->dpy, "_NET_ACTIVE_WINDOW", False); ps->atom_ewmh_active_win = get_atom(ps, "_NET_ACTIVE_WINDOW");
ps->atom_compton_shadow = XInternAtom(ps->dpy, "_COMPTON_SHADOW", False); ps->atom_compton_shadow = get_atom(ps, "_COMPTON_SHADOW");
ps->atom_win_type = XInternAtom(ps->dpy, ps->atom_win_type = get_atom(ps, "_NET_WM_WINDOW_TYPE");
"_NET_WM_WINDOW_TYPE", False);
ps->atoms_wintypes[WINTYPE_UNKNOWN] = 0; ps->atoms_wintypes[WINTYPE_UNKNOWN] = 0;
ps->atoms_wintypes[WINTYPE_DESKTOP] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_DESKTOP] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_DESKTOP", False); "_NET_WM_WINDOW_TYPE_DESKTOP");
ps->atoms_wintypes[WINTYPE_DOCK] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_DOCK] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_DOCK", False); "_NET_WM_WINDOW_TYPE_DOCK");
ps->atoms_wintypes[WINTYPE_TOOLBAR] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_TOOLBAR] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_TOOLBAR", False); "_NET_WM_WINDOW_TYPE_TOOLBAR");
ps->atoms_wintypes[WINTYPE_MENU] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_MENU] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_MENU", False); "_NET_WM_WINDOW_TYPE_MENU");
ps->atoms_wintypes[WINTYPE_UTILITY] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_UTILITY] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_UTILITY", False); "_NET_WM_WINDOW_TYPE_UTILITY");
ps->atoms_wintypes[WINTYPE_SPLASH] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_SPLASH] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_SPLASH", False); "_NET_WM_WINDOW_TYPE_SPLASH");
ps->atoms_wintypes[WINTYPE_DIALOG] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_DIALOG] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_DIALOG", False); "_NET_WM_WINDOW_TYPE_DIALOG");
ps->atoms_wintypes[WINTYPE_NORMAL] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_NORMAL] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_NORMAL", False); "_NET_WM_WINDOW_TYPE_NORMAL");
ps->atoms_wintypes[WINTYPE_DROPDOWN_MENU] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_DROPDOWN_MENU] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False); "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
ps->atoms_wintypes[WINTYPE_POPUP_MENU] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_POPUP_MENU] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_POPUP_MENU", False); "_NET_WM_WINDOW_TYPE_POPUP_MENU");
ps->atoms_wintypes[WINTYPE_TOOLTIP] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_TOOLTIP] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_TOOLTIP", False); "_NET_WM_WINDOW_TYPE_TOOLTIP");
ps->atoms_wintypes[WINTYPE_NOTIFY] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_NOTIFY] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_NOTIFICATION", False); "_NET_WM_WINDOW_TYPE_NOTIFICATION");
ps->atoms_wintypes[WINTYPE_COMBO] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_COMBO] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_COMBO", False); "_NET_WM_WINDOW_TYPE_COMBO");
ps->atoms_wintypes[WINTYPE_DND] = XInternAtom(ps->dpy, ps->atoms_wintypes[WINTYPE_DND] = get_atom(ps,
"_NET_WM_WINDOW_TYPE_DND", False); "_NET_WM_WINDOW_TYPE_DND");
} }
/** /**

View File

@ -128,7 +128,7 @@ typedef void(* event_callback_fn)(evutil_socket_t, short, void *);
#define REGISTER_PROP "_NET_WM_CM_S" #define REGISTER_PROP "_NET_WM_CM_S"
#define FADE_DELTA_TOLERANCE 0.2 #define FADE_DELTA_TOLERANCE 0.2
#define SWOPTI_TOLERANCE 1000 #define SWOPTI_TOLERANCE 3000
#define WIN_GET_LEADER_MAX_RECURSION 20 #define WIN_GET_LEADER_MAX_RECURSION 20
#define SEC_WRAP (15L * 24L * 60L * 60L) #define SEC_WRAP (15L * 24L * 60L * 60L)
@ -879,10 +879,10 @@ static int
should_ignore(session_t *ps, unsigned long sequence); should_ignore(session_t *ps, unsigned long sequence);
/** /**
* Wrapper of XInternAtom() for convience. * Wrapper of XInternAtom() for convenience.
*/ */
static inline Atom static inline Atom
get_atom(session_t *ps, char *atom_name) { get_atom(session_t *ps, const char *atom_name) {
return XInternAtom(ps->dpy, atom_name, False); return XInternAtom(ps->dpy, atom_name, False);
} }
@ -1530,8 +1530,25 @@ update_reg_ignore_expire(session_t *ps, const win *w) {
*/ */
static inline bool __attribute__((const)) static inline bool __attribute__((const))
win_has_frame(const win *w) { win_has_frame(const win *w) {
return w->top_width || w->left_width || w->right_width return w->a.border_width
|| w->bottom_width; || w->top_width || w->left_width || w->right_width || w->bottom_width;
}
/**
* Dump an drawable's info.
*/
static inline void
dump_drawable(session_t *ps, Drawable drawable) {
Window rroot = None;
int x = 0, y = 0;
unsigned width = 0, height = 0, border = 0, depth = 0;
if (XGetGeometry(ps->dpy, drawable, &rroot, &x, &y, &width, &height,
&border, &depth)) {
printf_dbgf("(%#010lx): x = %u, y = %u, wid = %u, hei = %d, b = %u, d = %u\n", drawable, x, y, width, height, border, depth);
}
else {
printf_dbgf("(%#010lx): Failed\n", drawable);
}
} }
/** /**