[mutter/gbsneto/content-part2: 363/366] Add MetaWindowContent
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/content-part2: 363/366] Add MetaWindowContent
- Date: Thu, 17 Oct 2019 06:45:42 +0000 (UTC)
commit 6e487b879a9b67ef918f546c7faf401be810a5ec
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.
src/compositor/meta-shaped-texture-private.h | 5 +
src/compositor/meta-shaped-texture.c | 14 ++
src/compositor/meta-window-actor-x11.c | 3 +
src/compositor/meta-window-actor.c | 44 ++++-
src/compositor/meta-window-content-private.h | 31 +++
src/compositor/meta-window-content.c | 285 +++++++++++++++++++++++++++
src/meson.build | 2 +
src/meta/meson.build | 1 +
src/meta/meta-window-actor.h | 3 +
src/meta/meta-window-content.h | 39 ++++
10 files changed, 426 insertions(+), 1 deletion(-)
---
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index e96c6f8a8..87527e884 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -63,4 +63,9 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
int height,
cairo_rectangle_int_t *clip);
+void meta_shaped_texture_paint_node (MetaShapedTexture *stex,
+ ClutterPaintNode *root_node,
+ ClutterActorBox *box,
+ guchar opacity);
+
#endif
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 401aaadf7..29b70cfb0 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -1431,3 +1431,17 @@ meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex)
return stex->buffer_scale;
}
+
+void
+meta_shaped_texture_paint_node (MetaShapedTexture *stex,
+ ClutterPaintNode *root_node,
+ ClutterActorBox *box,
+ guchar opacity)
+{
+ g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
+
+ if (!stex->texture)
+ return;
+
+ do_paint_content (stex, root_node, stex->texture, box, opacity);
+}
diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c
index 8bf65351f..1c4a22554 100644
--- a/src/compositor/meta-window-actor-x11.c
+++ b/src/compositor/meta-window-actor-x11.c
@@ -1095,12 +1095,15 @@ meta_window_actor_x11_update_shape (MetaWindowActorX11 *actor_x11)
{
MetaSurfaceActor *surface =
meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
+ ClutterContent *content =
+ meta_window_actor_get_content (META_WINDOW_ACTOR (actor_x11));
actor_x11->needs_reshape = TRUE;
if (meta_window_actor_is_frozen (META_WINDOW_ACTOR (actor_x11)))
return;
+ clutter_content_invalidate_size (content);
clutter_actor_queue_redraw (CLUTTER_ACTOR (surface));
}
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 6e86424dc..6f5302376 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -32,6 +32,7 @@
#include "compositor/meta-surface-actor-x11.h"
#include "compositor/meta-surface-actor.h"
#include "compositor/meta-window-actor-private.h"
+#include "compositor/meta-window-content-private.h"
#include "core/boxes-private.h"
#include "core/window-private.h"
#include "meta/window.h"
@@ -55,6 +56,8 @@ typedef struct _MetaWindowActorPrivate
MetaSurfaceActor *surface;
+ MetaWindowContent *content;
+
int geometry_scale;
/*
@@ -94,6 +97,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum
{
PROP_META_WINDOW = 1,
+ PROP_CONTENT,
};
static void meta_window_actor_dispose (GObject *object);
@@ -207,6 +211,10 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
g_object_class_install_property (object_class,
PROP_META_WINDOW,
pspec);
+
+ g_object_class_override_property (object_class,
+ PROP_CONTENT,
+ "content");
}
static void
@@ -216,6 +224,7 @@ meta_window_actor_init (MetaWindowActor *self)
meta_window_actor_get_instance_private (self);
priv->geometry_scale = 1;
+ priv->content = meta_window_content_new (self);
}
static void
@@ -223,7 +232,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));
}
gboolean
@@ -315,6 +328,8 @@ meta_window_actor_real_assign_surface_actor (MetaWindowActor *self,
meta_surface_actor_set_frozen (priv->surface, TRUE);
else
meta_window_actor_sync_thawed_state (self);
+
+ clutter_content_invalidate (CLUTTER_CONTENT (priv->content));
}
void
@@ -389,6 +404,8 @@ meta_window_actor_dispose (GObject *object)
priv->disposed = TRUE;
+ g_clear_object (&priv->content);
+
meta_compositor_remove_window_actor (compositor, self);
g_clear_object (&priv->window);
@@ -415,6 +432,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",
@@ -438,6 +458,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;
@@ -485,6 +508,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
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..cd41b0e52
--- /dev/null
+++ b/src/compositor/meta-window-content.c
@@ -0,0 +1,285 @@
+/*
+ * 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 (ClutterContentInterface *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 scale_h,
+ float scale_v)
+{
+ MetaShapedTexture *stex;
+ ClutterActorBox box;
+ CoglTexture *texture;
+ uint8_t opacity;
+
+ stex = meta_surface_actor_get_texture (surface_actor);
+
+ if (!stex)
+ return;
+
+ texture = meta_shaped_texture_get_texture (stex);
+
+ 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 * scale_h;
+ box.x2 = box.x2 * scale_h;
+ box.y1 = box.y1 * scale_v;
+ box.y2 = box.y2 * scale_v;
+
+ meta_shaped_texture_paint_node (stex,
+ root_node,
+ &box,
+ opacity);
+}
+
+static void
+meta_window_content_paint_content (ClutterContent *content,
+ ClutterActor *actor,
+ ClutterPaintNode *node)
+{
+ MetaWindowContent *window_content = META_WINDOW_CONTENT (content);
+ ClutterActor *window_actor = CLUTTER_ACTOR (window_content->window_actor);
+ ClutterActor *child;
+ 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));
+
+ /* Horizontal and vertical scales */
+ clutter_actor_get_size (window_actor, &width, &height);
+ clutter_actor_get_size (actor, &dst_width, &dst_height);
+ scale_h = dst_width / width;
+ scale_v = dst_height / height;
+
+ for (child = clutter_actor_get_first_child (window_actor);
+ child != NULL;
+ child = clutter_actor_get_next_sibling (child))
+ {
+ if (!META_IS_SURFACE_ACTOR (child))
+ continue;
+
+ add_surface_paint_nodes (META_SURFACE_ACTOR (child),
+ actor, node,
+ 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);
+
+ clutter_actor_get_size (CLUTTER_ACTOR (window_content->window_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 (ClutterContentInterface *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 db63ed317..a2e07acc4 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -319,6 +319,8 @@ mutter_sources = [
'compositor/meta-window-actor-private.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 14caec58d..01c9b447d 100644
--- a/src/meta/meson.build
+++ b/src/meta/meson.build
@@ -32,6 +32,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 7d3b96e59..96cd1f11f 100644
--- a/src/meta/meta-window-actor.h
+++ b/src/meta/meta-window-actor.h
@@ -51,6 +51,9 @@ META_EXPORT
cairo_surface_t * meta_window_actor_get_image (MetaWindowActor *self,
cairo_rectangle_int_t *clip);
+META_EXPORT
+ClutterContent *meta_window_actor_get_content (MetaWindowActor *self);
+
typedef enum
{
META_SHADOW_MODE_AUTO,
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]