diff --git a/ChangeLog b/ChangeLog index b43cc2595..ead767e8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Thu Feb 16 15:24:42 2006 Søren Sandmann + + * src/screen.c (meta_screen_composite_all_windows): New function. + + * src/prefs.[ch], src/metacity.schemas.in: Add new + compositing_manager key. + + * src/display.c (prefs_changed_callback): Handle + META_PREF_COMPOSITOR_MANAGER + + * src/display.c (event_callback): Only call + meta_compositor_process_event() if there is in fact a compositor. + + * src/display.c (enable/disable_compositor): Add code to + enable/disable compositor at runtime + Wed Feb 15 18:42:03 2006 Søren Sandmann * src/compositor.[ch]: Add code to destroy compositor. Implement diff --git a/src/display.c b/src/display.c index ca0b67642..ce349fb06 100644 --- a/src/display.c +++ b/src/display.c @@ -185,6 +185,48 @@ sn_error_trap_pop (SnDisplay *sn_display, } #endif +static void +enable_compositor (MetaDisplay *display) +{ + GSList *list; + + if (!display->compositor) + display->compositor = meta_compositor_new (display); + + if (!display->compositor) + return; + + for (list = display->screens; list != NULL; list = list->next) + { + MetaScreen *screen = list->data; + + meta_compositor_manage_screen (screen->display->compositor, + screen); + + meta_screen_composite_all_windows (screen); + } +} + +static void +disable_compositor (MetaDisplay *display) +{ + GSList *list; + + if (!display->compositor) + return; + + for (list = display->screens; list != NULL; list = list->next) + { + MetaScreen *screen = list->data; + + meta_compositor_unmanage_screen (screen->display->compositor, + screen); + } + + meta_compositor_destroy (display->compositor); + display->compositor = NULL; +} + gboolean meta_display_open (const char *name) { @@ -657,7 +699,7 @@ meta_display_open (const char *name) display->last_focus_time = timestamp; display->last_user_time = timestamp; - display->compositor = meta_compositor_new (display); + display->compositor = NULL; screens = NULL; @@ -692,18 +734,6 @@ meta_display_open (const char *name) { MetaScreen *screen = tmp->data; - /* The compositing manager opens its own connection to the X server - * and uses the XTest extension to ignore grabs. However, it also - * uses GL which opens yet another connection to the X server. With - * this ungrab/grab we would block indefinitely in XOpenDisplay(). - */ - meta_display_ungrab (display); - - meta_compositor_manage_screen (screen->display->compositor, - screen); - - meta_display_grab (display); - meta_screen_manage_all_windows (screen); tmp = tmp->next; @@ -748,6 +778,9 @@ meta_display_open (const char *name) } meta_display_ungrab (display); + + if (meta_prefs_get_compositing_manager ()) + enable_compositor (display); return TRUE; } @@ -2415,9 +2448,12 @@ event_callback (XEvent *event, break; } - meta_compositor_process_event (display->compositor, - event, - window); + if (display->compositor) + { + meta_compositor_process_event (display->compositor, + event, + window); + } display->current_time = CurrentTime; return filter_out_event; @@ -4752,6 +4788,8 @@ static void prefs_changed_callback (MetaPreference pref, void *data) { + MetaDisplay *display = data; + /* It may not be obvious why we regrab on focus mode * change; it's because we handle focus clicks a * bit differently for the different focus modes. @@ -4793,9 +4831,17 @@ prefs_changed_callback (MetaPreference pref, } else if (pref == META_PREF_AUDIBLE_BELL) { - MetaDisplay *display = data; meta_bell_set_audible (display, meta_prefs_bell_is_audible ()); } + else if (pref == META_PREF_COMPOSITING_MANAGER) + { + gboolean cm = meta_prefs_get_compositing_manager (); + + if (cm) + enable_compositor (display); + else + disable_compositor (display); + } } void diff --git a/src/metacity.schemas.in b/src/metacity.schemas.in index a2a3a4f9e..fdc835e08 100644 --- a/src/metacity.schemas.in +++ b/src/metacity.schemas.in @@ -268,6 +268,20 @@ + + /schemas/apps/metacity/general/compositing_manager + /apps/metacity/general/compositing_manager + metacity + boolean + FALSE + + Compositing Manager + + Determines whether Metacity is a compositing manager. + + + + /schemas/apps/metacity/workspace_names/name /apps/metacity/workspace_names/name_1 diff --git a/src/prefs.c b/src/prefs.c index 091ad2635..5683ac400 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -70,6 +70,7 @@ #define KEY_VISUAL_BELL_TYPE "/apps/metacity/general/visual_bell_type" #define KEY_CURSOR_THEME "/desktop/gnome/peripherals/mouse/cursor_theme" #define KEY_CURSOR_SIZE "/desktop/gnome/peripherals/mouse/cursor_size" +#define KEY_COMPOSITING_MANAGER "/apps/metacity/general/compositing_manager" #ifdef HAVE_GCONF static GConfClient *default_client = NULL; @@ -97,6 +98,7 @@ static gboolean reduced_resources = FALSE; static gboolean gnome_accessibility = FALSE; static char *cursor_theme = NULL; static int cursor_size = 24; +static gboolean compositing_manager = FALSE; static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH; static MetaButtonLayout button_layout = { @@ -150,6 +152,7 @@ static gboolean update_reduced_resources (gboolean value); static gboolean update_gnome_accessibility (gboolean value); static gboolean update_cursor_theme (const char *value); static gboolean update_cursor_size (int size); +static gboolean update_compositing_manager (gboolean value); static void change_notify (GConfClient *client, guint cnxn_id, @@ -443,7 +446,11 @@ meta_prefs_init (void) update_audible = get_bool (KEY_AUDIBLE_BELL, &bool_val_2); if (update_visual || update_audible) update_visual_bell (bool_val, bool_val_2); - + + bool_val = compositing_manager; + if (get_bool (KEY_COMPOSITING_MANAGER, &bool_val)) + update_compositing_manager (bool_val); + str_val = gconf_client_get_string (default_client, KEY_VISUAL_BELL_TYPE, &err); cleanup_error (&err); @@ -953,6 +960,22 @@ change_notify (GConfClient *client, if (update_cursor_size (d)) queue_changed (META_PREF_CURSOR_SIZE); } + else if (strcmp (key, KEY_COMPOSITING_MANAGER) == 0) + { + gboolean b; + + if (value && value->type != GCONF_VALUE_BOOL) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_COMPOSITING_MANAGER); + goto out; + } + + b = value ? gconf_value_get_bool (value) : compositing_manager; + + if (update_compositing_manager (b)) + queue_changed (META_PREF_COMPOSITING_MANAGER); + } else { meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n", @@ -1638,6 +1661,9 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_CURSOR_SIZE: return "CURSOR_SIZE"; + + case META_PREF_COMPOSITING_MANAGER: + return "COMPOSITING_MANAGER"; } return "(unknown)"; @@ -2492,3 +2518,21 @@ meta_prefs_get_window_binding (const char *name, g_assert_not_reached (); } + +#ifdef HAVE_GCONF +static gboolean +update_compositing_manager (gboolean value) +{ + gboolean old = compositing_manager; + + compositing_manager = value; + + return old != compositing_manager; +} +#endif + +gboolean +meta_prefs_get_compositing_manager (void) +{ + return compositing_manager; +} diff --git a/src/prefs.h b/src/prefs.h index 17ca7877c..264a4d36a 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -52,7 +52,8 @@ typedef enum META_PREF_REDUCED_RESOURCES, META_PREF_GNOME_ACCESSIBILITY, META_PREF_CURSOR_THEME, - META_PREF_CURSOR_SIZE + META_PREF_CURSOR_SIZE, + META_PREF_COMPOSITING_MANAGER } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -98,6 +99,7 @@ void meta_prefs_change_workspace_name (int i, const char* meta_prefs_get_cursor_theme (void); int meta_prefs_get_cursor_size (void); +gboolean meta_prefs_get_compositing_manager (void); /* Screen bindings */ #define META_KEYBINDING_WORKSPACE_1 "switch_to_workspace_1" diff --git a/src/screen.c b/src/screen.c index 003b04a15..c7a99f07c 100644 --- a/src/screen.c +++ b/src/screen.c @@ -731,62 +731,104 @@ meta_screen_free (MetaScreen *screen) meta_display_ungrab (display); } -void -meta_screen_manage_all_windows (MetaScreen *screen) +typedef struct +{ + Window xwindow; + XWindowAttributes attrs; +} WindowInfo; + +static GList * +list_windows (MetaScreen *screen) { Window ignored1, ignored2; Window *children; - int n_children; - int i; + guint n_children, i; + GList *result; - /* Must grab server to avoid obvious race condition */ - meta_display_grab (screen->display); - - meta_error_trap_push_with_return (screen->display); - XQueryTree (screen->display->xdisplay, screen->xroot, &ignored1, &ignored2, &children, &n_children); - if (meta_error_trap_pop_with_return (screen->display, TRUE) != Success) + result = NULL; + for (i = 0; i < n_children; ++i) { - meta_display_ungrab (screen->display); - return; - } + WindowInfo *info = g_new0 (WindowInfo, 1); - meta_stack_freeze (screen->stack); - i = 0; - while (i < n_children) - { - 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) - { + children[i], &info->attrs); + + if (meta_error_trap_pop_with_return (screen->display, TRUE)) + { meta_verbose ("Failed to get attributes for window 0x%lx\n", children[i]); + g_free (info); } else { - meta_window_new_with_attrs (screen->display, children[i], TRUE, - &attrs); + info->xwindow = children[i]; + } - meta_compositor_add_window (screen->display->compositor, - children[i], &attrs); - } + result = g_list_prepend (result, info); + } - ++i; + if (children) + XFree (children); + + return g_list_reverse (result); +} + +void +meta_screen_manage_all_windows (MetaScreen *screen) +{ + GList *windows; + GList *list; + + meta_display_grab (screen->display); + + windows = list_windows (screen); + + meta_stack_freeze (screen->stack); + for (list = windows; list != NULL; list = list->next) + { + WindowInfo *info = list->data; + + meta_window_new_with_attrs (screen->display, info->xwindow, TRUE, + &info->attrs); } meta_stack_thaw (screen->stack); + g_list_foreach (windows, (GFunc)g_free, NULL); + g_list_free (windows); + meta_display_ungrab (screen->display); +} + +void +meta_screen_composite_all_windows (MetaScreen *screen) +{ + GList *windows, *list; + + if (!screen->display->compositor) + return; - if (children) - XFree (children); + windows = list_windows (screen); + + meta_stack_freeze (screen->stack); + + for (list = windows; list != NULL; list = list->next) + { + WindowInfo *info = list->data; + + meta_compositor_add_window (screen->display->compositor, + info->xwindow, &info->attrs); + } + + meta_stack_thaw (screen->stack); + + g_list_foreach (windows, (GFunc)g_free, NULL); + g_list_free (windows); } MetaScreen* diff --git a/src/screen.h b/src/screen.h index 5ece4af70..8349b0fbd 100644 --- a/src/screen.h +++ b/src/screen.h @@ -205,6 +205,6 @@ void meta_screen_update_showing_desktop_hint (MetaScreen *screen); void meta_screen_apply_startup_properties (MetaScreen *screen, MetaWindow *window); - +void meta_screen_composite_all_windows (MetaScreen *screen); #endif