Animate app icons when urgent property is set

This commit is contained in:
Artyom Zorin
2020-12-18 23:42:26 +00:00
parent faf2ca26b9
commit f1aa64cb0d
4 changed files with 124 additions and 3 deletions

View File

@@ -110,12 +110,13 @@ var taskbarAppIcon = Utils.defineClass({
Extends: AppDisplay.AppIcon,
ParentConstrParams: [[0, 'app'], [2]],
_init: function(appInfo, panel, iconParams, previewMenu) {
_init: function(appInfo, panel, iconParams, previewMenu, iconAnimator) {
this.dtpPanel = panel;
this._nWindows = 0;
this.window = appInfo.window;
this.isLauncher = appInfo.isLauncher;
this._previewMenu = previewMenu;
this.iconAnimator = iconAnimator;
this._timeoutsHandler = new Utils.TimeoutsHandler();

View File

@@ -104,6 +104,8 @@ var dtpPanelManager = Utils.defineClass({
);
this._findPanelMenuButtons(p.panelBox).forEach(pmb => this._adjustPanelMenuButton(pmb, p.monitor, panelPosition));
p.taskbar.iconAnimator.start();
});
//in 3.32, BoxPointer now inherits St.Widget
@@ -278,6 +280,8 @@ var dtpPanelManager = Utils.defineClass({
this.proximityManager.destroy();
this.allPanels.forEach(p => {
p.taskbar.iconAnimator.pause();
this._findPanelMenuButtons(p.panelBox).forEach(pmb => {
if (pmb.menu._boxPointer._dtpGetPreferredHeightId) {
pmb.menu._boxPointer._container.disconnect(pmb.menu._boxPointer._dtpGetPreferredHeightId);
@@ -605,6 +609,76 @@ var dtpPanelManager = Utils.defineClass({
},
});
// This class drives long-running icon animations, to keep them running in sync
// with each other.
var IconAnimator = Utils.defineClass({
Name: 'DashToPanel.IconAnimator',
_init: function(actor) {
this._count = 0;
this._started = false;
this._animations = {
dance: [],
};
this._timeline = new Clutter.Timeline({
duration: 3000,
repeat_count: -1,
});
/* Just use the construction property when no need to support 3.36 */
if (this._timeline.set_actor)
this._timeline.set_actor(actor);
this._timeline.connect('new-frame', () => {
const progress = this._timeline.get_progress();
const danceRotation = progress < 1/6 ? 15*Math.sin(progress*24*Math.PI) : 0;
const dancers = this._animations.dance;
for (let i = 0, iMax = dancers.length; i < iMax; i++) {
dancers[i].rotation_angle_z = danceRotation;
}
});
},
destroy: function() {
this._timeline.stop();
this._timeline = null;
this._animations = null;
},
pause: function() {
if (this._started && this._count > 0) {
this._timeline.stop();
}
this._started = false;
},
start: function() {
if (!this._started && this._count > 0) {
this._timeline.start();
}
this._started = true;
},
addAnimation: function(target, name) {
this._animations[name].push(target);
if (this._started && this._count === 0) {
this._timeline.start();
}
this._count++;
},
removeAnimation: function(target, name) {
const index = this._animations[name].indexOf(target);
if (index >= 0) {
this._animations[name].splice(index, 1);
this._count--;
if (this._started && this._count === 0) {
this._timeline.stop();
}
}
}
});
function newViewSelectorAnimateIn(oldPage) {
if (oldPage)
oldPage.hide();
@@ -842,4 +916,4 @@ function _newLookingGlassOpen() {
this._resize();
this._oldOpen();
}
}

View File

@@ -176,6 +176,7 @@ var AppProgress = Utils.defineClass({
this._countVisible = false;
this._progress = 0.0;
this._progressVisible = false;
this._urgent = false;
this.update(properties);
},
@@ -231,6 +232,17 @@ var AppProgress = Utils.defineClass({
}
},
urgent: function() {
return this._urgent;
},
setUrgent: function(urgent) {
if (this._urgent != urgent) {
this._urgent = urgent;
this.emit('urgent-changed', this._urgent);
}
},
setDBusName: function(dbusName) {
if (this._dbusName != dbusName) {
let oldName = this._dbusName;
@@ -246,6 +258,7 @@ var AppProgress = Utils.defineClass({
this.setCountVisible(other.countVisible());
this.setProgress(other.progress());
this.setProgressVisible(other.progressVisible())
this.setUrgent(other.urgent());
} else {
for (let property in other) {
if (other.hasOwnProperty(property)) {
@@ -257,6 +270,8 @@ var AppProgress = Utils.defineClass({
this.setProgress(other[property].get_double());
} else if (property == 'progress-visible') {
this.setProgressVisible(Me.settings.get_boolean('progress-show-bar') && other[property].get_boolean());
} else if (property == 'urgent') {
this.setUrgent(other[property].get_boolean());
} else {
// Not implemented yet
}
@@ -513,6 +528,7 @@ var ProgressIndicator = Utils.defineClass({
this.toggleNotificationBadge(false);
this.setProgress(0);
this.toggleProgressOverlay(false);
this.setUrgent(false);
}
},
@@ -547,6 +563,12 @@ var ProgressIndicator = Utils.defineClass({
(appProgress, value) => {
this.toggleProgressOverlay(value);
}
], [
appProgress,
'urgent-changed',
(appProgress, value) => {
this.setUrgent(value)
}
]);
this.setNotificationBadge(appProgress.count());
@@ -554,5 +576,23 @@ var ProgressIndicator = Utils.defineClass({
this.setProgress(appProgress.progress());
this.toggleProgressOverlay(appProgress.progressVisible());
this._isUrgent = false;
},
setUrgent(urgent) {
const icon = this._source.icon._iconBin;
if (urgent) {
if (!this._isUrgent) {
icon.set_pivot_point(0.5, 0.5);
this._source.iconAnimator.addAnimation(icon, 'dance');
this._isUrgent = true;
}
} else {
if (this._isUrgent) {
this._source.iconAnimator.removeAnimation(icon, 'dance');
this._isUrgent = false;
}
icon.rotation_angle_z = 0;
}
}
});

View File

@@ -46,6 +46,7 @@ const Workspace = imports.ui.workspace;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const AppIcons = Me.imports.appIcons;
const Panel = Me.imports.panel;
const PanelManager = Me.imports.panelManager;
const Utils = Me.imports.utils;
const WindowPreview = Me.imports.windowPreview;
@@ -241,6 +242,8 @@ var taskbar = Utils.defineClass({
this._appSystem = Shell.AppSystem.get_default();
this.iconAnimator = new PanelManager.IconAnimator(this.dtpPanel.panel.actor);
this._signalsHandler.add(
[
this.dtpPanel.panel.actor,
@@ -351,6 +354,8 @@ var taskbar = Utils.defineClass({
},
destroy: function() {
this.iconAnimator.destroy();
this._signalsHandler.destroy();
this._signalsHandler = 0;
@@ -549,7 +554,8 @@ var taskbar = Utils.defineClass({
showLabel: false,
isDraggable: !Me.settings.get_boolean('taskbar-locked'),
},
this.previewMenu
this.previewMenu,
this.iconAnimator
);
if (appIcon._draggable) {