
There is literally zero reasons nowadays to still provide the tango color palette as part of the Clutter API. End users of Mutter can define the colors on their side if they want to. The change simplifies https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3544 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3588>
819 lines
24 KiB
C
819 lines
24 KiB
C
/*
|
|
* Copyright (c) 2008 Intel Corp.
|
|
* Copyright (c) 2023 Red Hat
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "tests/meta-test-shell.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "clutter/clutter.h"
|
|
#include "meta/meta-backend.h"
|
|
#include "meta/meta-background-actor.h"
|
|
#include "meta/meta-background-content.h"
|
|
#include "meta/meta-background-group.h"
|
|
#include "meta/meta-context.h"
|
|
#include "meta/meta-monitor-manager.h"
|
|
#include "meta/meta-plugin.h"
|
|
#include "meta/util.h"
|
|
#include "meta/window.h"
|
|
|
|
typedef enum
|
|
{
|
|
ANIMATION_DESTROY,
|
|
ANIMATION_MINIMIZE,
|
|
ANIMATION_MAP,
|
|
ANIMATION_SWITCH,
|
|
} Animation;
|
|
|
|
static unsigned int animation_durations[] = {
|
|
100, /* destroy */
|
|
250, /* minimize */
|
|
250, /* map */
|
|
500, /* switch */
|
|
};
|
|
|
|
#define ACTOR_DATA_KEY "-test-shell-actor-data"
|
|
#define DISPLAY_TILE_PREVIEW_DATA_KEY "-test-shell-display-tile-preview-data"
|
|
|
|
struct _MetaTestShell
|
|
{
|
|
MetaPlugin parent;
|
|
|
|
ClutterTimeline *switch_workspace1_timeline;
|
|
ClutterTimeline *switch_workspace2_timeline;
|
|
ClutterActor *desktop1;
|
|
ClutterActor *desktop2;
|
|
|
|
ClutterActor *background_group;
|
|
|
|
MetaPluginInfo info;
|
|
|
|
struct {
|
|
ClutterGrab *grab;
|
|
ClutterActor *prev_focus;
|
|
} overview;
|
|
};
|
|
|
|
typedef struct _ActorPrivate
|
|
{
|
|
ClutterActor *orig_parent;
|
|
|
|
ClutterTimeline *minimize_timeline;
|
|
ClutterTimeline *destroy_timeline;
|
|
ClutterTimeline *map_timeline;
|
|
|
|
guint minimize_stopped_id;
|
|
} ActorPrivate;
|
|
|
|
typedef struct
|
|
{
|
|
ClutterActor *actor;
|
|
MetaPlugin *plugin;
|
|
gpointer effect_data;
|
|
} EffectCompleteData;
|
|
|
|
typedef struct _DisplayTilePreview
|
|
{
|
|
ClutterActor *actor;
|
|
|
|
MtkRectangle tile_rect;
|
|
} DisplayTilePreview;
|
|
|
|
G_DEFINE_TYPE (MetaTestShell, meta_test_shell, META_TYPE_PLUGIN)
|
|
|
|
static GQuark actor_data_quark = 0;
|
|
static GQuark display_tile_preview_data_quark = 0;
|
|
|
|
static void
|
|
free_actor_private (gpointer data)
|
|
{
|
|
ActorPrivate *actor_priv = data;
|
|
|
|
g_clear_handle_id (&actor_priv->minimize_stopped_id, g_source_remove);
|
|
g_free (data);
|
|
}
|
|
|
|
static ActorPrivate *
|
|
get_actor_private (MetaWindowActor *actor)
|
|
{
|
|
ActorPrivate *actor_priv = g_object_get_qdata (G_OBJECT (actor), actor_data_quark);
|
|
|
|
if (G_UNLIKELY (actor_data_quark == 0))
|
|
actor_data_quark = g_quark_from_static_string (ACTOR_DATA_KEY);
|
|
|
|
if (G_UNLIKELY (!actor_priv))
|
|
{
|
|
actor_priv = g_new0 (ActorPrivate, 1);
|
|
|
|
g_object_set_qdata_full (G_OBJECT (actor),
|
|
actor_data_quark, actor_priv,
|
|
free_actor_private);
|
|
}
|
|
|
|
return actor_priv;
|
|
}
|
|
|
|
static gboolean
|
|
is_animations_disabled (void)
|
|
{
|
|
static gboolean is_animations_disabled_set;
|
|
static gboolean is_animations_disabled;
|
|
|
|
if (!is_animations_disabled_set)
|
|
{
|
|
if (g_strcmp0 (getenv ("MUTTER_DEBUG_DISABLE_ANIMATIONS"), "1") == 0)
|
|
is_animations_disabled = TRUE;
|
|
else
|
|
is_animations_disabled = FALSE;
|
|
|
|
is_animations_disabled_set = TRUE;
|
|
}
|
|
|
|
return is_animations_disabled;
|
|
}
|
|
|
|
static unsigned int
|
|
get_animation_duration (Animation animation)
|
|
{
|
|
if (is_animations_disabled ())
|
|
return 0;
|
|
|
|
return animation_durations[animation];
|
|
}
|
|
|
|
static ClutterTimeline *
|
|
actor_animate (ClutterActor *actor,
|
|
ClutterAnimationMode mode,
|
|
Animation animation,
|
|
const char *first_property,
|
|
...)
|
|
{
|
|
va_list args;
|
|
ClutterTransition *transition;
|
|
|
|
clutter_actor_save_easing_state (actor);
|
|
clutter_actor_set_easing_mode (actor, mode);
|
|
clutter_actor_set_easing_duration (actor, get_animation_duration (animation));
|
|
|
|
va_start (args, first_property);
|
|
g_object_set_valist (G_OBJECT (actor), first_property, args);
|
|
va_end (args);
|
|
|
|
transition = clutter_actor_get_transition (actor, first_property);
|
|
|
|
clutter_actor_restore_easing_state (actor);
|
|
|
|
return CLUTTER_TIMELINE (transition);
|
|
}
|
|
|
|
static void
|
|
finish_timeline (ClutterTimeline *timeline)
|
|
{
|
|
g_object_ref (timeline);
|
|
clutter_timeline_stop (timeline);
|
|
g_object_unref (timeline);
|
|
}
|
|
|
|
static void
|
|
kill_workspace_switch_animation (MetaTestShell *test_shell)
|
|
{
|
|
if (test_shell->switch_workspace1_timeline)
|
|
{
|
|
g_autoptr (ClutterTimeline) timeline1 = NULL;
|
|
g_autoptr (ClutterTimeline) timeline2 = NULL;
|
|
|
|
timeline1 = g_object_ref (test_shell->switch_workspace1_timeline);
|
|
timeline2 = g_object_ref (test_shell->switch_workspace2_timeline);
|
|
|
|
finish_timeline (timeline1);
|
|
finish_timeline (timeline2);
|
|
}
|
|
}
|
|
|
|
static void
|
|
on_switch_workspace_effect_stopped (ClutterTimeline *timeline,
|
|
gboolean is_finished,
|
|
gpointer data)
|
|
{
|
|
MetaPlugin *plugin = META_PLUGIN (data);
|
|
MetaTestShell *test_shell = META_TEST_SHELL (plugin);
|
|
MetaDisplay *display = meta_plugin_get_display (plugin);
|
|
GList *l = meta_get_window_actors (display);
|
|
|
|
while (l)
|
|
{
|
|
ClutterActor *a = l->data;
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (a);
|
|
ActorPrivate *actor_priv = get_actor_private (window_actor);
|
|
|
|
if (actor_priv->orig_parent)
|
|
{
|
|
g_object_ref (a);
|
|
clutter_actor_remove_child (clutter_actor_get_parent (a), a);
|
|
clutter_actor_add_child (actor_priv->orig_parent, a);
|
|
g_object_unref (a);
|
|
actor_priv->orig_parent = NULL;
|
|
}
|
|
|
|
l = l->next;
|
|
}
|
|
|
|
clutter_actor_destroy (test_shell->desktop1);
|
|
clutter_actor_destroy (test_shell->desktop2);
|
|
|
|
test_shell->switch_workspace1_timeline = NULL;
|
|
test_shell->switch_workspace2_timeline = NULL;
|
|
test_shell->desktop1 = NULL;
|
|
test_shell->desktop2 = NULL;
|
|
|
|
meta_plugin_switch_workspace_completed (plugin);
|
|
}
|
|
|
|
static void
|
|
on_monitors_changed (MetaMonitorManager *monitor_manager,
|
|
MetaPlugin *plugin)
|
|
{
|
|
MetaTestShell *test_shell = META_TEST_SHELL (plugin);
|
|
MetaDisplay *display = meta_plugin_get_display (plugin);
|
|
GRand *rand;
|
|
int i, n;
|
|
|
|
rand = g_rand_new_with_seed (123456);
|
|
clutter_actor_destroy_all_children (test_shell->background_group);
|
|
|
|
n = meta_display_get_n_monitors (display);
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
MetaBackgroundContent *background_content;
|
|
ClutterContent *content;
|
|
MtkRectangle rect;
|
|
ClutterActor *background_actor;
|
|
MetaBackground *background;
|
|
uint8_t red;
|
|
uint8_t green;
|
|
uint8_t blue;
|
|
ClutterColor color;
|
|
|
|
meta_display_get_monitor_geometry (display, i, &rect);
|
|
|
|
background_actor = meta_background_actor_new (display, i);
|
|
content = clutter_actor_get_content (background_actor);
|
|
background_content = META_BACKGROUND_CONTENT (content);
|
|
|
|
clutter_actor_set_position (background_actor, rect.x, rect.y);
|
|
clutter_actor_set_size (background_actor, rect.width, rect.height);
|
|
|
|
blue = g_rand_int_range (rand, 0, 255);
|
|
green = g_rand_int_range (rand, 0, 255);
|
|
red = g_rand_int_range (rand, 0, 255);
|
|
clutter_color_init (&color, red, green, blue, 255);
|
|
|
|
background = meta_background_new (display);
|
|
meta_background_set_color (background, &color);
|
|
meta_background_content_set_background (background_content, background);
|
|
g_object_unref (background);
|
|
|
|
meta_background_content_set_vignette (background_content, TRUE, 0.5, 0.5);
|
|
|
|
clutter_actor_add_child (test_shell->background_group, background_actor);
|
|
}
|
|
|
|
g_rand_free (rand);
|
|
}
|
|
|
|
static void
|
|
on_overlay_key (MetaDisplay *display,
|
|
MetaTestShell *test_shell)
|
|
{
|
|
MetaContext *context = meta_display_get_context (display);
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
|
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
|
|
|
if (!test_shell->overview.grab)
|
|
{
|
|
test_shell->overview.grab = clutter_stage_grab (stage, CLUTTER_ACTOR (stage));
|
|
test_shell->overview.prev_focus = clutter_stage_get_key_focus (stage);
|
|
clutter_stage_set_key_focus (stage, CLUTTER_ACTOR (stage));
|
|
}
|
|
else
|
|
{
|
|
g_clear_pointer (&test_shell->overview.grab, clutter_grab_dismiss);
|
|
clutter_stage_set_key_focus (stage,
|
|
g_steal_pointer (&test_shell->overview.prev_focus));
|
|
}
|
|
}
|
|
|
|
static void
|
|
prepare_shutdown (MetaBackend *backend,
|
|
MetaTestShell *test_shell)
|
|
{
|
|
kill_workspace_switch_animation (test_shell);
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_start (MetaPlugin *plugin)
|
|
{
|
|
MetaTestShell *test_shell = META_TEST_SHELL (plugin);
|
|
MetaDisplay *display = meta_plugin_get_display (plugin);
|
|
MetaContext *context = meta_display_get_context (display);
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
|
MetaMonitorManager *monitor_manager =
|
|
meta_backend_get_monitor_manager (backend);
|
|
|
|
test_shell->background_group = meta_background_group_new ();
|
|
clutter_actor_insert_child_below (meta_get_window_group_for_display (display),
|
|
test_shell->background_group, NULL);
|
|
|
|
g_signal_connect (monitor_manager, "monitors-changed",
|
|
G_CALLBACK (on_monitors_changed), plugin);
|
|
on_monitors_changed (monitor_manager, plugin);
|
|
|
|
g_signal_connect (display, "overlay-key",
|
|
G_CALLBACK (on_overlay_key), plugin);
|
|
|
|
g_signal_connect (backend, "prepare-shutdown",
|
|
G_CALLBACK (prepare_shutdown),
|
|
test_shell);
|
|
|
|
clutter_actor_show (meta_get_stage_for_display (display));
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_switch_workspace (MetaPlugin *plugin,
|
|
int from,
|
|
int to,
|
|
MetaMotionDirection direction)
|
|
{
|
|
MetaTestShell *test_shell = META_TEST_SHELL (plugin);
|
|
MetaDisplay *display;
|
|
ClutterActor *stage;
|
|
ClutterActor *workspace1, *workspace2;
|
|
int screen_width, screen_height;
|
|
GList *l;
|
|
|
|
if (from == to)
|
|
{
|
|
meta_plugin_switch_workspace_completed (plugin);
|
|
return;
|
|
}
|
|
|
|
display = meta_plugin_get_display (plugin);
|
|
stage = meta_get_stage_for_display (display);
|
|
|
|
meta_display_get_size (display,
|
|
&screen_width,
|
|
&screen_height);
|
|
|
|
workspace1 = clutter_actor_new ();
|
|
workspace2 = clutter_actor_new ();
|
|
|
|
clutter_actor_set_pivot_point (workspace1, 1.0, 1.0);
|
|
clutter_actor_set_size (workspace1,
|
|
screen_width,
|
|
screen_height);
|
|
clutter_actor_set_size (workspace2,
|
|
screen_width,
|
|
screen_height);
|
|
|
|
clutter_actor_set_scale (workspace1, 0.0, 0.0);
|
|
|
|
clutter_actor_add_child (stage, workspace1);
|
|
clutter_actor_add_child (stage, workspace2);
|
|
|
|
for (l = g_list_last (meta_get_window_actors (display)); l; l = l->prev)
|
|
{
|
|
MetaWindowActor *window_actor = l->data;
|
|
ActorPrivate *actor_priv = get_actor_private (window_actor);
|
|
ClutterActor *actor = CLUTTER_ACTOR (window_actor);
|
|
MetaWindow *window;
|
|
MetaWorkspace *workspace;
|
|
int workspace_idx;
|
|
|
|
window = meta_window_actor_get_meta_window (window_actor);
|
|
workspace = meta_window_get_workspace (window);
|
|
|
|
if (!workspace)
|
|
{
|
|
clutter_actor_hide (actor);
|
|
actor_priv->orig_parent = NULL;
|
|
continue;
|
|
}
|
|
|
|
if (meta_window_is_on_all_workspaces (window))
|
|
{
|
|
actor_priv->orig_parent = NULL;
|
|
continue;
|
|
}
|
|
|
|
workspace_idx = meta_workspace_index (workspace);
|
|
|
|
if (workspace_idx == to || workspace_idx == from)
|
|
{
|
|
ClutterActor *parent = workspace_idx == to ? workspace1
|
|
: workspace2;
|
|
actor_priv->orig_parent = clutter_actor_get_parent (actor);
|
|
|
|
g_object_ref (actor);
|
|
clutter_actor_remove_child (clutter_actor_get_parent (actor),
|
|
actor);
|
|
clutter_actor_add_child (parent, actor);
|
|
clutter_actor_set_child_below_sibling (parent, actor, NULL);
|
|
g_object_unref (actor);
|
|
continue;
|
|
}
|
|
|
|
clutter_actor_hide (actor);
|
|
actor_priv->orig_parent = NULL;
|
|
}
|
|
|
|
test_shell->desktop1 = workspace1;
|
|
test_shell->desktop2 = workspace2;
|
|
|
|
test_shell->switch_workspace1_timeline =
|
|
actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
|
|
ANIMATION_SWITCH,
|
|
"scale-x", 1.0,
|
|
"scale-y", 1.0,
|
|
NULL);
|
|
g_signal_connect (test_shell->switch_workspace1_timeline,
|
|
"stopped",
|
|
G_CALLBACK (on_switch_workspace_effect_stopped),
|
|
plugin);
|
|
|
|
test_shell->switch_workspace2_timeline =
|
|
actor_animate (workspace2, CLUTTER_EASE_IN_SINE,
|
|
ANIMATION_SWITCH,
|
|
"scale-x", 0.0,
|
|
"scale-y", 0.0,
|
|
NULL);
|
|
}
|
|
|
|
static void
|
|
restore_scale_idle (gpointer user_data)
|
|
{
|
|
EffectCompleteData *data = user_data;
|
|
MetaPlugin *plugin = data->plugin;
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor);
|
|
double original_scale = *(double *) data->effect_data;
|
|
ActorPrivate *actor_priv;
|
|
|
|
actor_priv = get_actor_private (META_WINDOW_ACTOR (data->actor));
|
|
actor_priv->minimize_timeline = NULL;
|
|
actor_priv->minimize_stopped_id = 0;
|
|
|
|
clutter_actor_hide (data->actor);
|
|
|
|
clutter_actor_set_scale (data->actor, original_scale, original_scale);
|
|
|
|
meta_plugin_minimize_completed (plugin, window_actor);
|
|
|
|
g_free (data->effect_data);
|
|
g_free (data);
|
|
}
|
|
|
|
static void
|
|
on_minimize_effect_stopped (ClutterTimeline *timeline,
|
|
gboolean is_finished,
|
|
EffectCompleteData *data)
|
|
{
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor);
|
|
ActorPrivate *actor_priv = get_actor_private (window_actor);
|
|
|
|
actor_priv->minimize_stopped_id =
|
|
g_idle_add_once (restore_scale_idle, data);
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_minimize (MetaPlugin *plugin,
|
|
MetaWindowActor *window_actor)
|
|
{
|
|
MetaWindowType type;
|
|
MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
|
|
ClutterTimeline *timeline = NULL;
|
|
ClutterActor *actor = CLUTTER_ACTOR (window_actor);
|
|
|
|
type = meta_window_get_window_type (window);
|
|
|
|
if (type == META_WINDOW_NORMAL)
|
|
{
|
|
timeline = actor_animate (actor,
|
|
CLUTTER_EASE_IN_SINE,
|
|
ANIMATION_MINIMIZE,
|
|
"scale-x", 0.0,
|
|
"scale-y", 0.0,
|
|
"x", (double) 0,
|
|
"y", (double) 0,
|
|
NULL);
|
|
}
|
|
|
|
if (timeline)
|
|
{
|
|
EffectCompleteData *data;
|
|
ActorPrivate *actor_priv = get_actor_private (window_actor);
|
|
double scale_x, scale_y;
|
|
|
|
data = g_new0 (EffectCompleteData, 1);
|
|
actor_priv->minimize_timeline = timeline;
|
|
data->plugin = plugin;
|
|
data->actor = actor;
|
|
data->effect_data = g_new0 (double, 1);
|
|
clutter_actor_get_scale (actor, &scale_x, &scale_y);
|
|
g_assert (scale_x == scale_y);
|
|
*((double *) data->effect_data) = scale_x;
|
|
g_signal_connect (actor_priv->minimize_timeline, "stopped",
|
|
G_CALLBACK (on_minimize_effect_stopped),
|
|
data);
|
|
g_clear_handle_id (&actor_priv->minimize_stopped_id, g_source_remove);
|
|
}
|
|
else
|
|
{
|
|
meta_plugin_minimize_completed (plugin, window_actor);
|
|
}
|
|
}
|
|
|
|
static void
|
|
on_map_effect_stopped (ClutterTimeline *timeline,
|
|
gboolean is_finished,
|
|
EffectCompleteData *data)
|
|
{
|
|
MetaPlugin *plugin = data->plugin;
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor);
|
|
ActorPrivate *actor_priv = get_actor_private (window_actor);
|
|
|
|
actor_priv->map_timeline = NULL;
|
|
|
|
meta_plugin_map_completed (plugin, window_actor);
|
|
|
|
g_free (data);
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_map (MetaPlugin *plugin,
|
|
MetaWindowActor *window_actor)
|
|
{
|
|
ClutterActor *actor = CLUTTER_ACTOR (window_actor);
|
|
MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
|
|
MetaWindowType type;
|
|
|
|
type = meta_window_get_window_type (window);
|
|
|
|
if (type == META_WINDOW_NORMAL)
|
|
{
|
|
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
|
ActorPrivate *actor_priv = get_actor_private (window_actor);
|
|
|
|
clutter_actor_set_pivot_point (actor, 0.5, 0.5);
|
|
clutter_actor_set_opacity (actor, 0);
|
|
clutter_actor_set_scale (actor, 0.5, 0.5);
|
|
clutter_actor_show (actor);
|
|
|
|
actor_priv->map_timeline = actor_animate (actor,
|
|
CLUTTER_EASE_OUT_QUAD,
|
|
ANIMATION_MAP,
|
|
"opacity", 255,
|
|
"scale-x", 1.0,
|
|
"scale-y", 1.0,
|
|
NULL);
|
|
if (actor_priv->map_timeline)
|
|
{
|
|
data->actor = actor;
|
|
data->plugin = plugin;
|
|
g_signal_connect (actor_priv->map_timeline, "stopped",
|
|
G_CALLBACK (on_map_effect_stopped),
|
|
data);
|
|
}
|
|
else
|
|
{
|
|
g_free (data);
|
|
meta_plugin_map_completed (plugin, window_actor);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
meta_plugin_map_completed (plugin, window_actor);
|
|
}
|
|
}
|
|
|
|
static void
|
|
on_destroy_effect_stopped (ClutterTimeline *timeline,
|
|
gboolean is_finished,
|
|
EffectCompleteData *data)
|
|
{
|
|
MetaPlugin *plugin = data->plugin;
|
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor);
|
|
ActorPrivate *actor_priv = get_actor_private (window_actor);
|
|
|
|
actor_priv->destroy_timeline = NULL;
|
|
|
|
meta_plugin_destroy_completed (plugin, window_actor);
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_destroy (MetaPlugin *plugin,
|
|
MetaWindowActor *window_actor)
|
|
{
|
|
ClutterActor *actor = CLUTTER_ACTOR (window_actor);
|
|
MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
|
|
MetaWindowType type;
|
|
ClutterTimeline *timeline = NULL;
|
|
|
|
type = meta_window_get_window_type (window);
|
|
|
|
if (type == META_WINDOW_NORMAL)
|
|
{
|
|
timeline = actor_animate (actor,
|
|
CLUTTER_EASE_OUT_QUAD,
|
|
ANIMATION_DESTROY,
|
|
"opacity", 0,
|
|
"scale-x", 0.8,
|
|
"scale-y", 0.8,
|
|
NULL);
|
|
}
|
|
|
|
if (timeline)
|
|
{
|
|
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
|
ActorPrivate *actor_priv = get_actor_private (window_actor);
|
|
|
|
actor_priv->destroy_timeline = timeline;
|
|
data->plugin = plugin;
|
|
data->actor = actor;
|
|
g_signal_connect (actor_priv->destroy_timeline, "stopped",
|
|
G_CALLBACK (on_destroy_effect_stopped),
|
|
data);
|
|
}
|
|
else
|
|
{
|
|
meta_plugin_destroy_completed (plugin, window_actor);
|
|
}
|
|
}
|
|
|
|
static void
|
|
free_display_tile_preview (DisplayTilePreview *preview)
|
|
{
|
|
|
|
if (preview)
|
|
{
|
|
clutter_actor_destroy (preview->actor);
|
|
g_free (preview);
|
|
}
|
|
}
|
|
|
|
static void
|
|
on_display_closing (MetaDisplay *display,
|
|
DisplayTilePreview *preview)
|
|
{
|
|
free_display_tile_preview (preview);
|
|
}
|
|
|
|
static DisplayTilePreview *
|
|
get_display_tile_preview (MetaDisplay *display)
|
|
{
|
|
DisplayTilePreview *preview;
|
|
|
|
if (!display_tile_preview_data_quark)
|
|
{
|
|
display_tile_preview_data_quark =
|
|
g_quark_from_static_string (DISPLAY_TILE_PREVIEW_DATA_KEY);
|
|
}
|
|
|
|
preview = g_object_get_qdata (G_OBJECT (display),
|
|
display_tile_preview_data_quark);
|
|
if (!preview)
|
|
{
|
|
preview = g_new0 (DisplayTilePreview, 1);
|
|
|
|
preview->actor = clutter_actor_new ();
|
|
clutter_actor_set_background_color (preview->actor, &CLUTTER_COLOR_INIT (0, 0, 255, 255));
|
|
clutter_actor_set_opacity (preview->actor, 100);
|
|
|
|
clutter_actor_add_child (meta_get_window_group_for_display (display),
|
|
preview->actor);
|
|
g_signal_connect (display,
|
|
"closing",
|
|
G_CALLBACK (on_display_closing),
|
|
preview);
|
|
g_object_set_qdata (G_OBJECT (display),
|
|
display_tile_preview_data_quark,
|
|
preview);
|
|
}
|
|
|
|
return preview;
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_show_tile_preview (MetaPlugin *plugin,
|
|
MetaWindow *window,
|
|
MtkRectangle *tile_rect,
|
|
int tile_monitor_number)
|
|
{
|
|
MetaDisplay *display = meta_plugin_get_display (plugin);
|
|
DisplayTilePreview *preview = get_display_tile_preview (display);
|
|
ClutterActor *window_actor;
|
|
|
|
if (clutter_actor_is_visible (preview->actor) &&
|
|
preview->tile_rect.x == tile_rect->x &&
|
|
preview->tile_rect.y == tile_rect->y &&
|
|
preview->tile_rect.width == tile_rect->width &&
|
|
preview->tile_rect.height == tile_rect->height)
|
|
return;
|
|
|
|
clutter_actor_set_position (preview->actor, tile_rect->x, tile_rect->y);
|
|
clutter_actor_set_size (preview->actor, tile_rect->width, tile_rect->height);
|
|
|
|
clutter_actor_show (preview->actor);
|
|
|
|
window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
|
|
clutter_actor_set_child_below_sibling (clutter_actor_get_parent (preview->actor),
|
|
preview->actor,
|
|
window_actor);
|
|
|
|
preview->tile_rect = *tile_rect;
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_hide_tile_preview (MetaPlugin *plugin)
|
|
{
|
|
MetaDisplay *display = meta_plugin_get_display (plugin);
|
|
DisplayTilePreview *preview = get_display_tile_preview (display);
|
|
|
|
clutter_actor_hide (preview->actor);
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_kill_switch_workspace (MetaPlugin *plugin)
|
|
{
|
|
MetaTestShell *test_shell = META_TEST_SHELL (plugin);
|
|
|
|
kill_workspace_switch_animation (test_shell);
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_kill_window_effects (MetaPlugin *plugin,
|
|
MetaWindowActor *window_actor)
|
|
{
|
|
ActorPrivate *actor_priv;
|
|
|
|
actor_priv = get_actor_private (window_actor);
|
|
|
|
if (actor_priv->minimize_timeline)
|
|
finish_timeline (actor_priv->minimize_timeline);
|
|
|
|
if (actor_priv->map_timeline)
|
|
finish_timeline (actor_priv->map_timeline);
|
|
|
|
if (actor_priv->destroy_timeline)
|
|
finish_timeline (actor_priv->destroy_timeline);
|
|
}
|
|
|
|
static const MetaPluginInfo *
|
|
meta_test_shell_plugin_info (MetaPlugin *plugin)
|
|
{
|
|
MetaTestShell *test_shell = META_TEST_SHELL (plugin);
|
|
|
|
return &test_shell->info;
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_class_init (MetaTestShellClass *klass)
|
|
{
|
|
MetaPluginClass *plugin_class = META_PLUGIN_CLASS (klass);
|
|
|
|
plugin_class->start = meta_test_shell_start;
|
|
plugin_class->map = meta_test_shell_map;
|
|
plugin_class->minimize = meta_test_shell_minimize;
|
|
plugin_class->destroy = meta_test_shell_destroy;
|
|
plugin_class->switch_workspace = meta_test_shell_switch_workspace;
|
|
plugin_class->show_tile_preview = meta_test_shell_show_tile_preview;
|
|
plugin_class->hide_tile_preview = meta_test_shell_hide_tile_preview;
|
|
plugin_class->kill_window_effects = meta_test_shell_kill_window_effects;
|
|
plugin_class->kill_switch_workspace = meta_test_shell_kill_switch_workspace;
|
|
plugin_class->plugin_info = meta_test_shell_plugin_info;
|
|
}
|
|
|
|
static void
|
|
meta_test_shell_init (MetaTestShell *test_shell)
|
|
{
|
|
test_shell->info.name = "Test Shell";
|
|
test_shell->info.version = VERSION;
|
|
test_shell->info.author = "Mutter developers";
|
|
test_shell->info.license = "GPL";
|
|
test_shell->info.description = "This is test shell plugin implementation.";
|
|
}
|