gettimeofday(&start, NULL);
#endif
obt_display_ignore_errors(TRUE);
- glXBindTexImageEXT(obt_display, win->gpixmap, GLX_FRONT_LEFT_EXT, NULL);
+ glXBindTexImageEXT(obt_display, win->gpixmap, GLX_FRONT_LEFT_EXT,
+ NULL);
obt_display_ignore_errors(FALSE);
if (obt_display_error_occured)
g_assert(0 && "ERROR BINDING GLX PIXMAP");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- x = win->toparea.x + win->area.x;
- y = win->toparea.y + win->area.y;
+ x = win->toparea.x + win->topborder + win->area.x;
+ y = win->toparea.y + win->topborder + win->area.y;
w = win->area.width;
h = win->area.height;
glColor4ui(0xffffffff, 0xffffffff, 0xffffffff, *win->alpha);
glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex3f(x, y, 0.0);
- glTexCoord2f(0, 1);
- glVertex3f(x, y + h, 0.0);
- glTexCoord2f(1, 1);
- glVertex3f(x + w, y + h, 0.0);
- glTexCoord2f(1, 0);
- glVertex3f(x + w, y, 0.0);
+ if (!win->n_rects) {
+ glTexCoord2f(0, 0);
+ glVertex3f(x, y, 0.0);
+ glTexCoord2f(0, 1);
+ glVertex3f(x, y + h, 0.0);
+ glTexCoord2f(1, 1);
+ glVertex3f(x + w, y + h, 0.0);
+ glTexCoord2f(1, 0);
+ glVertex3f(x + w, y, 0.0);
+ }
+ else {
+ gint i;
+ /* the border is not included in the shape rect coords */
+ const gint sb = window_top(win) == window_redir(win) ?
+ win->topborder : 0;
+
+
+ for (i = 0; i < win->n_rects; ++i) {
+ const gint xb = win->rects[i].x + sb;
+ const gint yb = win->rects[i].y + sb;
+ const gint wb = win->rects[i].width;
+ const gint hb = win->rects[i].height;
+
+ glTexCoord2d((GLdouble)xb/w,
+ (GLdouble)yb/h);
+ glVertex3f(x + xb, y + yb, 0.0f);
+
+ glTexCoord2d((GLdouble)xb/w,
+ (GLdouble)(yb+hb)/h);
+ glVertex3f(x + xb, y + yb + hb, 0.0f);
+
+ glTexCoord2d((GLdouble)(xb+wb)/w,
+ (GLdouble)(yb+hb)/h);
+ glVertex3f(x + xb + wb, y + yb + hb, 0.0f);
+
+ glTexCoord2d((GLdouble)(xb+wb)/w,
+ (GLdouble)yb/h);
+ glVertex3f(x + xb + wb, y + yb, 0.0f);
+ }
+ }
glEnd();
if (win->alpha && *win->alpha < 0xffffffff)
static void event_process(const XEvent *e, gpointer data);
static void event_handle_root(XEvent *e);
static gboolean event_handle_menu_input(XEvent *e);
+static gboolean event_handle_window(ObWindow *w, XEvent *e);
static void event_handle_menu(ObMenuFrame *frame, XEvent *e);
static gboolean event_handle_prompt(ObPrompt *p, XEvent *e);
static void event_handle_dock(ObDock *s, XEvent *e);
if (!obwin && xe->parent == obt_root(ob_screen))
obwin = UNMANAGED_AS_WINDOW(unmanaged_new(xe->window));
}
- else if ((obwin && obwin->type != OB_WINDOW_CLASS_PROMPT) &&
- ((e->type == ConfigureNotify &&
- /* for configure notify, track the position/size of
- both the top-level window and the redir window (when
- it is not the top-level window) */
- e->xconfigure.send_event == FALSE &&
- ((e->xconfigure.window == window_redir(obwin) &&
- window_redir(obwin) != window_top(obwin)) ||
- (e->xconfigure.window == window_top(obwin)))) ||
- (e->type == MapNotify &&
- e->xmap.window == window_redir(obwin))))
- {
- gboolean pixchange = FALSE;
-
- if (e->type == ConfigureNotify) {
- XConfigureEvent const *xe = &e->xconfigure;
-
- if (xe->window == window_redir(obwin)) {
- int x, y, w, h;
-
- /* if the redir window's size changes.. */
- if (obwin->area.width != xe->width ||
- obwin->area.height != xe->height ||
- /* or its border changes.. (assume only the top-level
- window will ever have a border) */
- (window_top(obwin) == window_redir(obwin) &&
- obwin->topborder != xe->border_width))
- {
- /* ..then need to change the pixmap */
- pixchange = TRUE;
- }
-
- /* set the redir window's area */
- if (window_redir(obwin) == window_top(obwin)) {
- /* same window then its area fills the whole top level
- window */
- x = 0;
- y = 0;
- w = xe->width + xe->border_width * 2;
- h = xe->height + xe->border_width * 2;
- }
- else {
- /* different window then it is inside the top level
- window */
- x = xe->x;
- y = xe->y;
- w = xe->width;
- h = xe->height;
- }
- RECT_SET(obwin->area, x, y, w, h);
- }
-
- /* set the top window's area/border */
- if (xe->window == window_top(obwin)) {
- RECT_SET(obwin->toparea, xe->x, xe->y, xe->width, xe->height);
- obwin->topborder = xe->border_width;
- }
- }
-
- if (e->type == MapNotify) {
- pixchange = TRUE;
- obwin->mapped = TRUE;
- }
-
- if (pixchange)
- composite_window_invalid(obwin);
- }
- else if ((e->type == UnmapNotify) && obwin &&
- obwin->type != OB_WINDOW_CLASS_PROMPT &&
- e->xunmap.window == window_top(obwin))
- {
- obwin->mapped = FALSE;
- }
+ else if (obwin && event_handle_window(obwin, e))
+ /* handled it ! */;
else if (client)
event_handle_client(client, e);
else if (um)
;
#ifdef SHAPE
{
- int kind;
+ int kind = -1;
if (obt_display_extension_shape &&
- e->type == obt_display_extension_shape_basep)
+ e->type == obt_display_extension_shape_basep + ShapeNotify)
{
switch (((XShapeEvent*)e)->kind) {
case ShapeBounding:
- case ShapeClip:
client->shaped = ((XShapeEvent*)e)->shaped;
kind = ShapeBounding;
break;
+ case ShapeClip:
+ break;
case ShapeInput:
client->shaped_input = ((XShapeEvent*)e)->shaped;
kind = ShapeInput;
default:
g_assert_not_reached();
}
- frame_adjust_shape_kind(client->frame, kind);
+ if (kind) frame_adjust_shape_kind(client->frame, kind);
}
}
#endif
}
}
+static gboolean event_handle_window(ObWindow *wi, XEvent *e)
+{
+ gboolean used = FALSE, pixchange = FALSE;
+
+ if (wi->type == OB_WINDOW_CLASS_PROMPT) return used;
+
+ switch (e->type) {
+ case ConfigureNotify:
+ if (e->xconfigure.send_event) break;
+
+ if (e->xconfigure.window == window_redir(wi)) {
+ XConfigureEvent const *xe = &e->xconfigure;
+ const gboolean same_window = window_top(wi) == window_redir(wi);
+ int x, y, w, h;
+
+ /* if the redir window's size changes.. */
+ if (wi->area.width != xe->width || wi->area.height != xe->height ||
+ /* or its border changes.. (assume only the top-level
+ window will ever have a border) */
+ (same_window && wi->topborder != xe->border_width))
+ {
+ /* ..then need to change the pixmap */
+ pixchange = TRUE;
+ }
+
+ /* set the redir window's area */
+ if (same_window) {
+ /* same window then its area fills the whole top level
+ window */
+ x = -xe->border_width;
+ y = -xe->border_width;
+ w = xe->width + xe->border_width * 2;
+ h = xe->height + xe->border_width * 2;
+ }
+ else {
+ /* different window then it is inside the top level
+ window */
+ x = xe->x;
+ y = xe->y;
+ w = xe->width;
+ h = xe->height;
+ }
+ RECT_SET(wi->area, x, y, w, h);
+ used = TRUE;
+ }
+
+ /* set the top window's area/border */
+ if (e->xconfigure.window == window_top(wi)) {
+ XConfigureEvent const *xe = &e->xconfigure;
+ RECT_SET(wi->toparea, xe->x, xe->y, xe->width, xe->height);
+ wi->topborder = xe->border_width;
+ used = TRUE;
+ }
+ break;
+
+ case MapNotify:
+ if (e->xmap.window == window_redir(wi)) {
+ wi->mapped = TRUE;
+ pixchange = TRUE;
+ used = TRUE;
+ }
+ break;
+ case UnmapNotify:
+ if (e->xunmap.window == window_top(wi)) {
+ wi->mapped = FALSE;
+ used = TRUE;
+ }
+ break;
+ default:
+#ifdef SHAPE
+#ifdef USE_COMPOSITING
+ if (obt_display_extension_shape &&
+ e->type == obt_display_extension_shape_basep + ShapeNotify)
+ {
+ XShapeEvent *s = (XShapeEvent*)e;
+ if (s->window == window_redir(wi) && s->kind == ShapeBounding) {
+ window_adjust_redir_shape(wi);
+ used = FALSE; /* let other people get this event also */
+ }
+ }
+#endif
+#endif
+ }
+ if (pixchange)
+ composite_window_invalid(wi);
+ return used;
+}
+
static void event_handle_unmanaged(ObUnmanaged *um, XEvent *e)
{
Window w;
/* set up any things in ObWindow that require use of the abstract pointers
now */
+#ifdef SHAPE
+#ifdef USE_COMPOSITING
+ {
+ gint foo;
+ guint ufoo;
+ gint s;
+
+ XShapeQueryExtents(obt_display, window_redir(self), &s, &foo,
+ &foo, &ufoo, &ufoo, &foo, &foo, &foo, &ufoo,
+ &ufoo);
+ if (s) window_adjust_redir_shape(self);
+ }
+#endif
+#endif
+
composite_window_setup(self);
}
#ifdef USE_COMPOSITING
self->toparea = *r;
self->topborder = border;
- RECT_SET(self->area, 0, 0, self->toparea.width, self->toparea.height);
+ RECT_SET(self->area, -border, -border,
+ self->toparea.width + border * 2,
+ self->toparea.height + border * 2);
#endif
}
/* The abstract pointers must not be used here, they are likely invalid
by now ! */
+ if (self->rects) XFree(self->rects);
g_slice_free1(self->bytes, self);
}
g_hash_table_remove(window_map, &xwin);
}
+void window_adjust_redir_shape(ObWindow *self)
+{
+#ifdef USE_COMPOSITING
+#ifdef SHAPE
+ gint ord;
+ if (self->rects)
+ XFree(self->rects);
+ self->rects = XShapeGetRectangles(obt_display, window_redir(self),
+ ShapeBounding, &self->n_rects, &ord);
+#endif
+#endif
+}
+
ObInternalWindow* window_internal_new(Window window, const Rect *area,
gint border, gint depth)
{