summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mader <robert.mader@collabora.com>2023-02-11 07:03:43 +0100
committerFlorian Müllner <fmuellner@gnome.org>2023-04-25 14:21:58 +0000
commit42b121e3deb7a4bb09194ff97c980a6e2048e8e0 (patch)
tree5cf26fb5496c253ba3de34ec8e03821aa0653116
parent6e5b4ab661ab2c27d5ebdf00bf065a9dc9d305ad (diff)
downloadmutter-42b121e3deb7a4bb09194ff97c980a6e2048e8e0.tar.gz
surface-actor/wayland: Ensure screen-casted surfaces have a primary view
Surfaces belonging to a screen-casted window should always be considered visible even if they are not visible on any stage view - be it because they are on a different workspace, minimized or occluded. Doing this in an optimal fashion is highly complex right now - interdependent with (and somewhat similar to) ClutterClones. Thus treat stream-casted surfaces similar to those with clones, with the small difference that even a fully invisible surface still gets a primary view - the fastest one. This ensures that clients never refresh too slow for a screen-cast, at the cost of sometimes refreshing too fast. The later only happens on certain multi-monitor setups and should thus be acceptable. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2789> (cherry picked from commit 4409dd24b640ecf44d158e2d1ee6f23ee778ce4e)
-rw-r--r--src/compositor/meta-surface-actor-wayland.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index b8d354627..a9e5ea3d9 100644
--- a/src/compositor/meta-surface-actor-wayland.c
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -30,7 +30,9 @@
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
+#include "backends/meta-screen-cast-window.h"
#include "compositor/meta-shaped-texture-private.h"
+#include "compositor/meta-window-actor-private.h"
#include "compositor/region-utils.h"
#include "wayland/meta-wayland-buffer.h"
#include "wayland/meta-wayland-private.h"
@@ -74,15 +76,19 @@ meta_surface_actor_wayland_is_view_primary (MetaSurfaceActor *actor,
ClutterStageView *current_primary_view = NULL;
float highest_refresh_rate = 0.f;
float biggest_unobscurred_fraction = 0.f;
+ MetaWindowActor *window_actor;
+ gboolean is_streaming = FALSE;
GList *l;
- if (!clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
- stage_view))
- return FALSE;
+ window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (actor));
+ if (window_actor)
+ is_streaming = meta_window_actor_is_streaming (window_actor);
- if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)))
+ if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)) || is_streaming)
{
ClutterStage *stage;
+ ClutterStageView *fallback_view = NULL;
+ float fallback_refresh_rate = 0.0;
stage = CLUTTER_STAGE (clutter_actor_get_stage (CLUTTER_ACTOR (actor)));
for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
@@ -90,28 +96,42 @@ meta_surface_actor_wayland_is_view_primary (MetaSurfaceActor *actor,
ClutterStageView *view = l->data;
float refresh_rate;
- if (!clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
- view))
- continue;
-
refresh_rate = clutter_stage_view_get_refresh_rate (view);
- if (refresh_rate > highest_refresh_rate)
+
+ if (clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
+ view))
{
- current_primary_view = view;
- highest_refresh_rate = refresh_rate;
+ if (refresh_rate > highest_refresh_rate)
+ {
+ current_primary_view = view;
+ highest_refresh_rate = refresh_rate;
+ }
+ }
+ else
+ {
+ if (refresh_rate > fallback_refresh_rate)
+ {
+ fallback_view = view;
+ fallback_refresh_rate = refresh_rate;
+ }
}
}
- return current_primary_view == stage_view;
+ if (current_primary_view)
+ return current_primary_view == stage_view;
+ else if (is_streaming)
+ return fallback_view == stage_view;
}
l = clutter_actor_peek_stage_views (CLUTTER_ACTOR (actor));
- g_return_val_if_fail (l, FALSE);
+ if (!l)
+ return FALSE;
if (!l->next)
{
- g_return_val_if_fail (l->data == stage_view, FALSE);
- return !meta_surface_actor_is_obscured (actor);
+ return !meta_surface_actor_is_obscured_on_stage_view (actor,
+ stage_view,
+ NULL);
}
for (; l; l = l->next)