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 ();