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