Skip to content
Merged
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
78 changes: 64 additions & 14 deletions src/AppSystem/Launcher.vala
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ public class Dock.Launcher : BaseItem {
public App app { get; construct; }

private Gtk.Image image;
private Gtk.Label badge;
private Gtk.Revealer progress_revealer;
private Gtk.Revealer badge_revealer;
private Adw.TimedAnimation badge_fade;
private Adw.TimedAnimation badge_scale;
private Adw.TimedAnimation bounce_up;
private Adw.TimedAnimation bounce_down;
private Adw.TimedAnimation shake;
Expand Down Expand Up @@ -107,16 +109,15 @@ public class Dock.Launcher : BaseItem {
image.gicon = new ThemedIcon ("application-default-icon");
}

var badge = new Gtk.Label ("!") {
halign = END,
valign = START
};
badge = new Gtk.Label ("!");
badge.add_css_class (Granite.STYLE_CLASS_BADGE);

badge_revealer = new Gtk.Revealer () {
var badge_container = new Granite.Bin () {
can_target = false,
child = badge,
transition_type = SWING_UP
halign = END,
valign = START,
overflow = VISIBLE
};

progress_revealer = new Gtk.Revealer () {
Expand All @@ -125,7 +126,7 @@ public class Dock.Launcher : BaseItem {
};

overlay.child = image;
overlay.add_overlay (badge_revealer);
overlay.add_overlay (badge_container);
overlay.add_overlay (progress_revealer);

insert_action_group (ACTION_GROUP_PREFIX, app.action_group);
Expand Down Expand Up @@ -196,6 +197,33 @@ public class Dock.Launcher : BaseItem {
reverse = true
};

badge_scale = new Adw.TimedAnimation (
badge, 0.25, 1,
Granite.TRANSITION_DURATION_OPEN,
new Adw.CallbackAnimationTarget ((val) => {
var height = badge_container.get_height ();
var width = badge_container.get_width ();

var x = (float) (width - (val * width)) / 2;
var y = (float) (height - (val * height)) / 2;

badge.allocate (
width, height, -1,
new Gsk.Transform ().scale ((float) val, (float) val).translate (Graphene.Point ().init (x, y))
);
})
);

badge_fade = new Adw.TimedAnimation (
badge, 0, 1,
Granite.TRANSITION_DURATION_OPEN,
new Adw.CallbackAnimationTarget ((val) => {
badge.opacity = val;
})
) {
easing = EASE_IN_OUT_QUAD
};

gesture_click.button = 0;
gesture_click.released.connect (on_click_released);

Expand All @@ -217,8 +245,8 @@ public class Dock.Launcher : BaseItem {

bind_property ("icon-size", image, "pixel-size", SYNC_CREATE);

app.notify["count-visible"].connect (update_badge_revealer);
update_badge_revealer ();
app.notify["count-visible"].connect (update_badge_revealed);
update_badge_revealed ();
current_count_binding = app.bind_property ("current_count", badge, "label", SYNC_CREATE,
(binding, srcval, ref targetval) => {
var src = (int64) srcval;
Expand All @@ -234,7 +262,7 @@ public class Dock.Launcher : BaseItem {
);

if (notify_settings != null) {
notify_settings.changed["do-not-disturb"].connect (update_badge_revealer);
notify_settings.changed["do-not-disturb"].connect (update_badge_revealed);
}

app.notify["progress-visible"].connect (update_progress_revealer);
Expand Down Expand Up @@ -385,9 +413,31 @@ public class Dock.Launcher : BaseItem {
}
}

private void update_badge_revealer () {
badge_revealer.reveal_child = app.count_visible
&& (notify_settings == null || !notify_settings.get_boolean ("do-not-disturb"));
private void update_badge_revealed () {
badge_fade.skip ();
badge_scale.skip ();

// Avoid a stutter at the beginning
badge.opacity = 0;

if (app.count_visible && (notify_settings == null || !notify_settings.get_boolean ("do-not-disturb"))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the idea behind the DND check here? It looks like it skips this and will use the default up above and still animate. And then if it is removing the badge and DND is on, it will use the default but won't be reversed. Am I reading this right?

Copy link
Member Author

@danirabbit danirabbit Sep 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept this the same as it was before. I think it's if the badge should be visible AND (either do not disturb status is unknown OR do not disturb is off) Do all the badge show animations otherwise do all the badge hide animations.

In other words, if do not disturb is turned on, don't show badges. We only need to check if DnD is turned on to show badges, we don't need to check it to hide badges

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oooooh I see

badge_fade.duration = Granite.TRANSITION_DURATION_OPEN;
badge_fade.reverse = false;

badge_scale.duration = Granite.TRANSITION_DURATION_OPEN;
badge_scale.easing = EASE_OUT_BACK;
badge_scale.reverse = false;
} else {
badge_fade.duration = Granite.TRANSITION_DURATION_CLOSE;
badge_fade.reverse = true;

badge_scale.duration = Granite.TRANSITION_DURATION_CLOSE;
badge_scale.easing = EASE_OUT_QUAD;
badge_scale.reverse = true;
}

badge_fade.play ();
badge_scale.play ();
}

private void update_progress_revealer () {
Expand Down