diff options
author | Richard Grenville <[email protected]> | 2012-09-22 20:49:17 +0800 |
---|---|---|
committer | Richard Grenville <[email protected]> | 2012-09-22 20:59:26 +0800 |
commit | 80a4f6d0ab1a2bce927627ecde37be4e09752e0e (patch) | |
tree | 5fda405c79fb178230ec6fc313cabd141a762cc0 | |
parent | cbdaa9c000fada417cabf2092751945cbafc6ec0 (diff) | |
download | tdebase-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.c | 91 | ||||
-rw-r--r-- | compton.h | 2 |
2 files changed, 38 insertions, 55 deletions
@@ -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" @@ -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, |