mirror of
https://github.com/elementary/gala.git
synced 2024-11-27 15:45:31 +03:00
implement smooth (un)maximize, may have some small offsets currently
This commit is contained in:
parent
5fa4764c98
commit
481da2cc71
@ -224,6 +224,38 @@ namespace Gala
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an actor showing the current contents of the given WindowActor.
|
||||
*
|
||||
* @param actor The actor from which to create a shnapshot
|
||||
* @param inner_rect The inner (actually visible) rectangle of the window
|
||||
* @param outer_rect The outer (input region) rectangle of the window
|
||||
*/
|
||||
public static Clutter.Actor get_window_actor_snapshot (Meta.WindowActor actor, Meta.Rectangle inner_rect, Meta.Rectangle outer_rect)
|
||||
{
|
||||
var surface = ((Meta.ShapedTexture) actor.get_texture ()).get_image ({
|
||||
inner_rect.x - outer_rect.x,
|
||||
inner_rect.y - outer_rect.y,
|
||||
inner_rect.width,
|
||||
inner_rect.height
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ring the system bell, will most likely emit a <beep> error sound or, if the
|
||||
* audible bell is disabled, flash the screen
|
||||
|
@ -36,7 +36,15 @@ namespace Gala
|
||||
|
||||
if (window.on_all_workspaces)
|
||||
instance.listen_on_window (window);
|
||||
|
||||
if (window.window_type == WindowType.NORMAL)
|
||||
instance.monitor_window (window);
|
||||
}
|
||||
|
||||
screen.get_display ().window_created.connect ((window) => {
|
||||
if (window.window_type == WindowType.NORMAL)
|
||||
instance.monitor_window (window);
|
||||
});
|
||||
}
|
||||
|
||||
public static WindowListener get_default ()
|
||||
@ -47,11 +55,14 @@ namespace Gala
|
||||
|
||||
public signal void window_no_longer_on_all_workspaces (Window window);
|
||||
|
||||
Gee.List<Window> listened_windows;
|
||||
public Meta.Rectangle last_maximized_window_frame_rect;
|
||||
public Meta.Rectangle last_maximized_window_buffer_rect;
|
||||
|
||||
Gee.List<Window> listened_windows_sticky;
|
||||
|
||||
WindowListener ()
|
||||
{
|
||||
listened_windows = new Gee.LinkedList<Window> ();
|
||||
listened_windows_sticky = new Gee.LinkedList<Window> ();
|
||||
}
|
||||
|
||||
public void listen_on_window (Window window)
|
||||
@ -62,7 +73,7 @@ namespace Gala
|
||||
window.notify["on-all-workspaces"].connect (window_on_all_workspaces_changed);
|
||||
window.unmanaged.connect (window_removed);
|
||||
|
||||
listened_windows.add (window);
|
||||
listened_windows_sticky.add (window);
|
||||
}
|
||||
|
||||
void window_on_all_workspaces_changed (Object object, ParamSpec param)
|
||||
@ -73,15 +84,46 @@ namespace Gala
|
||||
return;
|
||||
|
||||
window.notify.disconnect (window_on_all_workspaces_changed);
|
||||
window.unmanaged.disconnect (window_removed);
|
||||
listened_windows.remove (window);
|
||||
window.unmanaged.disconnect (sticky_window_removed);
|
||||
listened_windows_sticky.remove (window);
|
||||
|
||||
window_no_longer_on_all_workspaces (window);
|
||||
}
|
||||
|
||||
void monitor_window (Window window)
|
||||
{
|
||||
window.notify["maximized-horizontally"].connect (window_maximized_changed);
|
||||
window.notify["maximized-vertically"].connect (window_maximized_changed);
|
||||
window.unmanaged.connect (window_removed);
|
||||
}
|
||||
|
||||
void window_maximized_changed (Object object, ParamSpec pspec)
|
||||
{
|
||||
var window = (Window) object;
|
||||
|
||||
#if HAS_MUTTER312
|
||||
last_maximized_window_frame_rect = window.get_frame_rect ();
|
||||
#else
|
||||
last_maximized_window_frame_rect = window.get_outer_rect ();
|
||||
#endif
|
||||
|
||||
#if HAS_MUTTER314
|
||||
last_maximized_window_buffer_rect = window.get_buffer_rect ();
|
||||
#else
|
||||
last_maximized_window_buffer_rect = window.get_input_rect ();
|
||||
#endif
|
||||
}
|
||||
|
||||
void window_removed (Window window)
|
||||
{
|
||||
listened_windows.remove (window);
|
||||
window.notify["maximized-horizontally"].disconnect (window_maximized_changed);
|
||||
window.notify["maximized-vertically"].disconnect (window_maximized_changed);
|
||||
window.unmanaged.disconnect (window_removed);
|
||||
}
|
||||
|
||||
void sticky_window_removed (Window window)
|
||||
{
|
||||
listened_windows_sticky.remove (window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -727,42 +727,52 @@ namespace Gala
|
||||
}
|
||||
}
|
||||
|
||||
//stolen from original mutter plugin
|
||||
public override void maximize (WindowActor actor, int ex, int ey, int ew, int eh)
|
||||
{
|
||||
float x, y, width, height;
|
||||
actor.get_size (out width, out height);
|
||||
actor.get_position (out x, out y);
|
||||
var duration = AnimationSettings.get_default ().snap_duration;
|
||||
|
||||
if (!AnimationSettings.get_default ().enable_animations ||
|
||||
AnimationSettings.get_default ().snap_duration == 0 ||
|
||||
(x == ex && y == ey && ew == width && eh == height)) {
|
||||
if (!AnimationSettings.get_default ().enable_animations || duration == 0) {
|
||||
maximize_completed (actor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (actor.get_meta_window ().window_type == WindowType.NORMAL) {
|
||||
maximizing.add (actor);
|
||||
var old_inner_rect = WindowListener.get_default ().last_maximized_window_frame_rect;
|
||||
var old_outer_rect = WindowListener.get_default ().last_maximized_window_buffer_rect;
|
||||
var old_actor = Utils.get_window_actor_snapshot (actor, old_inner_rect, old_outer_rect);
|
||||
|
||||
float scale_x = (float)ew / width;
|
||||
float scale_y = (float)eh / height;
|
||||
float anchor_x = (float)(x - ex) * width / (ew - width);
|
||||
float anchor_y = (float)(y - ey) * height / (eh - height);
|
||||
old_actor.set_position (old_inner_rect.x, old_inner_rect.y);
|
||||
|
||||
//reset the actor's anchors
|
||||
actor.scale_gravity = actor.anchor_gravity = Clutter.Gravity.NORTH_WEST;
|
||||
ui_group.add_child (old_actor);
|
||||
|
||||
actor.move_anchor_point (anchor_x, anchor_y);
|
||||
actor.animate (Clutter.AnimationMode.EASE_IN_OUT_SINE, AnimationSettings.get_default ().snap_duration,
|
||||
scale_x:scale_x, scale_y:scale_y).get_timeline ().completed.connect ( () => {
|
||||
var scale_x = (double) ew / old_inner_rect.width;
|
||||
var scale_y = (double) eh / old_inner_rect.height;
|
||||
|
||||
actor.anchor_gravity = Clutter.Gravity.NORTH_WEST;
|
||||
actor.set_scale (1.0, 1.0);
|
||||
old_actor.animate (Clutter.AnimationMode.EASE_IN_OUT_QUAD, duration,
|
||||
x: (float) ex,
|
||||
y: (float) ey,
|
||||
opacity: 0,
|
||||
scale_x: scale_x,
|
||||
scale_y: scale_y).completed.connect (() => {
|
||||
old_actor.destroy ();
|
||||
|
||||
maximizing.remove (actor);
|
||||
maximize_completed (actor);
|
||||
actor.translation_x = 0;
|
||||
actor.translation_y = 0;
|
||||
});
|
||||
|
||||
maximize_completed (actor);
|
||||
actor.scale_gravity = Clutter.Gravity.NORTH_WEST;
|
||||
actor.translation_x = old_inner_rect.x - ex;
|
||||
actor.translation_y = old_inner_rect.y - ey;
|
||||
actor.scale_x = 1.0 / scale_x;
|
||||
actor.scale_y = 1.0 / scale_y;
|
||||
|
||||
actor.animate (Clutter.AnimationMode.EASE_IN_OUT_QUAD, duration,
|
||||
scale_x: 1.0,
|
||||
scale_y: 1.0,
|
||||
translation_x: 0.0f,
|
||||
translation_y: 0.0f);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -974,34 +984,46 @@ namespace Gala
|
||||
|
||||
public override void unmaximize (Meta.WindowActor actor, int ex, int ey, int ew, int eh)
|
||||
{
|
||||
if (!AnimationSettings.get_default ().enable_animations || AnimationSettings.get_default ().snap_duration == 0) {
|
||||
var duration = AnimationSettings.get_default ().snap_duration;
|
||||
|
||||
if (!AnimationSettings.get_default ().enable_animations || duration == 0) {
|
||||
unmaximize_completed (actor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (actor.get_meta_window ().window_type == WindowType.NORMAL) {
|
||||
unmaximizing.add (actor);
|
||||
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);
|
||||
|
||||
float x, y, width, height;
|
||||
actor.get_size (out width, out height);
|
||||
actor.get_position (out x, out y);
|
||||
old_actor.set_position (old_rect.x, old_rect.y);
|
||||
|
||||
float scale_x = (float)ew / width;
|
||||
float scale_y = (float)eh / height;
|
||||
float anchor_x = (float)(x - ex) * width / (ew - width);
|
||||
float anchor_y = (float)(y - ey) * height / (eh - height);
|
||||
ui_group.add_child (old_actor);
|
||||
|
||||
actor.move_anchor_point (anchor_x, anchor_y);
|
||||
actor.animate (Clutter.AnimationMode.EASE_IN_OUT_SINE, AnimationSettings.get_default ().snap_duration,
|
||||
scale_x:scale_x, scale_y:scale_y).completed.connect ( () => {
|
||||
actor.move_anchor_point_from_gravity (Clutter.Gravity.NORTH_WEST);
|
||||
actor.animate (Clutter.AnimationMode.LINEAR, 1, scale_x:1.0f,
|
||||
scale_y:1.0f);//just scaling didnt want to work..
|
||||
var scale_x = (double) ew / old_rect.width;
|
||||
var scale_y = (double) eh / old_rect.height;
|
||||
|
||||
unmaximizing.remove (actor);
|
||||
unmaximize_completed (actor);
|
||||
old_actor.animate (Clutter.AnimationMode.EASE_IN_OUT_QUAD, duration,
|
||||
x: (float) ex,
|
||||
y: (float) ey,
|
||||
opacity: 0,
|
||||
scale_x: scale_x,
|
||||
scale_y: scale_y).completed.connect (() => {
|
||||
old_actor.destroy ();
|
||||
});
|
||||
|
||||
unmaximize_completed (actor);
|
||||
actor.scale_gravity = Clutter.Gravity.NORTH_WEST;
|
||||
actor.translation_x = -actor.x;
|
||||
actor.translation_y = -actor.y;
|
||||
actor.scale_x = 1.0 / scale_x;
|
||||
actor.scale_y = 1.0 / scale_y;
|
||||
|
||||
actor.animate (Clutter.AnimationMode.EASE_IN_OUT_QUAD, duration,
|
||||
scale_x: 1.0,
|
||||
scale_y: 1.0,
|
||||
translation_x: 0.0,
|
||||
translation_y: 0.0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user