229 lines
7.6 KiB
Diff
229 lines
7.6 KiB
Diff
From 7ea1746494f0b2e381fe8f08249f7751cd8ae578 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
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 <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <glib-object.h>
|
|
|
|
#include <clutter/clutter.h>
|
|
#include <clutter/x11/clutter-x11.h>
|
|
+#include <meta/common.h>
|
|
#include <meta/display.h>
|
|
#include <meta/main.h>
|
|
#include <meta/util.h>
|
|
+#include <meta/meta-window-group.h>
|
|
|
|
#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
|
|
|