diff --git a/ChangeLog b/ChangeLog index fa73dcbf5..5a451839b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2003-11-20 Havoc Pennington + + * src/window.c (meta_window_new_with_attrs): new function + + * src/display.c, src/screen.c: create the compositor and feed + windows and events to it + 2003-11-20 Havoc Pennington * src/window.c (meta_window_notify_focus): revert the change here diff --git a/configure.in b/configure.in index af00938fc..3540be466 100644 --- a/configure.in +++ b/configure.in @@ -197,8 +197,8 @@ fi if test x$have_xcomposite = xyes; then echo "Building with CompositeExt" - METACITY_PC_MODULES="$METACITY_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender" - AC_DEFINE(HAVE_XCOMPOSITEENSIONS, , [Building with compositing manager support]) + METACITY_PC_MODULES="$METACITY_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender xdamage" + AC_DEFINE(HAVE_COMPOSITE_EXTENSIONS, , [Building with compositing manager support]) else echo "Building without compositing manager" fi diff --git a/src/compositor.c b/src/compositor.c index fe5efa964..e9aef849f 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -180,10 +180,45 @@ meta_compositor_add_window (MetaCompositor *compositor, XWindowAttributes *attrs) { #ifdef HAVE_COMPOSITE_EXTENSIONS + g_print ("compositor adding window 0x%lx\n", xwindow); + if (!compositor->enabled) return; /* no extension */ +#endif /* HAVE_COMPOSITE_EXTENSIONS */ +} + +void +meta_compositor_remove_window (MetaCompositor *compositor, + Window xwindow) +{ +#ifdef HAVE_COMPOSITE_EXTENSIONS + g_print ("compositor removing window 0x%lx\n", xwindow); + if (!compositor->enabled) + return; /* no extension */ + +#endif /* HAVE_COMPOSITE_EXTENSIONS */ +} + +void +meta_compositor_manage_screen (MetaCompositor *compositor, + MetaScreen *screen) +{ +#ifdef HAVE_COMPOSITE_EXTENSIONS + if (!compositor->enabled) + return; /* no extension */ + +#endif /* HAVE_COMPOSITE_EXTENSIONS */ +} + +void +meta_compositor_unmanage_screen (MetaCompositor *compositor, + MetaScreen *screen) +{ +#ifdef HAVE_COMPOSITE_EXTENSIONS + if (!compositor->enabled) + return; /* no extension */ #endif /* HAVE_COMPOSITE_EXTENSIONS */ } @@ -191,9 +226,3 @@ meta_compositor_add_window (MetaCompositor *compositor, - - - - - - diff --git a/src/compositor.h b/src/compositor.h index 0b98d32ff..48be7b11c 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -25,8 +25,6 @@ #include "util.h" #include "display.h" -typedef struct MetaCompositor MetaCompositor; - MetaCompositor* meta_compositor_new (MetaDisplay *display); void meta_compositor_unref (MetaCompositor *compositor); void meta_compositor_process_event (MetaCompositor *compositor, @@ -35,6 +33,13 @@ void meta_compositor_process_event (MetaCompositor *compositor, void meta_compositor_add_window (MetaCompositor *compositor, Window xwindow, XWindowAttributes *attrs); +void meta_compositor_remove_window (MetaCompositor *compositor, + Window xwindow); + +void meta_compositor_manage_screen (MetaCompositor *compositor, + MetaScreen *screen); +void meta_compositor_unmanage_screen (MetaCompositor *compositor, + MetaScreen *screen); #endif /* META_COMPOSITOR_H */ diff --git a/src/display.c b/src/display.c index 3a032d783..aa36bfe6d 100644 --- a/src/display.c +++ b/src/display.c @@ -36,6 +36,7 @@ #include "workspace.h" #include "bell.h" #include "effects.h" +#include "compositor.h" #include #include #ifdef HAVE_SOLARIS_XINERAMA @@ -530,6 +531,8 @@ meta_display_open (const char *name) #else /* HAVE_SHAPE */ meta_verbose ("Not compiled with Shape support\n"); #endif /* !HAVE_SHAPE */ + + display->compositor = meta_compositor_new (display); screens = NULL; @@ -750,6 +753,8 @@ meta_display_close (MetaDisplay *display) all_displays = g_slist_remove (all_displays, display); meta_display_shutdown_keys (display); + + meta_compositor_unref (display->compositor); g_free (display); @@ -1652,6 +1657,9 @@ event_callback (XEvent *event, } break; case UnmapNotify: + meta_compositor_remove_window (display->compositor, + modified); + if (window) { if (display->grab_op != META_GRAB_OP_NONE && @@ -1687,6 +1695,29 @@ event_callback (XEvent *event, } break; case MapNotify: + { + /* If a window becomes viewable, then we need to + * add it to the compositor + */ + XWindowAttributes attrs; + + meta_error_trap_push_with_return (display); + + XGetWindowAttributes (display->xdisplay, + modified, &attrs); + + if (meta_error_trap_pop_with_return (display, TRUE) != Success) + { + meta_verbose ("Failed to get attributes for window 0x%lx\n", + modified); + } + else + { + if (attrs.map_state == IsViewable) + meta_compositor_add_window (display->compositor, + modified, &attrs); + } + } break; case MapRequest: if (window == NULL) diff --git a/src/display.h b/src/display.h index a09d37c8b..97cc901c3 100644 --- a/src/display.h +++ b/src/display.h @@ -53,6 +53,7 @@ struct _MetaRectangle int height; }; +typedef struct MetaCompositor MetaCompositor; typedef struct _MetaDisplay MetaDisplay; typedef struct _MetaFrame MetaFrame; typedef struct _MetaKeyBinding MetaKeyBinding; @@ -293,6 +294,9 @@ struct _MetaDisplay /* Managed by group-props.c */ MetaGroupPropHooks *group_prop_hooks; + + /* Managed by compositor.c */ + MetaCompositor *compositor; #ifdef HAVE_STARTUP_NOTIFICATION SnDisplay *sn_display; diff --git a/src/screen.c b/src/screen.c index fdc31736c..d8d5defd4 100644 --- a/src/screen.c +++ b/src/screen.c @@ -34,6 +34,7 @@ #include "keybindings.h" #include "stack.h" #include "xprops.h" +#include "compositor.h" #ifdef HAVE_SOLARIS_XINERAMA #include @@ -654,9 +655,12 @@ meta_screen_new (MetaDisplay *display, if (space != NULL) meta_workspace_activate (space); } + + meta_compositor_manage_screen (screen->display->compositor, + screen); meta_verbose ("Added screen %d ('%s') root 0x%lx\n", - screen->number, screen->screen_name, screen->xroot); + screen->number, screen->screen_name, screen->xroot); return screen; } @@ -672,6 +676,9 @@ meta_screen_free (MetaScreen *screen) meta_display_grab (display); + meta_compositor_unmanage_screen (screen->display->compositor, + screen); + meta_display_unmanage_windows_for_screen (display, screen); meta_prefs_remove_listener (prefs_changed_callback, screen); @@ -749,7 +756,27 @@ meta_screen_manage_all_windows (MetaScreen *screen) i = 0; while (i < n_children) { - meta_window_new (screen->display, children[i], TRUE); + XWindowAttributes attrs; + + meta_error_trap_push_with_return (screen->display); + + XGetWindowAttributes (screen->display->xdisplay, + children[i], &attrs); + + if (meta_error_trap_pop_with_return (screen->display, TRUE) != Success) + { + meta_verbose ("Failed to get attributes for window 0x%lx\n", + children[i]); + } + else + { + meta_window_new_with_attrs (screen->display, children[i], TRUE, + &attrs); + + if (attrs.map_state == IsViewable) + meta_compositor_add_window (screen->display->compositor, + children[i], &attrs); + } ++i; } diff --git a/src/window.c b/src/window.c index 3d655e1f7..9c97134fa 100644 --- a/src/window.c +++ b/src/window.c @@ -172,8 +172,44 @@ meta_window_new (MetaDisplay *display, Window xwindow, gboolean must_be_viewable) { - MetaWindow *window; XWindowAttributes attrs; + MetaWindow *window; + + meta_display_grab (display); + meta_error_trap_push (display); /* Push a trap over all of window + * creation, to reduce XSync() calls + */ + + meta_error_trap_push_with_return (display); + + XGetWindowAttributes (display->xdisplay, + xwindow, &attrs); + + if (meta_error_trap_pop_with_return (display, TRUE) != Success) + { + meta_verbose ("Failed to get attributes for window 0x%lx\n", + xwindow); + meta_error_trap_pop (display, TRUE); + meta_display_ungrab (display); + return NULL; + } + window = meta_window_new_with_attrs (display, xwindow, + must_be_viewable, &attrs); + + + meta_error_trap_pop (display, FALSE); + meta_display_ungrab (display); + + return window; +} + +MetaWindow* +meta_window_new_with_attrs (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + XWindowAttributes *attrs) +{ + MetaWindow *window; GSList *tmp; MetaWorkspace *space; gulong existing_wm_state; @@ -182,7 +218,8 @@ meta_window_new (MetaDisplay *display, Atom initial_props[N_INITIAL_PROPS]; int i; gboolean has_shape; - + + g_assert (attrs != NULL); g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props)); meta_verbose ("Attempting to manage 0x%lx\n", xwindow); @@ -193,48 +230,32 @@ meta_window_new (MetaDisplay *display, xwindow); return NULL; } + + if (attrs->override_redirect) + { + meta_verbose ("Deciding not to manage override_redirect window 0x%lx\n", xwindow); + return NULL; + } /* Grab server */ meta_display_grab (display); meta_error_trap_push (display); /* Push a trap over all of window * creation, to reduce XSync() calls */ - - meta_error_trap_push_with_return (display); - - XGetWindowAttributes (display->xdisplay, - xwindow, &attrs); - if (meta_error_trap_pop_with_return (display, TRUE) != Success) - { - meta_verbose ("Failed to get attributes for window 0x%lx\n", - xwindow); - meta_error_trap_pop (display, TRUE); - meta_display_ungrab (display); - return NULL; - } - - if (attrs.override_redirect) - { - meta_verbose ("Deciding not to manage override_redirect window 0x%lx\n", xwindow); - meta_error_trap_pop (display, TRUE); - meta_display_ungrab (display); - return NULL; - } - - meta_verbose ("must_be_viewable = %d attrs.map_state = %d (%s)\n", + meta_verbose ("must_be_viewable = %d attrs->map_state = %d (%s)\n", must_be_viewable, - attrs.map_state, - (attrs.map_state == IsUnmapped) ? + attrs->map_state, + (attrs->map_state == IsUnmapped) ? "IsUnmapped" : - (attrs.map_state == IsViewable) ? + (attrs->map_state == IsViewable) ? "IsViewable" : - (attrs.map_state == IsUnviewable) ? + (attrs->map_state == IsUnviewable) ? "IsUnviewable" : "(unknown)"); existing_wm_state = WithdrawnState; - if (must_be_viewable && attrs.map_state != IsViewable) + if (must_be_viewable && attrs->map_state != IsViewable) { /* Only manage if WM_STATE is IconicState or NormalState */ gulong state; @@ -293,11 +314,11 @@ meta_window_new (MetaDisplay *display, #endif /* Get rid of any borders */ - if (attrs.border_width != 0) + if (attrs->border_width != 0) XSetWindowBorderWidth (display->xdisplay, xwindow, 0); /* Get rid of weird gravities */ - if (attrs.win_gravity != NorthWestGravity) + if (attrs->win_gravity != NorthWestGravity) { XSetWindowAttributes set_attrs; @@ -318,7 +339,7 @@ meta_window_new (MetaDisplay *display, return NULL; } - g_assert (!attrs.override_redirect); + g_assert (!attrs->override_redirect); window = g_new (MetaWindow, 1); @@ -343,7 +364,7 @@ meta_window_new (MetaDisplay *display, { MetaScreen *scr = tmp->data; - if (scr->xroot == attrs.root) + if (scr->xroot == attrs->root) { window->screen = tmp->data; break; @@ -367,17 +388,17 @@ meta_window_new (MetaDisplay *display, window->has_shape = has_shape; /* Remember this rect is the actual window size */ - window->rect.x = attrs.x; - window->rect.y = attrs.y; - window->rect.width = attrs.width; - window->rect.height = attrs.height; + window->rect.x = attrs->x; + window->rect.y = attrs->y; + window->rect.width = attrs->width; + window->rect.height = attrs->height; /* And border width, size_hints are the "request" */ - window->border_width = attrs.border_width; - window->size_hints.x = attrs.x; - window->size_hints.y = attrs.y; - window->size_hints.width = attrs.width; - window->size_hints.height = attrs.height; + window->border_width = attrs->border_width; + window->size_hints.x = attrs->x; + window->size_hints.y = attrs->y; + window->size_hints.width = attrs->width; + window->size_hints.height = attrs->height; /* initialize the remaining size_hints as if size_hints.flags were zero */ meta_set_normal_hints (window, NULL); @@ -385,9 +406,9 @@ meta_window_new (MetaDisplay *display, window->saved_rect = window->rect; window->user_rect = window->rect; - window->depth = attrs.depth; - window->xvisual = attrs.visual; - window->colormap = attrs.colormap; + window->depth = attrs->depth; + window->xvisual = attrs->visual; + window->colormap = attrs->colormap; window->title = NULL; window->icon_name = NULL; @@ -410,7 +431,7 @@ meta_window_new (MetaDisplay *display, window->initially_iconic = FALSE; window->minimized = FALSE; window->iconic = FALSE; - window->mapped = attrs.map_state != IsUnmapped; + window->mapped = attrs->map_state != IsUnmapped; /* if already mapped we don't want to do the placement thing */ window->placed = window->mapped; if (window->placed) @@ -688,7 +709,7 @@ meta_window_new (MetaDisplay *display, return window; } -/* This function should only be called from the end of meta_window_new () */ +/* This function should only be called from the end of meta_window_new_with_attrs () */ static void meta_window_apply_session_info (MetaWindow *window, const MetaWindowSessionInfo *info) diff --git a/src/window.h b/src/window.h index 8c515ab59..5523af13a 100644 --- a/src/window.h +++ b/src/window.h @@ -311,6 +311,10 @@ struct _MetaWindow MetaWindow* meta_window_new (MetaDisplay *display, Window xwindow, gboolean must_be_viewable); +MetaWindow* meta_window_new_with_attrs (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + XWindowAttributes *attrs); void meta_window_free (MetaWindow *window); void meta_window_calc_showing (MetaWindow *window); void meta_window_queue_calc_showing (MetaWindow *window);