Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:dreveman:Factory
compiz
compiz-0.7.6-NOMAD.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File compiz-0.7.6-NOMAD.diff of Package compiz
diff --git a/gtk/window-decorator/gtk-window-decorator.c b/gtk/window-decorator/gtk-window-decorator.c index 0ebb2d7..77e6d22 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; @@ -384,8 +386,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; @@ -572,6 +575,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 +602,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 +671,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 +997,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 +1010,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 +1026,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 +1043,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 +1168,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 +1242,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 +1270,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 +1311,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 +1334,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 +1371,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 +1380,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 +1389,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 +1467,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 +1494,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 +1878,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 +1932,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 +1960,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 +1975,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 +2021,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 +2039,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 +2078,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 +2112,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 +2123,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 +2141,7 @@ meta_draw_window_decoration (decor_t *d) meta_theme_draw_frame (theme, style_window, - pixmap, + pix, &rect, 0, -fgeom.top_height, @@ -2122,7 +2181,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 +2215,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 +2231,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 +2726,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 +2734,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 +2797,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 +2823,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); } @@ -3488,7 +3650,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 +3672,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 +3696,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 +3708,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); @@ -3791,6 +3968,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); @@ -3821,6 +3999,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)); @@ -3998,10 +4182,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); } } @@ -4009,10 +4194,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); } } } @@ -6866,6 +7052,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) @@ -6914,6 +7104,7 @@ main (int argc, char *argv[]) fprintf (stderr, "%s " "[--minimal] " "[--replace] " + "[--reduced-resources] " "[--blur none|titlebar|all] " #ifdef USE_METACITY @@ -6956,8 +7147,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); diff --git a/include/compiz-core.h b/include/compiz-core.h index e976d59..fcf8bb2 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 30080901 + 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; @@ -729,6 +737,652 @@ 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; + + GLushort opacity; + GLushort brightness; + GLushort saturation; + + Bool opacityPropSet; + int opacityFactor; + + WindowPaintAttrib paint; + WindowPaintAttrib lastPaint; + + unsigned int lastMask; + + CompWindowExtents input; + CompWindowExtents output; + + CompStruts *struts; + + CompIcon **icon; + int nIcon; + + 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; + + 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 +updateWindowOpacity (CompWindow *window); + +void +updateNormalHints (CompWindow *window); + +void +updateWmHints (CompWindow *w); + +void +updateWindowClassHints (CompWindow *window); + +void +updateTransientHint (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 +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); + +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); + +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, + 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); + + /* display.c */ #define COMP_DISPLAY_OPTION_ABI 0 @@ -1052,6 +1706,8 @@ struct _CompDisplay { Atom startupIdAtom; + Atom syncStateAtom; + unsigned int lastPing; CompTimeoutHandle pingHandle; @@ -1164,6 +1820,12 @@ addDisplay (const char *name); void removeDisplay (CompDisplay *d); +Bool +manageDisplay (CompDisplay *d); + +void +updatePlugins (CompDisplay *d); + Time getCurrentTimeFromDisplay (CompDisplay *d); @@ -1191,6 +1853,9 @@ virtualToRealModMask (CompDisplay *d, void updateModifierMappings (CompDisplay *d); +void +handleTimeouts (struct timeval *tv); + unsigned int keycodeToModifiers (CompDisplay *d, int keycode); @@ -1306,9 +1971,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]; @@ -1331,26 +1996,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) @@ -1408,7 +2056,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 { @@ -1421,6 +2069,16 @@ struct _CompWalker { WalkStepProc prev; }; +typedef void (*PainterFiniProc) (CompScreen *screen, + CompPainter *painter); + +struct _CompPainter { + PainterFiniProc fini; + CompPrivate priv; + + PaintWindowProc paintObject; +}; + /* window paint flags @@ -1451,6 +2109,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) @@ -1472,12 +2136,6 @@ struct _CompWalker { #define PAINT_WINDOW_BLEND_MASK (1 << 19) -typedef Bool (*PaintWindowProc) (CompWindow *window, - const WindowPaintAttrib *attrib, - const CompTransform *transform, - Region region, - unsigned int mask); - typedef Bool (*DrawWindowProc) (CompWindow *window, const CompTransform *transform, const FragmentAttrib *fragment, @@ -1495,8 +2153,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, @@ -1903,8 +2559,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) @@ -1927,12 +2587,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; @@ -2021,8 +2675,8 @@ struct _CompScreen { CompScreen *next; CompDisplay *display; - CompWindow *windows; - CompWindow *reverseWindows; + + CompWindow root; char *windowPrivateIndices; int windowPrivateLen; @@ -2040,7 +2694,6 @@ struct _CompScreen { REGION region; Region damage; unsigned long damageMask; - Window root; Window overlay; Window output; XWindowAttributes attrib; @@ -2073,9 +2726,6 @@ struct _CompScreen { CompOutput fullscreenOutput; Bool hasOverlappingOutputs; - int windowOffsetX; - int windowOffsetY; - XRectangle lastViewport; CompActiveWindowHistory history[ACTIVE_WINDOW_HISTORY_NUM]; @@ -2222,7 +2872,8 @@ struct _CompScreen { OutputChangeNotifyProc outputChangeNotify; - InitWindowWalkerProc initWindowWalker; + InitWindowWalkerProc initWindowWalker; + InitObjectPainterProc initObjectPainter; }; #define GET_CORE_SCREEN(object) ((CompScreen *) (object)) @@ -2285,6 +2936,12 @@ void detectRefreshRateOfScreen (CompScreen *s); void +getSupportingWmCheck (CompWindow *w); + +void +getDesktopHints (CompScreen *s); + +void showOutputWindow (CompScreen *s); void @@ -2314,15 +2971,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); @@ -2438,7 +3086,7 @@ disableScreenEdge (CompScreen *s, int edge); Window -getTopWindow (CompScreen *s); +getTopWindow (CompWindow *parent); void makeScreenCurrent (CompScreen *s); @@ -2525,579 +3173,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; - - GLushort opacity; - GLushort brightness; - GLushort saturation; - - Bool opacityPropSet; - int opacityFactor; - - WindowPaintAttrib paint; - WindowPaintAttrib lastPaint; - - unsigned int lastMask; - - CompWindowExtents input; - CompWindowExtents output; - - CompStruts *struts; - - CompIcon **icon; - int nIcon; - - 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 -updateWindowOpacity (CompWindow *window); - -void -updateNormalHints (CompWindow *window); - -void -updateWmHints (CompWindow *w); - -void -updateWindowClassHints (CompWindow *window); - -void -updateTransientHint (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); - -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); - -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, - 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/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/window.cpp b/kde/window-decorator-kde4/window.cpp index b13dc23..20cf513 100644 --- a/kde/window-decorator-kde4/window.cpp +++ b/kde/window-decorator-kde4/window.cpp @@ -1523,7 +1523,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..5fed1d2 100644 --- a/kde/window-decorator/window.cpp +++ b/kde/window-decorator/window.cpp @@ -1442,7 +1442,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/metadata/Makefile.am b/metadata/Makefile.am index a73ac20..1ef0ecb 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 \ @@ -27,6 +28,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 cfe0661..0cb295d 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 9f54ea4..e1a5679 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 bae9caa..6fc16c1 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 d7b3a1c..c164ada 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 @@ -144,6 +150,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 c377dee..a95c847 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 093b1b8..9daa085 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); } } @@ -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)); diff --git a/plugins/clone.c b/plugins/clone.c index ac2af5e..90b5a26 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 fffa851..b2d0b3f 100644 --- a/plugins/cube.c +++ b/plugins/cube.c @@ -1602,12 +1602,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 +1701,7 @@ cubeFold (CompDisplay *d, { CUBE_SCREEN (s); - if (xid && s->root != xid) + if (xid && s->root.id != xid) continue; if (cs->grabIndex) @@ -1864,7 +1864,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)); diff --git a/plugins/dbus.c b/plugins/dbus.c index 07fa228..f3f64bd 100644 --- a/plugins/dbus.c +++ b/plugins/dbus.c @@ -64,8 +64,10 @@ typedef struct _DbusCore { CompFileWatchHandle fileWatch[DBUS_FILE_WATCH_NUM]; - InitPluginForObjectProc initPluginForObject; - SetOptionForPluginProc setOptionForPlugin; + SetOptionForPluginProc setOptionForPlugin; + + ObjectAddProc objectAdd; + ObjectRemoveProc objectRemove; } DbusCore; static DBusHandlerResult dbusHandleMessage (DBusConnection *, @@ -2123,62 +2125,6 @@ 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) -{ - char objectPath[256]; - - DBUS_CORE (&core); - - 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); - - UNWRAP (dc, &core, initPluginForObject); - status = (*core.initPluginForObject) (p, o); - WRAP (dc, &core, initPluginForObject, dbusInitPluginForObject); - - if (status && p->vTable->getObjectOptions) - { - static InitPluginForObjectProc dispTab[] = { - (InitPluginForObjectProc) 0, /* InitPluginForCore */ - (InitPluginForObjectProc) dbusInitPluginForDisplay, - (InitPluginForObjectProc) dbusInitPluginForScreen - }; - - RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o)); - } - - return status; -} - -static CompBool dbusSetOptionForPlugin (CompObject *object, const char *plugin, const char *name, @@ -2250,6 +2196,80 @@ dbusSendPluginsChangedSignal (const char *name, dbus_message_unref (signal); } +static void +dbusDisplayAdd (CompCore *c, + CompDisplay *d) +{ + DBUS_CORE (&core); + + dbusRegisterPluginsForDisplay (dc->connection, d); +} + +static void +dbusDisplayRemove (CompCore *c, + CompDisplay *d) +{ + DBUS_CORE (&core); + + dbusUnregisterPluginsForDisplay (dc->connection, 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) @@ -2361,7 +2381,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; @@ -2396,7 +2417,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); @@ -2406,17 +2428,8 @@ static Bool dbusInitDisplay (CompPlugin *p, CompDisplay *d) { - char objectPath[256]; - - DBUS_CORE (&core); - - /* register core 'plugin' */ - dbusRegisterPluginForDisplay (dc->connection, d, "core"); - dbusRegisterPluginsForDisplay (dc->connection, d); - - snprintf (objectPath, 256, "%s/core/allscreens", COMPIZ_DBUS_ROOT_PATH); - - dbusRegisterOptions (dc->connection, objectPath); + if (d->base.parent) + dbusObjectAdd (d->base.parent, &d->base); return TRUE; } @@ -2425,26 +2438,16 @@ static void dbusFiniDisplay (CompPlugin *p, CompDisplay *d) { - DBUS_CORE (&core); - - dbusUnregisterPluginForDisplay (dc->connection, d, "core"); - dbusUnregisterPluginsForDisplay (dc->connection, d); + if (d->base.parent) + dbusObjectRemove (d->base.parent, &d->base); } static Bool dbusInitScreen (CompPlugin *p, CompScreen *s) { - char objectPath[256]; - - DBUS_CORE (&core); - - snprintf (objectPath, 256, "%s/%s/screen%d", COMPIZ_DBUS_ROOT_PATH, - "core", s->screenNum); - - dbusRegisterPluginForScreen (dc->connection, s, "core"); - dbusRegisterPluginsForScreen (dc->connection, s); - dbusRegisterOptions (dc->connection, objectPath); + if (s->base.parent) + dbusObjectAdd (s->base.parent, &s->base); return TRUE; } @@ -2453,10 +2456,8 @@ static void dbusFiniScreen (CompPlugin *p, CompScreen *s) { - DBUS_CORE (&core); - - dbusUnregisterPluginForScreen (dc->connection, s, "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 7fd617e..e67feeb 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; @@ -137,7 +133,11 @@ typedef struct _DecorScreen { typedef struct _DecorWindow { WindowDecoration *wd; - Decoration *decor; + + Window dmWin; + Window wmWin; + + Decoration *decor[DECOR_NUM]; CompTimeoutHandle resizeUpdateHandle; } DecorWindow; @@ -186,6 +186,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; @@ -222,7 +231,7 @@ decorDrawWindow (CompWindow *w, attrib, mask); } - return status; + return TRUE; } static DecorTexture * @@ -259,19 +268,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; @@ -406,9 +422,11 @@ decorCreateDecoration (CompScreen *screen, int left, right, top, bottom; int x1, y1, x2, y2; + DECOR_DISPLAY (screen->display); + result = XGetWindowProperty (screen->display->display, id, decorAtom, 0L, 1024L, FALSE, - XA_INTEGER, &actual, &format, + dd->winDecorAtom, &actual, &format, &n, &nleft, &data); if (result != Success || !n || !data) @@ -530,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 * @@ -652,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, @@ -710,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) { @@ -725,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; @@ -740,6 +776,9 @@ decorWindowUpdate (CompWindow *w, break; } + if (!GET_DECOR_WINDOW (w->parent, ds)->wmWin) + decorate = FALSE; + if (w->attrib.override_redirect) decorate = FALSE; @@ -752,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 @@ -770,7 +809,7 @@ decorWindowUpdate (CompWindow *w, if (matchEval (match, w)) { if (w->region->numRects == 1 && !w->alpha) - decor = ds->decor[DECOR_BARE]; + decor = GET_DECOR_WINDOW (w->parent, ds)->decor[DECOR_BARE]; /* no decoration on windows with below state */ if (w->state & CompWindowStateBelowMask) @@ -784,7 +823,7 @@ decorWindowUpdate (CompWindow *w, } } - if (!ds->dmWin || !allowDecoration) + if (!GET_DECOR_WINDOW (w->parent, ds)->dmWin || !allowDecoration) decor = NULL; if (decor == old) @@ -831,7 +870,7 @@ decorWindowUpdate (CompWindow *w, moveDy = -oldShiftY; } - if (!w->attrib.override_redirect && (moveDx || moveDy)) + if (w->managed && (moveDx || moveDy)) { XWindowChanges xwc; unsigned int mask = CWX | CWY; @@ -862,20 +901,22 @@ decorWindowUpdate (CompWindow *w, } static void -decorCheckForDmOnScreen (CompScreen *s, - Bool updateWindows) +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); @@ -895,46 +936,62 @@ decorCheckForDmOnScreen (CompScreen *s, dmWin = None; } - if (dmWin != ds->dmWin) + /* don't allow dm's on redirected windows */ + if (w->parent && w->parent->redirectSubwindows) + dmWin = None; + + 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); } } } @@ -943,7 +1000,6 @@ static void decorHandleEvent (CompDisplay *d, XEvent *event) { - Window activeWindow = d->activeWindow; CompWindow *w; DECOR_DISPLAY (d); @@ -951,12 +1007,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: @@ -984,7 +1044,8 @@ decorHandleEvent (CompDisplay *d, { ds = GET_DECOR_SCREEN (s, dd); - for (w = s->windows; w; w = w->next) + w = s->root.windows; + for (;;) { if (w->shaded || w->mapNum) { @@ -993,6 +1054,20 @@ decorHandleEvent (CompDisplay *d, if (dw->wd && dw->wd->decor->texture == t) damageWindowOutputExtents (w); } + + if (w->windows) + { + w = w->windows; + continue; + } + + while (!w->next && (w != &s->root)) + w = w->parent; + + if (w == &s->root) + break; + + w = w->next; } } return; @@ -1006,25 +1081,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) + decorWindowUpdate (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) + decorWindowUpdate (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); } } @@ -1036,14 +1133,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 { @@ -1053,17 +1149,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); + } } } } @@ -1161,9 +1263,9 @@ decorSetDisplayOption (CompPlugin *plugin, for (s = display->screens; s; s = s->next) { - DECOR_SCREEN (s); + DECOR_WINDOW ((&s->root)); - if (!ds->dmWin) + if (!dw->dmWin) runCommand (s, o->value.s); } @@ -1178,8 +1280,27 @@ decorSetDisplayOption (CompPlugin *plugin, CompWindow *w; for (s = display->screens; s; s = s->next) - for (w = s->windows; w; w = w->next) + { + w = s->root.windows; + for (;;) + { decorWindowUpdate (w, TRUE); + + if (w->windows) + { + w = w->windows; + continue; + } + + while (!w->next && (w != &s->root)) + w = w->parent; + + if (w == &s->root) + break; + + w = w->next; + } + } } break; default: @@ -1200,7 +1321,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; @@ -1245,15 +1366,20 @@ 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, 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. */ + dw->resizeUpdateHandle = + compAddTimeout (0, decorResizeUpdateTimeout, w); + updateWindowDecorationScale (w); + } UNWRAP (ds, w->screen, windowResizeNotify); (*w->screen->windowResizeNotify) (w, dx, dy, dwidth, dheight); @@ -1490,10 +1616,6 @@ decorInitScreen (CompPlugin *p, return FALSE; } - memset (ds->decor, 0, sizeof (ds->decor)); - - ds->dmWin = None; - WRAP (ds, s, drawWindow, decorDrawWindow); WRAP (ds, s, damageWindowRect, decorDamageWindowRect); WRAP (ds, s, getOutputExtentsForWindow, decorGetOutputExtentsForWindow); @@ -1503,11 +1625,6 @@ decorInitScreen (CompPlugin *p, s->base.privates[dd->screenPrivateIndex].ptr = ds; - decorCheckForDmOnScreen (s, FALSE); - - if (!ds->dmWin) - runCommand (s, dd->opt[DECOR_DISPLAY_OPTION_COMMAND].value.s); - return TRUE; } @@ -1515,14 +1632,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]); - freeWindowPrivateIndex (s, ds->windowPrivateIndex); UNWRAP (ds, s, drawWindow); @@ -1540,6 +1651,7 @@ decorInitWindow (CompPlugin *p, CompWindow *w) { DecorWindow *dw; + int i; DECOR_SCREEN (w->screen); @@ -1547,15 +1659,42 @@ 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); + if (w->parent && w->parent->redirectSubwindows) + { + 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_DISPLAY (w->screen->display); + + decorCheckForDm (w, FALSE); + + if (!w->parent && !dw->dmWin) + runCommand (w->screen, + dd->opt[DECOR_DISPLAY_OPTION_COMMAND].value.s); + } if (w->base.parent) decorWindowAdd (w->screen, w); @@ -1567,6 +1706,8 @@ static void decorFiniWindow (CompPlugin *p, CompWindow *w) { + int i; + DECOR_WINDOW (w); if (dw->resizeUpdateHandle) @@ -1578,8 +1719,9 @@ decorFiniWindow (CompPlugin *p, 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 7412e57..3d0c9ce 100644 --- a/plugins/fade.c +++ b/plugins/fade.c @@ -174,9 +174,26 @@ fadePreparePaintScreen (CompScreen *s, if (steps < 12) steps = 12; - for (w = s->windows; w; w = w->next) + w = s->root.windows; + for (;;) + { GET_FADE_WINDOW (w, fs)->steps = steps; + if (w->windows) + { + w = w->windows; + continue; + } + + while (!w->next && (w != &s->root)) + w = w->parent; + + if (w == &s->root) + break; + + w = w->next; + } + UNWRAP (fs, s, preparePaintScreen); (*s->preparePaintScreen) (s, msSinceLastPaint); WRAP (fs, s, preparePaintScreen, fadePreparePaintScreen); @@ -340,7 +357,7 @@ fadeAddDisplayModal (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) { FADE_WINDOW (w); @@ -375,7 +392,7 @@ fadeRemoveDisplayModal (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) { FADE_WINDOW (w); @@ -500,7 +517,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; @@ -645,7 +662,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 792c6e0..db898ff 100644 --- a/plugins/gconf.c +++ b/plugins/gconf.c @@ -701,12 +701,12 @@ gconfSendGLibNotify (CompDisplay *d) xev.xclient.format = 32; xev.xclient.message_type = XInternAtom (dpy, "_COMPIZ_GLIB_NOTIFY", 0); - xev.xclient.window = d->screens->root; + xev.xclient.window = d->screens->root.id; memset (xev.xclient.data.l, 0, sizeof (xev.xclient.data.l)); XSendEvent (dpy, - d->screens->root, + d->screens->root.id, FALSE, SubstructureRedirectMask | SubstructureNotifyMask, &xev); diff --git a/plugins/glx.c b/plugins/glx.c new file mode 100644 index 0000000..32b49af --- /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 (d, p->vTable->name, CompLogLevelError, + "GLX extension is not available"); + return FALSE; + } + + if (manualCompositeManagement) + return TRUE; + + if (d->screens) + { + compLogMessage (d, 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 4531824..751a5d4 100644 --- a/plugins/minimize.c +++ b/plugins/minimize.c @@ -353,7 +353,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); @@ -436,7 +436,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); @@ -472,7 +472,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); @@ -803,7 +803,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 214c25e..482127f 100644 --- a/plugins/move.c +++ b/plugins/move.c @@ -298,7 +298,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 +534,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 @@ -658,7 +664,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); diff --git a/plugins/place.c b/plugins/place.c index c74348f..bbeb0ea 100644 --- a/plugins/place.c +++ b/plugins/place.c @@ -241,7 +241,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); } @@ -665,7 +665,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); @@ -676,7 +676,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; @@ -797,7 +797,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; @@ -855,7 +855,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; @@ -890,7 +890,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; @@ -1031,7 +1031,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)) { @@ -1423,7 +1423,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 c7712b6..18eea43 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); @@ -424,6 +424,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; @@ -886,7 +890,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 fdd3878..90d547e 100644 --- a/plugins/rotate.c +++ b/plugins/rotate.c @@ -367,7 +367,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; @@ -679,7 +709,7 @@ rotateTerminate (CompDisplay *d, { ROTATE_SCREEN (s); - if (xid && s->root != xid) + if (xid && s->root.id != xid) continue; if (rs->grabIndex) @@ -749,7 +779,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); } @@ -836,7 +866,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); } @@ -1011,7 +1041,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"; @@ -1056,7 +1086,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"; @@ -1136,7 +1166,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"; @@ -1250,7 +1280,7 @@ rotateFlipTerminate (CompDisplay *d, { ROTATE_SCREEN (s); - if (xid && s->root != xid) + if (xid && s->root.id != xid) continue; if (rs->rotateHandle) @@ -1377,7 +1407,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"; @@ -1437,7 +1467,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"; @@ -1506,6 +1536,9 @@ rotateHandleEvent (CompDisplay *d, } break; case ClientMessage: + if (!windowManagement) + break; + if (event->xclient.message_type == d->desktopViewportAtom) { s = findScreenAtDisplay (d, event->xclient.window); @@ -1529,7 +1562,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) @@ -1547,7 +1580,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"; @@ -1590,7 +1623,7 @@ rotateActivateWindow (CompWindow *w) unsigned int ui; CompOption o[4]; - 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) @@ -1608,7 +1641,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 992e862..2688b64 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"; @@ -742,7 +742,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 +897,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 +962,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 +1028,7 @@ scaleTerminate (CompDisplay *d, { SCALE_SCREEN (s); - if (xid && s->root != xid) + if (xid && s->root.id != xid) continue; if (ss->grab) @@ -1048,7 +1048,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 +1102,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 +1420,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 +1453,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 +1548,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 +1592,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 +1649,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 +1788,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 +1926,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 b66b9f8..2de085e 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 4a4e9da..2ae439c 100644 --- a/plugins/switcher.c +++ b/plugins/switcher.c @@ -324,7 +324,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"; @@ -411,7 +411,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); @@ -471,7 +471,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; @@ -479,7 +479,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); } @@ -528,7 +528,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++; @@ -596,7 +596,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; @@ -627,11 +627,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, @@ -719,7 +719,7 @@ switchTerminate (CompDisplay *d, { SWITCH_SCREEN (s); - if (xid && s->root != xid) + if (xid && s->root.id != xid) continue; if (ss->grabIndex) @@ -981,7 +981,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; @@ -1314,8 +1314,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 @@ -1348,8 +1349,8 @@ switchPaintOutput (CompScreen *s, if (zoomed) { - unhookWindowFromScreen (s, zoomed); - insertWindowIntoScreen (s, zoomed, zoomedAbove); + unhookWindow (zoomed->parent, zoomed); + insertWindow (zoomed->parent, zoomed, zoomedAbove); } if (switcher) @@ -1835,7 +1836,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 4268d00..d52241a 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); } @@ -940,7 +940,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) { @@ -1046,7 +1046,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)); @@ -1165,7 +1166,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 fca4df3..7e7ee72 100644 --- a/plugins/water.c +++ b/plugins/water.c @@ -1268,7 +1268,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 +1595,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..01c5cc6 --- /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 (d, 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..62dadc5 100644 --- a/plugins/wobbly.c +++ b/plugins/wobbly.c @@ -270,7 +270,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 +375,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 +480,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 +583,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 +1656,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) + w = s->root.windows; + for (;;) { ww = GET_WOBBLY_WINDOW (w, ws); @@ -1738,6 +1739,20 @@ wobblyPreparePaintScreen (CompScreen *s, ws->wobblyWindows |= ww->wobbly; } + + if (w->windows) + { + w = w->windows; + continue; + } + + while (!w->next && (w != &s->root)) + w = w->parent; + + if (w == &s->root) + break; + + w = w->next; } } @@ -2000,12 +2015,27 @@ wobblyEnableSnapping (CompDisplay *d, for (s = d->screens; s; s = s->next) { - for (w = s->windows; w; w = w->next) + w = s->root.windows; + for (;;) { WOBBLY_WINDOW (w); if (ww->grabbed && ww->model) modelUpdateSnapping (w, ww->model); + + if (w->windows) + { + w = w->windows; + continue; + } + + while (!w->next && (w != &s->root)) + w = w->parent; + + if (w == &s->root) + break; + + w = w->next; } } @@ -2031,7 +2061,8 @@ wobblyDisableSnapping (CompDisplay *d, for (s = d->screens; s; s = s->next) { - for (w = s->windows; w; w = w->next) + w = s->root.windows; + for (;;) { WOBBLY_WINDOW (w); @@ -2047,6 +2078,20 @@ wobblyDisableSnapping (CompDisplay *d, damagePendingOnScreen (w->screen); } } + + if (w->windows) + { + w = w->windows; + continue; + } + + while (!w->next && (w != &s->root)) + w = w->parent; + + if (w == &s->root) + break; + + w = w->next; } } @@ -2678,7 +2723,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)); 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 de625f7..4423c47 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; } @@ -798,7 +798,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; @@ -915,7 +915,7 @@ setDisplayOption (CompPlugin *plugin, return FALSE; } -static void +void updatePlugins (CompDisplay *d) { CompOption *o; @@ -1420,7 +1420,7 @@ doPoll (int timeout) return rv; } -static void +void handleTimeouts (struct timeval *tv) { CompTimeout *t; @@ -1612,13 +1612,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; } } } @@ -1691,7 +1698,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; @@ -1815,24 +1822,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; } } @@ -1854,6 +1843,30 @@ 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; + + for (w = s->root.windows; w; w = w->next) + { + if (w->destroyed) + { + addWindowDamage (w); + removeWindow (w); + break; + } + } + + s->pendingDestroys--; + } + } + } } for (d = core.displays; d; d = d->next) @@ -1921,7 +1934,8 @@ compCheckForError (Display *dpy) static void addScreenActions (CompScreen *s) { - int i; + CompPlugin *p; + int i; for (i = 0; i < COMP_DISPLAY_OPTION_NUM; i++) { @@ -1931,6 +1945,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 @@ -1974,12 +2009,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) @@ -2253,6 +2286,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; @@ -2343,7 +2378,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")); @@ -2356,6 +2391,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); @@ -2374,7 +2452,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; @@ -2383,7 +2461,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) { @@ -2421,6 +2500,9 @@ addDisplay (const char *name) continue; } + + XSelectInput (dpy, currentCmSnOwner, + StructureNotifyMask); } attr.override_redirect = TRUE; @@ -2434,48 +2516,51 @@ addDisplay (const char *name) CWOverrideRedirect | CWEventMask, &attr); - XChangeProperty (dpy, - newWmSnOwner, - d->wmNameAtom, - d->utf8StringAtom, 8, - PropModeReplace, - (unsigned char *) PACKAGE, - strlen (PACKAGE)); + if (windowManagement) + { + XChangeProperty (dpy, + newWmSnOwner, + d->wmNameAtom, + d->utf8StringAtom, 8, + PropModeReplace, + (unsigned char *) PACKAGE, + strlen (PACKAGE)); - XWindowEvent (dpy, - newWmSnOwner, - PropertyChangeMask, - &event); + XWindowEvent (dpy, + newWmSnOwner, + PropertyChangeMask, + &event); - wmSnTimestamp = event.xproperty.time; + wmSnTimestamp = event.xproperty.time; - XSetSelectionOwner (dpy, wmSnAtom, newWmSnOwner, wmSnTimestamp); + XSetSelectionOwner (dpy, wmSnAtom, newWmSnOwner, wmSnTimestamp); - if (XGetSelectionOwner (dpy, wmSnAtom) != newWmSnOwner) - { - compLogMessage (d, "core", CompLogLevelError, - "Could not acquire window manager " - "selection on screen %d display \"%s\"", - i, DisplayString (dpy)); + if (XGetSelectionOwner (dpy, wmSnAtom) != newWmSnOwner) + { + compLogMessage (d, "core", CompLogLevelError, + "Could not acquire window manager " + "selection on screen %d display \"%s\"", + i, DisplayString (dpy)); - XDestroyWindow (dpy, newWmSnOwner); + 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; + 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 window manager to go away */ if (currentWmSnOwner != None) @@ -2486,18 +2571,35 @@ addDisplay (const char *name) } while (event.type != DestroyNotify); } - compCheckForError (dpy); + /* Wait for old compositing manager to go away */ + if (currentCmSnOwner != None && currentCmSnOwner != currentWmSnOwner) + { + do { + XWindowEvent (dpy, currentCmSnOwner, + StructureNotifyMask, &event); + } while (event.type != DestroyNotify); + } - XCompositeRedirectSubwindows (dpy, XRootWindow (dpy, i), - CompositeRedirectManual); + compCheckForError (dpy); - if (compCheckForError (dpy)) + if (manualCompositeManagement) { - compLogMessage (d, "core", CompLogLevelError, - "Another composite manager is already " - "running on screen: %d", i); + XCompositeRedirectSubwindows (dpy, XRootWindow (dpy, i), + CompositeRedirectManual); - continue; + if (compCheckForError (dpy)) + { + compLogMessage (d, "core", CompLogLevelError, + "Another composite manager is already " + "running on screen: %d", i); + + continue; + } + } + else + { + XCompositeRedirectSubwindows (dpy, XRootWindow (dpy, i), + CompositeRedirectAutomatic); } XSetSelectionOwner (dpy, cmSnAtom, newCmSnOwner, wmSnTimestamp); @@ -2514,28 +2616,39 @@ addDisplay (const char *name) 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 (d, "core", CompLogLevelError, - "Another window manager is " - "already running on screen: %d", i); + XSelectInput (dpy, XRootWindow (dpy, i), + SubstructureRedirectMask | + SubstructureNotifyMask | + StructureNotifyMask | + PropertyChangeMask | + LeaveWindowMask | + EnterWindowMask | + KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + FocusChangeMask | + ExposureMask); + + if (compCheckForError (dpy)) + { + compLogMessage (d, "core", CompLogLevelError, + "Another window manager is " + "already running on screen: %d", i); - XUngrabServer (dpy); - continue; + XUngrabServer (dpy); + continue; + } + } + else + { + XSelectInput (dpy, XRootWindow (dpy, i), + SubstructureNotifyMask | + StructureNotifyMask | + PropertyChangeMask | + ExposureMask); } if (!addScreen (d, i, newWmSnOwner, wmSnAtom, wmSnTimestamp)) @@ -2558,73 +2671,49 @@ addDisplay (const char *name) if (!d->screens) { compLogMessage (d, "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, - 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, + 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 @@ -2650,7 +2739,7 @@ findScreenAtDisplay (CompDisplay *d, for (s = d->screens; s; s = s->next) { - if (s->root == root) + if (s->root.id == root) return s; } @@ -2877,7 +2966,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 aaaed30..2e96171 100644 --- a/src/event.c +++ b/src/event.c @@ -63,10 +63,14 @@ handleWindowDamageRect (CompWindow *w, if (!(*w->screen->damageWindowRect) (w, initial, ®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; + CompWindow *p = w; + + do { + region.extents.x1 += p->attrib.x + p->attrib.border_width; + region.extents.y1 += p->attrib.y + p->attrib.border_width; + region.extents.x2 += p->attrib.x + p->attrib.border_width; + region.extents.y2 += p->attrib.y + p->attrib.border_width; + } while ((p = p->parent)); region.rects = ®ion.extents; region.numRects = region.size = 1; @@ -99,6 +103,9 @@ handleSyncAlarm (CompWindow *w) XRectangle *rects; int nDamage; + if (w->parent->substructureRedirect) + leaveSyncWaitState (w); + nDamage = w->nDamage; rects = w->damageRects; while (nDamage--) @@ -130,7 +137,7 @@ 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); if (ancestor && !(ancestor->type & (CompWindowTypeDesktopMask | @@ -146,7 +153,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 +284,7 @@ triggerButtonPressBindings (CompDisplay *d, if (event->xbutton.window != edgeWindow) { - if (!s->maxGrab || event->xbutton.window != s->root) + if (!s->maxGrab || event->xbutton.window != s->root.id) return FALSE; } @@ -1055,7 +1062,7 @@ handleActionEvent (CompDisplay *d, if (event->xclient.window == s->screenEdge[i].id) { edge = 1 << i; - root = s->root; + root = s->root.id; break; } } @@ -1106,7 +1113,7 @@ handleActionEvent (CompDisplay *d, if (xdndWindow == s->screenEdge[i].id) { edge = 1 << i; - root = s->root; + root = s->root.id; break; } } @@ -1298,32 +1305,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); } @@ -1332,11 +1336,8 @@ handleEvent (CompDisplay *d, w = findWindowAtDisplay (d, event->xmap.window); if (w) { - if (!w->attrib.override_redirect) - w->managed = TRUE; - /* been shaded */ - if (w->height == 0) + if (w->managed && w->height == 0) { if (w->id == d->activeWindow) moveInputFocusToWindow (w); @@ -1355,7 +1356,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) @@ -1383,12 +1384,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 @@ -1401,6 +1397,11 @@ handleEvent (CompDisplay *d, destroyWindow (w); } + + w = findWindowAtDisplay (d, event->xreparent.parent); + if (w) + addWindow (w, event->xreparent.window, getTopWindow (w)); + break; case CirculateNotify: w = findWindowAtDisplay (d, event->xcirculate.window); @@ -1642,10 +1643,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); @@ -1890,7 +1948,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]) @@ -1926,6 +1984,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); @@ -1984,7 +2053,7 @@ handleEvent (CompDisplay *d, xwcm = adjustConfigureRequestForGravity (w, &xwc, CWX | CWY, - gravity); + gravity, 1); if ((*w->screen->placeWindow) (w, xwc.x, xwc.y, &newX, &newY)) @@ -2016,6 +2085,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); } @@ -2118,14 +2196,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); @@ -2282,7 +2365,7 @@ handleEvent (CompDisplay *d, w = NULL; 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 19e9b6a..978f82c 100644 --- a/src/main.c +++ b/src/main.c @@ -67,6 +67,9 @@ Bool onlyCurrentScreen = FALSE; Bool useCow = TRUE; #endif +Bool windowManagement = FALSE; +Bool manualCompositeManagement = FALSE; + CompMetadata coreMetadata; static void @@ -434,6 +437,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/match.c b/src/match.c index 26b3eb8..8dc7728 100644 --- a/src/match.c +++ b/src/match.c @@ -760,7 +760,7 @@ matchExpHandlerChanged (CompDisplay *display) matchUpdateMatchOptions (option, nOption); } - for (w = s->windows; w; w = w->next) + for (w = s->root.windows; w; w = w->next) updateWindowOpacity (w); } } diff --git a/src/paint.c b/src/paint.c index a2051fa..a35b6a0 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> @@ -251,167 +252,49 @@ 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; - if (mask & PAINT_SCREEN_TRANSFORMED_MASK) - { - windowMask = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK; - count = 1; - } - else - { - windowMask = 0; - count = 0; - } + assert (r); - XSubtractRegion (region, &emptyRegion, tmpRegion); + (*screen->initObjectPainter) (screen, &painter); - (*screen->initWindowWalker) (screen, &walk); + if (mask & PAINT_SCREEN_TRANSFORMED_MASK) + windowMask = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK; + + 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; - } - - /* copy region */ - XSubtractRegion (tmpRegion, &emptyRegion, w->clip); - - 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++; - } + if ((*painter.paintObject) (&screen->root, + &screen->root.paint, + transform, + r, + PAINT_WINDOW_OCCLUSION_DETECTION_MASK)) + XSubtractRegion (r, screen->root.region, r); + + 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; - } - - if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) - clip = w->clip; - - if ((screen->windowOffsetX != 0 || screen->windowOffsetY != 0) && - !windowOnAllViewports (w)) - { - getWindowMovementForOffset (w, screen->windowOffsetX, - screen->windowOffsetY, &offX, &offY); + paintBackground (screen, r, (mask & PAINT_SCREEN_TRANSFORMED_MASK)); - 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); - } - } + (*painter.paintObject) (&screen->root, + &screen->root.paint, + transform, + r, + 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 @@ -1194,7 +1077,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; @@ -1218,6 +1107,9 @@ paintWindow (CompWindow *w, unsigned int mask) { FragmentAttrib fragment; + CompWindow *c; + CompWalker walk; + CompPainter painter; Bool status; w->lastPaint = *attrib; @@ -1241,6 +1133,117 @@ paintWindow (CompWindow *w, if (w->shaded) return 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; + int viewportOffsetX = 0; + int viewportOffsetY = 0; + int offsetMask = 0; + + if (c->destroyed) + continue; + + if (!windowOnAllViewports (c)) + { + if (w->viewportOffsetX || w->viewportOffsetY) + { + getWindowMovementForOffset (w, + w->viewportOffsetX, + w->viewportOffsetY, + &viewportOffsetX, + &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, + &c->paint, + &cTransform, + r, + mask | offsetMask)) + 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); + + XDestroyRegion (r); + } + + if (painter.fini) + (*painter.fini) (w->screen, &painter); + if (walk.fini) + (*walk.fini) (w->screen, &walk); + + if (w->attrib.map_state != IsViewable) + return FALSE; + + if (!w->redirected || !w->damaged || w->shaded) + return FALSE; + return TRUE; } @@ -1249,8 +1252,7 @@ paintWindow (CompWindow *w, initFragmentAttrib (&fragment, attrib); - if (mask & PAINT_WINDOW_TRANSFORMED_MASK || - mask & PAINT_WINDOW_WITH_OFFSET_MASK) + if (mask & (PAINT_WINDOW_TRANSFORMED_MASK | PAINT_WINDOW_WITH_OFFSET_MASK)) { glPushMatrix (); glLoadMatrixf (transform->m); @@ -1258,9 +1260,93 @@ paintWindow (CompWindow *w, status = (*w->screen->drawWindow) (w, transform, &fragment, region, mask); - if (mask & PAINT_WINDOW_TRANSFORMED_MASK || - mask & PAINT_WINDOW_WITH_OFFSET_MASK) + if (mask & (PAINT_WINDOW_TRANSFORMED_MASK | PAINT_WINDOW_WITH_OFFSET_MASK)) glPopMatrix (); + (*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; + + 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 (clip) + XOffsetRegion (clip, -w->attrib.x, -w->attrib.y); + } + + /* paint all sub-windows from bottom to top */ + for (; c; c = (*walk.next) (c)) + { + CompTransform cTransform = wTransform; + int viewportOffsetX = 0; + int viewportOffsetY = 0; + int offsetMask = 0; + + if (c->destroyed) + continue; + + if (mask & PAINT_WINDOW_CLIP_MASK) + clip = c->clip; + + if (!windowOnAllViewports (c)) + { + if (w->viewportOffsetX || w->viewportOffsetY) + { + getWindowMovementForOffset (w, + w->viewportOffsetX, + w->viewportOffsetY, + &viewportOffsetX, + &viewportOffsetY); + + matrixTranslate (&cTransform, + viewportOffsetX, + viewportOffsetY, + 0); + + if (clip != c->clip) + XOffsetRegion (clip, + -viewportOffsetX, + -viewportOffsetY); + + offsetMask = PAINT_WINDOW_WITH_OFFSET_MASK; + } + } + + (*painter.paintObject) (c, + &c->paint, + &cTransform, + clip, + mask | offsetMask); + + if (clip != c->clip && (viewportOffsetX || viewportOffsetY)) + XOffsetRegion (clip, + viewportOffsetX, + viewportOffsetY); + } + + 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; } diff --git a/src/screen.c b/src/screen.c index bfb7b8f..11cf32b 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) @@ -612,7 +618,7 @@ setScreenOption (CompPlugin *plugin, for (i = 0; i < o->value.list.nValue; i++) matchUpdate (screen->display, &o->value.list.value[i].match); - for (w = screen->windows; w; w = w->next) + for (w = screen->root.windows; w; w = w->next) updateWindowOpacity (w); return TRUE; @@ -623,7 +629,7 @@ setScreenOption (CompPlugin *plugin, { CompWindow *w; - for (w = screen->windows; w; w = w->next) + for (w = screen->root.windows; w; w = w->next) updateWindowOpacity (w); return TRUE; @@ -673,9 +679,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 @@ -882,11 +888,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; @@ -1000,7 +1007,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, @@ -1083,7 +1090,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); @@ -1110,6 +1117,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); @@ -1127,7 +1136,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); } @@ -1228,11 +1237,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; @@ -1242,7 +1306,7 @@ getDesktopHints (CompScreen *s) unsigned long n, left; unsigned char *propData; - 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); @@ -1256,7 +1320,7 @@ getDesktopHints (CompScreen *s) s->nDesktop = data[0]; } - 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); @@ -1277,7 +1341,7 @@ getDesktopHints (CompScreen *s) XFree (propData); } - 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); @@ -1291,7 +1355,7 @@ getDesktopHints (CompScreen *s) s->currentDesktop = data[0]; } - 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); @@ -1305,17 +1369,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 @@ -1323,7 +1390,7 @@ showOutputWindow (CompScreen *s) { #ifdef USE_COW - if (useCow) + if (useCow && manualCompositeManagement) { Display *dpy = s->display->display; XserverRegion region; @@ -1352,7 +1419,7 @@ hideOutputWindow (CompScreen *s) { #ifdef USE_COW - if (useCow) + if (useCow && manualCompositeManagement) { Display *dpy = s->display->display; XserverRegion region; @@ -1375,7 +1442,7 @@ updateOutputWindow (CompScreen *s) { #ifdef USE_COW - if (useCow) + if (useCow && manualCompositeManagement) { Display *dpy = s->display->display; XserverRegion region; @@ -1391,7 +1458,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); @@ -1419,9 +1486,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); @@ -1429,7 +1497,7 @@ makeOutputWindow (CompScreen *s) else #endif - s->output = s->overlay = s->root; + s->output = s->overlay = s->root.id; showOutputWindow (s); } @@ -1443,10 +1511,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)) @@ -1469,7 +1540,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); @@ -1482,6 +1553,9 @@ leaveShowDesktopMode (CompScreen *s, CompWindow *w; unsigned long data = 0; + if (!s->root.substructureRedirect) + return; + if (window) { if (!window->inShowDesktopMode) @@ -1491,7 +1565,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; @@ -1501,7 +1575,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; @@ -1515,22 +1589,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 * @@ -1547,6 +1621,7 @@ walkPrev (CompWindow *w) static void initWindowWalker (CompScreen *screen, + CompWindow *window, CompWalker *walker) { walker->fini = NULL; @@ -1556,6 +1631,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) { @@ -1668,9 +1779,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; @@ -1696,7 +1804,8 @@ addScreen (CompDisplay *display, s->screenNum = screenNum; s->colormap = DefaultColormap (dpy, screenNum); - s->root = XRootWindow (dpy, screenNum); + + initRootWindow (s, &s->root); s->mapNum = 1; s->activeNum = 1; @@ -1728,9 +1837,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; @@ -1797,11 +1903,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; @@ -1835,7 +1942,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 (display, "core", CompLogLevelFatal, @@ -1857,384 +1964,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 (display, "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 = manualCompositeManagement)) { - compLogMessage (display, "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 (display, "core", CompLogLevelFatal, + "Root visual is not a GL visual"); + XFree (visinfo); + return FALSE; + } - s->ctx = glXCreateContext (dpy, visinfo, NULL, !indirectRendering); - if (!s->ctx) - { - compLogMessage (display, "core", CompLogLevelFatal, - "glXCreateContext failed"); - XFree (visinfo); + glXGetConfig (dpy, visinfo, GLX_DOUBLEBUFFER, &value); + if (!value) + { + compLogMessage (display, "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 (display, "core", CompLogLevelFatal, + "glXCreateContext failed"); + XFree (visinfo); - glxExtensions = glXQueryExtensionsString (dpy, screenNum); - if (!strstr (glxExtensions, "GLX_EXT_texture_from_pixmap")) - { - compLogMessage (display, "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 (display, "core", CompLogLevelFatal, + "GLX_EXT_texture_from_pixmap is missing"); + XFree (visinfo); - XFree (visinfo); + return FALSE; + } - if (!strstr (glxExtensions, "GLX_SGIX_fbconfig")) - { - compLogMessage (display, "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 (display, "core", CompLogLevelFatal, - "glXBindTexImageEXT is missing"); - return FALSE; - } + if (!strstr (glxExtensions, "GLX_SGIX_fbconfig")) + { + compLogMessage (display, "core", CompLogLevelFatal, + "GLX_SGIX_fbconfig is missing"); + return FALSE; + } - if (!s->releaseTexImage) - { - compLogMessage (display, "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 (display, "core", CompLogLevelFatal, + "glXBindTexImageEXT is missing"); + return FALSE; + } - if (!s->queryDrawable || - !s->getFBConfigs || - !s->getFBConfigAttrib || - !s->createPixmap) - { - compLogMessage (display, "core", CompLogLevelFatal, - "fbconfig functions missing"); - return FALSE; - } + if (!s->releaseTexImage) + { + compLogMessage (display, "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 (display, "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 (display, "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 (display, "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 (display, "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 (display, "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; - if (value) + value = 0; + if (i == 32) { - rgba = 1; + (*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 (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 (display, "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 (display, "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); @@ -2244,23 +2390,6 @@ addScreen (CompDisplay *display, 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; @@ -2270,17 +2399,6 @@ addScreen (CompDisplay *display, 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; @@ -2288,34 +2406,10 @@ addScreen (CompDisplay *display, 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); @@ -2325,9 +2419,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, @@ -2344,19 +2442,52 @@ addScreen (CompDisplay *display, updateScreenEdges (s); - setDesktopHints (s); - setSupportingWmCheck (s); - setSupported (s); - s->normalCursor = XCreateFontCursor (dpy, XC_left_ptr); s->busyCursor = XCreateFontCursor (dpy, XC_watch); - XDefineCursor (dpy, s->root, s->normalCursor); + if ((s->root.substructureRedirect = windowManagement)) + { + 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); + + 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; } @@ -2376,14 +2507,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); @@ -2398,13 +2529,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); @@ -2442,7 +2574,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); } @@ -2453,6 +2585,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); @@ -2466,7 +2601,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; @@ -2496,7 +2631,7 @@ focusDefaultWindow (CompScreen *s) } else { - XSetInputFocus (d->display, s->root, RevertToPointerRoot, + XSetInputFocus (d->display, s->root.id, RevertToPointerRoot, CurrentTime); } } @@ -2511,14 +2646,30 @@ findWindowAtScreen (CompScreen *s, } else { - CompWindow *w; + CompWindow *w = &s->root; - for (w = s->windows; w; w = w->next) + for (;;) + { if (w->id == id) return (lastFoundWindow = w); + + if (w->windows) + { + w = w->windows; + continue; + } + + while (!w->next && (w != &s->root)) + w = w->parent; + + if (w == &s->root) + break; + + w = w->next; + } } - return 0; + return NULL; } CompWindow * @@ -2533,120 +2684,19 @@ 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; - } - - 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; + /* likely a frame window */ + for (w = w->parent->windows; w; w = w->next) + if (w->frame == id) + break; } -} -void -unhookWindowFromScreen (CompScreen *s, - CompWindow *w) -{ - CompWindow *next, *prev; - - next = w->next; - prev = w->prev; + if (w && w->managed) + return w; - if (next || prev) - { - if (next) - { - if (prev) - { - next->prev = prev; - } - else - { - s->windows = next; - next->prev = NULL; - } - } - - 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 | \ @@ -2664,7 +2714,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) @@ -2816,7 +2866,7 @@ grabUngrabOneKey (CompScreen *s, XGrabKey (s->display->display, keycode, modifiers, - s->root, + s->root.id, TRUE, GrabModeAsync, GrabModeAsync); @@ -2826,7 +2876,7 @@ grabUngrabOneKey (CompScreen *s, XUngrabKey (s->display->display, keycode, modifiers, - s->root); + s->root.id); } } @@ -2956,7 +3006,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++) { @@ -3112,7 +3162,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; @@ -3216,7 +3266,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); } } @@ -3283,6 +3333,9 @@ updateClientListForScreen (CompScreen *s) Bool updateClientListStacking = FALSE; int i, n = 0; + if (!s->root.substructureRedirect) + return; + forEachWindowOnScreen (s, countClientListWindow, (void *) &n); if (n == 0) @@ -3294,11 +3347,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); @@ -3354,13 +3407,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); @@ -3414,7 +3467,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 @@ -3485,7 +3539,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; @@ -3556,7 +3610,7 @@ moveWindowToViewportPosition (CompWindow *w, { int m, wx, wy; - if (!w->managed) + if (w->attrib.override_redirect) return; if (w->type & (CompWindowTypeDesktopMask | CompWindowTypeDockMask)) @@ -3727,7 +3781,7 @@ sendWindowActivationRequest (CompScreen *s, xev.xclient.data.l[4] = 0; XSendEvent (s->display->display, - s->root, + s->root.id, FALSE, SubstructureRedirectMask | SubstructureNotifyMask, &xev); @@ -3788,12 +3842,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; @@ -3805,24 +3859,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; + } } } @@ -3869,7 +3929,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; @@ -3890,6 +3950,9 @@ setCurrentDesktop (CompScreen *s, unsigned long data; CompWindow *w; + if (!s->root.substructureRedirect) + return; + if (desktop >= s->nDesktop) return; @@ -3898,7 +3961,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; @@ -3911,7 +3974,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); @@ -4267,6 +4330,6 @@ setWindowPaintOffset (CompScreen *s, int x, int y) { - s->windowOffsetX = x; - s->windowOffsetY = y; + s->root.viewportOffsetX = x; + s->root.viewportOffsetY = y; } diff --git a/src/window.c b/src/window.c index c5b5fbe..27aaf6f 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; @@ -1187,7 +1197,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, @@ -1287,14 +1297,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); + } } } @@ -1452,9 +1465,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; @@ -1467,10 +1477,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, ®); } @@ -1541,10 +1558,14 @@ addWindowDamageRect (CompWindow *w, if (!(*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; + CompWindow *p = w; + + do { + region.extents.x1 += p->attrib.x + p->attrib.border_width; + region.extents.y1 += p->attrib.y + p->attrib.border_width; + region.extents.x2 += p->attrib.x + p->attrib.border_width; + region.extents.y2 += p->attrib.y + p->attrib.border_width; + } while ((p = p->parent)); region.rects = ®ion.extents; region.numRects = region.size = 1; @@ -1888,21 +1909,118 @@ 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->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); +} + +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; @@ -1941,9 +2059,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; @@ -2000,6 +2127,8 @@ addWindow (CompScreen *screen, w->syncCounter = 0; w->syncWaitHandle = 0; + XSyncIntToValue (&w->syncValue, 0); + w->closeRequests = 0; w->lastCloseRequestTime = 0; @@ -2067,10 +2196,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; @@ -2087,10 +2229,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); @@ -2108,8 +2250,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); @@ -2180,28 +2323,32 @@ addWindow (CompScreen *screen, if (!w->attrib.override_redirect) { - w->managed = TRUE; - - if (getWmState (d, w->id) == IconicState) + if (w->parent->substructureRedirect) { - if (w->state & CompWindowStateShadedMask) - w->shaded = TRUE; - else - w->minimized = TRUE; - } - else - { - 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); + } } } } @@ -2244,7 +2391,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); updateWindowOpacity (w); @@ -2259,7 +2406,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) { @@ -2281,7 +2431,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); @@ -2301,7 +2451,7 @@ removeWindow (CompWindow *w) if (w->destroyed) updateClientListForScreen (w->screen); - if (!w->redirected) + if (w->parent->redirectSubwindows && !w->redirected) { w->screen->overlayWindowCount--; @@ -2309,7 +2459,7 @@ removeWindow (CompWindow *w) showOutputWindow (w->screen); } - (*core.objectRemove) (&w->screen->base, &w->base); + (*core.objectRemove) (&w->parent->base, &w->base); objectFiniPlugins (&w->base); @@ -2389,9 +2539,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; + } + w->pendingMaps--; w->mapNum = w->screen->mapNum++; @@ -2406,7 +2564,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; @@ -2427,13 +2585,20 @@ mapWindow (CompWindow *w) if (w->type & CompWindowTypeDesktopMask) w->screen->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) @@ -2442,35 +2607,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--; - addWindowDamage (w); + if (w->attrib.map_state == IsViewable) + addWindowDamage (w); - w->attrib.map_state = IsUnmapped; + w->attrib.map_state = state; w->invisible = TRUE; @@ -2486,6 +2647,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->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 @@ -2500,8 +2686,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); @@ -2579,7 +2765,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) { @@ -2618,6 +2805,9 @@ initializeSyncCounter (CompWindow *w) unsigned long n, left; unsigned char *data; + if (!w->parent->substructureRedirect) + return FALSE; + if (w->syncCounter) return w->syncAlarm != None; @@ -2637,7 +2827,6 @@ initializeSyncCounter (CompWindow *w) XFree (data); - XSyncIntsToValue (&w->syncValue, (unsigned int) rand (), 0); XSyncSetCounter (w->screen->display->display, w->syncCounter, w->syncValue); @@ -2693,6 +2882,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, syncWaitTimeout, w); +} + +void sendSyncRequest (CompWindow *w) { XClientMessageEvent xev; @@ -2701,7 +2904,10 @@ sendSyncRequest (CompWindow *w) return; if (!initializeSyncCounter (w)) + { + leaveSyncWaitState (w); return; + } xev.type = ClientMessage; xev.window = w->id; @@ -2715,23 +2921,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, 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; @@ -2742,15 +2951,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); } @@ -2759,6 +2959,9 @@ configureWindow (CompWindow *w, if (restackWindow (w, ce->above)) addWindowDamage (w); + + if (!w->parent) + configureScreen (w->screen, ce); } void @@ -2768,7 +2971,7 @@ circulateWindow (CompWindow *w, Window newAboveId; if (ce->place == PlaceOnTop) - newAboveId = getTopWindow (w->screen); + newAboveId = getTopWindow (w->parent); else newAboveId = 0; @@ -2804,29 +3007,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; @@ -2905,7 +3091,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)) @@ -2925,7 +3112,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; @@ -2935,7 +3122,7 @@ getModalTransient (CompWindow *window) if (w->state & CompWindowStateModalMask) { modalTransient = w; - w = window->screen->reverseWindows; + w = window->parent->reverseWindows; } } } @@ -2947,7 +3134,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; @@ -2983,14 +3170,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); } @@ -3030,7 +3221,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)) { @@ -3114,7 +3307,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; @@ -3160,7 +3353,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; @@ -3172,7 +3365,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; @@ -3369,11 +3562,40 @@ reconfigureXWindow (CompWindow *w, if (valueMask & CWBorderWidth) w->serverBorderWidth = xwc->border_width; + if (!w->parent->substructureRedirect) + valueMask |= + adjustConfigureRequestForGravity (w, + xwc, valueMask, + w->sizeHints.win_gravity, + -1); + 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 @@ -3387,7 +3609,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; @@ -3445,7 +3667,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 && @@ -3712,7 +3934,8 @@ unsigned int adjustConfigureRequestForGravity (CompWindow *w, XWindowChanges *xwc, unsigned int xwcm, - int gravity) + int gravity, + int direction) { int newX, newY; unsigned int mask = 0; @@ -3727,23 +3950,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: @@ -3759,23 +3982,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: @@ -3840,7 +4063,7 @@ moveResizeWindow (CompWindow *w, } } - xwcm |= adjustConfigureRequestForGravity (w, xwc, xwcm, gravity); + xwcm |= adjustConfigureRequestForGravity (w, xwc, xwcm, gravity, 1); if (!(w->type & (CompWindowTypeDockMask | CompWindowTypeFullscreenMask | @@ -4010,7 +4233,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; @@ -4075,7 +4298,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 */ @@ -4124,7 +4347,7 @@ updateWindowAttributes (CompWindow *w, XWindowChanges xwc; int mask = 0; - if (w->attrib.override_redirect || !w->managed) + if (!w->managed) return; if (w->state & CompWindowStateShadedMask) @@ -4202,7 +4425,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 | @@ -4261,6 +4484,30 @@ revealAncestors (CompWindow *w, void activateWindow (CompWindow *w) { + if (!w->parent->substructureRedirect) + { + XEvent xev; + + 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; + + XSendEvent (w->screen->display->display, w->parent->id, FALSE, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); + + return; + } + setCurrentDesktop (w->screen, w->desktop); forEachWindowOnScreen (w->screen, revealAncestors, (void *) w); @@ -4635,7 +4882,7 @@ void maximizeWindow (CompWindow *w, int state) { - if (w->attrib.override_redirect) + if (!w->managed) return; state = constrainWindowState (state, w->actions); @@ -4866,7 +5113,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, @@ -5185,3 +5432,127 @@ 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; +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor