From df35234841997a381f59b33c9ade831c221dc6ef Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 23 Apr 2012 17:42:49 -0400 Subject: [PATCH] Allow potentially supporting multiple MetaWindowActors per window A lot of the code in mutter assumed a one to one relationship between a MetaWindow and a MetaWindowActor, and that it owns its MetaWindowActor. For the most part, we've gotten around this in GNOME Shell by creating a ClutterClone of the MetaWindowActor. In some spots, we reparent the actor owned by Mutter, and use it for our own purpose, which just plain isn't nice. Since the Clutter maintainers have plans to kill off ClutterClone, and since MetaWindowActor is already a very thin wrapper around MetaShapedTexture, we should be able to create multiple MetaWindowActors for a MetaShapedTexture. This commit replaces the "compositor_private" property on MetaWindow with a direct reference to a MetaWindowActor (which may go away at some point, see below), and a list of window actors. The direct reference is a replacement for the "compositor_private" property that has been there previously. It doesn't make sense to run mutter without compositing, so there's no real reason to keep the veil of a compositor/core split. The eventual plan I have in mind is to remove the direct reference to MetaWindowActor, and have the compositor/plugin just create a new window actor like anybody else. https://bugzilla.gnome.org/show_bug.cgi?id=678989 --- src/compositor/compositor.c | 137 ++++++++++++----------------- src/compositor/meta-window-actor.c | 30 ------- src/core/window-private.h | 6 +- src/core/window.c | 18 ++-- src/meta/window.h | 1 - 5 files changed, 64 insertions(+), 128 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index daddf7724..98a7f0988 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -150,10 +150,28 @@ add_win (MetaWindow *window) { MetaScreen *screen = meta_window_get_screen (window); MetaCompScreen *info = meta_screen_get_compositor_data (screen); + MetaWindowActor *actor; + ClutterActor *window_group; g_return_if_fail (info != NULL); - meta_window_actor_new (window); + actor = meta_window_actor_new (window); + + window->core_actor = actor; + + if (window->layer == META_LAYER_OVERRIDE_REDIRECT) + window_group = info->top_window_group; + else + window_group = info->window_group; + clutter_actor_add_child (window_group, CLUTTER_ACTOR (actor)); + + clutter_actor_set_reactive (CLUTTER_ACTOR (actor), TRUE); + clutter_actor_hide (CLUTTER_ACTOR (actor)); + + /* Initial position in the stack is arbitrary; stacking will be synced + * before we first paint. + */ + info->windows = g_list_append (info->windows, actor); sync_actor_stacking (info); } @@ -163,16 +181,13 @@ process_damage (MetaCompositor *compositor, XDamageNotifyEvent *event, MetaWindow *window) { - MetaWindowActor *window_actor; + GSList *iter; if (window == NULL) return; - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (window_actor == NULL) - return; - - meta_window_actor_process_damage (window_actor, event); + for (iter = window->actors; iter != NULL; iter = iter->next) + meta_window_actor_process_damage (META_WINDOW_ACTOR (iter->data), event); } static void @@ -180,24 +195,12 @@ process_property_notify (MetaCompositor *compositor, XPropertyEvent *event, MetaWindow *window) { - MetaWindowActor *window_actor; - - if (window == NULL) - return; - - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (window_actor == NULL) + if (window == NULL || window->core_actor == NULL) return; /* Check for the opacity changing */ if (event->atom == compositor->atom_net_wm_window_opacity) - { - meta_window_actor_update_opacity (window_actor); - DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n"); - return; - } - - DEBUG_TRACE ("process_property_notify: unknown\n"); + meta_window_actor_update_opacity (window->core_actor); } static Window @@ -789,27 +792,30 @@ void meta_compositor_remove_window (MetaCompositor *compositor, MetaWindow *window) { - MetaWindowActor *window_actor = NULL; MetaScreen *screen; MetaCompScreen *info; + GSList *iter; DEBUG_TRACE ("meta_compositor_remove_window\n"); - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; screen = meta_window_get_screen (window); info = meta_screen_get_compositor_data (screen); - if (window_actor == info->unredirected_window) + if (window->core_actor == info->unredirected_window) { - meta_window_actor_set_redirected (window_actor, TRUE); - meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)), - NULL); + meta_window_actor_set_redirected (info->unredirected_window, TRUE); + meta_shape_cow_for_window (meta_window_get_screen (window), NULL); info->unredirected_window = NULL; } - meta_window_actor_destroy (window_actor); + window->core_actor = NULL; + + for (iter = window->actors; iter != NULL; iter = iter->next) + { + MetaWindowActor *actor = META_WINDOW_ACTOR (iter->data); + meta_window_actor_destroy (actor); + info->windows = g_list_remove (info->windows, (gconstpointer) actor); + } } void @@ -869,12 +875,10 @@ void meta_compositor_window_shape_changed (MetaCompositor *compositor, MetaWindow *window) { - MetaWindowActor *window_actor; - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; + GSList *iter; - meta_window_actor_update_shape (window_actor); + for (iter = window->actors; iter != NULL; iter = iter->next) + meta_window_actor_update_shape (META_WINDOW_ACTOR (iter->data)); } /* Clutter makes the assumption that there is only one X window @@ -1037,12 +1041,8 @@ meta_compositor_show_window (MetaCompositor *compositor, MetaWindow *window, MetaCompEffect effect) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_show_window\n"); - if (!window_actor) - return; - - meta_window_actor_show (window_actor, effect); + if (window->core_actor != NULL) + meta_window_actor_show (window->core_actor, effect); } void @@ -1050,12 +1050,8 @@ meta_compositor_hide_window (MetaCompositor *compositor, MetaWindow *window, MetaCompEffect effect) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_hide_window\n"); - if (!window_actor) - return; - - meta_window_actor_hide (window_actor, effect); + if (window->core_actor != NULL) + meta_window_actor_hide (window->core_actor, effect); } void @@ -1064,12 +1060,8 @@ meta_compositor_maximize_window (MetaCompositor *compositor, MetaRectangle *old_rect, MetaRectangle *new_rect) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_maximize_window\n"); - if (!window_actor) - return; - - meta_window_actor_maximize (window_actor, old_rect, new_rect); + if (window->core_actor != NULL) + meta_window_actor_maximize (window->core_actor, old_rect, new_rect); } void @@ -1078,12 +1070,8 @@ meta_compositor_unmaximize_window (MetaCompositor *compositor, MetaRectangle *old_rect, MetaRectangle *new_rect) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_unmaximize_window\n"); - if (!window_actor) - return; - - meta_window_actor_unmaximize (window_actor, old_rect, new_rect); + if (window->core_actor != NULL) + meta_window_actor_unmaximize (window->core_actor, old_rect, new_rect); } void @@ -1259,7 +1247,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor, while (stack) { stack_window = stack->data; - stack_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (stack_window)); + stack_actor = stack_window->core_actor; if (!stack_actor) { meta_verbose ("Failed to find corresponding MetaWindowActor " @@ -1308,24 +1296,16 @@ void meta_compositor_window_mapped (MetaCompositor *compositor, MetaWindow *window) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_window_mapped\n"); - if (!window_actor) - return; - - meta_window_actor_mapped (window_actor); + if (window->core_actor != NULL) + meta_window_actor_mapped (window->core_actor); } void meta_compositor_window_unmapped (MetaCompositor *compositor, MetaWindow *window) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_window_unmapped\n"); - if (!window_actor) - return; - - meta_window_actor_unmapped (window_actor); + if (window->core_actor != NULL) + meta_window_actor_unmapped (window->core_actor); } void @@ -1333,17 +1313,8 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor, MetaWindow *window, gboolean did_placement) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - MetaScreen *screen = meta_window_get_screen (window); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); - - DEBUG_TRACE ("meta_compositor_sync_window_geometry\n"); - g_return_if_fail (info); - - if (!window_actor) - return; - - meta_window_actor_sync_actor_geometry (window_actor, did_placement); + if (window->core_actor != NULL) + meta_window_actor_sync_actor_geometry (window->core_actor, did_placement); } void diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index a872673d6..79e16719d 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -358,7 +358,6 @@ meta_window_actor_dispose (GObject *object) MetaScreen *screen; MetaDisplay *display; Display *xdisplay; - MetaCompScreen *info; if (priv->disposed) return; @@ -368,7 +367,6 @@ meta_window_actor_dispose (GObject *object) screen = priv->screen; display = meta_screen_get_display (screen); xdisplay = meta_display_get_xdisplay (display); - info = meta_screen_get_compositor_data (screen); meta_window_actor_detach (self); @@ -398,8 +396,6 @@ meta_window_actor_dispose (GObject *object) priv->damage = None; } - info->windows = g_list_remove (info->windows, (gconstpointer) self); - g_clear_object (&priv->window); /* @@ -1251,7 +1247,6 @@ void meta_window_actor_destroy (MetaWindowActor *self) { MetaWindow *window; - MetaCompScreen *info; MetaWindowActorPrivate *priv; MetaWindowType window_type; @@ -1259,14 +1254,6 @@ meta_window_actor_destroy (MetaWindowActor *self) window = priv->window; window_type = meta_window_get_window_type (window); - meta_window_set_compositor_private (window, NULL); - - /* - * We remove the window from internal lookup hashes and thus any other - * unmap events etc fail - */ - info = meta_screen_get_compositor_data (priv->screen); - info->windows = g_list_remove (info->windows, (gconstpointer) self); if (window_type == META_WINDOW_DROPDOWN_MENU || window_type == META_WINDOW_POPUP_MENU || @@ -1476,11 +1463,8 @@ meta_window_actor_unmaximize (MetaWindowActor *self, MetaWindowActor * meta_window_actor_new (MetaWindow *window) { - MetaScreen *screen = meta_window_get_screen (window); - MetaCompScreen *info = meta_screen_get_compositor_data (screen); MetaWindowActor *self; MetaWindowActorPrivate *priv; - ClutterActor *window_group; self = g_object_new (META_TYPE_WINDOW_ACTOR, "meta-window", window, @@ -1506,20 +1490,6 @@ meta_window_actor_new (MetaWindow *window) meta_window_actor_sync_actor_geometry (self, priv->window->placed); - /* Hang our compositor window state off the MetaWindow for fast retrieval */ - meta_window_set_compositor_private (window, G_OBJECT (self)); - - if (window->layer == META_LAYER_OVERRIDE_REDIRECT) - window_group = info->top_window_group; - else - window_group = info->window_group; - - clutter_actor_add_child (window_group, CLUTTER_ACTOR (self)); - - clutter_actor_hide (CLUTTER_ACTOR (self)); - - clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); - /* Initial position in the stack is arbitrary; stacking will be synced * before we first paint. */ diff --git a/src/core/window-private.h b/src/core/window-private.h index cd29d9886..967f95429 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -36,6 +36,7 @@ #include #include +#include #include #include "screen-private.h" #include @@ -438,7 +439,10 @@ struct _MetaWindow /* maintained by group.c */ MetaGroup *group; - GObject *compositor_private; + GSList *actors; + + /* The core actor is the one in the window group. */ + MetaWindowActor *core_actor; /* Focused window that is (directly or indirectly) attached to this one */ MetaWindow *attached_focus_window; diff --git a/src/core/window.c b/src/core/window.c index fef3ca8eb..4a43151d0 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1193,7 +1193,8 @@ meta_window_new_with_attrs (MetaDisplay *display, window->initial_workspace = 0; /* not used */ window->initial_timestamp = 0; /* not used */ - window->compositor_private = NULL; + window->core_actor = NULL; + window->actors = NULL; window->monitor = meta_screen_get_monitor_for_window (window->screen, window); @@ -11064,24 +11065,15 @@ meta_window_get_gtk_menubar_object_path (MetaWindow *window) * meta_window_get_compositor_private: * @window: a #MetaWindow * - * Gets the compositor's wrapper object for @window. - * - * Return value: (transfer none): the wrapper object. - **/ + * Return value: (transfer none): + */ GObject * meta_window_get_compositor_private (MetaWindow *window) { if (!window) return NULL; - return window->compositor_private; -} -void -meta_window_set_compositor_private (MetaWindow *window, GObject *priv) -{ - if (!window) - return; - window->compositor_private = priv; + return G_OBJECT (window->core_actor); } const char * diff --git a/src/meta/window.h b/src/meta/window.h index 452aeaada..729c5adf9 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -154,7 +154,6 @@ void meta_window_change_workspace_by_index (MetaWindow *window, void meta_window_change_workspace (MetaWindow *window, MetaWorkspace *workspace); GObject *meta_window_get_compositor_private (MetaWindow *window); -void meta_window_set_compositor_private (MetaWindow *window, GObject *priv); void meta_window_configure_notify (MetaWindow *window, XConfigureEvent *event); const char *meta_window_get_role (MetaWindow *window); MetaStackLayer meta_window_get_layer (MetaWindow *window);