Skip to content

Commit 3f76365

Browse files
authored
Support wlr-layer-shell-protocol. (#803)
Extracted from #784 This is primarily to enable nemo-desktop and csd-background as to run as gtk-layer-shell clients and integrates their windows into the compositor stage. Immediate benefits: - csd-background can run as a wayland client (currently uses xwayland), and its surfaces can be cloned 'for free' to be re-used in Cinnamon's screensaver, alt-tab, expo modes. - nemo-desktop can run as a wayland client (also currently xwayland) and be automatically contained in a monitor's workarea without relying on Cinnamon to inform it. - Remove existing never-used background code. - Add new method to create per-monitor backgrounds. - Add new method to access stage background actors.
1 parent e521ee2 commit 3f76365

38 files changed

Lines changed: 2970 additions & 2919 deletions

clutter/clutter/cogl/clutter-stage-cogl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
595595
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION);
596596

597597
has_buffer_age =
598-
COGL_ONSCREEN (onscreen) &&
598+
cogl_is_onscreen (onscreen) &&
599599
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
600600

601601
redraw_clip = clutter_stage_view_take_redraw_clip (view);

debian/libmuffin0.symbols

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,29 +2054,8 @@ libmuffin.so.0 libmuffin0 #MINVER#
20542054
meta_backend_set_keymap@Base 5.3.0
20552055
meta_backend_set_numlock@Base 5.3.0
20562056
meta_backend_x11_nested_get_type@Base 5.3.0
2057-
meta_background_actor_get_type@Base 5.3.0
2058-
meta_background_actor_new@Base 5.3.0
2059-
meta_background_actor_set_background@Base 5.3.0
2060-
meta_background_actor_set_gradient@Base 5.3.0
2061-
meta_background_actor_set_monitor@Base 5.3.0
2062-
meta_background_actor_set_vignette@Base 5.3.0
2063-
meta_background_get_type@Base 5.3.0
2064-
meta_background_group_get_type@Base 5.3.0
2065-
meta_background_group_new@Base 5.3.0
2066-
meta_background_image_cache_get_default@Base 5.3.0
2067-
meta_background_image_cache_get_type@Base 5.3.0
2068-
meta_background_image_cache_load@Base 5.3.0
2069-
meta_background_image_cache_purge@Base 5.3.0
2070-
meta_background_image_get_success@Base 5.3.0
2071-
meta_background_image_get_texture@Base 5.3.0
2072-
meta_background_image_get_type@Base 5.3.0
2073-
meta_background_image_is_loaded@Base 5.3.0
2074-
meta_background_new@Base 5.3.0
2075-
meta_background_refresh_all@Base 5.3.0
2076-
meta_background_set_blend@Base 5.3.0
2077-
meta_background_set_color@Base 5.3.0
2078-
meta_background_set_file@Base 5.3.0
2079-
meta_background_set_gradient@Base 5.3.0
2057+
meta_create_background_for_monitor@Base 6.6.0
2058+
meta_get_background_actors_for_display@Base 6.6.0
20802059
meta_barrier_destroy@Base 5.3.0
20812060
meta_barrier_direction_get_type@Base 5.3.0
20822061
meta_barrier_event_get_type@Base 5.3.0
@@ -2593,6 +2572,8 @@ libmuffin.so.0 libmuffin0 #MINVER#
25932572
meta_virtual_modifier_get_type@Base 5.3.0
25942573
meta_warning@Base 5.3.0
25952574
meta_wayland_actor_surface_get_actor@Base 6.0.0
2575+
meta_wayland_background_actor_get_type@Base 6.6.0
2576+
meta_wayland_background_actor_new_for_monitor@Base 6.6.0
25962577
meta_wayland_compositor_get_default@Base 6.0.0
25972578
meta_wayland_get_wayland_display_name@Base 6.0.0
25982579
meta_wayland_get_xwayland_display_name@Base 6.0.0
@@ -2756,6 +2737,7 @@ libmuffin.so.0 libmuffin0 #MINVER#
27562737
meta_workspace_set_builtin_struts@Base 5.3.0
27572738
meta_x11_background_actor_get_type@Base 5.3.0
27582739
meta_x11_background_actor_new_for_display@Base 5.3.0
2740+
meta_x11_background_actor_new_for_monitor@Base 6.6.0
27592741
meta_x11_background_get_type@Base 5.3.0
27602742
meta_x11_background_transition_get_type@Base 5.3.0
27612743
meta_x11_display_clear_stage_input_region@Base 5.3.0

src/compositor/compositor.c

