diff --git a/data/gala.appdata.xml.in b/data/gala.appdata.xml.in
index 0392d5e8..091a706a 100644
--- a/data/gala.appdata.xml.in
+++ b/data/gala.appdata.xml.in
@@ -30,6 +30,8 @@
Duplicate "Plus" workspaces
Artifact around non native apps in the overview mode
"Not responding" dialog and not responding app close after inactivity
+ Unmaximize effect not working with mutter >= 3.38
+ Several (un-)maximize animations are not played
diff --git a/lib/Utils.vala b/lib/Utils.vala
index 6f108c32..8d85d07b 100644
--- a/lib/Utils.vala
+++ b/lib/Utils.vala
@@ -271,7 +271,7 @@ namespace Gala {
/**
* Creates an actor showing the current contents of the given WindowActor.
*
- * @param actor The actor from which to create a shnapshot
+ * @param actor The actor from which to create a snapshot
* @param inner_rect The inner (actually visible) rectangle of the window
* @param outer_rect The outer (input region) rectangle of the window
*
@@ -279,36 +279,20 @@ namespace Gala {
*/
public static Clutter.Actor? get_window_actor_snapshot (
Meta.WindowActor actor,
- Meta.Rectangle inner_rect,
- Meta.Rectangle outer_rect
+ Meta.Rectangle inner_rect
) {
- var texture = actor.get_texture () as Meta.ShapedTexture;
+ Clutter.Content content;
- if (texture == null)
+ try {
+ content = actor.paint_to_content (inner_rect);
+ } catch (Error e) {
+ warning ("Could not create window snapshot: %s", e.message);
return null;
-
- var surface = texture.get_image ({
- inner_rect.x - outer_rect.x,
- inner_rect.y - outer_rect.y,
- inner_rect.width,
- inner_rect.height
- });
-
- if (surface == null)
- return null;
-
- var canvas = new Clutter.Canvas ();
- var handler = canvas.draw.connect ((cr) => {
- cr.set_source_surface (surface, 0, 0);
- cr.paint ();
- return false;
- });
- canvas.set_size (inner_rect.width, inner_rect.height);
- SignalHandler.disconnect (canvas, handler);
+ }
var container = new Clutter.Actor ();
container.set_size (inner_rect.width, inner_rect.height);
- container.content = canvas;
+ container.content = content;
return container;
}
diff --git a/src/WindowManager.vala b/src/WindowManager.vala
index 83896e20..fdb422c8 100644
--- a/src/WindowManager.vala
+++ b/src/WindowManager.vala
@@ -104,6 +104,7 @@ namespace Gala {
private GLib.HashTable ws_assoc = new GLib.HashTable (direct_hash, direct_equal);
private Meta.SizeChange? which_change = null;
private Meta.Rectangle old_rect_size_change;
+ private Clutter.Actor latest_window_snapshot;
private GLib.Settings animations_settings;
private GLib.Settings behavior_settings;
@@ -1062,6 +1063,8 @@ namespace Gala {
public override void size_change (Meta.WindowActor actor, Meta.SizeChange which_change_local, Meta.Rectangle old_frame_rect, Meta.Rectangle old_buffer_rect) {
which_change = which_change_local;
old_rect_size_change = old_frame_rect;
+
+ latest_window_snapshot = Utils.get_window_actor_snapshot (actor, old_frame_rect);
}
// size_changed gets called after frame_rect has updated
@@ -1193,7 +1196,7 @@ namespace Gala {
var old_inner_rect = window_geometry != null ? window_geometry.inner : fallback;
var old_outer_rect = window_geometry != null ? window_geometry.outer : fallback;
- var old_actor = Utils.get_window_actor_snapshot (actor, old_inner_rect, old_outer_rect);
+ var old_actor = Utils.get_window_actor_snapshot (actor, old_inner_rect);
if (old_actor == null) {
return;
}
@@ -1586,41 +1589,40 @@ namespace Gala {
offset_height = 0;
}
- Meta.Rectangle old_rect = { (int) actor.x, (int) actor.y, (int) actor.width, (int) actor.height };
- var old_actor = Utils.get_window_actor_snapshot (actor, old_rect, old_rect);
-
- if (old_actor == null) {
+ if (latest_window_snapshot == null) {
return;
}
unmaximizing.add (actor);
- old_actor.set_position (old_rect.x, old_rect.y);
+ // FIXME: Gtk windows don't want to go out of bounds of screen when unmaximizing, so place them manually
+ // This is OS 7 (Mutter 42) specific, this was not needed in OS 6
+ window.move_frame (true, ex, ey);
- ui_group.add_child (old_actor);
+ latest_window_snapshot.set_position (old_rect_size_change.x, old_rect_size_change.y);
- var scale_x = (float) ew / old_rect.width;
- var scale_y = (float) eh / old_rect.height;
+ ui_group.add_child (latest_window_snapshot);
- old_actor.save_easing_state ();
- old_actor.set_easing_mode (Clutter.AnimationMode.EASE_IN_OUT_QUAD);
- old_actor.set_easing_duration (duration);
- old_actor.set_position (ex, ey);
- old_actor.set_scale (scale_x, scale_y);
- old_actor.opacity = 0U;
- old_actor.restore_easing_state ();
+ var scale_x = (float) ew / old_rect_size_change.width;
+ var scale_y = (float) eh / old_rect_size_change.height;
+
+ latest_window_snapshot.save_easing_state ();
+ latest_window_snapshot.set_easing_mode (Clutter.AnimationMode.EASE_IN_OUT_QUAD);
+ latest_window_snapshot.set_easing_duration (duration);
+ latest_window_snapshot.set_position (ex, ey);
+ latest_window_snapshot.set_scale (scale_x, scale_y);
+ latest_window_snapshot.opacity = 0U;
+ latest_window_snapshot.restore_easing_state ();
ulong unmaximize_old_handler_id = 0UL;
- unmaximize_old_handler_id = old_actor.transitions_completed.connect (() => {
- old_actor.disconnect (unmaximize_old_handler_id);
- old_actor.destroy ();
+ unmaximize_old_handler_id = latest_window_snapshot.transitions_completed.connect (() => {
+ latest_window_snapshot.disconnect (unmaximize_old_handler_id);
+ latest_window_snapshot.destroy ();
});
- var maximized_x = actor.x;
- var maximized_y = actor.y;
actor.set_pivot_point (0.0f, 0.0f);
actor.set_position (ex, ey);
- actor.set_translation (-ex + offset_x * (1.0f / scale_x - 1.0f) + maximized_x, -ey + offset_y * (1.0f / scale_y - 1.0f) + maximized_y, 0.0f);
+ actor.set_translation (-ex + offset_x * (1.0f / scale_x - 1.0f) + old_rect_size_change.x, -ey + offset_y * (1.0f / scale_y - 1.0f) + old_rect_size_change.y, 0.0f);
actor.set_scale (1.0f / scale_x, 1.0f / scale_y);
actor.save_easing_state ();