summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Grenville <[email protected]>2012-09-22 20:49:17 +0800
committerRichard Grenville <[email protected]>2012-09-22 20:59:26 +0800
commit80a4f6d0ab1a2bce927627ecde37be4e09752e0e (patch)
tree5fda405c79fb178230ec6fc313cabd141a762cc0
parentcbdaa9c000fada417cabf2092751945cbafc6ec0 (diff)
downloadtdebase-80a4f6d0ab1a2bce927627ecde37be4e09752e0e.tar.gz
tdebase-80a4f6d0ab1a2bce927627ecde37be4e09752e0e.zip
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().
-rw-r--r--compton.c91
-rw-r--r--compton.h2
2 files changed, 38 insertions, 55 deletions
diff --git a/compton.c b/compton.c
index 015f563fd..c6c6279dc 100644
--- a/compton.c
+++ b/compton.c
@@ -1517,50 +1517,39 @@ wintype_name(wintype type) {
#endif
static wintype
-get_wintype_prop(Display * dpy, Window w) {
+get_wintype_prop(Display *dpy, Window wid) {
Atom actual;
- wintype ret;
int format;
- unsigned long n, left, off;
- unsigned char *data;
-
- ret = WINTYPE_UNKNOWN;
- off = 0;
-
- do {
- set_ignore(dpy, NextRequest(dpy));
+ unsigned long n = 0, left, i;
+ long *data = NULL;
+ int j;
- int result = XGetWindowProperty(
- dpy, w, win_type_atom, off, 1L, False, XA_ATOM,
- &actual, &format, &n, &left, &data);
-
- if (result != Success) break;
-
- if (data != None) {
- int i;
+ set_ignore(dpy, NextRequest(dpy));
+ 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;
+ }
- for (i = 1; i < NUM_WINTYPES; ++i) {
- Atom a;
- memcpy(&a, data, sizeof(Atom));
- if (a == win_type[i]) {
- /* known type */
- ret = i;
- break;
- }
+ for (i = 0; i < n; ++i) {
+ for (j = 1; j < NUM_WINTYPES; ++j) {
+ if (win_type[j] == (Atom) data[i]) {
+ XFree(data);
+ return j;
}
-
- XFree((void *) data);
}
+ }
- ++off;
- } while (left >= 4 && ret == WINTYPE_UNKNOWN);
+ XFree(data);
- return ret;
+ return WINTYPE_UNKNOWN;
}
static wintype
-determine_wintype(Display *dpy, Window w, Window top) {
- Window root_return, parent_return;
+determine_wintype(Display *dpy, Window w) {
Window *children = NULL;
unsigned int nchildren, i;
wintype type;
@@ -1568,16 +1557,11 @@ determine_wintype(Display *dpy, Window w, Window top) {
type = get_wintype_prop(dpy, w);
if (type != WINTYPE_UNKNOWN) return type;
- set_ignore(dpy, NextRequest(dpy));
- if (!XQueryTree(dpy, w, &root_return, &parent_return,
- &children, &nchildren)) {
- /* XQueryTree failed. */
- if (children) XFree((void *)children);
+ if (!win_get_children(dpy, w, &children, &nchildren))
return WINTYPE_UNKNOWN;
- }
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;
}
@@ -1585,11 +1569,7 @@ determine_wintype(Display *dpy, Window w, Window top) {
XFree((void *)children);
}
- if (w != top) {
- return WINTYPE_UNKNOWN;
- } else {
- return WINTYPE_NORMAL;
- }
+ return WINTYPE_UNKNOWN;
}
static void
@@ -1602,12 +1582,6 @@ map_win(Display *dpy, Window id,
w->focused = False;
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
// changes are lost
@@ -1635,6 +1609,14 @@ map_win(Display *dpy, Window id,
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
if (track_wdata) {
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 != win_type_opacity[w->window_type]) {
+ if (1.0 != win_type_opacity[w->window_type]) {
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);
}
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
@@ -2026,7 +2010,6 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) {
*p = new;
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);
}
}
@@ -2954,7 +2937,7 @@ usage(void) {
" \"s\" (match from start), \"w\" (wildcard), and \"p\" (PCRE\n"
" regular expressions, if compiled with the support).\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"
"\n"
" <pattern> is the actual pattern string.\n"
diff --git a/compton.h b/compton.h
index a46213569..c57dd2fd2 100644
--- a/compton.h
+++ b/compton.h
@@ -588,7 +588,7 @@ static wintype
get_wintype_prop(Display * dpy, Window w);
static wintype
-determine_wintype(Display *dpy, Window w, Window top);
+determine_wintype(Display *dpy, Window w);
static void
map_win(Display *dpy, Window id,