New function.

Thu Feb 16 15:24:42 2006  Søren Sandmann  <sandmann@redhat.com>

	* 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
This commit is contained in:
Søren Sandmann 2006-02-16 20:26:05 +00:00 committed by Søren Sandmann Pedersen
parent 0f48ff448c
commit f6738a930c
7 changed files with 215 additions and 51 deletions

View File

@ -1,3 +1,19 @@
Thu Feb 16 15:24:42 2006 Søren Sandmann <sandmann@redhat.com>
* 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 <sandmann@redhat.com> Wed Feb 15 18:42:03 2006 Søren Sandmann <sandmann@redhat.com>
* src/compositor.[ch]: Add code to destroy compositor. Implement * src/compositor.[ch]: Add code to destroy compositor. Implement

View File

@ -185,6 +185,48 @@ sn_error_trap_pop (SnDisplay *sn_display,
} }
#endif #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 gboolean
meta_display_open (const char *name) meta_display_open (const char *name)
{ {
@ -657,7 +699,7 @@ meta_display_open (const char *name)
display->last_focus_time = timestamp; display->last_focus_time = timestamp;
display->last_user_time = timestamp; display->last_user_time = timestamp;
display->compositor = meta_compositor_new (display); display->compositor = NULL;
screens = NULL; screens = NULL;
@ -692,18 +734,6 @@ meta_display_open (const char *name)
{ {
MetaScreen *screen = tmp->data; 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); meta_screen_manage_all_windows (screen);
tmp = tmp->next; tmp = tmp->next;
@ -748,6 +778,9 @@ meta_display_open (const char *name)
} }
meta_display_ungrab (display); meta_display_ungrab (display);
if (meta_prefs_get_compositing_manager ())
enable_compositor (display);
return TRUE; return TRUE;
} }
@ -2415,9 +2448,12 @@ event_callback (XEvent *event,
break; break;
} }
meta_compositor_process_event (display->compositor, if (display->compositor)
event, {
window); meta_compositor_process_event (display->compositor,
event,
window);
}
display->current_time = CurrentTime; display->current_time = CurrentTime;
return filter_out_event; return filter_out_event;
@ -4752,6 +4788,8 @@ static void
prefs_changed_callback (MetaPreference pref, prefs_changed_callback (MetaPreference pref,
void *data) void *data)
{ {
MetaDisplay *display = data;
/* It may not be obvious why we regrab on focus mode /* It may not be obvious why we regrab on focus mode
* change; it's because we handle focus clicks a * change; it's because we handle focus clicks a
* bit differently for the different focus modes. * bit differently for the different focus modes.
@ -4793,9 +4831,17 @@ prefs_changed_callback (MetaPreference pref,
} }
else if (pref == META_PREF_AUDIBLE_BELL) else if (pref == META_PREF_AUDIBLE_BELL)
{ {
MetaDisplay *display = data;
meta_bell_set_audible (display, meta_prefs_bell_is_audible ()); 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 void

View File

@ -268,6 +268,20 @@
</locale> </locale>
</schema> </schema>
<schema>
<key>/schemas/apps/metacity/general/compositing_manager</key>
<applyto>/apps/metacity/general/compositing_manager</applyto>
<owner>metacity</owner>
<type>boolean</type>
<default>FALSE</default>
<locale name="C">
<short>Compositing Manager</short>
<long>
Determines whether Metacity is a compositing manager.
</long>
</locale>
</schema>
<schema> <schema>
<key>/schemas/apps/metacity/workspace_names/name</key> <key>/schemas/apps/metacity/workspace_names/name</key>
<applyto>/apps/metacity/workspace_names/name_1</applyto> <applyto>/apps/metacity/workspace_names/name_1</applyto>

View File

@ -70,6 +70,7 @@
#define KEY_VISUAL_BELL_TYPE "/apps/metacity/general/visual_bell_type" #define KEY_VISUAL_BELL_TYPE "/apps/metacity/general/visual_bell_type"
#define KEY_CURSOR_THEME "/desktop/gnome/peripherals/mouse/cursor_theme" #define KEY_CURSOR_THEME "/desktop/gnome/peripherals/mouse/cursor_theme"
#define KEY_CURSOR_SIZE "/desktop/gnome/peripherals/mouse/cursor_size" #define KEY_CURSOR_SIZE "/desktop/gnome/peripherals/mouse/cursor_size"
#define KEY_COMPOSITING_MANAGER "/apps/metacity/general/compositing_manager"
#ifdef HAVE_GCONF #ifdef HAVE_GCONF
static GConfClient *default_client = NULL; static GConfClient *default_client = NULL;
@ -97,6 +98,7 @@ static gboolean reduced_resources = FALSE;
static gboolean gnome_accessibility = FALSE; static gboolean gnome_accessibility = FALSE;
static char *cursor_theme = NULL; static char *cursor_theme = NULL;
static int cursor_size = 24; static int cursor_size = 24;
static gboolean compositing_manager = FALSE;
static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH; static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH;
static MetaButtonLayout button_layout = { 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_gnome_accessibility (gboolean value);
static gboolean update_cursor_theme (const char *value); static gboolean update_cursor_theme (const char *value);
static gboolean update_cursor_size (int size); static gboolean update_cursor_size (int size);
static gboolean update_compositing_manager (gboolean value);
static void change_notify (GConfClient *client, static void change_notify (GConfClient *client,
guint cnxn_id, guint cnxn_id,
@ -443,7 +446,11 @@ meta_prefs_init (void)
update_audible = get_bool (KEY_AUDIBLE_BELL, &bool_val_2); update_audible = get_bool (KEY_AUDIBLE_BELL, &bool_val_2);
if (update_visual || update_audible) if (update_visual || update_audible)
update_visual_bell (bool_val, bool_val_2); 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, str_val = gconf_client_get_string (default_client, KEY_VISUAL_BELL_TYPE,
&err); &err);
cleanup_error (&err); cleanup_error (&err);
@ -953,6 +960,22 @@ change_notify (GConfClient *client,
if (update_cursor_size (d)) if (update_cursor_size (d))
queue_changed (META_PREF_CURSOR_SIZE); 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 else
{ {
meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n", 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: case META_PREF_CURSOR_SIZE:
return "CURSOR_SIZE"; return "CURSOR_SIZE";
case META_PREF_COMPOSITING_MANAGER:
return "COMPOSITING_MANAGER";
} }
return "(unknown)"; return "(unknown)";
@ -2492,3 +2518,21 @@ meta_prefs_get_window_binding (const char *name,
g_assert_not_reached (); 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;
}

View File

@ -52,7 +52,8 @@ typedef enum
META_PREF_REDUCED_RESOURCES, META_PREF_REDUCED_RESOURCES,
META_PREF_GNOME_ACCESSIBILITY, META_PREF_GNOME_ACCESSIBILITY,
META_PREF_CURSOR_THEME, META_PREF_CURSOR_THEME,
META_PREF_CURSOR_SIZE META_PREF_CURSOR_SIZE,
META_PREF_COMPOSITING_MANAGER
} MetaPreference; } MetaPreference;
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, 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); const char* meta_prefs_get_cursor_theme (void);
int meta_prefs_get_cursor_size (void); int meta_prefs_get_cursor_size (void);
gboolean meta_prefs_get_compositing_manager (void);
/* Screen bindings */ /* Screen bindings */
#define META_KEYBINDING_WORKSPACE_1 "switch_to_workspace_1" #define META_KEYBINDING_WORKSPACE_1 "switch_to_workspace_1"

View File

@ -731,62 +731,104 @@ meta_screen_free (MetaScreen *screen)
meta_display_ungrab (display); meta_display_ungrab (display);
} }
void typedef struct
meta_screen_manage_all_windows (MetaScreen *screen) {
Window xwindow;
XWindowAttributes attrs;
} WindowInfo;
static GList *
list_windows (MetaScreen *screen)
{ {
Window ignored1, ignored2; Window ignored1, ignored2;
Window *children; Window *children;
int n_children; guint n_children, i;
int 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, XQueryTree (screen->display->xdisplay,
screen->xroot, screen->xroot,
&ignored1, &ignored2, &children, &n_children); &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); WindowInfo *info = g_new0 (WindowInfo, 1);
return;
}
meta_stack_freeze (screen->stack);
i = 0;
while (i < n_children)
{
XWindowAttributes attrs;
meta_error_trap_push_with_return (screen->display); meta_error_trap_push_with_return (screen->display);
XGetWindowAttributes (screen->display->xdisplay, XGetWindowAttributes (screen->display->xdisplay,
children[i], &attrs); children[i], &info->attrs);
if (meta_error_trap_pop_with_return (screen->display, TRUE) != Success) if (meta_error_trap_pop_with_return (screen->display, TRUE))
{ {
meta_verbose ("Failed to get attributes for window 0x%lx\n", meta_verbose ("Failed to get attributes for window 0x%lx\n",
children[i]); children[i]);
g_free (info);
} }
else else
{ {
meta_window_new_with_attrs (screen->display, children[i], TRUE, info->xwindow = children[i];
&attrs); }
meta_compositor_add_window (screen->display->compositor, result = g_list_prepend (result, info);
children[i], &attrs); }
}
++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); meta_stack_thaw (screen->stack);
g_list_foreach (windows, (GFunc)g_free, NULL);
g_list_free (windows);
meta_display_ungrab (screen->display); meta_display_ungrab (screen->display);
}
void
meta_screen_composite_all_windows (MetaScreen *screen)
{
GList *windows, *list;
if (!screen->display->compositor)
return;
if (children) windows = list_windows (screen);
XFree (children);
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* MetaScreen*

View File

@ -205,6 +205,6 @@ void meta_screen_update_showing_desktop_hint (MetaScreen *screen);
void meta_screen_apply_startup_properties (MetaScreen *screen, void meta_screen_apply_startup_properties (MetaScreen *screen,
MetaWindow *window); MetaWindow *window);
void meta_screen_composite_all_windows (MetaScreen *screen);
#endif #endif