Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions lib/Drawing/StyleManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public class Gala.Drawing.StyleManager : Object {
LIGHT
}

public enum ReducedMotion {
NO_PREFERENCE,
REDUCE,
}

[DBus (name="org.freedesktop.Accounts")]
private interface Accounts : Object {
public abstract async string find_user_by_name (string name) throws IOError, DBusError;
Expand All @@ -28,8 +33,16 @@ public class Gala.Drawing.StyleManager : Object {
public abstract int accent_color { get; set; }
}

[DBus (name = "org.freedesktop.portal.Settings")]
interface Portal : Object {
public signal void setting_changed (string namespace, string key, Variant value);
public abstract async Variant read_one (string namespace, string key) throws DBusError, IOError;
}

private const string FDO_ACCOUNTS_NAME = "org.freedesktop.Accounts";
private const string FDO_ACCOUNTS_PATH = "/org/freedesktop/Accounts";
private const string PORTAL_NAME = "org.freedesktop.portal.Desktop";
private const string PORTAL_PATH = "/org/freedesktop/portal/desktop";
private const uint8 ACCENT_COLOR_ALPHA = 64;

private static GLib.Once<StyleManager> instance;
Expand All @@ -43,9 +56,11 @@ public class Gala.Drawing.StyleManager : Object {
#else
public Cogl.Color theme_accent_color { get; private set; default = { 0, 0, 0, ACCENT_COLOR_ALPHA }; }
#endif
public ReducedMotion reduced_motion { get; private set; default = NO_PREFERENCE; }

private PantheonAccountsService? pantheon_proxy;
private SettingsDaemonAccountsService? settings_daemon_proxy;
private Portal? portal_proxy;

construct {
Bus.watch_name (
Expand All @@ -56,6 +71,12 @@ public class Gala.Drawing.StyleManager : Object {
settings_daemon_proxy = null;
}
);

Bus.watch_name (
SESSION, PORTAL_NAME, NONE,
() => on_portal_appeared.begin (),
() => portal_proxy = null
);
}

private async void connect_to_accounts_service () {
Expand Down Expand Up @@ -141,4 +162,37 @@ public class Gala.Drawing.StyleManager : Object {

return 0;
}

private async void on_portal_appeared () {
try {
portal_proxy = yield Bus.get_proxy<Portal> (SESSION, PORTAL_NAME, PORTAL_PATH);
} catch (Error e) {
warning ("Could not connect to portal: %s", e.message);
return;
}

portal_proxy.setting_changed.connect (on_setting_changed);

try {
var variant = yield portal_proxy.read_one ("org.freedesktop.appearance", "reduced-motion");
reduced_motion = (ReducedMotion) variant.get_uint32 ();
} catch (Error e) {
warning ("Could not read reduced-motion setting from portal: %s", e.message);
}
}

private void on_setting_changed (string namespace, string key, Variant value) {
if (namespace != "org.freedesktop.appearance") {
return;
}

switch (key) {
case "reduced-motion":
reduced_motion = (ReducedMotion) value.get_uint32 ();
break;

default:
break;
}
}
}
2 changes: 1 addition & 1 deletion lib/Gestures/GestureController.vala
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ public class Gala.GestureController : Object {
return;
}

if (!Meta.Prefs.get_gnome_animations ()) {
if (!Meta.Prefs.get_gnome_animations () || Utils.should_reduce_motion ()) {
target.propagate (COMMIT, action, clamped_to);
progress = clamped_to;
finished ();
Expand Down
39 changes: 34 additions & 5 deletions lib/TransitionBuilder.vala
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,30 @@
*/

public class Gala.TransitionBuilder : Object {
public enum ReducedMotionBehavior {
/**
* Adding the transition will be ignored i.e. a no op.
* If you don't want the transition to run but still the final
* value to be applied, use {@link APPLY} instead.
*/
IGNORE,
/**
* The transition will not animate but the final value
* will be applied immediately.
*/
APPLY,
/**
* The transition will run normally.
*/
RUN,
}

public Clutter.Actor actor { private get; construct; }
public uint duration { private get; construct; }
public Clutter.AnimationMode animation_mode { private get; construct; }

private Clutter.TransitionGroup group;
private bool transition_added = false;

public TransitionBuilder (Clutter.Actor actor, uint duration, Clutter.AnimationMode animation_mode) {
Object (actor: actor, duration: duration, animation_mode: animation_mode);
Expand All @@ -23,14 +42,22 @@ public class Gala.TransitionBuilder : Object {
};
}

public void add_property (string name, Value to) {
public void add_property (string name, Value to, ReducedMotionBehavior reduced_motion_behavior) {
Value from = {};
actor.get_property (name, ref from);
add_property_with_from (name, from, to);
add_property_with_from (name, from, to, reduced_motion_behavior);
}

public void add_property_with_from (string name, Value from, Value to) requires (from.type () == to.type ()) {
if (!Meta.Prefs.get_gnome_animations ()) {
public void add_property_with_from (
string name, Value from, Value to, ReducedMotionBehavior reduced_motion_behavior
) requires (from.type () == to.type ()) {
var reduce_motion = Utils.should_reduce_motion ();

if (reduce_motion && reduced_motion_behavior == IGNORE) {
return;
}

if (!Meta.Prefs.get_gnome_animations () || (reduce_motion && reduced_motion_behavior == APPLY)) {
actor.set_property (name, to);
return;
}
Expand All @@ -46,6 +73,8 @@ public class Gala.TransitionBuilder : Object {
progress_mode = animation_mode,
};
group.add_transition (property_transition);

transition_added = true;
}

/**
Expand All @@ -54,7 +83,7 @@ public class Gala.TransitionBuilder : Object {
* the actor was destroyed or remove all transitions was called).
*/
public async bool run () {
if (!Meta.Prefs.get_gnome_animations ()) {
if (!transition_added) {
return true;
}

Expand Down
4 changes: 4 additions & 0 deletions lib/Utils.vala
Original file line number Diff line number Diff line change
Expand Up @@ -364,5 +364,9 @@ namespace Gala {
return display.get_monitor_scale (monitor_index);
}
}

public static bool should_reduce_motion () {
return Drawing.StyleManager.get_instance ().reduced_motion == REDUCE;
}
}
}
4 changes: 2 additions & 2 deletions src/Misc/DesktopIntegration.vala
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ public class Gala.DesktopIntegration : GLib.Object {
unowned var display = wm.get_display ();

#if HAS_MUTTER49
if (window.is_maximized () || !Meta.Prefs.get_gnome_animations ()) {
if (window.is_maximized () || !Meta.Prefs.get_gnome_animations () || Utils.should_reduce_motion ()) {
#else
if (window.get_maximized () == BOTH || !Meta.Prefs.get_gnome_animations ()) {
if (window.get_maximized () == BOTH || !Meta.Prefs.get_gnome_animations () || Utils.should_reduce_motion ()) {
#endif
// If user has "Flash screen" enabled, make sure to respect it when shake animation is not played
InternalUtils.bell_notify (display);
Expand Down
10 changes: 5 additions & 5 deletions src/Misc/NotificationStack.vala
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class Gala.NotificationStack : Object {
var window_rect = window.get_frame_rect ();
window.stick ();

if (Meta.Prefs.get_gnome_animations ()) {
if (Meta.Prefs.get_gnome_animations () && !Utils.should_reduce_motion ()) {
// Don't flicker at the beginning of the animation
notification.opacity = 0;
notification.rotation_angle_x = 90;
Expand Down Expand Up @@ -134,7 +134,7 @@ public class Gala.NotificationStack : Object {
continue;
}

if (Meta.Prefs.get_gnome_animations ()) {
if (Meta.Prefs.get_gnome_animations () && !Utils.should_reduce_motion ()) {
actor.save_easing_state ();
actor.set_easing_mode (Clutter.AnimationMode.EASE_OUT_BACK);
actor.set_easing_duration (200);
Expand All @@ -143,7 +143,7 @@ public class Gala.NotificationStack : Object {

move_window (actor, -1, (int)y);

if (Meta.Prefs.get_gnome_animations ()) {
if (Meta.Prefs.get_gnome_animations () && !Utils.should_reduce_motion ()) {
actor.restore_easing_state ();
}

Expand All @@ -168,8 +168,8 @@ public class Gala.NotificationStack : Object {
update_positions ();

var builder = new TransitionBuilder (notification, AnimationDuration.CLOSE, EASE_IN_QUAD);
builder.add_property ("opacity", 0u);
builder.add_property ("x", notification.x + stack_width);
builder.add_property ("opacity", 0u, RUN);
builder.add_property ("x", notification.x + stack_width, IGNORE);

return yield builder.run ();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Misc/Zoom.vala
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public class Gala.Zoom : Object, GestureTarget, RootTarget {

case UPDATE:
var target_zoom = (float) progress * 10 + 1;
if (!Meta.Prefs.get_gnome_animations ()) {
if (!Meta.Prefs.get_gnome_animations () || Utils.should_reduce_motion ()) {
var delta = target_zoom - current_zoom;
if (delta.abs () >= SHORTCUT_DELTA - float.EPSILON) {
target_zoom = current_zoom + ((delta > 0) ? SHORTCUT_DELTA : -SHORTCUT_DELTA);
Expand Down
50 changes: 25 additions & 25 deletions src/WindowManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ namespace Gala {
// must wait for size_changed to get updated frame_rect
// as which_change is not passed to size_changed, save it as instance variable
public override void size_change (Meta.WindowActor actor, Meta.SizeChange which_change, Mtk.Rectangle old_frame_rect, Mtk.Rectangle old_buffer_rect) {
if (actor.meta_window.window_type != NORMAL || !Meta.Prefs.get_gnome_animations ()) {
if (actor.meta_window.window_type != NORMAL || !Meta.Prefs.get_gnome_animations () || Utils.should_reduce_motion ()) {
size_change_completed (actor);
return;
}
Expand Down Expand Up @@ -971,10 +971,10 @@ namespace Gala {
actor.set_pivot_point (0.0f, 0.0f);

var actor_transition_builder = new TransitionBuilder (actor, AnimationDuration.SNAP, EASE_IN_OUT_QUAD);
actor_transition_builder.add_property_with_from ("scale-x", actor_scale_x, 1.0);
actor_transition_builder.add_property_with_from ("scale-y", actor_scale_y, 1.0);
actor_transition_builder.add_property_with_from ("translation-x", translation_x, 0.0f);
actor_transition_builder.add_property_with_from ("translation-y", translation_y, 0.0f);
actor_transition_builder.add_property_with_from ("scale-x", actor_scale_x, 1.0, APPLY);
actor_transition_builder.add_property_with_from ("scale-y", actor_scale_y, 1.0, APPLY);
actor_transition_builder.add_property_with_from ("translation-x", translation_x, 0.0f, APPLY);
actor_transition_builder.add_property_with_from ("translation-y", translation_y, 0.0f, APPLY);

yield actor_transition_builder.run ();

Expand Down Expand Up @@ -1011,16 +1011,16 @@ namespace Gala {
(actor.y - icon.y) / (icon.height - actor.height)
);

builder.add_property ("scale-x", (double) (icon.width / actor.width));
builder.add_property ("scale-y", (double) (icon.height / actor.height));
builder.add_property ("scale-x", (double) (icon.width / actor.width), IGNORE);
builder.add_property ("scale-y", (double) (icon.height / actor.height), IGNORE);
} else {
actor.set_pivot_point (0.5f, 1.0f);

builder.add_property ("scale-x", 0.0);
builder.add_property ("scale-y", 0.0);
builder.add_property ("scale-x", 0.0, IGNORE);
builder.add_property ("scale-y", 0.0, IGNORE);
}

builder.add_property ("opacity", 0u);
builder.add_property ("opacity", 0u, RUN);

yield builder.run ();

Expand Down Expand Up @@ -1048,9 +1048,9 @@ namespace Gala {
actor.set_pivot_point (0.5f, 1.0f);

var builder = new TransitionBuilder (actor, AnimationDuration.HIDE, EASE_OUT_EXPO);
builder.add_property_with_from ("scale-x", 0.01, 1.0);
builder.add_property_with_from ("scale-y", 0.1, 1.0);
builder.add_property_with_from ("opacity", 0U, 255U);
builder.add_property_with_from ("scale-x", 0.01, 1.0, APPLY);
builder.add_property_with_from ("scale-y", 0.1, 1.0, APPLY);
builder.add_property_with_from ("opacity", 0U, 255U, RUN);

yield builder.run ();

Expand Down Expand Up @@ -1091,9 +1091,9 @@ namespace Gala {
actor.set_pivot_point (0.5f, 1.0f);

var builder = new TransitionBuilder (actor, AnimationDuration.HIDE, EASE_OUT_EXPO);
builder.add_property_with_from ("scale-x", 0.01, 1.0);
builder.add_property_with_from ("scale-y", 0.1, 1.0);
builder.add_property_with_from ("opacity", 0U, 255U);
builder.add_property_with_from ("scale-x", 0.01, 1.0, APPLY);
builder.add_property_with_from ("scale-y", 0.1, 1.0, APPLY);
builder.add_property_with_from ("opacity", 0U, 255U, RUN);
yield builder.run ();
break;

Expand All @@ -1103,9 +1103,9 @@ namespace Gala {
actor.set_pivot_point (0.5f, 0.5f);

var builder = new TransitionBuilder (actor, 200, EASE_OUT_QUAD);
builder.add_property_with_from ("scale-x", 1.05, 1.0);
builder.add_property_with_from ("scale-y", 1.05, 1.0);
builder.add_property_with_from ("opacity", 0U, 255U);
builder.add_property_with_from ("scale-x", 1.05, 1.0, APPLY);
builder.add_property_with_from ("scale-y", 1.05, 1.0, APPLY);
builder.add_property_with_from ("opacity", 0U, 255U, RUN);
yield builder.run ();
break;

Expand Down Expand Up @@ -1134,9 +1134,9 @@ namespace Gala {
actor.show ();

var builder = new TransitionBuilder (actor, AnimationDuration.CLOSE, LINEAR);
builder.add_property ("scale-x", 0.8);
builder.add_property ("scale-y", 0.8);
builder.add_property ("opacity", 0U);
builder.add_property ("scale-x", 0.8, IGNORE);
builder.add_property ("scale-y", 0.8, IGNORE);
builder.add_property ("opacity", 0U, RUN);
yield builder.run ();

Utils.clear_window_cache (window);
Expand All @@ -1147,9 +1147,9 @@ namespace Gala {
actor.set_pivot_point (0.5f, 0.5f);

var builder = new TransitionBuilder (actor, 150, EASE_OUT_QUAD);
builder.add_property ("scale-x", 1.05);
builder.add_property ("scale-y", 1.05);
builder.add_property ("opacity", 0U);
builder.add_property ("scale-x", 1.05, IGNORE);
builder.add_property ("scale-y", 1.05, IGNORE);
builder.add_property ("opacity", 0U, RUN);
yield builder.run ();
break;

Expand Down