mirror of
https://github.com/elementary/gala.git
synced 2024-11-30 19:27:01 +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;
|
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
|
* Ring the system bell, will most likely emit a <beep> error sound or, if the
|
||||||
* audible bell is disabled, flash the screen
|
* audible bell is disabled, flash the screen
|
||||||
|
@ -36,7 +36,15 @@ namespace Gala
|
|||||||
|
|
||||||
if (window.on_all_workspaces)
|
if (window.on_all_workspaces)
|
||||||
instance.listen_on_window (window);
|
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 ()
|
public static WindowListener get_default ()
|
||||||
@ -47,11 +55,14 @@ namespace Gala
|
|||||||
|
|
||||||
public signal void window_no_longer_on_all_workspaces (Window window);
|
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 ()
|
WindowListener ()
|
||||||
{
|
{
|
||||||
listened_windows = new Gee.LinkedList<Window> ();
|
listened_windows_sticky = new Gee.LinkedList<Window> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void listen_on_window (Window 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.notify["on-all-workspaces"].connect (window_on_all_workspaces_changed);
|
||||||
window.unmanaged.connect (window_removed);
|
window.unmanaged.connect (window_removed);
|
||||||
|
|
||||||
listened_windows.add (window);
|
listened_windows_sticky.add (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_on_all_workspaces_changed (Object object, ParamSpec param)
|
void window_on_all_workspaces_changed (Object object, ParamSpec param)
|
||||||
@ -73,15 +84,46 @@ namespace Gala
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
window.notify.disconnect (window_on_all_workspaces_changed);
|
window.notify.disconnect (window_on_all_workspaces_changed);
|
||||||
window.unmanaged.disconnect (window_removed);
|
window.unmanaged.disconnect (sticky_window_removed);
|
||||||
listened_windows.remove (window);
|
listened_windows_sticky.remove (window);
|
||||||
|
|
||||||
window_no_longer_on_all_workspaces (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)
|
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)
|
public override void maximize (WindowActor actor, int ex, int ey, int ew, int eh)
|
||||||
{
|
{
|
||||||
float x, y, width, height;
|
var duration = AnimationSettings.get_default ().snap_duration;
|
||||||
actor.get_size (out width, out height);
|
|
||||||
actor.get_position (out x, out y);
|
|
||||||
|
|
||||||
if (!AnimationSettings.get_default ().enable_animations ||
|
if (!AnimationSettings.get_default ().enable_animations || duration == 0) {
|
||||||
AnimationSettings.get_default ().snap_duration == 0 ||
|
|
||||||
(x == ex && y == ey && ew == width && eh == height)) {
|
|
||||||
maximize_completed (actor);
|
maximize_completed (actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor.get_meta_window ().window_type == WindowType.NORMAL) {
|
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;
|
old_actor.set_position (old_inner_rect.x, old_inner_rect.y);
|
||||||
float scale_y = (float)eh / height;
|
|
||||||
float anchor_x = (float)(x - ex) * width / (ew - width);
|
|
||||||
float anchor_y = (float)(y - ey) * height / (eh - height);
|
|
||||||
|
|
||||||
//reset the actor's anchors
|
ui_group.add_child (old_actor);
|
||||||
actor.scale_gravity = actor.anchor_gravity = Clutter.Gravity.NORTH_WEST;
|
|
||||||
|
|
||||||
actor.move_anchor_point (anchor_x, anchor_y);
|
var scale_x = (double) ew / old_inner_rect.width;
|
||||||
actor.animate (Clutter.AnimationMode.EASE_IN_OUT_SINE, AnimationSettings.get_default ().snap_duration,
|
var scale_y = (double) eh / old_inner_rect.height;
|
||||||
scale_x:scale_x, scale_y:scale_y).get_timeline ().completed.connect ( () => {
|
|
||||||
|
|
||||||
actor.anchor_gravity = Clutter.Gravity.NORTH_WEST;
|
old_actor.animate (Clutter.AnimationMode.EASE_IN_OUT_QUAD, duration,
|
||||||
actor.set_scale (1.0, 1.0);
|
x: (float) ex,
|
||||||
|
y: (float) ey,
|
||||||
|
opacity: 0,
|
||||||
|
scale_x: scale_x,
|
||||||
|
scale_y: scale_y).completed.connect (() => {
|
||||||
|
old_actor.destroy ();
|
||||||
|
|
||||||
maximizing.remove (actor);
|
actor.translation_x = 0;
|
||||||
maximize_completed (actor);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,34 +984,46 @@ namespace Gala
|
|||||||
|
|
||||||
public override void unmaximize (Meta.WindowActor actor, int ex, int ey, int ew, int eh)
|
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);
|
unmaximize_completed (actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor.get_meta_window ().window_type == WindowType.NORMAL) {
|
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;
|
old_actor.set_position (old_rect.x, old_rect.y);
|
||||||
actor.get_size (out width, out height);
|
|
||||||
actor.get_position (out x, out y);
|
|
||||||
|
|
||||||
float scale_x = (float)ew / width;
|
ui_group.add_child (old_actor);
|
||||||
float scale_y = (float)eh / height;
|
|
||||||
float anchor_x = (float)(x - ex) * width / (ew - width);
|
|
||||||
float anchor_y = (float)(y - ey) * height / (eh - height);
|
|
||||||
|
|
||||||
actor.move_anchor_point (anchor_x, anchor_y);
|
var scale_x = (double) ew / old_rect.width;
|
||||||
actor.animate (Clutter.AnimationMode.EASE_IN_OUT_SINE, AnimationSettings.get_default ().snap_duration,
|
var scale_y = (double) eh / old_rect.height;
|
||||||
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..
|
|
||||||
|
|
||||||
unmaximizing.remove (actor);
|
old_actor.animate (Clutter.AnimationMode.EASE_IN_OUT_QUAD, duration,
|
||||||
unmaximize_completed (actor);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user