fix: add long-living references to timers for ChatStatusIcon blinking

This commit is contained in:
foudfou 2013-06-17 23:45:38 +02:00
parent 97ef0cb65f
commit 8aaf2cfda7
3 changed files with 98 additions and 79 deletions

View File

@ -15,11 +15,6 @@ let log = firetray.Logging.getLogger("firetray.Chat");
firetray.Chat = {
initialized: false,
observedTopics: {},
shouldAcknowledgeConvs: { // TODO: FOUDIL: rename to convsToAcknoledge
ids: {},
length: function(){return Object.keys(this.ids).length;}
},
get isBlinking () {return (this.shouldAcknowledgeConvs.length() > 0);},
init: function() {
if (this.initialized) {
@ -132,16 +127,17 @@ firetray.Chat = {
this.startGetAttention(conv);
this.shouldAcknowledgeConvs.ids[conv.id] = conv;
log.debug(conv.id+' added to shouldAcknowledgeConvs, length='+this.shouldAcknowledgeConvs.length());
firetray.ChatStatusIcon.convsToAcknowledge.ids[conv.id] = conv;
log.debug(conv.id+' added to convsToAcknowledge, length='+firetray.ChatStatusIcon.convsToAcknowledge.length());
},
startGetAttention: function(conv) {
log.debug("startGetAttention");
this.setUrgencyMaybe(conv);
log.debug("this.isBlinking="+this.isBlinking);
if (this.isBlinking) return;
log.debug("firetray.ChatStatusIcon.isBlinking="+firetray.ChatStatusIcon.isBlinking);
if (firetray.ChatStatusIcon.isBlinking) return;
let blinkStyle = firetray.Utils.prefService.getIntPref("chat_icon_blink_style");
log.debug("chat_icon_blink_style="+blinkStyle);
if (blinkStyle === FIRETRAY_CHAT_ICON_BLINK_STYLE_NORMAL)
@ -157,21 +153,21 @@ firetray.Chat = {
*/
stopGetAttentionMaybe: function(xid) {
log.debug("stopGetAttentionMaybe");
log.debug("shouldAcknowledgeConvsLength="+this.shouldAcknowledgeConvs.length());
if (!this.isBlinking) return; // instead of pref chat_icon_blink — if pref was just unset
log.debug("convsToAcknowledgeLength="+firetray.ChatStatusIcon.convsToAcknowledge.length());
if (!firetray.ChatStatusIcon.isBlinking) return; // instead of pref chat_icon_blink — if pref was just unset
let selectedConv = this.getSelectedConv(xid);
if (!selectedConv) return;
for (let convId in this.shouldAcknowledgeConvs.ids) {
for (let convId in firetray.ChatStatusIcon.convsToAcknowledge.ids) {
log.debug(convId+" == "+selectedConv.id);
if (convId == selectedConv.id) {
delete this.shouldAcknowledgeConvs.ids[convId];
delete firetray.ChatStatusIcon.convsToAcknowledge.ids[convId];
break;
}
}
if (this.shouldAcknowledgeConvs.length() === 0)
if (firetray.ChatStatusIcon.convsToAcknowledge.length() === 0)
this.stopGetAttention(xid);
},

View File

@ -483,7 +483,7 @@ firetray.PrefListener = new PrefListener(
case 'chat_icon_blink':
if (!firetray.Utils.prefService.getBoolPref('chat_icon_blink') &&
firetray.Chat.isBlinking) {
firetray.ChatStatusIcon.isBlinking) {
/* FIXME: stopGetAttention() needs a window id. For now just pass the
active window */
firetray.Chat.stopGetAttention(firetray.Handler.findActiveWindow());
@ -491,8 +491,8 @@ firetray.PrefListener = new PrefListener(
break;
case 'chat_icon_blink_style':
if (!(firetray.Utils.prefService.getBoolPref('chat_icon_blink') &&
firetray.Chat.isBlinking))
if (!firetray.Utils.prefService.getBoolPref('chat_icon_blink') ||
!firetray.ChatStatusIcon.isBlinking)
break;
switch (firetray.Utils.prefService.getIntPref("chat_icon_blink_style")) {

View File

@ -23,6 +23,10 @@ if ("undefined" == typeof(firetray.Handler))
let log = firetray.Logging.getLogger("firetray.ChatStatusIcon");
const ALPHA_STEP = 5;
const ALPHA_STEP_SLEEP_MILLISECONDS = 10;
const FADE_OVER_SLEEP_MILLISECONDS = 500;
firetray.ChatStatusIcon = {
GTK_THEME_ICON_PATH: null,
@ -41,6 +45,13 @@ firetray.ChatStatusIcon = {
signals: {'focus-in': {callback: {}, handler: {}}},
timers: {},
events: {},
generators: {},
pixBuffer: {},
convsToAcknowledge: {
ids: {},
length: function(){return Object.keys(this.ids).length;}
},
get isBlinking () {return (this.convsToAcknowledge.length() > 0);},
init: function() {
if (!firetray.Handler.inMailApp) throw "ChatStatusIcon for mail app only";
@ -84,7 +95,7 @@ firetray.ChatStatusIcon = {
let blinkStyle = firetray.Utils.prefService.getIntPref("chat_icon_blink_style");
if (blinkStyle === FIRETRAY_CHAT_ICON_BLINK_STYLE_FADE &&
firetray.Chat.shouldAcknowledgeConvs.length()) {
this.isBlinking) {
this.events['icon-changed'] = true;
return;
}
@ -137,7 +148,7 @@ firetray.ChatStatusIcon = {
alpha_bak[(i-3)/n_channels] = pixels.contents[i];
log.debug("pixbuf created");
return {
this.pixBuffer = {
pixbuf: pixbuf, // TO BE UNREFED WITH to g_object_unref() !!
width: width,
height: height,
@ -148,71 +159,83 @@ firetray.ChatStatusIcon = {
alpha_bak: alpha_bak
};
},
dropPixBuf: function(p) {
gobject.g_object_unref(p.pixbuf);
dropPixBuf: function() {
gobject.g_object_unref(this.pixBuffer.pixbuf);
log.debug("pixbuf unref'd");
this.pixBuffer = {};
},
fadeGenerator: function() {
let pixbuf = firetray.ChatStatusIcon.pixBuffer;
for (let a=255; a>0; a-=ALPHA_STEP) {
for(let i=3; i<pixbuf.length; i+=pixbuf.n_channels)
if (pixbuf.pixels.contents[i]-ALPHA_STEP>0)
pixbuf.pixels.contents[i] -= ALPHA_STEP;
gtk.gtk_status_icon_set_from_pixbuf(firetray.ChatStatusIcon.trayIcon, pixbuf.pixbuf);
yield true;
}
for (let a=255; a>0; a-=ALPHA_STEP) {
for(let i=3; i<pixbuf.length; i+=pixbuf.n_channels)
if (pixbuf.pixels.contents[i]+ALPHA_STEP<=pixbuf.alpha_bak[(i-3)/pixbuf.n_channels]) {
pixbuf.pixels.contents[i] += ALPHA_STEP;
}
gtk.gtk_status_icon_set_from_pixbuf(firetray.ChatStatusIcon.trayIcon, pixbuf.pixbuf);
yield true;
}
},
fadeStep: function() {
try {
if (firetray.ChatStatusIcon.generators['fade'].next())
firetray.ChatStatusIcon.timers['fade-step'] = firetray.Utils.timer(
ALPHA_STEP_SLEEP_MILLISECONDS, Ci.nsITimer.TYPE_ONE_SHOT,
firetray.ChatStatusIcon.fadeStep);
} catch (e if e instanceof StopIteration) {
log.warn("stop-fade 1:"+firetray.ChatStatusIcon.events['stop-fade']);
if (firetray.ChatStatusIcon.events['stop-fade']) {
log.debug("stop-fade");
delete firetray.ChatStatusIcon.events['stop-fade'];
delete firetray.ChatStatusIcon.generators['fade'];
delete firetray.ChatStatusIcon.timers['fade-step'];
delete firetray.ChatStatusIcon.timers['fade-loop'];
firetray.ChatStatusIcon.setIconImage(firetray.ChatStatusIcon.themedIconNameCurrent);
firetray.ChatStatusIcon.dropPixBuf(p);
return;
}
if (firetray.ChatStatusIcon.events['icon-changed']) {
delete firetray.ChatStatusIcon.events['icon-changed'];
firetray.ChatStatusIcon.dropPixBuf();
firetray.ChatStatusIcon.buildPixBuf();
firetray.ChatStatusIcon.timers['fade-loop'] = firetray.Utils.timer(
FADE_OVER_SLEEP_MILLISECONDS, Ci.nsITimer.TYPE_ONE_SHOT, function(){
firetray.ChatStatusIcon.fadeLoop();}
);
} else {
log.warn("fadeLoop else -> 0");
firetray.ChatStatusIcon.timers['fade-loop'] = firetray.Utils.timer(
FADE_OVER_SLEEP_MILLISECONDS, Ci.nsITimer.TYPE_ONE_SHOT, function(){
log.warn("fadeLoop else -> 1");
firetray.ChatStatusIcon.fadeLoop();}
);
}
};
},
fadeLoop: function() {
log.warn("stop-fade 0:"+firetray.ChatStatusIcon.events['stop-fade']);
firetray.ChatStatusIcon.generators['fade'] = firetray.ChatStatusIcon.fadeGenerator();
firetray.ChatStatusIcon.fadeStep();
},
startFading: function() {
log.debug("startFading");
const ALPHA_STEP = 5;
const ALPHA_STEP_SLEEP_MILLISECONDS = 10;
const FADE_OVER_SLEEP_MILLISECONDS = 500;
function fadeGen(p) {
for (let a=255; a>0; a-=ALPHA_STEP) {
for(let i=3; i<p.length; i+=p.n_channels)
if (p.pixels.contents[i]-ALPHA_STEP>0)
p.pixels.contents[i] -= ALPHA_STEP;
gtk.gtk_status_icon_set_from_pixbuf(firetray.ChatStatusIcon.trayIcon, p.pixbuf);
yield true;
}
for (let a=255; a>0; a-=ALPHA_STEP) {
for(let i=3; i<p.length; i+=p.n_channels)
if (p.pixels.contents[i]+ALPHA_STEP<=p.alpha_bak[(i-3)/p.n_channels]) {
p.pixels.contents[i] += ALPHA_STEP;
}
gtk.gtk_status_icon_set_from_pixbuf(firetray.ChatStatusIcon.trayIcon, p.pixbuf);
yield true;
}
}
function fadeLoop(p) {
let fadeOutfadeIn = fadeGen(p);
(function step() {
try {
if (fadeOutfadeIn.next())
firetray.Utils.timer(ALPHA_STEP_SLEEP_MILLISECONDS,
Ci.nsITimer.TYPE_ONE_SHOT, step);
} catch (e if e instanceof StopIteration) {
if (firetray.ChatStatusIcon.events['stop-fade']) {
log.debug("stop-fade");
delete firetray.ChatStatusIcon.events['stop-fade'];
firetray.ChatStatusIcon.setIconImage(firetray.ChatStatusIcon.themedIconNameCurrent);
firetray.ChatStatusIcon.dropPixBuf(p);
return;
}
if (firetray.ChatStatusIcon.events['icon-changed']) {
delete firetray.ChatStatusIcon.events['icon-changed'];
firetray.ChatStatusIcon.dropPixBuf(p);
let newPixbufObj = firetray.ChatStatusIcon.buildPixBuf();
firetray.Utils.timer(FADE_OVER_SLEEP_MILLISECONDS,
Ci.nsITimer.TYPE_ONE_SHOT, function(){fadeLoop(newPixbufObj);});
} else {
firetray.Utils.timer(FADE_OVER_SLEEP_MILLISECONDS,
Ci.nsITimer.TYPE_ONE_SHOT, function(){fadeLoop(p);});
}
};
})();
}
let pixbufObj = this.buildPixBuf();
fadeLoop(pixbufObj);
this.buildPixBuf();
this.fadeLoop();
},
stopFading: function() {