From 04f89d601d988f97347683127816818d5a8a4521 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 6 Mar 2008 05:55:17 -0500 Subject: [PATCH] read the _NET_WM_WINDOW_OPACITY property that transset sets, and use it when determining the opacity level for windows. --- dcompmgr.c | 26 ++++++++++++++++++++++---- display.c | 3 ++- display.h | 1 + window.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- window.h | 4 +++- 5 files changed, 79 insertions(+), 9 deletions(-) diff --git a/dcompmgr.c b/dcompmgr.c index b3619ba..f6b7019 100644 --- a/dcompmgr.c +++ b/dcompmgr.c @@ -181,16 +181,34 @@ event(d_display_t *dpy) case XCB_PROPERTY_NOTIFY: { xcb_property_notify_event_t *pev; - d_screen_t *sc; pev = (xcb_property_notify_event_t*)ev; - sc = display_screen_from_root(dpy, pev->window); - if (!sc) break; if (pev->atom == dpy->a.xrootpmap_id || pev->atom == dpy->a.esetroot_pmap_id || pev->atom == dpy->a.xsetroot_id) { - sc->screen_root_pixmap_change(sc); + d_screen_t *sc; + + sc = display_screen_from_root(dpy, pev->window); + if (sc) sc->screen_root_pixmap_change(sc); + } + else if (pev->atom == dpy->a.net_wm_window_opacity) { + d_list_it_t *it; + + for (it = list_top(dpy->screens); it; it = it->next) { + d_screen_t *sc = it->data; + d_window_t *w; + + w = screen_find_window(sc, pev->window); + if (w) { + window_update_user_opacity(w); + if (window_is_mapped(w)) { + sc->window_opacity_change(w); + screen_refresh(w->sc); + } + } + } + } break; } diff --git a/display.c b/display.c index 7f02cb6..e331150 100644 --- a/display.c +++ b/display.c @@ -127,6 +127,8 @@ query_statics(d_display_t *dpy) .name = "_XROOTPMAP_ID" }, { .atom = &dpy->a.xsetroot_id, .name = "_XSETROOT_ID" }, + { .atom = &dpy->a.net_wm_window_opacity, + .name = "_NET_WM_WINDOW_OPACITY" }, { .atom = &dpy->a.net_wm_window_type, .name = "_NET_WM_WINDOW_TYPE" }, { .atom = &dpy->a.net_wm_window_type_desktop, @@ -421,6 +423,5 @@ display_screen_from_root(d_display_t *dpy, xcb_window_t root) if (sc->super.root == root) return sc; } - assert(0); return NULL; } diff --git a/display.h b/display.h index 6cfdc76..d03bdce 100644 --- a/display.h +++ b/display.h @@ -41,6 +41,7 @@ typedef struct d_display { xcb_atom_t xrootpmap_id; xcb_atom_t xsetroot_id; xcb_atom_t wm_transient_for; + xcb_atom_t net_wm_window_opacity; xcb_atom_t net_wm_window_type; xcb_atom_t net_wm_window_type_desktop; xcb_atom_t net_wm_window_type_dock; diff --git a/window.c b/window.c index 56cbf7e..8d420ee 100644 --- a/window.c +++ b/window.c @@ -11,6 +11,8 @@ #include #include +#define TOPLEVEL_WINDOW_EVENT_MASK (XCB_EVENT_MASK_PROPERTY_CHANGE) + typedef struct { /* public stuff */ xcb_window_t id; @@ -32,8 +34,10 @@ typedef struct { queries should go to this window */ xcb_window_t client; - /* opacity is from 0xffff to 0 */ - uint16_t opacity; + /* opacity is from 0xffff to 0, these 2 are combined to give the final + result */ + uint16_t opacity; /* this one is set by plugins/settings */ + uint16_t user_opacity; /* this one is set by the user */ gboolean mapped; gboolean zombie; @@ -46,6 +50,8 @@ typedef struct { xcb_get_window_attributes_cookie_t ck_get_attr; gboolean waiting_geom; xcb_get_geometry_cookie_t ck_get_geom; + gboolean waiting_opac; + xcb_get_property_cookie_t ck_get_opac; } d_window_priv_t; static void window_get_attributes_reply(d_window_priv_t *w); @@ -70,6 +76,7 @@ window_new(xcb_window_t id, struct d_screen *sc) w->region = XCB_NONE; w->type = DC_WINDOW_TYPE_INVALID; w->opacity = 0xffff; + w->user_opacity = 0xffff; screen_stacking_add(sc, (d_window_t*)w); @@ -127,6 +134,18 @@ window_get_pixmap(d_window_t *pubw) return w->pixmap; } +void +window_update_user_opacity(d_window_t *pubw) +{ + d_window_priv_t *w = (d_window_priv_t*)pubw; + + w->ck_get_opac = + xcb_get_property(w->sc->dpy->conn, FALSE, w->id, + w->sc->dpy->a.net_wm_window_opacity, + w->sc->dpy->a.cardinal, 0, 1); + w->waiting_opac = TRUE; +} + static void window_update_region(d_window_priv_t *w) { @@ -175,6 +194,7 @@ void window_show(d_window_t *pubw) { d_window_priv_t *w = (d_window_priv_t*)pubw; + unsigned int mask; assert(!w->mapped); @@ -184,8 +204,13 @@ window_show(d_window_t *pubw) if (w->sc->dpy->shape.present) xcb_shape_select_input(w->sc->dpy->conn, w->id, TRUE); + mask = TOPLEVEL_WINDOW_EVENT_MASK; + xcb_change_window_attributes(w->sc->dpy->conn, w->id, + XCB_CW_EVENT_MASK, &mask); + window_update_pixmap(w); window_update_region(w); + window_update_user_opacity(pubw); window_update_type(w); w->mapped = TRUE; } @@ -194,12 +219,16 @@ void window_hide(d_window_t *pubw) { d_window_priv_t *w = (d_window_priv_t*)pubw; + unsigned int mask; assert(w->mapped); //printf("hide window 0x%x\n", w->id); if (w->sc->dpy->shape.present) xcb_shape_select_input(w->sc->dpy->conn, w->id, FALSE); + mask = 0; + xcb_change_window_attributes(w->sc->dpy->conn, w->id, + XCB_CW_EVENT_MASK, &mask); w->mapped = FALSE; } @@ -573,8 +602,27 @@ uint16_t window_get_opacity(d_window_t *pubw) { d_window_priv_t *w = (d_window_priv_t*)pubw; + unsigned long long l; + + if (w->waiting_opac) { + xcb_get_property_reply_t *rep; + + w->user_opacity = 0xffff; + rep = xcb_get_property_reply(w->sc->dpy->conn, w->ck_get_opac, NULL); + if (rep) { + if (rep->type == w->sc->dpy->a.cardinal && rep->length >= 1) { + l = ((uint32_t*)xcb_get_property_value(rep))[0]; + l = 0xffff * l / 0xffffffff; + w->user_opacity = l; + } + free(rep); + } + w->waiting_opac = FALSE; + } - return w->opacity; + l = w->opacity; + l = l * w->user_opacity / 0xffff; + return l; } void diff --git a/window.h b/window.h index 354e872..6d0bc50 100644 --- a/window.h +++ b/window.h @@ -61,6 +61,8 @@ xcb_pixmap_t window_get_pixmap(d_window_t *w); xcb_visualid_t window_get_visual(d_window_t *w); xcb_xfixes_region_t window_get_region(d_window_t *w); +void window_update_user_opacity(d_window_t *w); + void window_add_plugin_data(d_window_t *w, int id, void *data); void* window_find_plugin_data(d_window_t *w, int id); void window_remove_plugin_data(d_window_t *w, int it); @@ -69,8 +71,8 @@ void window_create_damage(d_window_t *w); void window_destroy_damage(d_window_t *w); d_window_type_t window_get_type(d_window_t *w); -uint16_t window_get_opacity(d_window_t *w); +uint16_t window_get_opacity(d_window_t *w); void window_set_opacity(d_window_t *w, uint16_t o); #endif -- 2.34.1