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;
}
.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,
if (sc->super.root == root)
return sc;
}
- assert(0);
return NULL;
}
#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;
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;
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);
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);
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)
{
window_show(d_window_t *pubw)
{
d_window_priv_t *w = (d_window_priv_t*)pubw;
+ unsigned int mask;
assert(!w->mapped);
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;
}
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;
}
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
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);
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