From 6e82deb05b7e8d4c183d33c5a4acb978cf465b46 Mon Sep 17 00:00:00 2001 From: Richard Grenville Date: Sun, 15 Sep 2013 11:07:49 +0800 Subject: Bug fix #144: Workaround for insane window type changes Dynamically detect window type as a workaround to insane applications. Thanks to Feltzer for reporting. (#144) --- compton.c | 62 +++++++++++++++++++++++++++++++++++++------------------------- compton.h | 3 +++ 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/compton.c b/compton.c index 23e86dd32..55e638fca 100644 --- a/compton.c +++ b/compton.c @@ -2586,6 +2586,31 @@ calc_shadow_geometry(session_t *ps, win *w) { w->shadow_height = w->heightb + ps->gaussian_map->size; } +/** + * Update window type. + */ +static void +win_upd_wintype(session_t *ps, win *w) { + const wintype_t wtype_old = w->window_type; + + // Detect window type here + w->window_type = wid_get_prop_wintype(ps, w->client_win); + + // Conform to EWMH standard, if _NET_WM_WINDOW_TYPE is not present, take + // override-redirect windows or windows without WM_TRANSIENT_FOR as + // _NET_WM_WINDOW_TYPE_NORMAL, otherwise as _NET_WM_WINDOW_TYPE_DIALOG. + if (WINTYPE_UNKNOWN == w->window_type) { + if (w->a.override_redirect + || !wid_has_prop(ps, w->client_win, ps->atom_transient)) + w->window_type = WINTYPE_NORMAL; + else + w->window_type = WINTYPE_DIALOG; + } + + if (w->window_type != wtype_old) + win_on_wtype_change(ps, w); +} + /** * Mark a window as the client window of another. * @@ -2608,32 +2633,11 @@ win_mark_client(session_t *ps, win *w, Window client) { // Make sure the XSelectInput() requests are sent XSync(ps->dpy, False); - // Get frame widths if needed - if (ps->o.frame_opacity) { - get_frame_extents(ps, w, client); - } + win_upd_wintype(ps, w); - { - wintype_t wtype_old = w->window_type; - - // Detect window type here - if (WINTYPE_UNKNOWN == w->window_type) - w->window_type = wid_get_prop_wintype(ps, w->client_win); - - // Conform to EWMH standard, if _NET_WM_WINDOW_TYPE is not present, take - // override-redirect windows or windows without WM_TRANSIENT_FOR as - // _NET_WM_WINDOW_TYPE_NORMAL, otherwise as _NET_WM_WINDOW_TYPE_DIALOG. - if (WINTYPE_UNKNOWN == w->window_type) { - if (w->a.override_redirect - || !wid_has_prop(ps, client, ps->atom_transient)) - w->window_type = WINTYPE_NORMAL; - else - w->window_type = WINTYPE_DIALOG; - } - - if (w->window_type != wtype_old) - win_on_wtype_change(ps, w); - } + // Get frame widths. The window is in damaged area already. + if (ps->o.frame_opacity) + get_frame_extents(ps, w, client); // Get window group if (ps->o.track_leader) @@ -4027,6 +4031,14 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) { } } + // If _NET_WM_WINDOW_TYPE changes... God knows why this would happen, but + // there are always some stupid applications. (#144) + if (ev->atom == ps->atom_win_type) { + win *w = NULL; + if ((w = find_toplevel(ps, ev->window))) + win_upd_wintype(ps, w); + } + // If _NET_WM_OPACITY changes if (ev->atom == ps->atom_opacity) { win *w = NULL; diff --git a/compton.h b/compton.h index d44544633..1180ce32c 100644 --- a/compton.h +++ b/compton.h @@ -803,6 +803,9 @@ calc_win_size(session_t *ps, win *w); static void calc_shadow_geometry(session_t *ps, win *w); +static void +win_upd_wintype(session_t *ps, win *w); + static void win_mark_client(session_t *ps, win *w, Window client); -- cgit v1.2.1