[mutter/wip/mult-window-actors: 5/9] Allow potentially supporting multiple MetaWindowActors per window



commit 2fe0ad8693e669ce2ab437e5972ba879fd8486c4
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Apr 23 17:42:49 2012 -0400

    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
    mafia has plans to drive a bullet through 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. MetaWindow will become a GObject, meaning it has properties
    and signals, and we can e.g. bind the ClutterActor's opacity to the
    MetaWindow's opacity without having to go through atom_net_wm_window_opacity
    fanciness.

 src/compositor/compositor.c        |  131 +++++++++++++-----------------------
 src/compositor/meta-window-actor.c |   26 -------
 src/core/window-private.h          |    5 +-
 src/core/window.c                  |   32 ++++++---
 src/meta/compositor.h              |    1 +
 src/meta/window.h                  |    2 +-
 6 files changed, 74 insertions(+), 123 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 404e5f4..c78658c 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -84,10 +84,22 @@ add_win (MetaWindow *window)
 {
   MetaScreen		*screen = meta_window_get_screen (window);
   MetaCompScreen        *info = meta_screen_get_compositor_data (screen);
+  MetaWindowActor       *actor;
 
   g_return_if_fail (info != NULL);
 
-  meta_window_actor_new (window);
+  actor = meta_window_actor_new (window);
+
+  window->actors = g_slist_append (window->actors, actor);
+  window->core_actor = actor;
+
+  clutter_actor_add_child (info->window_group, CLUTTER_ACTOR (actor));
+  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);
 }
@@ -97,16 +109,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
@@ -114,8 +123,6 @@ process_property_notify (MetaCompositor	*compositor,
                          XPropertyEvent *event,
                          MetaWindow     *window)
 {
-  MetaWindowActor *window_actor;
-
   if (event->atom == compositor->atom_x_root_pixmap)
     {
       GSList *l;
@@ -131,22 +138,12 @@ process_property_notify (MetaCompositor	*compositor,
         }
     }
 
-  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
@@ -660,27 +657,29 @@ 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)
+  for (iter = window->actors; iter != NULL; iter = iter->next)
     {
-      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);
-      info->unredirected_window = NULL;
-    }
+      MetaWindowActor *actor = META_WINDOW_ACTOR (iter->data);
+
+      if (actor == info->unredirected_window)
+        {
+          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);
+      meta_window_actor_destroy (actor);
+      info->windows = g_list_remove (info->windows, (gconstpointer) actor);
+    }
 }
 
 void
@@ -712,9 +711,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));
-  meta_window_actor_update_shape (window_actor);
+  GSList *iter;
+
+  for (iter = window->actors; iter != NULL; iter = iter->next)
+    meta_window_actor_update_shape (META_WINDOW_ACTOR (iter->data));
 }
 
 /**
@@ -816,12 +816,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
@@ -829,12 +825,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
@@ -843,12 +835,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
@@ -857,12 +845,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
@@ -1025,7 +1009,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 "
@@ -1074,41 +1058,22 @@ 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
 meta_compositor_sync_window_geometry (MetaCompositor *compositor,
 				      MetaWindow *window)
 {
-  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_position (window_actor);
 }
 
 void
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 4325155..4412d66 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -372,7 +372,6 @@ meta_window_actor_dispose (GObject *object)
   MetaScreen             *screen;
   MetaDisplay            *display;
   Display                *xdisplay;
-  MetaCompScreen         *info;
 
   if (priv->disposed)
     return;
@@ -382,7 +381,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);
 
@@ -423,8 +421,6 @@ meta_window_actor_dispose (GObject *object)
       priv->damage = None;
     }
 
-  info->windows = g_list_remove (info->windows, (gconstpointer) self);
-
   if (priv->window)
     {
       g_object_unref (priv->window);
@@ -1255,7 +1251,6 @@ void
 meta_window_actor_destroy (MetaWindowActor *self)
 {
   MetaWindow	      *window;
-  MetaCompScreen      *info;
   MetaWindowActorPrivate *priv;
   MetaWindowType window_type;
 
@@ -1263,14 +1258,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,7 +1463,6 @@ 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;
   MetaFrame		 *frame;
@@ -1507,18 +1493,6 @@ meta_window_actor_new (MetaWindow *window)
 
   meta_window_actor_sync_actor_position (self);
 
-  /* Hang our compositor window state off the MetaWindow for fast retrieval */
-  meta_window_set_compositor_private (window, G_OBJECT (self));
-
-  clutter_actor_add_child (info->window_group,
-                           CLUTTER_ACTOR (self));
-  clutter_actor_hide (CLUTTER_ACTOR (self));
-
-  /* Initial position in the stack is arbitrary; stacking will be synced
-   * before we first paint.
-   */
-  info->windows = g_list_append (info->windows, self);
-
   return self;
 }
 
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 1db735e..ea7693a 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -406,7 +406,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 36c68b1..8195b33 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -1163,7 +1163,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->actors = NULL;
+  window->core_actor = NULL;
 
   window->monitor = meta_screen_get_monitor_for_window (window->screen, window);
 
@@ -10386,27 +10387,34 @@ meta_window_get_gtk_menubar_object_path (MetaWindow *window)
 }
 
 /**
- * meta_window_get_compositor_private:
+ * meta_window_get_window_actors:
  * @window: a #MetaWindow
  *
- * Gets the compositor's wrapper object for @window.
- *
- * Return value: (transfer none): the wrapper object.
+ * Return value: (transfer none) (element-type Meta.WindowActor):
+ * A list of window actors.
  **/
-GObject *
-meta_window_get_compositor_private (MetaWindow *window)
+GSList *
+meta_window_get_window_actors (MetaWindow *window)
 {
   if (!window)
     return NULL;
-  return window->compositor_private;
+
+  return window->actors;
 }
 
-void
-meta_window_set_compositor_private (MetaWindow *window, GObject *priv)
+/**
+ * meta_window_get_compositor_private:
+ * @window: a #MetaWindow
+ *
+ * Return value: (transfer none):
+ */
+GObject *
+meta_window_get_compositor_private (MetaWindow *window)
 {
   if (!window)
-    return;
-  window->compositor_private = priv;
+    return NULL;
+
+  return G_OBJECT (window->core_actor);
 }
 
 const char *
diff --git a/src/meta/compositor.h b/src/meta/compositor.h
index c65267b..7fe01c6 100644
--- a/src/meta/compositor.h
+++ b/src/meta/compositor.h
@@ -29,6 +29,7 @@
 #include <meta/boxes.h>
 #include <meta/window.h>
 #include <meta/workspace.h>
+#include <meta/meta-window-actor.h>
 
 /**
  * MetaCompEffect:
diff --git a/src/meta/window.h b/src/meta/window.h
index 1d2f59b..612f1b5 100644
--- a/src/meta/window.h
+++ b/src/meta/window.h
@@ -116,8 +116,8 @@ void meta_window_change_workspace_by_index (MetaWindow *window,
                                             gint        space_index,
                                             gboolean    append,
                                             guint32     timestamp);
+GSList *meta_window_get_window_actors (MetaWindow *window);
 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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]