Improvement: Change window type detection

- Let window type detection start with the client window if there's one,
  in hope to enhance performance.

- Change get_wintype_prop() to fetch the property only once.

- Default to WINTYPE_UNKNOWN instead of WINTYPE_NORMAL if
  _NET_WM_WINDOW_TYPE is missing.

- Fix a mistake in calc_opacity().

- Add some items to .gitignore.

- Fix a typo in usage().
This commit is contained in:
Richard Grenville 2012-09-22 20:49:17 +08:00
parent 0d6724385e
commit a5d9955ca4
3 changed files with 45 additions and 55 deletions

7
.gitignore vendored
View File

@ -15,6 +15,13 @@ stamp-h1
compton compton
*.o *.o
*~ *~
core
# Vim files # Vim files
.*.sw[a-z] .*.sw[a-z]
# oprofile files
oprofile_data
# clang files
compton.plist

View File

@ -1517,50 +1517,39 @@ wintype_name(wintype type) {
#endif #endif
static wintype static wintype
get_wintype_prop(Display * dpy, Window w) { get_wintype_prop(Display *dpy, Window wid) {
Atom actual; Atom actual;
wintype ret;
int format; int format;
unsigned long n, left, off; unsigned long n = 0, left, i;
unsigned char *data; long *data = NULL;
int j;
ret = WINTYPE_UNKNOWN; set_ignore(dpy, NextRequest(dpy));
off = 0; if (Success != XGetWindowProperty(
dpy, wid, win_type_atom, 0L, 32L, False, XA_ATOM,
&actual, &format, &n, &left, (unsigned char **) &data)
|| !data || !n) {
if (data)
XFree(data);
return WINTYPE_UNKNOWN;
}
do { for (i = 0; i < n; ++i) {
set_ignore(dpy, NextRequest(dpy)); for (j = 1; j < NUM_WINTYPES; ++j) {
if (win_type[j] == (Atom) data[i]) {
int result = XGetWindowProperty( XFree(data);
dpy, w, win_type_atom, off, 1L, False, XA_ATOM, return j;
&actual, &format, &n, &left, &data);
if (result != Success) break;
if (data != None) {
int i;
for (i = 1; i < NUM_WINTYPES; ++i) {
Atom a;
memcpy(&a, data, sizeof(Atom));
if (a == win_type[i]) {
/* known type */
ret = i;
break;
}
} }
XFree((void *) data);
} }
}
++off; XFree(data);
} while (left >= 4 && ret == WINTYPE_UNKNOWN);
return ret; return WINTYPE_UNKNOWN;
} }
static wintype static wintype
determine_wintype(Display *dpy, Window w, Window top) { determine_wintype(Display *dpy, Window w) {
Window root_return, parent_return;
Window *children = NULL; Window *children = NULL;
unsigned int nchildren, i; unsigned int nchildren, i;
wintype type; wintype type;
@ -1568,16 +1557,11 @@ determine_wintype(Display *dpy, Window w, Window top) {
type = get_wintype_prop(dpy, w); type = get_wintype_prop(dpy, w);
if (type != WINTYPE_UNKNOWN) return type; if (type != WINTYPE_UNKNOWN) return type;
set_ignore(dpy, NextRequest(dpy)); if (!win_get_children(dpy, w, &children, &nchildren))
if (!XQueryTree(dpy, w, &root_return, &parent_return,
&children, &nchildren)) {
/* XQueryTree failed. */
if (children) XFree((void *)children);
return WINTYPE_UNKNOWN; return WINTYPE_UNKNOWN;
}
for (i = 0; i < nchildren; i++) { for (i = 0; i < nchildren; i++) {
type = determine_wintype(dpy, children[i], top); type = determine_wintype(dpy, children[i]);
if (type != WINTYPE_UNKNOWN) return type; if (type != WINTYPE_UNKNOWN) return type;
} }
@ -1585,11 +1569,7 @@ determine_wintype(Display *dpy, Window w, Window top) {
XFree((void *)children); XFree((void *)children);
} }
if (w != top) { return WINTYPE_UNKNOWN;
return WINTYPE_UNKNOWN;
} else {
return WINTYPE_NORMAL;
}
} }
static void static void
@ -1602,12 +1582,6 @@ map_win(Display *dpy, Window id,
w->focused = False; w->focused = False;
w->a.map_state = IsViewable; w->a.map_state = IsViewable;
w->window_type = determine_wintype(dpy, w->id, w->id);
#ifdef DEBUG_WINTYPE
printf("map_win(): window %#010lx type %s\n",
w->id, wintype_name(w->window_type));
#endif
// Call XSelectInput() before reading properties so that no property // Call XSelectInput() before reading properties so that no property
// changes are lost // changes are lost
@ -1635,6 +1609,14 @@ map_win(Display *dpy, Window id,
get_frame_extents(dpy, w, w->client_win); get_frame_extents(dpy, w, w->client_win);
} }
if (WINTYPE_UNKNOWN == w->window_type)
w->window_type = determine_wintype(dpy, w->id);
#ifdef DEBUG_WINTYPE
printf("map_win(%#010lx): type %s\n",
w->id, wintype_name(w->window_type));
#endif
// Get window name and class if we are tracking them // Get window name and class if we are tracking them
if (track_wdata) { if (track_wdata) {
win_get_name(dpy, w); win_get_name(dpy, w);
@ -1821,7 +1803,7 @@ calc_opacity(Display *dpy, win *w, Bool refetch_prop) {
} }
if (OPAQUE == (opacity = w->opacity_prop)) { if (OPAQUE == (opacity = w->opacity_prop)) {
if (OPAQUE != win_type_opacity[w->window_type]) { if (1.0 != win_type_opacity[w->window_type]) {
opacity = win_type_opacity[w->window_type] * OPAQUE; opacity = win_type_opacity[w->window_type] * OPAQUE;
} }
} }
@ -1928,6 +1910,8 @@ mark_client_win(Display *dpy, win *w, Window client) {
get_frame_extents(dpy, w, client); get_frame_extents(dpy, w, client);
} }
XSelectInput(dpy, client, determine_evmask(dpy, client, WIN_EVMODE_CLIENT)); XSelectInput(dpy, client, determine_evmask(dpy, client, WIN_EVMODE_CLIENT));
if (WINTYPE_UNKNOWN == w->window_type)
w->window_type = get_wintype_prop(dpy, w->client_win);
} }
static void static void
@ -2026,7 +2010,6 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) {
*p = new; *p = new;
if (new->a.map_state == IsViewable) { if (new->a.map_state == IsViewable) {
new->window_type = determine_wintype(dpy, id, id);
map_win(dpy, id, new->damage_sequence - 1, True, override_redirect); map_win(dpy, id, new->damage_sequence - 1, True, override_redirect);
} }
} }
@ -2954,7 +2937,7 @@ usage(void) {
" \"s\" (match from start), \"w\" (wildcard), and \"p\" (PCRE\n" " \"s\" (match from start), \"w\" (wildcard), and \"p\" (PCRE\n"
" regular expressions, if compiled with the support).\n" " regular expressions, if compiled with the support).\n"
"\n" "\n"
" <flags> could a serious of flags. Currently the only defined\n" " <flags> could be a series of flags. Currently the only defined\n"
" flag is \"i\" (ignore case).\n" " flag is \"i\" (ignore case).\n"
"\n" "\n"
" <pattern> is the actual pattern string.\n" " <pattern> is the actual pattern string.\n"

View File

@ -588,7 +588,7 @@ static wintype
get_wintype_prop(Display * dpy, Window w); get_wintype_prop(Display * dpy, Window w);
static wintype static wintype
determine_wintype(Display *dpy, Window w, Window top); determine_wintype(Display *dpy, Window w);
static void static void
map_win(Display *dpy, Window id, map_win(Display *dpy, Window id,