Skip to content

Commit

Permalink
Bug fix #77 incorrect border_width handling & #73 window data issue
Browse files Browse the repository at this point in the history
- (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.
  • Loading branch information
richardgv committed Jan 9, 2013
1 parent 3521f10 commit 7188054
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 68 deletions.
16 changes: 8 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ BINDIR ?= $(PREFIX)/bin
MANDIR ?= $(PREFIX)/share/man/man1

PACKAGES = x11 xcomposite xfixes xdamage xrender xext xrandr
LIBS = -lm -lrt
LIBS = -lm
INCS =

# === Configuration flags ===
Expand All @@ -22,11 +22,11 @@ ifeq "$(shell pkg-config --modversion --print-errors libevent)" ""
CFG += -DCONFIG_LIBEVENT_LEGACY
LIBS += -levent
else
# Using pkg-config for linking with libevent will result in linking with
# libevent.so instead of the smaller libevent_core.so. But FreeBSD keeps
# libevent2 .so files at a separate place, and we must learn it from
# pkg-config.
LIBS += $(shell pkg-config --libs libevent)
# Using pkg-config --libs for linking with libevent will result in
# linking with libevent.so instead of the smaller libevent_core.so.
# FreeBSD keeps libevent2 .so files at a separate place, and we must
# learn it from pkg-config.
LIBS += $(shell pkg-config --libs-only-L libevent) -levent_core
INCS += $(shell pkg-config --cflags libevent)
endif

Expand Down Expand Up @@ -58,7 +58,7 @@ endif
# ==== OpenGL VSync ====
ifeq "$(NO_VSYNC_OPENGL)" ""
CFG += -DCONFIG_VSYNC_OPENGL
LIBS += -lGL
LIBS := -lGL $(LIBS)
endif

# ==== D-Bus ====
Expand All @@ -68,7 +68,7 @@ endif
# endif

# === 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)\""

LDFLAGS ?= -Wl,-O1 -Wl,--as-needed
Expand Down
112 changes: 57 additions & 55 deletions src/compton.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,7 @@ root_tile_f(session_t *ps) {
// Get the values of background attributes
for (p = 0; background_props_str[p]; p++) {
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);
if (prop.nitems) {
pixmap = *prop.data.p32;
Expand Down Expand Up @@ -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);
}
else {
int t = w->top_width;
int l = w->left_width;
int b = w->bottom_width;
int r = w->right_width;
// Painting parameters
const int t = w->a.border_width + w->top_width;
const int l = w->a.border_width + w->left_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) \
XRenderComposite(ps->dpy, PictOpOver, w->picture, w->frame_alpha_pict, \
Expand Down Expand Up @@ -1895,13 +1896,6 @@ map_win(session_t *ps, Window id) {
// Detect if the window is shaped or has rounded corners
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
// 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
Expand Down Expand Up @@ -2287,6 +2281,14 @@ win_mark_client(session_t *ps, win *w, Window client) {
if (ps->o.track_leader)
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);
}

Expand Down Expand Up @@ -2586,15 +2588,17 @@ configure_win(session_t *ps, XConfigureEvent *ce) {

// If window geometry did not change, don't free extents here
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->border_size);
}

w->a.x = ce->x;
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_picture(ps, &w->picture);
}
Expand Down Expand Up @@ -3415,8 +3419,7 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) {
else {
// Destroy the root "image" if the wallpaper probably changed
for (int p = 0; background_props_str[p]; p++) {
if (ev->atom ==
XInternAtom(ps->dpy, background_props_str[p], false)) {
if (ev->atom == get_atom(ps, background_props_str[p])) {
root_damaged(ps);
break;
}
Expand Down Expand Up @@ -3911,7 +3914,7 @@ register_cm(session_t *ps, bool want_glxct) {
buf = malloc(len);
snprintf(buf, len, REGISTER_PROP"%d", ps->scr);

a = XInternAtom(ps->dpy, buf, false);
a = get_atom(ps, buf);
free(buf);

XSetSelectionOwner(ps->dpy, a, ps->reg_win, 0);
Expand Down Expand Up @@ -4598,49 +4601,48 @@ get_cfg(session_t *ps, int argc, char *const *argv) {
*/
static void
init_atoms(session_t *ps) {
ps->atom_opacity = XInternAtom(ps->dpy, "_NET_WM_WINDOW_OPACITY", False);
ps->atom_frame_extents = XInternAtom(ps->dpy, "_NET_FRAME_EXTENTS", False);
ps->atom_client = XInternAtom(ps->dpy, "WM_STATE", False);
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 = 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_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_client_leader = XInternAtom(ps->dpy, "WM_CLIENT_LEADER", False);
ps->atom_ewmh_active_win = XInternAtom(ps->dpy, "_NET_ACTIVE_WINDOW", False);
ps->atom_compton_shadow = XInternAtom(ps->dpy, "_COMPTON_SHADOW", False);
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 = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE", False);
ps->atom_win_type = get_atom(ps, "_NET_WM_WINDOW_TYPE");
ps->atoms_wintypes[WINTYPE_UNKNOWN] = 0;
ps->atoms_wintypes[WINTYPE_DESKTOP] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_DESKTOP", False);
ps->atoms_wintypes[WINTYPE_DOCK] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_DOCK", False);
ps->atoms_wintypes[WINTYPE_TOOLBAR] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_TOOLBAR", False);
ps->atoms_wintypes[WINTYPE_MENU] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_MENU", False);
ps->atoms_wintypes[WINTYPE_UTILITY] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_UTILITY", False);
ps->atoms_wintypes[WINTYPE_SPLASH] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_SPLASH", False);
ps->atoms_wintypes[WINTYPE_DIALOG] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_DIALOG", False);
ps->atoms_wintypes[WINTYPE_NORMAL] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_NORMAL", False);
ps->atoms_wintypes[WINTYPE_DROPDOWN_MENU] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
ps->atoms_wintypes[WINTYPE_POPUP_MENU] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
ps->atoms_wintypes[WINTYPE_TOOLTIP] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_TOOLTIP", False);
ps->atoms_wintypes[WINTYPE_NOTIFY] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
ps->atoms_wintypes[WINTYPE_COMBO] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_COMBO", False);
ps->atoms_wintypes[WINTYPE_DND] = XInternAtom(ps->dpy,
"_NET_WM_WINDOW_TYPE_DND", False);
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");
}

/**
Expand Down
27 changes: 22 additions & 5 deletions src/compton.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ typedef void(* event_callback_fn)(evutil_socket_t, short, void *);
#define REGISTER_PROP "_NET_WM_CM_S"

#define FADE_DELTA_TOLERANCE 0.2
#define SWOPTI_TOLERANCE 1000
#define SWOPTI_TOLERANCE 3000
#define WIN_GET_LEADER_MAX_RECURSION 20

#define SEC_WRAP (15L * 24L * 60L * 60L)
Expand Down Expand Up @@ -879,10 +879,10 @@ static int
should_ignore(session_t *ps, unsigned long sequence);

/**
* Wrapper of XInternAtom() for convience.
* Wrapper of XInternAtom() for convenience.
*/
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);
}

Expand Down Expand Up @@ -1530,8 +1530,25 @@ update_reg_ignore_expire(session_t *ps, const win *w) {
*/
static inline bool __attribute__((const))
win_has_frame(const win *w) {
return w->top_width || w->left_width || w->right_width
|| w->bottom_width;
return w->a.border_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);
}
}

/**
Expand Down

0 comments on commit 7188054

Please sign in to comment.