[mutter/gbsneto/content-part2: 4/7] Add MetaWindowContent
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/content-part2: 4/7] Add MetaWindowContent
- Date: Mon, 4 Feb 2019 11:15:51 +0000 (UTC)
commit 378119362589ac10cebe386466e7afe29d12a891
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sun Dec 23 12:24:26 2018 -0200
Add MetaWindowContent
MetaWindowContent is a GObject class that implements ClutterContent.
It draws the contents of the window, unshadowed in the case of server
side decorated windows on X11, as a composition of the contents of
the subsurfaces.
WIP
src/compositor/meta-window-actor.c | 49 ++++-
src/compositor/meta-window-content-private.h | 31 +++
src/compositor/meta-window-content.c | 305 +++++++++++++++++++++++++++
src/meson.build | 2 +
src/meta/meson.build | 1 +
src/meta/meta-window-actor.h | 3 +
src/meta/meta-window-content.h | 39 ++++
7 files changed, 429 insertions(+), 1 deletion(-)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index d471f622a..dc888af05 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -33,6 +33,9 @@
#include "compositor/meta-surface-actor.h"
#include "compositor/meta-texture-rectangle.h"
#include "compositor/meta-window-actor-private.h"
+#include "compositor/meta-window-actor-wayland.h"
+#include "compositor/meta-window-actor-x11.h"
+#include "compositor/meta-window-content-private.h"
#include "compositor/region-utils.h"
#include "meta/meta-enum-types.h"
#include "meta/meta-shadow-factory.h"
@@ -58,6 +61,8 @@ typedef struct _MetaWindowActorPrivate
MetaSurfaceActor *surface;
+ MetaWindowContent *content;
+
/* MetaShadowFactory only caches shadows that are actually in use;
* to avoid unnecessary recomputation we do two things: 1) we store
* both a focused and unfocused shadow for the window. If the window
@@ -124,6 +129,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum
{
PROP_META_WINDOW = 1,
+ PROP_CONTENT,
PROP_SHADOW_MODE,
PROP_SHADOW_CLASS
};
@@ -255,11 +261,19 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
g_object_class_install_property (object_class,
PROP_SHADOW_CLASS,
pspec);
+
+ g_object_class_override_property (object_class,
+ PROP_CONTENT,
+ "content");
}
static void
meta_window_actor_init (MetaWindowActor *self)
{
+ MetaWindowActorPrivate *priv =
+ meta_window_actor_get_instance_private (self);
+
+ priv->content = meta_window_content_new (self);
}
static void
@@ -267,7 +281,11 @@ window_appears_focused_notify (MetaWindow *mw,
GParamSpec *arg1,
gpointer data)
{
- clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
+ MetaWindowActor *window_actor = META_WINDOW_ACTOR (data);
+ MetaWindowActorPrivate *priv =
+ meta_window_actor_get_instance_private (window_actor);
+
+ clutter_content_invalidate (CLUTTER_CONTENT (priv->content));
}
static void
@@ -396,6 +414,8 @@ set_surface (MetaWindowActor *self,
else
meta_window_actor_sync_thawed_state (self);
}
+
+ clutter_content_invalidate (CLUTTER_CONTENT (priv->content));
}
void
@@ -463,6 +483,7 @@ meta_window_actor_dispose (GObject *object)
priv->disposed = TRUE;
+ g_clear_object (&priv->content);
g_clear_pointer (&priv->shape_region, cairo_region_destroy);
g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
@@ -492,6 +513,9 @@ meta_window_actor_set_property (GObject *object,
switch (prop_id)
{
+ case PROP_CONTENT:
+ g_warning ("Overriding the content of MetaWindowActor is not allowed.");
+ break;
case PROP_META_WINDOW:
priv->window = g_value_dup_object (value);
g_signal_connect_object (priv->window, "notify::appears-focused",
@@ -540,6 +564,9 @@ meta_window_actor_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_CONTENT:
+ g_value_set_object (value, priv->content);
+ break;
case PROP_META_WINDOW:
g_value_set_object (value, priv->window);
break;
@@ -841,6 +868,25 @@ meta_window_actor_get_texture (MetaWindowActor *self)
return NULL;
}
+/**
+ * meta_window_actor_get_content:
+ * @window_actor: a #MetaWindowActor
+ *
+ * Gets the #ClutterContent that represents the visible contents of the
+ * window. This includes subsurfaces. It should be used as the content
+ * of a #ClutterActor, through clutter_actor_set_content().
+ *
+ * Return value: (transfer none): a #ClutterContent
+ */
+ClutterContent *
+meta_window_actor_get_content (MetaWindowActor *window_actor)
+{
+ MetaWindowActorPrivate *priv =
+ meta_window_actor_get_instance_private (window_actor);
+
+ return CLUTTER_CONTENT (priv->content);
+}
+
/**
* meta_window_actor_get_surface:
* @self: a #MetaWindowActor
@@ -1722,6 +1768,7 @@ meta_window_actor_update_shape (MetaWindowActor *self)
if (is_frozen (self))
return;
+ clutter_content_invalidate_size (CLUTTER_CONTENT (priv->content));
clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
}
diff --git a/src/compositor/meta-window-content-private.h b/src/compositor/meta-window-content-private.h
new file mode 100644
index 000000000..ab34e4337
--- /dev/null
+++ b/src/compositor/meta-window-content-private.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 Endless, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ * Georges Basile Stavracas Neto <gbsneto gnome org>
+ */
+
+#ifndef META_WINDOW_CONTENT_PRIVATE_H
+#define META_WINDOW_CONTENT_PRIVATE_H
+
+#include "meta/meta-window-content.h"
+#include "meta/meta-window-actor.h"
+
+MetaWindowContent* meta_window_content_new (MetaWindowActor *window_actor);
+
+#endif /* META_WINDOW_CONTENT_PRIVATE_H */
diff --git a/src/compositor/meta-window-content.c b/src/compositor/meta-window-content.c
new file mode 100644
index 000000000..1b4b9d51a
--- /dev/null
+++ b/src/compositor/meta-window-content.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2018 Endless, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ * Georges Basile Stavracas Neto <gbsneto gnome org>
+ */
+
+#include "compositor/meta-shaped-texture-private.h"
+#include "compositor/meta-surface-actor.h"
+#include "compositor/meta-window-actor-private.h"
+#include "compositor/meta-window-content-private.h"
+
+struct _MetaWindowContent
+{
+ GObject parent;
+
+ MetaWindowActor *window_actor;
+
+ unsigned int attached_actors;
+};
+
+static void clutter_content_iface_init (ClutterContentIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (MetaWindowContent, meta_window_content, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, clutter_content_iface_init))
+
+/**
+ * SECTION:meta-window-content
+ * @title: MetaWindowContent
+ * @short_description: Contents of a MetaWindowActor
+ *
+ * #MetaWindowContent represents the user-visible content of
+ * a #MetaWindowActor. It combines the contents of all the
+ * #MetaSurfaceActors that the window contains into a final
+ * texture.
+ *
+ * It is intended to be used as follows:
+ *
+ * |[
+ * ClutterActor *
+ * create_window_clone (MetaWindowActor *window_actor)
+ * {
+ * ClutterContent *window_content;
+ * ClutterActor *clone;
+ *
+ * window_content = meta_window_actor_get_content (window_actor);
+ *
+ * clone = clutter_actor_new ();
+ * clutter_actor_set_content (clone, window_content);
+ *
+ * return clone;
+ * }
+ * ]|
+ *
+ * It is also exposed as the #MetaWindowActor.content property
+ * that can be binded to other actors. Notice, however, that
+ * the value of #MetaWindowActor.content cannot be modified,
+ * only read.
+ */
+
+enum
+{
+ PROP_0,
+ PROP_WINDOW_ACTOR,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+add_surface_paint_nodes (MetaSurfaceActor *surface_actor,
+ ClutterActor *actor,
+ ClutterPaintNode *root_node,
+ float dx,
+ float dy,
+ float scale_h,
+ float scale_v)
+{
+ MetaShapedTexture *shaped_texture;
+ ClutterActorIter iter;
+ ClutterActor *child;
+ ClutterActorBox box;
+ CoglTexture *texture;
+ double actor_scale, surface_scale;
+ uint8_t opacity;
+
+ shaped_texture = meta_surface_actor_get_texture (surface_actor);
+ texture = meta_shaped_texture_get_texture (shaped_texture);
+
+ if (!texture)
+ return;
+
+ opacity = (guint) clutter_actor_get_paint_opacity (CLUTTER_ACTOR (surface_actor)) *
+ (guint) clutter_actor_get_paint_opacity (actor) /
+ 255;
+
+ clutter_actor_get_content_box (CLUTTER_ACTOR (surface_actor),
+ &box);
+ box.x1 = (box.x1 + dx) * scale_h;
+ box.x2 = (box.x2 + dx) * scale_h;
+ box.y1 = (box.y1 + dy) * scale_v;
+ box.y2 = (box.y2 + dy) * scale_v;
+
+ clutter_actor_get_scale (actor, &actor_scale, NULL);
+ clutter_actor_get_scale (CLUTTER_ACTOR (surface_actor), &surface_scale, NULL);
+
+ _meta_shaped_texture_paint_node (shaped_texture,
+ root_node,
+ &box,
+ actor_scale * surface_scale,
+ opacity);
+
+ clutter_actor_iter_init (&iter, CLUTTER_ACTOR (surface_actor));
+ while (clutter_actor_iter_next (&iter, &child))
+ {
+ float subsurface_dx, subsurface_dy;
+
+ subsurface_dx = dx + clutter_actor_get_x (child);
+ subsurface_dy = dy + clutter_actor_get_y (child);
+
+ add_surface_paint_nodes (META_SURFACE_ACTOR (child),
+ actor, root_node,
+ subsurface_dx, subsurface_dy,
+ scale_h, scale_v);
+ }
+}
+
+static void
+meta_window_content_paint_content (ClutterContent *content,
+ ClutterActor *actor,
+ ClutterPaintNode *node)
+{
+ MetaWindowContent *window_content = META_WINDOW_CONTENT (content);
+ MetaSurfaceActor *surface_actor =
+ meta_window_actor_get_surface (window_content->window_actor);
+ float dst_width, dst_height;
+ float scale_h, scale_v;
+ float width, height;
+
+ g_assert (!META_IS_WINDOW_ACTOR (actor));
+ g_assert (!META_IS_SURFACE_ACTOR (actor));
+
+ if (!surface_actor)
+ return;
+
+ /* Horizontal and vertical scales */
+ clutter_actor_get_size (CLUTTER_ACTOR (surface_actor),
+ &width, &height);
+ clutter_actor_get_size (actor, &dst_width, &dst_height);
+ scale_h = dst_width / width;
+ scale_v = dst_height / height;
+
+ add_surface_paint_nodes (surface_actor, actor,
+ node, 0.0, 0.0,
+ scale_h, scale_v);
+}
+
+static gboolean
+meta_window_content_get_preferred_size (ClutterContent *content,
+ float *width,
+ float *height)
+{
+ MetaWindowContent *window_content = META_WINDOW_CONTENT (content);
+ MetaSurfaceActor *surface_actor =
+ meta_window_actor_get_surface (window_content->window_actor);
+
+ if (!surface_actor)
+ return FALSE;
+
+ clutter_actor_get_size (CLUTTER_ACTOR (surface_actor),
+ width, height);
+ return TRUE;
+}
+
+static void
+meta_window_content_attached (ClutterContent *content,
+ ClutterActor *actor)
+{
+ MetaWindowContent *window_content = META_WINDOW_CONTENT (content);
+
+ window_content->attached_actors++;
+}
+
+static void
+meta_window_content_detached (ClutterContent *content,
+ ClutterActor *actor)
+{
+ MetaWindowContent *window_content = META_WINDOW_CONTENT (content);
+
+ window_content->attached_actors--;
+}
+
+static void
+clutter_content_iface_init (ClutterContentIface *iface)
+{
+ iface->paint_content = meta_window_content_paint_content;
+ iface->get_preferred_size = meta_window_content_get_preferred_size;
+ iface->attached = meta_window_content_attached;
+ iface->detached = meta_window_content_detached;
+}
+
+static void
+meta_window_content_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MetaWindowContent *window_content = META_WINDOW_CONTENT (object);
+
+ switch (prop_id)
+ {
+ case PROP_WINDOW_ACTOR:
+ g_value_set_object (value, window_content->window_actor);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meta_window_content_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MetaWindowContent *window_content = META_WINDOW_CONTENT (object);
+
+ switch (prop_id)
+ {
+ case PROP_WINDOW_ACTOR:
+ g_assert (window_content->window_actor == NULL);
+
+ window_content->window_actor = g_value_get_object (value);
+ g_assert (window_content->window_actor != NULL);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meta_window_content_class_init (MetaWindowContentClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = meta_window_content_get_property;
+ object_class->set_property = meta_window_content_set_property;
+
+ properties[PROP_WINDOW_ACTOR] =
+ g_param_spec_object ("window-actor",
+ "Window actor",
+ "Window actor",
+ META_TYPE_WINDOW_ACTOR,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+meta_window_content_init (MetaWindowContent *self)
+{
+}
+
+MetaWindowContent *
+meta_window_content_new (MetaWindowActor *window_actor)
+{
+ return g_object_new (META_TYPE_WINDOW_CONTENT,
+ "window-actor", window_actor,
+ NULL);
+}
+
+/**
+ * meta_window_content_get_window_actor:
+ * @window_content: a #MetaWindowContent
+ *
+ * Retrieves the window actor that @window_content represents.
+ *
+ * Returns: (transfer none): a #MetaWindowActor
+ */
+MetaWindowActor *
+meta_window_content_get_window_actor (MetaWindowContent *window_content)
+{
+ g_return_val_if_fail (META_IS_WINDOW_CONTENT (window_content), NULL);
+
+ return window_content->window_actor;
+}
diff --git a/src/meson.build b/src/meson.build
index a3e579d9b..a94d2de2e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -300,6 +300,8 @@ mutter_sources = [
'compositor/meta-window-actor-wayland.h',
'compositor/meta-window-actor-x11.c',
'compositor/meta-window-actor-x11.h',
+ 'compositor/meta-window-content.c',
+ 'compositor/meta-window-content-private.h',
'compositor/meta-window-group.c',
'compositor/meta-window-group-private.h',
'compositor/meta-window-shape.c',
diff --git a/src/meta/meson.build b/src/meta/meson.build
index 53c4723a2..853182606 100644
--- a/src/meta/meson.build
+++ b/src/meta/meson.build
@@ -29,6 +29,7 @@ mutter_public_headers = [
'meta-stage.h',
'meta-startup-notification.h',
'meta-window-actor.h',
+ 'meta-window-content.h',
'meta-window-group.h',
'meta-window-shape.h',
'meta-workspace-manager.h',
diff --git a/src/meta/meta-window-actor.h b/src/meta/meta-window-actor.h
index 55e2e7b27..ce80d8692 100644
--- a/src/meta/meta-window-actor.h
+++ b/src/meta/meta-window-actor.h
@@ -52,6 +52,9 @@ void meta_window_actor_sync_visibility (MetaWindowActor *self
META_EXPORT
gboolean meta_window_actor_is_destroyed (MetaWindowActor *self);
+META_EXPORT
+ClutterContent * meta_window_actor_get_content (MetaWindowActor *self);
+
typedef enum {
META_SHADOW_MODE_AUTO,
META_SHADOW_MODE_FORCED_OFF,
diff --git a/src/meta/meta-window-content.h b/src/meta/meta-window-content.h
new file mode 100644
index 000000000..1acb6d87d
--- /dev/null
+++ b/src/meta/meta-window-content.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 Endless, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ * Georges Basile Stavracas Neto <gbsneto gnome org>
+ */
+
+#ifndef META_WINDOW_CONTENT_H
+#define META_WINDOW_CONTENT_H
+
+#include "meta/meta-window-actor.h"
+
+#define META_TYPE_WINDOW_CONTENT (meta_window_content_get_type())
+
+META_EXPORT
+G_DECLARE_FINAL_TYPE (MetaWindowContent,
+ meta_window_content,
+ META, WINDOW_CONTENT,
+ GObject)
+
+META_EXPORT
+MetaWindowActor * meta_window_content_get_window_actor (MetaWindowContent *window_content);
+
+#endif /* META_WINDOW_CONTENT_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]