[mutter] compositor: Keep track of the top window actor on each view
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] compositor: Keep track of the top window actor on each view
- Date: Mon, 1 Aug 2022 21:40:45 +0000 (UTC)
commit 85b8632cd65aecc4c3cb3de70772dcd7f01875e7
Author: Dor Askayo <dor askayo gmail com>
Date: Sat Jul 2 22:51:13 2022 +0300
compositor: Keep track of the top window actor on each view
First, add logic in MetaCompositorView to find topmost visible
MetaWindowActor on its view, and expose it through a new API.
Then, queue an update to find the top MetaWindowActor of each
MetaCompositorView in the following cases:
1. The MetaCompositor is in its initial state.
2. The window stack order has changed.
3. A window has changed its visibility.
4. A "stage-views-changed" signal was emitted for a MetaWindowActor.
Finally, perform the queued update in meta_compositor_before_paint (),
and assert that an update isn't queued during painting. This ensures
that the top window actor in the MetaCompositorView remains up-to-date
and available to child classes of MetaCompositor throughout the entire
paint stage.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2526>
src/compositor/compositor-private.h | 2 +
src/compositor/compositor.c | 57 +++++++++++++++++++++++++++++
src/compositor/meta-compositor-view.c | 69 +++++++++++++++++++++++++++++++++++
src/compositor/meta-compositor-view.h | 6 +++
src/compositor/meta-window-actor.c | 19 ++++++++++
5 files changed, 153 insertions(+)
---
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
index 6d62af8558..096373fbfb 100644
--- a/src/compositor/compositor-private.h
+++ b/src/compositor/compositor-private.h
@@ -43,6 +43,8 @@ gboolean meta_compositor_do_manage (MetaCompositor *compositor,
void meta_compositor_remove_window_actor (MetaCompositor *compositor,
MetaWindowActor *window_actor);
+void meta_compositor_window_actor_stage_views_changed (MetaCompositor *compositor);
+
void meta_switch_workspace_completed (MetaCompositor *compositor);
MetaPluginManager * meta_compositor_get_plugin_manager (MetaCompositor *compositor);
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 53db2df4a6..a32f7affa6 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -123,6 +123,8 @@ typedef struct _MetaCompositorPrivate
CoglContext *context;
+ gboolean needs_update_top_window_actors;
+
MetaWindowActor *top_window_actor;
gulong top_window_actor_destroy_id;
@@ -592,6 +594,23 @@ meta_compositor_window_opacity_changed (MetaCompositor *compositor,
meta_window_actor_update_opacity (window_actor);
}
+static void
+invalidate_top_window_actor_for_views (MetaCompositor *compositor)
+{
+ MetaCompositorPrivate *priv =
+ meta_compositor_get_instance_private (compositor);
+
+ g_assert (!priv->frame_in_progress);
+
+ priv->needs_update_top_window_actors = TRUE;
+}
+
+void
+meta_compositor_window_actor_stage_views_changed (MetaCompositor *compositor)
+{
+ invalidate_top_window_actor_for_views (compositor);
+}
+
gboolean
meta_compositor_filter_keybinding (MetaCompositor *compositor,
MetaKeyBinding *binding)
@@ -913,6 +932,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
sync_actor_stacking (compositor);
update_top_window_actor (compositor);
+ invalidate_top_window_actor_for_views (compositor);
}
void
@@ -931,6 +951,39 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
meta_plugin_manager_event_size_changed (priv->plugin_mgr, window_actor);
}
+static void
+maybe_update_top_window_actor_for_views (MetaCompositor *compositor)
+{
+ MetaCompositorPrivate *priv =
+ meta_compositor_get_instance_private (compositor);
+ ClutterStage *stage;
+ GList *l;
+
+ if (!priv->needs_update_top_window_actors)
+ return;
+
+ priv->needs_update_top_window_actors = FALSE;
+
+ COGL_TRACE_BEGIN_SCOPED (UpdateTopWindowActorForViews,
+ "Compositor (update top window actors)");
+
+ stage = CLUTTER_STAGE (meta_backend_get_stage (priv->backend));
+
+ for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
+ {
+ ClutterStageView *stage_view = l->data;
+ MetaCompositorView *compositor_view;
+
+ compositor_view = g_object_get_qdata (G_OBJECT (stage_view),
+ quark_compositor_view);
+
+ g_assert (compositor_view != NULL);
+
+ meta_compositor_view_update_top_window_actor (compositor_view,
+ priv->windows);
+ }
+}
+
static void
meta_compositor_ensure_compositor_views (MetaCompositor *compositor)
{
@@ -1011,6 +1064,8 @@ meta_compositor_before_paint (MetaCompositor *compositor,
COGL_TRACE_BEGIN_SCOPED (MetaCompositorPrePaint,
"Compositor (before-paint)");
+ maybe_update_top_window_actor_for_views (compositor);
+
priv->frame_in_progress = TRUE;
META_COMPOSITOR_GET_CLASS (compositor)->before_paint (compositor, compositor_view);
@@ -1116,6 +1171,7 @@ on_window_visibility_updated (MetaDisplay *display,
MetaCompositor *compositor)
{
update_top_window_actor (compositor);
+ invalidate_top_window_actor_for_views (compositor);
}
static void
@@ -1174,6 +1230,7 @@ meta_compositor_get_property (GObject *object,
static void
meta_compositor_init (MetaCompositor *compositor)
{
+ invalidate_top_window_actor_for_views (compositor);
}
static void
diff --git a/src/compositor/meta-compositor-view.c b/src/compositor/meta-compositor-view.c
index 5bc16de3bf..b95cec7e87 100644
--- a/src/compositor/meta-compositor-view.c
+++ b/src/compositor/meta-compositor-view.c
@@ -26,6 +26,10 @@
#include "compositor/meta-compositor-view.h"
+#include "core/window-private.h"
+#include "meta/boxes.h"
+#include "meta/window.h"
+
enum
{
PROP_0,
@@ -40,6 +44,8 @@ static GParamSpec *obj_props[N_PROPS];
typedef struct _MetaCompositorViewPrivate
{
ClutterStageView *stage_view;
+
+ MetaWindowActor *top_window_actor;
} MetaCompositorViewPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCompositorView, meta_compositor_view,
@@ -55,6 +61,58 @@ meta_compositor_view_new (ClutterStageView *stage_view)
NULL);
}
+static MetaWindowActor *
+find_top_window_actor_on_view (ClutterStageView *stage_view,
+ GList *window_actors)
+{
+ GList *l;
+
+ for (l = g_list_last (window_actors); l; l = l->prev)
+ {
+ MetaWindowActor *window_actor = l->data;
+ MetaWindow *window =
+ meta_window_actor_get_meta_window (window_actor);
+ MetaRectangle buffer_rect;
+ MetaRectangle view_layout;
+
+ if (!window->visible_to_compositor)
+ continue;
+
+ meta_window_get_buffer_rect (window, &buffer_rect);
+ clutter_stage_view_get_layout (stage_view,
+ &view_layout);
+
+ if (meta_rectangle_overlap (&view_layout, &buffer_rect))
+ return window_actor;
+ }
+
+ return NULL;
+}
+
+void
+meta_compositor_view_update_top_window_actor (MetaCompositorView *compositor_view,
+ GList *window_actors)
+{
+ MetaCompositorViewPrivate *priv =
+ meta_compositor_view_get_instance_private (compositor_view);
+ MetaWindowActor *top_window_actor;
+
+ top_window_actor = find_top_window_actor_on_view (priv->stage_view,
+ window_actors);
+
+ g_set_weak_pointer (&priv->top_window_actor,
+ top_window_actor);
+}
+
+MetaWindowActor *
+meta_compositor_view_get_top_window_actor (MetaCompositorView *compositor_view)
+{
+ MetaCompositorViewPrivate *priv =
+ meta_compositor_view_get_instance_private (compositor_view);
+
+ return priv->top_window_actor;
+}
+
ClutterStageView *
meta_compositor_view_get_stage_view (MetaCompositorView *compositor_view)
{
@@ -104,6 +162,16 @@ meta_compositor_view_get_property (GObject *object,
}
}
+static void
+meta_compositor_view_finalize (GObject *object)
+{
+ MetaCompositorView *compositor_view = META_COMPOSITOR_VIEW (object);
+ MetaCompositorViewPrivate *priv =
+ meta_compositor_view_get_instance_private (compositor_view);
+
+ g_clear_weak_pointer (&priv->top_window_actor);
+}
+
static void
meta_compositor_view_class_init (MetaCompositorViewClass *klass)
{
@@ -111,6 +179,7 @@ meta_compositor_view_class_init (MetaCompositorViewClass *klass)
object_class->set_property = meta_compositor_view_set_property;
object_class->get_property = meta_compositor_view_get_property;
+ object_class->finalize = meta_compositor_view_finalize;
obj_props[PROP_STAGE_VIEW] =
g_param_spec_object ("stage-view",
diff --git a/src/compositor/meta-compositor-view.h b/src/compositor/meta-compositor-view.h
index bed3404f78..5588867fd7 100644
--- a/src/compositor/meta-compositor-view.h
+++ b/src/compositor/meta-compositor-view.h
@@ -28,6 +28,7 @@
#include <glib-object.h>
#include "clutter/clutter-mutter.h"
+#include "meta/meta-window-actor.h"
struct _MetaCompositorViewClass
{
@@ -40,6 +41,11 @@ G_DECLARE_FINAL_TYPE (MetaCompositorView, meta_compositor_view,
MetaCompositorView *meta_compositor_view_new (ClutterStageView *stage_view);
+void meta_compositor_view_update_top_window_actor (MetaCompositorView *compositor_view,
+ GList *window_actors);
+
+MetaWindowActor *meta_compositor_view_get_top_window_actor (MetaCompositorView *compositor_view);
+
ClutterStageView *meta_compositor_view_get_stage_view (MetaCompositorView *compositor_view);
#endif /* META_COMPOSITOR_VIEW_H */
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index ae1fa4d903..9fd9f758c6 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -53,6 +53,8 @@ typedef struct _MetaWindowActorPrivate
MetaWindow *window;
MetaCompositor *compositor;
+ gulong stage_views_changed_id;
+
MetaSurfaceActor *surface;
int geometry_scale;
@@ -402,6 +404,15 @@ init_surface_actor (MetaWindowActor *self)
meta_window_actor_assign_surface_actor (self, surface_actor);
}
+static void
+on_stage_views_changed (MetaWindowActor *self)
+{
+ MetaWindowActorPrivate *priv =
+ meta_window_actor_get_instance_private (self);
+
+ meta_compositor_window_actor_stage_views_changed (priv->compositor);
+}
+
static void
meta_window_actor_constructed (GObject *object)
{
@@ -412,6 +423,12 @@ meta_window_actor_constructed (GObject *object)
priv->compositor = window->display->compositor;
+ priv->stage_views_changed_id =
+ g_signal_connect (self,
+ "stage-views-changed",
+ G_CALLBACK (on_stage_views_changed),
+ NULL);
+
/* Hang our compositor window state off the MetaWindow for fast retrieval */
meta_window_set_compositor_private (window, object);
@@ -445,6 +462,8 @@ meta_window_actor_dispose (GObject *object)
priv->disposed = TRUE;
+ g_clear_signal_handler (&priv->stage_views_changed_id, self);
+
meta_compositor_remove_window_actor (compositor, self);
g_clear_object (&priv->window);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]