Lines changed: 205 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@
7474
#include "meta/compositor-muffin.h"
7575
#include "meta/main.h"
7676
#include "meta/meta-backend.h"
77-
#include "meta/meta-background-actor.h"
78-
#include "meta/meta-background-group.h"
77+
#include "meta/meta-monitor-manager.h"
7978
#include "meta/meta-shadow-factory.h"
8079
#include "meta/meta-x11-errors.h"
8180
#include "meta/meta-x11-background-actor.h"
@@ -85,6 +84,9 @@
8584

8685
#ifdef HAVE_WAYLAND
8786
#include "compositor/meta-window-actor-wayland.h"
87+
#include "meta/meta-wayland-background-actor.h"
88+
#include "wayland/meta-wayland-layer-shell.h"
89+
#include "wayland/meta-wayland-outputs.h"
8890
#include "wayland/meta-wayland-private.h"
8991
#endif
9092

@@ -127,7 +129,7 @@ typedef struct _MetaCompositorPrivate
127129
ClutterActor *feedback_group;
128130
ClutterActor *bottom_window_group;
129131

130-
ClutterActor *background_actor;
132+
GList *background_actors;
131133
ClutterActor *desklet_container;
132134

133135
GList *windows;
@@ -579,6 +581,123 @@ meta_compositor_redirect_x11_windows (MetaCompositor *compositor)
579581
redirect_windows (display->x11_display);
580582
}
581583

584+
static void
585+
rebuild_x11_background_actors (MetaCompositor *compositor)
586+
{
587+
MetaCompositorPrivate *priv =
588+
meta_compositor_get_instance_private (compositor);
589+
MetaDisplay *display = priv->display;
590+
int i, n;
591+
592+
g_list_free_full (priv->background_actors, (GDestroyNotify) clutter_actor_destroy);
593+
priv->background_actors = NULL;
594+
595+
n = meta_display_get_n_monitors (display);
596+
for (i = 0; i < n; i++)
597+
{
598+
ClutterActor *actor;
599+
MetaRectangle rect;
600+
601+
actor = meta_x11_background_actor_new_for_monitor (display, i);
602+
if (actor == NULL)
603+
continue;
604+
605+
meta_display_get_monitor_geometry (display, i, &rect);
606+
clutter_actor_set_position (actor, rect.x, rect.y);
607+
clutter_actor_set_size (actor, rect.width, rect.height);
608+
609+
clutter_actor_add_child (priv->window_group, actor);
610+
priv->background_actors = g_list_append (priv->background_actors, actor);
611+
}
612+
}
613+
614+
static void
615+
on_monitors_changed (MetaMonitorManager *monitor_manager,
616+
MetaCompositor *compositor)
617+
{
618+
if (!meta_is_wayland_compositor ())
619+
rebuild_x11_background_actors (compositor);
620+
}
621+
622+
#ifdef HAVE_WAYLAND
623+
static int
624+
get_monitor_index_for_layer_surface (MetaWaylandLayerSurface *layer_surface)
625+
{
626+
MetaWaylandCompositor *wl_compositor =
627+
meta_wayland_compositor_get_default ();
628+
MetaWaylandOutput *surface_output =
629+
meta_wayland_layer_surface_get_output (layer_surface);
630+
MetaDisplay *display = meta_get_display ();
631+
int i, n;
632+
633+
if (!surface_output)
634+
return -1;
635+
636+
n = meta_display_get_n_monitors (display);
637+
for (i = 0; i < n; i++)
638+
{
639+
MetaWaylandOutput *output =
640+
meta_wayland_compositor_get_output_for_monitor (wl_compositor, i);
641+
if (output == surface_output)
642+
return i;
643+
}
644+
645+
return -1;
646+
}
647+
648+
static void
649+
on_layer_surface_mapped (MetaWaylandLayerShell *layer_shell,
650+
MetaWaylandLayerSurface *layer_surface,
651+
MetaCompositor *compositor)
652+
{
653+
MetaCompositorPrivate *priv =
654+
meta_compositor_get_instance_private (compositor);
655+
MetaSurfaceActor *surface_actor;
656+
int monitor_index;
657+
658+
if (meta_wayland_layer_surface_get_layer (layer_surface) !=
659+
META_LAYER_SHELL_LAYER_BACKGROUND)
660+
return;
661+
662+
surface_actor = meta_wayland_actor_surface_get_actor (
663+
META_WAYLAND_ACTOR_SURFACE (layer_surface));
664+
if (!surface_actor)
665+
return;
666+
667+
monitor_index = get_monitor_index_for_layer_surface (layer_surface);
668+
669+
if (monitor_index < 0)
670+
{
671+
priv->background_actors =
672+
g_list_append (priv->background_actors, surface_actor);
673+
return;
674+
}
675+
676+
priv->background_actors =
677+
g_list_insert (priv->background_actors, surface_actor, monitor_index);
678+
}
679+
680+
static void
681+
on_layer_surface_unmapped (MetaWaylandLayerShell *layer_shell,
682+
MetaWaylandLayerSurface *layer_surface,
683+
MetaCompositor *compositor)
684+
{
685+
MetaCompositorPrivate *priv =
686+
meta_compositor_get_instance_private (compositor);
687+
MetaSurfaceActor *surface_actor;
688+
689+
if (meta_wayland_layer_surface_get_layer (layer_surface) !=
690+
META_LAYER_SHELL_LAYER_BACKGROUND)
691+
return;
692+
693+
surface_actor = meta_wayland_actor_surface_get_actor (
694+
META_WAYLAND_ACTOR_SURFACE (layer_surface));
695+
696+
priv->background_actors =
697+
g_list_remove (priv->background_actors, surface_actor);
698+
}
699+
#endif
700+
582701
gboolean
583702
meta_compositor_do_manage (MetaCompositor *compositor,
584703
GError **error)
@@ -615,14 +734,11 @@ meta_compositor_do_manage (MetaCompositor *compositor,
615734
priv->feedback_group = meta_window_group_new (display);
616735

617736
if (!meta_is_wayland_compositor ())
618-
{
619-
priv->background_actor = meta_x11_background_actor_new_for_display (display);
620-
clutter_actor_add_child (priv->window_group, priv->background_actor);
621-
}
737+
rebuild_x11_background_actors (compositor);
622738

623739
clutter_actor_add_child (priv->window_group, priv->bottom_window_group);
624740

625-
// This needs to remain stacked just above the background actor in the window group.
741+
// This needs to remain stacked just above the background actors in the window group.
626742
// So sync_actor_stacking() has to be able to reference it. The deskletManager
627743
// will take this and finish setting it up.
628744
priv->desklet_container = clutter_actor_new ();
@@ -634,6 +750,27 @@ meta_compositor_do_manage (MetaCompositor *compositor,
634750
if (!META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor, error))
635751
return FALSE;
636752

753+
g_signal_connect (meta_monitor_manager_get (), "monitors-changed",
754+
G_CALLBACK (on_monitors_changed), compositor);
755+
756+
#ifdef HAVE_WAYLAND
757+
if (meta_is_wayland_compositor ())
758+
{
759+
MetaWaylandCompositor *wl_compositor =
760+
meta_wayland_compositor_get_default ();
761+
MetaWaylandLayerShell *layer_shell =
762+
meta_wayland_compositor_get_layer_shell (wl_compositor);
763+
764+
if (layer_shell)
765+
{
766+
g_signal_connect (layer_shell, "layer-surface-mapped",
767+
G_CALLBACK (on_layer_surface_mapped), compositor);
768+
g_signal_connect (layer_shell, "layer-surface-unmapped",
769+
G_CALLBACK (on_layer_surface_unmapped), compositor);
770+
}
771+
}
772+
#endif
773+
637774
priv->plugin_mgr = meta_plugin_manager_new (compositor);
638775

639776
clutter_actor_show (priv->stage);
@@ -963,9 +1100,7 @@ sync_actor_stacking (MetaCompositor *compositor)
9631100
{
9641101
ClutterActor *actor = old->data;
9651102

966-
if (META_IS_BACKGROUND_GROUP (actor) ||
967-
META_IS_BACKGROUND_ACTOR (actor) ||
968-
META_IS_X11_BACKGROUND_ACTOR (actor))
1103+
if (META_IS_X11_BACKGROUND_ACTOR (actor))
9691104
{
9701105
backgrounds = g_list_prepend (backgrounds, actor);
9711106

@@ -1018,31 +1153,6 @@ sync_actor_stacking (MetaCompositor *compositor)
10181153
// Then the bottom window group (which META_WINDOW_DESKTOP windows like nemo-desktop's get placed in).
10191154
clutter_actor_set_child_below_sibling (priv->window_group, priv->bottom_window_group, NULL);
10201155

1021-
if (meta_is_wayland_compositor ())
1022-
{
1023-
children = clutter_actor_get_children (priv->bottom_window_group);
1024-
for (tmp = children; tmp != NULL; tmp = tmp->next)
1025-
{
1026-
MetaWindowActor *child = tmp->data;
1027-
MetaWindow *mw = meta_window_actor_get_meta_window (child);
1028-
1029-
if (mw != NULL)
1030-
{
1031-
// CsdBackground manager sets _NET_WM_STATE_BELOW (gtk_window_set_keep_below)
1032-
// This sets its stack layer to META_LAYER_BOTTOM, so we can keep these below
1033-
// the nemo-desktop, etc..
1034-
MetaStackLayer layer = meta_window_get_default_layer (mw);
1035-
1036-
if (layer == META_LAYER_BOTTOM)
1037-
{
1038-
clutter_actor_set_child_below_sibling (priv->bottom_window_group, CLUTTER_ACTOR (child), NULL);
1039-
}
1040-
}
1041-
}
1042-
1043-
g_list_free (children);
1044-
}
1045-
10461156
// and finally backgrounds..
10471157

10481158
/* we prepended the backgrounds above so the last actor in the list
@@ -1438,7 +1548,12 @@ meta_compositor_dispose (GObject *object)
14381548
g_clear_signal_handler (&priv->top_window_actor_destroy_id,
14391549
priv->top_window_actor);
14401550

1441-
g_clear_pointer (&priv->background_actor, clutter_actor_destroy);
1551+
if (!meta_is_wayland_compositor ())
1552+
{
1553+
for (GList *l = priv->background_actors; l; l = l->next)
1554+
clutter_actor_destroy (l->data);
1555+
}
1556+
g_clear_pointer (&priv->background_actors, g_list_free);
14421557
g_clear_pointer (&priv->bottom_window_group, clutter_actor_destroy);
14431558
g_clear_pointer (&priv->desklet_container, clutter_actor_destroy);
14441559
g_clear_pointer (&priv->window_group, clutter_actor_destroy);
@@ -1783,24 +1898,21 @@ meta_compositor_get_laters (MetaCompositor *compositor)
17831898
* meta_get_x11_background_actor_for_display:
17841899
* @display: a #MetaDisplay
17851900
*
1786-
* Gets the actor that draws the root window background under the windows.
1787-
* The root window background automatically tracks the image or color set
1788-
* by the environment.
1901+
* Deprecated. Returns the first per-monitor X11 background actor, or NULL.
1902+
* Use meta_get_background_actors_for_display() instead.
17891903
*
1790-
* Returns: (transfer none): The background actor corresponding to @display
1904+
* Returns: (transfer none) (nullable): A background actor, or NULL
17911905
*/
17921906
ClutterActor *
17931907
meta_get_x11_background_actor_for_display (MetaDisplay *display)
17941908
{
17951909
MetaCompositorPrivate *priv =
17961910
meta_compositor_get_instance_private (display->compositor);
17971911

1798-
if (meta_is_wayland_compositor ())
1799-
{
1800-
return NULL;
1801-
}
1912+
if (meta_is_wayland_compositor () || priv->background_actors == NULL)
1913+
return NULL;
18021914

1803-
return priv->background_actor;
1915+
return priv->background_actors->data;
18041916
}
18051917

18061918
/**
@@ -1853,3 +1965,50 @@ meta_update_desklet_stacking (MetaCompositor *compositor)
18531965

18541966
meta_stack_tracker_queue_sync_stack (priv->display->stack_tracker);
18551967
}
1968+
1969+
/**
1970+
* meta_create_background_for_monitor:
1971+
* @display: a #MetaDisplay
1972+
* @monitor: the monitor index
1973+
*
1974+
* Creates a new standalone actor that displays the desktop background for the
1975+
* given monitor. On X11, this returns a per-monitor root pixmap actor. On
1976+
* Wayland, this returns a monitor-sized clone of the layer-shell background
1977+
* surface.
1978+
*
1979+
* These are independent copies, not the live compositor background actors.
1980+
* Use meta_get_background_actors_for_display() to get the actual actors
1981+
* in the scene graph.
1982+
*
1983+
* Returns: (transfer full): The background actor for @monitor
1984+
*/
1985+
ClutterActor *
1986+
meta_create_background_for_monitor (MetaDisplay *display,
1987+
int monitor)
1988+
{
1989+
#ifdef HAVE_WAYLAND
1990+
if (meta_is_wayland_compositor ())
1991+
return meta_wayland_background_actor_new_for_monitor (display, monitor);
1992+
#endif
1993+
1994+
return g_object_ref_sink (meta_x11_background_actor_new_for_monitor (display, monitor));
1995+
}
1996+
1997+
/**
1998+
* meta_get_background_actors_for_display:
1999+
* @display: a #MetaDisplay
2000+
*
2001+
* Returns a list of the live per-monitor background actors in the compositor's
2002+
* scene graph. These actors can have effects applied to them directly.
2003+
*
2004+
* Returns: (transfer none) (element-type Clutter.Actor): The list of
2005+
* background actors
2006+
*/
2007+
GList *
2008+
meta_get_background_actors_for_display (MetaDisplay *display)
2009+
{
2010+
MetaCompositorPrivate *priv =
2011+
meta_compositor_get_instance_private (display->compositor);
2012+
2013+
return priv->background_actors;
2014+
}

0 commit comments

Comments
 (0)