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>
This commit is contained in:
parent
2ead3874f5
commit
85b8632cd6
5 changed files with 153 additions and 0 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue