From 7ea1746494f0b2e381fe8f08249f7751cd8ae578 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 15 Apr 2021 13:00:16 -0400 Subject: [PATCH] compositor: Be less aggressive about full screening windows It's common for kiosk type applications to have dialogs and utility windows that shouldn't get fullscreen. This commit tries to be a little less aggressive above fullscreening windows. Now we assume only the first window is "the application" and subsequent windows are auxillary and should be layered on top. --- compositor/kiosk-compositor.c | 78 +++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/compositor/kiosk-compositor.c b/compositor/kiosk-compositor.c index b3cd10f..dad7776 100644 --- a/compositor/kiosk-compositor.c +++ b/compositor/kiosk-compositor.c @@ -1,43 +1,45 @@ #include "config.h" #include "kiosk-compositor.h" #include #include #include #include #include +#include #include #include #include +#include #include "kiosk-backgrounds.h" #include "kiosk-input-sources-manager.h" #include "kiosk-service.h" #include "org.gnome.DisplayManager.Manager.h" struct _KioskCompositor { MetaPlugin parent; /* weak references */ MetaDisplay *display; ClutterBackend *backend; ClutterActor *stage; /* strong references */ GCancellable *cancellable; KioskBackgrounds *backgrounds; KioskInputSourcesManager *input_sources_manager; KioskService *service; }; G_DEFINE_TYPE (KioskCompositor, kiosk_compositor, META_TYPE_PLUGIN) static void kiosk_compositor_dispose (GObject *object); static void kiosk_compositor_dispose (GObject *object) { @@ -143,91 +145,151 @@ static void kiosk_compositor_minimize (MetaPlugin *plugin, MetaWindowActor *actor) { meta_plugin_minimize_completed (plugin, actor); } static void kiosk_compositor_unminimize (MetaPlugin *plugin, MetaWindowActor *actor) { meta_plugin_unminimize_completed (plugin, actor); } static void kiosk_compositor_size_changed (MetaPlugin *plugin, MetaWindowActor *actor) { g_assert (META_PLUGIN_CLASS (kiosk_compositor_parent_class)->size_changed == NULL); } static void kiosk_compositor_size_change (MetaPlugin *plugin, MetaWindowActor *actor, MetaSizeChange which_change, MetaRectangle *old_frame_rect, MetaRectangle *old_buffer_rect) { g_assert (META_PLUGIN_CLASS (kiosk_compositor_parent_class)->size_change == NULL); } +static gboolean +kiosk_compositor_wants_window_fullscreen (KioskCompositor *self, + MetaWindow *window) +{ + MetaWindowType window_type; + g_autoptr (GList) windows = NULL; + GList *node; + + if (!meta_window_allows_resize (window)) { + g_debug ("KioskCompositor: Window does not allow resizes"); + return FALSE; + } + + if (meta_window_is_override_redirect (window)) { + g_debug ("KioskCompositor: Window is override redirect"); + return FALSE; + } + + window_type = meta_window_get_window_type (window); + + if (window_type != META_WINDOW_NORMAL) { + g_debug ("KioskCompositor: Window is not normal"); + return FALSE; + } + + windows = meta_display_get_tab_list (self->display, META_TAB_LIST_NORMAL_ALL, NULL); + + for (node = windows; node != NULL; node = node->next) { + MetaWindow *existing_window = node->data; + + if (meta_window_is_fullscreen (existing_window)) { + return FALSE; + } + } + + return TRUE; +} + +static gboolean +kiosk_compositor_wants_window_above (KioskCompositor *self, + MetaWindow *window) +{ + if (meta_window_is_screen_sized (window)) { + return FALSE; + } + + if (meta_window_is_monitor_sized (window)) { + return FALSE; + } + + return TRUE; +} + static void on_faded_in (KioskCompositor *self, ClutterTransition *transition) { MetaWindowActor *actor = g_object_get_data (G_OBJECT (transition), "actor"); - MetaWindow *window; - - window = meta_window_actor_get_meta_window (actor); - - if (!meta_window_allows_resize (window) && !meta_window_is_override_redirect (window)) { - meta_window_make_above (window); - } meta_plugin_map_completed (META_PLUGIN (self), actor); } static void kiosk_compositor_map (MetaPlugin *plugin, MetaWindowActor *actor) { KioskCompositor *self = KIOSK_COMPOSITOR (plugin); MetaWindow *window; ClutterTransition *fade_in_transition; int easing_duration; window = meta_window_actor_get_meta_window (actor); - if (meta_window_allows_resize (window)) { + if (kiosk_compositor_wants_window_fullscreen (self, window)) { + g_debug ("KioskCompositor: Mapping window that does need to be fullscreened"); meta_window_make_fullscreen (window); easing_duration = 3000; } else { + ClutterActor *window_group; + + g_debug ("KioskCompositor: Mapping window that does not need to be fullscreened"); + window_group = meta_get_top_window_group_for_display (self->display); + + if (kiosk_compositor_wants_window_above (self, window)) { + g_object_ref (G_OBJECT (actor)); + clutter_actor_remove_child (clutter_actor_get_parent (CLUTTER_ACTOR (actor)), CLUTTER_ACTOR (actor)); + clutter_actor_add_child (window_group, CLUTTER_ACTOR (actor)); + clutter_actor_set_child_below_sibling (window_group, CLUTTER_ACTOR (actor), NULL); + g_object_unref (G_OBJECT (actor)); + } + easing_duration = 500; } clutter_actor_show (self->stage); clutter_actor_show (CLUTTER_ACTOR (actor)); clutter_actor_set_opacity (CLUTTER_ACTOR (actor), 0); clutter_actor_save_easing_state (CLUTTER_ACTOR (actor)); clutter_actor_set_easing_duration (CLUTTER_ACTOR (actor), easing_duration); clutter_actor_set_easing_mode (CLUTTER_ACTOR (actor), CLUTTER_EASE_IN_OUT_QUINT); clutter_actor_set_opacity (CLUTTER_ACTOR (actor), 255); fade_in_transition = clutter_actor_get_transition (CLUTTER_ACTOR (actor), "opacity"); clutter_actor_restore_easing_state (CLUTTER_ACTOR (actor)); g_object_set_data (G_OBJECT (fade_in_transition), "actor", actor); g_signal_connect_object (G_OBJECT (fade_in_transition), "completed", G_CALLBACK (on_faded_in), self, G_CONNECT_SWAPPED); } static void kiosk_compositor_destroy (MetaPlugin *plugin, MetaWindowActor *actor) { KioskCompositor *self = KIOSK_COMPOSITOR (plugin); -- 2.31.1