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
@ -43,6 +43,8 @@ gboolean meta_compositor_do_manage (MetaCompositor *compositor,
|
|||||||
void meta_compositor_remove_window_actor (MetaCompositor *compositor,
|
void meta_compositor_remove_window_actor (MetaCompositor *compositor,
|
||||||
MetaWindowActor *window_actor);
|
MetaWindowActor *window_actor);
|
||||||
|
|
||||||
|
void meta_compositor_window_actor_stage_views_changed (MetaCompositor *compositor);
|
||||||
|
|
||||||
void meta_switch_workspace_completed (MetaCompositor *compositor);
|
void meta_switch_workspace_completed (MetaCompositor *compositor);
|
||||||
|
|
||||||
MetaPluginManager * meta_compositor_get_plugin_manager (MetaCompositor *compositor);
|
MetaPluginManager * meta_compositor_get_plugin_manager (MetaCompositor *compositor);
|
||||||
|
@ -123,6 +123,8 @@ typedef struct _MetaCompositorPrivate
|
|||||||
|
|
||||||
CoglContext *context;
|
CoglContext *context;
|
||||||
|
|
||||||
|
gboolean needs_update_top_window_actors;
|
||||||
|
|
||||||
MetaWindowActor *top_window_actor;
|
MetaWindowActor *top_window_actor;
|
||||||
gulong top_window_actor_destroy_id;
|
gulong top_window_actor_destroy_id;
|
||||||
|
|
||||||
@ -592,6 +594,23 @@ meta_compositor_window_opacity_changed (MetaCompositor *compositor,
|
|||||||
meta_window_actor_update_opacity (window_actor);
|
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
|
gboolean
|
||||||
meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
||||||
MetaKeyBinding *binding)
|
MetaKeyBinding *binding)
|
||||||
@ -913,6 +932,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
|
|||||||
sync_actor_stacking (compositor);
|
sync_actor_stacking (compositor);
|
||||||
|
|
||||||
update_top_window_actor (compositor);
|
update_top_window_actor (compositor);
|
||||||
|
invalidate_top_window_actor_for_views (compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -931,6 +951,39 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
|||||||
meta_plugin_manager_event_size_changed (priv->plugin_mgr, window_actor);
|
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
|
static void
|
||||||
meta_compositor_ensure_compositor_views (MetaCompositor *compositor)
|
meta_compositor_ensure_compositor_views (MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
@ -1011,6 +1064,8 @@ meta_compositor_before_paint (MetaCompositor *compositor,
|
|||||||
COGL_TRACE_BEGIN_SCOPED (MetaCompositorPrePaint,
|
COGL_TRACE_BEGIN_SCOPED (MetaCompositorPrePaint,
|
||||||
"Compositor (before-paint)");
|
"Compositor (before-paint)");
|
||||||
|
|
||||||
|
maybe_update_top_window_actor_for_views (compositor);
|
||||||
|
|
||||||
priv->frame_in_progress = TRUE;
|
priv->frame_in_progress = TRUE;
|
||||||
|
|
||||||
META_COMPOSITOR_GET_CLASS (compositor)->before_paint (compositor, compositor_view);
|
META_COMPOSITOR_GET_CLASS (compositor)->before_paint (compositor, compositor_view);
|
||||||
@ -1116,6 +1171,7 @@ on_window_visibility_updated (MetaDisplay *display,
|
|||||||
MetaCompositor *compositor)
|
MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
update_top_window_actor (compositor);
|
update_top_window_actor (compositor);
|
||||||
|
invalidate_top_window_actor_for_views (compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1174,6 +1230,7 @@ meta_compositor_get_property (GObject *object,
|
|||||||
static void
|
static void
|
||||||
meta_compositor_init (MetaCompositor *compositor)
|
meta_compositor_init (MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
|
invalidate_top_window_actor_for_views (compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
|
|
||||||
#include "compositor/meta-compositor-view.h"
|
#include "compositor/meta-compositor-view.h"
|
||||||
|
|
||||||
|
#include "core/window-private.h"
|
||||||
|
#include "meta/boxes.h"
|
||||||
|
#include "meta/window.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -40,6 +44,8 @@ static GParamSpec *obj_props[N_PROPS];
|
|||||||
typedef struct _MetaCompositorViewPrivate
|
typedef struct _MetaCompositorViewPrivate
|
||||||
{
|
{
|
||||||
ClutterStageView *stage_view;
|
ClutterStageView *stage_view;
|
||||||
|
|
||||||
|
MetaWindowActor *top_window_actor;
|
||||||
} MetaCompositorViewPrivate;
|
} MetaCompositorViewPrivate;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCompositorView, meta_compositor_view,
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaCompositorView, meta_compositor_view,
|
||||||
@ -55,6 +61,58 @@ meta_compositor_view_new (ClutterStageView *stage_view)
|
|||||||
NULL);
|
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 *
|
ClutterStageView *
|
||||||
meta_compositor_view_get_stage_view (MetaCompositorView *compositor_view)
|
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
|
static void
|
||||||
meta_compositor_view_class_init (MetaCompositorViewClass *klass)
|
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->set_property = meta_compositor_view_set_property;
|
||||||
object_class->get_property = meta_compositor_view_get_property;
|
object_class->get_property = meta_compositor_view_get_property;
|
||||||
|
object_class->finalize = meta_compositor_view_finalize;
|
||||||
|
|
||||||
obj_props[PROP_STAGE_VIEW] =
|
obj_props[PROP_STAGE_VIEW] =
|
||||||
g_param_spec_object ("stage-view",
|
g_param_spec_object ("stage-view",
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#include "clutter/clutter-mutter.h"
|
#include "clutter/clutter-mutter.h"
|
||||||
|
#include "meta/meta-window-actor.h"
|
||||||
|
|
||||||
struct _MetaCompositorViewClass
|
struct _MetaCompositorViewClass
|
||||||
{
|
{
|
||||||
@ -40,6 +41,11 @@ G_DECLARE_FINAL_TYPE (MetaCompositorView, meta_compositor_view,
|
|||||||
|
|
||||||
MetaCompositorView *meta_compositor_view_new (ClutterStageView *stage_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);
|
ClutterStageView *meta_compositor_view_get_stage_view (MetaCompositorView *compositor_view);
|
||||||
|
|
||||||
#endif /* META_COMPOSITOR_VIEW_H */
|
#endif /* META_COMPOSITOR_VIEW_H */
|
||||||
|
@ -53,6 +53,8 @@ typedef struct _MetaWindowActorPrivate
|
|||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MetaCompositor *compositor;
|
MetaCompositor *compositor;
|
||||||
|
|
||||||
|
gulong stage_views_changed_id;
|
||||||
|
|
||||||
MetaSurfaceActor *surface;
|
MetaSurfaceActor *surface;
|
||||||
|
|
||||||
int geometry_scale;
|
int geometry_scale;
|
||||||
@ -402,6 +404,15 @@ init_surface_actor (MetaWindowActor *self)
|
|||||||
meta_window_actor_assign_surface_actor (self, surface_actor);
|
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
|
static void
|
||||||
meta_window_actor_constructed (GObject *object)
|
meta_window_actor_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
@ -412,6 +423,12 @@ meta_window_actor_constructed (GObject *object)
|
|||||||
|
|
||||||
priv->compositor = window->display->compositor;
|
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 */
|
/* Hang our compositor window state off the MetaWindow for fast retrieval */
|
||||||
meta_window_set_compositor_private (window, object);
|
meta_window_set_compositor_private (window, object);
|
||||||
|
|
||||||
@ -445,6 +462,8 @@ meta_window_actor_dispose (GObject *object)
|
|||||||
|
|
||||||
priv->disposed = TRUE;
|
priv->disposed = TRUE;
|
||||||
|
|
||||||
|
g_clear_signal_handler (&priv->stage_views_changed_id, self);
|
||||||
|
|
||||||
meta_compositor_remove_window_actor (compositor, self);
|
meta_compositor_remove_window_actor (compositor, self);
|
||||||
|
|
||||||
g_clear_object (&priv->window);
|
g_clear_object (&priv->window);
|
||||||
|
Loading…
Reference in New Issue
Block a user