CREATE_(NET_WM_ICON);
CREATE_(NET_WM_ICON_GEOMETRY);
CREATE_(NET_WM_PID);
+ CREATE_(NET_WM_WINDOW_OPACITY);
CREATE_(NET_WM_ALLOWED_ACTIONS);
CREATE_(NET_WM_USER_TIME);
/* CREATE_(NET_WM_USER_TIME_WINDOW); */
OBT_PROP_NET_WM_ICON,
OBT_PROP_NET_WM_ICON_GEOMETRY,
OBT_PROP_NET_WM_PID,
+ OBT_PROP_NET_WM_WINDOW_OPACITY,
OBT_PROP_NET_WM_ALLOWED_ACTIONS,
OBT_PROP_NET_WM_USER_TIME,
/* OBT_PROP_NET_WM_USER_TIME_WINDOW, */
/* create the decoration frame for the client window */
self->frame = frame_new(self);
+ /* this must occur after the frame exists, since we copy the opacity value
+ onto the frame */
+ client_update_opacity(self);
+
window_set_abstract(CLIENT_AS_WINDOW(self),
&self->frame->window, /* top level window */
&self->layer, /* stacking layer */
- &self->frame->depth); /* window depth */
+ &self->frame->depth, /* window depth */
+ &self->alpha); /* opacity */
frame_grab_client(self->frame);
window_set_abstract(CLIENT_AS_WINDOW(self),
&self->frame->window, /* top level window */
&self->layer, /* stacking layer */
- &self->frame->depth); /* window depth */
+ &self->frame->depth, /* window depth */
+ NULL); /* opacity */
frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
}
}
+void client_update_opacity(ObClient *self)
+{
+ /* The alpha value is to be copied from the client onto its top-level
+ window for third-party compositing managers to see */
+ if (!OBT_PROP_GET32(self->window, NET_WM_WINDOW_OPACITY, CARDINAL,
+ &self->alpha))
+ {
+ self->alpha = 0xffffffff;
+ OBT_PROP_ERASE(self->frame->window, NET_WM_WINDOW_OPACITY);
+ }
+ else
+ OBT_PROP_SET32(self->frame->window, NET_WM_WINDOW_OPACITY, CARDINAL,
+ self->alpha);
+}
+
static void client_get_session_ids(ObClient *self)
{
guint32 leader;
gchar *wm_command;
/*! The PID of the process which owns the window */
pid_t pid;
+ /*! The opacity for the window. 0 is transparent, 0xffffffff is opaque */
+ guint32 alpha;
/*! The application that created the window */
gchar *name;
void client_update_icons(ObClient *self);
/*! Updates the window's icon geometry (where to iconify to/from) */
void client_update_icon_geometry(ObClient *self);
+/*! Updates the window's opacity */
+void client_update_opacity(ObClient *client);
/*! Set up what decor should be shown on the window and what functions should
be allowed (ObClient::decorations and ObClient::functions).
w = win->area.width + win->border * 2;
h = win->area.height + win->border * 2;
+ if (win->alpha && *win->alpha < 0xffffffff)
+ glColor4ui(0xffffffff, 0xffffffff, 0xffffffff, *win->alpha);
+
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(x, y, 0.0);
glTexCoord2f(1, 0);
glVertex3f(x + w, y, 0.0);
glEnd();
+
+ if (win->alpha && *win->alpha < 0xffffffff)
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+
cglXReleaseTexImage(obt_display, win->gpixmap, GLX_FRONT_LEFT_EXT);
}
glFinish();
if (ob_comp_indirect)
- g_usleep(5000);
+ g_usleep(1000);
#ifdef DEBUG
{
window_set_abstract(DOCK_AS_WINDOW(dock),
&dock->frame, /* top level window */
&config_dock_layer, /* stacking layer */
- &dock->depth); /* window depth */
+ &dock->depth, /* window depth */
+ NULL);
window_add(&dock->frame, DOCK_AS_WINDOW(dock));
stacking_add(DOCK_AS_WINDOW(dock));
moveresize_end(FALSE);
client_update_sync_request_counter(client);
}
+ else if (msgtype == OBT_PROP_ATOM(NET_WM_WINDOW_OPACITY))
+ client_update_opacity(client);
#endif
break;
case ColormapNotify:
Window w;
switch (e->type) {
+ case PropertyNotify:
+ if (e->xproperty.atom == OBT_PROP_ATOM(NET_WM_WINDOW_OPACITY))
+ unmanaged_update_opacity(um);
+ break;
case DestroyNotify:
unmanaged_destroy(um);
break;
window_set_abstract(INTERNAL_AS_WINDOW(popup),
&popup->bg,
&popup->layer,
- &popup->depth);
+ &popup->depth,
+ NULL);
stacking_add(INTERNAL_AS_WINDOW(popup));
window_add(&popup->bg, INTERNAL_AS_WINDOW(popup));
window_set_abstract(MENUFRAME_AS_WINDOW(self),
&self->window, /* top level window */
&self->layer, /* stacking layer */
- &self->depth); /* window depth */
+ &self->depth, /* window depth */
+ NULL); /* opacity */
window_add(&self->window, MENUFRAME_AS_WINDOW(self));
stacking_add(MENUFRAME_AS_WINDOW(self));
window_set_abstract(INTERNAL_AS_WINDOW(self),
&self->bg, /* top level window */
&self->layer, /* stacking layer */
- &self->depth); /* window depth */
+ &self->depth, /* window depth */
+ NULL); /* opacity */
stacking_add(INTERNAL_AS_WINDOW(self));
window_add(&self->bg, INTERNAL_AS_WINDOW(self));
supported[i++] = OBT_PROP_ATOM(NET_WM_SYNC_REQUEST_COUNTER);
#endif
supported[i++] = OBT_PROP_ATOM(NET_WM_PID);
+ supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_OPACITY);
supported[i++] = OBT_PROP_ATOM(NET_WM_PING);
supported[i++] = OBT_PROP_ATOM(KDE_WM_CHANGE_STATE);
#include "composite.h"
#include "window.h"
#include "obt/display.h"
+#include "obt/prop.h"
struct _ObUnmanaged {
ObWindow super;
- Window win;
+ Window window;
ObStackingLayer layer;
gint depth;
-
+ guint32 alpha;
};
static GSList *unmanaged_list = NULL;
return NULL;
self = window_new(OB_WINDOW_CLASS_UNMANAGED, ObUnmanaged);
- self->win = w;
+ self->window = w;
self->layer = OB_STACKING_LAYER_ALL;
self->depth = at.depth;
+ self->alpha = 0xffffffff;
+
+ XSelectInput(obt_display, self->window, PropertyChangeMask);
+
+ unmanaged_update_opacity(self);
window_set_abstract(UNMANAGED_AS_WINDOW(self),
- &self->win,
+ &self->window,
&self->layer,
- &self->depth);
+ &self->depth,
+ &self->alpha);
- window_add(&self->win, UNMANAGED_AS_WINDOW(self));
+ window_add(&self->window, UNMANAGED_AS_WINDOW(self));
stacking_add(UNMANAGED_AS_WINDOW(self));
unmanaged_list = g_slist_prepend(unmanaged_list, self);
void unmanaged_destroy(ObUnmanaged *self)
{
+ XSelectInput(obt_display, self->window, NoEventMask);
+
window_cleanup(UNMANAGED_AS_WINDOW(self));
unmanaged_list = g_slist_remove(unmanaged_list, self);
stacking_remove(UNMANAGED_AS_WINDOW(self));
- window_remove(self->win);
+ window_remove(self->window);
window_free(UNMANAGED_AS_WINDOW(self));
}
while (unmanaged_list)
unmanaged_destroy(unmanaged_list->data);
}
+
+void unmanaged_update_opacity(ObUnmanaged *self)
+{
+ if (!OBT_PROP_GET32(self->window, NET_WM_WINDOW_OPACITY, CARDINAL,
+ &self->alpha))
+ self->alpha = 0xffffffff;
+}
void unmanaged_destroy_all(void);
+void unmanaged_update_opacity(ObUnmanaged *self);
+
#endif
void window_set_abstract(ObWindow *self,
const Window *top,
const ObStackingLayer *layer,
- const int *depth)
+ const int *depth,
+ const guint32 *alpha)
{
+ g_assert(!self->top && !self->layer && !self->depth && !self->alpha);
+
self->top = top;
self->layer = layer;
self->depth = depth;
+ self->alpha = alpha;
/* set up any things in ObWindow that require use of the abstract pointers
now */
self->layer = OB_STACKING_LAYER_INTERNAL;
self->depth = depth;
window_set_abstract(INTERNAL_AS_WINDOW(self),
- &self->window,
- &self->layer,
- &self->depth);
+ &self->window, /* top-most window */
+ &self->layer, /* stacking layer */
+ &self->depth, /* window depth */
+ NULL); /* opacity */
return self;
}
const Window *top;
/*! Points to the stacking layer for the ObWindow */
const ObStackingLayer *layer;
- /*! Points to the position and size occupied by the ObWindow */
/*! Points to the depth of the ObWindow */
const int *depth;
+ /*! Points to the alpha the ObWindow.
+ 0xffffffff is completely transparent, 0 is opaque. If this is NULL,
+ then the window will be considered opaque. */
+ const guint32 *alpha;
#ifdef USE_COMPOSITING
GLuint texture;
void window_set_abstract(ObWindow *self,
const Window *top,
const ObStackingLayer *layer,
- const int *depth);
+ const int *depth,
+ const guint32 *alpha);
/*! A subclass of ObWindow must call this when it is going to be destroying
itself, but _before_ it destroys the members it sets in
window_set_abstract() */