File compiz-0.7.8-NOMAD.diff of Package compiz
diff --git a/gtk/window-decorator/gtk-window-decorator.c b/gtk/window-decorator/gtk-window-decorator.c
index d018a42..e19d770 100644
--- a/gtk/window-decorator/gtk-window-decorator.c
+++ b/gtk/window-decorator/gtk-window-decorator.c
@@ -236,6 +236,7 @@ int right_click_action = RIGHT_CLICK_ACTION_DEFAULT;
int wheel_action = WHEEL_ACTION_DEFAULT;
static gboolean minimal = FALSE;
+static gboolean reduced_resources = FALSE;
static double decoration_alpha = 0.5;
@@ -304,8 +305,9 @@ static decor_shadow_t *switcher_shadow = NULL;
static GdkPixmap *decor_normal_pixmap = NULL;
static GdkPixmap *decor_active_pixmap = NULL;
-static Atom frame_window_atom;
static Atom win_decor_atom;
+static Atom win_decor_active_atom;
+static Atom frame_window_atom;
static Atom win_blur_decor_atom;
static Atom wm_move_resize_atom;
static Atom restack_window_atom;
@@ -371,6 +373,24 @@ static struct _pos {
{ 6, 2, 16, 16, 0, 0, 0, 0, 0, 0 }
};
+static char *wm_action_name[3][3] = {
+ {
+ "_COMPIZ_WM_WINDOW_SIZE_TOPLEFT_DECOR",
+ "_COMPIZ_WM_WINDOW_SIZE_TOP_DECOR",
+ "_COMPIZ_WM_WINDOW_SIZE_TOPRIGHT_DECOR"
+ }, {
+ "_COMPIZ_WM_WINDOW_SIZE_LEFT_DECOR",
+ "_COMPIZ_WM_WINDOW_MOVE_DECOR",
+ "_COMPIZ_WM_WINDOW_SIZE_RIGHT_DECOR"
+ }, {
+ "_COMPIZ_WM_WINDOW_SIZE_BOTTOMLEFT_DECOR",
+ "_COMPIZ_WM_WINDOW_SIZE_BOTTOM_DECOR",
+ "_COMPIZ_WM_WINDOW_SIZE_BOTTOMRIGHT_DECOR"
+ }
+};
+static Atom wm_action_atom[3][3];
+static Atom wm_action_notify_atom[3][3];
+
typedef struct _decor_color {
double r;
double g;
@@ -384,8 +404,9 @@ typedef struct _decor {
Window event_windows[3][3];
Window button_windows[BUTTON_NUM];
guint button_states[BUTTON_NUM];
- GdkPixmap *pixmap;
GdkPixmap *buffer_pixmap;
+ GdkPixmap *pixmap;
+ GdkPixmap *active_pixmap;
GdkGC *gc;
decor_layout_t border_layout;
decor_context_t *context;
@@ -477,32 +498,26 @@ static Window switcher_selected_window = None;
static XRenderPictFormat *xformat;
static void
-decor_update_blur_property (decor_t *d,
- int width,
- int height,
- Region top_region,
- int top_offset,
- Region bottom_region,
- int bottom_offset,
- Region left_region,
- int left_offset,
- Region right_region,
- int right_offset)
+decor_update_box_property (decor_t *d,
+ XID xid,
+ Atom property,
+ int value0,
+ int value1,
+ int width,
+ int height,
+ Region top_region,
+ int top_offset,
+ Region bottom_region,
+ int bottom_offset,
+ Region left_region,
+ int left_offset,
+ Region right_region,
+ int right_offset)
{
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
long *data = NULL;
int size = 0;
- if (blur_type != BLUR_TYPE_ALL)
- {
- bottom_region = NULL;
- left_region = NULL;
- right_region = NULL;
-
- if (blur_type != BLUR_TYPE_TITLEBAR)
- top_region = NULL;
- }
-
if (top_region)
size += top_region->numRects;
if (bottom_region)
@@ -517,15 +532,18 @@ decor_update_blur_property (decor_t *d,
if (data)
{
- decor_region_to_blur_property (data, 4, 0, width, height,
- top_region, top_offset,
- bottom_region, bottom_offset,
- left_region, left_offset,
- right_region, right_offset);
+ data[0] = value0;
+ data[1] = value1;
+
+ decor_region_to_box_property (data + 2, width, height,
+ top_region, top_offset,
+ bottom_region, bottom_offset,
+ left_region, left_offset,
+ right_region, right_offset);
gdk_error_trap_push ();
- XChangeProperty (xdisplay, d->prop_xid,
- win_blur_decor_atom,
+ XChangeProperty (xdisplay, xid,
+ property,
XA_INTEGER,
32, PropModeReplace, (guchar *) data,
2 + size * 6);
@@ -537,13 +555,52 @@ decor_update_blur_property (decor_t *d,
else
{
gdk_error_trap_push ();
- XDeleteProperty (xdisplay, d->prop_xid, win_blur_decor_atom);
+ XDeleteProperty (xdisplay, xid, property);
gdk_display_sync (gdk_display_get_default ());
gdk_error_trap_pop ();
}
}
static void
+decor_update_blur_property (decor_t *d,
+ int width,
+ int height,
+ Region top_region,
+ int top_offset,
+ Region bottom_region,
+ int bottom_offset,
+ Region left_region,
+ int left_offset,
+ Region right_region,
+ int right_offset)
+{
+ if (blur_type != BLUR_TYPE_ALL)
+ {
+ bottom_region = NULL;
+ left_region = NULL;
+ right_region = NULL;
+
+ if (blur_type != BLUR_TYPE_TITLEBAR)
+ top_region = NULL;
+ }
+
+ decor_update_box_property (d,
+ d->prop_xid,
+ win_blur_decor_atom,
+ 4, 0,
+ width,
+ height,
+ top_region,
+ top_offset,
+ bottom_region,
+ bottom_offset,
+ left_region,
+ left_offset,
+ right_region,
+ right_offset);
+}
+
+static void
decor_update_window_property (decor_t *d)
{
long data[256];
@@ -572,6 +629,24 @@ decor_update_window_property (decor_t *d)
extents.top += titlebar_height;
+ if (d->active_pixmap)
+ {
+ decor_quads_to_property (data, GDK_PIXMAP_XID (d->active_pixmap),
+ &extents, &extents,
+ ICON_SPACE + d->button_width,
+ 0,
+ quads, nQuad);
+
+ gdk_error_trap_push ();
+ XChangeProperty (xdisplay, d->prop_xid,
+ win_decor_active_atom,
+ win_decor_atom,
+ 32, PropModeReplace, (guchar *) data,
+ BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
+ gdk_display_sync (gdk_display_get_default ());
+ gdk_error_trap_pop ();
+ }
+
decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap),
&extents, &extents,
ICON_SPACE + d->button_width,
@@ -581,7 +656,7 @@ decor_update_window_property (decor_t *d)
gdk_error_trap_push ();
XChangeProperty (xdisplay, d->prop_xid,
win_decor_atom,
- XA_INTEGER,
+ win_decor_atom,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
gdk_display_sync (gdk_display_get_default ());
@@ -650,7 +725,7 @@ decor_update_switcher_property (decor_t *d)
gdk_error_trap_push ();
XChangeProperty (xdisplay, d->prop_xid,
win_decor_atom,
- XA_INTEGER,
+ win_decor_atom,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
gdk_display_sync (gdk_display_get_default ());
@@ -976,7 +1051,9 @@ button_state_paint (cairo_t *cr,
}
static void
-draw_window_decoration (decor_t *d)
+draw_window_decoration_to_pixmap (decor_t *d,
+ GdkPixmap *pixmap,
+ gint active)
{
cairo_t *cr;
GtkStyle *style;
@@ -987,7 +1064,7 @@ draw_window_decoration (decor_t *d)
int top;
int button_x;
- if (!d->pixmap)
+ if (!pixmap)
return;
style = gtk_widget_get_style (style_window);
@@ -1003,7 +1080,7 @@ draw_window_decoration (decor_t *d)
if (d->buffer_pixmap)
cr = gdk_cairo_create (GDK_DRAWABLE (d->buffer_pixmap));
else
- cr = gdk_cairo_create (GDK_DRAWABLE (d->pixmap));
+ cr = gdk_cairo_create (GDK_DRAWABLE (pixmap));
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
@@ -1020,7 +1097,7 @@ draw_window_decoration (decor_t *d)
draw_shadow_background (d, cr, d->shadow, d->context);
- if (d->active)
+ if (active)
{
decor_color_t *title_color = _title_color;
@@ -1145,7 +1222,7 @@ draw_window_decoration (decor_t *d)
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
- if (d->active)
+ if (active)
{
gdk_cairo_set_source_color_alpha (cr,
&style->fg[GTK_STATE_NORMAL],
@@ -1219,7 +1296,7 @@ draw_window_decoration (decor_t *d)
button_x -= 17;
- if (d->active)
+ if (active)
{
cairo_move_to (cr, x, y);
draw_close_button (d, cr, 3.0);
@@ -1247,7 +1324,7 @@ draw_window_decoration (decor_t *d)
cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
- if (d->active)
+ if (active)
{
gdk_cairo_set_source_color_alpha (cr,
&style->fg[GTK_STATE_NORMAL],
@@ -1288,7 +1365,7 @@ draw_window_decoration (decor_t *d)
button_x -= 17;
- if (d->active)
+ if (active)
{
gdk_cairo_set_source_color_alpha (cr,
&style->fg[GTK_STATE_NORMAL],
@@ -1311,7 +1388,7 @@ draw_window_decoration (decor_t *d)
if (d->layout)
{
- if (d->active)
+ if (active)
{
cairo_move_to (cr,
d->context->left_space + 21.0,
@@ -1348,7 +1425,7 @@ draw_window_decoration (decor_t *d)
cairo_rectangle (cr, 0.0, 0.0, 16.0, 16.0);
cairo_clip (cr);
- if (d->active)
+ if (active)
cairo_paint (cr);
else
cairo_paint_with_alpha (cr, alpha);
@@ -1357,7 +1434,7 @@ draw_window_decoration (decor_t *d)
cairo_destroy (cr);
if (d->buffer_pixmap)
- gdk_draw_drawable (d->pixmap,
+ gdk_draw_drawable (pixmap,
d->gc,
d->buffer_pixmap,
0,
@@ -1366,6 +1443,20 @@ draw_window_decoration (decor_t *d)
0,
d->width,
d->height);
+}
+
+static void
+draw_window_decoration (decor_t *d)
+{
+ if (d->active_pixmap)
+ {
+ draw_window_decoration_to_pixmap (d, d->pixmap, FALSE);
+ draw_window_decoration_to_pixmap (d, d->active_pixmap, TRUE);
+ }
+ else
+ {
+ draw_window_decoration_to_pixmap (d, d->pixmap, d->active);
+ }
if (d->prop_xid)
{
@@ -1430,6 +1521,24 @@ decor_update_meta_window_property (decor_t *d,
extents.top += titlebar_height;
max_extents.top += max_titlebar_height;
+ if (d->active_pixmap)
+ {
+ decor_quads_to_property (data, GDK_PIXMAP_XID (d->active_pixmap),
+ &extents, &max_extents,
+ ICON_SPACE + d->button_width,
+ 0,
+ quads, nQuad);
+
+ gdk_error_trap_push ();
+ XChangeProperty (xdisplay, d->prop_xid,
+ win_decor_active_atom,
+ win_decor_atom,
+ 32, PropModeReplace, (guchar *) data,
+ BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
+ gdk_display_sync (gdk_display_get_default ());
+ gdk_error_trap_pop ();
+ }
+
decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap),
&extents, &max_extents,
ICON_SPACE + d->button_width,
@@ -1439,7 +1548,7 @@ decor_update_meta_window_property (decor_t *d,
gdk_error_trap_push ();
XChangeProperty (xdisplay, d->prop_xid,
win_decor_atom,
- XA_INTEGER,
+ win_decor_atom,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
gdk_display_sync (gdk_display_get_default ());
@@ -1823,9 +1932,6 @@ meta_get_decoration_geometry (decor_t *d,
if (d->actions & WNCK_WINDOW_ACTION_SHADE)
*flags |= META_FRAME_ALLOWS_SHADE;
- if (d->active)
- *flags |= META_FRAME_HAS_FOCUS;
-
#define META_MAXIMIZED (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY | \
WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
@@ -1880,17 +1986,25 @@ meta_get_decoration_geometry (decor_t *d,
}
static void
-meta_draw_window_decoration (decor_t *d)
+meta_draw_window_decoration_to_pixmap (decor_t *d,
+ GdkPixmap *pixmap,
+ MetaTheme *theme,
+ gint active,
+ gint bg,
+ Region *top_region_return,
+ Region *bottom_region_return,
+ Region *left_region_return,
+ Region *right_region_return,
+ MetaFrameFlags *flags_return)
{
Display *xdisplay =
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
- GdkPixmap *pixmap;
+ GdkPixmap *pix;
Picture src;
MetaButtonState button_states[META_BUTTON_TYPE_LAST];
MetaButtonLayout button_layout;
MetaFrameGeometry fgeom;
MetaFrameFlags flags;
- MetaTheme *theme;
GtkStyle *style;
cairo_t *cr;
gint size, i;
@@ -1900,14 +2014,14 @@ meta_draw_window_decoration (decor_t *d)
Region bottom_region = NULL;
Region left_region = NULL;
Region right_region = NULL;
- double alpha = (d->active) ? meta_active_opacity : meta_opacity;
- gboolean shade_alpha = (d->active) ? meta_active_shade_opacity :
+ double alpha = (active) ? meta_active_opacity : meta_opacity;
+ gboolean shade_alpha = (active) ? meta_active_shade_opacity :
meta_shade_opacity;
MetaFrameStyle *frame_style;
GdkColor bg_color;
double bg_alpha;
- if (!d->pixmap || !d->picture)
+ if (!pixmap || !d->picture)
return;
if (decoration_alpha == 1.0)
@@ -1915,20 +2029,19 @@ meta_draw_window_decoration (decor_t *d)
style = gtk_widget_get_style (style_window);
- drawable = d->buffer_pixmap ? d->buffer_pixmap : d->pixmap;
+ drawable = d->buffer_pixmap ? d->buffer_pixmap : pixmap;
cr = gdk_cairo_create (GDK_DRAWABLE (drawable));
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- theme = meta_theme_get_current ();
-
meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
&clip);
- /* we only have to redraw the shadow background when decoration
- changed size */
- if (d->prop_xid || !d->buffer_pixmap)
+ if (active)
+ flags |= META_FRAME_HAS_FOCUS;
+
+ if (bg)
draw_shadow_background (d, cr, d->shadow, d->context);
for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
@@ -1962,14 +2075,14 @@ meta_draw_window_decoration (decor_t *d)
if (rect.width && size)
{
- pixmap = create_pixmap (rect.width, size);
+ pix = create_pixmap (rect.width, size);
- cr = gdk_cairo_create (GDK_DRAWABLE (pixmap));
+ cr = gdk_cairo_create (GDK_DRAWABLE (pix));
gdk_cairo_set_source_color_alpha (cr, &bg_color, bg_alpha);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
src = XRenderCreatePicture (xdisplay,
- GDK_PIXMAP_XID (pixmap),
+ GDK_PIXMAP_XID (pix),
xformat, 0, NULL);
if (fgeom.top_height)
@@ -1980,7 +2093,7 @@ meta_draw_window_decoration (decor_t *d)
meta_theme_draw_frame (theme,
style_window,
- pixmap,
+ pix,
&rect,
0, 0,
META_FRAME_TYPE_NORMAL,
@@ -2019,7 +2132,7 @@ meta_draw_window_decoration (decor_t *d)
meta_theme_draw_frame (theme,
style_window,
- pixmap,
+ pix,
&rect,
0,
-(clip.height - fgeom.bottom_height),
@@ -2053,7 +2166,7 @@ meta_draw_window_decoration (decor_t *d)
cairo_destroy (cr);
- g_object_unref (G_OBJECT (pixmap));
+ g_object_unref (G_OBJECT (pix));
XRenderFreePicture (xdisplay, src);
}
@@ -2064,14 +2177,14 @@ meta_draw_window_decoration (decor_t *d)
if (size && rect.height)
{
- pixmap = create_pixmap (size, rect.height);
+ pix = create_pixmap (size, rect.height);
- cr = gdk_cairo_create (GDK_DRAWABLE (pixmap));
+ cr = gdk_cairo_create (GDK_DRAWABLE (pix));
gdk_cairo_set_source_color_alpha (cr, &bg_color, bg_alpha);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
src = XRenderCreatePicture (xdisplay,
- GDK_PIXMAP_XID (pixmap),
+ GDK_PIXMAP_XID (pix),
xformat, 0, NULL);
if (fgeom.left_width)
@@ -2082,7 +2195,7 @@ meta_draw_window_decoration (decor_t *d)
meta_theme_draw_frame (theme,
style_window,
- pixmap,
+ pix,
&rect,
0,
-fgeom.top_height,
@@ -2122,7 +2235,7 @@ meta_draw_window_decoration (decor_t *d)
meta_theme_draw_frame (theme,
style_window,
- pixmap,
+ pix,
&rect,
-(clip.width - fgeom.right_width),
-fgeom.top_height,
@@ -2156,13 +2269,13 @@ meta_draw_window_decoration (decor_t *d)
cairo_destroy (cr);
- g_object_unref (G_OBJECT (pixmap));
+ g_object_unref (G_OBJECT (pix));
XRenderFreePicture (xdisplay, src);
}
if (d->buffer_pixmap)
- gdk_draw_drawable (d->pixmap,
+ gdk_draw_drawable (pixmap,
d->gc,
d->buffer_pixmap,
0,
@@ -2172,16 +2285,119 @@ meta_draw_window_decoration (decor_t *d)
d->width,
d->height);
- if (d->prop_xid)
+ /* translate from frame to client window space */
+ if (top_region_return)
{
- /* translate from frame to client window space */
if (top_region)
XOffsetRegion (top_region, -fgeom.left_width, -fgeom.top_height);
+
+ *top_region_return = top_region;
+ }
+ else if (top_region)
+ {
+ XDestroyRegion (top_region);
+ }
+
+ if (bottom_region_return)
+ {
if (bottom_region)
XOffsetRegion (bottom_region, -fgeom.left_width, 0);
+
+ *bottom_region_return = bottom_region;
+ }
+ else if (bottom_region)
+ {
+ XDestroyRegion (bottom_region);
+ }
+
+ if (left_region_return)
+ {
if (left_region)
XOffsetRegion (left_region, -fgeom.left_width, 0);
+ *left_region_return = left_region;
+ }
+ else if (left_region)
+ {
+ XDestroyRegion (left_region);
+ }
+
+ if (right_region_return)
+ {
+ *right_region_return = right_region;
+ }
+ else if (right_region)
+ {
+ XDestroyRegion (right_region);
+ }
+
+ *flags_return = flags;
+}
+
+static void
+meta_draw_window_decoration (decor_t *d)
+{
+ MetaTheme *theme = meta_theme_get_current ();
+ MetaFrameFlags flags;
+ Region top_region = NULL;
+ Region bottom_region = NULL;
+ Region left_region = NULL;
+ Region right_region = NULL;
+ Region *top_region_ptr = NULL;
+ Region *bottom_region_ptr = NULL;
+ Region *left_region_ptr = NULL;
+ Region *right_region_ptr = NULL;
+ gint bg = FALSE;
+
+ if (d->prop_xid)
+ {
+ bg = TRUE;
+
+ top_region_ptr = &top_region;
+ bottom_region_ptr = &bottom_region;
+ left_region_ptr = &left_region;
+ right_region_ptr = &right_region;
+ }
+ else if (!d->buffer_pixmap)
+ {
+ bg = TRUE;
+ }
+
+ if (d->active_pixmap)
+ {
+ meta_draw_window_decoration_to_pixmap (d,
+ d->pixmap,
+ theme,
+ FALSE,
+ bg,
+ NULL, NULL, NULL, NULL, &flags);
+ meta_draw_window_decoration_to_pixmap (d,
+ d->active_pixmap,
+ theme,
+ TRUE,
+ FALSE,
+ top_region_ptr,
+ bottom_region_ptr,
+ left_region_ptr,
+ right_region_ptr,
+ &flags);
+ }
+ else
+ {
+ meta_draw_window_decoration_to_pixmap (d,
+ d->pixmap,
+ theme,
+ d->active,
+ bg,
+ top_region_ptr,
+ bottom_region_ptr,
+ left_region_ptr,
+ right_region_ptr,
+ &flags);
+ }
+
+ if (d->prop_xid)
+ {
decor_update_meta_window_property (d, theme, flags,
top_region,
bottom_region,
@@ -2564,7 +2780,7 @@ update_default_decorations (GdkScreen *screen)
XChangeProperty (xdisplay, xroot,
bareAtom,
- XA_INTEGER,
+ win_decor_atom,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
@@ -2572,12 +2788,12 @@ update_default_decorations (GdkScreen *screen)
{
XChangeProperty (xdisplay, xroot,
normalAtom,
- XA_INTEGER,
+ win_decor_atom,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
XChangeProperty (xdisplay, xroot,
activeAtom,
- XA_INTEGER,
+ win_decor_atom,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
}
@@ -2635,7 +2851,7 @@ update_default_decorations (GdkScreen *screen)
XChangeProperty (xdisplay, xroot,
normalAtom,
- XA_INTEGER,
+ win_decor_atom,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
}
@@ -2661,7 +2877,7 @@ update_default_decorations (GdkScreen *screen)
XChangeProperty (xdisplay, xroot,
activeAtom,
- XA_INTEGER,
+ win_decor_atom,
32, PropModeReplace, (guchar *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
}
@@ -3081,13 +3297,21 @@ update_event_windows (WnckWindow *win)
{
Display *xdisplay;
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
- gint x0, y0, width, height, x, y, w, h;
+ Region move_xregion;
+ REGION xregion;
+ gint x0, y0, x1, y1, width, height, x, y, w, h;
gint i, j, k, l;
gint actions = d->actions;
xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
- wnck_window_get_client_window_geometry (win, &x0, &y0, &width, &height);
+ wnck_window_get_geometry (win, &x0, &y0, &width, &height);
+ wnck_window_get_client_window_geometry (win, &x1, &y1, &width, &height);
+
+ move_xregion = XCreateRegion ();
+
+ xregion.rects = &xregion.extents;
+ xregion.numRects = xregion.size = 1;
if (d->state & WNCK_WINDOW_STATE_SHADED)
{
@@ -3134,6 +3358,16 @@ update_event_windows (WnckWindow *win)
XMapWindow (xdisplay, d->event_windows[i][j]);
XMoveResizeWindow (xdisplay, d->event_windows[i][j],
x, y, w, h);
+
+ xregion.extents.x1 = x;
+ xregion.extents.y1 = y;
+ xregion.extents.x2 = x + w;
+ xregion.extents.y2 = y + h;
+
+ if (i == 1 && j == 1)
+ XUnionRegion (move_xregion, &xregion, move_xregion);
+ else
+ XSubtractRegion (move_xregion, &xregion, move_xregion);
}
else
{
@@ -3181,6 +3415,13 @@ update_event_windows (WnckWindow *win)
{
XMapWindow (xdisplay, d->button_windows[i]);
XMoveResizeWindow (xdisplay, d->button_windows[i], x, y, w, h);
+
+ xregion.extents.x1 = x;
+ xregion.extents.y1 = y;
+ xregion.extents.x2 = x + w;
+ xregion.extents.y2 = y + h;
+
+ XSubtractRegion (move_xregion, &xregion, move_xregion);
}
else
{
@@ -3188,6 +3429,28 @@ update_event_windows (WnckWindow *win)
}
}
+ XOffsetRegion (move_xregion, x0 - x1, y0 - y1);
+
+ xregion.extents.x1 = 0;
+ xregion.extents.y1 = 0;
+ xregion.extents.x2 = width;
+ xregion.extents.y2 = height;
+
+ XSubtractRegion (move_xregion, &xregion, move_xregion);
+
+ decor_update_box_property (d,
+ wnck_window_get_xid (win),
+ wm_action_atom[1][1],
+ 0,
+ 1,
+ width, height,
+ move_xregion, width / 2,
+ NULL, 0,
+ NULL, 0,
+ NULL, 0);
+
+ XDestroyRegion (move_xregion);
+
gdk_display_sync (gdk_display_get_default ());
gdk_error_trap_pop ();
}
@@ -3488,7 +3751,7 @@ static gboolean
update_window_decoration_size (WnckWindow *win)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
- GdkPixmap *pixmap, *buffer_pixmap = NULL;
+ GdkPixmap *pixmap, *active_pixmap = NULL, *buffer_pixmap = NULL;
Picture picture;
gint width, height;
gint w, h, name_width;
@@ -3510,10 +3773,21 @@ update_window_decoration_size (WnckWindow *win)
if (!pixmap)
return FALSE;
+ if (!reduced_resources)
+ {
+ active_pixmap = create_pixmap (width, height);
+ if (!active_pixmap)
+ {
+ g_object_unref (G_OBJECT (pixmap));
+ return FALSE;
+ }
+ }
+
buffer_pixmap = create_pixmap (width, height);
if (!buffer_pixmap)
{
g_object_unref (G_OBJECT (pixmap));
+ g_object_unref (G_OBJECT (active_pixmap));
return FALSE;
}
@@ -3523,6 +3797,9 @@ update_window_decoration_size (WnckWindow *win)
if (d->pixmap)
g_object_unref (G_OBJECT (d->pixmap));
+ if (d->active_pixmap)
+ g_object_unref (G_OBJECT (d->active_pixmap));
+
if (d->buffer_pixmap)
g_object_unref (G_OBJECT (d->buffer_pixmap));
@@ -3532,7 +3809,8 @@ update_window_decoration_size (WnckWindow *win)
if (d->picture)
XRenderFreePicture (xdisplay, d->picture);
- d->pixmap = pixmap;
+ d->pixmap = pixmap;
+ d->active_pixmap = active_pixmap;
d->buffer_pixmap = buffer_pixmap;
d->gc = gdk_gc_new (pixmap);
@@ -3792,6 +4070,7 @@ update_switcher_window (WnckWindow *win,
g_object_ref (G_OBJECT (buffer_pixmap));
d->pixmap = pixmap;
+ d->active_pixmap = NULL;
d->buffer_pixmap = buffer_pixmap;
d->gc = gdk_gc_new (pixmap);
@@ -3822,6 +4101,12 @@ remove_frame_window (WnckWindow *win)
d->pixmap = NULL;
}
+ if (d->active_pixmap)
+ {
+ g_object_unref (G_OBJECT (d->active_pixmap));
+ d->active_pixmap = NULL;
+ }
+
if (d->buffer_pixmap)
{
g_object_unref (G_OBJECT (d->buffer_pixmap));
@@ -3999,10 +4284,11 @@ active_window_changed (WnckScreen *screen)
if (win)
{
d = g_object_get_data (G_OBJECT (win), "decor");
- if (d && d->pixmap)
+ if (d)
{
d->active = wnck_window_is_active (win);
- queue_decor_draw (d);
+ if (d->pixmap && !d->active_pixmap)
+ queue_decor_draw (d);
}
}
@@ -4010,10 +4296,11 @@ active_window_changed (WnckScreen *screen)
if (win)
{
d = g_object_get_data (G_OBJECT (win), "decor");
- if (d && d->pixmap)
+ if (d)
{
d->active = wnck_window_is_active (win);
- queue_decor_draw (d);
+ if (d->pixmap && !d->active_pixmap)
+ queue_decor_draw (d);
}
}
}
@@ -4746,7 +5033,8 @@ unstick_button_event (WnckWindow *win,
static void
handle_title_button_event (WnckWindow *win,
int action,
- XButtonEvent *event)
+ int button,
+ Time time)
{
switch (action) {
case CLICK_ACTION_SHADE:
@@ -4772,7 +5060,7 @@ handle_title_button_event (WnckWindow *win,
restack_window (win, Below);
break;
case CLICK_ACTION_MENU:
- action_menu_map (win, event->button, event->time);
+ action_menu_map (win, button, time);
break;
}
}
@@ -4812,16 +5100,16 @@ dist (double x1, double y1,
return sqrt (square (x1 - x2) + square (y1 - y2));
}
+static int last_button_num = 0;
+static Window last_button_xwindow = None;
+static Time last_button_time = 0;
+static int last_button_x = 0;
+static int last_button_y = 0;
+
static void
title_event (WnckWindow *win,
XEvent *xevent)
{
- static int last_button_num = 0;
- static Window last_button_xwindow = None;
- static Time last_button_time = 0;
- static int last_button_x = 0;
- static int last_button_y = 0;
-
if (xevent->type != ButtonPress)
return;
@@ -4834,7 +5122,8 @@ title_event (WnckWindow *win,
last_button_x, last_button_y) < DOUBLE_CLICK_DISTANCE)
{
handle_title_button_event (win, double_click_action,
- &xevent->xbutton);
+ xevent->xbutton.button,
+ xevent->xbutton.time);
last_button_num = 0;
last_button_xwindow = None;
@@ -4858,12 +5147,14 @@ title_event (WnckWindow *win,
else if (xevent->xbutton.button == 2)
{
handle_title_button_event (win, middle_click_action,
- &xevent->xbutton);
+ xevent->xbutton.button,
+ xevent->xbutton.time);
}
else if (xevent->xbutton.button == 3)
{
handle_title_button_event (win, right_click_action,
- &xevent->xbutton);
+ xevent->xbutton.button,
+ xevent->xbutton.time);
}
else if (xevent->xbutton.button == 4 ||
xevent->xbutton.button == 5)
@@ -4887,11 +5178,13 @@ frame_common_event (WnckWindow *win,
break;
case 2:
handle_title_button_event (win, middle_click_action,
- &xevent->xbutton);
+ xevent->xbutton.button,
+ xevent->xbutton.time);
break;
case 3:
handle_title_button_event (win, right_click_action,
- &xevent->xbutton);
+ xevent->xbutton.button,
+ xevent->xbutton.time);
break;
}
}
@@ -5301,6 +5594,48 @@ event_filter_func (GdkXEvent *gdkxevent,
}
}
}
+ else if (xevent->xclient.message_type == wm_action_notify_atom[1][1])
+ {
+ WnckWindow *win;
+ gulong id = (gulong)
+ g_hash_table_lookup (frame_table,
+ GINT_TO_POINTER (xevent->xclient.window));
+
+ win = wnck_window_get (id);
+ if (win)
+ {
+ if (xevent->xclient.window == last_button_xwindow &&
+ xevent->xclient.data.l[0] == last_button_num &&
+ xevent->xclient.data.l[3] <
+ last_button_time + double_click_timeout &&
+ dist (xevent->xclient.data.l[1],
+ xevent->xclient.data.l[2],
+ last_button_x,
+ last_button_y) < DOUBLE_CLICK_DISTANCE)
+ {
+ handle_title_button_event (win,
+ double_click_action,
+ xevent->xclient.data.l[0],
+ xevent->xclient.data.l[3]);
+
+ last_button_num = 0;
+ last_button_xwindow = None;
+ last_button_time = 0;
+ last_button_x = 0;
+ last_button_y = 0;
+ }
+ else
+ {
+ last_button_num = xevent->xclient.data.l[0];
+ last_button_xwindow = xevent->xclient.window;
+ last_button_time = xevent->xclient.data.l[3];
+ last_button_x = xevent->xclient.data.l[1];
+ last_button_y = xevent->xclient.data.l[2];
+
+ restack_window (win, Above);
+ }
+ }
+ }
default:
break;
}
@@ -6909,6 +7244,10 @@ main (int argc, char *argv[])
{
replace = TRUE;
}
+ else if (strcmp (argv[i], "--reduced-resources") == 0)
+ {
+ reduced_resources = TRUE;
+ }
else if (strcmp (argv[i], "--blur") == 0)
{
if (argc > ++i)
@@ -6957,6 +7296,7 @@ main (int argc, char *argv[])
fprintf (stderr, "%s "
"[--minimal] "
"[--replace] "
+ "[--reduced-resources] "
"[--blur none|titlebar|all] "
#ifdef USE_METACITY
@@ -6999,8 +7339,12 @@ main (int argc, char *argv[])
xdisplay = gdk_x11_display_get_xdisplay (gdkdisplay);
gdkscreen = gdk_display_get_default_screen (gdkdisplay);
+ win_decor_atom = XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME,
+ FALSE);
+ win_decor_active_atom = XInternAtom (xdisplay, DECOR_ACTIVE_ATOM_NAME,
+ FALSE);
+
frame_window_atom = XInternAtom (xdisplay, "_NET_FRAME_WINDOW", FALSE);
- win_decor_atom = XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME, FALSE);
win_blur_decor_atom = XInternAtom (xdisplay, DECOR_BLUR_ATOM_NAME, FALSE);
wm_move_resize_atom = XInternAtom (xdisplay, "_NET_WM_MOVERESIZE", FALSE);
restack_window_atom = XInternAtom (xdisplay, "_NET_RESTACK_WINDOW", FALSE);
@@ -7027,6 +7371,23 @@ main (int argc, char *argv[])
panel_action_run_dialog_atom =
XInternAtom (xdisplay, "_GNOME_PANEL_ACTION_RUN_DIALOG", FALSE);
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ wm_action_atom[i][j] = XInternAtom (xdisplay,
+ wm_action_name[i][j],
+ FALSE);
+
+ for (i = 0; i < 3; i++)
+ {
+ char name[256];
+
+ for (j = 0; j < 3; j++)
+ {
+ sprintf (name, "%s_NOTIFY", wm_action_name[i][j]);
+ wm_action_notify_atom[i][j] = XInternAtom (xdisplay, name, FALSE);
+ }
+ }
+
status = decor_acquire_dm_session (xdisplay,
gdk_screen_get_number (gdkscreen),
"gwd", replace, &dm_sn_timestamp);
diff --git a/include/compiz-core.h b/include/compiz-core.h
index 38257e6..e649d19 100644
--- a/include/compiz-core.h
+++ b/include/compiz-core.h
@@ -1,3 +1,4 @@
+
/*
* Copyright © 2007 Novell, Inc.
*
@@ -48,6 +49,9 @@
#include <GL/gl.h>
#include <GL/glx.h>
+#undef CORE_ABIVERSION
+#define CORE_ABIVERSION 20081121
+
COMPIZ_BEGIN_DECLS
#if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR > 2
@@ -80,6 +84,8 @@ typedef struct _CompCursor CompCursor;
typedef struct _CompMatch CompMatch;
typedef struct _CompOutput CompOutput;
typedef struct _CompWalker CompWalker;
+typedef struct _CompPainter CompPainter;
+typedef struct _CompTransform CompTransform;
/* virtual modifiers */
@@ -219,6 +225,8 @@ extern Bool useCow;
extern Bool noDetection;
extern Bool useDesktopHints;
extern Bool onlyCurrentScreen;
+extern Bool windowManagement;
+extern Bool manualCompositeManagement;
extern int defaultRefreshRate;
extern char *defaultTextureFilter;
@@ -736,6 +744,664 @@ void
removeFileWatch (CompFileWatchHandle handle);
+/* window.c */
+
+typedef struct _CompMatrix {
+ float xx; float yx;
+ float xy; float yy;
+ float x0; float y0;
+} CompMatrix;
+
+typedef struct _CompGroup {
+ struct _CompGroup *next;
+ unsigned int refCnt;
+ Window id;
+} CompGroup;
+
+/* XXX: scale and translate fields will be removed */
+typedef struct _WindowPaintAttrib {
+ GLushort opacity;
+ GLushort brightness;
+ GLushort saturation;
+ GLfloat xScale;
+ GLfloat yScale;
+ GLfloat xTranslate;
+ GLfloat yTranslate;
+} WindowPaintAttrib;
+
+typedef void (*DrawWindowGeometryProc) (CompWindow *window);
+
+typedef Bool (*PaintWindowProc) (CompWindow *window,
+ const WindowPaintAttrib *attrib,
+ const CompTransform *transform,
+ Region region,
+ unsigned int mask);
+
+#define WINDOW_INVISIBLE(w) \
+ ((w)->attrib.map_state != IsViewable || \
+ (!(w)->damaged) || \
+ (w)->attrib.x + (w)->width + (w)->output.right <= 0 || \
+ (w)->attrib.y + (w)->height + (w)->output.bottom <= 0 || \
+ (w)->attrib.x - (w)->output.left >= (w)->screen->width || \
+ (w)->attrib.y - (w)->output.top >= (w)->screen->height)
+
+typedef enum {
+ CompStackingUpdateModeNone = 0,
+ CompStackingUpdateModeNormal,
+ CompStackingUpdateModeAboveFullscreen,
+ CompStackingUpdateModeInitialMap,
+ CompStackingUpdateModeInitialMapDeniedFocus
+} CompStackingUpdateMode;
+
+struct _CompWindowExtents {
+ int left;
+ int right;
+ int top;
+ int bottom;
+};
+
+typedef struct _CompStruts {
+ XRectangle left;
+ XRectangle right;
+ XRectangle top;
+ XRectangle bottom;
+} CompStruts;
+
+struct _CompWindow {
+ CompObject base;
+
+ CompScreen *screen;
+
+ CompWindow *parent;
+ CompWindow *next;
+ CompWindow *prev;
+
+ CompWindow *windows;
+ CompWindow *reverseWindows;
+
+ Bool substructureRedirect;
+ Bool redirectSubwindows;
+
+ int viewportOffsetX;
+ int viewportOffsetY;
+
+ int refcnt;
+ Window id;
+ Window frame;
+ unsigned int mapNum;
+ unsigned int activeNum;
+ XWindowAttributes attrib;
+ int serverX;
+ int serverY;
+ int serverWidth;
+ int serverHeight;
+ int serverBorderWidth;
+ Window transientFor;
+ Window clientLeader;
+ XSizeHints sizeHints;
+ Pixmap pixmap;
+ CompTexture *texture;
+ CompMatrix matrix;
+ Damage damage;
+ Bool inputHint;
+ Bool alpha;
+ GLint width;
+ GLint height;
+ Region region;
+ Region clip;
+ unsigned int wmType;
+ unsigned int type;
+ unsigned int state;
+ unsigned int actions;
+ unsigned int protocols;
+ unsigned int mwmDecor;
+ unsigned int mwmFunc;
+ Bool invisible;
+ Bool destroyed;
+ Bool damaged;
+ Bool redirected;
+ Bool managed;
+ Bool bindFailed;
+ Bool overlayWindow;
+ int destroyRefCnt;
+ int unmapRefCnt;
+
+ unsigned int initialViewportX;
+ unsigned int initialViewportY;
+
+ Time initialTimestamp;
+ Bool initialTimestampSet;
+
+ Bool placed;
+ Bool minimized;
+ Bool inShowDesktopMode;
+ Bool shaded;
+ Bool hidden;
+ Bool grabbed;
+
+ unsigned int desktop;
+
+ int pendingUnmaps;
+ int pendingMaps;
+
+ char *startupId;
+ char *resName;
+ char *resClass;
+
+ CompGroup *group;
+
+ unsigned int lastPong;
+ Bool alive;
+
+ WindowPaintAttrib paint;
+ WindowPaintAttrib lastPaint;
+
+ unsigned int lastMask;
+
+ CompWindowExtents input;
+ CompWindowExtents output;
+
+ CompStruts *struts;
+
+ CompIcon **icon;
+ int nIcon;
+
+ XRectangle iconGeometry;
+ Bool iconGeometrySet;
+
+ XWindowChanges saveWc;
+ int saveMask;
+
+ XSyncCounter syncCounter;
+ XSyncValue syncValue;
+ XSyncAlarm syncAlarm;
+ unsigned long syncAlarmConnection;
+ unsigned int syncWaitHandle;
+
+ Bool syncWait;
+ int syncX;
+ int syncY;
+ int syncWidth;
+ int syncHeight;
+ int syncBorderWidth;
+
+ Bool syncStateSupport;
+ Window supportingWmCheckWindow;
+ Window activeChild;
+ Window previousActiveChild;
+
+ Bool closeRequests;
+ Time lastCloseRequestTime;
+
+ XRectangle *damageRects;
+ int sizeDamage;
+ int nDamage;
+
+ int desktopWindowCount;
+
+ GLfloat *vertices;
+ int vertexSize;
+ int vertexStride;
+ GLushort *indices;
+ int indexSize;
+ int vCount;
+ int texUnits;
+ int texCoordSize;
+ int indexCount;
+
+ /* must be set by addWindowGeometry */
+ DrawWindowGeometryProc drawWindowGeometry;
+
+ PaintWindowProc paintWindowStack;
+};
+
+#define GET_CORE_WINDOW(object) ((CompWindow *) (object))
+#define CORE_WINDOW(object) CompWindow *w = GET_CORE_WINDOW (object)
+
+CompBool
+allocWindowObjectPrivates (CompObject *object,
+ CompObject *parent);
+
+int
+allocWindowObjectPrivateIndex (CompObject *parent);
+
+void
+freeWindowObjectPrivateIndex (CompObject *parent,
+ int index);
+
+CompBool
+forEachWindowObject (CompObject *parent,
+ ObjectCallBackProc proc,
+ void *closure);
+
+char *
+nameWindowObject (CompObject *object);
+
+CompObject *
+findWindowObject (CompObject *parent,
+ const char *name);
+
+int
+allocateWindowPrivateIndex (CompScreen *screen);
+
+void
+freeWindowPrivateIndex (CompScreen *screen,
+ int index);
+
+unsigned int
+windowStateMask (CompDisplay *display,
+ Atom state);
+
+unsigned int
+windowStateFromString (const char *str);
+
+unsigned int
+getWindowState (CompDisplay *display,
+ Window id);
+
+void
+setWindowState (CompDisplay *display,
+ unsigned int state,
+ Window id);
+
+void
+changeWindowState (CompWindow *w,
+ unsigned int newState);
+
+void
+recalcWindowActions (CompWindow *w);
+
+unsigned int
+constrainWindowState (unsigned int state,
+ unsigned int actions);
+
+unsigned int
+windowTypeFromString (const char *str);
+
+unsigned int
+getWindowType (CompDisplay *display,
+ Window id);
+
+void
+recalcWindowType (CompWindow *w);
+
+void
+getMwmHints (CompDisplay *display,
+ Window id,
+ unsigned int *func,
+ unsigned int *decor);
+
+unsigned int
+getProtocols (CompDisplay *display,
+ Window id);
+
+unsigned int
+getWindowProp (CompDisplay *display,
+ Window id,
+ Atom property,
+ unsigned int defaultValue);
+
+void
+setWindowProp (CompDisplay *display,
+ Window id,
+ Atom property,
+ unsigned int value);
+
+Bool
+readWindowProp32 (CompDisplay *display,
+ Window id,
+ Atom property,
+ unsigned short *returnValue);
+
+unsigned short
+getWindowProp32 (CompDisplay *display,
+ Window id,
+ Atom property,
+ unsigned short defaultValue);
+
+void
+setWindowProp32 (CompDisplay *display,
+ Window id,
+ Atom property,
+ unsigned short value);
+
+void
+updateNormalHints (CompWindow *window);
+
+void
+updateWmHints (CompWindow *w);
+
+void
+updateWindowClassHints (CompWindow *window);
+
+void
+updateTransientHint (CompWindow *w);
+
+void
+updateIconGeometry (CompWindow *w);
+
+Window
+getClientLeader (CompWindow *w);
+
+Window
+getFrameWindow (CompWindow *w);
+
+char *
+getStartupId (CompWindow *w);
+
+int
+getWmState (CompDisplay *display,
+ Window id);
+
+void
+setWmState (CompDisplay *display,
+ int state,
+ Window id);
+
+void
+setWindowFrameExtents (CompWindow *w,
+ CompWindowExtents *input);
+
+void
+updateWindowOutputExtents (CompWindow *w);
+
+void
+updateWindowRegion (CompWindow *w);
+
+Bool
+updateWindowStruts (CompWindow *w);
+
+void
+initRootWindow (CompScreen *s,
+ CompWindow *root);
+
+void
+addWindow (CompWindow *parent,
+ Window id,
+ Window aboveId);
+
+void
+removeWindow (CompWindow *w);
+
+void
+destroyWindow (CompWindow *w);
+
+void
+sendConfigureNotify (CompWindow *w);
+
+void
+mapWindow (CompWindow *w);
+
+void
+unmapWindow (CompWindow *w);
+
+Bool
+bindWindow (CompWindow *w);
+
+void
+releaseWindow (CompWindow *w);
+
+void
+moveWindow (CompWindow *w,
+ int dx,
+ int dy,
+ Bool damage,
+ Bool immediate);
+
+void
+configureXWindow (CompWindow *w,
+ unsigned int valueMask,
+ XWindowChanges *xwc);
+
+unsigned int
+adjustConfigureRequestForGravity (CompWindow *w,
+ XWindowChanges *xwc,
+ unsigned int xwcm,
+ int gravity,
+ int direction);
+
+void
+moveResizeWindow (CompWindow *w,
+ XWindowChanges *xwc,
+ unsigned int xwcm,
+ int gravity,
+ unsigned int source);
+
+void
+syncWindowPosition (CompWindow *w);
+
+void
+syncWait (CompWindow *w);
+
+void
+sendSyncRequest (CompWindow *w);
+
+Bool
+resizeWindow (CompWindow *w,
+ int x,
+ int y,
+ int width,
+ int height,
+ int borderWidth);
+
+void
+configureWindow (CompWindow *w,
+ XConfigureEvent *ce);
+
+void
+circulateWindow (CompWindow *w,
+ XCirculateEvent *ce);
+
+void
+addWindowDamageRect (CompWindow *w,
+ BoxPtr rect);
+
+void
+getOutputExtentsForWindow (CompWindow *w,
+ CompWindowExtents *output);
+
+void
+getAllowedActionsForWindow (CompWindow *w,
+ unsigned int *setActions,
+ unsigned int *clearActions);
+
+void
+addWindowDamage (CompWindow *w);
+
+void
+damageWindowOutputExtents (CompWindow *w);
+
+Bool
+damageWindowRect (CompWindow *w,
+ Bool initial,
+ BoxPtr rect);
+
+void
+damageTransformedWindowRect (CompWindow *w,
+ float xScale,
+ float yScale,
+ float xTranslate,
+ float yTranslate,
+ BoxPtr rect);
+
+Bool
+focusWindow (CompWindow *w);
+
+Bool
+placeWindow (CompWindow *w,
+ int x,
+ int y,
+ int *newX,
+ int *newY);
+
+void
+validateWindowResizeRequest (CompWindow *w,
+ unsigned int *mask,
+ XWindowChanges *xwc,
+ unsigned int source);
+
+void
+windowResizeNotify (CompWindow *w,
+ int dx,
+ int dy,
+ int dwidth,
+ int dheight);
+
+void
+windowMoveNotify (CompWindow *w,
+ int dx,
+ int dy,
+ Bool immediate);
+
+void
+windowGrabNotify (CompWindow *w,
+ int x,
+ int y,
+ unsigned int state,
+ unsigned int mask);
+
+void
+windowUngrabNotify (CompWindow *w);
+
+void
+windowStateChangeNotify (CompWindow *w,
+ unsigned int lastState);
+
+void
+moveInputFocusToWindow (CompWindow *w);
+
+void
+updateWindowSize (CompWindow *w);
+
+void
+raiseWindow (CompWindow *w);
+
+void
+lowerWindow (CompWindow *w);
+
+void
+restackWindowAbove (CompWindow *w,
+ CompWindow *sibling);
+
+void
+restackWindowBelow (CompWindow *w,
+ CompWindow *sibling);
+
+void
+updateWindowAttributes (CompWindow *w,
+ CompStackingUpdateMode stackingMode);
+
+void
+activateWindow (CompWindow *w);
+
+void
+closeWindow (CompWindow *w,
+ Time serverTime);
+
+Bool
+constrainNewWindowSize (CompWindow *w,
+ int width,
+ int height,
+ int *newWidth,
+ int *newHeight);
+
+void
+hideWindow (CompWindow *w);
+
+void
+showWindow (CompWindow *w);
+
+void
+minimizeWindow (CompWindow *w);
+
+void
+unminimizeWindow (CompWindow *w);
+
+void
+maximizeWindow (CompWindow *w,
+ int state);
+
+Bool
+getWindowUserTime (CompWindow *w,
+ Time *time);
+
+void
+setWindowUserTime (CompWindow *w,
+ Time time);
+
+Bool
+allowWindowFocus (CompWindow *w,
+ unsigned int noFocusMask,
+ unsigned int viewportX,
+ unsigned int viewportY,
+ Time timestamp);
+
+void
+unredirectWindow (CompWindow *w);
+
+void
+redirectWindow (CompWindow *w);
+
+void
+defaultViewportForWindow (CompWindow *w,
+ int *vx,
+ int *vy);
+
+CompIcon *
+getWindowIcon (CompWindow *w,
+ int width,
+ int height);
+
+void
+freeWindowIcons (CompWindow *w);
+
+int
+outputDeviceForWindow (CompWindow *w);
+
+Bool
+onCurrentDesktop (CompWindow *w);
+
+void
+setDesktopForWindow (CompWindow *w,
+ unsigned int desktop);
+
+int
+compareWindowActiveness (CompWindow *w1,
+ CompWindow *w2);
+
+Bool
+windowOnAllViewports (CompWindow *w);
+
+void
+getWindowMovementForOffset (CompWindow *w,
+ int offX,
+ int offY,
+ int *retX,
+ int *retY);
+
+void
+enterSyncWaitState (CompWindow *w);
+
+void
+leaveSyncWaitState (CompWindow *w);
+
+void
+insertWindow (CompWindow *parent,
+ CompWindow *w,
+ Window aboveId);
+
+void
+unhookWindow (CompWindow *parent,
+ CompWindow *w);
+
+CompWindow *
+findSibling (CompWindow *w,
+ Window id);
+
+CompWindow *
+walkDepthFirst (CompWindow *w);
+
+
/* display.c */
#define COMP_DISPLAY_OPTION_ABI 0
@@ -1053,6 +1719,8 @@ struct _CompDisplay {
Atom startupIdAtom;
+ Atom syncStateAtom;
+
unsigned int lastPing;
CompTimeoutHandle pingHandle;
@@ -1163,6 +1831,12 @@ addDisplay (const char *name);
void
removeDisplay (CompDisplay *d);
+Bool
+manageDisplay (CompDisplay *d);
+
+void
+updatePlugins (CompDisplay *d);
+
Time
getCurrentTimeFromDisplay (CompDisplay *d);
@@ -1180,6 +1854,10 @@ findWindowAtDisplay (CompDisplay *display,
Window id);
CompWindow *
+findClientWindowAtDisplay (CompDisplay *d,
+ Window id);
+
+CompWindow *
findTopLevelWindowAtDisplay (CompDisplay *d,
Window id);
@@ -1190,6 +1868,9 @@ virtualToRealModMask (CompDisplay *d,
void
updateModifierMappings (CompDisplay *d);
+void
+handleTimeouts (struct timeval *tv);
+
unsigned int
keycodeToModifiers (CompDisplay *d,
int keycode);
@@ -1305,9 +1986,9 @@ clearTargetOutput (CompDisplay *display,
#define DEG2RAD (M_PI / 180.0f)
-typedef struct _CompTransform {
+struct _CompTransform {
float m[16];
-} CompTransform;
+};
typedef union _CompVector {
float v[4];
@@ -1330,26 +2011,9 @@ typedef struct _ScreenPaintAttrib {
GLfloat zCamera;
} ScreenPaintAttrib;
-/* XXX: scale and translate fields will be removed */
-typedef struct _WindowPaintAttrib {
- GLushort opacity;
- GLushort brightness;
- GLushort saturation;
- GLfloat xScale;
- GLfloat yScale;
- GLfloat xTranslate;
- GLfloat yTranslate;
-} WindowPaintAttrib;
-
extern ScreenPaintAttrib defaultScreenPaintAttrib;
extern WindowPaintAttrib defaultWindowPaintAttrib;
-typedef struct _CompMatrix {
- float xx; float yx;
- float xy; float yy;
- float x0; float y0;
-} CompMatrix;
-
#define COMP_TEX_COORD_X(m, vx) ((m)->xx * (vx) + (m)->x0)
#define COMP_TEX_COORD_Y(m, vy) ((m)->yy * (vy) + (m)->y0)
@@ -1407,7 +2071,7 @@ typedef void (*DisableOutputClippingProc) (CompScreen *screen);
typedef void (*WalkerFiniProc) (CompScreen *screen,
CompWalker *walker);
-typedef CompWindow *(*WalkInitProc) (CompScreen *screen);
+typedef CompWindow *(*WalkInitProc) (CompWindow *parent);
typedef CompWindow *(*WalkStepProc) (CompWindow *window);
struct _CompWalker {
@@ -1420,6 +2084,16 @@ struct _CompWalker {
WalkStepProc prev;
};
+typedef void (*PainterFiniProc) (CompScreen *screen,
+ CompPainter *painter);
+
+struct _CompPainter {
+ PainterFiniProc fini;
+ CompPrivate priv;
+
+ PaintWindowProc paintObject;
+};
+
/*
window paint flags
@@ -1450,6 +2124,12 @@ struct _CompWalker {
#define PAINT_WINDOW_WITH_OFFSET_MASK (1 << 2)
/*
+ this flag is present when occlusion detection has been
+ performed and the window clip region is properly set.
+*/
+#define PAINT_WINDOW_CLIP_MASK (1 << 3)
+
+/*
flag indicate that window is translucent.
*/
#define PAINT_WINDOW_TRANSLUCENT_MASK (1 << 16)
@@ -1470,12 +2150,11 @@ struct _CompWalker {
*/
#define PAINT_WINDOW_BLEND_MASK (1 << 19)
+/*
+ flag indicate that there might be transformed child windows.
+*/
+#define PAINT_WINDOW_WITH_TRANSFORMED_CHILD_MASK (1 << 20)
-typedef Bool (*PaintWindowProc) (CompWindow *window,
- const WindowPaintAttrib *attrib,
- const CompTransform *transform,
- Region region,
- unsigned int mask);
typedef Bool (*DrawWindowProc) (CompWindow *window,
const CompTransform *transform,
@@ -1494,8 +2173,6 @@ typedef void (*DrawWindowTextureProc) (CompWindow *w,
const FragmentAttrib *fragment,
unsigned int mask);
-typedef void (*DrawWindowGeometryProc) (CompWindow *window);
-
typedef void (*PaintCursorProc) (CompCursor *cursor,
const CompTransform *transform,
Region region,
@@ -1594,6 +2271,11 @@ paintWindow (CompWindow *w,
unsigned int mask);
void
+drawTransformedWindowWithChildren (CompWindow *w,
+ const WindowPaintAttrib *attrib,
+ const CompTransform *transform);
+
+void
paintCursor (CompCursor *cursor,
const CompTransform *transform,
Region region,
@@ -1901,8 +2583,12 @@ typedef void (*WindowStateChangeNotifyProc) (CompWindow *window,
typedef void (*OutputChangeNotifyProc) (CompScreen *screen);
typedef void (*InitWindowWalkerProc) (CompScreen *screen,
+ CompWindow *parent,
CompWalker *walker);
+typedef void (*InitObjectPainterProc) (CompScreen *screen,
+ CompPainter *painter);
+
#define COMP_SCREEN_DAMAGE_PENDING_MASK (1 << 0)
#define COMP_SCREEN_DAMAGE_REGION_MASK (1 << 1)
#define COMP_SCREEN_DAMAGE_ALL_MASK (1 << 2)
@@ -1925,12 +2611,6 @@ typedef struct _CompGrab {
const char *name;
} CompGrab;
-typedef struct _CompGroup {
- struct _CompGroup *next;
- unsigned int refCnt;
- Window id;
-} CompGroup;
-
typedef struct _CompStartupSequence {
struct _CompStartupSequence *next;
SnStartupSequence *sequence;
@@ -2019,8 +2699,8 @@ struct _CompScreen {
CompScreen *next;
CompDisplay *display;
- CompWindow *windows;
- CompWindow *reverseWindows;
+
+ CompWindow root;
char *windowPrivateIndices;
int windowPrivateLen;
@@ -2038,7 +2718,6 @@ struct _CompScreen {
REGION region;
Region damage;
unsigned long damageMask;
- Window root;
Window overlay;
Window output;
XWindowAttributes attrib;
@@ -2061,7 +2740,6 @@ struct _CompScreen {
CompTexture backgroundTexture;
Bool backgroundLoaded;
unsigned int pendingDestroys;
- int desktopWindowCount;
unsigned int mapNum;
unsigned int activeNum;
@@ -2071,9 +2749,6 @@ struct _CompScreen {
CompOutput fullscreenOutput;
Bool hasOverlappingOutputs;
- int windowOffsetX;
- int windowOffsetY;
-
XRectangle lastViewport;
CompActiveWindowHistory history[ACTIVE_WINDOW_HISTORY_NUM];
@@ -2220,7 +2895,8 @@ struct _CompScreen {
OutputChangeNotifyProc outputChangeNotify;
- InitWindowWalkerProc initWindowWalker;
+ InitWindowWalkerProc initWindowWalker;
+ InitObjectPainterProc initObjectPainter;
};
#define GET_CORE_SCREEN(object) ((CompScreen *) (object))
@@ -2283,6 +2959,12 @@ void
detectRefreshRateOfScreen (CompScreen *s);
void
+getSupportingWmCheck (CompWindow *w);
+
+void
+getDesktopHints (CompScreen *s);
+
+void
showOutputWindow (CompScreen *s);
void
@@ -2312,15 +2994,6 @@ void
damagePendingOnScreen (CompScreen *s);
void
-insertWindowIntoScreen (CompScreen *s,
- CompWindow *w,
- Window aboveId);
-
-void
-unhookWindowFromScreen (CompScreen *s,
- CompWindow *w);
-
-void
forEachWindowOnScreen (CompScreen *screen,
ForEachWindowProc proc,
void *closure);
@@ -2330,6 +3003,10 @@ findWindowAtScreen (CompScreen *s,
Window id);
CompWindow *
+findClientWindowAtScreen (CompScreen *s,
+ Window id);
+
+CompWindow *
findTopLevelWindowAtScreen (CompScreen *s,
Window id);
@@ -2436,7 +3113,7 @@ disableScreenEdge (CompScreen *s,
int edge);
Window
-getTopWindow (CompScreen *s);
+getTopWindow (CompWindow *parent);
void
makeScreenCurrent (CompScreen *s);
@@ -2523,579 +3200,6 @@ setWindowPaintOffset (CompScreen *s,
int y);
-/* window.c */
-
-#define WINDOW_INVISIBLE(w) \
- ((w)->attrib.map_state != IsViewable || \
- (!(w)->damaged) || \
- (w)->attrib.x + (w)->width + (w)->output.right <= 0 || \
- (w)->attrib.y + (w)->height + (w)->output.bottom <= 0 || \
- (w)->attrib.x - (w)->output.left >= (w)->screen->width || \
- (w)->attrib.y - (w)->output.top >= (w)->screen->height)
-
-typedef enum {
- CompStackingUpdateModeNone = 0,
- CompStackingUpdateModeNormal,
- CompStackingUpdateModeAboveFullscreen,
- CompStackingUpdateModeInitialMap,
- CompStackingUpdateModeInitialMapDeniedFocus
-} CompStackingUpdateMode;
-
-struct _CompWindowExtents {
- int left;
- int right;
- int top;
- int bottom;
-};
-
-typedef struct _CompStruts {
- XRectangle left;
- XRectangle right;
- XRectangle top;
- XRectangle bottom;
-} CompStruts;
-
-struct _CompWindow {
- CompObject base;
-
- CompScreen *screen;
- CompWindow *next;
- CompWindow *prev;
-
- int refcnt;
- Window id;
- Window frame;
- unsigned int mapNum;
- unsigned int activeNum;
- XWindowAttributes attrib;
- int serverX;
- int serverY;
- int serverWidth;
- int serverHeight;
- int serverBorderWidth;
- Window transientFor;
- Window clientLeader;
- XSizeHints sizeHints;
- Pixmap pixmap;
- CompTexture *texture;
- CompMatrix matrix;
- Damage damage;
- Bool inputHint;
- Bool alpha;
- GLint width;
- GLint height;
- Region region;
- Region clip;
- unsigned int wmType;
- unsigned int type;
- unsigned int state;
- unsigned int actions;
- unsigned int protocols;
- unsigned int mwmDecor;
- unsigned int mwmFunc;
- Bool invisible;
- Bool destroyed;
- Bool damaged;
- Bool redirected;
- Bool managed;
- Bool bindFailed;
- Bool overlayWindow;
- int destroyRefCnt;
- int unmapRefCnt;
-
- unsigned int initialViewportX;
- unsigned int initialViewportY;
-
- Time initialTimestamp;
- Bool initialTimestampSet;
-
- Bool placed;
- Bool minimized;
- Bool inShowDesktopMode;
- Bool shaded;
- Bool hidden;
- Bool grabbed;
-
- unsigned int desktop;
-
- int pendingUnmaps;
- int pendingMaps;
-
- char *startupId;
- char *resName;
- char *resClass;
-
- CompGroup *group;
-
- unsigned int lastPong;
- Bool alive;
-
- WindowPaintAttrib paint;
- WindowPaintAttrib lastPaint;
-
- unsigned int lastMask;
-
- CompWindowExtents input;
- CompWindowExtents output;
-
- CompStruts *struts;
-
- CompIcon **icon;
- int nIcon;
-
- XRectangle iconGeometry;
- Bool iconGeometrySet;
-
- XWindowChanges saveWc;
- int saveMask;
-
- XSyncCounter syncCounter;
- XSyncValue syncValue;
- XSyncAlarm syncAlarm;
- unsigned long syncAlarmConnection;
- unsigned int syncWaitHandle;
-
- Bool syncWait;
- int syncX;
- int syncY;
- int syncWidth;
- int syncHeight;
- int syncBorderWidth;
-
- Bool closeRequests;
- Time lastCloseRequestTime;
-
- XRectangle *damageRects;
- int sizeDamage;
- int nDamage;
-
- GLfloat *vertices;
- int vertexSize;
- int vertexStride;
- GLushort *indices;
- int indexSize;
- int vCount;
- int texUnits;
- int texCoordSize;
- int indexCount;
-
- /* must be set by addWindowGeometry */
- DrawWindowGeometryProc drawWindowGeometry;
-};
-
-#define GET_CORE_WINDOW(object) ((CompWindow *) (object))
-#define CORE_WINDOW(object) CompWindow *w = GET_CORE_WINDOW (object)
-
-CompBool
-allocWindowObjectPrivates (CompObject *object,
- CompObject *parent);
-
-int
-allocWindowObjectPrivateIndex (CompObject *parent);
-
-void
-freeWindowObjectPrivateIndex (CompObject *parent,
- int index);
-
-CompBool
-forEachWindowObject (CompObject *parent,
- ObjectCallBackProc proc,
- void *closure);
-
-char *
-nameWindowObject (CompObject *object);
-
-CompObject *
-findWindowObject (CompObject *parent,
- const char *name);
-
-int
-allocateWindowPrivateIndex (CompScreen *screen);
-
-void
-freeWindowPrivateIndex (CompScreen *screen,
- int index);
-
-unsigned int
-windowStateMask (CompDisplay *display,
- Atom state);
-
-unsigned int
-windowStateFromString (const char *str);
-
-unsigned int
-getWindowState (CompDisplay *display,
- Window id);
-
-void
-setWindowState (CompDisplay *display,
- unsigned int state,
- Window id);
-
-void
-changeWindowState (CompWindow *w,
- unsigned int newState);
-
-void
-recalcWindowActions (CompWindow *w);
-
-unsigned int
-constrainWindowState (unsigned int state,
- unsigned int actions);
-
-unsigned int
-windowTypeFromString (const char *str);
-
-unsigned int
-getWindowType (CompDisplay *display,
- Window id);
-
-void
-recalcWindowType (CompWindow *w);
-
-void
-getMwmHints (CompDisplay *display,
- Window id,
- unsigned int *func,
- unsigned int *decor);
-
-unsigned int
-getProtocols (CompDisplay *display,
- Window id);
-
-unsigned int
-getWindowProp (CompDisplay *display,
- Window id,
- Atom property,
- unsigned int defaultValue);
-
-void
-setWindowProp (CompDisplay *display,
- Window id,
- Atom property,
- unsigned int value);
-
-Bool
-readWindowProp32 (CompDisplay *display,
- Window id,
- Atom property,
- unsigned short *returnValue);
-
-unsigned short
-getWindowProp32 (CompDisplay *display,
- Window id,
- Atom property,
- unsigned short defaultValue);
-
-void
-setWindowProp32 (CompDisplay *display,
- Window id,
- Atom property,
- unsigned short value);
-
-void
-updateNormalHints (CompWindow *window);
-
-void
-updateWmHints (CompWindow *w);
-
-void
-updateWindowClassHints (CompWindow *window);
-
-void
-updateTransientHint (CompWindow *w);
-
-void
-updateIconGeometry (CompWindow *w);
-
-Window
-getClientLeader (CompWindow *w);
-
-char *
-getStartupId (CompWindow *w);
-
-int
-getWmState (CompDisplay *display,
- Window id);
-
-void
-setWmState (CompDisplay *display,
- int state,
- Window id);
-
-void
-setWindowFrameExtents (CompWindow *w,
- CompWindowExtents *input);
-
-void
-updateWindowOutputExtents (CompWindow *w);
-
-void
-updateWindowRegion (CompWindow *w);
-
-Bool
-updateWindowStruts (CompWindow *w);
-
-void
-addWindow (CompScreen *screen,
- Window id,
- Window aboveId);
-
-void
-removeWindow (CompWindow *w);
-
-void
-destroyWindow (CompWindow *w);
-
-void
-sendConfigureNotify (CompWindow *w);
-
-void
-mapWindow (CompWindow *w);
-
-void
-unmapWindow (CompWindow *w);
-
-Bool
-bindWindow (CompWindow *w);
-
-void
-releaseWindow (CompWindow *w);
-
-void
-moveWindow (CompWindow *w,
- int dx,
- int dy,
- Bool damage,
- Bool immediate);
-
-void
-configureXWindow (CompWindow *w,
- unsigned int valueMask,
- XWindowChanges *xwc);
-
-unsigned int
-adjustConfigureRequestForGravity (CompWindow *w,
- XWindowChanges *xwc,
- unsigned int xwcm,
- int gravity);
-
-void
-moveResizeWindow (CompWindow *w,
- XWindowChanges *xwc,
- unsigned int xwcm,
- int gravity,
- unsigned int source);
-
-void
-syncWindowPosition (CompWindow *w);
-
-void
-sendSyncRequest (CompWindow *w);
-
-Bool
-resizeWindow (CompWindow *w,
- int x,
- int y,
- int width,
- int height,
- int borderWidth);
-
-void
-configureWindow (CompWindow *w,
- XConfigureEvent *ce);
-
-void
-circulateWindow (CompWindow *w,
- XCirculateEvent *ce);
-
-void
-addWindowDamageRect (CompWindow *w,
- BoxPtr rect);
-
-void
-getOutputExtentsForWindow (CompWindow *w,
- CompWindowExtents *output);
-
-void
-getAllowedActionsForWindow (CompWindow *w,
- unsigned int *setActions,
- unsigned int *clearActions);
-
-void
-addWindowDamage (CompWindow *w);
-
-void
-damageWindowOutputExtents (CompWindow *w);
-
-Bool
-damageWindowRect (CompWindow *w,
- Bool initial,
- BoxPtr rect);
-
-void
-damageTransformedWindowRect (CompWindow *w,
- float xScale,
- float yScale,
- float xTranslate,
- float yTranslate,
- BoxPtr rect);
-
-Bool
-focusWindow (CompWindow *w);
-
-Bool
-placeWindow (CompWindow *w,
- int x,
- int y,
- int *newX,
- int *newY);
-
-void
-validateWindowResizeRequest (CompWindow *w,
- unsigned int *mask,
- XWindowChanges *xwc,
- unsigned int source);
-
-void
-windowResizeNotify (CompWindow *w,
- int dx,
- int dy,
- int dwidth,
- int dheight);
-
-void
-windowMoveNotify (CompWindow *w,
- int dx,
- int dy,
- Bool immediate);
-
-void
-windowGrabNotify (CompWindow *w,
- int x,
- int y,
- unsigned int state,
- unsigned int mask);
-
-void
-windowUngrabNotify (CompWindow *w);
-
-void
-windowStateChangeNotify (CompWindow *w,
- unsigned int lastState);
-
-void
-moveInputFocusToWindow (CompWindow *w);
-
-void
-updateWindowSize (CompWindow *w);
-
-void
-raiseWindow (CompWindow *w);
-
-void
-lowerWindow (CompWindow *w);
-
-void
-restackWindowAbove (CompWindow *w,
- CompWindow *sibling);
-
-void
-restackWindowBelow (CompWindow *w,
- CompWindow *sibling);
-
-void
-updateWindowAttributes (CompWindow *w,
- CompStackingUpdateMode stackingMode);
-
-void
-activateWindow (CompWindow *w);
-
-void
-closeWindow (CompWindow *w,
- Time serverTime);
-
-Bool
-constrainNewWindowSize (CompWindow *w,
- int width,
- int height,
- int *newWidth,
- int *newHeight);
-
-void
-hideWindow (CompWindow *w);
-
-void
-showWindow (CompWindow *w);
-
-void
-minimizeWindow (CompWindow *w);
-
-void
-unminimizeWindow (CompWindow *w);
-
-void
-maximizeWindow (CompWindow *w,
- int state);
-
-Bool
-getWindowUserTime (CompWindow *w,
- Time *time);
-
-void
-setWindowUserTime (CompWindow *w,
- Time time);
-
-Bool
-allowWindowFocus (CompWindow *w,
- unsigned int noFocusMask,
- unsigned int viewportX,
- unsigned int viewportY,
- Time timestamp);
-
-void
-unredirectWindow (CompWindow *w);
-
-void
-redirectWindow (CompWindow *w);
-
-void
-defaultViewportForWindow (CompWindow *w,
- int *vx,
- int *vy);
-
-CompIcon *
-getWindowIcon (CompWindow *w,
- int width,
- int height);
-
-void
-freeWindowIcons (CompWindow *w);
-
-int
-outputDeviceForWindow (CompWindow *w);
-
-Bool
-onCurrentDesktop (CompWindow *w);
-
-void
-setDesktopForWindow (CompWindow *w,
- unsigned int desktop);
-
-int
-compareWindowActiveness (CompWindow *w1,
- CompWindow *w2);
-
-Bool
-windowOnAllViewports (CompWindow *w);
-
-void
-getWindowMovementForOffset (CompWindow *w,
- int offX,
- int offY,
- int *retX,
- int *retY);
-
/* plugin.c */
#define HOME_PLUGINDIR ".compiz/plugins"
diff --git a/include/decoration.h b/include/decoration.h
index 5eed043..9bc6552 100644
--- a/include/decoration.h
+++ b/include/decoration.h
@@ -196,19 +196,32 @@ decor_property_to_quads (long *data,
decor_quad_t *quad);
void
+decor_region_to_box_property (long *data,
+ int width,
+ int height,
+ Region topRegion,
+ int topOffset,
+ Region bottomRegion,
+ int bottomOffset,
+ Region leftRegion,
+ int leftOffset,
+ Region rightRegion,
+ int rightOffset);
+
+void
decor_region_to_blur_property (long *data,
int threshold,
int filter,
int width,
int height,
- Region topRegion,
- int topOffset,
- Region bottomRegion,
- int bottomOffset,
- Region leftRegion,
- int leftOffset,
- Region rightRegion,
- int rightOffset);
+ Region top_region,
+ int top_offset,
+ Region bottom_region,
+ int bottom_offset,
+ Region left_region,
+ int left_offset,
+ Region right_region,
+ int right_offset);
void
decor_apply_gravity (int gravity,
diff --git a/kde/window-decorator-kde4/decorator.cpp b/kde/window-decorator-kde4/decorator.cpp
index 96b818d..6ca2a39 100644
--- a/kde/window-decorator-kde4/decorator.cpp
+++ b/kde/window-decorator-kde4/decorator.cpp
@@ -403,7 +403,7 @@ KWD::Decorator::updateShadow (void)
KWD::trapXError ();
XChangeProperty (QX11Info::display(), QX11Info::appRootWindow(),
Atoms::netWindowDecorBare,
- XA_INTEGER,
+ Atoms::netWindowDecor,
32, PropModeReplace, (unsigned char *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
KWD::popXError ();
diff --git a/kde/window-decorator-kde4/switcher.cpp b/kde/window-decorator-kde4/switcher.cpp
index 2978e69..860b8aa 100644
--- a/kde/window-decorator-kde4/switcher.cpp
+++ b/kde/window-decorator-kde4/switcher.cpp
@@ -261,15 +261,18 @@ KWD::Switcher::updateBlurProperty (int topOffset,
if (size)
{
- long data[size * 6 + 2];
-
- decor_region_to_blur_property (data, 4, 0,
- mGeometry.width (),
- mGeometry.height (),
- topRegion, topOffset,
- bottomRegion, bottomOffset,
- leftRegion, leftOffset,
- rightRegion, rightOffset);
+ long data[size * 6 + 2];
+
+ data[0] = 4;
+ data[1] = 0;
+
+ decor_region_to_box_property (data + 2,
+ mGeometry.width (),
+ mGeometry.height (),
+ topRegion, topOffset,
+ bottomRegion, bottomOffset,
+ leftRegion, leftOffset,
+ rightRegion, rightOffset);
KWD::trapXError ();
XChangeProperty (QX11Info::display (), mId, atom, XA_INTEGER,
diff --git a/kde/window-decorator-kde4/window.cpp b/kde/window-decorator-kde4/window.cpp
index d2d362b..1e7d8c5 100644
--- a/kde/window-decorator-kde4/window.cpp
+++ b/kde/window-decorator-kde4/window.cpp
@@ -1426,13 +1426,16 @@ KWD::Window::updateBlurProperty (int topOffset,
{
long data[size * 6 + 2];
- decor_region_to_blur_property (data, 4, 0,
- mGeometry.width (),
- mGeometry.height (),
- topRegion, topOffset,
- bottomRegion, bottomOffset,
- leftRegion, leftOffset,
- rightRegion, rightOffset);
+ data[0] = 4;
+ data[1] = 0;
+
+ decor_region_to_box_property (data + 2,
+ mGeometry.width (),
+ mGeometry.height (),
+ topRegion, topOffset,
+ bottomRegion, bottomOffset,
+ leftRegion, leftOffset,
+ rightRegion, rightOffset);
KWD::trapXError ();
XChangeProperty (QX11Info::display(), mClientId, atom,
@@ -1542,7 +1545,7 @@ KWD::Window::updateProperty (void)
KWD::trapXError ();
XChangeProperty (QX11Info::display(), mClientId, atom,
- XA_INTEGER,
+ Atoms::netWindowDecor,
32, PropModeReplace, (unsigned char *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
KWD::popXError ();
diff --git a/kde/window-decorator/decorator.cpp b/kde/window-decorator/decorator.cpp
index 2d5ada0..03819dc 100644
--- a/kde/window-decorator/decorator.cpp
+++ b/kde/window-decorator/decorator.cpp
@@ -530,7 +530,7 @@ KWD::Decorator::updateShadow (void)
KWD::trapXError ();
XChangeProperty (qt_xdisplay (), qt_xrootwin (),
Atoms::netWindowDecorBare,
- XA_INTEGER,
+ Atoms::netWindowDecor,
32, PropModeReplace, (unsigned char *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
KWD::popXError ();
diff --git a/kde/window-decorator/window.cpp b/kde/window-decorator/window.cpp
index 55580e6..9e73e1a 100644
--- a/kde/window-decorator/window.cpp
+++ b/kde/window-decorator/window.cpp
@@ -1323,13 +1323,16 @@ KWD::Window::updateBlurProperty (int topOffset,
{
long data[size * 6 + 2];
- decor_region_to_blur_property (data, 4, 0,
- mGeometry.width (),
- mGeometry.height (),
- topRegion, topOffset,
- bottomRegion, bottomOffset,
- leftRegion, leftOffset,
- rightRegion, rightOffset);
+ data[0] = 4;
+ data[1] = 0;
+
+ decor_region_to_box_property (data + 2,
+ mGeometry.width (),
+ mGeometry.height (),
+ topRegion, topOffset,
+ bottomRegion, bottomOffset,
+ leftRegion, leftOffset,
+ rightRegion, rightOffset);
KWD::trapXError ();
XChangeProperty (qt_xdisplay (), mClientId, atom,
@@ -1442,7 +1445,7 @@ KWD::Window::updateProperty (void)
KWD::trapXError ();
XChangeProperty (qt_xdisplay (), mClientId, atom,
- XA_INTEGER,
+ Atoms::netWindowDecor,
32, PropModeReplace, (unsigned char *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
KWD::popXError ();
diff --git a/libdecoration/decoration.c b/libdecoration/decoration.c
index 1f3407c..b261045 100644
--- a/libdecoration/decoration.c
+++ b/libdecoration/decoration.c
@@ -205,13 +205,13 @@ decor_property_to_quads (long *data,
}
static int
-add_blur_boxes (long *data,
- BoxPtr box,
- int n_box,
- int width,
- int height,
- int gravity,
- int offset)
+add_boxes (long *data,
+ BoxPtr box,
+ int n_box,
+ int width,
+ int height,
+ int gravity,
+ int offset)
{
int x1, y1, x2, y2;
int more_gravity;
@@ -289,6 +289,52 @@ add_blur_boxes (long *data,
}
void
+decor_region_to_box_property (long *data,
+ int width,
+ int height,
+ Region top_region,
+ int top_offset,
+ Region bottom_region,
+ int bottom_offset,
+ Region left_region,
+ int left_offset,
+ Region right_region,
+ int right_offset)
+{
+ if (top_region)
+ data += add_boxes (data,
+ top_region->rects,
+ top_region->numRects,
+ width, height,
+ GRAVITY_NORTH,
+ top_offset);
+
+ if (bottom_region)
+ data += add_boxes (data,
+ bottom_region->rects,
+ bottom_region->numRects,
+ width, height,
+ GRAVITY_SOUTH,
+ bottom_offset);
+
+ if (left_region)
+ data += add_boxes (data,
+ left_region->rects,
+ left_region->numRects,
+ width, height,
+ GRAVITY_WEST,
+ left_offset);
+
+ if (right_region)
+ data += add_boxes (data,
+ right_region->rects,
+ right_region->numRects,
+ width, height,
+ GRAVITY_EAST,
+ right_offset);
+}
+
+void
decor_region_to_blur_property (long *data,
int threshold,
int filter,
@@ -303,40 +349,14 @@ decor_region_to_blur_property (long *data,
Region right_region,
int right_offset)
{
- *data++ = threshold;
- *data++ = filter;
-
- if (top_region)
- data += add_blur_boxes (data,
- top_region->rects,
- top_region->numRects,
- width, height,
- GRAVITY_NORTH,
- top_offset);
-
- if (bottom_region)
- data += add_blur_boxes (data,
- bottom_region->rects,
- bottom_region->numRects,
- width, height,
- GRAVITY_SOUTH,
- bottom_offset);
-
- if (left_region)
- data += add_blur_boxes (data,
- left_region->rects,
- left_region->numRects,
- width, height,
- GRAVITY_WEST,
- left_offset);
-
- if (right_region)
- data += add_blur_boxes (data,
- right_region->rects,
- right_region->numRects,
- width, height,
- GRAVITY_EAST,
- right_offset);
+ data[0] = threshold;
+ data[1] = filter;
+
+ decor_region_to_box_property (data + 2, width, height,
+ top_region, top_offset,
+ bottom_region, bottom_offset,
+ left_region, left_offset,
+ right_region, right_offset);
}
void
diff --git a/metadata/Makefile.am b/metadata/Makefile.am
index 666d989..eeb208a 100644
--- a/metadata/Makefile.am
+++ b/metadata/Makefile.am
@@ -11,6 +11,7 @@ xml_in_files = \
fs.xml.in \
gconf.xml.in \
glib.xml.in \
+ glx.xml.in \
ini.xml.in \
inotify.xml.in \
kconfig.xml.in \
@@ -28,6 +29,7 @@ xml_in_files = \
switcher.xml.in \
video.xml.in \
water.xml.in \
+ wm.xml.in \
wobbly.xml.in \
zoom.xml.in
xml_files = $(xml_in_files:.xml.in=.xml)
diff --git a/metadata/annotate.xml.in b/metadata/annotate.xml.in
index 46a2b09..486b84a 100644
--- a/metadata/annotate.xml.in
+++ b/metadata/annotate.xml.in
@@ -2,6 +2,14 @@
<plugin name="annotate">
<_short>Annotate</_short>
<_long>Annotate plugin</_long>
+ <deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
+ <relation type="after">
+ <plugin>glx</plugin>
+ </relation>
+ </deps>
<display>
<option name="initiate_button" type="button">
<_short>Initiate</_short>
diff --git a/metadata/blur.xml.in b/metadata/blur.xml.in
index 21be0f0..1fd674f 100644
--- a/metadata/blur.xml.in
+++ b/metadata/blur.xml.in
@@ -4,6 +4,9 @@
<_long>Blur windows</_long>
<feature>blur</feature>
<deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
<relation type="before">
<plugin>video</plugin>
</relation>
diff --git a/metadata/clone.xml.in b/metadata/clone.xml.in
index d7c7ce4..7735f7c 100644
--- a/metadata/clone.xml.in
+++ b/metadata/clone.xml.in
@@ -2,6 +2,11 @@
<plugin name="clone">
<_short>Clone Output</_short>
<_long>Output clone handler</_long>
+ <deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
+ </deps>
<display>
<option name="initiate_button" type="button">
<_short>Initiate</_short>
diff --git a/metadata/cube.xml.in b/metadata/cube.xml.in
index f07da8b..ff9b114 100644
--- a/metadata/cube.xml.in
+++ b/metadata/cube.xml.in
@@ -4,6 +4,9 @@
<_long>Place windows on cube</_long>
<feature>largedesktop</feature>
<deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
<relation type="before">
<plugin>switcher</plugin>
<plugin>scale</plugin>
diff --git a/metadata/fade.xml.in b/metadata/fade.xml.in
index 7e1ddff..a327e1e 100644
--- a/metadata/fade.xml.in
+++ b/metadata/fade.xml.in
@@ -3,6 +3,9 @@
<_short>Fading Windows</_short>
<_long>Fade in windows when mapped and fade out windows when unmapped</_long>
<deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
<relation type="before">
<plugin>cube</plugin>
<plugin>scale</plugin>
diff --git a/metadata/glx.xml.in b/metadata/glx.xml.in
new file mode 100644
index 0000000..9f25dcd
--- /dev/null
+++ b/metadata/glx.xml.in
@@ -0,0 +1,9 @@
+<compiz>
+ <plugin name="glx">
+ <_short>GLX</_short>
+ <_long>GLX compositing output</_long>
+ <display>
+ <option name="abi" type="int" read_only="true"/>
+ </display>
+ </plugin>
+</compiz>
\ No newline at end of file
diff --git a/metadata/minimize.xml.in b/metadata/minimize.xml.in
index 4968549..f9e8077 100644
--- a/metadata/minimize.xml.in
+++ b/metadata/minimize.xml.in
@@ -4,6 +4,9 @@
<_long>Transform windows when they are minimized and unminimized</_long>
<feature>windowanimations</feature>
<deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
<relation type="before">
<plugin>cube</plugin>
<plugin>scale</plugin>
diff --git a/metadata/place.xml.in b/metadata/place.xml.in
index 19625ba..fd9b524 100644
--- a/metadata/place.xml.in
+++ b/metadata/place.xml.in
@@ -2,6 +2,11 @@
<plugin name="place">
<_short>Place Windows</_short>
<_long>Place windows at appropriate positions when mapped</_long>
+ <deps>
+ <requirement>
+ <plugin>wm</plugin>
+ </requirement>
+ </deps>
<screen>
<option name="workarounds" type="bool">
<_short>Workarounds</_short>
diff --git a/metadata/scale.xml.in b/metadata/scale.xml.in
index c551aa3..f85132c 100644
--- a/metadata/scale.xml.in
+++ b/metadata/scale.xml.in
@@ -2,6 +2,11 @@
<plugin name="scale">
<_short>Scale</_short>
<_long>Scale windows</_long>
+ <deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
+ </deps>
<display>
<option name="abi" type="int" read_only="true"/>
<option name="index" type="int" read_only="true"/>
diff --git a/metadata/screenshot.xml.in b/metadata/screenshot.xml.in
index d7b528e..8de85e7 100644
--- a/metadata/screenshot.xml.in
+++ b/metadata/screenshot.xml.in
@@ -2,6 +2,11 @@
<plugin name="screenshot">
<_short>Screenshot</_short>
<_long>Screenshot plugin</_long>
+ <deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
+ </deps>
<display>
<option name="initiate_button" type="button">
<_short>Initiate</_short>
diff --git a/metadata/svg.xml.in b/metadata/svg.xml.in
index 7eaa8b8..eaa0293 100644
--- a/metadata/svg.xml.in
+++ b/metadata/svg.xml.in
@@ -4,5 +4,10 @@
<_long>Svg image loader</_long>
<feature>imageext:svg</feature>
<feature>imagemime:image/svg+xml</feature>
+ <deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
+ </deps>
</plugin>
</compiz>
diff --git a/metadata/switcher.xml.in b/metadata/switcher.xml.in
index e829cc3..03c01e5 100644
--- a/metadata/switcher.xml.in
+++ b/metadata/switcher.xml.in
@@ -2,6 +2,11 @@
<plugin name="switcher">
<_short>Application Switcher</_short>
<_long>Application Switcher</_long>
+ <deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
+ </deps>
<display>
<option name="next_button" type="button">
<_short>Next window</_short>
diff --git a/metadata/video.xml.in b/metadata/video.xml.in
index 09c5076..1a7cedc 100644
--- a/metadata/video.xml.in
+++ b/metadata/video.xml.in
@@ -3,6 +3,11 @@
<_short>Video Playback</_short>
<_long>Video playback</_long>
<feature>video</feature>
+ <deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
+ </deps>
<display>
<option name="yv12" type="bool">
<_short>YV12 colorspace</_short>
diff --git a/metadata/water.xml.in b/metadata/water.xml.in
index 9d3b9d2..4ea35a1 100644
--- a/metadata/water.xml.in
+++ b/metadata/water.xml.in
@@ -3,6 +3,9 @@
<_short>Water Effect</_short>
<_long>Adds water effects to different desktop actions</_long>
<deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
<relation type="before">
<plugin>blur</plugin>
<plugin>video</plugin>
diff --git a/metadata/wm.xml.in b/metadata/wm.xml.in
new file mode 100644
index 0000000..5c5a023
--- /dev/null
+++ b/metadata/wm.xml.in
@@ -0,0 +1,9 @@
+<compiz>
+ <plugin name="wm">
+ <_short>Window Management</_short>
+ <_long>Window management</_long>
+ <display>
+ <option name="abi" type="int" read_only="true"/>
+ </display>
+ </plugin>
+</compiz>
diff --git a/metadata/wobbly.xml.in b/metadata/wobbly.xml.in
index 005ef3d..c2fb951 100644
--- a/metadata/wobbly.xml.in
+++ b/metadata/wobbly.xml.in
@@ -3,6 +3,9 @@
<_short>Wobbly Windows</_short>
<_long>Use spring model for wobbly window effect</_long>
<deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
<relation type="before">
<plugin>fade</plugin>
<plugin>cube</plugin>
diff --git a/metadata/zoom.xml.in b/metadata/zoom.xml.in
index 1a5bd5b..6903c5e 100644
--- a/metadata/zoom.xml.in
+++ b/metadata/zoom.xml.in
@@ -2,6 +2,11 @@
<plugin name="zoom">
<_short>Zoom Desktop</_short>
<_long>Zoom and pan desktop cube</_long>
+ <deps>
+ <requirement>
+ <plugin>glx</plugin>
+ </requirement>
+ </deps>
<display>
<option name="initiate_button" type="button">
<_short>Initiate</_short>
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 66e4ed7..7e1129d 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1,3 +1,9 @@
+libwm_la_LDFLAGS = -module -avoid-version -no-undefined
+libwm_la_SOURCES = wm.c
+
+libglx_la_LDFLAGS = -module -avoid-version -no-undefined
+libglx_la_SOURCES = glx.c
+
libfade_la_LDFLAGS = -module -avoid-version -no-undefined
libfade_la_SOURCES = fade.c
@@ -19,7 +25,9 @@ libwobbly_la_SOURCES = wobbly.c
libminimize_la_LDFLAGS = -module -avoid-version -no-undefined
libminimize_la_SOURCES = minimize.c
+libmove_la_DEPENDENCIES = $(top_builddir)/libdecoration/libdecoration.la
libmove_la_LDFLAGS = -module -avoid-version -no-undefined
+libmove_la_LIBADD = $(top_builddir)/libdecoration/libdecoration.la
libmove_la_SOURCES = move.c
libresize_la_LDFLAGS = -module -avoid-version -no-undefined
@@ -148,6 +156,8 @@ INCLUDES = \
moduledir = $(plugindir)
module_LTLIBRARIES = \
+ libwm.la \
+ libglx.la \
$(libglib_module) \
$(libgconf_module) \
$(libkconfig_module) \
diff --git a/plugins/annotate.c b/plugins/annotate.c
index 6271260..e671468 100644
--- a/plugins/annotate.c
+++ b/plugins/annotate.c
@@ -118,7 +118,7 @@ annoCairoContext (CompScreen *s)
format = XRenderFindStandardFormat (s->display->display,
PictStandardARGB32);
- as->pixmap = XCreatePixmap (s->display->display, s->root, w, h, 32);
+ as->pixmap = XCreatePixmap (s->display->display, s->root.id, w, h, 32);
if (!bindPixmapToTexture (s, &as->texture, as->pixmap, w, h, 32))
{
@@ -497,7 +497,7 @@ annoTerminate (CompDisplay *d,
{
ANNO_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (as->grabIndex)
@@ -758,7 +758,8 @@ annoInitDisplay (CompPlugin *p,
{
AnnoDisplay *ad;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
ad = malloc (sizeof (AnnoDisplay));
diff --git a/plugins/blur.c b/plugins/blur.c
index d7da5da..ecb3a6d 100644
--- a/plugins/blur.c
+++ b/plugins/blur.c
@@ -588,7 +588,7 @@ blurSetScreenOption (CompPlugin *plugin,
{
CompWindow *w;
- for (w = screen->windows; w; w = w->next)
+ for (w = screen->root.windows; w; w = w->next)
blurUpdateWindowMatch (bs, w);
bs->moreBlur = TRUE;
@@ -784,7 +784,7 @@ blurPreparePaintScreen (CompScreen *s,
bs->moreBlur = FALSE;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
BLUR_WINDOW (w);
@@ -843,7 +843,7 @@ blurPreparePaintScreen (CompScreen *s,
int x1, y1, x2, y2;
int count = 0;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
BLUR_WINDOW (w);
@@ -914,7 +914,7 @@ blurPaintOutput (CompScreen *s,
XSubtractRegion (&emptyRegion, &emptyRegion, bs->occlusion);
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
XSubtractRegion (&emptyRegion, &emptyRegion,
GET_BLUR_WINDOW (w, bs)->clip);
}
@@ -944,7 +944,7 @@ blurPaintTransformedOutput (CompScreen *s,
XSubtractRegion (&emptyRegion, &emptyRegion, bs->occlusion);
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
XSubtractRegion (&emptyRegion, &emptyRegion,
GET_BLUR_WINDOW (w, bs)->clip);
}
@@ -964,7 +964,7 @@ blurDonePaintScreen (CompScreen *s)
{
CompWindow *w;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
BLUR_WINDOW (w);
@@ -2715,7 +2715,7 @@ blurMatchExpHandlerChanged (CompDisplay *d)
{
BLUR_SCREEN (s);
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
blurUpdateWindowMatch (bs, w);
}
}
@@ -2735,10 +2735,10 @@ blurMatchPropertyChanged (CompDisplay *d,
}
static void
-blurWindowAdd (CompScreen *s,
+blurWindowAdd (CompObject *parent,
CompWindow *w)
{
- BLUR_SCREEN (s);
+ BLUR_SCREEN (w->screen);
blurWindowUpdate (w, BLUR_STATE_CLIENT);
blurWindowUpdate (w, BLUR_STATE_DECOR);
@@ -2772,7 +2772,8 @@ blurInitCore (CompPlugin *p,
{
BlurCore *bc;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
bc = malloc (sizeof (BlurCore));
@@ -3112,7 +3113,7 @@ blurInitWindow (CompPlugin *p,
w->base.privates[bs->windowPrivateIndex].ptr = bw;
if (w->base.parent)
- blurWindowAdd (w->screen, w);
+ blurWindowAdd (w->base.parent, w);
return TRUE;
}
diff --git a/plugins/clone.c b/plugins/clone.c
index 31b78a6..4854406 100644
--- a/plugins/clone.c
+++ b/plugins/clone.c
@@ -167,7 +167,7 @@ cloneFinish (CompScreen *s)
clone->input =
XCreateWindow (s->display->display,
- s->root, x, y,
+ s->root.id, x, y,
s->outputDev[cs->dst].width,
s->outputDev[cs->dst].height,
0, 0, InputOnly, CopyFromParent,
@@ -400,7 +400,7 @@ clonePaintOutput (CompScreen *s,
if (cs->offset == 0.0f)
s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (w->destroyed)
continue;
@@ -515,7 +515,7 @@ cloneTerminate (CompDisplay *d,
{
CLONE_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (cs->grabIndex)
@@ -723,7 +723,8 @@ cloneInitDisplay (CompPlugin *p,
{
CloneDisplay *cd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
cd = malloc (sizeof (CloneDisplay));
diff --git a/plugins/cube.c b/plugins/cube.c
index 91845f8..eaf76ed 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -1277,59 +1277,6 @@ cubePaintInside (CompScreen *s,
}
static void
-cubeEnableOutputClipping (CompScreen *s,
- const CompTransform *transform,
- Region region,
- CompOutput *output)
-{
- CUBE_SCREEN (s);
-
- if (cs->rotationState != RotationNone)
- {
- glPushMatrix ();
- glLoadMatrixf (transform->m);
- glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
- glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
-
- if (cs->invert == 1)
- {
- GLdouble clipPlane0[] = { 1.0, 0.0, 0.5 / cs->distance, 0.0 };
- GLdouble clipPlane1[] = { -1.0, 0.0, 0.5 / cs->distance, 0.0 };
- GLdouble clipPlane2[] = { 0.0, -1.0, 0.5 / cs->distance, 0.0 };
- GLdouble clipPlane3[] = { 0.0, 1.0, 0.5 / cs->distance, 0.0 };
- glClipPlane (GL_CLIP_PLANE0, clipPlane0);
- glClipPlane (GL_CLIP_PLANE1, clipPlane1);
- glClipPlane (GL_CLIP_PLANE2, clipPlane2);
- glClipPlane (GL_CLIP_PLANE3, clipPlane3);
- }
- else
- {
- GLdouble clipPlane0[] = { -1.0, 0.0, -0.5 / cs->distance, 0.0 };
- GLdouble clipPlane1[] = { 1.0, 0.0, -0.5 / cs->distance, 0.0 };
- GLdouble clipPlane2[] = { 0.0, 1.0, -0.5 / cs->distance, 0.0 };
- GLdouble clipPlane3[] = { 0.0, -1.0, -0.5 / cs->distance, 0.0 };
- glClipPlane (GL_CLIP_PLANE0, clipPlane0);
- glClipPlane (GL_CLIP_PLANE1, clipPlane1);
- glClipPlane (GL_CLIP_PLANE2, clipPlane2);
- glClipPlane (GL_CLIP_PLANE3, clipPlane3);
- }
-
- glEnable (GL_CLIP_PLANE0);
- glEnable (GL_CLIP_PLANE1);
- glEnable (GL_CLIP_PLANE2);
- glEnable (GL_CLIP_PLANE3);
-
- glPopMatrix ();
- }
- else
- {
- UNWRAP (cs, s, enableOutputClipping);
- (*s->enableOutputClipping) (s, transform, region, output);
- WRAP (cs, s, enableOutputClipping, cubeEnableOutputClipping);
- }
-}
-
-static void
cubePaintViewport (CompScreen *s,
const ScreenPaintAttrib *sAttrib,
const CompTransform *transform,
@@ -1580,7 +1527,8 @@ cubePaintWindow (CompWindow *w,
CompScreen *s = w->screen;
CUBE_SCREEN (s);
- if ((w->type & CompWindowTypeDesktopMask) &&
+ if (w->parent == &s->root &&
+ (w->type & CompWindowTypeDesktopMask) &&
(attrib->opacity != cs->desktopOpacity))
{
WindowPaintAttrib wAttrib = *attrib;
@@ -1602,12 +1550,12 @@ cubePaintWindow (CompWindow *w,
}
static void
-cubeInitWindowWalker (CompScreen *s, CompWalker* walker)
+cubeInitWindowWalker (CompScreen *s, CompWindow *w, CompWalker* walker)
{
CUBE_SCREEN (s);
UNWRAP (cs, s, initWindowWalker);
- (*s->initWindowWalker) (s, walker);
+ (*s->initWindowWalker) (s, w, walker);
WRAP (cs, s, initWindowWalker, cubeInitWindowWalker);
if (cs->paintOrder == FTB)
@@ -1701,7 +1649,7 @@ cubeFold (CompDisplay *d,
{
CUBE_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (cs->grabIndex)
@@ -1806,7 +1754,7 @@ cubeSetOptionForPlugin (CompObject *o,
status = (*core.setOptionForPlugin) (o, plugin, name, value);
WRAP (cc, &core, setOptionForPlugin, cubeSetOptionForPlugin);
- if (status && o->type == COMP_OBJECT_TYPE_SCREEN)
+ if (status && o->parent && o->type == COMP_OBJECT_TYPE_SCREEN)
{
if (strcmp (plugin, "core") == 0 && strcmp (name, "hsize") == 0)
{
@@ -1864,7 +1812,8 @@ cubeInitCore (CompPlugin *p,
{
CubeCore *cc;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
cc = malloc (sizeof (CubeCore));
@@ -2081,7 +2030,6 @@ cubeInitScreen (CompPlugin *p,
WRAP (cs, s, paintScreen, cubePaintScreen);
WRAP (cs, s, paintOutput, cubePaintOutput);
WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput);
- WRAP (cs, s, enableOutputClipping, cubeEnableOutputClipping);
WRAP (cs, s, paintWindow, cubePaintWindow);
WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform);
WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify);
@@ -2107,7 +2055,6 @@ cubeFiniScreen (CompPlugin *p,
UNWRAP (cs, s, paintScreen);
UNWRAP (cs, s, paintOutput);
UNWRAP (cs, s, paintTransformedOutput);
- UNWRAP (cs, s, enableOutputClipping);
UNWRAP (cs, s, paintWindow);
UNWRAP (cs, s, applyScreenTransform);
UNWRAP (cs, s, outputChangeNotify);
diff --git a/plugins/dbus.c b/plugins/dbus.c
index bcc6f28..01734d5 100644
--- a/plugins/dbus.c
+++ b/plugins/dbus.c
@@ -65,13 +65,17 @@ typedef struct _DbusCore {
CompFileWatchHandle fileWatch[DBUS_FILE_WATCH_NUM];
- InitPluginForObjectProc initPluginForObject;
- SetOptionForPluginProc setOptionForPlugin;
+ SetOptionForPluginProc setOptionForPlugin;
+
+ ObjectAddProc objectAdd;
+ ObjectRemoveProc objectRemove;
} DbusCore;
typedef struct _DbusDisplay {
char **pluginList;
unsigned int nPlugins;
+
+ CompTimeoutHandle registerPluginsHandle;
} DbusDisplay;
static DBusHandlerResult dbusHandleMessage (DBusConnection *,
@@ -96,6 +100,19 @@ static DBusObjectPathVTable dbusMessagesVTable = {
DbusDisplay *dd = GET_DBUS_DISPLAY (d)
static void
+dbusEmptyPluginList (CompDisplay *d)
+{
+ int i;
+
+ DBUS_DISPLAY (d);
+
+ for (i = 0; i < dd->nPlugins; i++)
+ free (dd->pluginList[i]);
+
+ dd->nPlugins = 0;
+}
+
+static void
dbusUpdatePluginList (CompDisplay *d)
{
CompListValue *pl;
@@ -105,20 +122,15 @@ dbusUpdatePluginList (CompDisplay *d)
pl = &d->opt[COMP_DISPLAY_OPTION_ACTIVE_PLUGINS].value.list;
- for (i = 0; i < dd->nPlugins; i++)
- free (dd->pluginList[i]);
+ dbusEmptyPluginList (d);
dd->pluginList = realloc (dd->pluginList, pl->nValue * sizeof (char *));
if (!dd->pluginList)
- {
- dd->nPlugins = 0;
return;
- }
for (i = 0; i < pl->nValue; i++)
- dd->pluginList[i] = strdup (pl->value[i].s);
-
- dd->nPlugins = pl->nValue;
+ if (findActivePlugin (pl->value[i].s))
+ dd->pluginList[dd->nPlugins++] = strdup (pl->value[i].s);
}
static CompOption *
@@ -1814,6 +1826,7 @@ dbusHandleMessage (DBusConnection *connection,
dbus_free_string_array (path);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
+
/* option message */
if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE,
"Introspect"))
@@ -2169,59 +2182,26 @@ dbusUnregisterPluginsForScreen (DBusConnection *connection,
}
static CompBool
-dbusInitPluginForDisplay (CompPlugin *p,
- CompDisplay *d)
-{
- char objectPath[256];
-
- DBUS_CORE (&core);
-
- snprintf (objectPath, 256, "%s/%s/%s", COMPIZ_DBUS_ROOT_PATH,
- p->vTable->name, "allscreens");
- dbusRegisterOptions (dc->connection, objectPath);
-
- return TRUE;
-}
-
-static Bool
-dbusInitPluginForScreen (CompPlugin *p,
- CompScreen *s)
+dbusRegisterPlugins (void *data)
{
- char objectPath[256];
+ CompDisplay *d = (CompDisplay *) data;
+ CompScreen *s;
DBUS_CORE (&core);
+ DBUS_DISPLAY (d);
- snprintf (objectPath, 256, "%s/%s/screen%d", COMPIZ_DBUS_ROOT_PATH,
- p->vTable->name, s->screenNum);
- dbusRegisterOptions (dc->connection, objectPath);
-
- return TRUE;
-}
-
-static CompBool
-dbusInitPluginForObject (CompPlugin *p,
- CompObject *o)
-{
- CompBool status;
-
- DBUS_CORE (&core);
+ if (d->dirtyPluginList)
+ return TRUE;
- UNWRAP (dc, &core, initPluginForObject);
- status = (*core.initPluginForObject) (p, o);
- WRAP (dc, &core, initPluginForObject, dbusInitPluginForObject);
+ dd->registerPluginsHandle = 0;
- if (status && p->vTable->getObjectOptions)
- {
- static InitPluginForObjectProc dispTab[] = {
- (InitPluginForObjectProc) 0, /* InitPluginForCore */
- (InitPluginForObjectProc) dbusInitPluginForDisplay,
- (InitPluginForObjectProc) dbusInitPluginForScreen
- };
+ dbusUpdatePluginList (d);
- RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
- }
+ dbusRegisterPluginsForDisplay (dc->connection, d);
+ for (s = d->screens; s; s = s->next)
+ dbusRegisterPluginsForScreen (dc->connection, s);
- return status;
+ return FALSE;
}
static CompBool
@@ -2262,16 +2242,19 @@ dbusSetOptionForPlugin (CompObject *object,
CompScreen *s;
CORE_DISPLAY (object);
+ DBUS_DISPLAY (d);
dbusUnregisterPluginsForDisplay (dc->connection, d);
for (s = d->screens; s; s = s->next)
dbusUnregisterPluginsForScreen (dc->connection, s);
- dbusUpdatePluginList (d);
+ dbusEmptyPluginList (d);
- dbusRegisterPluginsForDisplay (dc->connection, d);
- for (s = d->screens; s; s = s->next)
- dbusRegisterPluginsForScreen (dc->connection, s);
+ if (!dd->registerPluginsHandle)
+ dd->registerPluginsHandle =
+ compAddTimeout (10, -1,
+ dbusRegisterPlugins,
+ d);
}
}
}
@@ -2297,6 +2280,84 @@ dbusSendPluginsChangedSignal (const char *name,
dbus_message_unref (signal);
}
+static void
+dbusDisplayAdd (CompCore *c,
+ CompDisplay *d)
+{
+ DBUS_DISPLAY (d);
+
+ if (!dd->registerPluginsHandle)
+ dd->registerPluginsHandle = compAddTimeout (10, -1,
+ dbusRegisterPlugins,
+ d);
+}
+
+static void
+dbusDisplayRemove (CompCore *c,
+ CompDisplay *d)
+{
+ DBUS_CORE (&core);
+
+ dbusUnregisterPluginsForDisplay (dc->connection, d);
+ dbusEmptyPluginList (d);
+}
+
+static void
+dbusScreenAdd (CompDisplay *d,
+ CompScreen *s)
+{
+ DBUS_CORE (&core);
+
+ dbusRegisterPluginsForScreen (dc->connection, s);
+}
+
+static void
+dbusScreenRemove (CompDisplay *d,
+ CompScreen *s)
+{
+ DBUS_CORE (&core);
+
+ dbusUnregisterPluginsForScreen (dc->connection, s);
+}
+
+static void
+dbusObjectAdd (CompObject *parent,
+ CompObject *object)
+{
+ static ObjectAddProc dispTab[] = {
+ (ObjectAddProc) 0, /* CoreAdd */
+ (ObjectAddProc) dbusDisplayAdd,
+ (ObjectAddProc) dbusScreenAdd
+ };
+
+ DBUS_CORE (&core);
+
+ UNWRAP (dc, &core, objectAdd);
+ (*core.objectAdd) (parent, object);
+ WRAP (dc, &core, objectAdd, dbusObjectAdd);
+
+ DISPATCH (object, dispTab, ARRAY_SIZE (dispTab), (parent, object));
+}
+
+static void
+dbusObjectRemove (CompObject *parent,
+ CompObject *object)
+{
+ static ObjectRemoveProc dispTab[] = {
+ (ObjectRemoveProc) 0, /* CoreRemove */
+ (ObjectRemoveProc) dbusDisplayRemove,
+ (ObjectRemoveProc) dbusScreenRemove
+ };
+
+ DBUS_CORE (&core);
+
+ DISPATCH (object, dispTab, ARRAY_SIZE (dispTab), (parent, object));
+
+ UNWRAP (dc, &core, objectRemove);
+ (*core.objectRemove) (parent, object);
+ WRAP (dc, &core, objectRemove, dbusObjectRemove);
+}
+
static Bool
dbusInitCore (CompPlugin *p,
CompCore *c)
@@ -2415,7 +2476,8 @@ dbusInitCore (CompPlugin *p,
}
}
- WRAP (dc, c, initPluginForObject, dbusInitPluginForObject);
+ WRAP (dc, c, objectAdd, dbusObjectAdd);
+ WRAP (dc, c, objectRemove, dbusObjectRemove);
WRAP (dc, c, setOptionForPlugin, dbusSetOptionForPlugin);
c->base.privates[corePrivateIndex].ptr = dc;
@@ -2452,7 +2514,8 @@ dbusFiniCore (CompPlugin *p,
dbus_connection_unref (dc->connection);
*/
- UNWRAP (dc, c, initPluginForObject);
+ UNWRAP (dc, c, objectAdd);
+ UNWRAP (dc, c, objectRemove);
UNWRAP (dc, c, setOptionForPlugin);
free (dc);
@@ -2464,8 +2527,6 @@ dbusInitDisplay (CompPlugin *p,
{
DbusDisplay *dd;
- DBUS_CORE (&core);
-
dd = malloc (sizeof (DbusDisplay));
if (!dd)
return FALSE;
@@ -2473,10 +2534,12 @@ dbusInitDisplay (CompPlugin *p,
dd->pluginList = NULL;
dd->nPlugins = 0;
+ dd->registerPluginsHandle = 0;
+
d->base.privates[displayPrivateIndex].ptr = dd;
- dbusUpdatePluginList (d);
- dbusRegisterPluginsForDisplay (dc->connection, d);
+ if (d->base.parent)
+ dbusObjectAdd (d->base.parent, &d->base);
return TRUE;
}
@@ -2485,10 +2548,13 @@ static void
dbusFiniDisplay (CompPlugin *p,
CompDisplay *d)
{
- DBUS_CORE (&core);
DBUS_DISPLAY (d);
- dbusUnregisterPluginsForDisplay (dc->connection, d);
+ if (dd->registerPluginsHandle)
+ compRemoveTimeout (dd->registerPluginsHandle);
+
+ if (d->base.parent)
+ dbusObjectRemove (d->base.parent, &d->base);
if (dd->pluginList)
{
@@ -2506,9 +2572,8 @@ static Bool
dbusInitScreen (CompPlugin *p,
CompScreen *s)
{
- DBUS_CORE (&core);
-
- dbusRegisterPluginsForScreen (dc->connection, s);
+ if (s->base.parent)
+ dbusObjectAdd (s->base.parent, &s->base);
return TRUE;
}
@@ -2517,9 +2582,8 @@ static void
dbusFiniScreen (CompPlugin *p,
CompScreen *s)
{
- DBUS_CORE (&core);
-
- dbusUnregisterPluginsForScreen (dc->connection, s);
+ if (s->base.parent)
+ dbusObjectRemove (s->base.parent, &s->base);
}
static CompBool
diff --git a/plugins/decoration.c b/plugins/decoration.c
index 003685f..a7a8d47 100644
--- a/plugins/decoration.c
+++ b/plugins/decoration.c
@@ -121,10 +121,6 @@ typedef struct _DecorDisplay {
typedef struct _DecorScreen {
int windowPrivateIndex;
- Window dmWin;
-
- Decoration *decor[DECOR_NUM];
-
DrawWindowProc drawWindow;
DamageWindowRectProc damageWindowRect;
GetOutputExtentsForWindowProc getOutputExtentsForWindow;
@@ -139,7 +135,11 @@ typedef struct _DecorScreen {
typedef struct _DecorWindow {
WindowDecoration *wd;
- Decoration *decor;
+
+ Window dmWin;
+ Window wmWin;
+
+ Decoration *decor[DECOR_NUM];
CompTimeoutHandle resizeUpdateHandle;
} DecorWindow;
@@ -188,6 +188,15 @@ decorDrawWindow (CompWindow *w,
status = (*w->screen->drawWindow) (w, transform, attrib, region, mask);
WRAP (ds, w->screen, drawWindow, decorDrawWindow);
+ if (!w->shaded)
+ {
+ if (w->attrib.map_state != IsViewable)
+ return status;
+
+ if (!w->damaged)
+ return status;
+ }
+
if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
region = &infiniteRegion;
@@ -224,7 +233,7 @@ decorDrawWindow (CompWindow *w,
attrib, mask);
}
- return status;
+ return TRUE;
}
static DecorTexture *
@@ -261,19 +270,26 @@ decorGetTexture (CompScreen *screen,
return NULL;
}
- if (!bindPixmapToTexture (screen, &texture->texture, pixmap,
- width, height, depth))
+ if (manualCompositeManagement)
{
- finiTexture (screen, &texture->texture);
- free (texture);
- return NULL;
- }
+ if (!bindPixmapToTexture (screen, &texture->texture, pixmap,
+ width, height, depth))
+ {
+ finiTexture (screen, &texture->texture);
+ free (texture);
+ return NULL;
+ }
- if (!dd->opt[DECOR_DISPLAY_OPTION_MIPMAP].value.b)
- texture->texture.mipmap = FALSE;
+ if (!dd->opt[DECOR_DISPLAY_OPTION_MIPMAP].value.b)
+ texture->texture.mipmap = FALSE;
- texture->damage = XDamageCreate (screen->display->display, pixmap,
- XDamageReportRawRectangles);
+ texture->damage = XDamageCreate (screen->display->display, pixmap,
+ XDamageReportRawRectangles);
+ }
+ else
+ {
+ texture->damage = None;
+ }
texture->refCount = 1;
texture->pixmap = pixmap;
@@ -410,7 +426,7 @@ decorCreateDecoration (CompScreen *screen,
result = XGetWindowProperty (screen->display->display, id,
decorAtom, 0L, 1024L, FALSE,
- XA_INTEGER, &actual, &format,
+ 0, &actual, &format,
&n, &nleft, &data);
if (result != Success || !n || !data)
@@ -532,19 +548,20 @@ decorReleaseDecoration (CompScreen *screen,
}
static void
-decorWindowUpdateDecoration (CompWindow *w)
+decorWindowUpdateDecoration (CompWindow *w,
+ Atom atom,
+ int type)
{
Decoration *decoration;
- DECOR_DISPLAY (w->screen->display);
DECOR_WINDOW (w);
- decoration = decorCreateDecoration (w->screen, w->id, dd->winDecorAtom);
+ decoration = decorCreateDecoration (w->screen, w->id, atom);
- if (dw->decor)
- decorReleaseDecoration (w->screen, dw->decor);
+ if (dw->decor[type])
+ decorReleaseDecoration (w->screen, dw->decor[type]);
- dw->decor = decoration;
+ dw->decor[type] = decoration;
}
static WindowDecoration *
@@ -654,6 +671,9 @@ updateWindowDecorationScale (CompWindow *w)
if (!wd)
return;
+ if (!manualCompositeManagement)
+ return;
+
for (i = 0; i < wd->nQuad; i++)
{
computeQuadBox (&wd->decor->quad[i], w->width, w->height,
@@ -712,6 +732,17 @@ decorWindowShiftY (CompWindow *w)
}
static Bool
+decorIsActiveWindow (CompWindow *w)
+{
+ for (; w->parent; w = w->parent)
+ if (w->parent->redirectSubwindows || w->parent->substructureRedirect)
+ if (w->parent->activeChild != w->id)
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
decorWindowUpdate (CompWindow *w,
Bool allowDecoration)
{
@@ -727,6 +758,9 @@ decorWindowUpdate (CompWindow *w,
DECOR_SCREEN (w->screen);
DECOR_WINDOW (w);
+ if (!w->parent)
+ return FALSE;
+
wd = dw->wd;
old = (wd) ? wd->decor : NULL;
@@ -742,6 +776,9 @@ decorWindowUpdate (CompWindow *w,
break;
}
+ if (!GET_DECOR_WINDOW (w->parent, ds)->wmWin)
+ decorate = FALSE;
+
if (w->attrib.override_redirect)
decorate = FALSE;
@@ -754,16 +791,16 @@ decorWindowUpdate (CompWindow *w,
if (decorate)
{
- if (dw->decor && decorCheckSize (w, dw->decor))
+ decor = dw->decor[DECOR_NORMAL];
+ if (decorIsActiveWindow (w) && dw->decor[DECOR_ACTIVE])
+ decor = dw->decor[DECOR_ACTIVE];
+
+ if (!decor || !decorCheckSize (w, decor))
{
- decor = dw->decor;
- }
- else
- {
- if (w->id == w->screen->display->activeWindow)
- decor = ds->decor[DECOR_ACTIVE];
+ if (decorIsActiveWindow (w))
+ decor = GET_DECOR_WINDOW (w->parent, ds)->decor[DECOR_ACTIVE];
else
- decor = ds->decor[DECOR_NORMAL];
+ decor = GET_DECOR_WINDOW (w->parent, ds)->decor[DECOR_NORMAL];
}
}
else
@@ -772,7 +809,7 @@ decorWindowUpdate (CompWindow *w,
if (matchEval (match, w))
{
if (w->region->numRects == 1)
- decor = ds->decor[DECOR_BARE];
+ decor = GET_DECOR_WINDOW (w->parent, ds)->decor[DECOR_BARE];
if (decor)
{
@@ -782,7 +819,7 @@ decorWindowUpdate (CompWindow *w,
}
}
- if (!ds->dmWin || !allowDecoration)
+ if (!GET_DECOR_WINDOW (w->parent, ds)->dmWin || !allowDecoration)
decor = NULL;
if (decor == old)
@@ -829,7 +866,7 @@ decorWindowUpdate (CompWindow *w,
moveDy = -oldShiftY;
}
- if (w->placed && !w->attrib.override_redirect && (moveDx || moveDy))
+ if (w->placed && w->managed && (moveDx || moveDy))
{
XWindowChanges xwc;
unsigned int mask = CWX | CWY;
@@ -860,20 +897,34 @@ decorWindowUpdate (CompWindow *w,
}
static void
-decorCheckForDmOnScreen (CompScreen *s,
- Bool updateWindows)
+decorWindowUpdateTree (CompWindow *ancestor,
+ Bool allowDecoration)
+{
+ CompWindow *w;
+
+ w = ancestor;
+ do {
+ decorWindowUpdate (w, allowDecoration);
+ } while ((w = walkDepthFirst (w)) && w != ancestor);
+}
+
+static void
+decorCheckForDm (CompWindow *w,
+ Bool updateWindows)
{
+ CompScreen *s = w->screen;
CompDisplay *d = s->display;
Atom actual;
int result, format;
unsigned long n, left;
unsigned char *data;
Window dmWin = None;
+ Window wmWin = w->supportingWmCheckWindow;
DECOR_DISPLAY (s->display);
- DECOR_SCREEN (s);
+ DECOR_WINDOW (w);
- result = XGetWindowProperty (d->display, s->root,
+ result = XGetWindowProperty (d->display, w->id,
dd->supportingDmCheckAtom, 0L, 1L, FALSE,
XA_WINDOW, &actual, &format,
&n, &left, &data);
@@ -893,46 +944,58 @@ decorCheckForDmOnScreen (CompScreen *s,
dmWin = None;
}
- if (dmWin != ds->dmWin)
+ if (dmWin != dw->dmWin)
{
- CompWindow *w;
+ CompWindow *c;
int i;
if (dmWin)
{
for (i = 0; i < DECOR_NUM; i++)
- ds->decor[i] =
- decorCreateDecoration (s, s->root, dd->decorAtom[i]);
+ dw->decor[i] = decorCreateDecoration (s,
+ w->id,
+ dd->decorAtom[i]);
}
else
{
+ DECOR_SCREEN (w->screen);
+
for (i = 0; i < DECOR_NUM; i++)
{
- if (ds->decor[i])
+ if (dw->decor[i])
{
- decorReleaseDecoration (s, ds->decor[i]);
- ds->decor[i] = 0;
+ decorReleaseDecoration (s, dw->decor[i]);
+ dw->decor[i] = 0;
}
}
- for (w = s->windows; w; w = w->next)
+ for (c = w->windows; c; c = c->next)
{
- DECOR_WINDOW (w);
+ DecorWindow *dc = GET_DECOR_WINDOW (c, ds);
- if (dw->decor)
+ for (i = 0; i < DECOR_NUM; i++)
{
- decorReleaseDecoration (s, dw->decor);
- dw->decor = 0;
+ if (dc->decor[i])
+ {
+ decorReleaseDecoration (s, dc->decor[i]);
+ dc->decor[i] = 0;
+ }
}
}
}
+ }
- ds->dmWin = dmWin;
+ if ((wmWin != dw->wmWin) || (dmWin != dw->dmWin))
+ {
+ dw->wmWin = wmWin;
+ dw->dmWin = dmWin;
if (updateWindows)
{
- for (w = s->windows; w; w = w->next)
- decorWindowUpdate (w, TRUE);
+ CompWindow *c;
+
+ for (c = w->windows; c; c = c->next)
+ decorWindowUpdate (c, TRUE);
}
}
}
@@ -941,7 +1004,6 @@ static void
decorHandleEvent (CompDisplay *d,
XEvent *event)
{
- Window activeWindow = d->activeWindow;
CompWindow *w;
DECOR_DISPLAY (d);
@@ -949,12 +1011,16 @@ decorHandleEvent (CompDisplay *d,
switch (event->type) {
case DestroyNotify:
w = findWindowAtDisplay (d, event->xdestroywindow.window);
- if (w)
+ if (w && (w = w->parent))
{
- DECOR_SCREEN (w->screen);
+ DECOR_WINDOW (w);
- if (w->id == ds->dmWin)
- decorCheckForDmOnScreen (w->screen, TRUE);
+ if (w->supportingWmCheckWindow == event->xdestroywindow.window)
+ getSupportingWmCheck (w);
+
+ if (event->xdestroywindow.window == dw->wmWin ||
+ event->xdestroywindow.window == dw->dmWin)
+ decorCheckForDm (w, TRUE);
}
break;
case MapRequest:
@@ -982,7 +1048,7 @@ decorHandleEvent (CompDisplay *d,
{
ds = GET_DECOR_SCREEN (s, dd);
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = walkDepthFirst (w))
{
if (w->shaded || w->mapNum)
{
@@ -1004,25 +1070,47 @@ decorHandleEvent (CompDisplay *d,
(*d->handleEvent) (d, event);
WRAP (dd, d, handleEvent, decorHandleEvent);
- if (d->activeWindow != activeWindow)
- {
- w = findWindowAtDisplay (d, activeWindow);
- if (w)
- decorWindowUpdate (w, TRUE);
-
- w = findWindowAtDisplay (d, d->activeWindow);
- if (w)
- decorWindowUpdate (w, TRUE);
- }
-
switch (event->type) {
+ case FocusIn:
+ if (event->xfocus.mode != NotifyGrab)
+ {
+ w = findTopLevelWindowAtDisplay (d, event->xfocus.window);
+ if (w && w->managed && (w = w->parent))
+ {
+ CompWindow *c;
+
+ for (c = w->windows; c; c = c->next)
+ if (c->id == w->previousActiveChild ||
+ c->id == w->activeChild)
+ decorWindowUpdateTree (c, TRUE);
+ }
+ }
+ break;
case PropertyNotify:
- if (event->xproperty.atom == dd->winDecorAtom)
+ if (event->xproperty.atom == d->winActiveAtom)
+ {
+ w = findWindowAtDisplay (d, event->xproperty.window);
+ if (w)
+ {
+ if (!w->substructureRedirect)
+ {
+ CompWindow *c;
+
+ for (c = w->windows; c; c = c->next)
+ if (c->id == w->previousActiveChild ||
+ c->id == w->activeChild)
+ decorWindowUpdateTree (c, TRUE);
+ }
+ }
+ }
+ else if (event->xproperty.atom == dd->winDecorAtom)
{
w = findWindowAtDisplay (d, event->xproperty.window);
if (w)
{
- decorWindowUpdateDecoration (w);
+ decorWindowUpdateDecoration (w,
+ dd->winDecorAtom,
+ DECOR_NORMAL);
decorWindowUpdate (w, TRUE);
}
}
@@ -1034,14 +1122,13 @@ decorHandleEvent (CompDisplay *d,
}
else
{
- CompScreen *s;
-
- s = findScreenAtDisplay (d, event->xproperty.window);
- if (s)
+ w = findWindowAtDisplay (d, event->xproperty.window);
+ if (w)
{
- if (event->xproperty.atom == dd->supportingDmCheckAtom)
+ if (event->xproperty.atom == d->supportingWmCheckAtom ||
+ event->xproperty.atom == dd->supportingDmCheckAtom)
{
- decorCheckForDmOnScreen (s, TRUE);
+ decorCheckForDm (w, TRUE);
}
else
{
@@ -1051,17 +1138,23 @@ decorHandleEvent (CompDisplay *d,
{
if (event->xproperty.atom == dd->decorAtom[i])
{
- DECOR_SCREEN (s);
+ DECOR_WINDOW (w);
- if (ds->decor[i])
- decorReleaseDecoration (s, ds->decor[i]);
+ decorWindowUpdateDecoration (w,
+ dd->decorAtom[i],
+ i);
- ds->decor[i] =
- decorCreateDecoration (s, s->root,
- dd->decorAtom[i]);
+ if (dw->dmWin)
+ {
+ CompWindow *c;
- for (w = s->windows; w; w = w->next)
+ for (c = w->windows; c; c = c->next)
+ decorWindowUpdate (c, TRUE);
+ }
+ else
+ {
decorWindowUpdate (w, TRUE);
+ }
}
}
}
@@ -1132,10 +1225,11 @@ decorStartDecorator (void *closure)
DECOR_DISPLAY (s->display);
DECOR_SCREEN (s);
+ DECOR_WINDOW ((&s->root));
ds->decoratorStartHandle = 0;
- if (!ds->dmWin)
+ if (!dw->dmWin)
runCommand (s, dd->opt[DECOR_DISPLAY_OPTION_COMMAND].value.s);
return FALSE;
@@ -1175,10 +1269,14 @@ decorSetDisplayOption (CompPlugin *plugin,
for (s = display->screens; s; s = s->next)
{
+ DECOR_WINDOW ((&s->root));
DECOR_SCREEN (s);
- if (!ds->dmWin)
- runCommand (s, o->value.s);
+ if (!dw->dmWin && !ds->decoratorStartHandle)
+ ds->decoratorStartHandle =
+ compAddTimeout (0, -1,
+ decorStartDecorator,
+ s);
}
return TRUE;
@@ -1221,11 +1319,9 @@ decorSetDisplayOption (CompPlugin *plugin,
if (compSetMatchOption (o, value))
{
CompScreen *s;
- CompWindow *w;
for (s = display->screens; s; s = s->next)
- for (w = s->windows; w; w = w->next)
- decorWindowUpdate (w, TRUE);
+ decorWindowUpdateTree (&s->root, TRUE);
}
break;
default:
@@ -1246,7 +1342,7 @@ decorWindowMoveNotify (CompWindow *w,
DECOR_SCREEN (w->screen);
DECOR_WINDOW (w);
- if (dw->wd)
+ if (dw->wd && w->parent && w->parent->redirectSubwindows)
{
WindowDecoration *wd = dw->wd;
int i;
@@ -1291,15 +1387,21 @@ decorWindowResizeNotify (CompWindow *w,
DECOR_SCREEN (w->screen);
DECOR_WINDOW (w);
- /* FIXME: we should not need a timer for calling decorWindowUpdate,
- and only call updateWindowDecorationScale if decorWindowUpdate
- returns FALSE. Unfortunately, decorWindowUpdate may call
- updateWindowOutputExtents, which may call WindowResizeNotify. As
- we never should call a wrapped function that's currently
- processed, we need the timer for the moment. updateWindowOutputExtents
- should be fixed so that it does not emit a resize notification. */
- dw->resizeUpdateHandle = compAddTimeout (0, 0, decorResizeUpdateTimeout, w);
- updateWindowDecorationScale (w);
+ if (w->parent && w->parent->redirectSubwindows)
+ {
+ /* FIXME: we should not need a timer for calling decorWindowUpdate,
+ and only call updateWindowDecorationScale if decorWindowUpdate
+ returns FALSE. Unfortunately, decorWindowUpdate may call
+ updateWindowOutputExtents, which may call WindowResizeNotify. As
+ we never should call a wrapped function that's currently
+ processed, we need the timer for the moment.
+ updateWindowOutputExtents should be fixed so that it does not
+ emit a resize notification. */
+ if (!dw->resizeUpdateHandle)
+ dw->resizeUpdateHandle =
+ compAddTimeout (0, 0, decorResizeUpdateTimeout, w);
+ updateWindowDecorationScale (w);
+ }
UNWRAP (ds, w->screen, windowResizeNotify);
(*w->screen->windowResizeNotify) (w, dx, dy, dwidth, dheight);
@@ -1343,7 +1445,7 @@ decorMatchPropertyChanged (CompDisplay *d,
}
static void
-decorWindowAdd (CompScreen *s,
+decorWindowAdd (CompObject *parent,
CompWindow *w)
{
if (w->shaded || w->attrib.map_state == IsViewable)
@@ -1351,7 +1453,7 @@ decorWindowAdd (CompScreen *s,
}
static void
-decorWindowRemove (CompScreen *s,
+decorWindowRemove (CompObject *parent,
CompWindow *w)
{
if (!w->destroyed)
@@ -1536,9 +1638,6 @@ decorInitScreen (CompPlugin *p,
return FALSE;
}
- memset (ds->decor, 0, sizeof (ds->decor));
-
- ds->dmWin = None;
ds->decoratorStartHandle = 0;
WRAP (ds, s, drawWindow, decorDrawWindow);
@@ -1550,12 +1649,6 @@ decorInitScreen (CompPlugin *p,
s->base.privates[dd->screenPrivateIndex].ptr = ds;
- decorCheckForDmOnScreen (s, FALSE);
-
- if (!ds->dmWin)
- ds->decoratorStartHandle = compAddTimeout (0, -1,
- decorStartDecorator, s);
-
return TRUE;
}
@@ -1563,14 +1656,8 @@ static void
decorFiniScreen (CompPlugin *p,
CompScreen *s)
{
- int i;
-
DECOR_SCREEN (s);
- for (i = 0; i < DECOR_NUM; i++)
- if (ds->decor[i])
- decorReleaseDecoration (s, ds->decor[i]);
-
if (ds->decoratorStartHandle)
compRemoveTimeout (ds->decoratorStartHandle);
@@ -1591,6 +1678,7 @@ decorInitWindow (CompPlugin *p,
CompWindow *w)
{
DecorWindow *dw;
+ int i;
DECOR_SCREEN (w->screen);
@@ -1598,18 +1686,46 @@ decorInitWindow (CompPlugin *p,
if (!dw)
return FALSE;
- dw->wd = NULL;
- dw->decor = NULL;
+ dw->wmWin = None;
+ dw->dmWin = None;
+
+ dw->wd = NULL;
+
+ for (i = 0; i < DECOR_NUM; i++)
+ dw->decor[i] = 0;
dw->resizeUpdateHandle = 0;
w->base.privates[ds->windowPrivateIndex].ptr = dw;
- if (!w->attrib.override_redirect)
- decorWindowUpdateDecoration (w);
+ decorCheckForDm (w, FALSE);
+
+ if (w->parent)
+ {
+ if (!w->attrib.override_redirect)
+ {
+ DECOR_DISPLAY (w->screen->display);
+
+ decorWindowUpdateDecoration (w,
+ dd->winDecorAtom,
+ DECOR_NORMAL);
+ decorWindowUpdateDecoration (w,
+ dd->decorAtom[DECOR_ACTIVE],
+ DECOR_ACTIVE);
+ }
+ }
+ else
+ {
+ DECOR_SCREEN (w->screen);
+
+ if (!dw->dmWin && !ds->decoratorStartHandle)
+ ds->decoratorStartHandle = compAddTimeout (0, -1,
+ decorStartDecorator,
+ w->screen);
+ }
if (w->base.parent)
- decorWindowAdd (w->screen, w);
+ decorWindowAdd (w->base.parent, w);
return TRUE;
}
@@ -1618,19 +1734,22 @@ static void
decorFiniWindow (CompPlugin *p,
CompWindow *w)
{
+ int i;
+
DECOR_WINDOW (w);
if (dw->resizeUpdateHandle)
compRemoveTimeout (dw->resizeUpdateHandle);
if (w->base.parent)
- decorWindowRemove (w->screen, w);
+ decorWindowRemove (w->base.parent, w);
if (dw->wd)
destroyWindowDecoration (w->screen, dw->wd);
- if (dw->decor)
- decorReleaseDecoration (w->screen, dw->decor);
+ for (i = 0; i < DECOR_NUM; i++)
+ if (dw->decor[i])
+ decorReleaseDecoration (w->screen, dw->decor[i]);
free (dw);
}
diff --git a/plugins/fade.c b/plugins/fade.c
index a30deef..7526750 100644
--- a/plugins/fade.c
+++ b/plugins/fade.c
@@ -196,16 +196,16 @@ fadePreparePaintScreen (CompScreen *s,
if (steps < 12)
steps = 12;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = walkDepthFirst (w))
{
FadeWindow *fw = GET_FADE_WINDOW (w, fs);
+
fw->steps = steps;
fw->fadeTime = 0;
- }
-
+ }
break;
case FADE_MODE_CONSTANTTIME:
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = walkDepthFirst (w))
{
FadeWindow *fw = GET_FADE_WINDOW (w, fs);
@@ -221,7 +221,6 @@ fadePreparePaintScreen (CompScreen *s,
fw->steps = 0;
}
}
-
break;
}
@@ -569,7 +568,7 @@ fadeHandleEvent (CompDisplay *d,
option = FADE_SCREEN_OPTION_FULLSCREEN_VISUAL_BELL;
if (fs->opt[option].value.b)
{
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (w->destroyed)
continue;
@@ -731,7 +730,8 @@ fadeInitDisplay (CompPlugin *p,
{
FadeDisplay *fd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
fd = malloc (sizeof (FadeDisplay));
diff --git a/plugins/gconf.c b/plugins/gconf.c
index 8d365e0..98094d8 100644
--- a/plugins/gconf.c
+++ b/plugins/gconf.c
@@ -691,22 +691,23 @@ gconfKeyChanged (GConfClient *client,
}
static void
-gconfSendGLibNotify (CompDisplay *d)
+gconfSendGLibNotify (CompScreen *s)
{
- Display *dpy = d->display;
- XEvent xev;
+ CompDisplay *d = s->display;
+ Display *dpy = d->display;
+ XEvent xev;
xev.xclient.type = ClientMessage;
xev.xclient.display = dpy;
xev.xclient.format = 32;
xev.xclient.message_type = XInternAtom (dpy, "_COMPIZ_GLIB_NOTIFY", 0);
- xev.xclient.window = d->screens->root;
+ xev.xclient.window = s->root.id;
memset (xev.xclient.data.l, 0, sizeof (xev.xclient.data.l));
XSendEvent (dpy,
- d->screens->root,
+ s->root.id,
FALSE,
SubstructureRedirectMask | SubstructureNotifyMask,
&xev);
@@ -767,10 +768,10 @@ gconfFiniCore (CompPlugin *p,
}
static Bool
-gconfInitDisplay (CompPlugin *p,
- CompDisplay *d)
+gconfInitScreen (CompPlugin *p,
+ CompScreen *s)
{
- gconfSendGLibNotify (d);
+ gconfSendGLibNotify (s);
return TRUE;
}
@@ -781,7 +782,8 @@ gconfInitObject (CompPlugin *p,
{
static InitPluginObjectProc dispTab[] = {
(InitPluginObjectProc) gconfInitCore,
- (InitPluginObjectProc) gconfInitDisplay
+ (InitPluginObjectProc) NULL,
+ (InitPluginObjectProc) gconfInitScreen
};
RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
diff --git a/plugins/glx.c b/plugins/glx.c
new file mode 100644
index 0000000..5bf6274
--- /dev/null
+++ b/plugins/glx.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright © 2008 Novell, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Novell, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * Novell, Inc. makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#include <compiz-core.h>
+
+static CompMetadata glxMetadata;
+
+static CompOption *
+glxGetDisplayOptions (CompPlugin *plugin,
+ CompDisplay *display,
+ int *count)
+{
+ *count = 1;
+ return &display->opt[COMP_DISPLAY_OPTION_ABI];
+}
+
+static Bool
+glxInitDisplay (CompPlugin *p,
+ CompDisplay *d)
+{
+ int error, event;
+
+ if (!checkPluginABI ("core", CORE_ABIVERSION))
+ return FALSE;
+
+ if (!glXQueryExtension (d->display, &error, &event))
+ {
+ compLogMessage (p->vTable->name, CompLogLevelError,
+ "GLX extension is not available");
+ return FALSE;
+ }
+
+ if (manualCompositeManagement)
+ return TRUE;
+
+ if (d->screens)
+ {
+ compLogMessage (p->vTable->name, CompLogLevelError,
+ "%s plugin must be loaded before screens are "
+ "initialize", p->vTable->name);
+ return FALSE;
+ }
+
+ manualCompositeManagement = TRUE;
+
+ return TRUE;
+}
+
+static CompBool
+glxInitObject (CompPlugin *p,
+ CompObject *o)
+{
+ static InitPluginObjectProc dispTab[] = {
+ (InitPluginObjectProc) 0, /* InitCore */
+ (InitPluginObjectProc) glxInitDisplay
+ };
+
+ RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
+}
+
+static CompOption *
+glxGetObjectOptions (CompPlugin *plugin,
+ CompObject *object,
+ int *count)
+{
+ static GetPluginObjectOptionsProc dispTab[] = {
+ (GetPluginObjectOptionsProc) 0, /* GetCoreOptions */
+ (GetPluginObjectOptionsProc) glxGetDisplayOptions
+ };
+
+ RETURN_DISPATCH (object, dispTab, ARRAY_SIZE (dispTab),
+ (void *) (*count = 0), (plugin, object, count));
+}
+
+static Bool
+glxInit (CompPlugin *p)
+{
+ if (!compInitPluginMetadataFromInfo (&glxMetadata, p->vTable->name,
+ 0, 0, 0, 0))
+ return FALSE;
+
+ compAddMetadataFromFile (&glxMetadata, p->vTable->name);
+
+ return TRUE;
+}
+
+static void
+glxFini (CompPlugin *p)
+{
+ compFiniMetadata (&glxMetadata);
+}
+
+static CompMetadata *
+glxGetMetadata (CompPlugin *plugin)
+{
+ return &glxMetadata;
+}
+
+CompPluginVTable glxVTable = {
+ "glx",
+ glxGetMetadata,
+ glxInit,
+ glxFini,
+ glxInitObject,
+ 0, /* FiniObject */
+ glxGetObjectOptions,
+ 0 /* SetObjectOption */
+};
+
+CompPluginVTable *
+getCompPluginInfo20070830 (void)
+{
+ return &glxVTable;
+}
diff --git a/plugins/minimize.c b/plugins/minimize.c
index eb82370..901c29c 100644
--- a/plugins/minimize.c
+++ b/plugins/minimize.c
@@ -312,7 +312,7 @@ minPreparePaintScreen (CompScreen *s,
{
ms->moreAdjust = 0;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
MIN_WINDOW (w);
@@ -395,7 +395,7 @@ minPreparePaintScreen (CompScreen *s,
if (ms->moreAdjust)
{
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
MIN_WINDOW (w);
@@ -431,7 +431,7 @@ minDonePaintScreen (CompScreen *s)
CompWindow *w;
int h;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
MIN_WINDOW (w);
@@ -762,7 +762,9 @@ minInitDisplay (CompPlugin *p,
{
MinDisplay *md;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("wm", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
md = malloc (sizeof (MinDisplay));
diff --git a/plugins/move.c b/plugins/move.c
index 32fb456..d66f17a 100644
--- a/plugins/move.c
+++ b/plugins/move.c
@@ -28,8 +28,10 @@
#include <string.h>
#include <X11/cursorfont.h>
+#include <X11/Xatom.h>
#include <compiz-core.h>
+#include <decoration.h>
static CompMetadata moveMetadata;
@@ -51,6 +53,11 @@ struct _MoveKeys {
#define SNAP_BACK 20
#define SNAP_OFF 100
+typedef struct _MoveBox {
+ decor_point_t p1;
+ decor_point_t p2;
+} MoveBox;
+
static int displayPrivateIndex;
#define MOVE_DISPLAY_OPTION_INITIATE_BUTTON 0
@@ -76,12 +83,17 @@ typedef struct _MoveDisplay {
int status;
KeyCode key[NUM_KEYS];
+ Atom moveAtom;
+ Atom moveNotifyAtom;
+
int releaseButton;
GLushort moveOpacity;
} MoveDisplay;
typedef struct _MoveScreen {
+ int windowPrivateIndex;
+
PaintWindowProc paintWindow;
int grabIndex;
@@ -94,6 +106,12 @@ typedef struct _MoveScreen {
int snapBackY;
} MoveScreen;
+typedef struct _MoveWindow {
+ int button;
+ MoveBox *box;
+ int nBox;
+} MoveWindow;
+
#define GET_MOVE_DISPLAY(d) \
((MoveDisplay *) (d)->base.privates[displayPrivateIndex].ptr)
@@ -106,8 +124,106 @@ typedef struct _MoveScreen {
#define MOVE_SCREEN(s) \
MoveScreen *ms = GET_MOVE_SCREEN (s, GET_MOVE_DISPLAY (s->display))
+#define GET_MOVE_WINDOW(w, ms) \
+ ((MoveWindow *) (w)->base.privates[(ms)->windowPrivateIndex].ptr)
+
+#define MOVE_WINDOW(w) \
+ MoveWindow *mw = GET_MOVE_WINDOW (w, \
+ GET_MOVE_SCREEN (w->screen, \
+ GET_MOVE_DISPLAY (w->screen->display)))
+
+
#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
+
+static Bool
+movePointInBoxes (int x,
+ int y,
+ MoveBox *box,
+ int nBox,
+ int width,
+ int height)
+{
+ int x0, y0, x1, y1;
+
+ while (nBox--)
+ {
+ decor_apply_gravity (box->p1.gravity, box->p1.x, box->p1.y,
+ width, height,
+ &x0, &y0);
+
+ decor_apply_gravity (box->p2.gravity, box->p2.x, box->p2.y,
+ width, height,
+ &x1, &y1);
+
+ if (x >= x0 && x < x1 && y >= y0 && y < y1)
+ return TRUE;
+
+ box++;
+ }
+
+ return FALSE;
+}
+
+static void
+moveWindowUpdate (CompWindow *w)
+{
+ Atom actual;
+ int result, format;
+ unsigned long n, left;
+ unsigned char *propData;
+ MoveBox *box = NULL;
+ int nBox = 0;
+
+ MOVE_DISPLAY (w->screen->display);
+ MOVE_WINDOW (w);
+
+ result = XGetWindowProperty (w->screen->display->display, w->id,
+ md->moveAtom, 0L, 8192L, FALSE,
+ XA_INTEGER, &actual, &format,
+ &n, &left, &propData);
+
+ if (result == Success && n && propData)
+ {
+ if (n >= 2)
+ {
+ long *data = (long *) propData;
+
+ mw->button = data[1];
+
+ nBox = (n - 2) / 6;
+ if (nBox)
+ {
+ box = malloc (sizeof (MoveBox) * nBox);
+ if (box)
+ {
+ int i;
+
+ data += 2;
+
+ for (i = 0; i < nBox; i++)
+ {
+ box[i].p1.gravity = *data++;
+ box[i].p1.x = *data++;
+ box[i].p1.y = *data++;
+ box[i].p2.gravity = *data++;
+ box[i].p2.x = *data++;
+ box[i].p2.y = *data++;
+ }
+ }
+ }
+ }
+
+ XFree (propData);
+ }
+
+ if (mw->box)
+ free (mw->box);
+
+ mw->box = box;
+ mw->nBox = nBox;
+}
+
static Bool
moveInitiate (CompDisplay *d,
CompAction *action,
@@ -125,18 +241,25 @@ moveInitiate (CompDisplay *d,
w = findWindowAtDisplay (d, xid);
if (w && (w->actions & CompWindowActionMoveMask))
{
+ CompWindow *p;
XRectangle workArea;
unsigned int mods;
int x, y, button;
MOVE_SCREEN (w->screen);
+ x = w->width / 2;
+ y = w->height / 2;
+ for (p = w; p; p = p->parent)
+ {
+ x += p->attrib.x;
+ y += p->attrib.y;
+ }
+
mods = getIntOptionNamed (option, nOption, "modifiers", 0);
- x = getIntOptionNamed (option, nOption, "x",
- w->attrib.x + (w->width / 2));
- y = getIntOptionNamed (option, nOption, "y",
- w->attrib.y + (w->height / 2));
+ x = getIntOptionNamed (option, nOption, "x", x);
+ y = getIntOptionNamed (option, nOption, "y", y);
button = getIntOptionNamed (option, nOption, "button", -1);
@@ -192,6 +315,12 @@ moveInitiate (CompDisplay *d,
md->releaseButton = button;
+ for (p = w->parent; p; p = p->parent)
+ {
+ x -= p->attrib.x;
+ y -= p->attrib.y;
+ }
+
(w->screen->windowGrabNotify) (w, x, y, mods,
CompWindowGrabMoveMask |
CompWindowGrabButtonMask);
@@ -208,6 +337,8 @@ moveInitiate (CompDisplay *d,
if (md->moveOpacity != OPAQUE)
addWindowDamage (w);
+
+ return TRUE;
}
}
@@ -298,7 +429,7 @@ moveGetYConstrainRegion (CompScreen *s)
getWorkareaForOutput (s, i, &workArea);
extents = s->outputDev[i].region.extents;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (!w->mapNum)
continue;
@@ -534,12 +665,18 @@ moveHandleMotionEvent (CompScreen *s,
if (dx || dy)
{
+ Bool lazy = md->opt[MOVE_DISPLAY_OPTION_LAZY_POSITIONING].value.b;
+
moveWindow (w,
wX + dx - w->attrib.x,
wY + dy - w->attrib.y,
TRUE, FALSE);
- if (md->opt[MOVE_DISPLAY_OPTION_LAZY_POSITIONING].value.b)
+ /* lazy positioning cannot be used without manual compositing */
+ if (!manualCompositeManagement)
+ lazy = FALSE;
+
+ if (lazy)
{
/* FIXME: This form of lazy positioning is broken and should
be replaced asap. Current code exists just to avoid a
@@ -563,11 +700,85 @@ moveHandleEvent (CompDisplay *d,
XEvent *event)
{
CompScreen *s;
+ CompWindow *w;
MOVE_DISPLAY (d);
switch (event->type) {
case ButtonPress:
+ w = findClientWindowAtDisplay (d, event->xbutton.window);
+ if (w)
+ {
+ CompWindow *p;
+ int option = MOVE_DISPLAY_OPTION_INITIATE_BUTTON;
+ int x = event->xbutton.x_root;
+ int y = event->xbutton.y_root;
+
+ MOVE_WINDOW (w);
+
+ for (p = w; p; p = p->parent)
+ {
+ x -= p->attrib.x;
+ y -= p->attrib.y;
+ }
+
+ if (event->xbutton.button == mw->button &&
+ movePointInBoxes (x, y,
+ mw->box, mw->nBox,
+ w->width, w->height))
+ {
+ CompOption o[5];
+
+ o[0].type = CompOptionTypeInt;
+ o[0].name = "window";
+ o[0].value.i = w->id;
+
+ o[1].type = CompOptionTypeInt;
+ o[1].name = "modifiers";
+ o[1].value.i = event->xbutton.state;
+
+ o[2].type = CompOptionTypeInt;
+ o[2].name = "x";
+ o[2].value.i = event->xbutton.x_root;
+
+ o[3].type = CompOptionTypeInt;
+ o[3].name = "y";
+ o[3].value.i = event->xbutton.y_root;
+
+ o[4].type = CompOptionTypeInt;
+ o[4].name = "button";
+ o[4].value.i = event->xbutton.button;
+
+ if (moveInitiate (d,
+ &md->opt[option].value.action,
+ CompActionStateInitButton,
+ o, 5))
+ {
+ XEvent ev;
+ int mask = NoEventMask;
+
+ if (!w->parent->substructureRedirect)
+ activateWindow (w);
+
+ if (w->parent == &w->screen->root)
+ mask = SubstructureRedirectMask |
+ SubstructureNotifyMask;
+
+ ev.type = ClientMessage;
+ ev.xclient.window = event->xbutton.subwindow;
+ ev.xclient.message_type = md->moveNotifyAtom;
+ ev.xclient.format = 32;
+ ev.xclient.data.l[0] = event->xbutton.button;
+ ev.xclient.data.l[1] = event->xbutton.x;
+ ev.xclient.data.l[2] = event->xbutton.y;
+ ev.xclient.data.l[3] = event->xbutton.time;
+ ev.xclient.data.l[4] = 0;
+
+ XSendEvent (d->display, w->parent->id, FALSE, mask, &ev);
+ }
+ }
+ }
+ break;
case ButtonRelease:
s = findScreenAtDisplay (d, event->xbutton.root);
if (s)
@@ -626,8 +837,6 @@ moveHandleEvent (CompDisplay *d,
case ClientMessage:
if (event->xclient.message_type == d->wmMoveResizeAtom)
{
- CompWindow *w;
-
if (event->xclient.data.l[2] == WmMoveResizeMove ||
event->xclient.data.l[2] == WmMoveResizeMoveKeyboard)
{
@@ -658,7 +867,7 @@ moveHandleEvent (CompDisplay *d,
option = MOVE_DISPLAY_OPTION_INITIATE_BUTTON;
- XQueryPointer (d->display, w->screen->root,
+ XQueryPointer (d->display, w->screen->root.id,
&root, &child, &xRoot, &yRoot,
&i, &i, &mods);
@@ -709,6 +918,14 @@ moveHandleEvent (CompDisplay *d,
}
}
}
+ else if (event->xclient.message_type == md->moveNotifyAtom)
+ {
+ /* forward to owner */
+ XSendEvent (d->display,
+ event->xclient.window,
+ FALSE, NoEventMask,
+ event);
+ }
break;
case DestroyNotify:
if (md->w && md->w->id == event->xdestroywindow.window)
@@ -746,6 +963,18 @@ moveHandleEvent (CompDisplay *d,
UNWRAP (md, d, handleEvent);
(*d->handleEvent) (d, event);
WRAP (md, d, handleEvent, moveHandleEvent);
+
+ if (event->type == PropertyNotify)
+ {
+ if (event->xproperty.atom == md->moveAtom)
+ {
+ CompWindow *w;
+
+ w = findWindowAtDisplay (d, event->xproperty.window);
+ if (w)
+ moveWindowUpdate (w);
+ }
+ }
}
static Bool
@@ -876,6 +1105,13 @@ moveInitDisplay (CompPlugin *p,
md->key[i] = XKeysymToKeycode (d->display,
XStringToKeysym (mKeys[i].name));
+ md->moveAtom = XInternAtom (d->display,
+ "_COMPIZ_WM_WINDOW_MOVE_DECOR",
+ 0);
+ md->moveNotifyAtom = XInternAtom (d->display,
+ "_COMPIZ_WM_WINDOW_MOVE_DECOR_NOTIFY",
+ 0);
+
WRAP (md, d, handleEvent, moveHandleEvent);
d->base.privates[displayPrivateIndex].ptr = md;
@@ -910,6 +1146,13 @@ moveInitScreen (CompPlugin *p,
if (!ms)
return FALSE;
+ ms->windowPrivateIndex = allocateWindowPrivateIndex (s);
+ if (ms->windowPrivateIndex < 0)
+ {
+ free (ms);
+ return FALSE;
+ }
+
ms->grabIndex = 0;
ms->moveCursor = XCreateFontCursor (s->display->display, XC_fleur);
@@ -932,9 +1175,46 @@ moveFiniScreen (CompPlugin *p,
if (ms->moveCursor)
XFreeCursor (s->display->display, ms->moveCursor);
+ freeWindowPrivateIndex (s, ms->windowPrivateIndex);
+
free (ms);
}
+static Bool
+moveInitWindow (CompPlugin *p,
+ CompWindow *w)
+{
+ MoveWindow *mw;
+
+ MOVE_SCREEN (w->screen);
+
+ mw = malloc (sizeof (MoveWindow));
+ if (!mw)
+ return FALSE;
+
+ mw->button = 0;
+ mw->box = NULL;
+ mw->nBox = 0;
+
+ w->base.privates[ms->windowPrivateIndex].ptr = mw;
+
+ moveWindowUpdate (w);
+
+ return TRUE;
+}
+
+static void
+moveFiniWindow (CompPlugin *p,
+ CompWindow *w)
+{
+ MOVE_WINDOW (w);
+
+ if (mw->box)
+ free (mw->box);
+
+ free (mw);
+}
+
static CompBool
moveInitObject (CompPlugin *p,
CompObject *o)
@@ -942,7 +1222,8 @@ moveInitObject (CompPlugin *p,
static InitPluginObjectProc dispTab[] = {
(InitPluginObjectProc) 0, /* InitCore */
(InitPluginObjectProc) moveInitDisplay,
- (InitPluginObjectProc) moveInitScreen
+ (InitPluginObjectProc) moveInitScreen,
+ (InitPluginObjectProc) moveInitWindow
};
RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
@@ -955,7 +1236,8 @@ moveFiniObject (CompPlugin *p,
static FiniPluginObjectProc dispTab[] = {
(FiniPluginObjectProc) 0, /* FiniCore */
(FiniPluginObjectProc) moveFiniDisplay,
- (FiniPluginObjectProc) moveFiniScreen
+ (FiniPluginObjectProc) moveFiniScreen,
+ (FiniPluginObjectProc) moveFiniWindow
};
DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
diff --git a/plugins/obs.c b/plugins/obs.c
index bec8136..d526772 100644
--- a/plugins/obs.c
+++ b/plugins/obs.c
@@ -75,7 +75,6 @@ typedef struct _ObsScreen
int windowPrivateIndex;
PaintWindowProc paintWindow;
- DrawWindowProc drawWindow;
CompOption *stepOptions[MODIFIER_COUNT];
CompOption *matchOptions[MODIFIER_COUNT];
@@ -210,76 +209,32 @@ obsPaintWindow (CompWindow *w,
Region region,
unsigned int mask)
{
- CompScreen *s = w->screen;
- Bool status;
+ WindowPaintAttrib wAttrib = *attrib;
+ CompScreen *s = w->screen;
+ int factor;
+ Bool status;
OBS_SCREEN (s);
OBS_WINDOW (w);
- if (ow->customFactor[MODIFIER_OPACITY] != 100)
- mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
-
- UNWRAP (os, s, paintWindow);
- status = (*s->paintWindow) (w, attrib, transform, region, mask);
- WRAP (os, s, paintWindow, obsPaintWindow);
-
- return status;
-}
-
-/* Note: Normally plugins should wrap into PaintWindow to modify opacity,
- brightness and saturation. As some plugins bypass paintWindow when
- they draw windows and our custom values always need to be applied,
- we wrap into DrawWindow here */
-
-static Bool
-obsDrawWindow (CompWindow *w,
- const CompTransform *transform,
- const FragmentAttrib *attrib,
- Region region,
- unsigned int mask)
-{
- CompScreen *s = w->screen;
- Bool hasCustomFactor = FALSE;
- Bool status;
- int i;
-
- OBS_SCREEN (s);
- OBS_WINDOW (w);
-
- for (i = 0; i < MODIFIER_COUNT; i++)
- if (ow->customFactor[i] != 100)
- {
- hasCustomFactor = TRUE;
- break;
- }
-
- if (hasCustomFactor)
+ factor = ow->customFactor[MODIFIER_OPACITY];
+ if (factor != 100)
{
- FragmentAttrib fragment = *attrib;
- int factor;
-
- factor = ow->customFactor[MODIFIER_OPACITY];
- if (factor != 100)
- fragment.opacity = (int) fragment.opacity * factor / 100;
+ wAttrib.opacity = (int) wAttrib.opacity * factor / 100;
+ mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+ }
- factor = ow->customFactor[MODIFIER_BRIGHTNESS];
- if (factor != 100)
- fragment.brightness = (int) fragment.brightness * factor / 100;
+ factor = ow->customFactor[MODIFIER_BRIGHTNESS];
+ if (factor != 100)
+ wAttrib.brightness = (int) wAttrib.brightness * factor / 100;
- factor = ow->customFactor[MODIFIER_SATURATION];
- if (factor != 100)
- fragment.saturation = (int) fragment.saturation * factor / 100;
+ factor = ow->customFactor[MODIFIER_SATURATION];
+ if (factor != 100)
+ wAttrib.saturation = (int) wAttrib.saturation * factor / 100;
- UNWRAP (os, s, drawWindow);
- status = (*s->drawWindow) (w, transform, &fragment, region, mask);
- WRAP (os, s, drawWindow, obsDrawWindow);
- }
- else
- {
- UNWRAP (os, s, drawWindow);
- status = (*s->drawWindow) (w, transform, attrib, region, mask);
- WRAP (os, s, drawWindow, obsDrawWindow);
- }
+ UNWRAP (os, s, paintWindow);
+ status = (*s->paintWindow) (w, &wAttrib, transform, region, mask);
+ WRAP (os, s, paintWindow, obsPaintWindow);
return status;
}
@@ -299,7 +254,7 @@ obsMatchExpHandlerChanged (CompDisplay *d)
/* match options are up to date after the call to matchExpHandlerChanged */
for (s = d->screens; s; s = s->next)
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
for (i = 0; i < MODIFIER_COUNT; i++)
updatePaintModifier (w, i);
}
@@ -386,7 +341,7 @@ obsSetScreenOption (CompPlugin *p,
for (j = 0; j < o->value.list.nValue; j++)
matchUpdate (s->display, &o->value.list.value[j].match);
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
updatePaintModifier (w, i);
return TRUE;
@@ -398,7 +353,7 @@ obsSetScreenOption (CompPlugin *p,
{
CompWindow *w;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
updatePaintModifier (w, i);
return TRUE;
@@ -599,7 +554,6 @@ obsInitScreen (CompPlugin *p,
s->base.privates[od->screenPrivateIndex].ptr = os;
WRAP (os, s, paintWindow, obsPaintWindow);
- WRAP (os, s, drawWindow, obsDrawWindow);
return TRUE;
}
@@ -611,7 +565,6 @@ obsFiniScreen (CompPlugin *p,
OBS_SCREEN (s);
UNWRAP (os, s, paintWindow);
- UNWRAP (os, s, drawWindow);
damageScreen (s);
diff --git a/plugins/place.c b/plugins/place.c
index 596a3a5..6c9a8e4 100644
--- a/plugins/place.c
+++ b/plugins/place.c
@@ -257,7 +257,7 @@ placeSendWindowMaximizationRequest (CompWindow *w)
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
- XSendEvent (d->display, w->screen->root, FALSE,
+ XSendEvent (d->display, w->screen->root.id, FALSE,
SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
@@ -681,7 +681,7 @@ placeCascade (CompWindow *w,
unsigned int count = 0;
/* get the total window count */
- for (wi = w->screen->windows; wi; wi = wi->next)
+ for (wi = w->screen->root.windows; wi; wi = wi->next)
count++;
windows = malloc (sizeof (CompWindow *) * count);
@@ -692,7 +692,7 @@ placeCascade (CompWindow *w,
* as placed window, may be shaded - if shaded we pretend it isn't
* for placement purposes)
*/
- for (wi = w->screen->windows, count = 0; wi; wi = wi->next)
+ for (wi = w->screen->root.windows, count = 0; wi; wi = wi->next)
{
if (!IS_PLACE_RELEVANT (wi, w))
continue;
@@ -813,7 +813,7 @@ placeSmart (CompWindow *w,
cyt = yTmp;
cyb = yTmp + ch;
- for (wi = w->screen->windows; wi; wi = wi->next)
+ for (wi = w->screen->root.windows; wi; wi = wi->next)
{
if (!IS_PLACE_RELEVANT (wi, w))
continue;
@@ -871,7 +871,7 @@ placeSmart (CompWindow *w,
possible -= cw;
/* compare to the position of each client on the same desk */
- for (wi = w->screen->windows; wi; wi = wi->next)
+ for (wi = w->screen->root.windows; wi; wi = wi->next)
{
if (!IS_PLACE_RELEVANT (wi, w))
continue;
@@ -906,7 +906,7 @@ placeSmart (CompWindow *w,
possible -= ch;
/* test the position of each window on the desk */
- for (wi = w->screen->windows; wi; wi = wi->next)
+ for (wi = w->screen->root.windows; wi; wi = wi->next)
{
if (!IS_PLACE_RELEVANT (wi, w))
continue;
@@ -1016,7 +1016,7 @@ placeGetPlacementOutput (CompWindow *w,
{
CompWindow *parent;
- parent = findWindowAtScreen (s, w->transientFor);
+ parent = findSibling (w, w->transientFor);
if (parent)
output = outputDeviceForWindow (parent);
}
@@ -1047,7 +1047,7 @@ placeGetPlacementOutput (CompWindow *w,
/* this means a server roundtrip, which kind of sucks; thus
this code should be replaced as soon as we have software
cursor rendering and thus have a cached pointer coordinate */
- if (XQueryPointer (s->display->display, s->root,
+ if (XQueryPointer (s->display->display, s->root.id,
&wDummy, &wDummy, &xPointer, &yPointer,
&iDummy, &iDummy, &uiDummy))
{
@@ -1085,21 +1085,31 @@ placeConstrainToWorkarea (CompWindow *w,
int *y)
{
CompWindowExtents extents;
+ int delta;
extents.left = *x - w->input.left;
extents.top = *y - w->input.top;
extents.right = *x + w->serverWidth + w->input.right;
extents.bottom = *y + w->serverHeight + w->input.bottom;
- if (extents.left < workArea->x)
- *x += workArea->x - extents.left;
- else if (extents.right > workArea->x + workArea->width)
- *x += workArea->x + workArea->width - extents.right;
+ delta = workArea->x + workArea->width - extents.right;
+ if (delta < 0)
+ extents.left += delta;
- if (extents.top < workArea->y)
- *y += workArea->y - extents.top;
- else if (extents.bottom > workArea->y + workArea->height)
- *y += workArea->y + workArea->height - extents.bottom;
+ delta = workArea->x - extents.left;
+ if (delta > 0)
+ extents.left += delta;
+
+ delta = workArea->y + workArea->height - extents.bottom;
+ if (delta < 0)
+ extents.top += delta;
+
+ delta = workArea->y - extents.top;
+ if (delta > 0)
+ extents.top += delta;
+
+ *x = extents.left + w->input.left;
+ *y = extents.top + w->input.top;
}
static Bool
@@ -1138,7 +1148,7 @@ placeDoWindowPlacement (CompWindow *w,
{
CompWindow *parent;
- parent = findWindowAtScreen (s, w->transientFor);
+ parent = findSibling (w, w->transientFor);
if (parent)
{
/* center over parent horizontally */
@@ -1443,7 +1453,8 @@ placeInitDisplay (CompPlugin *p,
{
PlaceDisplay *pd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("wm", CORE_ABIVERSION))
return FALSE;
pd = malloc (sizeof (PlaceDisplay));
diff --git a/plugins/resize.c b/plugins/resize.c
index 5b8b12b..d2de79b 100644
--- a/plugins/resize.c
+++ b/plugins/resize.c
@@ -269,7 +269,7 @@ resizeSendResizeNotify (CompDisplay *d)
xev.xclient.data.l[4] = 0;
XSendEvent (d->display,
- rd->w->screen->root,
+ rd->w->screen->root.id,
FALSE,
SubstructureRedirectMask | SubstructureNotifyMask,
&xev);
@@ -438,6 +438,10 @@ resizeInitiate (CompDisplay *d,
}
}
+ /* only normal resize mode can be used without manual compositing */
+ if (!manualCompositeManagement)
+ rd->mode = RESIZE_MODE_NORMAL;
+
if (!rs->grabIndex)
{
Cursor cursor;
@@ -900,7 +904,7 @@ resizeHandleEvent (CompDisplay *d,
option = RESIZE_DISPLAY_OPTION_INITIATE_BUTTON;
- XQueryPointer (d->display, w->screen->root,
+ XQueryPointer (d->display, w->screen->root.id,
&root, &child, &xRoot, &yRoot,
&i, &i, &mods);
diff --git a/plugins/rotate.c b/plugins/rotate.c
index 8b76d4d..1369d62 100644
--- a/plugins/rotate.c
+++ b/plugins/rotate.c
@@ -368,7 +368,37 @@ rotatePreparePaintScreen (CompScreen *s,
/* flag end of rotation */
cs->rotationState = RotationNone;
- moveScreenViewport (s, tx, 0, TRUE);
+ if (s->root.substructureRedirect)
+ {
+ moveScreenViewport (s, tx, 0, TRUE);
+ }
+ else
+ {
+ CompDisplay *d = s->display;
+ XEvent xev;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = d->display;
+ xev.xclient.format = 32;
+
+ xev.xclient.message_type = d->desktopViewportAtom;
+ xev.xclient.window = s->root.id;
+
+ xev.xclient.data.l[0] = (s->x - tx) * s->width;
+ xev.xclient.data.l[1] = s->y * s->height;
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (s->display->display,
+ s->root.id,
+ FALSE,
+ SubstructureRedirectMask |
+ SubstructureNotifyMask,
+ &xev);
+
+ moveScreenViewport (s, tx, 0, FALSE);
+ }
rs->xrot = 0.0f;
rs->yrot = 0.0f;
@@ -680,7 +710,7 @@ rotateTerminate (CompDisplay *d,
{
ROTATE_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (rs->grabIndex)
@@ -750,7 +780,7 @@ rotate (CompDisplay *d,
o[2].type = CompOptionTypeInt;
o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].value.i = s->root.id;
rotateInitiate (d, NULL, 0, o, 3);
}
@@ -839,7 +869,7 @@ rotateWithWindow (CompDisplay *d,
o[2].type = CompOptionTypeInt;
o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].value.i = s->root.id;
rotateInitiate (d, NULL, 0, o, 3);
}
@@ -1014,7 +1044,7 @@ rotateFlipLeft (void *closure)
o[2].type = CompOptionTypeInt;
o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].value.i = s->root.id;
o[3].type = CompOptionTypeInt;
o[3].name = "direction";
@@ -1059,7 +1089,7 @@ rotateFlipRight (void *closure)
o[2].type = CompOptionTypeInt;
o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].value.i = s->root.id;
o[3].type = CompOptionTypeInt;
o[3].name = "direction";
@@ -1139,7 +1169,7 @@ rotateEdgeFlip (CompScreen *s,
o[2].type = CompOptionTypeInt;
o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].value.i = s->root.id;
o[3].type = CompOptionTypeInt;
o[3].name = "direction";
@@ -1256,7 +1286,7 @@ rotateFlipTerminate (CompDisplay *d,
{
ROTATE_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (rs->rotateHandle)
@@ -1383,7 +1413,7 @@ rotateTo (CompDisplay *d,
o[2].type = CompOptionTypeInt;
o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].value.i = s->root.id;
o[3].type = CompOptionTypeInt;
o[3].name = "direction";
@@ -1443,7 +1473,7 @@ rotateToWithWindow (CompDisplay *d,
o[2].type = CompOptionTypeInt;
o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].value.i = s->root.id;
o[3].type = CompOptionTypeInt;
o[3].name = "direction";
@@ -1464,6 +1494,7 @@ rotateHandleEvent (CompDisplay *d,
XEvent *event)
{
CompScreen *s;
+ int dx = 0;
ROTATE_DISPLAY (d);
@@ -1512,13 +1543,14 @@ rotateHandleEvent (CompDisplay *d,
}
break;
case ClientMessage:
+ if (!windowManagement)
+ break;
+
if (event->xclient.message_type == d->desktopViewportAtom)
{
s = findScreenAtDisplay (d, event->xclient.window);
if (s)
{
- int dx;
-
ROTATE_SCREEN (s);
if (otherScreenGrabExist (s, "rotate", "switcher", "cube", 0))
@@ -1535,7 +1567,7 @@ rotateHandleEvent (CompDisplay *d,
unsigned int ui;
CompOption o[4];
- XQueryPointer (d->display, s->root,
+ XQueryPointer (d->display, s->root.id,
&win, &win, &x, &y, &i, &i, &ui);
if (dx * 2 > s->hsize)
@@ -1553,7 +1585,7 @@ rotateHandleEvent (CompDisplay *d,
o[2].type = CompOptionTypeInt;
o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].value.i = s->root.id;
o[3].type = CompOptionTypeInt;
o[3].name = "direction";
@@ -1570,6 +1602,29 @@ rotateHandleEvent (CompDisplay *d,
UNWRAP (rd, d, handleEvent);
(*d->handleEvent) (d, event);
WRAP (rd, d, handleEvent, rotateHandleEvent);
+
+ switch (event->type) {
+ case ClientMessage:
+ if (!dx)
+ break;
+
+ if (event->xclient.message_type == d->desktopViewportAtom)
+ {
+ s = findScreenAtDisplay (d, event->xclient.window);
+ if (s)
+ {
+ ROTATE_SCREEN (s);
+
+ if (rs->moving)
+ {
+ rs->moveTo += (360.0f / s->hsize) * -dx;
+ rs->baseXrot += (360.0f / s->hsize) * dx;
+ }
+ }
+ }
+ default:
+ break;
+ }
}
static void
@@ -1596,7 +1651,7 @@ rotateActivateWindow (CompWindow *w)
unsigned int ui;
CompOption o[5];
- XQueryPointer (s->display->display, s->root,
+ XQueryPointer (s->display->display, s->root.id,
&win, &win, &x, &y, &i, &i, &ui);
if (dx * 2 > s->hsize)
@@ -1614,7 +1669,7 @@ rotateActivateWindow (CompWindow *w)
o[2].type = CompOptionTypeInt;
o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].value.i = s->root.id;
o[3].type = CompOptionTypeInt;
o[3].name = "direction";
diff --git a/plugins/scale.c b/plugins/scale.c
index 5b4df25..7046b17 100644
--- a/plugins/scale.c
+++ b/plugins/scale.c
@@ -151,7 +151,7 @@ scaleActivateEvent (CompScreen *s,
o[0].type = CompOptionTypeInt;
o[0].name = "root";
- o[0].value.i = s->root;
+ o[0].value.i = s->root.id;
o[1].type = CompOptionTypeBool;
o[1].name = "active";
@@ -313,6 +313,9 @@ setScaledPaintAttributes (CompWindow *w,
SCALE_SCREEN (w->screen);
SCALE_WINDOW (w);
+ if (w->parent != &w->screen->root)
+ return FALSE;
+
if (sw->adjust || sw->slot)
{
SCALE_DISPLAY (w->screen->display);
@@ -379,7 +382,12 @@ scalePaintWindow (CompWindow *w,
scaled = (*ss->setScaledPaintAttributes) (w, &sAttrib);
if (sw->adjust || sw->slot)
+ {
+ if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
+ return FALSE;
+
mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
+ }
UNWRAP (ss, s, paintWindow);
status = (*s->paintWindow) (w, &sAttrib, transform, region, mask);
@@ -387,16 +395,7 @@ scalePaintWindow (CompWindow *w,
if (scaled)
{
- FragmentAttrib fragment;
- CompTransform wTransform = *transform;
-
- if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
- return FALSE;
-
- initFragmentAttrib (&fragment, &w->lastPaint);
-
- if (w->alpha || fragment.opacity != OPAQUE)
- mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+ CompTransform wTransform = *transform;
matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f);
matrixScale (&wTransform, sw->scale, sw->scale, 1.0f);
@@ -405,13 +404,7 @@ scalePaintWindow (CompWindow *w,
sw->ty / sw->scale - w->attrib.y,
0.0f);
- glPushMatrix ();
- glLoadMatrixf (wTransform.m);
-
- (*s->drawWindow) (w, &wTransform, &fragment, region,
- mask | PAINT_WINDOW_TRANSFORMED_MASK);
-
- glPopMatrix ();
+ drawTransformedWindowWithChildren (w, NULL, &wTransform);
(*ss->scalePaintDecoration) (w, &sAttrib, transform, region, mask);
}
@@ -742,7 +735,7 @@ layoutThumbs (CompScreen *s)
ss->nWindows = 0;
/* add windows scale list, top most window first */
- for (w = s->reverseWindows; w; w = w->prev)
+ for (w = s->root.reverseWindows; w; w = w->prev)
{
SCALE_WINDOW (w);
@@ -897,7 +890,7 @@ scalePreparePaintScreen (CompScreen *s,
{
ss->moreAdjust = 0;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
SCALE_WINDOW (w);
@@ -962,7 +955,7 @@ scaleCheckForWindowAt (CompScreen *s,
int x1, y1, x2, y2;
CompWindow *w;
- for (w = s->reverseWindows; w; w = w->prev)
+ for (w = s->root.reverseWindows; w; w = w->prev)
{
SCALE_WINDOW (w);
@@ -1028,7 +1021,7 @@ scaleTerminate (CompDisplay *d,
{
SCALE_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (ss->grab)
@@ -1048,7 +1041,7 @@ scaleTerminate (CompDisplay *d,
{
CompWindow *w;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
SCALE_WINDOW (w);
@@ -1102,7 +1095,7 @@ scaleEnsureDndRedirectWindow (CompScreen *s)
attr.override_redirect = TRUE;
ss->dndTarget = XCreateWindow (s->display->display,
- s->root,
+ s->root.id,
0, 0, 1, 1, 0,
CopyFromParent,
InputOnly,
@@ -1420,7 +1413,7 @@ scaleMoveFocusWindow (CompScreen *s,
cx = (sw->slot->x1 + sw->slot->x2) / 2;
cy = (sw->slot->y1 + sw->slot->y2) / 2;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
slot = GET_SCALE_WINDOW (w, ss)->slot;
if (!slot)
@@ -1453,7 +1446,7 @@ scaleMoveFocusWindow (CompScreen *s,
SCALE_SCREEN (s);
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (!GET_SCALE_WINDOW (w, ss)->slot)
continue;
@@ -1548,7 +1541,7 @@ scaleWindowRemove (CompDisplay *d,
o.type = CompOptionTypeInt;
o.name = "root";
- o.value.i = w->screen->root;
+ o.value.i = w->screen->root.id;
opt = SCALE_DISPLAY_OPTION_INITIATE_EDGE;
action = &sd->opt[opt].value.action;
@@ -1592,7 +1585,7 @@ scaleHoverTimeout (void *closure)
o.type = CompOptionTypeInt;
o.name = "root";
- o.value.i = s->root;
+ o.value.i = s->root.id;
option = SCALE_DISPLAY_OPTION_INITIATE_EDGE;
scaleTerminate (s->display, &sd->opt[option].value.action, 0, &o, 1);
@@ -1649,7 +1642,7 @@ scaleHandleEvent (CompDisplay *d,
o.type = CompOptionTypeInt;
o.name = "root";
- o.value.i = s->root;
+ o.value.i = s->root.id;
if (scaleSelectWindowAt (s,
event->xbutton.x_root,
@@ -1788,7 +1781,7 @@ scaleHandleEvent (CompDisplay *d,
o.type = CompOptionTypeInt;
o.name = "root";
- o.value.i = w->screen->root;
+ o.value.i = w->screen->root.id;
option = SCALE_DISPLAY_OPTION_INITIATE_EDGE;
scaleTerminate (d, &sd->opt[option].value.action,
@@ -1926,7 +1919,8 @@ scaleInitDisplay (CompPlugin *p,
{
ScaleDisplay *sd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
sd = malloc (sizeof (ScaleDisplay));
diff --git a/plugins/screenshot.c b/plugins/screenshot.c
index 74f44ba..899b2f0 100644
--- a/plugins/screenshot.c
+++ b/plugins/screenshot.c
@@ -122,7 +122,7 @@ shotTerminate (CompDisplay *d,
{
SHOT_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (ss->grabIndex)
@@ -436,7 +436,8 @@ shotInitDisplay (CompPlugin *p,
{
ShotDisplay *sd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
sd = malloc (sizeof (ShotDisplay));
diff --git a/plugins/svg.c b/plugins/svg.c
index bd39174..0ebebbf 100644
--- a/plugins/svg.c
+++ b/plugins/svg.c
@@ -178,7 +178,7 @@ initSvgTexture (CompWindow *w,
XGetWindowAttributes (s->display->display, w->id, &attr);
depth = attr.depth;
- texture->pixmap = XCreatePixmap (s->display->display, s->root,
+ texture->pixmap = XCreatePixmap (s->display->display, s->root.id,
width, height, depth);
if (!bindPixmapToTexture (s,
@@ -795,7 +795,8 @@ svgInitDisplay (CompPlugin *p,
SvgDisplay *sd;
CompScreen *s;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
sd = malloc (sizeof (SvgDisplay));
diff --git a/plugins/switcher.c b/plugins/switcher.c
index 13be8ad..b0acfec 100644
--- a/plugins/switcher.c
+++ b/plugins/switcher.c
@@ -328,7 +328,7 @@ switchActivateEvent (CompScreen *s,
o[0].type = CompOptionTypeInt;
o[0].name = "root";
- o[0].value.i = s->root;
+ o[0].value.i = s->root.id;
o[1].type = CompOptionTypeBool;
o[1].name = "active";
@@ -415,7 +415,7 @@ switchCreateWindowList (CompScreen *s,
ss->nWindows = 0;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (isSwitchWin (w))
switchAddWindowToList (s, w);
@@ -475,7 +475,7 @@ switchToWindow (CompScreen *s,
xev.xclient.format = 32;
xev.xclient.message_type = s->display->desktopViewportAtom;
- xev.xclient.window = s->root;
+ xev.xclient.window = s->root.id;
xev.xclient.data.l[0] = x * s->width;
xev.xclient.data.l[1] = y * s->height;
@@ -483,7 +483,7 @@ switchToWindow (CompScreen *s,
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
- XSendEvent (s->display->display, s->root, FALSE,
+ XSendEvent (s->display->display, s->root.id, FALSE,
SubstructureRedirectMask | SubstructureNotifyMask,
&xev);
}
@@ -532,7 +532,7 @@ switchCountWindows (CompScreen *s)
CompWindow *w;
int count = 0;
- for (w = s->windows; w && count < 5; w = w->next)
+ for (w = s->root.windows; w && count < 5; w = w->next)
if (isSwitchWin (w))
count++;
@@ -600,7 +600,7 @@ switchInitiate (CompScreen *s,
if (count < 1)
return;
- if (!ss->popupWindow && showPopup)
+ if (!ss->popupWindow && showPopup && s->root.substructureRedirect)
{
Display *dpy = s->display->display;
XSizeHints xsh;
@@ -635,11 +635,11 @@ switchInitiate (CompScreen *s,
attr.background_pixel = 0;
attr.border_pixel = 0;
- attr.colormap = XCreateColormap (dpy, s->root, visual,
+ attr.colormap = XCreateColormap (dpy, s->root.id, visual,
AllocNone);
ss->popupWindow =
- XCreateWindow (dpy, s->root,
+ XCreateWindow (dpy, s->root.id,
s->width / 2 - xsh.width / 2,
s->height / 2 - xsh.height / 2,
xsh.width, xsh.height, 0,
@@ -727,7 +727,7 @@ switchTerminate (CompDisplay *d,
{
SWITCH_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (ss->grabIndex)
@@ -989,7 +989,7 @@ switchWindowRemove (CompDisplay *d,
o.type = CompOptionTypeInt;
o.name = "root";
- o.value.i = w->screen->root;
+ o.value.i = w->screen->root.id;
switchTerminate (d, NULL, 0, &o, 1);
return;
@@ -1322,8 +1322,9 @@ switchPaintOutput (CompScreen *s,
for (w = zoomed->prev; w && w->id <= 1; w = w->prev);
zoomedAbove = (w) ? w->id : None;
- unhookWindowFromScreen (s, zoomed);
- insertWindowIntoScreen (s, zoomed, s->reverseWindows->id);
+ unhookWindow (zoomed->parent, zoomed);
+ insertWindow (zoomed->parent, zoomed,
+ zoomed->parent->reverseWindows->id);
}
}
else
@@ -1356,8 +1357,8 @@ switchPaintOutput (CompScreen *s,
if (zoomed)
{
- unhookWindowFromScreen (s, zoomed);
- insertWindowIntoScreen (s, zoomed, zoomedAbove);
+ unhookWindow (zoomed->parent, zoomed);
+ insertWindow (zoomed->parent, zoomed, zoomedAbove);
}
if (switcher)
@@ -1445,7 +1446,6 @@ switchPaintThumb (CompWindow *w,
if (w->texture->pixmap)
{
AddWindowGeometryProc oldAddWindowGeometry;
- FragmentAttrib fragment;
CompTransform wTransform = *transform;
int ww, wh;
@@ -1481,11 +1481,6 @@ switchPaintThumb (CompWindow *w,
sAttrib.xTranslate = wx - w->attrib.x + w->input.left * sAttrib.xScale;
sAttrib.yTranslate = wy - w->attrib.y + w->input.top * sAttrib.yScale;
- initFragmentAttrib (&fragment, &sAttrib);
-
- if (w->alpha || fragment.opacity != OPAQUE)
- mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
-
matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f);
matrixScale (&wTransform, sAttrib.xScale, sAttrib.yScale, 1.0f);
matrixTranslate (&wTransform,
@@ -1493,20 +1488,14 @@ switchPaintThumb (CompWindow *w,
sAttrib.yTranslate / sAttrib.yScale - w->attrib.y,
0.0f);
- glPushMatrix ();
- glLoadMatrixf (wTransform.m);
-
/* XXX: replacing the addWindowGeometry function like this is
very ugly but necessary until the vertex stage has been made
fully pluggable. */
oldAddWindowGeometry = w->screen->addWindowGeometry;
w->screen->addWindowGeometry = addWindowGeometry;
- (w->screen->drawWindow) (w, &wTransform, &fragment, &infiniteRegion,
- mask);
+ drawTransformedWindowWithChildren (w, &sAttrib, &wTransform);
w->screen->addWindowGeometry = oldAddWindowGeometry;
- glPopMatrix ();
-
if (ss->opt[SWITCH_SCREEN_OPTION_ICON].value.b)
{
icon = getWindowIcon (w, ICON_SIZE, ICON_SIZE);
@@ -1634,6 +1623,12 @@ switchPaintWindow (CompWindow *w,
status = (*s->paintWindow) (w, attrib, transform, region, mask);
WRAP (ss, s, paintWindow, switchPaintWindow);
+ if (w->attrib.map_state != IsViewable)
+ return status;
+
+ if (!w->damaged)
+ return status;
+
if (!(mask & PAINT_WINDOW_TRANSFORMED_MASK) && region->numRects == 0)
return TRUE;
@@ -1708,44 +1703,53 @@ switchPaintWindow (CompWindow *w,
status = (*s->paintWindow) (w, attrib, transform, region, mask);
WRAP (ss, s, paintWindow, switchPaintWindow);
}
- else if (ss->switching)
+ else if (w->parent == &s->root)
{
- WindowPaintAttrib sAttrib = *attrib;
- GLuint value;
-
- value = ss->opt[SWITCH_SCREEN_OPTION_SATURATION].value.i;
- if (value != 100)
- sAttrib.saturation = sAttrib.saturation * value / 100;
+ if (ss->switching)
+ {
+ WindowPaintAttrib sAttrib = *attrib;
+ GLuint value;
- value = ss->opt[SWITCH_SCREEN_OPTION_BRIGHTNESS].value.i;
- if (value != 100)
- sAttrib.brightness = sAttrib.brightness * value / 100;
+ value = ss->opt[SWITCH_SCREEN_OPTION_SATURATION].value.i;
+ if (value != 100)
+ sAttrib.saturation = sAttrib.saturation * value / 100;
- if (w->wmType & ~(CompWindowTypeDockMask | CompWindowTypeDesktopMask))
- {
- value = ss->opt[SWITCH_SCREEN_OPTION_OPACITY].value.i;
+ value = ss->opt[SWITCH_SCREEN_OPTION_BRIGHTNESS].value.i;
if (value != 100)
- sAttrib.opacity = sAttrib.opacity * value / 100;
- }
+ sAttrib.brightness = sAttrib.brightness * value / 100;
- if (ss->opt[SWITCH_SCREEN_OPTION_BRINGTOFRONT].value.b &&
- w->id == ss->zoomedWindow)
- zoomType = ZOOMED_WINDOW_MASK;
+ if (w->wmType & ~(CompWindowTypeDockMask | CompWindowTypeDesktopMask))
+ {
+ value = ss->opt[SWITCH_SCREEN_OPTION_OPACITY].value.i;
+ if (value != 100)
+ sAttrib.opacity = sAttrib.opacity * value / 100;
+ }
- if (!(ss->zoomMask & zoomType))
- return (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) ?
- FALSE : TRUE;
+ if (ss->opt[SWITCH_SCREEN_OPTION_BRINGTOFRONT].value.b &&
+ w->id == ss->zoomedWindow)
+ zoomType = ZOOMED_WINDOW_MASK;
- UNWRAP (ss, s, paintWindow);
- status = (*s->paintWindow) (w, &sAttrib, transform, region, mask);
- WRAP (ss, s, paintWindow, switchPaintWindow);
+ if (!(ss->zoomMask & zoomType))
+ return (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) ?
+ FALSE : TRUE;
+
+ UNWRAP (ss, s, paintWindow);
+ status = (*s->paintWindow) (w, &sAttrib, transform, region, mask);
+ WRAP (ss, s, paintWindow, switchPaintWindow);
+ }
+ else
+ {
+ if (!(ss->zoomMask & zoomType))
+ return (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) ?
+ FALSE : TRUE;
+
+ UNWRAP (ss, s, paintWindow);
+ status = (*s->paintWindow) (w, attrib, transform, region, mask);
+ WRAP (ss, s, paintWindow, switchPaintWindow);
+ }
}
else
{
- if (!(ss->zoomMask & zoomType))
- return (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) ?
- FALSE : TRUE;
-
UNWRAP (ss, s, paintWindow);
status = (*s->paintWindow) (w, attrib, transform, region, mask);
WRAP (ss, s, paintWindow, switchPaintWindow);
@@ -1843,7 +1847,8 @@ switchInitDisplay (CompPlugin *p,
{
SwitchDisplay *sd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
sd = malloc (sizeof (SwitchDisplay));
diff --git a/plugins/video.c b/plugins/video.c
index b95eb6b..6364e08 100644
--- a/plugins/video.c
+++ b/plugins/video.c
@@ -190,7 +190,7 @@ videoSetSupportedHint (CompScreen *s)
data[n++] = vd->videoImageFormatAtom[i];
}
- XChangeProperty (s->display->display, s->root,
+ XChangeProperty (s->display->display, s->root.id,
vd->videoSupportedAtom, XA_ATOM, 32,
PropModeReplace, (unsigned char *) data, n);
}
@@ -939,7 +939,7 @@ videoHandleEvent (CompDisplay *d,
{
vs = GET_VIDEO_SCREEN (s, vd);
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (w->shaded || w->mapNum)
{
@@ -1045,7 +1045,8 @@ videoInitDisplay (CompPlugin *p,
{
VideoDisplay *vd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
vd = malloc (sizeof (VideoDisplay));
@@ -1164,7 +1165,7 @@ videoFiniScreen (CompPlugin *p,
freeWindowPrivateIndex (s, vs->windowPrivateIndex);
- XDeleteProperty (s->display->display, s->root, vd->videoSupportedAtom);
+ XDeleteProperty (s->display->display, s->root.id, vd->videoSupportedAtom);
videoDestroyFragmentFunctions (s, &vs->yv12Functions);
diff --git a/plugins/water.c b/plugins/water.c
index ef2f191..485060d 100644
--- a/plugins/water.c
+++ b/plugins/water.c
@@ -1040,6 +1040,7 @@ waterDrawWindowTexture (CompWindow *w,
Bool lighting = w->screen->lighting;
int param, function, unit;
GLfloat plane[4];
+ CompWindow *p;
WATER_DISPLAY (w->screen->display);
@@ -1049,6 +1050,17 @@ waterDrawWindowTexture (CompWindow *w,
function = getBumpMapFragmentFunction (w->screen, texture, unit, param);
if (function)
{
+ float dx = ws->tx / (GLfloat) w->screen->width;
+ float dy = ws->ty / (GLfloat) w->screen->height;
+ int wx = 0;
+ int wy = 0;
+
+ for (p = w->parent; p; p = p->parent)
+ {
+ wx += p->attrib.x;
+ wy += p->attrib.y;
+ }
+
addFragmentFunction (&fa, function);
screenLighting (w->screen, TRUE);
@@ -1058,16 +1070,16 @@ waterDrawWindowTexture (CompWindow *w,
glBindTexture (ws->target, ws->texture[TINDEX (ws, 0)]);
plane[1] = plane[2] = 0.0f;
- plane[0] = ws->tx / (GLfloat) w->screen->width;
- plane[3] = 0.0f;
+ plane[0] = dx;
+ plane[3] = dx * wx;
glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv (GL_S, GL_EYE_PLANE, plane);
glEnable (GL_TEXTURE_GEN_S);
plane[0] = plane[2] = 0.0f;
- plane[1] = ws->ty / (GLfloat) w->screen->height;
- plane[3] = 0.0f;
+ plane[1] = dy;
+ plane[3] = dy * wy;
glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv (GL_T, GL_EYE_PLANE, plane);
@@ -1268,7 +1280,8 @@ waterInitiate (CompDisplay *d,
if (!ws->grabIndex)
ws->grabIndex = pushScreenGrab (s, None, "water");
- if (XQueryPointer (d->display, s->root, &root, &child, &xRoot, &yRoot,
+ if (XQueryPointer (d->display, s->root.id, &root, &child,
+ &xRoot, &yRoot,
&i, &i, &ui))
{
XPoint p;
@@ -1594,7 +1607,8 @@ waterInitDisplay (CompPlugin *p,
{
WaterDisplay *wd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
wd = malloc (sizeof (WaterDisplay));
diff --git a/plugins/wm.c b/plugins/wm.c
new file mode 100644
index 0000000..e797c36
--- /dev/null
+++ b/plugins/wm.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright © 2008 Novell, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Novell, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * Novell, Inc. makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#include <compiz-core.h>
+
+static CompMetadata wmMetadata;
+
+static CompOption *
+wmGetDisplayOptions (CompPlugin *plugin,
+ CompDisplay *display,
+ int *count)
+{
+ *count = 1;
+ return &display->opt[COMP_DISPLAY_OPTION_ABI];
+}
+
+static Bool
+wmInitDisplay (CompPlugin *p,
+ CompDisplay *d)
+{
+ if (!checkPluginABI ("core", CORE_ABIVERSION))
+ return FALSE;
+
+ if (windowManagement)
+ return TRUE;
+
+ if (d->screens)
+ {
+ compLogMessage (p->vTable->name, CompLogLevelError,
+ "%s plugin must be loaded before screens are "
+ "initialize", p->vTable->name);
+ return FALSE;
+ }
+
+ windowManagement = TRUE;
+
+ return TRUE;
+}
+
+static CompBool
+wmInitObject (CompPlugin *p,
+ CompObject *o)
+{
+ static InitPluginObjectProc dispTab[] = {
+ (InitPluginObjectProc) 0, /* InitCore */
+ (InitPluginObjectProc) wmInitDisplay
+ };
+
+ RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
+}
+
+static CompOption *
+wmGetObjectOptions (CompPlugin *plugin,
+ CompObject *object,
+ int *count)
+{
+ static GetPluginObjectOptionsProc dispTab[] = {
+ (GetPluginObjectOptionsProc) 0, /* GetCoreOptions */
+ (GetPluginObjectOptionsProc) wmGetDisplayOptions
+ };
+
+ RETURN_DISPATCH (object, dispTab, ARRAY_SIZE (dispTab),
+ (void *) (*count = 0), (plugin, object, count));
+}
+
+static Bool
+wmInit (CompPlugin *p)
+{
+ if (!compInitPluginMetadataFromInfo (&wmMetadata, p->vTable->name,
+ 0, 0, 0, 0))
+ return FALSE;
+
+ compAddMetadataFromFile (&wmMetadata, p->vTable->name);
+
+ return TRUE;
+}
+
+static void
+wmFini (CompPlugin *p)
+{
+ compFiniMetadata (&wmMetadata);
+}
+
+static CompMetadata *
+wmGetMetadata (CompPlugin *plugin)
+{
+ return &wmMetadata;
+}
+
+CompPluginVTable wmVTable = {
+ "wm",
+ wmGetMetadata,
+ wmInit,
+ wmFini,
+ wmInitObject,
+ 0, /* FiniObject */
+ wmGetObjectOptions,
+ 0 /* SetObjectOption */
+};
+
+CompPluginVTable *
+getCompPluginInfo20070830 (void)
+{
+ return &wmVTable;
+}
diff --git a/plugins/wobbly.c b/plugins/wobbly.c
index d05c983..1beacb0 100644
--- a/plugins/wobbly.c
+++ b/plugins/wobbly.c
@@ -161,6 +161,12 @@ typedef struct _WobblyScreen {
unsigned int grabMask;
CompWindow *grabWindow;
Bool moveWindow;
+
+ Model *model;
+ int x;
+ int y;
+ float width;
+ float height;
} WobblyScreen;
#define WobblyInitial (1L << 0)
@@ -270,7 +276,7 @@ findNextWestEdge (CompWindow *w,
v1 = w->screen->outputDev[output].region.extents.x1;
- for (p = w->screen->windows; p; p = p->next)
+ for (p = w->parent->windows; p; p = p->next)
{
if (w == p)
continue;
@@ -375,7 +381,7 @@ findNextEastEdge (CompWindow *w,
v1 = w->screen->outputDev[output].region.extents.x2;
- for (p = w->screen->windows; p; p = p->next)
+ for (p = w->parent->windows; p; p = p->next)
{
if (w == p)
continue;
@@ -480,7 +486,7 @@ findNextNorthEdge (CompWindow *w,
v1 = w->screen->outputDev[output].region.extents.y1;
- for (p = w->screen->windows; p; p = p->next)
+ for (p = w->parent->windows; p; p = p->next)
{
if (w == p)
continue;
@@ -583,7 +589,7 @@ findNextSouthEdge (CompWindow *w,
v1 = w->screen->outputDev[output].region.extents.y2;
- for (p = w->screen->windows; p; p = p->next)
+ for (p = w->parent->windows; p; p = p->next)
{
if (w == p)
continue;
@@ -1656,7 +1662,8 @@ wobblyPreparePaintScreen (CompScreen *s,
springK = ws->opt[WOBBLY_SCREEN_OPTION_SPRING_K].value.f;
ws->wobblyWindows = 0;
- for (w = s->windows; w; w = w->next)
+
+ for (w = s->root.windows; w; w = walkDepthFirst (w))
{
ww = GET_WOBBLY_WINDOW (w, ws);
@@ -1806,19 +1813,17 @@ wobblyAddWindowGeometry (CompWindow *w,
Region region,
Region clip)
{
- WOBBLY_WINDOW (w);
WOBBLY_SCREEN (w->screen);
- if (ww->wobbly)
+ if (ws->model)
{
- BoxPtr pClip;
- int nClip, nVertices, nIndices;
+ BoxPtr pClip, pBox;
+ int nClip, nBox, nVertices, nIndices;
GLushort *i;
GLfloat *v;
int x1, y1, x2, y2;
- float width, height;
float deformedX, deformedY;
- int x, y, iw, ih, wx, wy;
+ int x, y, iw, ih;
int vSize, it;
int gridW, gridH;
Bool rect = TRUE;
@@ -1832,21 +1837,16 @@ wobblyAddWindowGeometry (CompWindow *w,
}
}
- wx = WIN_X (w);
- wy = WIN_Y (w);
- width = WIN_W (w);
- height = WIN_H (w);
-
- gridW = width / ws->opt[WOBBLY_SCREEN_OPTION_GRID_RESOLUTION].value.i;
+ gridW = ws->width / ws->opt[WOBBLY_SCREEN_OPTION_GRID_RESOLUTION].value.i;
if (gridW < ws->opt[WOBBLY_SCREEN_OPTION_MIN_GRID_SIZE].value.i)
gridW = ws->opt[WOBBLY_SCREEN_OPTION_MIN_GRID_SIZE].value.i;
- gridH = height / ws->opt[WOBBLY_SCREEN_OPTION_GRID_RESOLUTION].value.i;
+ gridH = ws->height / ws->opt[WOBBLY_SCREEN_OPTION_GRID_RESOLUTION].value.i;
if (gridH < ws->opt[WOBBLY_SCREEN_OPTION_MIN_GRID_SIZE].value.i)
gridH = ws->opt[WOBBLY_SCREEN_OPTION_MIN_GRID_SIZE].value.i;
- nClip = region->numRects;
- pClip = region->rects;
+ nBox = region->numRects;
+ pBox = region->rects;
w->texUnits = nMatrix;
@@ -1858,96 +1858,117 @@ wobblyAddWindowGeometry (CompWindow *w,
v = w->vertices + (nVertices * vSize);
i = w->indices + nIndices;
- while (nClip--)
+ while (nBox--)
{
- x1 = pClip->x1;
- y1 = pClip->y1;
- x2 = pClip->x2;
- y2 = pClip->y2;
-
- iw = ((x2 - x1 - 1) / gridW) + 1;
- ih = ((y2 - y1 - 1) / gridH) + 1;
-
- if (nIndices + (iw * ih * 4) > w->indexSize)
- {
- if (!moreWindowIndices (w, nIndices + (iw * ih * 4)))
- return;
-
- i = w->indices + nIndices;
- }
-
- iw++;
- ih++;
+ nClip = clip->numRects;
+ pClip = clip->rects;
- for (y = 0; y < ih - 1; y++)
+ while (nClip--)
{
- for (x = 0; x < iw - 1; x++)
+ x1 = pClip->x1;
+ y1 = pClip->y1;
+ x2 = pClip->x2;
+ y2 = pClip->y2;
+
+ if (x1 < pBox->x1)
+ x1 = pBox->x1;
+ if (y1 < pBox->y1)
+ y1 = pBox->y1;
+ if (x2 > pBox->x2)
+ x2 = pBox->x2;
+ if (y2 > pBox->y2)
+ y2 = pBox->y2;
+
+ if (x1 < x2 && y1 < y2)
{
- *i++ = nVertices + iw * (y + 1) + x;
- *i++ = nVertices + iw * (y + 1) + x + 1;
- *i++ = nVertices + iw * y + x + 1;
- *i++ = nVertices + iw * y + x;
-
- nIndices += 4;
- }
- }
+ iw = ((x2 - x1 - 1) / gridW) + 1;
+ ih = ((y2 - y1 - 1) / gridH) + 1;
- if (((nVertices + iw * ih) * vSize) > w->vertexSize)
- {
- if (!moreWindowVertices (w, (nVertices + iw * ih) * vSize))
- return;
-
- v = w->vertices + (nVertices * vSize);
- }
-
- for (y = y1;; y += gridH)
- {
- if (y > y2)
- y = y2;
+ if (nIndices + (iw * ih * 4) > w->indexSize)
+ {
+ if (!moreWindowIndices (w, nIndices + (iw * ih * 4)))
+ return;
- for (x = x1;; x += gridW)
- {
- if (x > x2)
- x = x2;
+ i = w->indices + nIndices;
+ }
- bezierPatchEvaluate (ww->model,
- (x - wx) / width,
- (y - wy) / height,
- &deformedX,
- &deformedY);
+ iw++;
+ ih++;
- if (rect)
+ for (y = 0; y < ih - 1; y++)
{
- for (it = 0; it < nMatrix; it++)
+ for (x = 0; x < iw - 1; x++)
{
- *v++ = COMP_TEX_COORD_X (&matrix[it], x);
- *v++ = COMP_TEX_COORD_Y (&matrix[it], y);
+ *i++ = nVertices + iw * (y + 1) + x;
+ *i++ = nVertices + iw * (y + 1) + x + 1;
+ *i++ = nVertices + iw * y + x + 1;
+ *i++ = nVertices + iw * y + x;
+
+ nIndices += 4;
}
}
- else
+
+ if (((nVertices + iw * ih) * vSize) > w->vertexSize)
{
- for (it = 0; it < nMatrix; it++)
- {
- *v++ = COMP_TEX_COORD_XY (&matrix[it], x, y);
- *v++ = COMP_TEX_COORD_YX (&matrix[it], x, y);
- }
+ if (!moreWindowVertices (w,
+ (nVertices + iw * ih) * vSize))
+ return;
+
+ v = w->vertices + (nVertices * vSize);
}
- *v++ = deformedX;
- *v++ = deformedY;
- *v++ = 0.0;
+ for (y = y1;; y += gridH)
+ {
+ if (y > y2)
+ y = y2;
- nVertices++;
+ for (x = x1;; x += gridW)
+ {
+ if (x > x2)
+ x = x2;
+
+ bezierPatchEvaluate (ws->model,
+ (x - ws->x) / ws->width,
+ (y - ws->y) / ws->height,
+ &deformedX,
+ &deformedY);
+
+ if (rect)
+ {
+ for (it = 0; it < nMatrix; it++)
+ {
+ *v++ = COMP_TEX_COORD_X (&matrix[it], x);
+ *v++ = COMP_TEX_COORD_Y (&matrix[it], y);
+ }
+ }
+ else
+ {
+ for (it = 0; it < nMatrix; it++)
+ {
+ *v++ = COMP_TEX_COORD_XY (&matrix[it], x, y);
+ *v++ = COMP_TEX_COORD_YX (&matrix[it], x, y);
+ }
+ }
+
+ *v++ = deformedX;
+ *v++ = deformedY;
+ *v++ = 0.0;
+
+ nVertices++;
+
+ if (x == x2)
+ break;
+ }
- if (x == x2)
- break;
+ if (y == y2)
+ break;
+ }
}
-
- if (y == y2)
- break;
+
+ pClip++;
}
- pClip++;
+ pBox++;
}
w->vCount = nVertices;
@@ -1964,6 +1985,53 @@ wobblyAddWindowGeometry (CompWindow *w,
}
}
+static void
+wobblyDrawSubWindows (CompWindow *w,
+ const CompTransform *transform,
+ Region region,
+ int mask)
+{
+ CompWindow *c;
+
+ for (c = w->windows; c; c = c->next)
+ {
+ FragmentAttrib fragment;
+ unsigned int wMask = mask;
+
+ initFragmentAttrib (&fragment, &c->lastPaint);
+
+ if (c->alpha || fragment.opacity != OPAQUE)
+ wMask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+
+ (*w->screen->drawWindow) (c, transform, &fragment, region, wMask);
+
+ if (c->windows)
+ {
+ Region r;
+
+ r = XCreateRegion ();
+ if (r)
+ {
+ WOBBLY_SCREEN (w->screen);
+
+ XSubtractRegion (region, &emptyRegion, r);
+ XIntersectRegion (r, c->region, r);
+ XOffsetRegion (r, -c->attrib.x, -c->attrib.y);
+
+ ws->x -= c->attrib.x;
+ ws->y -= c->attrib.y;
+
+ wobblyDrawSubWindows (c, transform, r, mask);
+
+ ws->x += c->attrib.x;
+ ws->y += c->attrib.y;
+
+ XDestroyRegion (r);
+ }
+ }
+ }
+}
+
static Bool
wobblyPaintWindow (CompWindow *w,
const WindowPaintAttrib *attrib,
@@ -1971,17 +2039,69 @@ wobblyPaintWindow (CompWindow *w,
Region region,
unsigned int mask)
{
- Bool status;
+ CompScreen *s = w->screen;
+ Bool status;
- WOBBLY_SCREEN (w->screen);
+ WOBBLY_SCREEN (s);
WOBBLY_WINDOW (w);
if (ww->wobbly)
- mask |= PAINT_WINDOW_TRANSFORMED_MASK;
+ {
+ FragmentAttrib fragment;
- UNWRAP (ws, w->screen, paintWindow);
- status = (*w->screen->paintWindow) (w, attrib, transform, region, mask);
- WRAP (ws, w->screen, paintWindow, wobblyPaintWindow);
+ if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
+ return FALSE;
+
+ UNWRAP (ws, s, paintWindow);
+ status = (*s->paintWindow) (w, attrib, transform, region,
+ mask | PAINT_WINDOW_NO_CORE_INSTANCE_MASK);
+ WRAP (ws, s, paintWindow, wobblyPaintWindow);
+
+ glPushMatrix ();
+ glLoadMatrixf (transform->m);
+
+ ws->model = ww->model;
+ ws->x = WIN_X (w);
+ ws->y = WIN_Y (w);
+ ws->width = WIN_W (w);
+ ws->height = WIN_H (w);
+
+ initFragmentAttrib (&fragment, &w->lastPaint);
+
+ if (w->alpha || fragment.opacity != OPAQUE)
+ mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+
+ (*s->drawWindow) (w,
+ transform,
+ &fragment,
+ region,
+ mask | PAINT_WINDOW_TRANSFORMED_MASK);
+
+ if (w->windows)
+ {
+ XOffsetRegion (w->region, -w->attrib.x, -w->attrib.y);
+
+ ws->x -= w->attrib.x;
+ ws->y -= w->attrib.y;
+
+ wobblyDrawSubWindows (w,
+ transform,
+ w->region,
+ PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK);
+
+ XOffsetRegion (w->region, w->attrib.x, w->attrib.y);
+ }
+
+ ws->model = NULL;
+
+ glPopMatrix ();
+ }
+ else
+ {
+ UNWRAP (ws, s, paintWindow);
+ status = (*s->paintWindow) (w, attrib, transform, region, mask);
+ WRAP (ws, s, paintWindow, wobblyPaintWindow);
+ }
return status;
}
@@ -2000,7 +2120,7 @@ wobblyEnableSnapping (CompDisplay *d,
for (s = d->screens; s; s = s->next)
{
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = walkDepthFirst (w))
{
WOBBLY_WINDOW (w);
@@ -2031,7 +2151,7 @@ wobblyDisableSnapping (CompDisplay *d,
for (s = d->screens; s; s = s->next)
{
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = walkDepthFirst (w))
{
WOBBLY_WINDOW (w);
@@ -2678,7 +2798,8 @@ wobblyInitDisplay (CompPlugin *p,
{
WobblyDisplay *wd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
wd = malloc (sizeof (WobblyDisplay));
@@ -2763,6 +2884,8 @@ wobblyInitScreen (CompPlugin *p,
ws->grabWindow = NULL;
ws->moveWindow = FALSE;
+ ws->model = NULL;
+
WRAP (ws, s, preparePaintScreen, wobblyPreparePaintScreen);
WRAP (ws, s, donePaintScreen, wobblyDonePaintScreen);
WRAP (ws, s, paintOutput, wobblyPaintOutput);
diff --git a/plugins/zoom.c b/plugins/zoom.c
index 8996c1c..4c3b881 100644
--- a/plugins/zoom.c
+++ b/plugins/zoom.c
@@ -163,7 +163,7 @@ zoomInEvent (CompScreen *s)
o[0].type = CompOptionTypeInt;
o[0].name = "root";
- o[0].value.i = s->root;
+ o[0].value.i = s->root.id;
o[1].type = CompOptionTypeInt;
o[1].name = "output";
@@ -197,7 +197,7 @@ zoomOutEvent (CompScreen *s)
o[0].type = CompOptionTypeInt;
o[0].name = "root";
- o[0].value.i = s->root;
+ o[0].value.i = s->root.id;
o[1].type = CompOptionTypeInt;
o[1].name = "output";
@@ -694,7 +694,7 @@ zoomTerminate (CompDisplay *d,
{
ZOOM_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (zs->grab)
@@ -719,7 +719,7 @@ zoomTerminate (CompDisplay *d,
o.type = CompOptionTypeInt;
o.name = "root";
- o.value.i = s->root;
+ o.value.i = s->root.id;
zoomOut (d, action, state, &o, 1);
}
@@ -787,7 +787,7 @@ zoomTerminatePan (CompDisplay *d,
{
ZOOM_SCREEN (s);
- if (xid && s->root != xid)
+ if (xid && s->root.id != xid)
continue;
if (zs->panGrabIndex)
@@ -970,7 +970,8 @@ zoomInitDisplay (CompPlugin *p,
{
ZoomDisplay *zd;
- if (!checkPluginABI ("core", CORE_ABIVERSION))
+ if (!checkPluginABI ("core", CORE_ABIVERSION) ||
+ !checkPluginABI ("glx", CORE_ABIVERSION))
return FALSE;
zd = malloc (sizeof (ZoomDisplay));
diff --git a/src/display.c b/src/display.c
index 23b0ba1..72515b6 100644
--- a/src/display.c
+++ b/src/display.c
@@ -195,8 +195,8 @@ mainMenu (CompDisplay *d,
s = findScreenAtDisplay (d, xid);
if (s && !s->maxGrab)
- toolkitAction (s, s->display->toolkitActionMainMenuAtom, time, s->root,
- 0, 0, 0);
+ toolkitAction (s, s->display->toolkitActionMainMenuAtom, time,
+ s->root.id, 0, 0, 0);
return TRUE;
}
@@ -217,8 +217,8 @@ runDialog (CompDisplay *d,
s = findScreenAtDisplay (d, xid);
if (s && !s->maxGrab)
- toolkitAction (s, s->display->toolkitActionRunDialogAtom, time, s->root,
- 0, 0, 0);
+ toolkitAction (s, s->display->toolkitActionRunDialogAtom, time,
+ s->root.id, 0, 0, 0);
return TRUE;
}
@@ -725,7 +725,7 @@ pingTimeout (void *closure)
for (s = d->screens; s; s = s->next)
{
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (w->attrib.map_state != IsViewable)
continue;
@@ -841,7 +841,7 @@ setDisplayOption (CompPlugin *plugin,
return FALSE;
}
-static void
+void
updatePlugins (CompDisplay *d)
{
CompOption *o;
@@ -1349,7 +1349,7 @@ doPoll (int timeout)
return rv;
}
-static void
+void
handleTimeouts (struct timeval *tv)
{
CompTimeout *t;
@@ -1545,13 +1545,20 @@ eventLoop (void)
{
for (s = d->screens; s; s = s->next)
{
- if (s->damageMask)
+ if (manualCompositeManagement)
{
- finishScreenDrawing (s);
+ if (s->damageMask)
+ {
+ finishScreenDrawing (s);
+ }
+ else
+ {
+ s->idle = TRUE;
+ }
}
else
{
- s->idle = TRUE;
+ s->damageMask = 0;
}
}
}
@@ -1624,7 +1631,7 @@ eventLoop (void)
/* substract top most overlay window region */
if (s->overlayWindowCount)
{
- for (w = s->reverseWindows; w; w = w->prev)
+ for (w = s->root.reverseWindows; w; w = w->prev)
{
if (w->destroyed || w->invisible)
continue;
@@ -1748,24 +1755,6 @@ eventLoop (void)
(*s->donePaintScreen) (s);
- /* remove destroyed windows */
- while (s->pendingDestroys)
- {
- CompWindow *w;
-
- for (w = s->windows; w; w = w->next)
- {
- if (w->destroyed)
- {
- addWindowDamage (w);
- removeWindow (w);
- break;
- }
- }
-
- s->pendingDestroys--;
- }
-
s->idle = FALSE;
}
}
@@ -1797,6 +1786,38 @@ eventLoop (void)
doPoll (-1);
}
}
+
+ for (d = core.displays; d; d = d->next)
+ {
+ for (s = d->screens; s; s = s->next)
+ {
+ /* remove destroyed windows */
+ while (s->pendingDestroys)
+ {
+ CompWindow *w, *c;
+
+ for (w = s->root.windows; w; w = walkDepthFirst (w))
+ {
+ if (w->destroyed)
+ {
+ for (c = w->windows;
+ c && c != w;
+ c = walkDepthFirst (c))
+ {
+ if (c->destroyed)
+ s->pendingDestroys--;
+ }
+
+ addWindowDamage (w);
+ removeWindow (w);
+ break;
+ }
+ }
+
+ s->pendingDestroys--;
+ }
+ }
+ }
}
for (d = core.displays; d; d = d->next)
@@ -1864,7 +1885,8 @@ compCheckForError (Display *dpy)
static void
addScreenActions (CompScreen *s)
{
- int i;
+ CompPlugin *p;
+ int i;
for (i = 0; i < COMP_DISPLAY_OPTION_NUM; i++)
{
@@ -1874,6 +1896,27 @@ addScreenActions (CompScreen *s)
if (s->display->opt[i].value.action.state & CompActionStateAutoGrab)
addScreenAction (s, &s->display->opt[i].value.action);
}
+
+ for (p = getPlugins (); p; p = p->next)
+ {
+ CompOption *option;
+ int nOption;
+
+ if (!p->vTable->getObjectOptions)
+ continue;
+
+ option = (*p->vTable->getObjectOptions) (p,
+ &s->display->base,
+ &nOption);
+ for (i = 0; i < nOption; i++)
+ {
+ if (!isActionOption (&option[i]))
+ continue;
+
+ if (option[i].value.action.state & CompActionStateAutoGrab)
+ addScreenAction (s, &option[i].value.action);
+ }
+ }
}
void
@@ -1920,12 +1963,10 @@ addDisplay (const char *name)
CompDisplay *d;
CompPrivate *privates;
Display *dpy;
- Window focus;
- int revertTo, i;
int compositeMajor, compositeMinor;
int fixesMinor;
int xkbOpcode;
- int firstScreen, lastScreen;
+ int i;
d = malloc (sizeof (CompDisplay));
if (!d)
@@ -2198,6 +2239,8 @@ addDisplay (const char *name)
d->startupIdAtom = XInternAtom (dpy, "_NET_STARTUP_ID", 0);
+ d->syncStateAtom = XInternAtom (dpy, "_COMPIZ_SYNC_STATE", 0);
+
d->snDisplay = sn_display_new (dpy, NULL, NULL);
if (!d->snDisplay)
return FALSE;
@@ -2288,7 +2331,7 @@ addDisplay (const char *name)
&d->xineramaEvent,
&d->xineramaError);
- if (d->xineramaExtension)
+ if (d->xineramaExtension && XineramaIsActive (dpy))
d->screenInfo = XineramaQueryScreens (dpy, &d->nScreenInfo);
d->escapeKeyCode = XKeysymToKeycode (dpy, XStringToKeysym ("Escape"));
@@ -2301,6 +2344,49 @@ addDisplay (const char *name)
(*core.objectAdd) (&core.base, &d->base);
+ return TRUE;
+}
+
+void
+removeDisplay (CompDisplay *d)
+{
+ CompDisplay *p;
+
+ for (p = core.displays; p; p = p->next)
+ if (p->next == d)
+ break;
+
+ if (p)
+ p->next = d->next;
+ else
+ core.displays = NULL;
+
+ while (d->screens)
+ removeScreen (d->screens);
+
+ (*core.objectRemove) (&core.base, &d->base);
+
+ objectFiniPlugins (&d->base);
+
+ compRemoveTimeout (d->pingHandle);
+
+ if (d->snDisplay)
+ sn_display_unref (d->snDisplay);
+
+ XSync (d->display, False);
+ XCloseDisplay (d->display);
+
+ freeDisplay (d);
+}
+
+Bool
+manageDisplay (CompDisplay *d)
+{
+ Display *dpy = d->display;
+ Window focus;
+ int revertTo, i;
+ int firstScreen, lastScreen;
+
if (onlyCurrentScreen)
{
firstScreen = DefaultScreen (dpy);
@@ -2319,7 +2405,7 @@ addDisplay (const char *name)
Time wmSnTimestamp = 0;
XEvent event;
XSetWindowAttributes attr;
- Window currentWmSnOwner, currentCmSnOwner;
+ Window currentWmSnOwner = None, currentCmSnOwner;
char buf[128];
Window rootDummy, childDummy;
unsigned int uDummy;
@@ -2328,7 +2414,8 @@ addDisplay (const char *name)
sprintf (buf, "WM_S%d", i);
wmSnAtom = XInternAtom (dpy, buf, 0);
- currentWmSnOwner = XGetSelectionOwner (dpy, wmSnAtom);
+ if (windowManagement)
+ currentWmSnOwner = XGetSelectionOwner (dpy, wmSnAtom);
if (currentWmSnOwner != None)
{
@@ -2366,6 +2453,9 @@ addDisplay (const char *name)
continue;
}
+
+ XSelectInput (dpy, currentCmSnOwner,
+ StructureNotifyMask);
}
attr.override_redirect = TRUE;
@@ -2394,36 +2484,60 @@ addDisplay (const char *name)
wmSnTimestamp = event.xproperty.time;
- XSetSelectionOwner (dpy, wmSnAtom, newWmSnOwner, wmSnTimestamp);
+ XSetSelectionOwner (dpy, cmSnAtom, newCmSnOwner, wmSnTimestamp);
- if (XGetSelectionOwner (dpy, wmSnAtom) != newWmSnOwner)
+ if (XGetSelectionOwner (dpy, cmSnAtom) != newCmSnOwner)
{
compLogMessage ("core", CompLogLevelError,
- "Could not acquire window manager "
+ "Could not acquire compositing manager "
"selection on screen %d display \"%s\"",
i, DisplayString (dpy));
- XDestroyWindow (dpy, newWmSnOwner);
-
continue;
}
- /* Send client message indicating that we are now the WM */
- event.xclient.type = ClientMessage;
- event.xclient.window = XRootWindow (dpy, i);
- event.xclient.message_type = d->managerAtom;
- event.xclient.format = 32;
- event.xclient.data.l[0] = wmSnTimestamp;
- event.xclient.data.l[1] = wmSnAtom;
- event.xclient.data.l[2] = 0;
- event.xclient.data.l[3] = 0;
- event.xclient.data.l[4] = 0;
+ if (windowManagement)
+ {
+ XSetSelectionOwner (dpy, wmSnAtom, newWmSnOwner, wmSnTimestamp);
+
+ if (XGetSelectionOwner (dpy, wmSnAtom) != newWmSnOwner)
+ {
+ compLogMessage ("core", CompLogLevelError,
+ "Could not acquire window manager "
+ "selection on screen %d display \"%s\"",
+ i, DisplayString (dpy));
+
+ XDestroyWindow (dpy, newWmSnOwner);
+
+ continue;
+ }
- XSendEvent (dpy, XRootWindow (dpy, i), FALSE,
- StructureNotifyMask, &event);
+ /* Send client message indicating that we are now the WM */
+ event.xclient.type = ClientMessage;
+ event.xclient.window = XRootWindow (dpy, i);
+ event.xclient.message_type = d->managerAtom;
+ event.xclient.format = 32;
+ event.xclient.data.l[0] = wmSnTimestamp;
+ event.xclient.data.l[1] = wmSnAtom;
+ event.xclient.data.l[2] = 0;
+ event.xclient.data.l[3] = 0;
+ event.xclient.data.l[4] = 0;
+
+ XSendEvent (dpy, XRootWindow (dpy, i), FALSE,
+ StructureNotifyMask, &event);
+ }
+
+ /* Wait for old compositing manager to go away */
+ if (currentCmSnOwner != None)
+ {
+ do {
+ XWindowEvent (dpy, currentCmSnOwner,
+ StructureNotifyMask, &event);
+ } while (event.type != DestroyNotify);
+ }
/* Wait for old window manager to go away */
- if (currentWmSnOwner != None)
+ if (currentWmSnOwner != None && currentCmSnOwner != currentWmSnOwner)
{
do {
XWindowEvent (dpy, currentWmSnOwner,
@@ -2433,54 +2547,59 @@ addDisplay (const char *name)
compCheckForError (dpy);
- XCompositeRedirectSubwindows (dpy, XRootWindow (dpy, i),
- CompositeRedirectManual);
-
- if (compCheckForError (dpy))
+ if (manualCompositeManagement)
{
- compLogMessage ("core", CompLogLevelError,
- "Another composite manager is already "
- "running on screen: %d", i);
-
- continue;
- }
+ XCompositeRedirectSubwindows (dpy, XRootWindow (dpy, i),
+ CompositeRedirectManual);
- XSetSelectionOwner (dpy, cmSnAtom, newCmSnOwner, wmSnTimestamp);
+ if (compCheckForError (dpy))
+ {
+ compLogMessage ("core", CompLogLevelError,
+ "Another composite manager is already "
+ "running on screen: %d", i);
- if (XGetSelectionOwner (dpy, cmSnAtom) != newCmSnOwner)
+ continue;
+ }
+ }
+ else
{
- compLogMessage ("core", CompLogLevelError,
- "Could not acquire compositing manager "
- "selection on screen %d display \"%s\"",
- i, DisplayString (dpy));
-
- continue;
+ XCompositeRedirectSubwindows (dpy, XRootWindow (dpy, i),
+ CompositeRedirectAutomatic);
}
XGrabServer (dpy);
- XSelectInput (dpy, XRootWindow (dpy, i),
- SubstructureRedirectMask |
- SubstructureNotifyMask |
- StructureNotifyMask |
- PropertyChangeMask |
- LeaveWindowMask |
- EnterWindowMask |
- KeyPressMask |
- KeyReleaseMask |
- ButtonPressMask |
- ButtonReleaseMask |
- FocusChangeMask |
- ExposureMask);
-
- if (compCheckForError (dpy))
+ if (windowManagement)
{
- compLogMessage ("core", CompLogLevelError,
- "Another window manager is "
- "already running on screen: %d", i);
+ XSelectInput (dpy, XRootWindow (dpy, i),
+ SubstructureRedirectMask |
+ StructureNotifyMask |
+ PropertyChangeMask |
+ LeaveWindowMask |
+ EnterWindowMask |
+ KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ FocusChangeMask |
+ ExposureMask);
+
+ if (compCheckForError (dpy))
+ {
+ compLogMessage ("core", CompLogLevelError,
+ "Another window manager is "
+ "already running on screen: %d", i);
- XUngrabServer (dpy);
- continue;
+ XUngrabServer (dpy);
+ continue;
+ }
+ }
+ else
+ {
+ XSelectInput (dpy, XRootWindow (dpy, i),
+ StructureNotifyMask |
+ PropertyChangeMask |
+ ExposureMask);
}
if (!addScreen (d, i, newWmSnOwner, wmSnAtom, wmSnTimestamp))
@@ -2503,74 +2622,50 @@ addDisplay (const char *name)
if (!d->screens)
{
compLogMessage ("core", CompLogLevelFatal,
- "No manageable screens found on display %s",
- XDisplayName (name));
+ "No manageable screens found on display");
return FALSE;
}
setAudibleBell (d, d->opt[COMP_DISPLAY_OPTION_AUDIBLE_BELL].value.b);
- XGetInputFocus (dpy, &focus, &revertTo);
-
- /* move input focus to root window so that we get a FocusIn event when
- moving it to the default window */
- XSetInputFocus (dpy, d->screens->root, RevertToPointerRoot, CurrentTime);
-
- if (focus == None || focus == PointerRoot)
+ if (windowManagement)
{
- focusDefaultWindow (d->screens);
- }
- else
- {
- CompWindow *w;
+ XGetInputFocus (dpy, &focus, &revertTo);
- w = findWindowAtDisplay (d, focus);
- if (w)
+ /* move input focus to root window so that we get a FocusIn event when
+ moving it to the default window */
+ XSetInputFocus (dpy, d->screens->root.id, RevertToPointerRoot,
+ CurrentTime);
+
+ if (focus == None || focus == PointerRoot)
{
- moveInputFocusToWindow (w);
+ focusDefaultWindow (d->screens);
}
else
- focusDefaultWindow (d->screens);
- }
-
- d->pingHandle =
- compAddTimeout (d->opt[COMP_DISPLAY_OPTION_PING_DELAY].value.i,
- d->opt[COMP_DISPLAY_OPTION_PING_DELAY].value.i + 500,
- pingTimeout, d);
-
- return TRUE;
-}
-
-void
-removeDisplay (CompDisplay *d)
-{
- CompDisplay *p;
+ {
+ CompWindow *w;
- for (p = core.displays; p; p = p->next)
- if (p->next == d)
- break;
+ w = findWindowAtDisplay (d, focus);
+ if (w)
+ {
+ moveInputFocusToWindow (w);
+ }
+ else
+ focusDefaultWindow (d->screens);
+ }
- if (p)
- p->next = d->next;
+ d->pingHandle =
+ compAddTimeout (d->opt[COMP_DISPLAY_OPTION_PING_DELAY].value.i,
+ d->opt[COMP_DISPLAY_OPTION_PING_DELAY].value.i +
+ 500, pingTimeout, d);
+ }
else
- core.displays = NULL;
-
- while (d->screens)
- removeScreen (d->screens);
-
- (*core.objectRemove) (&core.base, &d->base);
-
- objectFiniPlugins (&d->base);
-
- compRemoveTimeout (d->pingHandle);
-
- if (d->snDisplay)
- sn_display_unref (d->snDisplay);
-
- XSync (d->display, False);
- XCloseDisplay (d->display);
+ {
+ d->activeWindow = d->screens->root.activeChild =
+ getActiveWindow (d, d->screens->root.id);
+ }
- freeDisplay (d);
+ return TRUE;
}
Time
@@ -2596,7 +2691,7 @@ findScreenAtDisplay (CompDisplay *d,
for (s = d->screens; s; s = s->next)
{
- if (s->root == root)
+ if (s->root.id == root)
return s;
}
@@ -2632,6 +2727,23 @@ findWindowAtDisplay (CompDisplay *d,
}
CompWindow *
+findClientWindowAtDisplay (CompDisplay *d,
+ Window id)
+{
+ CompScreen *s;
+ CompWindow *w;
+
+ for (s = d->screens; s; s = s->next)
+ {
+ w = findClientWindowAtScreen (s, id);
+ if (w)
+ return w;
+ }
+
+ return 0;
+}
+
+CompWindow *
findTopLevelWindowAtDisplay (CompDisplay *d,
Window id)
{
@@ -2823,7 +2935,7 @@ warpPointer (CompScreen *s,
pointerY = 0;
XWarpPointer (display->display,
- None, s->root,
+ None, s->root.id,
0, 0, 0, 0,
pointerX, pointerY);
diff --git a/src/event.c b/src/event.c
index ac61749..f9edcfc 100644
--- a/src/event.c
+++ b/src/event.c
@@ -45,37 +45,46 @@ handleWindowDamageRect (CompWindow *w,
int height)
{
REGION region;
- Bool initial = FALSE;
+ Bool status = TRUE;
if (!w->redirected || w->bindFailed)
return;
- if (!w->damaged)
- {
- w->damaged = initial = TRUE;
- w->invisible = WINDOW_INVISIBLE (w);
- }
-
region.extents.x1 = x;
region.extents.y1 = y;
region.extents.x2 = region.extents.x1 + width;
region.extents.y2 = region.extents.y1 + height;
- if (!(*w->screen->damageWindowRect) (w, initial, ®ion.extents))
+ while (w != &w->screen->root)
{
+ Bool initial = FALSE;
+
+ if (!w->damaged)
+ {
+ w->damaged = initial = TRUE;
+ w->invisible = WINDOW_INVISIBLE (w);
+ }
+
+ status &= (*w->screen->damageWindowRect) (w, initial, ®ion.extents);
+
+ if (initial)
+ damageWindowOutputExtents (w);
+
region.extents.x1 += w->attrib.x + w->attrib.border_width;
region.extents.y1 += w->attrib.y + w->attrib.border_width;
region.extents.x2 += w->attrib.x + w->attrib.border_width;
region.extents.y2 += w->attrib.y + w->attrib.border_width;
+ w = w->parent;
+ }
+
+ if (!status)
+ {
region.rects = ®ion.extents;
region.numRects = region.size = 1;
damageScreenRegion (w->screen, ®ion);
}
-
- if (initial)
- damageWindowOutputExtents (w);
}
void
@@ -99,6 +108,9 @@ handleSyncAlarm (CompWindow *w)
XRectangle *rects;
int nDamage;
+ if (w->parent->substructureRedirect)
+ leaveSyncWaitState (w);
+
nDamage = w->nDamage;
rects = w->damageRects;
while (nDamage--)
@@ -130,9 +142,9 @@ moveInputFocusToOtherWindow (CompWindow *w)
{
CompWindow *ancestor;
- if (w->transientFor && w->transientFor != w->screen->root)
+ if (w->transientFor && w->transientFor != w->screen->root.id)
{
- ancestor = findWindowAtDisplay (display, w->transientFor);
+ ancestor = findSibling (w, w->transientFor);
if (ancestor && !(ancestor->type & (CompWindowTypeDesktopMask |
CompWindowTypeDockMask)))
{
@@ -146,7 +158,7 @@ moveInputFocusToOtherWindow (CompWindow *w)
{
CompWindow *a, *focus = NULL;
- for (a = w->screen->reverseWindows; a; a = a->prev)
+ for (a = w->screen->root.reverseWindows; a; a = a->prev)
{
if (a->clientLeader == w->clientLeader)
{
@@ -277,7 +289,7 @@ triggerButtonPressBindings (CompDisplay *d,
if (event->window != edgeWindow)
{
- if (!s->maxGrab || event->window != s->root)
+ if (!s->maxGrab || event->window != s->root.id)
return FALSE;
}
@@ -1064,7 +1076,7 @@ handleActionEvent (CompDisplay *d,
if (event->xclient.window == s->screenEdge[i].id)
{
edge = 1 << i;
- root = s->root;
+ root = s->root.id;
break;
}
}
@@ -1115,7 +1127,7 @@ handleActionEvent (CompDisplay *d,
if (xdndWindow == s->screenEdge[i].id)
{
edge = 1 << i;
- root = s->root;
+ root = s->root.id;
break;
}
}
@@ -1307,32 +1319,29 @@ handleEvent (CompDisplay *d,
case ConfigureNotify:
w = findWindowAtDisplay (d, event->xconfigure.window);
if (w)
- {
configureWindow (w, &event->xconfigure);
- }
- else
- {
- s = findScreenAtDisplay (d, event->xconfigure.window);
- if (s)
- configureScreen (s, &event->xconfigure);
- }
break;
case CreateNotify:
- s = findScreenAtDisplay (d, event->xcreatewindow.parent);
- if (s)
+ w = findWindowAtDisplay (d, event->xcreatewindow.parent);
+ if (w)
{
/* The first time some client asks for the composite
* overlay window, the X server creates it, which causes
* an errorneous CreateNotify event. We catch it and
* ignore it. */
- if (s->overlay != event->xcreatewindow.window)
- addWindow (s, event->xcreatewindow.window, getTopWindow (s));
+ if (w->screen->overlay != event->xcreatewindow.window)
+ addWindow (w,
+ event->xcreatewindow.window,
+ getTopWindow (w));
}
break;
case DestroyNotify:
w = findWindowAtDisplay (d, event->xdestroywindow.window);
if (w)
{
+ if (w->parent->supportingWmCheckWindow == w->id)
+ getSupportingWmCheck (w->parent);
+
moveInputFocusToOtherWindow (w);
destroyWindow (w);
}
@@ -1341,11 +1350,8 @@ handleEvent (CompDisplay *d,
w = findWindowAtDisplay (d, event->xmap.window);
if (w)
{
- if (w->pendingMaps)
- w->managed = TRUE;
-
/* been shaded */
- if (w->height == 0)
+ if (w->managed && w->height == 0)
{
if (w->id == d->activeWindow)
moveInputFocusToWindow (w);
@@ -1356,7 +1362,7 @@ handleEvent (CompDisplay *d,
break;
case UnmapNotify:
w = findWindowAtDisplay (d, event->xunmap.window);
- if (w)
+ if (w && w->parent)
{
/* Normal -> Iconic */
if (w->pendingUnmaps)
@@ -1364,7 +1370,7 @@ handleEvent (CompDisplay *d,
setWmState (d, IconicState, w->id);
w->pendingUnmaps--;
}
- else /* X -> Withdrawn */
+ else if (w->managed) /* X -> Withdrawn */
{
/* Iconic -> Withdrawn */
if (w->state & CompWindowStateHiddenMask)
@@ -1392,12 +1398,7 @@ handleEvent (CompDisplay *d,
break;
case ReparentNotify:
w = findWindowAtDisplay (d, event->xreparent.window);
- s = findScreenAtDisplay (d, event->xreparent.parent);
- if (s && !w)
- {
- addWindow (s, event->xreparent.window, getTopWindow (s));
- }
- else if (w)
+ if (w)
{
/* This is the only case where a window is removed but not
destroyed. We must remove our event mask and all passive
@@ -1410,6 +1411,11 @@ handleEvent (CompDisplay *d,
destroyWindow (w);
}
+
+ w = findWindowAtDisplay (d, event->xreparent.parent);
+ if (w && (w->redirectSubwindows || w->substructureRedirect))
+ addWindow (w, event->xreparent.window, getTopWindow (w));
+
break;
case CirculateNotify:
w = findWindowAtDisplay (d, event->xcirculate.window);
@@ -1456,9 +1462,9 @@ handleEvent (CompDisplay *d,
if (w->attrib.map_state == IsViewable)
{
if (w->type == CompWindowTypeDesktopMask)
- w->screen->desktopWindowCount--;
+ w->parent->desktopWindowCount--;
else if (type == CompWindowTypeDesktopMask)
- w->screen->desktopWindowCount++;
+ w->parent->desktopWindowCount++;
}
w->wmType = type;
@@ -1533,6 +1539,12 @@ handleEvent (CompDisplay *d,
if (w)
w->clientLeader = getClientLeader (w);
}
+ else if (event->xproperty.atom == d->frameWindowAtom)
+ {
+ w = findWindowAtDisplay (d, event->xproperty.window);
+ if (w && w->parent && !w->parent->substructureRedirect)
+ w->frame = getFrameWindow (w);
+ }
else if (event->xproperty.atom == d->wmIconGeometryAtom)
{
w = findWindowAtDisplay (d, event->xproperty.window);
@@ -1681,10 +1693,67 @@ handleEvent (CompDisplay *d,
if (w)
updateWindowClassHints (w);
}
+ else if (event->xproperty.atom == d->supportingWmCheckAtom ||
+ event->xproperty.atom == d->supportedAtom)
+ {
+ w = findWindowAtDisplay (d, event->xproperty.window);
+ if (w && !w->substructureRedirect)
+ getSupportingWmCheck (w);
+ }
+ else if (event->xproperty.atom == d->syncStateAtom)
+ {
+ w = findWindowAtDisplay (d, event->xproperty.window);
+ if (w && w->parent)
+ {
+ if (!w->parent->substructureRedirect)
+ {
+ if (event->xproperty.state == PropertyDelete)
+ {
+ if (w->parent->syncStateSupport)
+ syncWait (w);
+ }
+ else
+ handleSyncAlarm (w);
+ }
+ }
+ }
+ else if (event->xproperty.atom == d->winActiveAtom)
+ {
+ w = findWindowAtDisplay (d, event->xproperty.window);
+ if (w)
+ {
+ if (!w->substructureRedirect)
+ {
+ Window activeChild;
+
+ activeChild = getActiveWindow (d, w->id);
+ if (activeChild != w->activeChild)
+ {
+ w->previousActiveChild = w->activeChild;
+ w->activeChild = activeChild;
+ }
+
+ if (!w->parent)
+ d->activeWindow = activeChild;
+ }
+ }
+ }
+ else if (event->xproperty.atom == d->desktopViewportAtom)
+ {
+ w = findWindowAtDisplay (d, event->xproperty.window);
+ if (w && !w->parent)
+ {
+ if (!w->substructureRedirect)
+ getDesktopHints (w->screen);
+ }
+ }
break;
case MotionNotify:
break;
case ClientMessage:
+ if (!windowManagement)
+ break;
+
if (event->xclient.message_type == d->winActiveAtom)
{
w = findWindowAtDisplay (d, event->xclient.window);
@@ -1932,7 +2001,7 @@ handleEvent (CompDisplay *d,
{
for (s = d->screens; s; s = s->next)
{
- if (event->xclient.window == s->root ||
+ if (event->xclient.window == s->root.id ||
event->xclient.window == None)
{
if (event->xclient.data.l[0])
@@ -1968,6 +2037,17 @@ handleEvent (CompDisplay *d,
if (w)
setDesktopForWindow (w, event->xclient.data.l[0]);
}
+ else if (event->xclient.message_type == d->desktopViewportAtom)
+ {
+ s = findScreenAtDisplay (d, event->xclient.window);
+ if (s)
+ moveScreenViewport (s,
+ s->x -
+ (event->xclient.data.l[0] / s->width),
+ s->y -
+ (event->xclient.data.l[1] / s->height),
+ TRUE);
+ }
break;
case MappingNotify:
updateModifierMappings (d);
@@ -2026,7 +2106,7 @@ handleEvent (CompDisplay *d,
xwcm = adjustConfigureRequestForGravity (w, &xwc,
CWX | CWY,
- gravity);
+ gravity, 1);
if ((*w->screen->placeWindow) (w, xwc.x, xwc.y,
&newX, &newY))
@@ -2061,6 +2141,15 @@ handleEvent (CompDisplay *d,
if (!(w->state & CompWindowStateHiddenMask))
{
+ /* predict that input will be moved to window. this
+ makes it look like the window became active just
+ before it got mapped to external applications */
+ if (w->inputHint && allowFocus)
+ XChangeProperty (d->display, w->screen->root.id,
+ d->winActiveAtom,
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *) &w->id, 1);
+
w->pendingMaps++;
XMapWindow (d->display, w->id);
}
@@ -2165,14 +2254,19 @@ handleEvent (CompDisplay *d,
{
unsigned int state = w->state;
- if (w->id != d->activeWindow)
+ if (w->id != w->parent->activeChild)
{
- d->activeWindow = w->id;
+ w->parent->previousActiveChild = w->parent->activeChild;
+ w->parent->activeChild = w->id;
+
+ if (w->parent == &w->screen->root)
+ d->activeWindow = w->id;
+
w->activeNum = w->screen->activeNum++;
addToCurrentActiveWindowHistory (w->screen, w->id);
- XChangeProperty (d->display, w->screen->root,
+ XChangeProperty (d->display, w->screen->root.id,
d->winActiveAtom,
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &w->id, 1);
@@ -2324,7 +2418,7 @@ handleEvent (CompDisplay *d,
for (s = d->screens; s; s = s->next)
{
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (w->syncAlarm == sa->alarm)
break;
diff --git a/src/main.c b/src/main.c
index ff8328d..ec76311 100644
--- a/src/main.c
+++ b/src/main.c
@@ -68,6 +68,9 @@ Bool onlyCurrentScreen = FALSE;
Bool useCow = TRUE;
#endif
+Bool windowManagement = FALSE;
+Bool manualCompositeManagement = FALSE;
+
CompMetadata coreMetadata;
static void
@@ -435,6 +438,15 @@ main (int argc, char **argv)
if (!addDisplay (displayName))
return 1;
+ while (core.displays->dirtyPluginList)
+ {
+ updatePlugins (core.displays);
+ handleTimeouts (&core.lastTimeout);
+ }
+
+ if (!manageDisplay (core.displays))
+ return 1;
+
eventLoop ();
if (!disableSm)
diff --git a/src/paint.c b/src/paint.c
index a2051fa..529fdc6 100644
--- a/src/paint.c
+++ b/src/paint.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <assert.h>
#include <compiz-core.h>
@@ -157,7 +158,7 @@ paintBackground (CompScreen *s,
if (!nBox)
return;
- if (s->desktopWindowCount)
+ if (s->root.desktopWindowCount)
{
if (bg->name)
{
@@ -251,167 +252,54 @@ paintOutputRegion (CompScreen *screen,
CompOutput *output,
unsigned int mask)
{
- static Region tmpRegion = NULL;
- CompWindow *w;
- CompCursor *c;
- int count, windowMask, odMask, i;
- CompWindow *fullscreenWindow = NULL;
- CompWalker walk;
- Bool status;
- Bool withOffset = FALSE;
- CompTransform vTransform;
- int offX, offY;
- Region clip = region;
-
- if (!tmpRegion)
- {
- tmpRegion = XCreateRegion ();
- if (!tmpRegion)
- return;
- }
+ Region r = XCreateRegion ();
+ CompPainter painter;
+ CompCursor *c;
+ int windowMask = 0;
+
+ assert (r);
+
+ (*screen->initObjectPainter) (screen, &painter);
if (mask & PAINT_SCREEN_TRANSFORMED_MASK)
- {
- windowMask = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
- count = 1;
- }
- else
- {
- windowMask = 0;
- count = 0;
- }
+ windowMask = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
- XSubtractRegion (region, &emptyRegion, tmpRegion);
+ if (mask & PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK)
+ windowMask |= PAINT_WINDOW_WITH_TRANSFORMED_CHILD_MASK;
- (*screen->initWindowWalker) (screen, &walk);
+ XSubtractRegion (region, &emptyRegion, r);
if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
{
- /* detect occlusions */
- for (w = (*walk.last) (screen); w; w = (*walk.prev) (w))
- {
- if (w->destroyed)
- continue;
-
- if (!w->shaded)
- {
- if (w->attrib.map_state != IsViewable || !w->damaged)
- continue;
- }
+ XSubtractRegion (r, &emptyRegion, screen->root.clip);
- /* copy region */
- XSubtractRegion (tmpRegion, &emptyRegion, w->clip);
+ if ((*painter.paintObject) (&screen->root,
+ &screen->root.paint,
+ transform,
+ r,
+ PAINT_WINDOW_OCCLUSION_DETECTION_MASK))
+ XSubtractRegion (r, screen->root.region, r);
- odMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK;
-
- if ((screen->windowOffsetX != 0 || screen->windowOffsetY != 0) &&
- !windowOnAllViewports (w))
- {
- withOffset = TRUE;
-
- getWindowMovementForOffset (w, screen->windowOffsetX,
- screen->windowOffsetY,
- &offX, &offY);
-
- vTransform = *transform;
- matrixTranslate (&vTransform, offX, offY, 0);
-
- XOffsetRegion (w->clip, -offX, -offY);
-
- odMask |= PAINT_WINDOW_WITH_OFFSET_MASK;
- status = (*screen->paintWindow) (w, &w->paint, &vTransform,
- tmpRegion, odMask);
- }
- else
- {
- withOffset = FALSE;
- status = (*screen->paintWindow) (w, &w->paint, transform, tmpRegion,
- odMask);
- }
-
- if (status)
- {
- if (withOffset)
- {
- XOffsetRegion (w->region, offX, offY);
- XSubtractRegion (tmpRegion, w->region, tmpRegion);
- XOffsetRegion (w->region, -offX, -offY);
- }
- else
- XSubtractRegion (tmpRegion, w->region, tmpRegion);
-
- /* unredirect top most fullscreen windows. */
- if (count == 0 &&
- screen->opt[COMP_SCREEN_OPTION_UNREDIRECT_FS].value.b)
- {
- if (XEqualRegion (w->region, &screen->region) &&
- !REGION_NOT_EMPTY (tmpRegion))
- {
- fullscreenWindow = w;
- }
- else
- {
- for (i = 0; i < screen->nOutputDev; i++)
- if (XEqualRegion (w->region,
- &screen->outputDev[i].region))
- fullscreenWindow = w;
- }
- }
- }
-
- count++;
- }
+ windowMask |= PAINT_WINDOW_CLIP_MASK;
}
- if (fullscreenWindow)
- unredirectWindow (fullscreenWindow);
-
if (!(mask & PAINT_SCREEN_NO_BACKGROUND_MASK))
- paintBackground (screen, tmpRegion,
- (mask & PAINT_SCREEN_TRANSFORMED_MASK));
-
- /* paint all windows from bottom to top */
- for (w = (*walk.first) (screen); w; w = (*walk.next) (w))
- {
- if (w->destroyed)
- continue;
-
- if (w == fullscreenWindow)
- continue;
-
- if (!w->shaded)
- {
- if (w->attrib.map_state != IsViewable || !w->damaged)
- continue;
- }
+ paintBackground (screen, r, (mask & PAINT_SCREEN_TRANSFORMED_MASK));
- if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
- clip = w->clip;
+ (*painter.paintObject) (&screen->root,
+ &screen->root.paint,
+ transform,
+ r,
+ windowMask);
- if ((screen->windowOffsetX != 0 || screen->windowOffsetY != 0) &&
- !windowOnAllViewports (w))
- {
- getWindowMovementForOffset (w, screen->windowOffsetX,
- screen->windowOffsetY, &offX, &offY);
-
- vTransform = *transform;
- matrixTranslate (&vTransform, offX, offY, 0);
- (*screen->paintWindow) (w, &w->paint, &vTransform, clip,
- windowMask | PAINT_WINDOW_WITH_OFFSET_MASK);
- }
- else
- {
- (*screen->paintWindow) (w, &w->paint, transform, clip,
- windowMask);
- }
- }
-
- if (walk.fini)
- (*walk.fini) (screen, &walk);
+ if (painter.fini)
+ (*painter.fini) (screen, &painter);
/* paint cursors */
for (c = screen->cursors; c; c = c->next)
- (*screen->paintCursor) (c, transform, tmpRegion, 0);
+ (*screen->paintCursor) (c, transform, r, 0);
+
+ XDestroyRegion (r);
}
void
@@ -420,21 +308,15 @@ enableOutputClipping (CompScreen *screen,
Region region,
CompOutput *output)
{
- GLdouble h = screen->height;
-
- GLdouble p1[2] = { region->extents.x1, h - region->extents.y2 };
- GLdouble p2[2] = { region->extents.x2, h - region->extents.y1 };
-
- GLdouble halfW = output->width / 2.0;
- GLdouble halfH = output->height / 2.0;
-
- GLdouble cx = output->region.extents.x1 + halfW;
- GLdouble cy = (h - output->region.extents.y2) + halfH;
+ GLdouble x1 = region->extents.x1 > 0 ? 1.0 / region->extents.x1 : MAXSHORT;
+ GLdouble y1 = region->extents.y1 > 0 ? 1.0 / region->extents.y1 : MAXSHORT;
+ GLdouble x2 = region->extents.x2 > 0 ? 1.0 / region->extents.x2 : MAXSHORT;
+ GLdouble y2 = region->extents.y2 > 0 ? 1.0 / region->extents.y2 : MAXSHORT;
- GLdouble top[4] = { 0.0, halfH / (cy - p1[1]), 0.0, 0.5 };
- GLdouble bottom[4] = { 0.0, halfH / (cy - p2[1]), 0.0, 0.5 };
- GLdouble left[4] = { halfW / (cx - p1[0]), 0.0, 0.0, 0.5 };
- GLdouble right[4] = { halfW / (cx - p2[0]), 0.0, 0.0, 0.5 };
+ GLdouble top[4] = { 0.0, y1, 0.0, -1.0 };
+ GLdouble bottom[4] = { 0.0, -y2, 0.0, 1.0 };
+ GLdouble left[4] = { x1, 0.0, 0.0, -1.0 };
+ GLdouble right[4] = { -x2, 0.0, 0.0, 1.0 };
glPushMatrix ();
glLoadMatrixf (transform->m);
@@ -461,9 +343,6 @@ disableOutputClipping (CompScreen *screen)
glDisable (GL_CLIP_PLANE3);
}
-#define CLIP_PLANE_MASK (PAINT_SCREEN_TRANSFORMED_MASK | \
- PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK)
-
void
paintTransformedOutput (CompScreen *screen,
const ScreenPaintAttrib *sAttrib,
@@ -481,34 +360,14 @@ paintTransformedOutput (CompScreen *screen,
(*screen->applyScreenTransform) (screen, sAttrib, output, &sTransform);
- if ((mask & CLIP_PLANE_MASK) == CLIP_PLANE_MASK)
- {
- screen->enableOutputClipping (screen, &sTransform, region, output);
-
- transformToScreenSpace (screen, output, -sAttrib->zTranslate,
- &sTransform);
-
- glPushMatrix ();
- glLoadMatrixf (sTransform.m);
+ transformToScreenSpace (screen, output, -sAttrib->zTranslate, &sTransform);
- paintOutputRegion (screen, &sTransform, region, output, mask);
-
- glPopMatrix ();
-
- screen->disableOutputClipping (screen);
- }
- else
- {
- transformToScreenSpace (screen, output, -sAttrib->zTranslate,
- &sTransform);
-
- glPushMatrix ();
- glLoadMatrixf (sTransform.m);
+ glPushMatrix ();
+ glLoadMatrixf (sTransform.m);
- paintOutputRegion (screen, &sTransform, region, output, mask);
+ paintOutputRegion (screen, &sTransform, region, output, mask);
- glPopMatrix ();
- }
+ glPopMatrix ();
}
Bool
@@ -1194,7 +1053,13 @@ drawWindow (CompWindow *w,
return TRUE;
if (w->attrib.map_state != IsViewable)
- return TRUE;
+ return FALSE;
+
+ if (!w->damaged)
+ return FALSE;
+
+ if (!w->parent || !w->parent->redirectSubwindows)
+ return FALSE;
if (!w->texture->pixmap && !bindWindow (w))
return FALSE;
@@ -1210,6 +1075,44 @@ drawWindow (CompWindow *w,
return TRUE;
}
+static int
+paintOffsetX (CompWindow *w,
+ int x)
+{
+ int vWidth = w->screen->width * (w->screen->hsize - 1);
+
+ if (vWidth)
+ {
+ int wx = w->attrib.x + x;
+
+ if (wx - w->input.left < -vWidth)
+ return x + vWidth + w->screen->width;
+ else if (wx + w->width + w->input.right > vWidth)
+ return x - vWidth - w->screen->width;
+ }
+
+ return x;
+}
+
+static int
+paintOffsetY (CompWindow *w,
+ int y)
+{
+ int vHeight = w->screen->height * (w->screen->vsize - 1);
+
+ if (vHeight)
+ {
+ int wy = w->attrib.y + y;
+
+ if (wy - w->input.top < -vHeight)
+ return y + vHeight + w->screen->height;
+ else if (wy + w->height + w->input.bottom > vHeight)
+ return y - vHeight - w->screen->height;
+ }
+
+ return y;
+}
+
Bool
paintWindow (CompWindow *w,
const WindowPaintAttrib *attrib,
@@ -1217,8 +1120,10 @@ paintWindow (CompWindow *w,
Region region,
unsigned int mask)
{
- FragmentAttrib fragment;
- Bool status;
+ CompWindow *c;
+ CompWalker walk;
+ CompPainter painter;
+ Bool status;
w->lastPaint = *attrib;
@@ -1229,38 +1134,395 @@ paintWindow (CompWindow *w,
if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
{
- if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
- return FALSE;
+ Bool occlude = TRUE;
if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
- return FALSE;
+ occlude = FALSE;
+
+ if (w->shaded)
+ occlude = FALSE;
+
+ if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
+ occlude = FALSE;
if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
- return FALSE;
+ occlude = FALSE;
- if (w->shaded)
- return FALSE;
+ if (w->attrib.map_state != IsViewable)
+ occlude = FALSE;
- return TRUE;
+ if (!w->redirected || !w->damaged)
+ occlude = FALSE;
+
+ (*w->screen->initWindowWalker) (w->screen, w, &walk);
+ (*w->screen->initObjectPainter) (w->screen, &painter);
+
+ c = (*walk.last) (w);
+ if (c)
+ {
+ Region r = XCreateRegion ();
+ CompTransform wTransform = *transform;
+ int count = 0;
+ CompWindow *fullscreenWindow = NULL;
+
+ assert (r);
+
+ XIntersectRegion (region, w->region, r);
+
+ if (w->attrib.x || w->attrib.y)
+ {
+ matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0);
+ XOffsetRegion (r, -w->attrib.x, -w->attrib.y);
+ mask |= PAINT_WINDOW_WITH_OFFSET_MASK;
+ }
+
+ for (; c; c = (*walk.prev) (c))
+ {
+ CompTransform cTransform = wTransform;
+ WindowPaintAttrib cPaint = c->paint;
+ int viewportOffsetX = 0;
+ int viewportOffsetY = 0;
+ int offsetMask = 0;
+
+ if (c->destroyed)
+ continue;
+
+ cPaint.opacity = MULTIPLY_USHORT (cPaint.opacity,
+ attrib->opacity);
+ cPaint.brightness = MULTIPLY_USHORT (cPaint.brightness,
+ attrib->brightness);
+ cPaint.saturation = MULTIPLY_USHORT (cPaint.saturation,
+ attrib->saturation);
+
+ if (!windowOnAllViewports (c))
+ {
+ if (w->viewportOffsetX || w->viewportOffsetY)
+ {
+ viewportOffsetX = paintOffsetX (c, w->viewportOffsetX);
+ viewportOffsetY = paintOffsetY (c, w->viewportOffsetY);
+
+ matrixTranslate (&cTransform,
+ viewportOffsetX,
+ viewportOffsetY,
+ 0);
+
+ XOffsetRegion (r,
+ -viewportOffsetX,
+ -viewportOffsetY);
+
+ offsetMask = PAINT_WINDOW_WITH_OFFSET_MASK;
+ }
+ }
+
+ /* copy region */
+ XSubtractRegion (r, &emptyRegion, c->clip);
+
+ if ((*painter.paintObject) (c,
+ &cPaint,
+ &cTransform,
+ r,
+ mask | offsetMask) && !occlude)
+ XSubtractRegion (r, c->region, r);
+
+ if (viewportOffsetX || viewportOffsetY)
+ XOffsetRegion (r,
+ viewportOffsetX,
+ viewportOffsetY);
+
+ /* unredirect top most top-level fullscreen windows. */
+ if (!w->parent &&
+ count == 0 &&
+ w->screen->opt[COMP_SCREEN_OPTION_UNREDIRECT_FS].value.b)
+ {
+ if (XEqualRegion (c->region, &w->screen->region) &&
+ !REGION_NOT_EMPTY (r))
+ {
+ fullscreenWindow = c;
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < w->screen->nOutputDev; i++)
+ if (XEqualRegion (c->region,
+ &w->screen->outputDev[i].region))
+ fullscreenWindow = c;
+ }
+ }
+
+ count++;
+ }
+
+ if (fullscreenWindow)
+ unredirectWindow (fullscreenWindow);
+
+ if (!occlude)
+ {
+ if (w->attrib.x || w->attrib.y)
+ XOffsetRegion (r, w->attrib.x, w->attrib.y);
+
+ XSubtractRegion (region, w->region, region);
+ XUnionRegion (region, r, region);
+ }
+
+ XDestroyRegion (r);
+ }
+
+ if (painter.fini)
+ (*painter.fini) (w->screen, &painter);
+ if (walk.fini)
+ (*walk.fini) (w->screen, &walk);
+
+ return occlude;
}
if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
- return TRUE;
+ {
+ status = TRUE;
+ }
+ else
+ {
+ FragmentAttrib fragment;
- initFragmentAttrib (&fragment, attrib);
+ initFragmentAttrib (&fragment, attrib);
- if (mask & PAINT_WINDOW_TRANSFORMED_MASK ||
- mask & PAINT_WINDOW_WITH_OFFSET_MASK)
- {
- glPushMatrix ();
- glLoadMatrixf (transform->m);
+ if (mask & (PAINT_WINDOW_TRANSFORMED_MASK |
+ PAINT_WINDOW_WITH_OFFSET_MASK))
+ {
+ glPushMatrix ();
+ glLoadMatrixf (transform->m);
+ }
+
+ status = (*w->screen->drawWindow) (w, transform, &fragment, region, mask);
+
+ if (mask & (PAINT_WINDOW_TRANSFORMED_MASK |
+ PAINT_WINDOW_WITH_OFFSET_MASK))
+ glPopMatrix ();
}
- status = (*w->screen->drawWindow) (w, transform, &fragment, region, mask);
+ (*w->screen->initWindowWalker) (w->screen, w, &walk);
+ (*w->screen->initObjectPainter) (w->screen, &painter);
+
+ c = (*walk.first) (w);
+ if (c)
+ {
+ Region clip = NULL;
+ CompTransform wTransform = *transform;
+ unsigned int clipMask = PAINT_WINDOW_WITH_TRANSFORMED_CHILD_MASK;
+
+ if (!(mask & PAINT_WINDOW_CLIP_MASK))
+ {
+ clip = XCreateRegion ();
+ assert (clip);
+ XIntersectRegion (region, w->region, clip);
+ }
+
+ if (w->attrib.x || w->attrib.y)
+ {
+ matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0);
+
+ mask |= PAINT_WINDOW_WITH_OFFSET_MASK;
- if (mask & PAINT_WINDOW_TRANSFORMED_MASK ||
- mask & PAINT_WINDOW_WITH_OFFSET_MASK)
- glPopMatrix ();
+ if (clip)
+ XOffsetRegion (clip, -w->attrib.x, -w->attrib.y);
+ }
+
+ if (w->redirectSubwindows)
+ {
+ /* root only need clip planes when transformed */
+ if (!w->parent)
+ clipMask |= PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
+
+ if ((mask & clipMask) == clipMask)
+ {
+ glPushAttrib (GL_TRANSFORM_BIT);
+
+ if (mask & PAINT_WINDOW_CLIP_MASK)
+ {
+ REGION reg;
+
+ reg.rects = ®.extents;
+ reg.numRects = reg.size = 1;
+ reg.extents = w->clip->extents;
+
+ if (reg.extents.x1 < w->region->extents.x1)
+ reg.extents.x1 = w->region->extents.x1;
+ if (reg.extents.y1 < w->region->extents.y1)
+ reg.extents.y1 = w->region->extents.y1;
+ if (reg.extents.x2 > w->region->extents.x2)
+ reg.extents.x2 = w->region->extents.x2;
+ if (reg.extents.y2 > w->region->extents.y2)
+ reg.extents.y2 = w->region->extents.y2;
+
+ reg.extents.x1 -= w->attrib.x;
+ reg.extents.y1 -= w->attrib.y;
+ reg.extents.x2 -= w->attrib.x;
+ reg.extents.y2 -= w->attrib.y;
+
+ (*w->screen->enableOutputClipping) (w->screen,
+ &wTransform,
+ ®,
+ 0);
+ }
+ else
+ (*w->screen->enableOutputClipping) (w->screen,
+ &wTransform,
+ clip,
+ 0);
+ }
+ }
+
+ /* paint all sub-windows from bottom to top */
+ for (; c; c = (*walk.next) (c))
+ {
+ CompTransform cTransform = wTransform;
+ WindowPaintAttrib cPaint = c->paint;
+ int viewportOffsetX = 0;
+ int viewportOffsetY = 0;
+ int offsetMask = 0;
+
+ if (c->destroyed)
+ continue;
+
+ cPaint.opacity = MULTIPLY_USHORT (cPaint.opacity,
+ attrib->opacity);
+ cPaint.brightness = MULTIPLY_USHORT (cPaint.brightness,
+ attrib->brightness);
+ cPaint.saturation = MULTIPLY_USHORT (cPaint.saturation,
+ attrib->saturation);
+
+ if (mask & PAINT_WINDOW_CLIP_MASK)
+ clip = c->clip;
+
+ if (!windowOnAllViewports (c))
+ {
+ if (w->viewportOffsetX || w->viewportOffsetY)
+ {
+ viewportOffsetX = paintOffsetX (c, w->viewportOffsetX);
+ viewportOffsetY = paintOffsetY (c, w->viewportOffsetY);
+
+ matrixTranslate (&cTransform,
+ viewportOffsetX,
+ viewportOffsetY,
+ 0);
+
+ if (clip != c->clip)
+ XOffsetRegion (clip,
+ -viewportOffsetX,
+ -viewportOffsetY);
+
+ offsetMask = PAINT_WINDOW_WITH_OFFSET_MASK;
+ }
+ }
+
+ (*painter.paintObject) (c,
+ &cPaint,
+ &cTransform,
+ clip,
+ mask | offsetMask);
+
+ if (clip != c->clip && (viewportOffsetX || viewportOffsetY))
+ XOffsetRegion (clip,
+ viewportOffsetX,
+ viewportOffsetY);
+ }
+
+ if (w->redirectSubwindows)
+ {
+ if ((mask & clipMask) == clipMask)
+ glPopAttrib ();
+ }
+
+ if (!(mask & PAINT_WINDOW_CLIP_MASK))
+ XDestroyRegion (clip);
+ }
+
+ if (painter.fini)
+ (*painter.fini) (w->screen, &painter);
+ if (walk.fini)
+ (*walk.fini) (w->screen, &walk);
return status;
}
+
+static void
+drawWindowAndChildren (CompWindow *w,
+ const WindowPaintAttrib *attrib,
+ const CompTransform *transform,
+ Region region)
+{
+ FragmentAttrib fragment;
+ unsigned int wMask = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
+
+ if (attrib)
+ initFragmentAttrib (&fragment, attrib);
+ else
+ initFragmentAttrib (&fragment, &w->lastPaint);
+
+ if (w->alpha || fragment.opacity != OPAQUE)
+ wMask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+
+ (*w->screen->drawWindow) (w, transform, &fragment, region, wMask);
+
+ if (w->windows)
+ {
+ Region r;
+
+ r = XCreateRegion ();
+ if (r)
+ {
+ CompWindow *c;
+
+ XSubtractRegion (region, &emptyRegion, r);
+ XIntersectRegion (r, w->region, r);
+ XOffsetRegion (r, -w->attrib.x, -w->attrib.y);
+
+ glTranslatef (w->attrib.x, w->attrib.y, 0);
+
+ for (c = w->windows; c; c = c->next)
+ drawWindowAndChildren (c, attrib, transform, r);
+
+ glTranslatef (-w->attrib.x, -w->attrib.y, 0);
+
+ XDestroyRegion (r);
+ }
+ }
+}
+
+void
+drawTransformedWindowWithChildren (CompWindow *w,
+ const WindowPaintAttrib *attrib,
+ const CompTransform *transform)
+{
+ FragmentAttrib fragment;
+ unsigned int wMask = PAINT_WINDOW_TRANSFORMED_MASK;
+
+ if (attrib)
+ initFragmentAttrib (&fragment, attrib);
+ else
+ initFragmentAttrib (&fragment, &w->lastPaint);
+
+ if (w->alpha || fragment.opacity != OPAQUE)
+ wMask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+
+ glPushMatrix ();
+ glLoadMatrixf (transform->m);
+
+ (*w->screen->drawWindow) (w, transform, &fragment, &infiniteRegion, wMask);
+
+ if (w->windows)
+ {
+ CompWindow *c;
+
+ XOffsetRegion (w->region, -w->attrib.x, -w->attrib.y);
+ glTranslatef (w->attrib.x, w->attrib.y, 0);
+
+ for (c = w->windows; c; c = c->next)
+ drawWindowAndChildren (c, attrib, transform, w->region);
+
+ glTranslatef (-w->attrib.x, -w->attrib.y, 0);
+ XOffsetRegion (w->region, w->attrib.x, w->attrib.y);
+ }
+
+ glPopMatrix ();
+}
diff --git a/src/screen.c b/src/screen.c
index 33cb3cc..83caa9f 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -184,6 +184,9 @@ setDesktopHints (CompScreen *s)
unsigned long *data;
int size, offset, hintSize, i;
+ if (!s->root.substructureRedirect)
+ return;
+
size = s->nDesktop * 2 + s->nDesktop * 2 + s->nDesktop * 4 + 1;
data = malloc (sizeof (unsigned long) * size);
@@ -200,7 +203,7 @@ setDesktopHints (CompScreen *s)
}
if (!desktopHintEqual (s, data, size, offset, hintSize))
- XChangeProperty (d->display, s->root, d->desktopViewportAtom,
+ XChangeProperty (d->display, s->root.id, d->desktopViewportAtom,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &data[offset], hintSize);
@@ -213,7 +216,7 @@ setDesktopHints (CompScreen *s)
}
if (!desktopHintEqual (s, data, size, offset, hintSize))
- XChangeProperty (d->display, s->root, d->desktopGeometryAtom,
+ XChangeProperty (d->display, s->root.id, d->desktopGeometryAtom,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &data[offset], hintSize);
@@ -229,7 +232,7 @@ setDesktopHints (CompScreen *s)
}
if (!desktopHintEqual (s, data, size, offset, hintSize))
- XChangeProperty (d->display, s->root, d->workareaAtom,
+ XChangeProperty (d->display, s->root.id, d->workareaAtom,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &data[offset], hintSize);
@@ -239,7 +242,7 @@ setDesktopHints (CompScreen *s)
hintSize = 1;
if (!desktopHintEqual (s, data, size, offset, hintSize))
- XChangeProperty (d->display, s->root, d->numberOfDesktopsAtom,
+ XChangeProperty (d->display, s->root.id, d->numberOfDesktopsAtom,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &data[offset], hintSize);
@@ -375,8 +378,11 @@ updateOutputDevices (CompScreen *s)
updateWorkareaForScreen (s);
- setDefaultViewport (s);
- damageScreen (s);
+ if (manualCompositeManagement)
+ {
+ setDefaultViewport (s);
+ damageScreen (s);
+ }
region = XCreateRegion ();
if (region)
@@ -644,9 +650,9 @@ static void
updateStartupFeedback (CompScreen *s)
{
if (s->startupSequences)
- XDefineCursor (s->display->display, s->root, s->busyCursor);
+ XDefineCursor (s->display->display, s->root.id, s->busyCursor);
else
- XDefineCursor (s->display->display, s->root, s->normalCursor);
+ XDefineCursor (s->display->display, s->root.id, s->normalCursor);
}
#define STARTUP_TIMEOUT_DELAY 15000
@@ -853,11 +859,12 @@ reshape (CompScreen *s,
{
#ifdef USE_COW
- if (useCow)
+ if (useCow && manualCompositeManagement)
XMoveResizeWindow (s->display->display, s->overlay, 0, 0, w, h);
#endif
- if (s->display->xineramaExtension)
+ if (s->display->xineramaExtension &&
+ XineramaIsActive (s->display->display))
{
CompDisplay *d = s->display;
@@ -971,7 +978,7 @@ updateScreenBackground (CompScreen *screen,
for (i = 0; pixmap == 0 && i < 2; i++)
{
- status = XGetWindowProperty (dpy, screen->root,
+ status = XGetWindowProperty (dpy, screen->root.id,
screen->display->xBackgroundAtom[i],
0, 4, FALSE, AnyPropertyType,
&actualType, &actualFormat, &nItems,
@@ -1054,7 +1061,7 @@ detectRefreshRateOfScreen (CompScreen *s)
{
XRRScreenConfiguration *config;
- config = XRRGetScreenInfo (s->display->display, s->root);
+ config = XRRGetScreenInfo (s->display->display, s->root.id);
value.i = (int) XRRConfigCurrentRate (config);
XRRFreeScreenConfigInfo (config);
@@ -1081,6 +1088,8 @@ setSupportingWmCheck (CompScreen *s)
{
CompDisplay *d = s->display;
+ s->root.supportingWmCheckWindow = s->grabWindow;
+
XChangeProperty (d->display, s->grabWindow, d->supportingWmCheckAtom,
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &s->grabWindow, 1);
@@ -1098,7 +1107,7 @@ setSupportingWmCheck (CompScreen *s)
XA_ATOM, 32, PropModeAppend,
(unsigned char *) &d->winStateHiddenAtom, 1);
- XChangeProperty (d->display, s->root, d->supportingWmCheckAtom,
+ XChangeProperty (d->display, s->root.id, d->supportingWmCheckAtom,
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &s->grabWindow, 1);
}
@@ -1199,11 +1208,66 @@ setSupported (CompScreen *s)
data[i++] = d->moveResizeWindowAtom;
data[i++] = d->restackWindowAtom;
- XChangeProperty (d->display, s->root, d->supportedAtom, XA_ATOM, 32,
+ data[i++] = d->syncStateAtom;
+
+ XChangeProperty (d->display, s->root.id, d->supportedAtom, XA_ATOM, 32,
PropModeReplace, (unsigned char *) data, i);
}
-static void
+void
+getSupportingWmCheck (CompWindow *w)
+{
+ CompDisplay *d = w->screen->display;
+ Atom actual;
+ int result, format;
+ unsigned long n, left;
+ unsigned char *propData;
+
+ w->supportingWmCheckWindow = None;
+ w->syncStateSupport = FALSE;
+
+ result = XGetWindowProperty (d->display, w->id,
+ d->supportingWmCheckAtom, 0L, 1L, FALSE,
+ XA_WINDOW, &actual, &format,
+ &n, &left, &propData);
+ if (result == Success && n && propData)
+ {
+ Window wmCheckWindow = *((unsigned long *) propData);
+
+ XFree (propData);
+
+ result = XGetWindowProperty (d->display,
+ wmCheckWindow,
+ d->supportingWmCheckAtom, 0L, 1L, FALSE,
+ XA_WINDOW, &actual, &format,
+ &n, &left, &propData);
+ if (result == Success && n && propData)
+ {
+ XFree (propData);
+
+ w->supportingWmCheckWindow = wmCheckWindow;
+
+ result = XGetWindowProperty (d->display,
+ w->id,
+ d->supportedAtom, 0L, 4096L,
+ FALSE, XA_ATOM, &actual, &format,
+ &n, &left, &propData);
+ if (result == Success && n && propData)
+ {
+ unsigned long *data = (unsigned long *) propData;
+ int i;
+
+ for (i = 0; i < n; i++)
+ if ((Atom) data[i] == d->syncStateAtom)
+ w->syncStateSupport = TRUE;
+
+ XFree (propData);
+ }
+ }
+ }
+}
+
+void
getDesktopHints (CompScreen *s)
{
CompDisplay *d = s->display;
@@ -1215,7 +1279,7 @@ getDesktopHints (CompScreen *s)
if (useDesktopHints)
{
- result = XGetWindowProperty (s->display->display, s->root,
+ result = XGetWindowProperty (s->display->display, s->root.id,
d->numberOfDesktopsAtom, 0L, 1L, FALSE,
XA_CARDINAL, &actual, &format,
&n, &left, &propData);
@@ -1229,7 +1293,7 @@ getDesktopHints (CompScreen *s)
s->nDesktop = data[0];
}
- result = XGetWindowProperty (s->display->display, s->root,
+ result = XGetWindowProperty (s->display->display, s->root.id,
d->currentDesktopAtom, 0L, 1L, FALSE,
XA_CARDINAL, &actual, &format,
&n, &left, &propData);
@@ -1244,7 +1308,7 @@ getDesktopHints (CompScreen *s)
}
}
- result = XGetWindowProperty (s->display->display, s->root,
+ result = XGetWindowProperty (s->display->display, s->root.id,
d->desktopViewportAtom, 0L, 2L,
FALSE, XA_CARDINAL, &actual, &format,
&n, &left, &propData);
@@ -1265,7 +1329,7 @@ getDesktopHints (CompScreen *s)
XFree (propData);
}
- result = XGetWindowProperty (s->display->display, s->root,
+ result = XGetWindowProperty (s->display->display, s->root.id,
d->showingDesktopAtom, 0L, 1L, FALSE,
XA_CARDINAL, &actual, &format,
&n, &left, &propData);
@@ -1279,17 +1343,20 @@ getDesktopHints (CompScreen *s)
(*s->enterShowDesktopMode) (s);
}
- data[0] = s->currentDesktop;
+ if (s->root.substructureRedirect)
+ {
+ data[0] = s->currentDesktop;
- XChangeProperty (d->display, s->root, d->currentDesktopAtom,
- XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *) data, 1);
+ XChangeProperty (d->display, s->root.id, d->currentDesktopAtom,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) data, 1);
- data[0] = s->showingDesktopMask ? TRUE : FALSE;
+ data[0] = s->showingDesktopMask ? TRUE : FALSE;
- XChangeProperty (d->display, s->root, d->showingDesktopAtom,
- XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *) data, 1);
+ XChangeProperty (d->display, s->root.id, d->showingDesktopAtom,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) data, 1);
+ }
}
void
@@ -1297,7 +1364,7 @@ showOutputWindow (CompScreen *s)
{
#ifdef USE_COW
- if (useCow)
+ if (useCow && manualCompositeManagement)
{
Display *dpy = s->display->display;
XserverRegion region;
@@ -1326,7 +1393,7 @@ hideOutputWindow (CompScreen *s)
{
#ifdef USE_COW
- if (useCow)
+ if (useCow && manualCompositeManagement)
{
Display *dpy = s->display->display;
XserverRegion region;
@@ -1349,7 +1416,7 @@ updateOutputWindow (CompScreen *s)
{
#ifdef USE_COW
- if (useCow)
+ if (useCow && manualCompositeManagement)
{
Display *dpy = s->display->display;
XserverRegion region;
@@ -1365,7 +1432,7 @@ updateOutputWindow (CompScreen *s)
XSubtractRegion (&s->region, &emptyRegion, tmpRegion);
- for (w = s->reverseWindows; w; w = w->prev)
+ for (w = s->root.reverseWindows; w; w = w->prev)
if (w->overlayWindow)
{
XSubtractRegion (tmpRegion, w->region, tmpRegion);
@@ -1393,9 +1460,10 @@ makeOutputWindow (CompScreen *s)
{
#ifdef USE_COW
- if (useCow)
+ if (useCow && manualCompositeManagement)
{
- s->overlay = XCompositeGetOverlayWindow (s->display->display, s->root);
+ s->overlay = XCompositeGetOverlayWindow (s->display->display,
+ s->root.id);
s->output = s->overlay;
XSelectInput (s->display->display, s->output, ExposureMask);
@@ -1403,7 +1471,7 @@ makeOutputWindow (CompScreen *s)
else
#endif
- s->output = s->overlay = s->root;
+ s->output = s->overlay = s->root.id;
showOutputWindow (s);
}
@@ -1417,10 +1485,13 @@ enterShowDesktopMode (CompScreen *s)
int count = 0;
CompOption *st = &d->opt[COMP_DISPLAY_OPTION_HIDE_SKIP_TASKBAR_WINDOWS];
+ if (!s->root.substructureRedirect)
+ return;
+
s->showingDesktopMask = ~(CompWindowTypeDesktopMask |
CompWindowTypeDockMask);
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if ((s->showingDesktopMask & w->wmType) &&
(!(w->state & CompWindowStateSkipTaskbarMask) || st->value.b))
@@ -1443,7 +1514,7 @@ enterShowDesktopMode (CompScreen *s)
data = 0;
}
- XChangeProperty (s->display->display, s->root,
+ XChangeProperty (s->display->display, s->root.id,
s->display->showingDesktopAtom,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &data, 1);
@@ -1456,6 +1527,9 @@ leaveShowDesktopMode (CompScreen *s,
CompWindow *w;
unsigned long data = 0;
+ if (!s->root.substructureRedirect)
+ return;
+
if (window)
{
if (!window->inShowDesktopMode)
@@ -1465,7 +1539,7 @@ leaveShowDesktopMode (CompScreen *s,
showWindow (window);
/* return if some other window is still in show desktop mode */
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
if (w->inShowDesktopMode)
return;
@@ -1475,7 +1549,7 @@ leaveShowDesktopMode (CompScreen *s,
{
s->showingDesktopMask = 0;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (!w->inShowDesktopMode)
continue;
@@ -1489,22 +1563,22 @@ leaveShowDesktopMode (CompScreen *s,
focusDefaultWindow (s);
}
- XChangeProperty (s->display->display, s->root,
+ XChangeProperty (s->display->display, s->root.id,
s->display->showingDesktopAtom,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &data, 1);
}
static CompWindow *
-walkFirst (CompScreen *s)
+walkFirst (CompWindow *parent)
{
- return s->windows;
+ return parent->windows;
}
static CompWindow *
-walkLast (CompScreen *s)
+walkLast (CompWindow *parent)
{
- return s->reverseWindows;
+ return parent->reverseWindows;
}
static CompWindow *
@@ -1521,6 +1595,7 @@ walkPrev (CompWindow *w)
static void
initWindowWalker (CompScreen *screen,
+ CompWindow *window,
CompWalker *walker)
{
walker->fini = NULL;
@@ -1530,6 +1605,42 @@ initWindowWalker (CompScreen *screen,
walker->prev = walkPrev;
}
+static Bool
+paintObject (CompWindow *w,
+ const WindowPaintAttrib *attrib,
+ const CompTransform *transform,
+ Region region,
+ unsigned int mask)
+{
+ PaintWindowProc paint = w->screen->paintWindow;
+ Bool status;
+
+ if (w->parent)
+ w->paintWindowStack = w->parent->paintWindowStack;
+ else
+ w->paintWindowStack = paint;
+
+ status = (*w->paintWindowStack) (w, attrib, transform, region, mask);
+
+ w->screen->paintWindow = paint;
+
+ return status;
+}
+
+static void
+initObjectPainter (CompScreen *screen,
+ CompPainter *painter)
+{
+ painter->fini = NULL;
+ painter->paintObject = paintObject;
+}
+
+static FuncPtr
+dummyGetProcAddress (const GLubyte *procName)
+{
+ return NULL;
+}
+
static void
freeScreen (CompScreen *s)
{
@@ -1611,7 +1722,7 @@ addScreen (CompDisplay *display,
GLfloat light0Position[] = { -0.5f, 0.5f, -9.0f, 1.0f };
CompWindow *w;
- s = malloc (sizeof (CompScreen));
+ s = calloc (1, sizeof (CompScreen));
if (!s)
return FALSE;
@@ -1652,9 +1763,6 @@ addScreen (CompDisplay *display,
s->hsize = s->opt[COMP_SCREEN_OPTION_HSIZE].value.i;
s->vsize = s->opt[COMP_SCREEN_OPTION_VSIZE].value.i;
- s->windowOffsetX = 0;
- s->windowOffsetY = 0;
-
s->nDesktop = 1;
s->currentDesktop = 0;
@@ -1680,11 +1788,12 @@ addScreen (CompDisplay *display,
s->screenNum = screenNum;
s->colormap = DefaultColormap (dpy, screenNum);
- s->root = XRootWindow (dpy, screenNum);
s->mapNum = 1;
s->activeNum = 1;
+ initRootWindow (s, &s->root);
+
s->groups = NULL;
s->snContext = sn_monitor_context_new (display->snDisplay,
@@ -1712,9 +1821,6 @@ addScreen (CompDisplay *display,
s->nOutputDev = 0;
s->currentOutputDev = 0;
- s->windows = 0;
- s->reverseWindows = 0;
-
s->nextRedraw = 0;
s->frameStatus = 0;
s->timeMult = 1;
@@ -1781,11 +1887,12 @@ addScreen (CompDisplay *display,
s->outputChangeNotify = outputChangeNotify;
- s->initWindowWalker = initWindowWalker;
+ s->initWindowWalker = initWindowWalker;
+ s->initObjectPainter = initObjectPainter;
- s->getProcAddress = 0;
+ s->getProcAddress = dummyGetProcAddress;
- if (!XGetWindowAttributes (dpy, s->root, &s->attrib))
+ if (!XGetWindowAttributes (dpy, s->root.id, &s->attrib))
return FALSE;
s->workArea.x = 0;
@@ -1818,7 +1925,7 @@ addScreen (CompDisplay *display,
return FALSE;
}
- bitmap = XCreateBitmapFromData (dpy, s->root, &data, 1, 1);
+ bitmap = XCreateBitmapFromData (dpy, s->root.id, &data, 1, 1);
if (!bitmap)
{
compLogMessage ("core", CompLogLevelFatal, "Couldn't create bitmap");
@@ -1839,383 +1946,423 @@ addScreen (CompDisplay *display,
XFreePixmap (dpy, bitmap);
XFreeColors (dpy, s->colormap, &black.pixel, 1, 0);
- glXGetConfig (dpy, visinfo, GLX_USE_GL, &value);
- if (!value)
- {
- compLogMessage ("core", CompLogLevelFatal,
- "Root visual is not a GL visual");
- XFree (visinfo);
- return FALSE;
- }
-
- glXGetConfig (dpy, visinfo, GLX_DOUBLEBUFFER, &value);
- if (!value)
+ if (s->root.redirectSubwindows)
{
- compLogMessage ("core", CompLogLevelFatal,
- "Root visual is not a double buffered GL visual");
- XFree (visinfo);
- return FALSE;
- }
+ glXGetConfig (dpy, visinfo, GLX_USE_GL, &value);
+ if (!value)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "Root visual is not a GL visual");
+ XFree (visinfo);
+ return FALSE;
+ }
- s->ctx = glXCreateContext (dpy, visinfo, NULL, !indirectRendering);
- if (!s->ctx)
- {
- compLogMessage ("core", CompLogLevelFatal, "glXCreateContext failed");
- XFree (visinfo);
+ glXGetConfig (dpy, visinfo, GLX_DOUBLEBUFFER, &value);
+ if (!value)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "Root visual is not a double buffered GL visual");
+ XFree (visinfo);
+ return FALSE;
+ }
- return FALSE;
- }
+ s->ctx = glXCreateContext (dpy, visinfo, NULL, !indirectRendering);
+ if (!s->ctx)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "glXCreateContext failed");
+ XFree (visinfo);
- glxExtensions = glXQueryExtensionsString (dpy, screenNum);
- if (!strstr (glxExtensions, "GLX_EXT_texture_from_pixmap"))
- {
- compLogMessage ("core", CompLogLevelFatal,
- "GLX_EXT_texture_from_pixmap is missing");
- XFree (visinfo);
+ return FALSE;
+ }
- return FALSE;
- }
+ glxExtensions = glXQueryExtensionsString (dpy, screenNum);
+ if (!strstr (glxExtensions, "GLX_EXT_texture_from_pixmap"))
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "GLX_EXT_texture_from_pixmap is missing");
+ XFree (visinfo);
- XFree (visinfo);
+ return FALSE;
+ }
- if (!strstr (glxExtensions, "GLX_SGIX_fbconfig"))
- {
- compLogMessage ("core", CompLogLevelFatal,
- "GLX_SGIX_fbconfig is missing");
- return FALSE;
- }
+ XFree (visinfo);
- s->getProcAddress = (GLXGetProcAddressProc)
- getProcAddress (s, "glXGetProcAddressARB");
- s->bindTexImage = (GLXBindTexImageProc)
- getProcAddress (s, "glXBindTexImageEXT");
- s->releaseTexImage = (GLXReleaseTexImageProc)
- getProcAddress (s, "glXReleaseTexImageEXT");
- s->queryDrawable = (GLXQueryDrawableProc)
- getProcAddress (s, "glXQueryDrawable");
- s->getFBConfigs = (GLXGetFBConfigsProc)
- getProcAddress (s, "glXGetFBConfigs");
- s->getFBConfigAttrib = (GLXGetFBConfigAttribProc)
- getProcAddress (s, "glXGetFBConfigAttrib");
- s->createPixmap = (GLXCreatePixmapProc)
- getProcAddress (s, "glXCreatePixmap");
-
- if (!s->bindTexImage)
- {
- compLogMessage ("core", CompLogLevelFatal,
- "glXBindTexImageEXT is missing");
- return FALSE;
- }
+ if (!strstr (glxExtensions, "GLX_SGIX_fbconfig"))
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "GLX_SGIX_fbconfig is missing");
+ return FALSE;
+ }
- if (!s->releaseTexImage)
- {
- compLogMessage ("core", CompLogLevelFatal,
- "glXReleaseTexImageEXT is missing");
- return FALSE;
- }
+ s->getProcAddress = (GLXGetProcAddressProc)
+ getProcAddress (s, "glXGetProcAddressARB");
+ s->bindTexImage = (GLXBindTexImageProc)
+ getProcAddress (s, "glXBindTexImageEXT");
+ s->releaseTexImage = (GLXReleaseTexImageProc)
+ getProcAddress (s, "glXReleaseTexImageEXT");
+ s->queryDrawable = (GLXQueryDrawableProc)
+ getProcAddress (s, "glXQueryDrawable");
+ s->getFBConfigs = (GLXGetFBConfigsProc)
+ getProcAddress (s, "glXGetFBConfigs");
+ s->getFBConfigAttrib = (GLXGetFBConfigAttribProc)
+ getProcAddress (s, "glXGetFBConfigAttrib");
+ s->createPixmap = (GLXCreatePixmapProc)
+ getProcAddress (s, "glXCreatePixmap");
+
+ if (!s->bindTexImage)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "glXBindTexImageEXT is missing");
+ return FALSE;
+ }
- if (!s->queryDrawable ||
- !s->getFBConfigs ||
- !s->getFBConfigAttrib ||
- !s->createPixmap)
- {
- compLogMessage ("core", CompLogLevelFatal,
- "fbconfig functions missing");
- return FALSE;
- }
+ if (!s->releaseTexImage)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "glXReleaseTexImageEXT is missing");
+ return FALSE;
+ }
- s->copySubBuffer = NULL;
- if (strstr (glxExtensions, "GLX_MESA_copy_sub_buffer"))
- s->copySubBuffer = (GLXCopySubBufferProc)
- getProcAddress (s, "glXCopySubBufferMESA");
+ if (!s->queryDrawable ||
+ !s->getFBConfigs ||
+ !s->getFBConfigAttrib ||
+ !s->createPixmap)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "fbconfig functions missing");
+ return FALSE;
+ }
- s->getVideoSync = NULL;
- s->waitVideoSync = NULL;
- if (strstr (glxExtensions, "GLX_SGI_video_sync"))
- {
- s->getVideoSync = (GLXGetVideoSyncProc)
- getProcAddress (s, "glXGetVideoSyncSGI");
+ s->copySubBuffer = NULL;
+ if (strstr (glxExtensions, "GLX_MESA_copy_sub_buffer"))
+ s->copySubBuffer = (GLXCopySubBufferProc)
+ getProcAddress (s, "glXCopySubBufferMESA");
- s->waitVideoSync = (GLXWaitVideoSyncProc)
- getProcAddress (s, "glXWaitVideoSyncSGI");
- }
+ s->getVideoSync = NULL;
+ s->waitVideoSync = NULL;
+ if (strstr (glxExtensions, "GLX_SGI_video_sync"))
+ {
+ s->getVideoSync = (GLXGetVideoSyncProc)
+ getProcAddress (s, "glXGetVideoSyncSGI");
- glXMakeCurrent (dpy, s->output, s->ctx);
- currentRoot = s->root;
+ s->waitVideoSync = (GLXWaitVideoSyncProc)
+ getProcAddress (s, "glXWaitVideoSyncSGI");
+ }
- glExtensions = (const char *) glGetString (GL_EXTENSIONS);
- if (!glExtensions)
- {
- compLogMessage ("core", CompLogLevelFatal,
- "No valid GL extensions string found.");
- return FALSE;
- }
+ glXMakeCurrent (dpy, s->output, s->ctx);
+ currentRoot = s->root.id;
- s->textureNonPowerOfTwo = 0;
- if (strstr (glExtensions, "GL_ARB_texture_non_power_of_two"))
- s->textureNonPowerOfTwo = 1;
+ glExtensions = (const char *) glGetString (GL_EXTENSIONS);
+ if (!glExtensions)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "No valid GL extensions string found.");
+ return FALSE;
+ }
- glGetIntegerv (GL_MAX_TEXTURE_SIZE, &s->maxTextureSize);
+ s->textureNonPowerOfTwo = 0;
+ if (strstr (glExtensions, "GL_ARB_texture_non_power_of_two"))
+ s->textureNonPowerOfTwo = 1;
- s->textureRectangle = 0;
- if (strstr (glExtensions, "GL_NV_texture_rectangle") ||
- strstr (glExtensions, "GL_EXT_texture_rectangle") ||
- strstr (glExtensions, "GL_ARB_texture_rectangle"))
- {
- s->textureRectangle = 1;
+ glGetIntegerv (GL_MAX_TEXTURE_SIZE, &s->maxTextureSize);
- if (!s->textureNonPowerOfTwo)
+ s->textureRectangle = 0;
+ if (strstr (glExtensions, "GL_NV_texture_rectangle") ||
+ strstr (glExtensions, "GL_EXT_texture_rectangle") ||
+ strstr (glExtensions, "GL_ARB_texture_rectangle"))
{
- GLint maxTextureSize;
+ s->textureRectangle = 1;
- glGetIntegerv (GL_MAX_RECTANGLE_TEXTURE_SIZE_NV, &maxTextureSize);
- if (maxTextureSize > s->maxTextureSize)
- s->maxTextureSize = maxTextureSize;
- }
- }
+ if (!s->textureNonPowerOfTwo)
+ {
+ GLint maxTextureSize;
- if (!(s->textureRectangle || s->textureNonPowerOfTwo))
- {
- compLogMessage ("core", CompLogLevelFatal,
- "Support for non power of two textures missing");
- return FALSE;
- }
+ glGetIntegerv (GL_MAX_RECTANGLE_TEXTURE_SIZE_NV,
+ &maxTextureSize);
+ if (maxTextureSize > s->maxTextureSize)
+ s->maxTextureSize = maxTextureSize;
+ }
+ }
- s->textureEnvCombine = s->textureEnvCrossbar = 0;
- if (strstr (glExtensions, "GL_ARB_texture_env_combine"))
- {
- s->textureEnvCombine = 1;
+ if (!(s->textureRectangle || s->textureNonPowerOfTwo))
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "Support for non power of two textures missing");
+ return FALSE;
+ }
- /* XXX: GL_NV_texture_env_combine4 need special code but it seams to
- be working anyway for now... */
- if (strstr (glExtensions, "GL_ARB_texture_env_crossbar") ||
- strstr (glExtensions, "GL_NV_texture_env_combine4"))
- s->textureEnvCrossbar = 1;
- }
+ s->textureEnvCombine = s->textureEnvCrossbar = 0;
+ if (strstr (glExtensions, "GL_ARB_texture_env_combine"))
+ {
+ s->textureEnvCombine = 1;
- s->textureBorderClamp = 0;
- if (strstr (glExtensions, "GL_ARB_texture_border_clamp") ||
- strstr (glExtensions, "GL_SGIS_texture_border_clamp"))
- s->textureBorderClamp = 1;
+ /* XXX: GL_NV_texture_env_combine4 need special code but it
+ seems to be working anyway for now... */
+ if (strstr (glExtensions, "GL_ARB_texture_env_crossbar") ||
+ strstr (glExtensions, "GL_NV_texture_env_combine4"))
+ s->textureEnvCrossbar = 1;
+ }
- s->maxTextureUnits = 1;
- if (strstr (glExtensions, "GL_ARB_multitexture"))
- {
- s->activeTexture = (GLActiveTextureProc)
- getProcAddress (s, "glActiveTexture");
- s->clientActiveTexture = (GLClientActiveTextureProc)
- getProcAddress (s, "glClientActiveTexture");
- s->multiTexCoord2f = (GLMultiTexCoord2fProc)
- getProcAddress (s, "glMultiTexCoord2f");
-
- if (s->activeTexture && s->clientActiveTexture && s->multiTexCoord2f)
- glGetIntegerv (GL_MAX_TEXTURE_UNITS_ARB, &s->maxTextureUnits);
- }
+ s->textureBorderClamp = 0;
+ if (strstr (glExtensions, "GL_ARB_texture_border_clamp") ||
+ strstr (glExtensions, "GL_SGIS_texture_border_clamp"))
+ s->textureBorderClamp = 1;
- s->fragmentProgram = 0;
- if (strstr (glExtensions, "GL_ARB_fragment_program"))
- {
- s->genPrograms = (GLGenProgramsProc)
- getProcAddress (s, "glGenProgramsARB");
- s->deletePrograms = (GLDeleteProgramsProc)
- getProcAddress (s, "glDeleteProgramsARB");
- s->bindProgram = (GLBindProgramProc)
- getProcAddress (s, "glBindProgramARB");
- s->programString = (GLProgramStringProc)
- getProcAddress (s, "glProgramStringARB");
- s->programEnvParameter4f = (GLProgramParameter4fProc)
- getProcAddress (s, "glProgramEnvParameter4fARB");
- s->programLocalParameter4f = (GLProgramParameter4fProc)
- getProcAddress (s, "glProgramLocalParameter4fARB");
- s->getProgramiv = (GLGetProgramivProc)
- getProcAddress (s, "glGetProgramivARB");
-
- if (s->genPrograms &&
- s->deletePrograms &&
- s->bindProgram &&
- s->programString &&
- s->programEnvParameter4f &&
- s->programLocalParameter4f &&
- s->getProgramiv)
- s->fragmentProgram = 1;
- }
+ s->maxTextureUnits = 1;
+ if (strstr (glExtensions, "GL_ARB_multitexture"))
+ {
+ s->activeTexture = (GLActiveTextureProc)
+ getProcAddress (s, "glActiveTexture");
+ s->clientActiveTexture = (GLClientActiveTextureProc)
+ getProcAddress (s, "glClientActiveTexture");
+ s->multiTexCoord2f = (GLMultiTexCoord2fProc)
+ getProcAddress (s, "glMultiTexCoord2f");
+
+ if (s->activeTexture &&
+ s->clientActiveTexture &&
+ s->multiTexCoord2f)
+ glGetIntegerv (GL_MAX_TEXTURE_UNITS_ARB, &s->maxTextureUnits);
+ }
- s->fbo = 0;
- if (strstr (glExtensions, "GL_EXT_framebuffer_object"))
- {
- s->genFramebuffers = (GLGenFramebuffersProc)
- getProcAddress (s, "glGenFramebuffersEXT");
- s->deleteFramebuffers = (GLDeleteFramebuffersProc)
- getProcAddress (s, "glDeleteFramebuffersEXT");
- s->bindFramebuffer = (GLBindFramebufferProc)
- getProcAddress (s, "glBindFramebufferEXT");
- s->checkFramebufferStatus = (GLCheckFramebufferStatusProc)
- getProcAddress (s, "glCheckFramebufferStatusEXT");
- s->framebufferTexture2D = (GLFramebufferTexture2DProc)
- getProcAddress (s, "glFramebufferTexture2DEXT");
- s->generateMipmap = (GLGenerateMipmapProc)
- getProcAddress (s, "glGenerateMipmapEXT");
-
- if (s->genFramebuffers &&
- s->deleteFramebuffers &&
- s->bindFramebuffer &&
- s->checkFramebufferStatus &&
- s->framebufferTexture2D &&
- s->generateMipmap)
- s->fbo = 1;
- }
+ s->fragmentProgram = 0;
+ if (strstr (glExtensions, "GL_ARB_fragment_program"))
+ {
+ s->genPrograms = (GLGenProgramsProc)
+ getProcAddress (s, "glGenProgramsARB");
+ s->deletePrograms = (GLDeleteProgramsProc)
+ getProcAddress (s, "glDeleteProgramsARB");
+ s->bindProgram = (GLBindProgramProc)
+ getProcAddress (s, "glBindProgramARB");
+ s->programString = (GLProgramStringProc)
+ getProcAddress (s, "glProgramStringARB");
+ s->programEnvParameter4f = (GLProgramParameter4fProc)
+ getProcAddress (s, "glProgramEnvParameter4fARB");
+ s->programLocalParameter4f = (GLProgramParameter4fProc)
+ getProcAddress (s, "glProgramLocalParameter4fARB");
+ s->getProgramiv = (GLGetProgramivProc)
+ getProcAddress (s, "glGetProgramivARB");
+
+ if (s->genPrograms &&
+ s->deletePrograms &&
+ s->bindProgram &&
+ s->programString &&
+ s->programEnvParameter4f &&
+ s->programLocalParameter4f &&
+ s->getProgramiv)
+ s->fragmentProgram = 1;
+ }
- s->textureCompression = 0;
- if (strstr (glExtensions, "GL_ARB_texture_compression"))
- s->textureCompression = 1;
+ s->fbo = 0;
+ if (strstr (glExtensions, "GL_EXT_framebuffer_object"))
+ {
+ s->genFramebuffers = (GLGenFramebuffersProc)
+ getProcAddress (s, "glGenFramebuffersEXT");
+ s->deleteFramebuffers = (GLDeleteFramebuffersProc)
+ getProcAddress (s, "glDeleteFramebuffersEXT");
+ s->bindFramebuffer = (GLBindFramebufferProc)
+ getProcAddress (s, "glBindFramebufferEXT");
+ s->checkFramebufferStatus = (GLCheckFramebufferStatusProc)
+ getProcAddress (s, "glCheckFramebufferStatusEXT");
+ s->framebufferTexture2D = (GLFramebufferTexture2DProc)
+ getProcAddress (s, "glFramebufferTexture2DEXT");
+ s->generateMipmap = (GLGenerateMipmapProc)
+ getProcAddress (s, "glGenerateMipmapEXT");
+
+ if (s->genFramebuffers &&
+ s->deleteFramebuffers &&
+ s->bindFramebuffer &&
+ s->checkFramebufferStatus &&
+ s->framebufferTexture2D &&
+ s->generateMipmap)
+ s->fbo = 1;
+ }
- fbConfigs = (*s->getFBConfigs) (dpy,
- screenNum,
- &nElements);
+ s->textureCompression = 0;
+ if (strstr (glExtensions, "GL_ARB_texture_compression"))
+ s->textureCompression = 1;
- for (i = 0; i <= MAX_DEPTH; i++)
- {
- int j, db, stencil, depth, alpha, mipmap, rgba;
+ fbConfigs = (*s->getFBConfigs) (dpy,
+ screenNum,
+ &nElements);
- s->glxPixmapFBConfigs[i].fbConfig = NULL;
- s->glxPixmapFBConfigs[i].mipmap = 0;
- s->glxPixmapFBConfigs[i].yInverted = 0;
- s->glxPixmapFBConfigs[i].textureFormat = 0;
- s->glxPixmapFBConfigs[i].textureTargets = 0;
+ for (i = 0; i <= MAX_DEPTH; i++)
+ {
+ int j, db, stencil, depth, alpha, mipmap, rgba;
- db = MAXSHORT;
- stencil = MAXSHORT;
- depth = MAXSHORT;
- mipmap = 0;
- rgba = 0;
+ s->glxPixmapFBConfigs[i].fbConfig = NULL;
+ s->glxPixmapFBConfigs[i].mipmap = 0;
+ s->glxPixmapFBConfigs[i].yInverted = 0;
+ s->glxPixmapFBConfigs[i].textureFormat = 0;
+ s->glxPixmapFBConfigs[i].textureTargets = 0;
- for (j = 0; j < nElements; j++)
- {
- XVisualInfo *vi;
- int visualDepth;
+ db = MAXSHORT;
+ stencil = MAXSHORT;
+ depth = MAXSHORT;
+ mipmap = 0;
+ rgba = 0;
- vi = glXGetVisualFromFBConfig (dpy, fbConfigs[j]);
- if (vi == NULL)
- continue;
+ for (j = 0; j < nElements; j++)
+ {
+ XVisualInfo *vi;
+ int visualDepth;
- visualDepth = vi->depth;
+ vi = glXGetVisualFromFBConfig (dpy, fbConfigs[j]);
+ if (vi == NULL)
+ continue;
- XFree (vi);
+ visualDepth = vi->depth;
- if (visualDepth != i)
- continue;
+ XFree (vi);
- (*s->getFBConfigAttrib) (dpy,
- fbConfigs[j],
- GLX_ALPHA_SIZE,
- &alpha);
- (*s->getFBConfigAttrib) (dpy,
- fbConfigs[j],
- GLX_BUFFER_SIZE,
- &value);
- if (value != i && (value - alpha) != i)
- continue;
+ if (visualDepth != i)
+ continue;
- value = 0;
- if (i == 32)
- {
(*s->getFBConfigAttrib) (dpy,
fbConfigs[j],
- GLX_BIND_TO_TEXTURE_RGBA_EXT,
+ GLX_ALPHA_SIZE,
+ &alpha);
+ (*s->getFBConfigAttrib) (dpy,
+ fbConfigs[j],
+ GLX_BUFFER_SIZE,
&value);
+ if (value != i && (value - alpha) != i)
+ continue;
+
+ value = 0;
+ if (i == 32)
+ {
+ (*s->getFBConfigAttrib) (dpy,
+ fbConfigs[j],
+ GLX_BIND_TO_TEXTURE_RGBA_EXT,
+ &value);
+
+ if (value)
+ {
+ rgba = 1;
+
+ s->glxPixmapFBConfigs[i].textureFormat =
+ GLX_TEXTURE_FORMAT_RGBA_EXT;
+ }
+ }
- if (value)
+ if (!value)
{
- rgba = 1;
+ if (rgba)
+ continue;
+
+ (*s->getFBConfigAttrib) (dpy,
+ fbConfigs[j],
+ GLX_BIND_TO_TEXTURE_RGB_EXT,
+ &value);
+ if (!value)
+ continue;
s->glxPixmapFBConfigs[i].textureFormat =
- GLX_TEXTURE_FORMAT_RGBA_EXT;
+ GLX_TEXTURE_FORMAT_RGB_EXT;
}
- }
- if (!value)
- {
- if (rgba)
+ (*s->getFBConfigAttrib) (dpy,
+ fbConfigs[j],
+ GLX_DOUBLEBUFFER,
+ &value);
+ if (value > db)
continue;
+ db = value;
+
(*s->getFBConfigAttrib) (dpy,
fbConfigs[j],
- GLX_BIND_TO_TEXTURE_RGB_EXT,
+ GLX_STENCIL_SIZE,
&value);
- if (!value)
+ if (value > stencil)
continue;
- s->glxPixmapFBConfigs[i].textureFormat =
- GLX_TEXTURE_FORMAT_RGB_EXT;
- }
-
- (*s->getFBConfigAttrib) (dpy,
- fbConfigs[j],
- GLX_DOUBLEBUFFER,
- &value);
- if (value > db)
- continue;
+ stencil = value;
- db = value;
+ (*s->getFBConfigAttrib) (dpy,
+ fbConfigs[j],
+ GLX_DEPTH_SIZE,
+ &value);
+ if (value > depth)
+ continue;
- (*s->getFBConfigAttrib) (dpy,
- fbConfigs[j],
- GLX_STENCIL_SIZE,
- &value);
- if (value > stencil)
- continue;
+ depth = value;
- stencil = value;
+ if (s->fbo)
+ {
+ (*s->getFBConfigAttrib) (dpy,
+ fbConfigs[j],
+ GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
+ &value);
+ if (value < mipmap)
+ continue;
+
+ mipmap = value;
+ }
- (*s->getFBConfigAttrib) (dpy,
- fbConfigs[j],
- GLX_DEPTH_SIZE,
- &value);
- if (value > depth)
- continue;
+ (*s->getFBConfigAttrib) (dpy,
+ fbConfigs[j],
+ GLX_Y_INVERTED_EXT,
+ &value);
- depth = value;
+ s->glxPixmapFBConfigs[i].yInverted = value;
- if (s->fbo)
- {
(*s->getFBConfigAttrib) (dpy,
fbConfigs[j],
- GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT,
&value);
- if (value < mipmap)
- continue;
- mipmap = value;
+ s->glxPixmapFBConfigs[i].textureTargets = value;
+
+ s->glxPixmapFBConfigs[i].fbConfig = fbConfigs[j];
+ s->glxPixmapFBConfigs[i].mipmap = mipmap;
}
+ }
- (*s->getFBConfigAttrib) (dpy,
- fbConfigs[j],
- GLX_Y_INVERTED_EXT,
- &value);
+ if (nElements)
+ XFree (fbConfigs);
- s->glxPixmapFBConfigs[i].yInverted = value;
+ if (!s->glxPixmapFBConfigs[defaultDepth].fbConfig)
+ {
+ compLogMessage ("core", CompLogLevelFatal,
+ "No GLXFBConfig for default depth, "
+ "this isn't going to work.");
+ return FALSE;
+ }
- (*s->getFBConfigAttrib) (dpy,
- fbConfigs[j],
- GLX_BIND_TO_TEXTURE_TARGETS_EXT,
- &value);
+ glClearColor (0.0, 0.0, 0.0, 1.0);
+ glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable (GL_CULL_FACE);
+ glDisable (GL_BLEND);
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glColor4usv (defaultColor);
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+
+ s->canDoSaturated = s->canDoSlightlySaturated = FALSE;
+ if (s->textureEnvCombine && s->maxTextureUnits >= 2)
+ {
+ s->canDoSaturated = TRUE;
+ if (s->textureEnvCrossbar && s->maxTextureUnits >= 4)
+ s->canDoSlightlySaturated = TRUE;
+ }
- s->glxPixmapFBConfigs[i].textureTargets = value;
+ glLightModelfv (GL_LIGHT_MODEL_AMBIENT, globalAmbient);
- s->glxPixmapFBConfigs[i].fbConfig = fbConfigs[j];
- s->glxPixmapFBConfigs[i].mipmap = mipmap;
- }
- }
+ glEnable (GL_LIGHT0);
+ glLightfv (GL_LIGHT0, GL_AMBIENT, ambientLight);
+ glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuseLight);
+ glLightfv (GL_LIGHT0, GL_POSITION, light0Position);
- if (nElements)
- XFree (fbConfigs);
+ glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
- if (!s->glxPixmapFBConfigs[defaultDepth].fbConfig)
+ glNormal3f (0.0f, 0.0f, -1.0f);
+ }
+ else
{
- compLogMessage ("core", CompLogLevelFatal,
- "No GLXFBConfig for default depth, "
- "this isn't going to work.");
- return FALSE;
+ s->maxTextureSize = SHRT_MAX;
+ s->canDoSaturated = s->canDoSlightlySaturated = FALSE;
}
initTexture (s, &s->backgroundTexture);
@@ -2223,80 +2370,13 @@ addScreen (CompDisplay *display,
s->defaultIcon = NULL;
- s->desktopWindowCount = 0;
-
- glClearColor (0.0, 0.0, 0.0, 1.0);
- glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_CULL_FACE);
- glDisable (GL_BLEND);
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glColor4usv (defaultColor);
- glEnableClientState (GL_VERTEX_ARRAY);
- glEnableClientState (GL_TEXTURE_COORD_ARRAY);
-
- s->canDoSaturated = s->canDoSlightlySaturated = FALSE;
- if (s->textureEnvCombine && s->maxTextureUnits >= 2)
- {
- s->canDoSaturated = TRUE;
- if (s->textureEnvCrossbar && s->maxTextureUnits >= 4)
- s->canDoSlightlySaturated = TRUE;
- }
-
s->redrawTime = 1000 / defaultRefreshRate;
s->optimalRedrawTime = s->redrawTime;
- reshape (s, s->attrib.width, s->attrib.height);
-
- detectRefreshRateOfScreen (s);
- detectOutputDevices (s);
- updateOutputDevices (s);
-
- glLightModelfv (GL_LIGHT_MODEL_AMBIENT, globalAmbient);
-
- glEnable (GL_LIGHT0);
- glLightfv (GL_LIGHT0, GL_AMBIENT, ambientLight);
- glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuseLight);
- glLightfv (GL_LIGHT0, GL_POSITION, light0Position);
-
- glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
-
- glNormal3f (0.0f, 0.0f, -1.0f);
-
- s->lighting = FALSE;
- s->slowAnimations = FALSE;
-
- addScreenToDisplay (display, s);
-
- getDesktopHints (s);
-
- /* TODO: bailout properly when objectInitPlugins fails */
- assert (objectInitPlugins (&s->base));
-
- (*core.objectAdd) (&display->base, &s->base);
-
- XQueryTree (dpy, s->root,
- &rootReturn, &parentReturn,
- &children, &nchildren);
-
- for (i = 0; i < nchildren; i++)
- addWindow (s, children[i], i ? children[i - 1] : 0);
-
- for (w = s->windows; w; w = w->next)
- {
- if (w->attrib.map_state == IsViewable)
- {
- w->activeNum = s->activeNum++;
- w->damaged = TRUE;
- w->invisible = WINDOW_INVISIBLE (w);
- }
- }
-
- XFree (children);
-
attrib.override_redirect = 1;
attrib.event_mask = PropertyChangeMask;
- s->grabWindow = XCreateWindow (dpy, s->root, -100, -100, 1, 1, 0,
+ s->grabWindow = XCreateWindow (dpy, s->root.id, -100, -100, 1, 1, 0,
CopyFromParent, InputOnly, CopyFromParent,
CWOverrideRedirect | CWEventMask,
&attrib);
@@ -2306,9 +2386,13 @@ addScreen (CompDisplay *display,
{
long xdndVersion = 3;
- s->screenEdge[i].id = XCreateWindow (dpy, s->root, -100, -100, 1, 1, 0,
- CopyFromParent, InputOnly,
- CopyFromParent, CWOverrideRedirect,
+ s->screenEdge[i].id = XCreateWindow (dpy,
+ s->root.id,
+ -100, -100, 1, 1, 0,
+ CopyFromParent,
+ InputOnly,
+ CopyFromParent,
+ CWOverrideRedirect,
&attrib);
XChangeProperty (dpy, s->screenEdge[i].id, display->xdndAwareAtom,
@@ -2325,19 +2409,90 @@ addScreen (CompDisplay *display,
updateScreenEdges (s);
- setDesktopHints (s);
- setSupportingWmCheck (s);
- setSupported (s);
+ reshape (s, s->attrib.width, s->attrib.height);
+
+ detectRefreshRateOfScreen (s);
+ detectOutputDevices (s);
+ updateOutputDevices (s);
+
+ s->lighting = FALSE;
+ s->slowAnimations = FALSE;
+
+ addScreenToDisplay (display, s);
+
+ getDesktopHints (s);
s->normalCursor = XCreateFontCursor (dpy, XC_left_ptr);
s->busyCursor = XCreateFontCursor (dpy, XC_watch);
- XDefineCursor (dpy, s->root, s->normalCursor);
+ if (s->root.substructureRedirect)
+ {
+ setDesktopHints (s);
+ setSupportingWmCheck (s);
+ setSupported (s);
+
+ XDefineCursor (dpy, s->root.id, s->normalCursor);
+ }
+ else
+ {
+ getSupportingWmCheck (&s->root);
+ }
s->filter[NOTHING_TRANS_FILTER] = COMP_TEXTURE_FILTER_FAST;
s->filter[SCREEN_TRANS_FILTER] = COMP_TEXTURE_FILTER_GOOD;
s->filter[WINDOW_TRANS_FILTER] = COMP_TEXTURE_FILTER_GOOD;
+ /* TODO: bailout properly when objectInitPlugins fails */
+ assert (objectInitPlugins (&s->base));
+ (*core.objectAdd) (&display->base, &s->base);
+
+ assert (objectInitPlugins (&s->root.base));
+ (*core.objectAdd) (&s->base, &s->root.base);
+
+ XQueryTree (dpy, s->root.id,
+ &rootReturn, &parentReturn,
+ &children, &nchildren);
+
+ if (windowManagement)
+ {
+ XSelectInput (dpy, s->root.id,
+ SubstructureRedirectMask |
+ SubstructureNotifyMask |
+ StructureNotifyMask |
+ PropertyChangeMask |
+ LeaveWindowMask |
+ EnterWindowMask |
+ KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ FocusChangeMask |
+ ExposureMask);
+ }
+ else
+ {
+ XSelectInput (dpy, s->root.id,
+ SubstructureNotifyMask |
+ StructureNotifyMask |
+ PropertyChangeMask |
+ ExposureMask);
+ }
+
+ for (i = 0; i < nchildren; i++)
+ addWindow (&s->root, children[i], i ? children[i - 1] : 0);
+
+ for (w = s->root.windows; w; w = w->next)
+ {
+ if (w->attrib.map_state == IsViewable)
+ {
+ w->activeNum = s->activeNum++;
+ w->damaged = TRUE;
+ w->invisible = WINDOW_INVISIBLE (w);
+ }
+ }
+
+ XFree (children);
+
return TRUE;
}
@@ -2357,14 +2512,14 @@ removeScreen (CompScreen *s)
else
d->screens = NULL;
- while (s->windows)
- removeWindow (s->windows);
+ while (s->root.windows)
+ removeWindow (s->root.windows);
(*core.objectRemove) (&d->base, &s->base);
objectFiniPlugins (&s->base);
- XUngrabKey (d->display, AnyKey, AnyModifier, s->root);
+ XUngrabKey (d->display, AnyKey, AnyModifier, s->root.id);
for (i = 0; i < SCREEN_EDGE_NUM; i++)
XDestroyWindow (d->display, s->screenEdge[i].id);
@@ -2372,6 +2527,7 @@ removeScreen (CompScreen *s)
XDestroyWindow (d->display, s->grabWindow);
finiTexture (s, &s->backgroundTexture);
+ destroyTexture (s, s->root.texture);
if (s->defaultIcon)
{
@@ -2379,13 +2535,14 @@ removeScreen (CompScreen *s)
free (s->defaultIcon);
}
- glXDestroyContext (d->display, s->ctx);
+ if (manualCompositeManagement)
+ glXDestroyContext (d->display, s->ctx);
XFreeCursor (d->display, s->invisibleCursor);
#ifdef USE_COW
- if (useCow)
- XCompositeReleaseOverlayWindow (s->display->display, s->root);
+ if (useCow && manualCompositeManagement)
+ XCompositeReleaseOverlayWindow (s->display->display, s->root.id);
#endif
freeScreen (s);
@@ -2430,7 +2587,7 @@ forEachWindowOnScreen (CompScreen *screen,
{
CompWindow *w;
- for (w = screen->windows; w; w = w->next)
+ for (w = screen->root.windows; w; w = w->next)
(*proc) (w, closure);
}
@@ -2441,6 +2598,9 @@ focusDefaultWindow (CompScreen *s)
CompWindow *w;
CompWindow *focus = NULL;
+ if (!s->root.substructureRedirect)
+ return;
+
if (!d->opt[COMP_DISPLAY_OPTION_CLICK_TO_FOCUS].value.b)
{
w = findTopLevelWindowAtDisplay (d, d->below);
@@ -2461,11 +2621,11 @@ focusDefaultWindow (CompScreen *s)
/* huh, we didn't find d->below ... perhaps it's out of date;
try grabbing it through the server */
- status = XQueryPointer (d->display, s->root, &rootReturn,
+ status = XQueryPointer (d->display, s->root.id, &rootReturn,
&childReturn, &dummyInt, &dummyInt,
&dummyInt, &dummyInt, &dummyUInt);
- if (status && rootReturn == s->root)
+ if (status && rootReturn == s->root.id)
{
w = findTopLevelWindowAtDisplay (d, childReturn);
@@ -2481,7 +2641,7 @@ focusDefaultWindow (CompScreen *s)
if (!focus)
{
- for (w = s->reverseWindows; w; w = w->prev)
+ for (w = s->root.reverseWindows; w; w = w->prev)
{
if (w->type & CompWindowTypeDockMask)
continue;
@@ -2511,7 +2671,7 @@ focusDefaultWindow (CompScreen *s)
}
else
{
- XSetInputFocus (d->display, s->root, RevertToPointerRoot,
+ XSetInputFocus (d->display, s->root.id, RevertToPointerRoot,
CurrentTime);
}
}
@@ -2528,17 +2688,17 @@ findWindowAtScreen (CompScreen *s,
{
CompWindow *w;
- for (w = s->windows; w; w = w->next)
+ for (w = &s->root; w; w = walkDepthFirst (w))
if (w->id == id)
return (lastFoundWindow = w);
}
- return 0;
+ return NULL;
}
CompWindow *
-findTopLevelWindowAtScreen (CompScreen *s,
- Window id)
+findClientWindowAtScreen (CompScreen *s,
+ Window id)
{
CompWindow *w;
@@ -2548,120 +2708,29 @@ findTopLevelWindowAtScreen (CompScreen *s,
if (w->attrib.override_redirect)
{
- /* likely a frame window */
- if (w->attrib.class == InputOnly)
- {
- for (w = s->windows; w; w = w->next)
- if (w->frame == id)
- return w;
- }
+ if (!w->parent || w->attrib.class != InputOnly)
+ return NULL;
- return NULL;
+ /* likely a frame window */
+ for (w = w->parent->windows; w; w = w->next)
+ if (w->frame == id)
+ break;
}
return w;
}
-void
-insertWindowIntoScreen (CompScreen *s,
- CompWindow *w,
- Window aboveId)
-{
- CompWindow *p;
-
- if (s->windows)
- {
- if (!aboveId)
- {
- w->next = s->windows;
- w->prev = NULL;
- s->windows->prev = w;
- s->windows = w;
- }
- else
- {
- for (p = s->windows; p; p = p->next)
- {
- if (p->id == aboveId)
- {
- if (p->next)
- {
- w->next = p->next;
- w->prev = p;
- p->next->prev = w;
- p->next = w;
- }
- else
- {
- p->next = w;
- w->next = NULL;
- w->prev = p;
- s->reverseWindows = w;
- }
- break;
- }
- }
-
-#ifdef DEBUG
- if (!p)
- abort ();
-#endif
-
- }
- }
- else
- {
- s->reverseWindows = s->windows = w;
- w->prev = w->next = NULL;
- }
-}
-
-void
-unhookWindowFromScreen (CompScreen *s,
- CompWindow *w)
+CompWindow *
+findTopLevelWindowAtScreen (CompScreen *s,
+ Window id)
{
- CompWindow *next, *prev;
-
- next = w->next;
- prev = w->prev;
+ CompWindow *w;
- if (next || prev)
- {
- if (next)
- {
- if (prev)
- {
- next->prev = prev;
- }
- else
- {
- s->windows = next;
- next->prev = NULL;
- }
- }
+ w = findClientWindowAtScreen (s, id);
+ if (w && w->managed)
+ return w;
- if (prev)
- {
- if (next)
- {
- prev->next = next;
- }
- else
- {
- s->reverseWindows = prev;
- prev->next = NULL;
- }
- }
- }
- else
- {
- s->windows = s->reverseWindows = NULL;
- }
-
- if (w == lastFoundWindow)
- lastFoundWindow = NULL;
- if (w == lastDamagedWindow)
- lastDamagedWindow = NULL;
+ return NULL;
}
#define POINTER_GRAB_MASK (ButtonReleaseMask | \
@@ -2679,7 +2748,7 @@ pushScreenGrab (CompScreen *s,
status = XGrabPointer (s->display->display, s->grabWindow, TRUE,
POINTER_GRAB_MASK,
GrabModeAsync, GrabModeAsync,
- s->root, cursor,
+ s->root.id, cursor,
CurrentTime);
if (status == GrabSuccess)
@@ -2831,7 +2900,7 @@ grabUngrabOneKey (CompScreen *s,
XGrabKey (s->display->display,
keycode,
modifiers,
- s->root,
+ s->root.id,
TRUE,
GrabModeAsync,
GrabModeAsync);
@@ -2841,7 +2910,7 @@ grabUngrabOneKey (CompScreen *s,
XUngrabKey (s->display->display,
keycode,
modifiers,
- s->root);
+ s->root.id);
}
}
@@ -2971,7 +3040,7 @@ updatePassiveKeyGrabs (CompScreen *s)
{
int i;
- XUngrabKey (s->display->display, AnyKey, AnyModifier, s->root);
+ XUngrabKey (s->display->display, AnyKey, AnyModifier, s->root.id);
for (i = 0; i < s->nKeyGrab; i++)
{
@@ -3127,7 +3196,7 @@ computeWorkareaForBox (CompScreen *s,
XUnionRegion (&r, region, region);
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (!w->mapNum)
continue;
@@ -3241,7 +3310,7 @@ updateWorkareaForScreen (CompScreen *s)
/* as work area changed, update all maximized windows on this
screen to snap to the new work area */
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
updateWindowSize (w);
}
}
@@ -3308,6 +3377,9 @@ updateClientListForScreen (CompScreen *s)
Bool updateClientListStacking = FALSE;
int i, n = 0;
+ if (!s->root.substructureRedirect)
+ return;
+
forEachWindowOnScreen (s, countClientListWindow, (void *) &n);
if (n == 0)
@@ -3319,11 +3391,11 @@ updateClientListForScreen (CompScreen *s)
s->clientList = NULL;
s->nClientList = 0;
- XChangeProperty (s->display->display, s->root,
+ XChangeProperty (s->display->display, s->root.id,
s->display->clientListAtom,
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &s->grabWindow, 1);
- XChangeProperty (s->display->display, s->root,
+ XChangeProperty (s->display->display, s->root.id,
s->display->clientListStackingAtom,
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &s->grabWindow, 1);
@@ -3379,13 +3451,13 @@ updateClientListForScreen (CompScreen *s)
}
if (updateClientList)
- XChangeProperty (s->display->display, s->root,
+ XChangeProperty (s->display->display, s->root.id,
s->display->clientListAtom,
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) clientList, s->nClientList);
if (updateClientListStacking)
- XChangeProperty (s->display->display, s->root,
+ XChangeProperty (s->display->display, s->root.id,
s->display->clientListStackingAtom,
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) clientListStacking, s->nClientList);
@@ -3439,7 +3511,8 @@ toolkitAction (CompScreen *s,
XUngrabPointer (s->display->display, CurrentTime);
XUngrabKeyboard (s->display->display, CurrentTime);
- XSendEvent (s->display->display, s->root, FALSE, StructureNotifyMask, &ev);
+ XSendEvent (s->display->display, s->root.id, FALSE, StructureNotifyMask,
+ &ev);
}
void
@@ -3510,7 +3583,7 @@ moveScreenViewport (CompScreen *s,
tx *= -s->width;
ty *= -s->height;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (windowOnAllViewports (w))
continue;
@@ -3581,7 +3654,7 @@ moveWindowToViewportPosition (CompWindow *w,
{
int m, wx, wy;
- if (!w->managed)
+ if (w->attrib.override_redirect)
return;
if (w->type & (CompWindowTypeDesktopMask | CompWindowTypeDockMask))
@@ -3698,7 +3771,7 @@ applyStartupProperties (CompScreen *screen,
{
CompWindow *leader;
- leader = findWindowAtScreen (screen, window->clientLeader);
+ leader = findSibling (window, window->clientLeader);
if (leader)
startupId = leader->startupId;
@@ -3752,7 +3825,7 @@ sendWindowActivationRequest (CompScreen *s,
xev.xclient.data.l[4] = 0;
XSendEvent (s->display->display,
- s->root,
+ s->root.id,
FALSE,
SubstructureRedirectMask | SubstructureNotifyMask,
&xev);
@@ -3813,12 +3886,12 @@ disableScreenEdge (CompScreen *s,
}
Window
-getTopWindow (CompScreen *s)
+getTopWindow (CompWindow *parent)
{
CompWindow *w;
/* return first window that has not been destroyed */
- for (w = s->reverseWindows; w; w = w->prev)
+ for (w = parent->reverseWindows; w; w = w->prev)
{
if (w->id > 1)
return w->id;
@@ -3830,24 +3903,30 @@ getTopWindow (CompScreen *s)
void
makeScreenCurrent (CompScreen *s)
{
- if (currentRoot != s->root)
+ if (manualCompositeManagement)
{
- glXMakeCurrent (s->display->display, s->output, s->ctx);
- currentRoot = s->root;
- }
+ if (currentRoot != s->root.id)
+ {
+ glXMakeCurrent (s->display->display, s->output, s->ctx);
+ currentRoot = s->root.id;
+ }
- s->pendingCommands = TRUE;
+ s->pendingCommands = TRUE;
+ }
}
void
finishScreenDrawing (CompScreen *s)
{
- if (s->pendingCommands)
+ if (manualCompositeManagement)
{
- makeScreenCurrent (s);
- glFinish ();
+ if (s->pendingCommands)
+ {
+ makeScreenCurrent (s);
+ glFinish ();
- s->pendingCommands = FALSE;
+ s->pendingCommands = FALSE;
+ }
}
}
@@ -3894,7 +3973,7 @@ setNumberOfDesktops (CompScreen *s,
if (s->currentDesktop >= nDesktop)
s->currentDesktop = nDesktop - 1;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (w->desktop == 0xffffffff)
continue;
@@ -3915,6 +3994,9 @@ setCurrentDesktop (CompScreen *s,
unsigned long data;
CompWindow *w;
+ if (!s->root.substructureRedirect)
+ return;
+
if (desktop >= s->nDesktop)
return;
@@ -3923,7 +4005,7 @@ setCurrentDesktop (CompScreen *s,
s->currentDesktop = desktop;
- for (w = s->windows; w; w = w->next)
+ for (w = s->root.windows; w; w = w->next)
{
if (w->desktop == 0xffffffff)
continue;
@@ -3936,7 +4018,7 @@ setCurrentDesktop (CompScreen *s,
data = desktop;
- XChangeProperty (s->display->display, s->root,
+ XChangeProperty (s->display->display, s->root.id,
s->display->currentDesktopAtom,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &data, 1);
@@ -4292,6 +4374,14 @@ setWindowPaintOffset (CompScreen *s,
int x,
int y)
{
- s->windowOffsetX = x;
- s->windowOffsetY = y;
+ x = (s->x * s->width) - x;
+ x = MOD (x, s->hsize * s->width);
+ x -= (s->x * s->width);
+
+ y = (s->y * s->height) - y;
+ y = MOD (y, s->vsize * s->height);
+ y -= (s->y * s->height);
+
+ s->root.viewportOffsetX = -x;
+ s->root.viewportOffsetY = -y;
}
diff --git a/src/window.c b/src/window.c
index 881bbd5..ca9fa52 100644
--- a/src/window.c
+++ b/src/window.c
@@ -53,18 +53,18 @@ static int
reallocWindowPrivates (int size,
void *closure)
{
- CompScreen *s = (CompScreen *) closure;
- CompWindow *w;
+ CompWindow *c, *w = (CompWindow *) closure;
void *privates;
- for (w = s->windows; w; w = w->next)
- {
- privates = realloc (w->base.privates, size * sizeof (CompPrivate));
- if (!privates)
- return FALSE;
+ privates = realloc (w->base.privates, size * sizeof (CompPrivate));
+ if (!privates)
+ return FALSE;
- w->base.privates = (CompPrivate *) privates;
- }
+ w->base.privates = (CompPrivate *) privates;
+
+ for (c = w->windows; c; c = c->next)
+ if (!reallocWindowPrivates (size, (void *) c))
+ return FALSE;
return TRUE;
}
@@ -77,7 +77,7 @@ allocWindowObjectPrivateIndex (CompObject *parent)
return allocatePrivateIndex (&screen->windowPrivateLen,
&screen->windowPrivateIndices,
reallocWindowPrivates,
- (void *) screen);
+ (void *) &screen->root);
}
void
@@ -98,15 +98,16 @@ forEachWindowObject (CompObject *parent,
{
if (parent->type == COMP_OBJECT_TYPE_SCREEN)
{
- CompWindow *w;
-
- CORE_SCREEN (parent);
+ if (!(*proc) (&GET_CORE_SCREEN (parent)->root.base, closure))
+ return FALSE;
+ }
+ else if (parent->type == COMP_OBJECT_TYPE_WINDOW)
+ {
+ CompWindow *c;
- for (w = s->windows; w; w = w->next)
- {
- if (!(*proc) (&w->base, closure))
+ for (c = GET_CORE_WINDOW (parent)->windows; c; c = c->next)
+ if (!(*proc) (&c->base, closure))
return FALSE;
- }
}
return TRUE;
@@ -130,14 +131,23 @@ findWindowObject (CompObject *parent,
{
if (parent->type == COMP_OBJECT_TYPE_SCREEN)
{
- CompWindow *w;
- Window id = atoi (name);
+ Window id = atoi (name);
CORE_SCREEN (parent);
- for (w = s->windows; w; w = w->next)
- if (w->id == id)
- return &w->base;
+ if (s->root.id == id)
+ return &s->root.base;
+ }
+ else if (parent->type == COMP_OBJECT_TYPE_WINDOW)
+ {
+ CompWindow *c;
+ Window id = atoi (name);
+
+ CORE_WINDOW (parent);
+
+ for (c = w->windows; c; c = c->next)
+ if (c->id == id)
+ return &c->base;
}
return NULL;
@@ -168,8 +178,7 @@ isAncestorTo (CompWindow *transient,
if (transient->transientFor == ancestor->id)
return TRUE;
- transient = findWindowAtScreen (transient->screen,
- transient->transientFor);
+ transient = findSibling (transient, transient->transientFor);
if (transient)
return isAncestorTo (transient, ancestor);
}
@@ -376,7 +385,7 @@ updateTransientHint (CompWindow *w)
{
CompWindow *ancestor;
- ancestor = findWindowAtScreen (w->screen, transientFor);
+ ancestor = findSibling (w, transientFor);
if (!ancestor)
return;
@@ -426,7 +435,7 @@ getClientLeaderOfAncestor (CompWindow *w)
{
if (w->transientFor)
{
- w = findWindowAtScreen (w->screen, w->transientFor);
+ w = findSibling (w, w->transientFor);
if (w)
{
if (w->clientLeader)
@@ -1153,6 +1162,33 @@ setWindowProp32 (CompDisplay *display,
(unsigned char *) &value32, 1);
}
+Window
+getFrameWindow (CompWindow *w)
+{
+ Atom actual;
+ int result, format;
+ unsigned long n, left;
+ unsigned char *data;
+
+ result = XGetWindowProperty (w->screen->display->display, w->id,
+ w->screen->display->frameWindowAtom,
+ 0L, 1L, False, XA_WINDOW, &actual, &format,
+ &n, &left, &data);
+
+ if (result == Success && n && data)
+ {
+ Window win;
+
+ memcpy (&win, data, sizeof (Window));
+ XFree ((void *) data);
+
+ if (win)
+ return win;
+ }
+
+ return None;
+}
+
static void
updateFrameWindow (CompWindow *w)
{
@@ -1181,7 +1217,7 @@ updateFrameWindow (CompWindow *w)
attr.event_mask = 0;
attr.override_redirect = TRUE;
- w->frame = XCreateWindow (d->display, w->screen->root,
+ w->frame = XCreateWindow (d->display, w->parent->id,
x, y, width, height, 0,
CopyFromParent,
InputOnly,
@@ -1281,14 +1317,17 @@ setWindowFrameExtents (CompWindow *w,
data[2] = input->top;
data[3] = input->bottom;
- updateWindowSize (w);
- updateFrameWindow (w);
- recalcWindowActions (w);
-
- XChangeProperty (w->screen->display->display, w->id,
- w->screen->display->frameExtentsAtom,
- XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *) data, 4);
+ if (w->parent->substructureRedirect)
+ {
+ updateWindowSize (w);
+ updateFrameWindow (w);
+ recalcWindowActions (w);
+
+ XChangeProperty (w->screen->display->display, w->id,
+ w->screen->display->frameExtentsAtom,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) data, 4);
+ }
}
}
@@ -1397,7 +1436,7 @@ freeWindow (CompWindow *w)
destroyTexture (w->screen, w->texture);
- if (w->frame)
+ if (w->frame && w->parent->substructureRedirect)
XDestroyWindow (w->screen->display->display, w->frame);
if (w->clip)
@@ -1446,9 +1485,6 @@ damageTransformedWindowRect (CompWindow *w,
{
REGION reg;
- reg.rects = ®.extents;
- reg.numRects = 1;
-
reg.extents.x1 = (rect->x1 * xScale) - 1;
reg.extents.y1 = (rect->y1 * yScale) - 1;
reg.extents.x2 = (rect->x2 * xScale + 0.5f) + 1;
@@ -1461,10 +1497,17 @@ damageTransformedWindowRect (CompWindow *w,
if (reg.extents.x2 > reg.extents.x1 && reg.extents.y2 > reg.extents.y1)
{
- reg.extents.x1 += w->attrib.x + w->attrib.border_width;
- reg.extents.y1 += w->attrib.y + w->attrib.border_width;
- reg.extents.x2 += w->attrib.x + w->attrib.border_width;
- reg.extents.y2 += w->attrib.y + w->attrib.border_width;
+ CompWindow *p = w;
+
+ do {
+ reg.extents.x1 += p->attrib.x + p->attrib.border_width;
+ reg.extents.y1 += p->attrib.y + p->attrib.border_width;
+ reg.extents.x2 += p->attrib.x + p->attrib.border_width;
+ reg.extents.y2 += p->attrib.y + p->attrib.border_width;
+ } while ((p = p->parent));
+
+ reg.rects = ®.extents;
+ reg.numRects = reg.size = 1;
damageScreenRegion (w->screen, ®);
}
@@ -1527,19 +1570,27 @@ addWindowDamageRect (CompWindow *w,
BoxPtr rect)
{
REGION region;
+ Bool status = TRUE;
if (w->screen->damageMask & COMP_SCREEN_DAMAGE_ALL_MASK)
return;
region.extents = *rect;
- if (!(*w->screen->damageWindowRect) (w, FALSE, ®ion.extents))
+ while (w != &w->screen->root)
{
+ status &= (*w->screen->damageWindowRect) (w, FALSE, ®ion.extents);
+
region.extents.x1 += w->attrib.x + w->attrib.border_width;
region.extents.y1 += w->attrib.y + w->attrib.border_width;
region.extents.x2 += w->attrib.x + w->attrib.border_width;
region.extents.y2 += w->attrib.y + w->attrib.border_width;
+ w = w->parent;
+ }
+
+ if (!status)
+ {
region.rects = ®ion.extents;
region.numRects = region.size = 1;
@@ -1882,21 +1933,125 @@ setDefaultWindowAttributes (XWindowAttributes *wa)
}
void
-addWindow (CompScreen *screen,
+initRootWindow (CompScreen *s,
+ CompWindow *root)
+{
+ CompWindow *w = root;
+ CompPrivate *privates;
+ CompDisplay *d = s->display;
+ REGION rect;
+
+ memset (w, 0, sizeof (*w));
+
+ w->id = XRootWindow (d->display, s->screenNum);
+ w->screen = s;
+
+ w->bindFailed = TRUE;
+ w->alive = TRUE;
+
+ w->mapNum = s->mapNum++;
+
+ w->paint.opacity = OPAQUE;
+ w->paint.brightness = BRIGHT;
+ w->paint.saturation = COLOR;
+ w->paint.xScale = 1.0f;
+ w->paint.yScale = 1.0f;
+ w->paint.xTranslate = 0.0f;
+ w->paint.yTranslate = 0.0f;
+
+ w->lastPaint = w->paint;
+
+ if (s->windowPrivateLen)
+ {
+ privates = malloc (s->windowPrivateLen * sizeof (CompPrivate));
+ assert (privates);
+ }
+ else
+ privates = 0;
+
+ compObjectInit (&w->base, privates, COMP_OBJECT_TYPE_WINDOW);
+
+ w->clip = XCreateRegion ();
+ w->region = XCreateRegion ();
+
+ assert (w->clip && w->region);
+
+ if (!XGetWindowAttributes (d->display, w->id, &w->attrib))
+ setDefaultWindowAttributes (&w->attrib);
+
+ w->attrib.override_redirect = TRUE;
+
+ w->serverWidth = w->attrib.width;
+ w->serverHeight = w->attrib.height;
+ w->serverBorderWidth = w->attrib.border_width;
+
+ w->width = w->attrib.width + w->attrib.border_width * 2;
+ w->height = w->attrib.height + w->attrib.border_width * 2;
+
+ w->serverX = w->attrib.x;
+ w->serverY = w->attrib.y;
+
+ w->syncWait = FALSE;
+ w->syncX = w->attrib.x;
+ w->syncY = w->attrib.y;
+ w->syncWidth = w->attrib.width;
+ w->syncHeight = w->attrib.height;
+ w->syncBorderWidth = w->attrib.border_width;
+
+ w->alpha = (w->attrib.depth == 32);
+ w->type = CompWindowTypeUnknownMask;
+
+ w->invisible = TRUE;
+
+ rect.rects = &rect.extents;
+ rect.numRects = rect.size = 1;
+
+ rect.extents.x1 = w->attrib.x;
+ rect.extents.y1 = w->attrib.y;
+ rect.extents.x2 = w->attrib.x + w->width;
+ rect.extents.y2 = w->attrib.y + w->height;
+
+ XUnionRegion (&rect, w->region, w->region);
+
+ w->substructureRedirect = windowManagement;
+ w->redirectSubwindows = manualCompositeManagement;
+
+ w->texture = createTexture (s);
+}
+
+void
+addWindow (CompWindow *parent,
Window id,
Window aboveId)
{
CompWindow *w;
CompPrivate *privates;
+ CompScreen *screen = parent->screen;
CompDisplay *d = screen->display;
w = (CompWindow *) malloc (sizeof (CompWindow));
if (!w)
return;
+ w->parent = parent;
+
+ w->windows = 0;
+ w->reverseWindows = 0;
+
w->next = NULL;
w->prev = NULL;
+ w->substructureRedirect = FALSE;
+ w->redirectSubwindows = FALSE;
+
+ w->supportingWmCheckWindow = None;
+ w->syncStateSupport = FALSE;
+ w->activeChild = None;
+ w->previousActiveChild = None;
+
+ w->viewportOffsetX = 0;
+ w->viewportOffsetY = 0;
+
w->mapNum = 0;
w->activeNum = 0;
@@ -1935,9 +2090,18 @@ addWindow (CompScreen *screen,
w->pixmap = None;
w->destroyed = FALSE;
w->damaged = FALSE;
- w->redirected = TRUE;
w->managed = FALSE;
- w->bindFailed = FALSE;
+
+ if (parent->redirectSubwindows)
+ {
+ w->redirected = TRUE;
+ w->bindFailed = FALSE;
+ }
+ else
+ {
+ w->redirected = FALSE;
+ w->bindFailed = TRUE;
+ }
w->destroyRefCnt = 1;
w->unmapRefCnt = 1;
@@ -1996,11 +2160,15 @@ addWindow (CompScreen *screen,
w->syncCounter = 0;
w->syncWaitHandle = 0;
+ XSyncIntToValue (&w->syncValue, 0);
+
w->closeRequests = 0;
w->lastCloseRequestTime = 0;
w->overlayWindow = FALSE;
+ w->desktopWindowCount = 0;
+
if (screen->windowPrivateLen)
{
privates = malloc (screen->windowPrivateLen * sizeof (CompPrivate));
@@ -2063,10 +2231,23 @@ addWindow (CompScreen *screen,
w->saveMask = 0;
- XSelectInput (d->display, id,
- PropertyChangeMask |
- EnterWindowMask |
- FocusChangeMask);
+ if (w->parent->substructureRedirect)
+ {
+ XSelectInput (d->display, id,
+ PropertyChangeMask |
+ EnterWindowMask |
+ FocusChangeMask);
+ }
+ else if (w->parent->redirectSubwindows)
+ {
+ XSelectInput (d->display, id, PropertyChangeMask);
+
+ if (w->parent->syncStateSupport)
+ {
+ if (!getWindowProp (d, w->id, d->syncStateAtom, 0))
+ syncWait (w);
+ }
+ }
w->id = id;
@@ -2083,10 +2264,10 @@ addWindow (CompScreen *screen,
w->type = CompWindowTypeUnknownMask;
w->lastPong = d->lastPing;
- if (d->shapeExtension)
+ if (d->shapeExtension && parent->redirectSubwindows)
XShapeSelectInput (d->display, id, ShapeNotifyMask);
- insertWindowIntoScreen (screen, w, aboveId);
+ insertWindow (parent, w, aboveId);
EMPTY_REGION (w->region);
@@ -2104,8 +2285,9 @@ addWindow (CompScreen *screen,
XUnionRegion (&rect, w->region, w->region);
- w->damage = XDamageCreate (d->display, id,
- XDamageReportRawRectangles);
+ if (parent->redirectSubwindows)
+ w->damage = XDamageCreate (d->display, id,
+ XDamageReportRawRectangles);
/* need to check for DisplayModal state on all windows */
w->state = getWindowState (d, w->id);
@@ -2115,7 +2297,6 @@ addWindow (CompScreen *screen,
else
{
w->damage = None;
- w->attrib.map_state = IsUnmapped;
}
w->invisible = TRUE;
@@ -2134,6 +2315,9 @@ addWindow (CompScreen *screen,
if (!w->clientLeader)
w->startupId = getStartupId (w);
+ if (w->parent && !w->parent->substructureRedirect)
+ w->frame = getFrameWindow (w);
+
recalcWindowType (w);
getMwmHints (d, w->id, &w->mwmFunc, &w->mwmDecor);
@@ -2168,35 +2352,41 @@ addWindow (CompScreen *screen,
else
w->paint.saturation = getWindowProp32 (d, w->id,
d->winSaturationAtom, COLOR);
-
+
+ getSupportingWmCheck (w);
+
if (w->attrib.map_state == IsViewable)
{
w->placed = TRUE;
if (!w->attrib.override_redirect)
{
- w->managed = TRUE;
-
- if (getWmState (d, w->id) == IconicState)
- {
- if (w->state & CompWindowStateShadedMask)
- w->shaded = TRUE;
- else
- w->minimized = TRUE;
- }
- else
+ if (w->parent->substructureRedirect)
{
- if (w->wmType & (CompWindowTypeDockMask |
- CompWindowTypeDesktopMask))
+ w->managed = TRUE;
+
+ if (getWmState (d, w->id) == IconicState)
{
- setDesktopForWindow (w, 0xffffffff);
+ if (w->state & CompWindowStateShadedMask)
+ w->shaded = TRUE;
+ else
+ w->minimized = TRUE;
}
else
{
- if (w->desktop != 0xffffffff)
- w->desktop = screen->currentDesktop;
+ if (w->wmType & (CompWindowTypeDockMask |
+ CompWindowTypeDesktopMask))
+ {
+ setDesktopForWindow (w, 0xffffffff);
+ }
+ else
+ {
+ if (w->desktop != 0xffffffff)
+ w->desktop = screen->currentDesktop;
- setWindowProp (d, w->id, d->winDesktopAtom, w->desktop);
+ setWindowProp (d, w->id, d->winDesktopAtom,
+ w->desktop);
+ }
}
}
}
@@ -2239,7 +2429,7 @@ addWindow (CompScreen *screen,
/* TODO: bailout properly when objectInitPlugins fails */
assert (objectInitPlugins (&w->base));
- (*core.objectAdd) (&screen->base, &w->base);
+ (*core.objectAdd) (&parent->base, &w->base);
recalcWindowActions (w);
updateIconGeometry (w);
@@ -2254,7 +2444,10 @@ addWindow (CompScreen *screen,
void
removeWindow (CompWindow *w)
{
- unhookWindowFromScreen (w->screen, w);
+ while (w->windows)
+ removeWindow (w->windows);
+
+ unhookWindow (w->parent, w);
if (!w->destroyed)
{
@@ -2276,7 +2469,7 @@ removeWindow (CompWindow *w)
if (w->damage)
XDamageDestroy (d->display, w->damage);
- if (d->shapeExtension)
+ if (d->shapeExtension && w->parent->redirectSubwindows)
XShapeSelectInput (d->display, w->id, NoEventMask);
XSelectInput (d->display, w->id, NoEventMask);
@@ -2287,7 +2480,7 @@ removeWindow (CompWindow *w)
if (w->attrib.map_state == IsViewable && w->damaged)
{
if (w->type == CompWindowTypeDesktopMask)
- w->screen->desktopWindowCount--;
+ w->parent->desktopWindowCount--;
if (w->destroyed && w->struts)
updateWorkareaForScreen (w->screen);
@@ -2296,7 +2489,7 @@ removeWindow (CompWindow *w)
if (w->destroyed)
updateClientListForScreen (w->screen);
- if (!w->redirected)
+ if (w->parent->redirectSubwindows && !w->redirected)
{
w->screen->overlayWindowCount--;
@@ -2304,7 +2497,7 @@ removeWindow (CompWindow *w)
showOutputWindow (w->screen);
}
- (*core.objectRemove) (&w->screen->base, &w->base);
+ (*core.objectRemove) (&w->parent->base, &w->base);
objectFiniPlugins (&w->base);
@@ -2384,9 +2577,17 @@ sendConfigureNotify (CompWindow *w)
void
mapWindow (CompWindow *w)
{
+ CompWindow *c;
+
if (w->attrib.map_state == IsViewable)
return;
+ if (w->parent->attrib.map_state != IsViewable)
+ {
+ w->attrib.map_state = IsUnviewable;
+ return;
+ }
+
if (w->pendingMaps > 0)
w->pendingMaps--;
@@ -2402,7 +2603,7 @@ mapWindow (CompWindow *w)
w->attrib.map_state = IsViewable;
- if (!w->attrib.override_redirect)
+ if (w->managed)
setWmState (w->screen->display, NormalState, w->id);
w->invisible = TRUE;
@@ -2415,21 +2616,28 @@ mapWindow (CompWindow *w)
updateWindowRegion (w);
updateWindowSize (w);
- if (w->frame)
+ if (w->frame && w->parent->substructureRedirect)
XMapWindow (w->screen->display->display, w->frame);
updateClientListForScreen (w->screen);
if (w->type & CompWindowTypeDesktopMask)
- w->screen->desktopWindowCount++;
+ w->parent->desktopWindowCount++;
- if (w->protocols & CompWindowProtocolSyncRequestMask)
+ if (w->parent->substructureRedirect)
{
- sendSyncRequest (w);
- sendConfigureNotify (w);
+ if (w->protocols & CompWindowProtocolSyncRequestMask)
+ {
+ sendSyncRequest (w);
+ sendConfigureNotify (w);
+ }
+ else
+ {
+ leaveSyncWaitState (w);
+ }
}
- if (!w->attrib.override_redirect)
+ if (w->managed)
{
/* been shaded */
if (!w->height)
@@ -2438,35 +2646,31 @@ mapWindow (CompWindow *w)
w->attrib.width, ++w->attrib.height - 1,
w->attrib.border_width);
}
+
+ for (c = w->windows; c; c = c->next)
+ if (c->attrib.map_state == IsUnviewable)
+ mapWindow (c);
}
-void
-unmapWindow (CompWindow *w)
+static void
+withdrawWindowToState (CompWindow *w,
+ int state)
{
- if (w->mapNum)
- {
- if (w->frame && !w->shaded)
- XUnmapWindow (w->screen->display->display, w->frame);
-
- w->mapNum = 0;
- }
-
- w->unmapRefCnt--;
- if (w->unmapRefCnt > 0)
- return;
+ CompWindow *c;
if (w->struts)
updateWorkareaForScreen (w->screen);
- if (w->attrib.map_state != IsViewable)
+ if (w->attrib.map_state == state)
return;
if (w->type == CompWindowTypeDesktopMask)
- w->screen->desktopWindowCount--;
+ w->parent->desktopWindowCount--;
- addWindowDamage (w);
+ if (w->attrib.map_state == IsViewable)
+ addWindowDamage (w);
- w->attrib.map_state = IsUnmapped;
+ w->attrib.map_state = state;
w->invisible = TRUE;
@@ -2482,6 +2686,31 @@ unmapWindow (CompWindow *w)
if (!w->redirected)
redirectWindow (w);
+
+ for (c = w->windows; c; c = c->next)
+ if (c->attrib.map_state == IsViewable)
+ withdrawWindowToState (c, IsUnviewable);
+}
+
+void
+unmapWindow (CompWindow *w)
+{
+ if (w->mapNum)
+ {
+ if (w->frame && w->parent->substructureRedirect && !w->shaded)
+ XUnmapWindow (w->screen->display->display, w->frame);
+
+ if (w->parent->substructureRedirect)
+ enterSyncWaitState (w);
+
+ w->mapNum = 0;
+ }
+
+ w->unmapRefCnt--;
+ if (w->unmapRefCnt > 0)
+ return;
+
+ withdrawWindowToState (w, IsUnmapped);
}
static int
@@ -2496,8 +2725,8 @@ restackWindow (CompWindow *w,
else if (aboveId == None && !w->next)
return 0;
- unhookWindowFromScreen (w->screen, w);
- insertWindowIntoScreen (w->screen, w, aboveId);
+ unhookWindow (w->parent, w);
+ insertWindow (w->parent, w, aboveId);
updateClientListForScreen (w->screen);
@@ -2575,7 +2804,8 @@ resizeWindow (CompWindow *w,
w->invisible = WINDOW_INVISIBLE (w);
- updateFrameWindow (w);
+ if (w->parent && w->parent->substructureRedirect)
+ updateFrameWindow (w);
}
else if (w->attrib.x != x || w->attrib.y != y)
{
@@ -2586,7 +2816,7 @@ resizeWindow (CompWindow *w,
moveWindow (w, dx, dy, TRUE, TRUE);
- if (w->frame)
+ if (w->frame && w->parent->substructureRedirect)
XMoveWindow (w->screen->display->display, w->frame,
w->attrib.x - w->input.left,
w->attrib.y - w->input.top);
@@ -2614,6 +2844,9 @@ initializeSyncCounter (CompWindow *w)
unsigned long n, left;
unsigned char *data;
+ if (!w->parent->substructureRedirect)
+ return FALSE;
+
if (w->syncCounter)
return w->syncAlarm != None;
@@ -2633,7 +2866,6 @@ initializeSyncCounter (CompWindow *w)
XFree (data);
- XSyncIntsToValue (&w->syncValue, (unsigned int) rand (), 0);
XSyncSetCounter (w->screen->display->display,
w->syncCounter,
w->syncValue);
@@ -2689,6 +2921,20 @@ syncWaitTimeout (void *closure)
}
void
+syncWait (CompWindow *w)
+{
+ w->syncWait = TRUE;
+ w->syncX = w->serverX;
+ w->syncY = w->serverY;
+ w->syncWidth = w->serverWidth;
+ w->syncHeight = w->serverHeight;
+ w->syncBorderWidth = w->serverBorderWidth;
+
+ if (!w->syncWaitHandle)
+ w->syncWaitHandle = compAddTimeout (1000, 1200, syncWaitTimeout, w);
+}
+
+void
sendSyncRequest (CompWindow *w)
{
XClientMessageEvent xev;
@@ -2697,7 +2943,10 @@ sendSyncRequest (CompWindow *w)
return;
if (!initializeSyncCounter (w))
+ {
+ leaveSyncWaitState (w);
return;
+ }
xev.type = ClientMessage;
xev.window = w->id;
@@ -2711,23 +2960,26 @@ sendSyncRequest (CompWindow *w)
syncValueIncrement (&w->syncValue);
- XSendEvent (w->screen->display->display, w->id, FALSE, 0, (XEvent *) &xev);
+ enterSyncWaitState (w);
- w->syncWait = TRUE;
- w->syncX = w->serverX;
- w->syncY = w->serverY;
- w->syncWidth = w->serverWidth;
- w->syncHeight = w->serverHeight;
- w->syncBorderWidth = w->serverBorderWidth;
+ XSendEvent (w->screen->display->display, w->id, FALSE, 0, (XEvent *) &xev);
- if (!w->syncWaitHandle)
- w->syncWaitHandle = compAddTimeout (1000, 1200, syncWaitTimeout, w);
+ syncWait (w);
}
void
configureWindow (CompWindow *w,
XConfigureEvent *ce)
{
+ if (!w->managed)
+ {
+ w->serverX = ce->x;
+ w->serverY = ce->y;
+ w->serverWidth = ce->width;
+ w->serverHeight = ce->height;
+ w->serverBorderWidth = ce->border_width;
+ }
+
if (w->syncWait)
{
w->syncX = ce->x;
@@ -2738,15 +2990,6 @@ configureWindow (CompWindow *w,
}
else
{
- if (ce->override_redirect)
- {
- w->serverX = ce->x;
- w->serverY = ce->y;
- w->serverWidth = ce->width;
- w->serverHeight = ce->height;
- w->serverBorderWidth = ce->border_width;
- }
-
resizeWindow (w, ce->x, ce->y, ce->width, ce->height,
ce->border_width);
}
@@ -2755,6 +2998,9 @@ configureWindow (CompWindow *w,
if (restackWindow (w, ce->above))
addWindowDamage (w);
+
+ if (!w->parent)
+ configureScreen (w->screen, ce);
}
void
@@ -2764,7 +3010,7 @@ circulateWindow (CompWindow *w,
Window newAboveId;
if (ce->place == PlaceOnTop)
- newAboveId = getTopWindow (w->screen);
+ newAboveId = getTopWindow (w->parent);
else
newAboveId = 0;
@@ -2800,29 +3046,12 @@ moveWindow (CompWindow *w,
}
}
-void
-syncWindowPosition (CompWindow *w)
-{
- w->serverX = w->attrib.x;
- w->serverY = w->attrib.y;
-
- XMoveWindow (w->screen->display->display, w->id, w->attrib.x, w->attrib.y);
-
- if (w->frame)
- XMoveWindow (w->screen->display->display, w->frame,
- w->serverX - w->input.left,
- w->serverY - w->input.top);
-}
-
Bool
focusWindow (CompWindow *w)
{
if (w->attrib.override_redirect)
return FALSE;
- if (!w->managed)
- return FALSE;
-
if (!onCurrentDesktop (w))
return FALSE;
@@ -2902,7 +3131,8 @@ isGroupTransient (CompWindow *w,
if (!clientLeader)
return FALSE;
- if (w->transientFor == None || w->transientFor == w->screen->root)
+ if (w->transientFor == None ||
+ (w->parent && w->transientFor == w->parent->id))
{
if (w->type & (CompWindowTypeDialogMask |
CompWindowTypeModalDialogMask))
@@ -2922,7 +3152,7 @@ getModalTransient (CompWindow *window)
modalTransient = window;
- for (w = window->screen->reverseWindows; w; w = w->prev)
+ for (w = window->parent->reverseWindows; w; w = w->prev)
{
if (w == modalTransient || w->mapNum == 0)
continue;
@@ -2932,7 +3162,7 @@ getModalTransient (CompWindow *window)
if (w->state & CompWindowStateModalMask)
{
modalTransient = w;
- w = window->screen->reverseWindows;
+ w = window->parent->reverseWindows;
}
}
}
@@ -2944,7 +3174,7 @@ getModalTransient (CompWindow *window)
if (window->state & CompWindowStateModalMask)
return NULL;
- for (w = window->screen->reverseWindows; w; w = w->prev)
+ for (w = window->parent->reverseWindows; w; w = w->prev)
{
if (w == modalTransient || w->mapNum == 0)
continue;
@@ -2980,14 +3210,18 @@ moveInputFocusToWindow (CompWindow *w)
CompDisplay *d = s->display;
CompWindow *modalTransient;
+ if (!w->managed)
+ return;
+
modalTransient = getModalTransient (w);
if (modalTransient)
w = modalTransient;
if (w->state & CompWindowStateHiddenMask)
{
- XSetInputFocus (d->display, w->frame, RevertToPointerRoot, CurrentTime);
- XChangeProperty (d->display, s->root, d->winActiveAtom,
+ XSetInputFocus (d->display, w->frame, RevertToPointerRoot,
+ CurrentTime);
+ XChangeProperty (d->display, w->parent->id, d->winActiveAtom,
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &w->id, 1);
}
@@ -3027,7 +3261,9 @@ moveInputFocusToWindow (CompWindow *w)
CompWindow *ancestor;
/* move input to closest ancestor */
- for (ancestor = s->windows; ancestor; ancestor = ancestor->next)
+ for (ancestor = w->parent->windows;
+ ancestor;
+ ancestor = ancestor->next)
{
if (isAncestorTo (w, ancestor))
{
@@ -3111,7 +3347,7 @@ findSiblingBelow (CompWindow *w,
if (w->transientFor || isGroupTransient (w, clientLeader))
clientLeader = None;
- for (below = w->screen->reverseWindows; below; below = below->prev)
+ for (below = w->parent->reverseWindows; below; below = below->prev)
{
if (below == w || avoidStackingRelativeTo (below))
continue;
@@ -3157,7 +3393,7 @@ findSiblingBelow (CompWindow *w,
static CompWindow *
findLowestSiblingBelow (CompWindow *w)
{
- CompWindow *below, *lowest = w->screen->reverseWindows;
+ CompWindow *below, *lowest = w->parent->reverseWindows;
Window clientLeader = w->clientLeader;
unsigned int type = w->type;
@@ -3169,7 +3405,7 @@ findLowestSiblingBelow (CompWindow *w)
if (w->transientFor || isGroupTransient (w, clientLeader))
clientLeader = None;
- for (below = w->screen->reverseWindows; below; below = below->prev)
+ for (below = w->parent->reverseWindows; below; below = below->prev)
{
if (below == w || avoidStackingRelativeTo (below))
continue;
@@ -3351,6 +3587,55 @@ reconfigureXWindow (CompWindow *w,
unsigned int valueMask,
XWindowChanges *xwc)
{
+ if (!w->parent->substructureRedirect)
+ {
+ XEvent xev;
+ int mask = 0;
+
+ valueMask |=
+ adjustConfigureRequestForGravity (w,
+ xwc, valueMask,
+ w->sizeHints.win_gravity,
+ -1);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = w->screen->display->display;
+ xev.xclient.format = 32;
+
+ xev.xclient.message_type = w->screen->display->moveResizeWindowAtom;
+ xev.xclient.window = w->id;
+
+ xev.xclient.data.l[0] = (ClientTypePager << 12);
+
+ if (valueMask & CWX)
+ xev.xclient.data.l[0] |= (1 << 8);
+
+ if (valueMask & CWY)
+ xev.xclient.data.l[0] |= (1 << 9);
+
+ if (valueMask & CWWidth)
+ xev.xclient.data.l[0] |= (1 << 9);
+
+ if (valueMask & CWHeight)
+ xev.xclient.data.l[0] |= (1 << 9);
+
+ xev.xclient.data.l[1] = xwc->x;
+ xev.xclient.data.l[2] = xwc->y;
+ xev.xclient.data.l[3] = xwc->width;
+ xev.xclient.data.l[4] = xwc->height;
+
+ if (w->parent == &w->screen->root)
+ mask = SubstructureRedirectMask | SubstructureNotifyMask;
+
+ XSendEvent (w->screen->display->display,
+ w->parent->id,
+ FALSE,
+ mask,
+ &xev);
+
+ return;
+ }
+
if (valueMask & CWX)
w->serverX = xwc->x;
@@ -3368,9 +3653,31 @@ reconfigureXWindow (CompWindow *w,
XConfigureWindow (w->screen->display->display, w->id, valueMask, xwc);
- if (w->frame && (valueMask & (CWSibling | CWStackMode)))
+ if (w->frame && (valueMask & (CWSibling | CWStackMode | CWX | CWY)))
+ {
+ XWindowChanges wc = *xwc;
+
+ wc.x -= w->input.left;
+ wc.y -= w->input.top;
+
XConfigureWindow (w->screen->display->display, w->frame,
- valueMask & (CWSibling | CWStackMode), xwc);
+ valueMask & (CWSibling | CWStackMode | CWX | CWY),
+ &wc);
+
+ }
+}
+
+void
+syncWindowPosition (CompWindow *w)
+{
+ XWindowChanges xwc;
+
+ xwc.x = w->attrib.x;
+ xwc.y = w->attrib.y;
+ xwc.width = w->serverWidth;
+ xwc.height = w->serverHeight;
+
+ reconfigureXWindow (w, CWX | CWY, &xwc);
}
static Bool
@@ -3384,7 +3691,7 @@ stackTransients (CompWindow *w,
if (w->transientFor || isGroupTransient (w, clientLeader))
clientLeader = None;
- for (t = w->screen->reverseWindows; t; t = t->prev)
+ for (t = w->parent->reverseWindows; t; t = t->prev)
{
if (t == w || t == avoid)
continue;
@@ -3417,7 +3724,7 @@ stackAncestors (CompWindow *w,
{
CompWindow *ancestor;
- ancestor = findWindowAtScreen (w->screen, w->transientFor);
+ ancestor = findSibling (w, w->transientFor);
if (ancestor)
{
if (!stackTransients (ancestor, w, xwc))
@@ -3442,7 +3749,7 @@ stackAncestors (CompWindow *w,
{
CompWindow *a;
- for (a = w->screen->reverseWindows; a; a = a->prev)
+ for (a = w->parent->reverseWindows; a; a = a->prev)
{
if (a->clientLeader == w->clientLeader &&
a->transientFor == None &&
@@ -3709,7 +4016,8 @@ unsigned int
adjustConfigureRequestForGravity (CompWindow *w,
XWindowChanges *xwc,
unsigned int xwcm,
- int gravity)
+ int gravity,
+ int direction)
{
int newX, newY;
unsigned int mask = 0;
@@ -3724,23 +4032,23 @@ adjustConfigureRequestForGravity (CompWindow *w,
case WestGravity:
case SouthWestGravity:
if (xwcm & CWX)
- newX += w->input.left;
+ newX += w->input.left * direction;
break;
case NorthGravity:
case CenterGravity:
case SouthGravity:
if (!(xwcm & CWX))
- newX += (w->serverWidth - xwc->width) / 2;
+ newX += ((w->serverWidth - xwc->width) / 2) * direction;
break;
case NorthEastGravity:
case EastGravity:
case SouthEastGravity:
if (xwcm & CWX)
- newX -= w->input.right;
+ newX -= w->input.right * direction;
else
- newX += w->serverWidth - xwc->width;
+ newX += (w->serverWidth - xwc->width) * direction;
break;
case StaticGravity:
@@ -3756,23 +4064,23 @@ adjustConfigureRequestForGravity (CompWindow *w,
case NorthGravity:
case NorthEastGravity:
if (xwcm & CWY)
- newY += w->input.top;
+ newY += w->input.top * direction;
break;
case WestGravity:
case CenterGravity:
case EastGravity:
if (!(xwcm & CWY))
- newY += (w->serverHeight - xwc->height) / 2;
+ newY += ((w->serverHeight - xwc->height) / 2) * direction;
break;
case SouthWestGravity:
case SouthGravity:
case SouthEastGravity:
if (xwcm & CWY)
- newY -= w->input.bottom;
+ newY -= w->input.bottom * direction;
else
- newY += w->serverHeight - xwc->height;
+ newY += (w->serverHeight - xwc->height) * direction;
break;
case StaticGravity:
@@ -3838,7 +4146,7 @@ moveResizeWindow (CompWindow *w,
}
}
- xwcm |= adjustConfigureRequestForGravity (w, xwc, xwcm, gravity);
+ xwcm |= adjustConfigureRequestForGravity (w, xwc, xwcm, gravity, 1);
if (!(w->type & (CompWindowTypeDockMask |
CompWindowTypeFullscreenMask |
@@ -3864,7 +4172,7 @@ moveResizeWindow (CompWindow *w,
{
int min, max;
- min = w->screen->workArea.x + w->input.left;
+ min = w->screen->workArea.x - w->serverWidth;
max = w->screen->workArea.x + w->screen->workArea.width;
min -= w->screen->x * w->screen->width;
@@ -3975,7 +4283,7 @@ addWindowStackChanges (CompWindow *w,
if (!sibling)
{
XLowerWindow (w->screen->display->display, w->id);
- if (w->frame)
+ if (w->frame && w->parent->substructureRedirect)
XLowerWindow (w->screen->display->display, w->frame);
}
else if (sibling->id != w->prev->id)
@@ -4008,7 +4316,7 @@ addWindowStackChanges (CompWindow *w,
{
CompWindow *dw;
- for (dw = w->screen->reverseWindows; dw; dw = dw->prev)
+ for (dw = w->parent->reverseWindows; dw; dw = dw->prev)
if (dw == sibling)
break;
@@ -4073,7 +4381,7 @@ findValidStackSiblingBelow (CompWindow *w,
lowest = last = findLowestSiblingBelow (w);
/* walk from bottom up */
- for (p = w->screen->windows; p; p = p->next)
+ for (p = w->parent->windows; p; p = p->next)
{
/* stop walking when we reach the sibling we should try to stack
below */
@@ -4122,7 +4430,7 @@ updateWindowAttributes (CompWindow *w,
XWindowChanges xwc;
int mask = 0;
- if (w->attrib.override_redirect || !w->managed)
+ if (!w->managed)
return;
if (w->state & CompWindowStateShadedMask)
@@ -4200,7 +4508,7 @@ ensureWindowVisibility (CompWindow *w)
int dx = 0;
int dy = 0;
- if (w->struts || w->attrib.override_redirect)
+ if (w->struts || !w->managed)
return;
if (w->type & (CompWindowTypeDockMask |
@@ -4259,6 +4567,34 @@ revealAncestors (CompWindow *w,
void
activateWindow (CompWindow *w)
{
+ if (!w->parent->substructureRedirect)
+ {
+ XEvent xev;
+ int mask = 0;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.display = w->screen->display->display;
+ xev.xclient.format = 32;
+
+ xev.xclient.message_type = w->screen->display->winActiveAtom;
+ xev.xclient.window = w->id;
+
+ xev.xclient.data.l[0] = 2; /* pretend to be a pager */
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ if (w->parent == &w->screen->root)
+ mask = SubstructureRedirectMask | SubstructureNotifyMask;
+
+ XSendEvent (w->screen->display->display, w->parent->id, FALSE,
+ mask,
+ &xev);
+
+ return;
+ }
+
setCurrentDesktop (w->screen, w->desktop);
forEachWindowOnScreen (w->screen, revealAncestors, (void *) w);
@@ -4511,7 +4847,8 @@ hideWindow (CompWindow *w)
w->shaded = FALSE;
- if ((w->state & CompWindowStateShadedMask) && w->frame)
+ if ((w->state & CompWindowStateShadedMask) &&
+ w->frame && w->parent->substructureRedirect)
XUnmapWindow (w->screen->display->display, w->frame);
}
@@ -4551,7 +4888,7 @@ showWindow (CompWindow *w)
{
w->shaded = TRUE;
- if (w->frame)
+ if (w->frame && w->parent->substructureRedirect)
XMapWindow (w->screen->display->display, w->frame);
if (w->height)
@@ -4633,7 +4970,7 @@ void
maximizeWindow (CompWindow *w,
int state)
{
- if (w->attrib.override_redirect)
+ if (!w->managed)
return;
state = constrainWindowState (state, w->actions);
@@ -4770,7 +5107,7 @@ isWindowFocusAllowed (CompWindow *w,
{
CompWindow *parent;
- parent = findWindowAtScreen (w->screen, w->transientFor);
+ parent = findSibling (w, w->transientFor);
if (parent)
gotTimestamp = getUsageTimestampForWindow (parent, &wUserTime);
}
@@ -4880,7 +5217,7 @@ unredirectWindow (CompWindow *w)
void
redirectWindow (CompWindow *w)
{
- if (w->redirected)
+ if (!w->parent || !w->parent->redirectSubwindows || w->redirected)
return;
XCompositeRedirectWindow (w->screen->display->display, w->id,
@@ -5199,3 +5536,151 @@ getWindowMovementForOffset (CompWindow *w,
}
}
+
+void
+enterSyncWaitState (CompWindow *w)
+{
+ XDeleteProperty (w->screen->display->display,
+ w->id,
+ w->screen->display->syncStateAtom);
+}
+
+void
+leaveSyncWaitState (CompWindow *w)
+{
+ unsigned long data = XSyncValueLow32 (w->syncValue);
+
+ XChangeProperty (w->screen->display->display,
+ w->id,
+ w->screen->display->syncStateAtom,
+ XA_CARDINAL,
+ 32,
+ PropModeReplace,
+ (unsigned char *) &data, 1);
+}
+
+void
+insertWindow (CompWindow *parent,
+ CompWindow *w,
+ Window aboveId)
+{
+ CompWindow *p;
+
+ if (parent->windows)
+ {
+ if (!aboveId)
+ {
+ w->next = parent->windows;
+ w->prev = NULL;
+ parent->windows->prev = w;
+ parent->windows = w;
+ }
+ else
+ {
+ for (p = parent->windows; p; p = p->next)
+ {
+ if (p->id == aboveId)
+ {
+ if (p->next)
+ {
+ w->next = p->next;
+ w->prev = p;
+ p->next->prev = w;
+ p->next = w;
+ }
+ else
+ {
+ p->next = w;
+ w->next = NULL;
+ w->prev = p;
+ parent->reverseWindows = w;
+ }
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ if (!p)
+ abort ();
+#endif
+
+ }
+ }
+ else
+ {
+ parent->reverseWindows = parent->windows = w;
+ w->prev = w->next = NULL;
+ }
+}
+
+void
+unhookWindow (CompWindow *parent,
+ CompWindow *w)
+{
+ CompWindow *next, *prev;
+
+ next = w->next;
+ prev = w->prev;
+
+ if (next || prev)
+ {
+ if (next)
+ {
+ if (prev)
+ {
+ next->prev = prev;
+ }
+ else
+ {
+ parent->windows = next;
+ next->prev = NULL;
+ }
+ }
+
+ if (prev)
+ {
+ if (next)
+ {
+ prev->next = next;
+ }
+ else
+ {
+ parent->reverseWindows = prev;
+ prev->next = NULL;
+ }
+ }
+ }
+ else
+ {
+ parent->windows = parent->reverseWindows = NULL;
+ }
+
+ if (w == lastFoundWindow)
+ lastFoundWindow = NULL;
+ if (w == lastDamagedWindow)
+ lastDamagedWindow = NULL;
+}
+
+CompWindow *
+findSibling (CompWindow *w,
+ Window id)
+{
+ if (w->parent)
+ for (w = w->parent->windows; w; w = w->next)
+ if (w->id == id)
+ return w;
+
+ return NULL;
+}
+
+CompWindow *
+walkDepthFirst (CompWindow *w)
+{
+ if (w->windows)
+ return w->windows;
+
+ while (!w->next && w->parent)
+ w = w->parent;
+
+ return w->next;
+}