read the _NET_WM_WINDOW_OPACITY property that transset sets, and use it when determin...
authorDana Jansens <danakj@orodu.net>
Thu, 6 Mar 2008 10:55:17 +0000 (05:55 -0500)
committerDana Jansens <danakj@orodu.net>
Thu, 6 Mar 2008 10:59:56 +0000 (05:59 -0500)
dcompmgr.c
display.c
display.h
window.c
window.h

index b3619ba..f6b7019 100644 (file)
@@ -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;
         }
index 7f02cb6..e331150 100644 (file)
--- 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;
 }
index 6cfdc76..d03bdce 100644 (file)
--- 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;
index 56cbf7e..8d420ee 100644 (file)
--- a/window.c
+++ b/window.c
@@ -11,6 +11,8 @@
 #include <xcb/composite.h>
 #include <xcb/damage.h>
 
+#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
index 354e872..6d0bc50 100644 (file)
--- 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