Compare commits
30 Commits
Author | SHA1 | Date |
---|---|---|
foudfou | 0d209aa5ab | |
foudfou | 9a1d80e00f | |
foudfou | 56b88bb481 | |
foudfou | df4d0e8763 | |
foudfou | 972f1c642c | |
foudfou | 3e0ede74c7 | |
foudfou | d588605620 | |
foudfou | a95709e544 | |
foudfou | e4318ed5d9 | |
foudfou | 389e6cec51 | |
foudfou | 58130c5a7d | |
foudfou | 9b8ab13265 | |
foudfou | 9deaea08bb | |
foudfou | 2b0084b69a | |
foudfou | f2acc43dce | |
foudfou | 0dc0cc34b3 | |
foudfou | a0c0061cd6 | |
foudfou | 0fee978ec3 | |
foudfou | 9a4d379e76 | |
foudfou | 4beb428492 | |
foudfou | bd3f894a15 | |
foudfou | 6feb13e7e2 | |
foudfou | 233e442a09 | |
foudfou | 08bc12e28c | |
foudfou | 4805e3b49b | |
foudfou | 2cf236bf14 | |
foudfou | 0cfe58e410 | |
foudfou | e2448d4ae8 | |
foudfou | d34f7d2eeb | |
foudfou | a7020999a8 |
|
@ -20,6 +20,7 @@ Features
|
|||
* show icon only when hidden to tray
|
||||
* mouse scroll on tray icon shows/hides
|
||||
* GTK-themable icons
|
||||
* StatusNotifierItem support (can be disabled by `with_appindicator` hidden pref)
|
||||
* customizable tray icons
|
||||
* popup menu (show/hide individual windows, open new windows, quit)
|
||||
* command-line `-firetrayShowHide` option (useful for window manager's keyboard shortcuts)
|
||||
|
@ -43,7 +44,10 @@ Features
|
|||
Notes
|
||||
-----
|
||||
|
||||
* requires GTK+ 2.20 and higher.
|
||||
* Under Linux:
|
||||
* GTK+ 2.20+ required.
|
||||
* libappindicator3 can be used for StatusNotifierItem (KDE, Unity).
|
||||
* Under Windows, few features are not yet implemented.
|
||||
* Firetray temporarily unsets:
|
||||
* the `tabs.warnOnClose` built-in preference, which otherwise disrupts the handeling of the close event
|
||||
* `mail.biff.show_tray_icon` for mail applications
|
||||
|
|
|
@ -92,7 +92,7 @@ chrome_sources := $(chrome_sources_js) \
|
|||
$(wildcard $(chrome_source_root)/content/*.xul) \
|
||||
$(wildcard $(chrome_source_root)/content/*.xml) \
|
||||
$(wildcard $(chrome_source_root)/content/*.css) \
|
||||
$(wildcard $(chrome_source_root)/skin/icons/*.css) \
|
||||
$(wildcard $(chrome_source_root)/skin/*.css) \
|
||||
$(wildcard $(chrome_source_root)/skin/icons/*.gif) \
|
||||
$(wildcard $(chrome_source_root)/skin/icons/*.png) \
|
||||
$(wildcard $(chrome_source_root)/skin/icons/*.svg) \
|
||||
|
|
|
@ -11,6 +11,7 @@ locale firetray pl-PL chrome/locale/pl-PL/
|
|||
locale firetray ru-RU chrome/locale/ru-RU/
|
||||
locale firetray sk-SK chrome/locale/sk-SK/
|
||||
locale firetray zh-TW chrome/locale/zh-TW/
|
||||
locale firetray zh-TW chrome/locale/uk-UA/
|
||||
resource firetray modules/
|
||||
|
||||
overlay chrome://browser/content/browser.xul chrome://firetray/content/overlay.xul
|
||||
|
|
|
@ -38,7 +38,8 @@ var firetrayUIOptions = {
|
|||
}
|
||||
|
||||
if (firetray.Handler.isChatProvided() &&
|
||||
FIRETRAY_CHAT_SUPPORTED_OS.indexOf(firetray.Handler.runtimeOS) > -1) {
|
||||
firetray.Handler.support['chat'] &&
|
||||
!firetray.AppIndicator) {
|
||||
Cu.import("resource://firetray/"+firetray.Handler.runtimeOS+"/FiretrayChat.jsm");
|
||||
this.initChatControls();
|
||||
} else {
|
||||
|
@ -48,13 +49,23 @@ var firetrayUIOptions = {
|
|||
this.updateWindowAndIconOptions();
|
||||
this.updateScrollOptions();
|
||||
this.initAppIconType();
|
||||
if (firetray.Handler.support['full_feat']) {
|
||||
if (firetray.Handler.support['winnt']) {
|
||||
this.hideUnsupportedOptions([
|
||||
'ui_hides_last_only', 'ui_show_activates', 'ui_remember_desktop',
|
||||
'app_icon_default', 'ui_show_icon_on_hide', 'ui_scroll_hides',
|
||||
'ui_radiogroup_scroll', 'ui_scroll_hides', 'ui_middle_click',
|
||||
'newmail_icon_names'
|
||||
]);
|
||||
} else if (firetray.AppIndicator) {
|
||||
this.hideUnsupportedOptions([
|
||||
'app_icon_default', 'ui_mail_notification_unread_count',
|
||||
'newmail_icon_names'
|
||||
]);
|
||||
} else {
|
||||
this.initAppIconNames();
|
||||
if (firetray.Handler.inMailApp)
|
||||
this.initNewMailIconNames();
|
||||
} else {
|
||||
this.hideUnsupportedOptions();
|
||||
};
|
||||
}
|
||||
|
||||
window.sizeToContent();
|
||||
},
|
||||
|
@ -66,26 +77,39 @@ var firetrayUIOptions = {
|
|||
}
|
||||
},
|
||||
|
||||
hideUnsupportedOptions: function() { // full_feat
|
||||
// windows prefs
|
||||
['ui_hides_last_only', 'ui_show_activates', 'ui_remember_desktop']
|
||||
.forEach(function(id){
|
||||
document.getElementById(id).hidden = true;
|
||||
});
|
||||
hideUnsupportedOptions: function(uiElts) {
|
||||
uiElts.forEach(function(id){
|
||||
switch(id){
|
||||
// windows prefs
|
||||
case 'ui_hides_last_only':
|
||||
case 'ui_show_activates':
|
||||
case 'ui_remember_desktop':
|
||||
// icon prefs
|
||||
case 'app_icon_default':
|
||||
case 'ui_show_icon_on_hide':
|
||||
case 'ui_scroll_hides':
|
||||
case 'ui_radiogroup_scroll':
|
||||
case 'ui_middle_click':
|
||||
document.getElementById(id).hidden = true;
|
||||
break;
|
||||
case 'ui_scroll_hides':
|
||||
document.getElementById(id).removeAttribute("oncommand");
|
||||
break;
|
||||
// mail prefs
|
||||
case 'newmail_icon_names':
|
||||
for (let i=1; i<4; ++i) {
|
||||
document.getElementById("radio_mail_notification_newmail_icon_name"+i).
|
||||
setAttribute("observes", void(0));
|
||||
}
|
||||
case 'ui_mail_notification_unread_count':
|
||||
document.getElementById(id).hidden = true;
|
||||
break;
|
||||
default:
|
||||
log.error("Unhandled id: "+id);
|
||||
};
|
||||
});
|
||||
|
||||
// icon prefs
|
||||
['app_icon_default', 'ui_show_icon_on_hide', 'ui_scroll_hides',
|
||||
'ui_radiogroup_scroll'].forEach(function(id){
|
||||
document.getElementById(id).hidden = true;
|
||||
});
|
||||
document.getElementById("ui_scroll_hides").setAttribute("oncommand", void(0));
|
||||
|
||||
// mail prefs
|
||||
document.getElementById("newmail_icon_names").hidden = true;
|
||||
for (let i=1; i<4; ++i) {
|
||||
document.getElementById("radio_mail_notification_newmail_icon_name"+i).
|
||||
setAttribute("observes", void(0));
|
||||
}
|
||||
},
|
||||
|
||||
hidePrefPane: function(name){
|
||||
|
@ -196,7 +220,7 @@ var firetrayUIOptions = {
|
|||
},
|
||||
|
||||
disableIconTypeMaybe: function(appIconType) {
|
||||
if (firetray.Handler.support['full_feat']) {
|
||||
if (firetray.Handler.support['winnt']) {
|
||||
let appIconDefaultGroup = document.getElementById("app_icon_default");
|
||||
this.disableNChildren(appIconDefaultGroup, 2,
|
||||
(appIconType !== FIRETRAY_APPLICATION_ICON_TYPE_THEMED));
|
||||
|
@ -301,7 +325,7 @@ var firetrayUIOptions = {
|
|||
this.disableChildren(iconTextColor,
|
||||
(notificationSetting !== FIRETRAY_NOTIFICATION_MESSAGE_COUNT));
|
||||
|
||||
if (firetray.Handler.support['full_feat']) {
|
||||
if (firetray.Handler.support['winnt']) {
|
||||
let newMailIconNames = document.getElementById("newmail_icon_names");
|
||||
this.disableNChildren(newMailIconNames, 2,
|
||||
(notificationSetting !== FIRETRAY_NOTIFICATION_NEWMAIL_ICON));
|
||||
|
@ -323,7 +347,7 @@ var firetrayUIOptions = {
|
|||
let mailNotificationType = +mailNotifyRadio.getItemAtIndex(mailNotifyRadio.selectedIndex).value;
|
||||
if (msgCountTypeIsNewMessages && (mailNotificationType === FIRETRAY_NOTIFICATION_MESSAGE_COUNT)) {
|
||||
mailNotifyRadio.selectedIndex = this.radioGetIndexByValue(mailNotifyRadio, FIRETRAY_NOTIFICATION_NEWMAIL_ICON);
|
||||
if (firetray.Handler.support['full_feat']) {
|
||||
if (firetray.Handler.support['winnt']) {
|
||||
let newMailIconNames = document.getElementById("newmail_icon_names");
|
||||
this.disableNChildren(newMailIconNames, 2, false);
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
<preference id="pref_show_icon_on_hide" name="extensions.firetray.show_icon_on_hide" type="bool"/>
|
||||
<preference id="pref_scroll_hides" name="extensions.firetray.scroll_hides" type="bool" />
|
||||
<preference id="pref_scroll_mode" name="extensions.firetray.scroll_mode" type="string" />
|
||||
<preference id="pref_middle_click" name="extensions.firetray.middle_click" type="int" />
|
||||
</preferences>
|
||||
|
||||
<vbox pack="start" align="left" flex="1">
|
||||
|
@ -120,6 +121,15 @@
|
|||
<radio id="ui_radio_scroll_up_hides" label="&up;=&hide;, &down;=&restore;" value="up_hides" />
|
||||
</radiogroup>
|
||||
|
||||
<radiogroup id="ui_middle_click" preference="pref_middle_click">
|
||||
<hbox align="center" flex="1">
|
||||
<label control="ui_middle_click" value="&middle_click.label;"
|
||||
accesskey="&middle_click.accesskey;" />
|
||||
<radio id="ui_middle_click_activate_last" label="&activate_last;" value="0" />
|
||||
<radio id="ui_middle_click_show_hide" label="&show_hide;" value="1" />
|
||||
</hbox>
|
||||
</radiogroup>
|
||||
|
||||
</vbox>
|
||||
|
||||
</prefpane>
|
||||
|
|
|
@ -23,7 +23,7 @@ var firetrayChrome = { // each new window gets a new firetrayChrome !
|
|||
firetray_log.debug("Handler initialized: "+firetray.Handler.initialized);
|
||||
let init = firetray.Handler.initialized || firetray.Handler.init();
|
||||
|
||||
firetray_log.debug("ONLOAD"); firetray.Handler.dumpWindows();
|
||||
firetray_log.debug("ONLOAD");
|
||||
this.winId = firetray.Handler.registerWindow(win);
|
||||
|
||||
win.addEventListener('close', firetrayChrome.onClose, true);
|
||||
|
@ -39,7 +39,7 @@ var firetrayChrome = { // each new window gets a new firetrayChrome !
|
|||
onQuit: function(win) {
|
||||
win.removeEventListener('close', firetrayChrome.onClose, true);
|
||||
firetray.Handler.unregisterWindow(win);
|
||||
firetray_log.info("windowsCount="+firetray.Handler.windowsCount+", visibleWindowsCount="+firetray.Handler.visibleWindowsCount);
|
||||
firetray_log.debug("windowsCount="+firetray.Handler.windowsCount+", visibleWindowsCount="+firetray.Handler.visibleWindowsCount);
|
||||
firetray_log.debug('Firetray UNLOADED !');
|
||||
},
|
||||
|
||||
|
@ -75,72 +75,53 @@ var firetrayChrome = { // each new window gets a new firetrayChrome !
|
|||
*/
|
||||
hijackTitlebarButtons: function() {
|
||||
Object.keys(this.titlebarDispatch).forEach(function(id) {
|
||||
let button = this.titlebarDispatch[id];
|
||||
let fInfo = firetrayChrome.replaceCommand(id, button.new);
|
||||
if (fInfo) {
|
||||
button.old = fInfo[0];
|
||||
firetray_log.debug('replaced command='+button.id+' type='+fInfo[1]+' func='+fInfo[0]);
|
||||
button.type = fInfo[1];
|
||||
if (firetrayChrome.replaceCommand(id, this.titlebarDispatch[id])) {
|
||||
firetray_log.debug('replaced command='+id);
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
titlebarDispatch: {
|
||||
"titlebar-min": { new: function(e){
|
||||
firetray_log.debug(' titlebar-min clicked');
|
||||
if (!firetray.Handler.onMinimize(firetrayChrome.winId))
|
||||
firetrayChrome.applyDefaultCommand("titlebar-min");
|
||||
}, old: null, type: null },
|
||||
"titlebar-close": { new: function(e){
|
||||
firetray_log.debug(' titlebar-close clicked');
|
||||
if (!firetrayChrome.onClose(null)) {
|
||||
firetrayChrome.applyDefaultCommand("titlebar-close");
|
||||
}
|
||||
}, old: null, type: null }
|
||||
"titlebar-min": function() {
|
||||
return firetray.Handler.onMinimize(firetrayChrome.winId);
|
||||
},
|
||||
"titlebar-close": function() {
|
||||
return firetrayChrome.onClose(null);
|
||||
}
|
||||
},
|
||||
|
||||
replaceCommand: function(eltId, func) {
|
||||
replaceCommand: function(eltId, gotHidden) {
|
||||
let elt = document.getElementById(eltId);
|
||||
if (!elt) {
|
||||
firetray_log.debug("Element '"+eltId+"' not found. Command not replaced.");
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
let command = elt.command;
|
||||
let oncommand = elt.getAttribute("oncommand");
|
||||
let old = null, type = null;
|
||||
if (command) {
|
||||
firetray_log.debug('command');
|
||||
type = FIRETRAY_XUL_ATTRIBUTE_COMMAND;
|
||||
old = elt.command;
|
||||
elt.command = null;
|
||||
elt.addEventListener('click', func, false);
|
||||
} else if (oncommand) {
|
||||
firetray_log.debug('oncommand');
|
||||
type = FIRETRAY_XUL_ATTRIBUTE_ONCOMMAND;
|
||||
let prev = elt.getAttribute("oncommand");
|
||||
old = new Function(prev);
|
||||
elt.setAttribute("oncommand", void(0));
|
||||
elt.addEventListener('command', func, false);
|
||||
let prevent = null;
|
||||
if (elt.command) {
|
||||
prevent = { event: "click", func: function(e){e.preventDefault();} };
|
||||
} else if (elt.getAttribute("oncommand")) {
|
||||
prevent = { event: "command", func: function(e){e.stopPropagation();} };
|
||||
} else {
|
||||
firetray_log.warn('Could not replace oncommand on '+eltId);
|
||||
return false;
|
||||
}
|
||||
|
||||
return [old, type];
|
||||
},
|
||||
applyDefaultCommand: function(key) {
|
||||
let callType = this.titlebarDispatch[key]['type'];
|
||||
if (callType === FIRETRAY_XUL_ATTRIBUTE_COMMAND) {
|
||||
let cmdName = firetrayChrome.titlebarDispatch[key]['old'];
|
||||
let cmd = document.getElementById(cmdName);
|
||||
cmd.doCommand();
|
||||
let callback = function(event) {
|
||||
if (event.target.id === eltId) {
|
||||
firetray_log.debug(prevent.event +' on '+eltId);
|
||||
if (gotHidden())
|
||||
prevent.func(event);
|
||||
}
|
||||
};
|
||||
/* We put listeners on the "titlebar" parent node, because:
|
||||
- we can hardly short-circuit command/oncommand (probably because they are
|
||||
registered first)
|
||||
- we'd have otherwise to alter "oncommand"/"command" attribute and use
|
||||
Function(), which do not pass review nowadays. */
|
||||
elt.parentNode.addEventListener(prevent.event, callback, true);
|
||||
|
||||
} else if (callType === FIRETRAY_XUL_ATTRIBUTE_ONCOMMAND) {
|
||||
firetrayChrome.titlebarDispatch[key]['old']();
|
||||
|
||||
} else {
|
||||
firetray_log.error("Calling type undefined for "+key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
<!ENTITY down "↓" >
|
||||
<!ENTITY hide "verstecken" >
|
||||
<!ENTITY restore "wiederherstellen" >
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
|
||||
<!ENTITY mail_notification_enabled.label "Mailbenachrichtigung">
|
||||
<!ENTITY mail_notification_enabled.accesskey "M">
|
||||
|
@ -56,8 +60,8 @@
|
|||
<!ENTITY mail_notification_unread_count.accesskey "A">
|
||||
<!ENTITY mail_notification_newmail_icon.label "Icon aus dem Desktop-Theme">
|
||||
<!ENTITY mail_notification_newmail_icon.accesskey "T">
|
||||
<!ENTITY mail_notification_custom_mail_icon.label "Beliebiges Icon">
|
||||
<!ENTITY mail_notification_custom_mail_icon.accesskey "I">
|
||||
<!ENTITY mail_notification_mail_icon_custom.label "Beliebiges Icon">
|
||||
<!ENTITY mail_notification_mail_icon_custom.accesskey "I">
|
||||
<!ENTITY icon_text_color "Textfarbe">
|
||||
<!ENTITY icon_text_color.accesskey "F">
|
||||
<!ENTITY choose "Auswählen">
|
||||
|
@ -86,8 +90,8 @@
|
|||
<!ENTITY mail_change_trigger.accesskey "A">
|
||||
<!ENTITY mail_change_trigger.placeholder "/bin/notify-send">
|
||||
<!ENTITY mail_change_trigger.tooltip "absoluter Pfad eines Executables, das aufgerufen wird, falls sich die Anzahl der Mails ändert; die (neue) Anzahl der Mails wird als Argument übergeben.">
|
||||
<!ENTITY mail_urgency_hint.label "»X11 urgency hint« absetzen">
|
||||
<!ENTITY mail_urgency_hint.accesskey "X">
|
||||
<!ENTITY mail_get_attention.label "»X11 urgency hint« absetzen">
|
||||
<!ENTITY mail_get_attention.accesskey "X">
|
||||
|
||||
<!ENTITY chat_icon_enable.label "Chat-Icon aktivieren">
|
||||
<!ENTITY chat_icon_enable.accesskey "A">
|
||||
|
|
|
@ -1 +1 @@
|
|||
|
||||
<!ENTITY firetray.label "My localized menuitem">
|
||||
|
|
|
@ -4,5 +4,7 @@ popupMenu.itemLabel.Preferences=Einstellungen
|
|||
popupMenu.itemLabel.Quit=Beenden
|
||||
popupMenu.itemLabel.NewWindow=Neues Fenster
|
||||
popupMenu.itemLabel.NewMessage=Neue Nachricht
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 ungelesene Nachricht;#1 ungelesene Nachrichten
|
||||
tooltip.new_messages=Neue Nachrichten!
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
<!ENTITY down "↓" >
|
||||
<!ENTITY hide "hide" >
|
||||
<!ENTITY restore "restore" >
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
|
||||
<!ENTITY mail_notification_enabled.label "Enable mail notification">
|
||||
<!ENTITY mail_notification_enabled.accesskey "a">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=A system tray extension for linux.
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=A system tray extension.
|
||||
popupMenu.itemLabel.ResetIcon=Reset icon
|
||||
popupMenu.itemLabel.Preferences=Preferences
|
||||
popupMenu.itemLabel.Quit=Quit
|
||||
popupMenu.itemLabel.NewWindow=New window
|
||||
popupMenu.itemLabel.NewMessage=New message
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 unread message;#1 unread messages
|
||||
tooltip.new_messages=New messages !
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
<!ENTITY down "↓">
|
||||
<!ENTITY hide "ocultar">
|
||||
<!ENTITY restore "restaurar">
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
<!ENTITY mail_notification_enabled.label "Habilitar notificaciones por correo">
|
||||
<!ENTITY mail_notification_enabled.accesskey "H">
|
||||
<!ENTITY message_count_type.label "tipo de contador de mensajes:">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Una extensión para la bandeja del sistema en linux.
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Una extensión para la bandeja del sistema.
|
||||
popupMenu.itemLabel.ResetIcon=Ícono de reset
|
||||
popupMenu.itemLabel.Preferences=Preferences
|
||||
popupMenu.itemLabel.Quit=Salir
|
||||
popupMenu.itemLabel.NewWindow=Nueva ventana
|
||||
popupMenu.itemLabel.NewMessage=Nuevo mensaje
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 mensaje no leido;#1 mensajes no leídos
|
||||
tooltip.new_messages=Nuevos mensajes !
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
<!ENTITY down "↓">
|
||||
<!ENTITY hide "masquer">
|
||||
<!ENTITY restore "restaurer">
|
||||
<!ENTITY middle_click.label "Souris clic du milieu :" >
|
||||
<!ENTITY middle_click.accesskey "m" >
|
||||
<!ENTITY show_hide "Masquer/Restaurer" >
|
||||
<!ENTITY activate_last "Activer la dernière fenêtre ouverte" >
|
||||
<!ENTITY mail_notification_enabled.label "Autoriser la notification des courriers">
|
||||
<!ENTITY mail_notification_enabled.accesskey "A">
|
||||
<!ENTITY message_count_type.label "compter les messages :">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Une extension qui crée une zone de notification pour Linux
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Une extension qui crée une zone de notification.
|
||||
popupMenu.itemLabel.ResetIcon=Restaurer l'icône
|
||||
popupMenu.itemLabel.Preferences=Préférences
|
||||
popupMenu.itemLabel.Quit=Quitter
|
||||
popupMenu.itemLabel.NewWindow=Nouvelle fenêtre
|
||||
popupMenu.itemLabel.NewMessage=Nouveau message
|
||||
popupMenu.itemLabel.ShowHide=Montrer/Cacher
|
||||
popupMenu.itemLabel.ActivateLast=Activer la dernière fenêtre
|
||||
tooltip.unread_messages=#1 mesage non lu;#1 messages non lus
|
||||
tooltip.new_messages=Nouveaux messages !
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
<!ENTITY down "↓">
|
||||
<!ENTITY hide "sakrij">
|
||||
<!ENTITY restore "obnovi">
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
<!ENTITY mail_notification_enabled.label "Omogući obavijesti pošte">
|
||||
<!ENTITY mail_notification_enabled.accesskey "a">
|
||||
<!ENTITY message_count_type.label "broj vrsta poruka:">
|
||||
|
@ -51,8 +55,8 @@
|
|||
<!ENTITY mail_notification_unread_count.accesskey "U">
|
||||
<!ENTITY mail_notification_newmail_icon.label "prikaži ikonu pristigle pošte">
|
||||
<!ENTITY mail_notification_newmail_icon.accesskey "N">
|
||||
<!ENTITY mail_notification_custom_mail_icon.label "prikaži prilagođenu ikonu">
|
||||
<!ENTITY mail_notification_custom_mail_icon.accesskey "I">
|
||||
<!ENTITY mail_notification_mail_icon_custom.label "prikaži prilagođenu ikonu">
|
||||
<!ENTITY mail_notification_mail_icon_custom.accesskey "I">
|
||||
<!ENTITY icon_text_color "Boja teksta">
|
||||
<!ENTITY icon_text_color.accesskey "T">
|
||||
<!ENTITY choose "Odaberi">
|
||||
|
@ -77,8 +81,8 @@
|
|||
<!ENTITY mail_change_trigger.accesskey "L">
|
||||
<!ENTITY mail_change_trigger.placeholder "/bin/pošalji-obavijest">
|
||||
<!ENTITY mail_change_trigger.tooltip "Potpuna putanja programa koji će se pokrenuti kada se broj poruka promijeni. Taj program će dobiti novi broj poruka kao prvi argument.">
|
||||
<!ENTITY mail_urgency_hint.label "Postavi X11 napomenu hitnosti">
|
||||
<!ENTITY mail_urgency_hint.accesskey "X">
|
||||
<!ENTITY mail_get_attention.label "Postavi X11 napomenu hitnosti">
|
||||
<!ENTITY mail_get_attention.accesskey "X">
|
||||
<!ENTITY chat_icon_enable.label "Omogući ikonu čavrljanja">
|
||||
<!ENTITY chat_icon_enable.accesskey "E">
|
||||
<!ENTITY chat_icon_blink.label "Ikona čavrljanja blinka kod pristigle poruke">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Proširenje za traku sustava u linuxu.
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Proširenje za traku sustava.
|
||||
popupMenu.itemLabel.ResetIcon=Ponovno pokreni ikonu
|
||||
popupMenu.itemLabel.Preferences=Osobitosti
|
||||
popupMenu.itemLabel.Quit=Zatvori
|
||||
popupMenu.itemLabel.NewWindow=Novi prozor
|
||||
popupMenu.itemLabel.NewMessage=Nova poruka
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 nepročitana poruka;#1 nepročitano poruka
|
||||
tooltip.new_messages=Nove poruke!
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
<!ENTITY down "↓">
|
||||
<!ENTITY hide "Nascondi">
|
||||
<!ENTITY restore "Ripristina">
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
<!ENTITY mail_notification_enabled.label "Attiva notifiche e-mail">
|
||||
<!ENTITY mail_notification_enabled.accesskey "a">
|
||||
<!ENTITY message_count_type.label "Tipo di contatore messaggi:">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Permette di ridurre l'applicazione nell'area di notifica di Linux
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Permette di ridurre l'applicazione nell'area di notifica
|
||||
popupMenu.itemLabel.ResetIcon=Ripristina icona
|
||||
popupMenu.itemLabel.Preferences=Preferenze
|
||||
popupMenu.itemLabel.Quit=Esci
|
||||
popupMenu.itemLabel.NewWindow=Nuova finestra
|
||||
popupMenu.itemLabel.NewMessage=Nuovo messaggio
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 messaggio non letto;#1 messaggi non letti
|
||||
tooltip.new_messages=Nuovi messaggi
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
<!ENTITY down "↓">
|
||||
<!ENTITY hide "verbergen">
|
||||
<!ENTITY restore "herstellen">
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
<!ENTITY mail_notification_enabled.label "E-mailnotificatie inschakelen">
|
||||
<!ENTITY mail_notification_enabled.accesskey "a">
|
||||
<!ENTITY message_count_type.label "type berichttelling:">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Een systeemvakextensie voor Linux.
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Een systeemvakextensie.
|
||||
popupMenu.itemLabel.ResetIcon=Pictogram resetten
|
||||
popupMenu.itemLabel.Preferences=Preferences
|
||||
popupMenu.itemLabel.Quit=Stoppen
|
||||
popupMenu.itemLabel.NewWindow=Nieuw venster
|
||||
popupMenu.itemLabel.NewMessage=Nieuw bericht
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 ongelezen bericht;#1 ongelezen berichten
|
||||
tooltip.new_messages=Nieuwe berichten!
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
<!ENTITY down "↓" >
|
||||
<!ENTITY hide "ukrywa" >
|
||||
<!ENTITY restore "przywraca" >
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
|
||||
<!ENTITY mail_notification_enabled.label "Włącz powiadomienie o poczcie">
|
||||
<!ENTITY mail_notification_enabled.accesskey "i">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Rozszerzenie zasobnika dla linuxa.
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Rozszerzenie zasobnika.
|
||||
popupMenu.itemLabel.ResetIcon=Resetuj ikonę
|
||||
popupMenu.itemLabel.Preferences=Ustawienia
|
||||
popupMenu.itemLabel.Quit=Wyjdź
|
||||
popupMenu.itemLabel.NewWindow=Nowe okno
|
||||
popupMenu.itemLabel.NewMessage=Nowa wiadomość
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 nieprzeczytana wiadomość;#1 nieprzeczytane wiadomości
|
||||
tooltip.new_messages=Nowe wiadomości !
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
<!ENTITY down "↓" >
|
||||
<!ENTITY hide "скрыть" >
|
||||
<!ENTITY restore "показать" >
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
|
||||
<!ENTITY mail_notification_enabled.label "Включить оповещение о новых сообщениях">
|
||||
<!ENTITY mail_notification_enabled.accesskey "a">
|
||||
|
@ -57,8 +61,8 @@
|
|||
<!ENTITY mail_notification_unread_count.accesskey "U">
|
||||
<!ENTITY mail_notification_newmail_icon.label "показать значок новой почты">
|
||||
<!ENTITY mail_notification_newmail_icon.accesskey "N">
|
||||
<!ENTITY mail_notification_custom_mail_icon.label "показать выбранный значок">
|
||||
<!ENTITY mail_notification_custom_mail_icon.accesskey "I">
|
||||
<!ENTITY mail_notification_mail_icon_custom.label "показать выбранный значок">
|
||||
<!ENTITY mail_notification_mail_icon_custom.accesskey "I">
|
||||
<!ENTITY icon_text_color "Цвет текста">
|
||||
<!ENTITY icon_text_color.accesskey "T">
|
||||
<!ENTITY choose "Выбрать">
|
||||
|
@ -87,8 +91,8 @@
|
|||
<!ENTITY mail_change_trigger.accesskey "L">
|
||||
<!ENTITY mail_change_trigger.placeholder "/bin/notify-send">
|
||||
<!ENTITY mail_change_trigger.tooltip "Абсолютный путь к программе. В качестве первого аргумента будет передано количество сообщений">
|
||||
<!ENTITY mail_urgency_hint.label "Установить срочное оповещение X11">
|
||||
<!ENTITY mail_urgency_hint.accesskey "X">
|
||||
<!ENTITY mail_get_attention.label "Установить срочное оповещение X11">
|
||||
<!ENTITY mail_get_attention.accesskey "X">
|
||||
|
||||
<!ENTITY chat_icon_enable.label "Включить значок чата">
|
||||
<!ENTITY chat_icon_enable.accesskey "E">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Значок в трее для GNU/Linux
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Значок в трее
|
||||
popupMenu.itemLabel.ResetIcon=Обновить
|
||||
popupMenu.itemLabel.Preferences=Настройки
|
||||
popupMenu.itemLabel.Quit=Выход
|
||||
popupMenu.itemLabel.NewWindow=Новое окно
|
||||
popupMenu.itemLabel.NewMessage=Создать сообщение
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 непрочитанных сообщений;#1 непрочитанных сообщений
|
||||
tooltip.new_messages=Новые сообщения !
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
<!ENTITY down "↓" >
|
||||
<!ENTITY hide "skryť" >
|
||||
<!ENTITY restore "obnoviť" >
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
|
||||
<!ENTITY mail_notification_enabled.label "Zapnúť upozornenia pošty">
|
||||
<!ENTITY mail_notification_enabled.accesskey "a">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Linuxové rozšírenie pre oznamovaciu lištu
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Rozšírenie pre oznamovaciu lištu
|
||||
popupMenu.itemLabel.ResetIcon=Obnoviť ikonu
|
||||
popupMenu.itemLabel.Preferences=Preferences
|
||||
popupMenu.itemLabel.Quit=Koniec
|
||||
popupMenu.itemLabel.NewWindow=Nové okno
|
||||
popupMenu.itemLabel.NewMessage=Nová správa
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 neprečítaná správa;#1 neprečítané správy;#1 neprečítaných správ
|
||||
tooltip.new_messages=Nové správy!
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
<!-- if you need multiline/carriage return, use a .properties -->
|
||||
<!ENTITY prefwindow.title "FireTray вподобання">
|
||||
|
||||
<!ENTITY NOT_IMPLEMENTED_YET "ЩЕ НЕ РЕАЛІЗОВАНО.">
|
||||
|
||||
<!ENTITY windows_options "Вікна">
|
||||
<!ENTITY icon_options "Піктограма">
|
||||
<!ENTITY mail_options "Пошта">
|
||||
<!ENTITY chat_options "Чат">
|
||||
|
||||
<!ENTITY hides_on_close.label "Закрите вікно приховувати до трею">
|
||||
<!ENTITY hides_on_close.accesskey "З">
|
||||
<!ENTITY hides_on_minimize.label "Згорнуте вікно приховувати до трею">
|
||||
<!ENTITY hides_on_minimize.accesskey "г">
|
||||
<!ENTITY hides_single_window.label "Ховати вікна індівілуально">
|
||||
<!ENTITY hides_single_window.tooltip "не всі вікна відразу">
|
||||
<!ENTITY hides_single_window.accesskey "н">
|
||||
<!ENTITY hides_last_only.label "Тільки останнє вікно може бути приховане">
|
||||
<!ENTITY hides_last_only.tooltip "інші вікна будуть закриті (припинені)">
|
||||
<!ENTITY hides_last_only.accesskey "і">
|
||||
<!ENTITY start_hidden.label "Запуск додатка прихованим в трей">
|
||||
<!ENTITY start_hidden.accesskey "п">
|
||||
<!ENTITY show_activates.label "Активувате відновлені вікна">
|
||||
<!ENTITY show_activates.accesskey "А">
|
||||
<!ENTITY show_activates.tooltip "відновлені вікна підняти вгору та показати">
|
||||
<!ENTITY remember_desktop.label "Відновити вікна у їх вихідному робочому столі">
|
||||
<!ENTITY remember_desktop.accesskey "р">
|
||||
|
||||
<!ENTITY show_icon_on_hide.label "Показувати піктограму у треї тільки коли вікно приховане">
|
||||
<!ENTITY show_icon_on_hide.accesskey "ї">
|
||||
<!ENTITY app_icon_type "Тип значку розширення">
|
||||
<!ENTITY app_icon_themed.label "Типова тема">
|
||||
<!ENTITY app_icon_themed.accesskey "Т">
|
||||
<!ENTITY app_icon_themed_name "Назва значку">
|
||||
<!ENTITY icon_themed.tooltip "Назва значків, що надаються графічним середовищем">
|
||||
<!ENTITY app_icon_custom.label "Власний">
|
||||
<!ENTITY app_icon_custom.accesskey "с">
|
||||
|
||||
<!ENTITY mouse_wheel_options "Параметри коліщата миші">
|
||||
<!ENTITY enable_mouse_scroll.label "Прокрутка миші на іконці трея">
|
||||
<!ENTITY enable_mouse_scroll.accesskey "я">
|
||||
<!ENTITY up "↑">
|
||||
<!ENTITY down "↓">
|
||||
<!ENTITY hide "сховати">
|
||||
<!ENTITY restore "відновити">
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
|
||||
<!ENTITY mail_notification_enabled.label "Включити поштові повідомлення">
|
||||
<!ENTITY mail_notification_enabled.accesskey "ю">
|
||||
<!ENTITY message_count_type.label "тип лічильника повідомлень:">
|
||||
<!ENTITY message_count_type.accesskey "л">
|
||||
<!ENTITY message_count_type_unread "непрочитані повідомлення">
|
||||
<!ENTITY message_count_type_new "нові повідомлення">
|
||||
<!ENTITY message_count_type_new.tooltip "нові повідомлення з останнього заходу.">
|
||||
<!ENTITY mail_notification_type.label "Тип поштових повідомлень">
|
||||
<!ENTITY mail_notification_type.tooltip "aka. Biff">
|
||||
<!ENTITY mail_notification_unread_count.label "показувати лічильник нових повідомлень">
|
||||
<!ENTITY mail_notification_unread_count.accesskey "н">
|
||||
<!ENTITY mail_notification_newmail_icon.label "показувати значок нових повідомлень">
|
||||
<!ENTITY mail_notification_newmail_icon.accesskey "з">
|
||||
<!ENTITY mail_notification_mail_icon_custom.label "показувати власний значок">
|
||||
<!ENTITY mail_notification_mail_icon_custom.accesskey "в">
|
||||
<!ENTITY icon_text_color "Колір тексту">
|
||||
<!ENTITY icon_text_color.accesskey "К">
|
||||
<!ENTITY choose "Обрати">
|
||||
<!ENTITY choose.accesskey "О">
|
||||
|
||||
<!ENTITY unread_count_folder_exceptions.label "Включити спеціальні теки">
|
||||
<!ENTITY unread_count_folder_exceptions.tooltip "Включити спеціальні теки до підрахунку непрочитаних повідомлень">
|
||||
<!ENTITY excluded_folders_list.tooltip "Використовуйте CTRL + ліве клацання мишею, щоб вибрати/скасувати теки для лічильника нових повідомлень">
|
||||
|
||||
<!ENTITY unread_count_account_exceptions.label "Включені облікові записи">
|
||||
<!ENTITY unread_count_account_exceptions.tooltip "Включені облікові записи для лічильника непрочитаних повідомлень">
|
||||
<!ENTITY folder_count_recursive.label "включити вкладені теки">
|
||||
<!ENTITY folder_count_recursive.accesskey "л">
|
||||
<!ENTITY only_favorite_folders.label "Тільки обрані теки">
|
||||
<!ENTITY only_favorite_folders.accesskey "о">
|
||||
<!ENTITY only_favorite_folders.tooltip "Підрахунок повідомлень лише у обраних теках">
|
||||
|
||||
<!ENTITY account_or_server_type_name "Обліковий запис">
|
||||
<!ENTITY account_or_server_type_name.tooltip "Ім'я чи тип облікового запису">
|
||||
<!ENTITY account_or_server_type_excluded "Включені">
|
||||
<!ENTITY account_or_server_type_excluded.tooltip "Включені облікові записи чи типи до лічильника непрочитаних повідомлень">
|
||||
<!ENTITY account_or_server_type_order "Порядок">
|
||||
<!ENTITY account_or_server_type_order.tooltip "Порядок в якому відображаються типи поштових серверів. Зробіть подвійне клацання, щоб редагувати.">
|
||||
|
||||
<!ENTITY mail_change_trigger.label "Запуск при зміні кількості:">
|
||||
<!ENTITY mail_change_trigger.accesskey "З">
|
||||
<!ENTITY mail_change_trigger.placeholder "/кошик/повідомити-відправити">
|
||||
<!ENTITY mail_change_trigger.tooltip "Абсолютний шлях запуску програми при зміні кількості повідомлень. Ця програма буде отримувати нову кількість повідомлень як перший аргумент.">
|
||||
<!ENTITY mail_get_attention.label "Вікно концентрується на нових повідомленнях">
|
||||
<!ENTITY mail_get_attention.accesskey "х">
|
||||
|
||||
|
||||
<!ENTITY chat_icon_enable.label "Включити значок чату">
|
||||
<!ENTITY chat_icon_enable.accesskey "ч">
|
||||
<!ENTITY chat_icon_blink.label "Значок чату блимає при наявності нових повідомлень">
|
||||
<!ENTITY chat_icon_blink.accesskey "б">
|
||||
<!ENTITY chat_icon_blink.tooltip "коли приватне повідомлення або цитата в каналі">
|
||||
|
||||
<!ENTITY chat_icon_blink_style.label "Стиль блимання">
|
||||
<!ENTITY chat_icon_blink_style.accesskey "С">
|
||||
<!ENTITY chat_icon_blink_style_normal "Звичайний">
|
||||
<!ENTITY chat_icon_blink_style_fade "Затихаючий">
|
|
@ -0,0 +1,8 @@
|
|||
Archive=Архів
|
||||
Drafts=Чернетки
|
||||
Junk=Мотлох
|
||||
Queue=Черга
|
||||
SentMail=Надіслані
|
||||
Templates=Тимчасові
|
||||
Trash=Кошик
|
||||
Virtual=Віртуальний
|
|
@ -0,0 +1 @@
|
|||
<!ENTITY firetray.label "Мій локалізований пункт меню">
|
|
@ -0,0 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Розширення системного лотка для Linux.
|
||||
popupMenu.itemLabel.ResetIcon=Піктограма скидання
|
||||
popupMenu.itemLabel.Preferences=Вподобання
|
||||
popupMenu.itemLabel.Quit=Вийти
|
||||
popupMenu.itemLabel.NewWindow=Нове вікно
|
||||
popupMenu.itemLabel.NewMessage=Нове повідомлення
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 непрочитане повідомлення;#1 непрочитані повідомлення
|
||||
tooltip.new_messages=Нові повідомлення!
|
|
@ -38,6 +38,10 @@
|
|||
<!ENTITY down "↓">
|
||||
<!ENTITY hide "隱藏">
|
||||
<!ENTITY restore "恢復">
|
||||
<!ENTITY middle_click.label "Mouse middle click action :" >
|
||||
<!ENTITY middle_click.accesskey "k" >
|
||||
<!ENTITY show_hide "Show/hide" >
|
||||
<!ENTITY activate_last "Activate last window" >
|
||||
<!ENTITY mail_notification_enabled.label "啟用郵件通知">
|
||||
<!ENTITY mail_notification_enabled.accesskey "A">
|
||||
<!ENTITY message_count_type.label "郵件計數器類型:">
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=Linux 用的系統列套件。
|
||||
extensions.{9533f794-00b4-4354-aa15-c2bbda6989f8}.description=用的系統列套件。
|
||||
popupMenu.itemLabel.ResetIcon=重設圖示
|
||||
popupMenu.itemLabel.Preferences=Preferences
|
||||
popupMenu.itemLabel.Quit=結束
|
||||
popupMenu.itemLabel.NewWindow=開新視窗
|
||||
popupMenu.itemLabel.NewMessage=新增訊息
|
||||
popupMenu.itemLabel.ShowHide=Show/Hide
|
||||
popupMenu.itemLabel.ActivateLast=Activate last window
|
||||
tooltip.unread_messages=#1 封未讀訊息;#1 封未讀訊息
|
||||
tooltip.new_messages=有新訊息!
|
||||
|
|
|
@ -15,12 +15,12 @@ treechildren::-moz-tree-checkbox(checked, disabled) {
|
|||
|
||||
/* properties="disabled" */
|
||||
treechildren::-moz-tree-cell-text(disabled) {
|
||||
color: GrayText;
|
||||
color: GrayText;
|
||||
}
|
||||
|
||||
/*
|
||||
treechildren::-moz-tree-cell(disabled) {
|
||||
background-color: #eeeeee;
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ pref("extensions.firetray.new_mail_icon_names", '["indicator-messages-new", "mai
|
|||
pref("extensions.firetray.show_icon_on_hide", false);
|
||||
pref("extensions.firetray.scroll_hides", true);
|
||||
pref("extensions.firetray.scroll_mode", "down_hides");
|
||||
pref("extensions.firetray.middle_click", 0);
|
||||
pref("extensions.firetray.chat_icon_enable", true);
|
||||
pref("extensions.firetray.chat_icon_blink", true);
|
||||
pref("extensions.firetray.chat_icon_blink_style", 0);
|
||||
|
@ -38,3 +39,5 @@ pref("extensions.firetray.excluded_folders_flags", 1077956384);
|
|||
// exposed in 1 tree, hence 2 branches: serverTypes, excludedAccounts
|
||||
pref("extensions.firetray.mail_accounts", '{ "serverTypes": {"pop3":{"order":1,"excluded":false}, "imap":{"order":1,"excluded":false}, "movemail":{"order":2,"excluded":true}, "none":{"order":3,"excluded":false}, "rss":{"order":4,"excluded":true}, "nntp":{"order":5,"excluded":true}, "exquilla":{"order":6,"excluded":true}}, "excludedAccounts": [] }'); // JSON
|
||||
pref("extensions.firetray.only_favorite_folders", false);
|
||||
|
||||
pref("extensions.firetray.with_appindicator", true);
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
<em:unpack>true</em:unpack> <!-- needed for embedded icons -->
|
||||
<em:type>2</em:type>
|
||||
<em:name>FireTray</em:name>
|
||||
<em:version>0.5.0b2</em:version> <!-- change FIRETRAY_VERSION accordingly ! -->
|
||||
<em:version>0.5.4</em:version> <!-- change FIRETRAY_VERSION accordingly ! -->
|
||||
<em:creator>Hua Luo, Francesco Solero, Foudil BRÉTEL</em:creator>
|
||||
<em:contributor>Hua Luo, Francesco Solero (Firetray original authors)</em:contributor>
|
||||
<em:homepageURL>https://github.com/foudfou/firetray</em:homepageURL>
|
||||
<em:description>A system tray extension for linux.</em:description>
|
||||
<em:description>A system tray extension.</em:description>
|
||||
<em:optionsURL>chrome://firetray/content/options.xul</em:optionsURL>
|
||||
<em:iconURL>chrome://firetray/skin/icons/firetray48.png</em:iconURL>
|
||||
<em:icon64URL>chrome://firetray/skin/icons/firetray64.png</em:icon64URL>
|
||||
|
@ -21,7 +21,7 @@
|
|||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- Firefox -->
|
||||
<em:minVersion>7.0</em:minVersion>
|
||||
<em:maxVersion>35.0</em:maxVersion>
|
||||
<em:maxVersion>38.0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
|||
<Description>
|
||||
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
|
||||
<em:minVersion>7.0</em:minVersion>
|
||||
<em:maxVersion>35.0</em:maxVersion>
|
||||
<em:maxVersion>38.0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
|||
<Description>
|
||||
<em:id>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</em:id>
|
||||
<em:minVersion>2.4</em:minVersion>
|
||||
<em:maxVersion>2.32</em:maxVersion>
|
||||
<em:maxVersion>2.35</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
@ -98,7 +98,7 @@
|
|||
<Description>
|
||||
<em:locale>de-DE</em:locale>
|
||||
<em:translator>Florian Haftmann</em:translator>
|
||||
<em:description>Tray-Erweiterung für GNU/Linux.</em:description>
|
||||
<em:description>Tray-Erweiterung.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
@ -106,7 +106,7 @@
|
|||
<Description>
|
||||
<em:locale>es-AR</em:locale>
|
||||
<em:translator>profediego@gmail.com</em:translator>
|
||||
<em:description>Una extensión para la bandeja del sistema en linux.</em:description>
|
||||
<em:description>Una extensión para la bandeja del sistema.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
@ -116,7 +116,7 @@
|
|||
<em:translator>Goofy</em:translator>
|
||||
<em:translator>Jojaba - BabelZilla</em:translator>
|
||||
<em:translator>nico@nc</em:translator>
|
||||
<em:description>Une extension qui crée une zone de notification pour Linux.</em:description>
|
||||
<em:description>Une extension qui crée une zone de notification.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
@ -124,7 +124,7 @@
|
|||
<Description>
|
||||
<em:locale>hr-HR</em:locale>
|
||||
<em:translator>Goran Vidović (gogo)</em:translator>
|
||||
<em:description>Proširenje za traku sustava u linuxu.</em:description>
|
||||
<em:description>Proširenje za traku sustava.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
@ -132,7 +132,7 @@
|
|||
<Description>
|
||||
<em:locale>it</em:locale>
|
||||
<em:translator>Underpass (mozillaitalia.org)</em:translator>
|
||||
<em:description>Permette di ridurre l'applicazione nell'area di notifica di Linux.</em:description>
|
||||
<em:description>Permette di ridurre l'applicazione nell'area di notifica.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
@ -140,7 +140,7 @@
|
|||
<Description>
|
||||
<em:locale>nl</em:locale>
|
||||
<em:translator>markh van BabelZilla.org</em:translator>
|
||||
<em:description>Een systeemvakextensie voor Linux.</em:description>
|
||||
<em:description>Een systeemvakextensie.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
@ -148,7 +148,7 @@
|
|||
<Description>
|
||||
<em:locale>pl-PL</em:locale>
|
||||
<em:translator>AreYouLoco?</em:translator>
|
||||
<em:description>Rozszerzenie zasobnika dla linuxa.</em:description>
|
||||
<em:description>Rozszerzenie zasobnika.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
@ -156,7 +156,7 @@
|
|||
<Description>
|
||||
<em:locale>sk-SK</em:locale>
|
||||
<em:translator>Slavko slavino.sk</em:translator>
|
||||
<em:description>Linuxové rozšírenie pre oznamovaciu lištu.</em:description>
|
||||
<em:description>Rozšírenie pre oznamovaciu lištu.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
@ -164,7 +164,15 @@
|
|||
<Description>
|
||||
<em:locale>ru-RU</em:locale>
|
||||
<em:translator>VitalD</em:translator>
|
||||
<em:description>Значок в трее для GNU/Linux.</em:description>
|
||||
<em:description>Значок в трее.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
<em:localized>
|
||||
<Description>
|
||||
<em:locale>uk-UA</em:locale>
|
||||
<em:translator>Володимир Савчук Volodymyr Savchuk</em:translator>
|
||||
<em:description>Розширення системного лотка.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
@ -172,7 +180,7 @@
|
|||
<Description>
|
||||
<em:locale>zh-TW</em:locale>
|
||||
<em:translator>Velociraptor</em:translator>
|
||||
<em:description>Linux 用的系統列套件。</em:description>
|
||||
<em:description>用的系統列套件。</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
||||
|
|
|
@ -62,15 +62,15 @@ firetray.Handler = {
|
|||
}
|
||||
throw new Error("not resolved");
|
||||
})(),
|
||||
support: {chat: false, full_feat: false},
|
||||
support: {chat: false, winnt: false},
|
||||
|
||||
init: function() { // does creates icon
|
||||
firetray.PrefListener.register(false);
|
||||
firetray.MailChatPrefListener.register(false);
|
||||
|
||||
log.info("OS=" + this.runtimeOS + ", ABI=" + this.runtimeABI + ", XULrunner=" + this.xulVer);
|
||||
if (FIRETRAY_SUPPORTED_OS.indexOf(this.runtimeOS) < 0) {
|
||||
let platforms = FIRETRAY_SUPPORTED_OS.join(", ");
|
||||
if (FIRETRAY_OS_SUPPORT.indexOf(this.runtimeOS) < 0) {
|
||||
let platforms = FIRETRAY_OS_SUPPORT.join(", ");
|
||||
log.error("Only "+platforms+" platform(s) supported at this time. Firetray not loaded");
|
||||
return false;
|
||||
} else if (this.runtimeOS == "winnt" &&
|
||||
|
@ -83,9 +83,8 @@ firetray.Handler = {
|
|||
Cu.import("resource://firetray/"+this.runtimeOS+"/FiretrayWindow.jsm");
|
||||
log.debug("FiretrayWindow "+this.runtimeOS+" imported");
|
||||
|
||||
this.support['chat'] = FIRETRAY_CHAT_SUPPORTED_OS
|
||||
.indexOf(this.runtimeOS) > -1;
|
||||
this.support['full_feat'] = FIRETRAY_FULL_FEAT_SUPPORTED_OS
|
||||
this.support['chat'] = ['linux'].indexOf(this.runtimeOS) > -1;
|
||||
this.support['winnt'] = ['winnt']
|
||||
.indexOf(firetray.Handler.runtimeOS) > -1;
|
||||
|
||||
if (this.appId === FIRETRAY_APP_DB['thunderbird']['id'] ||
|
||||
|
@ -131,8 +130,7 @@ firetray.Handler = {
|
|||
this.existsChatAccount())
|
||||
firetray.Chat.init();
|
||||
} else {
|
||||
let platforms = FIRETRAY_CHAT_SUPPORTED_OS.join(", ");
|
||||
log.warn("Only "+platforms+" platform(s) supported at this time. Chat not loaded");
|
||||
log.warn("Chat not supported for this platform. Chat not loaded");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +156,7 @@ firetray.Handler = {
|
|||
VersionChange.init(FIRETRAY_ID, FIRETRAY_VERSION, FIRETRAY_PREF_BRANCH);
|
||||
let vc = VersionChange, vch = firetray.VersionChangeHandler;
|
||||
vc.addHook(["install", "upgrade", "reinstall"], vch.showReleaseNotes);
|
||||
vc.addHook(["upgrade", "reinstall"], vch.tryEraseOldOptions);
|
||||
vc.addHook(["upgrade", "reinstall"], vch.deleteOrRenameOldOptions);
|
||||
vc.addHook(["upgrade", "reinstall"], vch.correctMailNotificationType);
|
||||
vc.addHook(["upgrade", "reinstall"], vch.correctMailServerTypes);
|
||||
if (this.inMailApp) {
|
||||
|
@ -201,6 +199,14 @@ firetray.Handler = {
|
|||
return this.appHasChat && Services.prefs.getBoolPref("mail.chat.enabled");
|
||||
},
|
||||
|
||||
subscribeLibsForClosing: function(libs) {
|
||||
for (let i=0, len=libs.length; i<len; ++i) {
|
||||
let lib = libs[i];
|
||||
if (!this.ctypesLibs.hasOwnProperty(lib.name))
|
||||
this.ctypesLibs[lib.name] = lib;
|
||||
}
|
||||
},
|
||||
|
||||
tryCloseLibs: function() {
|
||||
try {
|
||||
for (let libName in this.ctypesLibs) {
|
||||
|
@ -211,14 +217,6 @@ firetray.Handler = {
|
|||
} catch(x) { log.error(x); }
|
||||
},
|
||||
|
||||
subscribeLibsForClosing: function(libs) {
|
||||
for (let i=0, len=libs.length; i<len; ++i) {
|
||||
let lib = libs[i];
|
||||
if (!this.ctypesLibs.hasOwnProperty(lib.name))
|
||||
this.ctypesLibs[lib.name] = lib;
|
||||
}
|
||||
},
|
||||
|
||||
readTBRestoreWindowsCount: function() {
|
||||
Cu.import("resource:///modules/IOUtils.js");
|
||||
let sessionFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
|
||||
|
@ -328,6 +326,7 @@ firetray.Handler = {
|
|||
},
|
||||
|
||||
// these get overridden in OS-specific Icon/Window handlers
|
||||
loadIcons: function() {},
|
||||
setIconImageDefault: function() {},
|
||||
setIconImageNewMail: function() {},
|
||||
setIconImageCustom: function(prefname) {},
|
||||
|
@ -376,11 +375,10 @@ firetray.Handler = {
|
|||
},
|
||||
|
||||
onMinimize: function(wid) {
|
||||
log.debug("onMinimize");
|
||||
let hidden = false;
|
||||
let hides_on_minimize = firetray.Utils.prefService.getBoolPref('hides_on_minimize');
|
||||
if (hides_on_minimize) {
|
||||
let hides_single_window = firetray.Utils.prefService.getBoolPref('hides_single_window');
|
||||
if (hides_single_window)
|
||||
if (firetray.Utils.prefService.getBoolPref('hides_on_minimize')) {
|
||||
if (firetray.Utils.prefService.getBoolPref('hides_single_window'))
|
||||
firetray.Handler.hideWindow(wid);
|
||||
else
|
||||
firetray.Handler.hideAllWindows();
|
||||
|
@ -552,7 +550,7 @@ firetray.PrefListener = new PrefListener(
|
|||
firetray.Messaging.updateIcon();
|
||||
break;
|
||||
case 'new_mail_icon_names':
|
||||
firetray.StatusIcon.loadThemedIcons();
|
||||
this.loadIcons();
|
||||
case 'excluded_folders_flags':
|
||||
case 'folder_count_recursive':
|
||||
case 'mail_accounts':
|
||||
|
@ -563,7 +561,7 @@ firetray.PrefListener = new PrefListener(
|
|||
case 'app_mail_icon_names':
|
||||
case 'app_browser_icon_names':
|
||||
case 'app_default_icon_names':
|
||||
firetray.StatusIcon.loadThemedIcons(); // linux
|
||||
this.loadIcons(); // linux
|
||||
case 'app_icon_custom':
|
||||
case 'mail_icon_custom':
|
||||
firetray.StatusIcon.loadImageCustom(name);
|
||||
|
@ -573,6 +571,10 @@ firetray.PrefListener = new PrefListener(
|
|||
firetray.Messaging.updateMsgCountWithCb();
|
||||
break;
|
||||
|
||||
case 'middle_click':
|
||||
firetray.StatusIcon.middleClickActionChanged();
|
||||
break;
|
||||
|
||||
case 'chat_icon_enable':
|
||||
firetray.Handler.toggleChat(firetray.Handler.isChatEnabled());
|
||||
break;
|
||||
|
@ -709,7 +711,7 @@ firetray.VersionChangeHandler = {
|
|||
} catch (e) {log.error(e);}
|
||||
},
|
||||
|
||||
tryEraseOldOptions: function() {
|
||||
deleteOrRenameOldOptions: function() {
|
||||
let v0_3_Opts = [
|
||||
"close_to_tray", "minimize_to_tray", "start_minimized", "confirm_exit",
|
||||
"restore_to_next_unread", "mail_count_type", "show_mail_count",
|
||||
|
@ -720,8 +722,7 @@ firetray.VersionChangeHandler = {
|
|||
"text_color", "scroll_to_hide", "scroll_action", "grab_multimedia_keys",
|
||||
"hide_show_mm_key", "accounts_to_exclude" ];
|
||||
let v0_4_0b2_Opts = [ 'mail_notification' ];
|
||||
let v0_5_0b1_Opts = [ 'mail_urgency_hint', 'app_icon_filename', 'custom_mail_icon' ];
|
||||
let oldOpts = v0_3_Opts.concat(v0_4_0b2_Opts).concat(v0_5_0b1_Opts);
|
||||
let oldOpts = v0_3_Opts.concat(v0_4_0b2_Opts);
|
||||
|
||||
for (let i=0, len=oldOpts.length; i<len; ++i) {
|
||||
try {
|
||||
|
@ -729,6 +730,35 @@ firetray.VersionChangeHandler = {
|
|||
firetray.Utils.prefService.clearUserPref(option);
|
||||
} catch (x) {}
|
||||
}
|
||||
|
||||
let v0_5_0b1_Renames = {
|
||||
'mail_urgency_hint': 'mail_get_attention',
|
||||
'app_icon_filename': 'app_icon_custom',
|
||||
'custom_mail_icon': 'mail_icon_custom'
|
||||
};
|
||||
oldOpts = v0_5_0b1_Renames;
|
||||
|
||||
let prefSrv = firetray.Utils.prefService;
|
||||
for (let opt in oldOpts) {
|
||||
log.debug("opt rename: "+opt);
|
||||
if (prefSrv.prefHasUserValue(opt)) {
|
||||
let prefType = prefSrv.getPrefType(opt);
|
||||
switch (prefType) {
|
||||
case Ci.nsIPrefBranch.PREF_STRING:
|
||||
prefSrv.setCharPref(oldOpts[opt], prefSrv.getCharPref(opt));
|
||||
break;
|
||||
case Ci.nsIPrefBranch.PREF_INT:
|
||||
prefSrv.setIntPref(oldOpts[opt], prefSrv.getIntPref(opt));
|
||||
break;
|
||||
case Ci.nsIPrefBranch.PREF_BOOL:
|
||||
prefSrv.setBoolPref(oldOpts[opt], prefSrv.getBoolPref(opt));
|
||||
break;
|
||||
default:
|
||||
log.error("Unknow pref type: "+prefType);
|
||||
}
|
||||
}
|
||||
try { prefSrv.clearUserPref(opt); } catch (x) {}
|
||||
}
|
||||
},
|
||||
|
||||
correctMailNotificationType: function() {
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
/* for now, logging facilities (imported from logging.jsm) and Services are
|
||||
automatically provided by this module */
|
||||
var EXPORTED_SYMBOLS =
|
||||
[ "firetray", "FIRETRAY_VERSION", "FIRETRAY_SUPPORTED_OS",
|
||||
"FIRETRAY_CHAT_SUPPORTED_OS", "FIRETRAY_FULL_FEAT_SUPPORTED_OS",
|
||||
"FIRETRAY_ID", "FIRETRAY_PREF_BRANCH", "FIRETRAY_SPLASH_PAGE",
|
||||
[ "firetray", "FIRETRAY_VERSION", "FIRETRAY_OS_SUPPORT", "FIRETRAY_ID",
|
||||
"FIRETRAY_PREF_BRANCH", "FIRETRAY_SPLASH_PAGE",
|
||||
"FIRETRAY_APPLICATION_ICON_TYPE_THEMED",
|
||||
"FIRETRAY_APPLICATION_ICON_TYPE_CUSTOM",
|
||||
"FIRETRAY_MIDDLE_CLICK_ACTIVATE_LAST", "FIRETRAY_MIDDLE_CLICK_SHOW_HIDE",
|
||||
"FIRETRAY_NOTIFICATION_MESSAGE_COUNT",
|
||||
"FIRETRAY_NOTIFICATION_NEWMAIL_ICON", "FIRETRAY_NOTIFICATION_CUSTOM_ICON",
|
||||
"FIRETRAY_IM_STATUS_AVAILABLE", "FIRETRAY_IM_STATUS_AWAY",
|
||||
|
@ -15,8 +15,8 @@ var EXPORTED_SYMBOLS =
|
|||
"FIRETRAY_ACCOUNT_SERVER_TYPE_IM", "FIRETRAY_DELAY_STARTUP_MILLISECONDS",
|
||||
"FIRETRAY_DELAY_NOWAIT_MILLISECONDS", "FIRETRAY_MESSAGE_COUNT_TYPE_UNREAD",
|
||||
"FIRETRAY_MESSAGE_COUNT_TYPE_NEW", "FIRETRAY_CHAT_ICON_BLINK_STYLE_NORMAL",
|
||||
"FIRETRAY_CHAT_ICON_BLINK_STYLE_FADE", "FIRETRAY_APP_DB",
|
||||
"FIRETRAY_XUL_ATTRIBUTE_COMMAND", "FIRETRAY_XUL_ATTRIBUTE_ONCOMMAND" ];
|
||||
"FIRETRAY_CHAT_ICON_BLINK_STYLE_FADE", "FIRETRAY_APPINDICATOR_ID",
|
||||
"FIRETRAY_APP_DB", "FIRETRAY_CB_SENTINEL" ];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
@ -25,17 +25,18 @@ const Cu = Components.utils;
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://firetray/logging.jsm");
|
||||
|
||||
const FIRETRAY_VERSION = "0.5.0b2"; // needed for sync call of onVersionChange() :(
|
||||
const FIRETRAY_SUPPORTED_OS = ['linux', 'winnt']; // install.rdf sync :(
|
||||
const FIRETRAY_CHAT_SUPPORTED_OS = ['linux'];
|
||||
const FIRETRAY_FULL_FEAT_SUPPORTED_OS = FIRETRAY_CHAT_SUPPORTED_OS;
|
||||
const FIRETRAY_ID = "{9533f794-00b4-4354-aa15-c2bbda6989f8}";
|
||||
const FIRETRAY_PREF_BRANCH = "extensions.firetray.";
|
||||
const FIRETRAY_SPLASH_PAGE = "http://foudfou.github.com/FireTray/";
|
||||
const FIRETRAY_VERSION = "0.5.4"; // needed for sync call of onVersionChange() :(
|
||||
const FIRETRAY_OS_SUPPORT = ['linux', 'winnt']; // install.rdf sync :(
|
||||
const FIRETRAY_ID = "{9533f794-00b4-4354-aa15-c2bbda6989f8}";
|
||||
const FIRETRAY_PREF_BRANCH = "extensions.firetray.";
|
||||
const FIRETRAY_SPLASH_PAGE = "http://foudfou.github.com/FireTray/";
|
||||
|
||||
const FIRETRAY_APPLICATION_ICON_TYPE_THEMED = 0;
|
||||
const FIRETRAY_APPLICATION_ICON_TYPE_CUSTOM = 1;
|
||||
|
||||
const FIRETRAY_MIDDLE_CLICK_ACTIVATE_LAST = 0;
|
||||
const FIRETRAY_MIDDLE_CLICK_SHOW_HIDE = 1;
|
||||
|
||||
const FIRETRAY_MESSAGE_COUNT_TYPE_UNREAD = 0;
|
||||
const FIRETRAY_MESSAGE_COUNT_TYPE_NEW = 1;
|
||||
|
||||
|
@ -56,8 +57,7 @@ const FIRETRAY_DELAY_NOWAIT_MILLISECONDS = 0;
|
|||
const FIRETRAY_CHAT_ICON_BLINK_STYLE_NORMAL = 0;
|
||||
const FIRETRAY_CHAT_ICON_BLINK_STYLE_FADE = 1;
|
||||
|
||||
const FIRETRAY_XUL_ATTRIBUTE_COMMAND = 0;
|
||||
const FIRETRAY_XUL_ATTRIBUTE_ONCOMMAND = 1;
|
||||
const FIRETRAY_APPINDICATOR_ID = "firetray";
|
||||
|
||||
const FIRETRAY_APP_DB = {
|
||||
|
||||
|
@ -91,6 +91,28 @@ const FIRETRAY_APP_DB = {
|
|||
|
||||
};
|
||||
|
||||
/*
|
||||
* Debugging purpose: if a callback fails (like "expected type int, got (void
|
||||
* 0)"), there is no easy way to find out which (for ex. when called through
|
||||
* g_signal_connect()). A possible way is to remove the sentinel definition on
|
||||
* each callback definition one-by-one. For ex:
|
||||
*
|
||||
* let callback = gtk.GCallbackWidgetFocusEvent_t(
|
||||
* firetray.Window.onFocusIn, null, FIRETRAY_CB_SENTINEL);
|
||||
*
|
||||
* becomes
|
||||
*
|
||||
* let callback = gtk.GCallbackWidgetFocusEvent_t(
|
||||
* firetray.Window.onFocusIn);
|
||||
*
|
||||
* and see if the the message "JavaScript callback failed, and an error
|
||||
* sentinel was not specified" appears in the console.
|
||||
*
|
||||
* Note: it's not possible to define a sentinel when the return type is void.
|
||||
* Note: almost all return types end up as int's (even gboolean).
|
||||
*/
|
||||
const FIRETRAY_CB_SENTINEL = -1;
|
||||
|
||||
/**
|
||||
* firetray namespace.
|
||||
*/
|
||||
|
@ -195,17 +217,7 @@ firetray.Utils = {
|
|||
return protocolHandler.getFileFromURLSpec(aPath).path;
|
||||
},
|
||||
|
||||
dumpObj: function(obj) {
|
||||
let str = "";
|
||||
for(let prop in firetray.js.listAllProperties(obj)) {
|
||||
try {
|
||||
str += "obj["+prop+"]: " + obj[prop] + "\n";
|
||||
} catch(e) {
|
||||
str += "obj["+prop+"]: Unavailable\n";
|
||||
}
|
||||
}
|
||||
log.info(str);
|
||||
},
|
||||
dumpObj: function(obj) {}, // Use JSON.stringify(obj) instead.
|
||||
|
||||
_nsResolver: function(prefix) {
|
||||
var ns = {
|
||||
|
|
|
@ -119,17 +119,15 @@ function ctypes_library(aName, aABIs, aDefines, aGlobal) {
|
|||
for each (let abi in aABIs) {
|
||||
// FIXME: ABI is in fact SO_VER. Now we're mixing .so versions and the
|
||||
// .dll extension :(
|
||||
let soname = abi === 'dll' ? aName :
|
||||
let libname = abi === 'dll' ? aName :
|
||||
"lib" + aName + ".so." + abi.toString();
|
||||
log.debug("Trying " + soname);
|
||||
log.debug("Trying " + libname);
|
||||
try {
|
||||
library = ctypes.open(soname);
|
||||
library = ctypes.open(libname);
|
||||
this.ABI = abi;
|
||||
log.debug("Successfully loaded " + soname);
|
||||
log.debug("Successfully loaded " + libname);
|
||||
break;
|
||||
} catch(e) {
|
||||
log.error(soname+" unfound.");
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
this.name = aName;
|
||||
|
@ -153,7 +151,7 @@ function ctypes_library(aName, aABIs, aDefines, aGlobal) {
|
|||
};
|
||||
|
||||
if (!library) {
|
||||
log.debug("Failed to load library: " + aName);
|
||||
log.info("Library does not exist: " + aName);
|
||||
this.ABI = -1;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
var EXPORTED_SYMBOLS = [ "appind3" ];
|
||||
|
||||
const APPINDICATOR_LIBNAME = "appindicator3";
|
||||
const APPINDICATOR_ABIS = [ 1 ];
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||
Cu.import("resource://firetray/ctypes/ctypes-utils.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gtk.jsm");
|
||||
|
||||
function appindicator_defines(lib) {
|
||||
this.AppIndicator = ctypes.StructType("AppIndicator");
|
||||
|
||||
this.INDICATOR_APPLICATION_DBUS_ADDR = "com.canonical.indicator.application";
|
||||
this.INDICATOR_APPLICATION_DBUS_OBJ = "/com/canonical/indicator/application/service";
|
||||
this.INDICATOR_APPLICATION_DBUS_IFACE = "com.canonical.indicator.application.service";
|
||||
this.NOTIFICATION_WATCHER_DBUS_ADDR = "org.kde.StatusNotifierWatcher";
|
||||
this.NOTIFICATION_WATCHER_DBUS_OBJ = "/StatusNotifierWatcher";
|
||||
this.NOTIFICATION_WATCHER_DBUS_IFACE = "org.kde.StatusNotifierWatcher";
|
||||
this.NOTIFICATION_ITEM_DBUS_IFACE = "org.kde.StatusNotifierItem";
|
||||
this.NOTIFICATION_ITEM_DEFAULT_OBJ = "/StatusNotifierItem";
|
||||
this.NOTIFICATION_APPROVER_DBUS_IFACE = "org.ayatana.StatusNotifierApprover";
|
||||
|
||||
this.AppIndicatorCategory = ctypes.int; // enum
|
||||
this.APP_INDICATOR_CATEGORY_APPLICATION_STATUS = 0; /*< nick=ApplicationStatus >*/
|
||||
this.APP_INDICATOR_CATEGORY_COMMUNICATIONS = 1; /*< nick=Communications >*/
|
||||
this.APP_INDICATOR_CATEGORY_SYSTEM_SERVICES = 2; /*< nick=SystemServices >*/
|
||||
this.APP_INDICATOR_CATEGORY_HARDWARE = 3; /*< nick=Hardware >*/
|
||||
this.APP_INDICATOR_CATEGORY_OTHER = 4; /*< nick=Other >*/
|
||||
|
||||
this.AppIndicatorStatus = ctypes.int; // enum
|
||||
this.APP_INDICATOR_STATUS_PASSIVE = 0; /*< nick=Passive >*/
|
||||
this.APP_INDICATOR_STATUS_ACTIVE = 1; /*< nick=Active >*/
|
||||
this.APP_INDICATOR_STATUS_ATTENTION = 2; /*< nick=NeedsAttention >*/
|
||||
|
||||
lib.lazy_bind("app_indicator_new", this.AppIndicator.ptr, gobject.gchar.ptr, gobject.gchar.ptr, this.AppIndicatorCategory);
|
||||
lib.lazy_bind("app_indicator_set_status", ctypes.void_t, this.AppIndicator.ptr, this.AppIndicatorStatus);
|
||||
lib.lazy_bind("app_indicator_get_status", this.AppIndicatorStatus, this.AppIndicator.ptr);
|
||||
lib.lazy_bind("app_indicator_set_menu", ctypes.void_t, this.AppIndicator.ptr, gtk.GtkMenu.ptr);
|
||||
lib.lazy_bind("app_indicator_set_icon", ctypes.void_t, this.AppIndicator.ptr, gobject.gchar.ptr);
|
||||
lib.lazy_bind("app_indicator_set_attention_icon", ctypes.void_t, this.AppIndicator.ptr, gobject.gchar.ptr);
|
||||
lib.lazy_bind("app_indicator_set_label", ctypes.void_t, this.AppIndicator.ptr, gobject.gchar.ptr, gobject.gchar.ptr);
|
||||
lib.lazy_bind("app_indicator_set_secondary_activate_target", ctypes.void_t, this.AppIndicator.ptr, gtk.GtkWidget.ptr);
|
||||
|
||||
this.ConnectionChangedCb_t = ctypes.FunctionType(
|
||||
ctypes.default_abi, ctypes.void_t, [this.AppIndicator.ptr, gobject.gboolean, gobject.gpointer]).ptr;
|
||||
|
||||
this.OnScrollCb_t = ctypes.FunctionType(
|
||||
ctypes.default_abi, ctypes.void_t, [this.AppIndicator.ptr, gobject.gint, gobject.guint, gobject.gpointer]).ptr;
|
||||
};
|
||||
|
||||
var appind3 = new ctypes_library(APPINDICATOR_LIBNAME, APPINDICATOR_ABIS, appindicator_defines, this);
|
|
@ -11,6 +11,7 @@ const Ci = Components.interfaces;
|
|||
|
||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||
Cu.import("resource://firetray/ctypes/ctypes-utils.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/glib.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
|
||||
|
||||
function gio_defines(lib) {
|
||||
|
@ -21,6 +22,25 @@ function gio_defines(lib) {
|
|||
lib.lazy_bind("g_themed_icon_new_from_names", this.GIcon.ptr, ctypes.char.ptr.ptr, ctypes.int);
|
||||
lib.lazy_bind("g_themed_icon_get_names", gobject.gchar.ptr.ptr, this.GThemedIcon.ptr);
|
||||
|
||||
this.GBusType = ctypes.int; // enum
|
||||
this.G_BUS_TYPE_STARTER = -1;
|
||||
this.G_BUS_TYPE_NONE = 0;
|
||||
this.G_BUS_TYPE_SYSTEM = 1;
|
||||
this.G_BUS_TYPE_SESSION = 2;
|
||||
this.GDBusProxyFlags = ctypes.int; // enum
|
||||
this.G_DBUS_PROXY_FLAGS_NONE = 0;
|
||||
this.G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES = (1<<0);
|
||||
this.G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS = (1<<1);
|
||||
this.G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START = (1<<2);
|
||||
|
||||
this.GDBusConnection = ctypes.StructType("GDBusConnection");
|
||||
this.GCancellable = ctypes.StructType("GCancellable");
|
||||
this.GDBusProxy = ctypes.StructType("GDBusProxy");
|
||||
this.GDBusInterfaceInfo = ctypes.StructType("GDBusInterfaceInfo");
|
||||
|
||||
lib.lazy_bind("g_bus_get_sync", this.GDBusConnection.ptr, this.GBusType, this.GCancellable.ptr, glib.GError.ptr.ptr);
|
||||
lib.lazy_bind("g_dbus_proxy_new_for_bus_sync", this.GDBusProxy.ptr, this.GBusType, this.GDBusProxyFlags, this.GDBusInterfaceInfo.ptr, gobject.gchar.ptr, gobject.gchar.ptr, gobject.gchar.ptr, this.GCancellable.ptr, glib.GError.ptr.ptr);
|
||||
lib.lazy_bind("g_dbus_proxy_get_name_owner", gobject.gchar.ptr, this.GDBusProxy.ptr);
|
||||
}
|
||||
|
||||
new ctypes_library(GIO_LIBNAME, GIO_ABIS, gio_defines, this);
|
||||
|
|
|
@ -15,7 +15,13 @@ Cu.import("resource://firetray/ctypes/ctypes-utils.jsm");
|
|||
function glib_defines(lib) {
|
||||
/* mutual inclusion not possible */
|
||||
this.GQuark = ctypes.uint32_t; // this.GQuark = gobject.guint32;
|
||||
this.GError = ctypes.StructType("GError");
|
||||
this.GError = ctypes.StructType("GError", [
|
||||
{ domain: this.GQuark },
|
||||
{ code: ctypes.int }, // gint
|
||||
{ message: ctypes.char.ptr } // gchar.ptr
|
||||
]);
|
||||
lib.lazy_bind("g_error_free", ctypes.void_t, this.GError.ptr);
|
||||
lib.lazy_bind("g_strfreev", ctypes.void_t, ctypes.char.ptr.ptr);
|
||||
};
|
||||
|
||||
new ctypes_library(GLIB_LIBNAME, GLIB_ABIS, glib_defines, this);
|
||||
|
|
|
@ -70,6 +70,7 @@ function gobject_defines(lib) {
|
|||
this.gchar = ctypes.char;
|
||||
this.guchar = ctypes.unsigned_char;
|
||||
this.gboolean = this.gint;
|
||||
this.FALSE = this.gboolean(0);
|
||||
this.gfloat = ctypes.float;
|
||||
this.gdouble = ctypes.double;
|
||||
this.gsize = ctypes.unsigned_long;
|
||||
|
@ -131,6 +132,9 @@ function gobject_defines(lib) {
|
|||
|
||||
/* NOTE: we can't easily work with g_object_get_property() because it uses
|
||||
GValue, which is an opaque struct, and thus can't be initialized by ctypes */
|
||||
this.GValue = ctypes.StructType("GValue");
|
||||
lib.lazy_bind("g_object_get_property", ctypes.void_t, this.GObject.ptr, this.gchar.ptr, this.GValue.ptr);
|
||||
lib.lazy_bind("g_object_get", ctypes.void_t, this.gpointer, this.gchar.ptr, "...");
|
||||
}
|
||||
|
||||
new ctypes_library(GOBJECT_LIBNAME, GOBJECT_ABIS, gobject_defines, this);
|
||||
|
|
|
@ -101,6 +101,7 @@ function gtk_defines(lib) {
|
|||
|
||||
lib.lazy_bind("gtk_icon_theme_get_default", this.GtkIconTheme.ptr);
|
||||
lib.lazy_bind("gtk_icon_theme_get_for_screen", this.GtkIconTheme.ptr, gdk.GdkScreen.ptr);
|
||||
lib.lazy_bind("gtk_icon_theme_get_search_path", ctypes.void_t, this.GtkIconTheme.ptr, gobject.gchar.ptr.ptr.array(), gobject.gint.ptr);
|
||||
lib.lazy_bind("gtk_icon_theme_append_search_path", ctypes.void_t, this.GtkIconTheme.ptr, gobject.gchar.ptr);
|
||||
lib.lazy_bind("gtk_icon_theme_prepend_search_path", ctypes.void_t, this.GtkIconTheme.ptr, gobject.gchar.ptr);
|
||||
lib.lazy_bind("gtk_icon_theme_choose_icon", this.GtkIconInfo.ptr, this.GtkIconTheme.ptr, gobject.gchar.ptr.array(), gobject.gint, this.GtkIconLookupFlags);
|
||||
|
@ -122,6 +123,7 @@ function gtk_defines(lib) {
|
|||
lib.lazy_bind("gtk_image_menu_item_set_image", ctypes.void_t, this.GtkImageMenuItem.ptr, this.GtkWidget.ptr);
|
||||
lib.lazy_bind("gtk_menu_shell_append", ctypes.void_t, this.GtkMenuShell.ptr, this.GtkWidget.ptr);
|
||||
lib.lazy_bind("gtk_menu_shell_prepend", ctypes.void_t, this.GtkMenuShell.ptr, this.GtkWidget.ptr);
|
||||
lib.lazy_bind("gtk_menu_shell_insert", ctypes.void_t, this.GtkMenuShell.ptr, this.GtkWidget.ptr, gobject.gint);
|
||||
lib.lazy_bind("gtk_menu_popup", ctypes.void_t, this.GtkMenu.ptr, this.GtkWidget.ptr, this.GtkWidget.ptr, this.GtkMenuPositionFunc_t, gobject.gpointer, gobject.guint, gobject.guint);
|
||||
lib.lazy_bind("gtk_status_icon_position_menu", ctypes.void_t, this.GtkMenu.ptr, gobject.gint.ptr, gobject.gint.ptr, gobject.gboolean.ptr, gobject.gpointer);
|
||||
lib.lazy_bind("gtk_separator_menu_item_new", this.GtkWidget.ptr);
|
||||
|
@ -154,6 +156,7 @@ function gtk_defines(lib) {
|
|||
lib.lazy_bind("gtk_widget_get_events", gobject.gint, this.GtkWidget.ptr);
|
||||
lib.lazy_bind("gtk_widget_add_events", ctypes.void_t, this.GtkWidget.ptr, gobject.gint);
|
||||
lib.lazy_bind("gtk_widget_get_toplevel", this.GtkWidget.ptr, this.GtkWidget.ptr);
|
||||
lib.lazy_bind("gtk_widget_set_sensitive", ctypes.void_t, this.GtkWidget.ptr, gobject.gboolean);
|
||||
lib.lazy_bind("gtk_window_get_type", gobject.GType);
|
||||
lib.lazy_bind("gtk_window_get_position", ctypes.void_t, this.GtkWindow.ptr, gobject.gint.ptr, gobject.gint.ptr);
|
||||
lib.lazy_bind("gtk_window_move", ctypes.void_t, this.GtkWindow.ptr, gobject.gint, gobject.gint);
|
||||
|
|
|
@ -35,6 +35,30 @@ function kernel32_defines(lib) {
|
|||
lib.lazy_bind("GetProcAddress", win32.FARPROC, win32.HMODULE, win32.LPCSTR);
|
||||
lib.lazy_bind("GetCurrentThreadId", win32.DWORD);
|
||||
|
||||
this.STARTUPINFO = ctypes.StructType("STARTUPINFO", [
|
||||
{ "cb": win32.DWORD },
|
||||
{ "lpReserved": win32.LPTSTR },
|
||||
{ "lpDesktop": win32.LPTSTR },
|
||||
{ "lpTitle": win32.LPTSTR },
|
||||
{ "dwX": win32.DWORD },
|
||||
{ "dwY": win32.DWORD },
|
||||
{ "dwXSize": win32.DWORD },
|
||||
{ "dwYSize": win32.DWORD },
|
||||
{ "dwXCountChars": win32.DWORD },
|
||||
{ "dwYCountChars": win32.DWORD },
|
||||
{ "dwFillAttribute": win32.DWORD },
|
||||
{ "dwFlags": win32.DWORD },
|
||||
{ "wShowWindow": win32.WORD },
|
||||
{ "cbReserved2": win32.WORD },
|
||||
{ "lpReserved2": win32.LPBYTE },
|
||||
{ "hStdInput": win32.HANDLE },
|
||||
{ "hStdOutput": win32.HANDLE },
|
||||
{ "hStdError": win32.HANDLE }
|
||||
]);
|
||||
this.LPSTARTUPINFO = ctypes.PointerType(this.STARTUPINFO);
|
||||
|
||||
lib.lazy_bind("GetStartupInfoW", ctypes.void_t, this.LPSTARTUPINFO);
|
||||
|
||||
}
|
||||
|
||||
new ctypes_library(KERNEL32_LIBNAME, KERNEL32_ABIS, kernel32_defines, this);
|
||||
|
|
|
@ -372,6 +372,22 @@ function user32_defines(lib) {
|
|||
lib.lazy_bind("GetCursorPos", win32.BOOL, win32.LPPOINT);
|
||||
lib.lazy_bind("GetMessagePos", win32.DWORD);
|
||||
|
||||
this.WINDOWINFO = ctypes.StructType("WINDOWINFO", [
|
||||
{ "cbSize": win32.DWORD },
|
||||
{ "rcWindow": win32.RECT },
|
||||
{ "rcClient": win32.RECT },
|
||||
{ "dwStyle": win32.DWORD },
|
||||
{ "dwExStyle": win32.DWORD },
|
||||
{ "dwWindowStatus": win32.DWORD },
|
||||
{ "cxWindowBorders": win32.UINT },
|
||||
{ "cyWindowBorders": win32.UINT },
|
||||
{ "atomWindowType": win32.ATOM },
|
||||
{ "wCreatorVersion": win32.WORD }
|
||||
]);
|
||||
this.PWINDOWINFO = this.LPWINDOWINFO = this.WINDOWINFO.ptr;
|
||||
|
||||
lib.lazy_bind("GetWindowInfo", win32.BOOL, win32.HWND, this.WINDOWINFO.ptr);
|
||||
|
||||
this.WINDOWPLACEMENT = ctypes.StructType("WINDOWPLACEMENT", [
|
||||
{ "length": win32.UINT },
|
||||
{ "flags": win32.UINT },
|
||||
|
@ -411,6 +427,7 @@ function user32_defines(lib) {
|
|||
this.SWP_NOREPOSITION = this.SWP_NOOWNERZORDER;
|
||||
this.SWP_DEFERERASE = 0x2000;
|
||||
this.SWP_ASYNCWINDOWPOS = 0x4000;
|
||||
this.SWP_STATECHANGED = 0x8000; /* Undocumented */
|
||||
|
||||
lib.lazy_bind("GetSysColor", win32.DWORD, ctypes.int);
|
||||
this.COLOR_MENU = 4;
|
||||
|
|
|
@ -21,6 +21,7 @@ var win32 = new function() {
|
|||
|
||||
this.BOOL = ctypes.bool;
|
||||
this.BYTE = ctypes.unsigned_char;
|
||||
this.LPBYTE = this.BYTE.ptr;
|
||||
this.INT_PTR = is64bit ? ctypes.int64_t : ctypes.int;
|
||||
this.UINT = ctypes.unsigned_int;
|
||||
this.UINT_PTR = is64bit ? ctypes.uint64_t : ctypes.unsigned_int;
|
||||
|
@ -48,6 +49,7 @@ var win32 = new function() {
|
|||
this.HGDIOBJ = this.HANDLE;
|
||||
this.HBITMAP = this.HANDLE;
|
||||
this.HFONT = this.HANDLE;
|
||||
// FIXME: jschar renamed to char16_t (FF35+)
|
||||
this.TCHAR = ctypes.jschar, // Mozilla compiled with UNICODE/_UNICODE macros and wchar_t = jschar
|
||||
this.LPSTR = ctypes.char.ptr;
|
||||
this.LPCSTR = ctypes.char.ptr;
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
var EXPORTED_SYMBOLS = [ "firetray" ];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||
// FIXME: can't subscribeLibsForClosing([appind3])
|
||||
// https://bugs.launchpad.net/ubuntu/+source/firefox/+bug/1393256
|
||||
Cu.import("resource://firetray/ctypes/linux/appindicator.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gtk.jsm");
|
||||
Cu.import("resource://firetray/commons.js");
|
||||
firetray.Handler.subscribeLibsForClosing([gobject, gtk]);
|
||||
|
||||
let log = firetray.Logging.getLogger("firetray.AppIndicator");
|
||||
|
||||
if ("undefined" == typeof(firetray.StatusIcon))
|
||||
log.error("This module MUST be imported from/after FiretrayStatusIcon !");
|
||||
|
||||
|
||||
firetray.AppIndicator = {
|
||||
initialized: false,
|
||||
callbacks: {},
|
||||
indicator: null,
|
||||
|
||||
init: function() {
|
||||
this.indicator = appind3.app_indicator_new(
|
||||
FIRETRAY_APPINDICATOR_ID,
|
||||
firetray.StatusIcon.defaultAppIconName,
|
||||
appind3.APP_INDICATOR_CATEGORY_COMMUNICATIONS
|
||||
);
|
||||
appind3.app_indicator_set_status(this.indicator,
|
||||
appind3.APP_INDICATOR_STATUS_ACTIVE);
|
||||
appind3.app_indicator_set_menu(this.indicator,
|
||||
firetray.PopupMenu.menu); // mandatory
|
||||
log.debug("indicator="+this.indicator);
|
||||
|
||||
this.addCallbacks();
|
||||
|
||||
for (let item in firetray.PopupMenu.menuItem) {
|
||||
firetray.PopupMenu.showItem(firetray.PopupMenu.menuItem[item]);
|
||||
}
|
||||
|
||||
this.attachMiddleClickCallback();
|
||||
firetray.Handler.setIconTooltipDefault();
|
||||
|
||||
this.initialized = true;
|
||||
return true;
|
||||
},
|
||||
|
||||
shutdown: function() {
|
||||
log.debug("Disabling AppIndicator");
|
||||
gobject.g_object_unref(this.indicator);
|
||||
this.initialized = false;
|
||||
},
|
||||
|
||||
addCallbacks: function() {
|
||||
this.callbacks.connChanged = appind3.ConnectionChangedCb_t(
|
||||
firetray.AppIndicator.onConnectionChanged); // void return, no sentinel
|
||||
gobject.g_signal_connect(this.indicator, "connection-changed",
|
||||
firetray.AppIndicator.callbacks.connChanged, null);
|
||||
|
||||
this.callbacks.onScroll = appind3.OnScrollCb_t(
|
||||
firetray.AppIndicator.onScroll); // void return, no sentinel
|
||||
gobject.g_signal_connect(this.indicator, "scroll-event",
|
||||
firetray.AppIndicator.callbacks.onScroll, null);
|
||||
},
|
||||
|
||||
attachMiddleClickCallback: function(pref) {
|
||||
let pref = firetray.Utils.prefService.getIntPref("middle_click");
|
||||
if (pref === FIRETRAY_MIDDLE_CLICK_ACTIVATE_LAST) {
|
||||
item = firetray.PopupMenu.menuItem.activateLast;
|
||||
firetray.PopupMenu.showItem(firetray.PopupMenu.menuItem.activateLast);
|
||||
} else if (pref === FIRETRAY_MIDDLE_CLICK_SHOW_HIDE) {
|
||||
item = firetray.PopupMenu.menuItem.showHide;
|
||||
firetray.PopupMenu.hideItem(firetray.PopupMenu.menuItem.activateLast);
|
||||
} else {
|
||||
log.error("Unknown pref value for 'middle_click': "+pref);
|
||||
return false;
|
||||
}
|
||||
let menuItemShowHideWidget = ctypes.cast(item, gtk.GtkWidget.ptr);
|
||||
appind3.app_indicator_set_secondary_activate_target(
|
||||
this.indicator, menuItemShowHideWidget);
|
||||
return true;
|
||||
},
|
||||
|
||||
onConnectionChanged: function(indicator, connected, data) {
|
||||
log.debug("AppIndicator connection-changed: "+connected);
|
||||
},
|
||||
|
||||
// https://bugs.kde.org/show_bug.cgi?id=340978 broken under KDE4
|
||||
onScroll: function(indicator, delta, direction, data) { // AppIndicator*, gint, GdkScrollDirection, gpointer
|
||||
log.debug("onScroll: "+direction);
|
||||
firetray.StatusIcon.onScroll(direction);
|
||||
},
|
||||
|
||||
}; // AppIndicator
|
||||
|
||||
firetray.StatusIcon.initImpl =
|
||||
firetray.AppIndicator.init.bind(firetray.AppIndicator);
|
||||
|
||||
firetray.StatusIcon.shutdownImpl =
|
||||
firetray.AppIndicator.shutdown.bind(firetray.AppIndicator);
|
||||
|
||||
firetray.StatusIcon.middleClickActionChanged = function() {
|
||||
log.debug("middleClickActionChanged");
|
||||
firetray.AppIndicator.attachMiddleClickCallback();
|
||||
};
|
||||
|
||||
|
||||
firetray.Handler.setIconImageDefault = function() {
|
||||
log.debug("setIconImageDefault");
|
||||
appind3.app_indicator_set_icon(firetray.AppIndicator.indicator,
|
||||
firetray.StatusIcon.defaultAppIconName);
|
||||
};
|
||||
|
||||
firetray.Handler.setIconImageNewMail = function() {
|
||||
log.debug("setIconImageNewMail");
|
||||
appind3.app_indicator_set_icon(firetray.AppIndicator.indicator,
|
||||
firetray.StatusIcon.defaultNewMailIconName);
|
||||
};
|
||||
|
||||
firetray.Handler.setIconImageCustom = function(prefname) {
|
||||
let prefCustomIconPath = firetray.Utils.prefService.getCharPref(prefname);
|
||||
// Undocumented: ok to pass a *path* instead of an icon name! Otherwise we
|
||||
// should be changing the default icons (which is maybe a better
|
||||
// implementation anyway)...
|
||||
appind3.app_indicator_set_icon(firetray.AppIndicator.indicator, prefCustomIconPath);
|
||||
};
|
||||
|
||||
// No tooltips in AppIndicator
|
||||
// https://bugs.launchpad.net/indicator-application/+bug/527458
|
||||
firetray.Handler.setIconTooltip = function(toolTipStr) {
|
||||
log.debug("setIconTooltip");
|
||||
if (!firetray.AppIndicator.indicator)
|
||||
return false;
|
||||
firetray.PopupMenu.setItemLabel(firetray.PopupMenu.menuItem.tip,
|
||||
toolTipStr);
|
||||
return true;
|
||||
};
|
||||
|
||||
// AppIndicator doesn't support pixbuf https://bugs.launchpad.net/bugs/812067
|
||||
firetray.Handler.setIconText = function(text, color) { };
|
||||
|
||||
firetray.Handler.setIconVisibility = function(visible) {
|
||||
if (!firetray.AppIndicator.indicator)
|
||||
return false;
|
||||
|
||||
let status = visible ?
|
||||
appind3.APP_INDICATOR_STATUS_ACTIVE :
|
||||
appind3.APP_INDICATOR_STATUS_PASSIVE;
|
||||
appind3.app_indicator_set_status(firetray.AppIndicator.indicator, status);
|
||||
return true;
|
||||
};
|
|
@ -10,13 +10,13 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||
Cu.import("resource://firetray/ctypes/ctypesMap.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gio.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gdk.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gio.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gtk.jsm");
|
||||
Cu.import("resource://firetray/linux/FiretrayWindow.jsm");
|
||||
Cu.import("resource://firetray/commons.js");
|
||||
firetray.Handler.subscribeLibsForClosing([gobject, gio, gtk]);
|
||||
firetray.Handler.subscribeLibsForClosing([gdk, gio, gobject, gtk]);
|
||||
|
||||
if ("undefined" == typeof(firetray.Handler))
|
||||
log.error("This module MUST be imported from/after FiretrayHandler !");
|
||||
|
@ -51,7 +51,7 @@ firetray.ChatStatusIcon = {
|
|||
|
||||
init: function() {
|
||||
if (!firetray.Handler.appHasChat) throw "ChatStatusIcon for chat app only";
|
||||
if (!firetray.GtkIcons.initialized) throw "GtkIcons should have been initialized by StatusIcon";
|
||||
firetray.GtkIcons.init();
|
||||
|
||||
this.trayIcon = gtk.gtk_status_icon_new();
|
||||
this.loadThemedIcons();
|
||||
|
|
|
@ -25,7 +25,7 @@ firetray.GtkIcons = {
|
|||
try {
|
||||
if (this.initialized) return true;
|
||||
|
||||
this.loadDefaultTheme();
|
||||
this.appendSearchPath();
|
||||
this.initialized = true;
|
||||
return true;
|
||||
} catch (x) {
|
||||
|
@ -35,15 +35,33 @@ firetray.GtkIcons = {
|
|||
},
|
||||
|
||||
shutdown: function() {
|
||||
// FIXME: XXX destroy icon here
|
||||
this.initialized = false;
|
||||
},
|
||||
|
||||
loadDefaultTheme: function() {
|
||||
appendSearchPath: function() {
|
||||
this.GTK_THEME_ICON_PATH = firetray.Utils.chromeToPath("chrome://firetray/skin/icons/linux");
|
||||
log.debug(this.GTK_THEME_ICON_PATH);
|
||||
let gtkIconTheme = gtk.gtk_icon_theme_get_default();
|
||||
log.debug("gtkIconTheme="+gtkIconTheme);
|
||||
gtk.gtk_icon_theme_append_search_path(gtkIconTheme, this.GTK_THEME_ICON_PATH);
|
||||
|
||||
if (log.level <= firetray.Logging.LogMod.Level.Debug) {
|
||||
Cu.import("resource://firetray/ctypes/linux/glib.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
|
||||
firetray.Handler.subscribeLibsForClosing([glib, gobject]);
|
||||
let path = new gobject.gchar.ptr.ptr;
|
||||
let n_elements = new gobject.gint;
|
||||
gtk.gtk_icon_theme_get_search_path(gtkIconTheme, path.address(), n_elements.address());
|
||||
log.debug("n_elements="+n_elements+" path="+path);
|
||||
let pathIt = path;
|
||||
for (let i=0, len=n_elements.value; i<len || pathIt.isNull(); ++i) {
|
||||
log.debug("path["+i+"]="+pathIt.contents.readString());
|
||||
pathIt = pathIt.increment();
|
||||
}
|
||||
log.debug("path="+path+" pathIt="+pathIt);
|
||||
glib.g_strfreev(path);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
var EXPORTED_SYMBOLS = [ "firetray" ];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/cairo.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gdk.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gio.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gtk.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/pango.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/pangocairo.jsm");
|
||||
Cu.import("resource://firetray/linux/FiretrayGtkIcons.jsm");
|
||||
Cu.import("resource://firetray/commons.js");
|
||||
firetray.Handler.subscribeLibsForClosing([cairo, gdk, gio, gobject, gtk, pango,
|
||||
pangocairo]);
|
||||
|
||||
let log = firetray.Logging.getLogger("firetray.GtkStatusIcon");
|
||||
|
||||
if ("undefined" == typeof(firetray.Handler))
|
||||
log.error("This module MUST be imported from/after FiretrayStatusIcon !");
|
||||
|
||||
|
||||
firetray.GtkStatusIcon = {
|
||||
MIN_FONT_SIZE: 4,
|
||||
FILENAME_BLANK: null,
|
||||
GTK_THEME_ICON_PATH: null,
|
||||
|
||||
initialized: false,
|
||||
callbacks: {},
|
||||
trayIcon: null,
|
||||
themedIconApp: null,
|
||||
themedIconNewMail: null,
|
||||
|
||||
init: function() {
|
||||
this.FILENAME_BLANK = firetray.Utils.chromeToPath(
|
||||
"chrome://firetray/skin/icons/blank-icon.png");
|
||||
|
||||
firetray.GtkIcons.init();
|
||||
this.loadThemedIcons();
|
||||
|
||||
this.trayIcon = gtk.gtk_status_icon_new();
|
||||
firetray.Handler.setIconImageDefault();
|
||||
firetray.Handler.setIconTooltipDefault();
|
||||
this.addCallbacks();
|
||||
|
||||
this.initialized = true;
|
||||
return true;
|
||||
},
|
||||
|
||||
shutdown: function() {
|
||||
log.debug("Disabling GtkStatusIcon");
|
||||
firetray.GtkIcons.shutdown();
|
||||
// FIXME: XXX destroy icon here
|
||||
this.initialized = false;
|
||||
},
|
||||
|
||||
loadThemedIcons: function() {
|
||||
if (firetray.Handler.inMailApp) {
|
||||
let newMailIconNames = firetray.StatusIcon.getNewMailIconNames();
|
||||
if (this.themedIconNewMail) gobject.g_object_unref(this.themedIconNewMail);
|
||||
this.themedIconNewMail = this.initThemedIcon(newMailIconNames);
|
||||
}
|
||||
let appIconNames = firetray.StatusIcon.getAppIconNames();
|
||||
if (this.themedIconApp) gobject.g_object_unref(this.themedIconApp);
|
||||
this.themedIconApp = this.initThemedIcon(appIconNames);
|
||||
},
|
||||
|
||||
initThemedIcon: function(names) {
|
||||
if (!firetray.js.isArray(names)) throw new TypeError();
|
||||
log.debug("themedIconNames="+names);
|
||||
let namesLen = names.length;
|
||||
log.debug("themedIconNamesLen="+namesLen);
|
||||
let themedIconNames = ctypes.char.ptr.array(namesLen)();
|
||||
for (let i=0; i<namesLen; ++i)
|
||||
themedIconNames[i] = ctypes.char.array()(names[i]);
|
||||
log.debug("themedIconNames="+themedIconNames);
|
||||
let themedIcon = gio.g_themed_icon_new_from_names(themedIconNames, namesLen);
|
||||
log.debug("themedIcon="+themedIcon);
|
||||
return themedIcon;
|
||||
},
|
||||
|
||||
addCallbacks: function() {
|
||||
Cu.import("resource://firetray/linux/FiretrayPopupMenu.jsm");
|
||||
/* NOTE: here we do use a function handler (instead of a function
|
||||
definition) because we need the args passed to it ! As a consequence, we
|
||||
need to abandon 'this' in PopupMenu.popup() */
|
||||
this.callbacks.menuPopup = gtk.GCallbackMenuPopup_t(firetray.PopupMenu.popup); // void return, no sentinel
|
||||
gobject.g_signal_connect(this.trayIcon, "popup-menu",
|
||||
firetray.GtkStatusIcon.callbacks.menuPopup, firetray.PopupMenu.menu);
|
||||
this.callbacks.onScroll = gtk.GCallbackOnScroll_t(
|
||||
firetray.GtkStatusIcon.onScroll, null, FIRETRAY_CB_SENTINEL);
|
||||
gobject.g_signal_connect(this.trayIcon, "scroll-event",
|
||||
firetray.GtkStatusIcon.callbacks.onScroll, null);
|
||||
|
||||
log.debug("showHideAllWindows: "+firetray.Handler.hasOwnProperty("showHideAllWindows"));
|
||||
this.callbacks.iconActivate = gtk.GCallbackStatusIconActivate_t(
|
||||
firetray.GtkStatusIcon.onClick, null, FIRETRAY_CB_SENTINEL);
|
||||
let handlerId = gobject.g_signal_connect(firetray.GtkStatusIcon.trayIcon,
|
||||
"activate", firetray.GtkStatusIcon.callbacks.iconActivate, null);
|
||||
log.debug("g_connect activate="+handlerId);
|
||||
|
||||
let pref = firetray.Utils.prefService.getIntPref("middle_click");
|
||||
this.attachMiddleClickCallback(pref);
|
||||
},
|
||||
|
||||
attachMiddleClickCallback: function(pref) {
|
||||
log.debug("attachMiddleClickCallback pref="+pref);
|
||||
if (pref === FIRETRAY_MIDDLE_CLICK_ACTIVATE_LAST) {
|
||||
this.callbacks.iconMiddleClick = gtk.GCallbackStatusIconMiddleClick_t(
|
||||
firetray.Handler.activateLastWindowCb, null, FIRETRAY_CB_SENTINEL);
|
||||
} else if (pref === FIRETRAY_MIDDLE_CLICK_SHOW_HIDE) {
|
||||
this.callbacks.iconMiddleClick = gtk.GCallbackStatusIconMiddleClick_t(
|
||||
function(widget, event, data) {firetray.Handler.showHideAllWindows(); return true;},
|
||||
null, FIRETRAY_CB_SENTINEL);
|
||||
} else {
|
||||
log.error("Unknown pref value for 'middle_click': "+pref);
|
||||
return;
|
||||
}
|
||||
this.callbacks.iconMiddleClickId = gobject.g_signal_connect(
|
||||
firetray.GtkStatusIcon.trayIcon,
|
||||
"button-press-event", firetray.GtkStatusIcon.callbacks.iconMiddleClick,
|
||||
null);
|
||||
log.debug("g_connect middleClick="+this.callbacks.iconMiddleClickId);
|
||||
},
|
||||
|
||||
detachMiddleClickCallback: function() {
|
||||
log.debug("detachMiddleClickCallback");
|
||||
gobject.g_signal_handler_disconnect(
|
||||
firetray.GtkStatusIcon.trayIcon,
|
||||
gobject.gulong(this.callbacks.iconMiddleClickId)
|
||||
);
|
||||
delete this.callbacks.iconMiddleClickId;
|
||||
},
|
||||
|
||||
onScroll: function(icon, event, data) {
|
||||
let gdkEventScroll = ctypes.cast(event, gdk.GdkEventScroll.ptr);
|
||||
let direction = gdkEventScroll.contents.direction;
|
||||
|
||||
firetray.StatusIcon.onScroll(direction);
|
||||
|
||||
let stopPropagation = false;
|
||||
return stopPropagation;
|
||||
},
|
||||
|
||||
onClick: function(gtkStatusIcon, userData) {
|
||||
firetray.Handler.showHideAllWindows();
|
||||
let stopPropagation = true;
|
||||
return stopPropagation;
|
||||
},
|
||||
|
||||
setIconImageFromFile: function(filename) {
|
||||
if (!firetray.GtkStatusIcon.trayIcon)
|
||||
log.error("Icon missing");
|
||||
log.debug(filename);
|
||||
gtk.gtk_status_icon_set_from_file(firetray.GtkStatusIcon.trayIcon,
|
||||
filename);
|
||||
},
|
||||
|
||||
setIconImageFromGIcon: function(gicon) {
|
||||
if (!firetray.GtkStatusIcon.trayIcon || !gicon)
|
||||
log.error("Icon missing");
|
||||
log.debug(gicon);
|
||||
gtk.gtk_status_icon_set_from_gicon(firetray.GtkStatusIcon.trayIcon, gicon);
|
||||
},
|
||||
|
||||
}; // GtkStatusIcon
|
||||
|
||||
firetray.StatusIcon.initImpl =
|
||||
firetray.GtkStatusIcon.init.bind(firetray.GtkStatusIcon);
|
||||
|
||||
firetray.StatusIcon.shutdownImpl =
|
||||
firetray.GtkStatusIcon.shutdown.bind(firetray.GtkStatusIcon);
|
||||
|
||||
firetray.StatusIcon.middleClickActionChanged = function() {
|
||||
log.debug("middleClickActionChanged");
|
||||
let pref = firetray.Utils.prefService.getIntPref("middle_click");
|
||||
firetray.GtkStatusIcon.detachMiddleClickCallback();
|
||||
firetray.GtkStatusIcon.attachMiddleClickCallback(pref);
|
||||
};
|
||||
|
||||
|
||||
firetray.Handler.loadIcons = firetray.GtkStatusIcon.loadThemedIcons;
|
||||
|
||||
firetray.Handler.setIconImageDefault = function() {
|
||||
log.debug("setIconImageDefault");
|
||||
if (!firetray.GtkStatusIcon.themedIconApp)
|
||||
throw "Default application themed icon not set";
|
||||
let appIconType = firetray.Utils.prefService.getIntPref("app_icon_type");
|
||||
if (appIconType === FIRETRAY_APPLICATION_ICON_TYPE_THEMED) {
|
||||
firetray.GtkStatusIcon.setIconImageFromGIcon(
|
||||
firetray.GtkStatusIcon.themedIconApp);
|
||||
} else if (appIconType === FIRETRAY_APPLICATION_ICON_TYPE_CUSTOM) {
|
||||
firetray.Handler.setIconImageCustom("app_icon_custom");
|
||||
}
|
||||
};
|
||||
|
||||
firetray.Handler.setIconImageNewMail = function() {
|
||||
firetray.GtkStatusIcon.setIconImageFromGIcon(
|
||||
firetray.GtkStatusIcon.themedIconNewMail);
|
||||
};
|
||||
|
||||
firetray.Handler.setIconImageCustom = function(prefname) {
|
||||
let prefCustomIconPath = firetray.Utils.prefService.getCharPref(prefname);
|
||||
firetray.GtkStatusIcon.setIconImageFromFile(prefCustomIconPath);
|
||||
};
|
||||
|
||||
// GTK bug: Gdk-CRITICAL **: IA__gdk_window_get_root_coords: assertion `GDK_IS_WINDOW (window)' failed
|
||||
firetray.Handler.setIconTooltip = function(toolTipStr) {
|
||||
if (!firetray.GtkStatusIcon.trayIcon)
|
||||
return false;
|
||||
|
||||
log.debug("setIconTooltip, toolTipStr="+toolTipStr);
|
||||
try {
|
||||
gtk.gtk_status_icon_set_tooltip_text(firetray.GtkStatusIcon.trayIcon,
|
||||
toolTipStr);
|
||||
} catch (x) {
|
||||
log.error(x);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
firetray.Handler.setIconText = function(text, color) { // FIXME: function too long
|
||||
log.debug("setIconText, color="+color);
|
||||
if (typeof(text) != "string")
|
||||
throw new TypeError();
|
||||
|
||||
try {
|
||||
// build background from image
|
||||
let specialIcon = gdk.gdk_pixbuf_new_from_file(
|
||||
firetray.GtkStatusIcon.FILENAME_BLANK, null); // GError **error);
|
||||
let dest = gdk.gdk_pixbuf_copy(specialIcon);
|
||||
let w = gdk.gdk_pixbuf_get_width(specialIcon);
|
||||
let h = gdk.gdk_pixbuf_get_height(specialIcon);
|
||||
|
||||
// prepare colors/alpha
|
||||
let colorMap = gdk.gdk_screen_get_system_colormap(gdk.gdk_screen_get_default());
|
||||
let visual = gdk.gdk_colormap_get_visual(colorMap);
|
||||
let visualDepth = visual.contents.depth;
|
||||
log.debug("colorMap="+colorMap+" visual="+visual+" visualDepth="+visualDepth);
|
||||
let fore = new gdk.GdkColor;
|
||||
fore.pixel = fore.red = fore.green = fore.blue = 0;
|
||||
let alpha = new gdk.GdkColor;
|
||||
alpha.pixel = alpha.red = alpha.green = alpha.blue = 0xFFFF;
|
||||
if (!fore || !alpha)
|
||||
log.warn("Undefined GdkColor fore or alpha");
|
||||
gdk.gdk_color_parse(color, fore.address());
|
||||
if(fore.red == alpha.red && fore.green == alpha.green && fore.blue == alpha.blue) {
|
||||
alpha.red=0; // make sure alpha is different from fore
|
||||
}
|
||||
gdk.gdk_colormap_alloc_color(colorMap, fore.address(), true, true);
|
||||
gdk.gdk_colormap_alloc_color(colorMap, alpha.address(), true, true);
|
||||
|
||||
// build pixmap with rectangle
|
||||
let pm = gdk.gdk_pixmap_new(null, w, h, visualDepth);
|
||||
let pmDrawable = ctypes.cast(pm, gdk.GdkDrawable.ptr);
|
||||
let cr = gdk.gdk_cairo_create(pmDrawable);
|
||||
gdk.gdk_cairo_set_source_color(cr, alpha.address());
|
||||
cairo.cairo_rectangle(cr, 0, 0, w, h);
|
||||
cairo.cairo_set_source_rgb(cr, 1, 1, 1);
|
||||
cairo.cairo_fill(cr);
|
||||
|
||||
// build text
|
||||
let scratch = gtk.gtk_window_new(gtk.GTK_WINDOW_TOPLEVEL);
|
||||
let layout = gtk.gtk_widget_create_pango_layout(scratch, null);
|
||||
gtk.gtk_widget_destroy(scratch);
|
||||
let fnt = pango.pango_font_description_from_string("Sans 18");
|
||||
pango.pango_font_description_set_weight(fnt,pango.PANGO_WEIGHT_SEMIBOLD);
|
||||
pango.pango_layout_set_spacing(layout,0);
|
||||
pango.pango_layout_set_font_description(layout, fnt);
|
||||
log.debug("layout="+layout);
|
||||
log.debug("text="+text);
|
||||
pango.pango_layout_set_text(layout, text,-1);
|
||||
let tw = new ctypes.int;
|
||||
let th = new ctypes.int;
|
||||
let sz;
|
||||
let border = 4;
|
||||
pango.pango_layout_get_pixel_size(layout, tw.address(), th.address());
|
||||
log.debug("tw="+tw.value+" th="+th.value);
|
||||
// fit text to the icon by decreasing font size
|
||||
while ( tw.value > (w - border) || th.value > (h - border) ) {
|
||||
sz = pango.pango_font_description_get_size(fnt);
|
||||
if(sz < firetray.GtkStatusIcon.MIN_FONT_SIZE) {
|
||||
sz = firetray.GtkStatusIcon.MIN_FONT_SIZE;
|
||||
break;
|
||||
}
|
||||
sz -= pango.PANGO_SCALE;
|
||||
pango.pango_font_description_set_size(fnt,sz);
|
||||
pango.pango_layout_set_font_description(layout, fnt);
|
||||
pango.pango_layout_get_pixel_size(layout, tw.address(), th.address());
|
||||
}
|
||||
log.debug("tw="+tw.value+" th="+th.value);
|
||||
pango.pango_font_description_free(fnt);
|
||||
// center text
|
||||
let px = (w-tw.value)/2;
|
||||
let py = (h-th.value)/2;
|
||||
|
||||
// draw text on pixmap
|
||||
gdk.gdk_cairo_set_source_color(cr, fore.address());
|
||||
cairo.cairo_move_to(cr, px, py);
|
||||
pangocairo.pango_cairo_show_layout(cr, layout);
|
||||
cairo.cairo_destroy(cr);
|
||||
gobject.g_object_unref(layout);
|
||||
|
||||
let buf = gdk.gdk_pixbuf_get_from_drawable(null, pmDrawable, null, 0, 0, 0, 0, w, h);
|
||||
gobject.g_object_unref(pm);
|
||||
log.debug("alpha="+alpha);
|
||||
let alphaRed = gobject.guint16(alpha.red);
|
||||
let alphaRed_guchar = ctypes.cast(alphaRed, gobject.guchar);
|
||||
let alphaGreen = gobject.guint16(alpha.green);
|
||||
let alphaGreen_guchar = ctypes.cast(alphaGreen, gobject.guchar);
|
||||
let alphaBlue = gobject.guint16(alpha.blue);
|
||||
let alphaBlue_guchar = ctypes.cast(alphaBlue, gobject.guchar);
|
||||
let bufAlpha = gdk.gdk_pixbuf_add_alpha(buf, true, alphaRed_guchar, alphaGreen_guchar, alphaBlue_guchar);
|
||||
gobject.g_object_unref(buf);
|
||||
|
||||
// merge the rendered text on top
|
||||
gdk.gdk_pixbuf_composite(bufAlpha,dest,0,0,w,h,0,0,1,1,gdk.GDK_INTERP_BILINEAR,255);
|
||||
gobject.g_object_unref(bufAlpha);
|
||||
|
||||
log.debug("gtk_status_icon_set_from_pixbuf="+dest);
|
||||
gtk.gtk_status_icon_set_from_pixbuf(firetray.GtkStatusIcon.trayIcon, dest);
|
||||
} catch (x) {
|
||||
log.error(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
firetray.Handler.setIconVisibility = function(visible) {
|
||||
if (!firetray.GtkStatusIcon.trayIcon)
|
||||
return false;
|
||||
gtk.gtk_status_icon_set_visible(firetray.GtkStatusIcon.trayIcon, visible);
|
||||
return true;
|
||||
};
|
|
@ -21,11 +21,14 @@ if ("undefined" == typeof(firetray.StatusIcon))
|
|||
|
||||
|
||||
firetray.PopupMenu = {
|
||||
MENU_ITEM_WINDOWS_POSITION: 4,
|
||||
|
||||
initialized: false,
|
||||
callbacks: {menuItemWindowActivate: {}}, // FIXME: try to store them into a ctypes array/struct.
|
||||
menu: null,
|
||||
menuShell: null,
|
||||
menuSeparatorWindows: null,
|
||||
menuItem: {tip: null, showHide: null, activateLast: null, sep: null},
|
||||
|
||||
init: function() {
|
||||
this.menu = gtk.gtk_menu_new();
|
||||
|
@ -33,34 +36,46 @@ firetray.PopupMenu = {
|
|||
var addMenuSeparator = false;
|
||||
|
||||
if (firetray.Handler.inMailApp) {
|
||||
this.addItem("ResetIcon", "gtk-apply", "activate", firetray.Handler.setIconImageDefault);
|
||||
this.addItem("NewMessage", "gtk-edit", "activate", firetray.Handler.openMailMessage);
|
||||
this.addItem({itemName:"ResetIcon", iconName:"gtk-apply",
|
||||
action:"activate", callback: firetray.Handler.setIconImageDefault});
|
||||
this.addItem({itemName:"NewMessage", iconName:"gtk-edit",
|
||||
action:"activate", callback: firetray.Handler.openMailMessage});
|
||||
addMenuSeparator = true;
|
||||
}
|
||||
|
||||
if (firetray.Handler.inBrowserApp) {
|
||||
this.addItem("NewWindow", "gtk-new", "activate", firetray.Handler.openBrowserWindow);
|
||||
this.addItem({itemName:"NewWindow", iconName:"gtk-new",
|
||||
action:"activate", callback: firetray.Handler.openBrowserWindow});
|
||||
addMenuSeparator = true;
|
||||
}
|
||||
|
||||
var menuSeparator;
|
||||
if (addMenuSeparator) {
|
||||
menuSeparator = gtk.gtk_separator_menu_item_new();
|
||||
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuSeparator, gtk.GtkWidget.ptr));
|
||||
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuSeparator,
|
||||
gtk.GtkWidget.ptr));
|
||||
}
|
||||
|
||||
this.addItem("Preferences", "gtk-preferences", "activate", firetray.Handler.openPrefWindow);
|
||||
this.addItem({itemName:"Preferences", iconName:"gtk-preferences",
|
||||
action:"activate", callback: firetray.Handler.openPrefWindow});
|
||||
menuSeparator = gtk.gtk_separator_menu_item_new();
|
||||
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuSeparator, gtk.GtkWidget.ptr));
|
||||
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuSeparator,
|
||||
gtk.GtkWidget.ptr));
|
||||
|
||||
this.addItem("Quit", "gtk-quit", "activate", firetray.Handler.quitApplication);
|
||||
this.addItem({itemName:"Quit", iconName:"gtk-quit",
|
||||
action:"activate", callback: firetray.Handler.quitApplication});
|
||||
|
||||
var menuWidget = ctypes.cast(this.menu, gtk.GtkWidget.ptr);
|
||||
gtk.gtk_widget_show_all(menuWidget);
|
||||
|
||||
var menuSeparatorWindows = gtk.gtk_separator_menu_item_new();
|
||||
gtk.gtk_menu_shell_prepend(this.menuShell, ctypes.cast(menuSeparatorWindows, gtk.GtkWidget.ptr));
|
||||
this.menuSeparatorWindows = menuSeparatorWindows;
|
||||
// for hidden windows, not shown otherwise
|
||||
this.menuSeparatorWindows = gtk.gtk_separator_menu_item_new();
|
||||
gtk.gtk_menu_shell_prepend(
|
||||
this.menuShell, ctypes.cast(this.menuSeparatorWindows, gtk.GtkWidget.ptr));
|
||||
// FIXME: we better use a submenu for this: gtk_menu_new(), gtk_menu_item_set_submenu();
|
||||
|
||||
// for AppIndicator, not shown otherwise
|
||||
this.prependAppIndicatorItems();
|
||||
|
||||
this.initialized = true;
|
||||
return true;
|
||||
|
@ -71,56 +86,88 @@ firetray.PopupMenu = {
|
|||
this.initialized = false;
|
||||
},
|
||||
|
||||
addItem: function(itemName, iconName, action, callback) {
|
||||
var menuItemLabel = firetray.Utils.strings.GetStringFromName("popupMenu.itemLabel."+itemName); // shouldn't need to convert to utf8 later thank to js-ctypes
|
||||
addItem: function(it) {
|
||||
var menuItemLabel = firetray.Utils.strings.GetStringFromName("popupMenu.itemLabel."+it.itemName); // shouldn't need to convert to utf8 later thank to js-ctypes
|
||||
var menuItem = gtk.gtk_image_menu_item_new_with_label(menuItemLabel);
|
||||
var menuItemIcon = gtk.gtk_image_new_from_stock(iconName, gtk.GTK_ICON_SIZE_MENU);
|
||||
var menuItemIcon = gtk.gtk_image_new_from_stock(it.iconName, gtk.GTK_ICON_SIZE_MENU);
|
||||
gtk.gtk_image_menu_item_set_image(menuItem, menuItemIcon);
|
||||
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuItem, gtk.GtkWidget.ptr));
|
||||
var menuItemWidget = ctypes.cast(menuItem, gtk.GtkWidget.ptr);
|
||||
if (it.inFront)
|
||||
gtk.gtk_menu_shell_prepend(this.menuShell, menuItemWidget);
|
||||
else
|
||||
gtk.gtk_menu_shell_append(this.menuShell, menuItemWidget);
|
||||
|
||||
function capitalizeFirst(str) {
|
||||
return str.charAt(0).toUpperCase() + str.substring(1);
|
||||
}
|
||||
|
||||
let cbName = "menuItem"+capitalizeFirst(itemName)+capitalizeFirst(action);
|
||||
log.debug("cbName="+cbName);
|
||||
this.callbacks[cbName] = gobject.GCallback_t(callback);
|
||||
gobject.g_signal_connect(menuItem, action,
|
||||
let cbName = "menuItem"+capitalizeFirst(it.itemName)+capitalizeFirst(it.action);
|
||||
if (this.callbacks.hasOwnProperty(cbName))
|
||||
log.warn("callback '"+cbName+"' already registered");
|
||||
else
|
||||
log.debug("cbName="+cbName);
|
||||
this.callbacks[cbName] = gobject.GCallback_t(it.callback); // void return, no sentinel
|
||||
gobject.g_signal_connect(menuItem, it.action,
|
||||
firetray.PopupMenu.callbacks[cbName], null);
|
||||
|
||||
return menuItem;
|
||||
},
|
||||
|
||||
prependAppIndicatorItems: function() {
|
||||
this.menuItem.sep = gtk.gtk_separator_menu_item_new();
|
||||
gtk.gtk_menu_shell_prepend(this.menuShell, ctypes.cast(this.menuItem.sep,
|
||||
gtk.GtkWidget.ptr));
|
||||
|
||||
this.menuItem.activateLast = this.addItem({
|
||||
itemName:"ActivateLast", iconName:null, action:"activate", callback:
|
||||
firetray.Handler.showAllWindowsAndActivate, inFront: true});
|
||||
|
||||
this.menuItem.showHide = this.addItem({
|
||||
itemName:"ShowHide", iconName:"gtk-go-down", action:"activate", callback:
|
||||
firetray.Handler.showHideAllWindows, inFront: true});
|
||||
|
||||
this.menuItem.tip = this.createAndAddItemToMenuAt(0);
|
||||
gtk.gtk_widget_set_sensitive(
|
||||
ctypes.cast(this.menuItem.tip, gtk.GtkWidget.ptr), false);
|
||||
},
|
||||
|
||||
popup: function(icon, button, activateTime, menu) {
|
||||
log.debug("menu-popup");
|
||||
log.debug("ARGS="+icon+", "+button+", "+activateTime+", "+menu);
|
||||
|
||||
try {
|
||||
var gtkMenuPtr = ctypes.cast(menu, gtk.GtkMenu.ptr);
|
||||
var iconGpointer = ctypes.cast(icon, gobject.gpointer);
|
||||
gtk.gtk_menu_popup(
|
||||
gtkMenuPtr, null, null, gtk.gtk_status_icon_position_menu,
|
||||
iconGpointer, button, activateTime);
|
||||
} catch (x) { log.error(x); }
|
||||
var gtkMenuPtr = ctypes.cast(menu, gtk.GtkMenu.ptr);
|
||||
var iconGpointer = ctypes.cast(icon, gobject.gpointer);
|
||||
gtk.gtk_menu_popup(
|
||||
gtkMenuPtr, null, null, gtk.gtk_status_icon_position_menu,
|
||||
iconGpointer, button, activateTime);
|
||||
|
||||
let stopPropagation = false;
|
||||
return stopPropagation;
|
||||
},
|
||||
|
||||
// we'll be creating menuItems for windows (and not showing them) even if
|
||||
// hides_single_window is false, because if hides_single_window becomes true,
|
||||
// we'll just have to show the menuItems
|
||||
addWindowItem: function(xid) { // on registerWindow
|
||||
var menuItemWindow = this.createAndAddItemToMenu();
|
||||
log.debug("addWindowItem");
|
||||
var menuItemWindow = this.createAndAddItemToMenuAt(
|
||||
this.MENU_ITEM_WINDOWS_POSITION);
|
||||
firetray.Handler.gtkPopupMenuWindowItems.insert(xid, menuItemWindow);
|
||||
this.setWindowItemLabel(menuItemWindow, xid.toString()); // default to xid
|
||||
this.setItemLabel(menuItemWindow, xid.toString()); // default to xid
|
||||
|
||||
this.callbacks.menuItemWindowActivate[xid] = gobject.GCallback_t(
|
||||
function(){firetray.Handler.showWindow(xid);});
|
||||
gobject.g_signal_connect(menuItemWindow, "activate",
|
||||
firetray.PopupMenu.callbacks.menuItemWindowActivate[xid], null);
|
||||
let callback = gobject.GCallback_t(
|
||||
function(){firetray.Handler.showWindow(xid);}); // void return, no sentinel
|
||||
this.callbacks.menuItemWindowActivate[xid] = callback,
|
||||
gobject.g_signal_connect(menuItemWindow, "activate", callback, null);
|
||||
|
||||
log.debug("added gtkPopupMenuWindowItems: "+firetray.Handler.gtkPopupMenuWindowItems.count);
|
||||
},
|
||||
|
||||
createAndAddItemToMenu: function() {
|
||||
createAndAddItemToMenuAt: function(pos) {
|
||||
var menuItem = gtk.gtk_image_menu_item_new();
|
||||
gtk.gtk_menu_shell_prepend(this.menuShell, ctypes.cast(menuItem, gtk.GtkWidget.ptr));
|
||||
gtk.gtk_menu_shell_insert(this.menuShell,
|
||||
ctypes.cast(menuItem, gtk.GtkWidget.ptr),
|
||||
pos);
|
||||
return menuItem;
|
||||
},
|
||||
|
||||
|
@ -147,7 +194,7 @@ firetray.PopupMenu = {
|
|||
log.debug("showWindowItem");
|
||||
let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
|
||||
this.showItem(menuItemWindow);
|
||||
this.setWindowItemLabel(menuItemWindow, firetray.Window.getWindowTitle(xid));
|
||||
this.setItemLabel(menuItemWindow, firetray.Window.getWindowTitle(xid));
|
||||
this.showWindowSeparator();
|
||||
},
|
||||
|
||||
|
@ -155,7 +202,7 @@ firetray.PopupMenu = {
|
|||
gtk.gtk_widget_show(ctypes.cast(menuItem, gtk.GtkWidget.ptr));
|
||||
},
|
||||
|
||||
setWindowItemLabel: function(menuItem, label) {
|
||||
setItemLabel: function(menuItem, label) {
|
||||
log.debug("about to set title: "+label);
|
||||
if (label)
|
||||
gtk.gtk_menu_item_set_label(ctypes.cast(menuItem, gtk.GtkMenuItem.ptr), label);
|
||||
|
|
|
@ -6,18 +6,12 @@ const Cc = Components.classes;
|
|||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/cairo.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gdk.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gio.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gtk.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/pango.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/pangocairo.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/glib.jsm");
|
||||
Cu.import("resource://firetray/ctypes/linux/gobject.jsm");
|
||||
Cu.import("resource://firetray/commons.js");
|
||||
firetray.Handler.subscribeLibsForClosing([cairo, gobject, gdk, gio, gtk, pango, pangocairo]);
|
||||
firetray.Handler.subscribeLibsForClosing([gdk, gio, glib, gobject]);
|
||||
|
||||
let log = firetray.Logging.getLogger("firetray.StatusIcon");
|
||||
|
||||
|
@ -26,37 +20,41 @@ if ("undefined" == typeof(firetray.Handler))
|
|||
|
||||
|
||||
firetray.StatusIcon = {
|
||||
MIN_FONT_SIZE: 4,
|
||||
FILENAME_BLANK: null,
|
||||
|
||||
initialized: false,
|
||||
callbacks: {}, // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
|
||||
trayIcon: null,
|
||||
themedIconApp: null,
|
||||
themedIconNewMail: null,
|
||||
prefAppIconNames: null,
|
||||
prefNewMailIconNames: null,
|
||||
defaultAppIconName: null,
|
||||
defaultNewMailIconName: null,
|
||||
canAppIndicator: null,
|
||||
|
||||
init: function() {
|
||||
this.FILENAME_BLANK = firetray.Utils.chromeToPath(
|
||||
"chrome://firetray/skin/icons/blank-icon.png");
|
||||
|
||||
Cu.import("resource://firetray/linux/FiretrayGtkIcons.jsm");
|
||||
firetray.GtkIcons.init();
|
||||
this.defineIconNames();
|
||||
this.loadThemedIcons();
|
||||
|
||||
this.trayIcon = gtk.gtk_status_icon_new();
|
||||
firetray.Handler.setIconImageDefault();
|
||||
firetray.Handler.setIconTooltipDefault();
|
||||
// PopupMenu g_connect's some Handler functions. As these are overridden is
|
||||
// StatusIcon implementations, PopupMenu must be initialized *after*
|
||||
// implemenations are imported.
|
||||
Cu.import("resource://firetray/ctypes/linux/appindicator.jsm");
|
||||
this.canAppIndicator =
|
||||
(appind3.available() && this.dbusNotificationWatcherReady());
|
||||
log.info("canAppIndicator="+this.canAppIndicator);
|
||||
if (firetray.Utils.prefService.getBoolPref('with_appindicator') &&
|
||||
this.canAppIndicator) {
|
||||
/* FIXME: Ubuntu14.04/Unity: successfully closing appind3 crashes FF/TB
|
||||
during exit, in Ubuntu's unity-menubar.patch's code.
|
||||
https://bugs.launchpad.net/ubuntu/+source/firefox/+bug/1393256 */
|
||||
// firetray.Handler.subscribeLibsForClosing([appind3]);
|
||||
Cu.import("resource://firetray/linux/FiretrayAppIndicator.jsm");
|
||||
} else {
|
||||
Cu.import("resource://firetray/linux/FiretrayGtkStatusIcon.jsm");
|
||||
}
|
||||
|
||||
Cu.import("resource://firetray/linux/FiretrayPopupMenu.jsm");
|
||||
if (!firetray.PopupMenu.init())
|
||||
return false;
|
||||
|
||||
this.addCallbacks();
|
||||
if (!firetray.StatusIcon.initImpl())
|
||||
return false;
|
||||
|
||||
this.initialized = true;
|
||||
return true;
|
||||
|
@ -64,9 +62,8 @@ firetray.StatusIcon = {
|
|||
|
||||
shutdown: function() {
|
||||
log.debug("Disabling StatusIcon");
|
||||
firetray.StatusIcon.shutdownImpl();
|
||||
firetray.PopupMenu.shutdown();
|
||||
// FIXME: should destroy/hide icon here
|
||||
firetray.GtkIcons.shutdown();
|
||||
this.initialized = false;
|
||||
},
|
||||
|
||||
|
@ -86,78 +83,71 @@ firetray.StatusIcon = {
|
|||
this.defaultNewMailIconName = "mail-unread";
|
||||
},
|
||||
|
||||
loadThemedIcons: function() {
|
||||
if (firetray.Handler.inMailApp) {
|
||||
let newMailIconNames = this.getNewMailIconNames();
|
||||
if (this.themedIconNewMail) gobject.g_object_unref(this.themedIconNewMail);
|
||||
this.themedIconNewMail = this.initThemedIcon(newMailIconNames);
|
||||
}
|
||||
let appIconNames = this.getAppIconNames();
|
||||
if (this.themedIconApp) gobject.g_object_unref(this.themedIconApp);
|
||||
this.themedIconApp = this.initThemedIcon(appIconNames);
|
||||
getAppIconNames: function() {
|
||||
let appIconNames = firetray.Utils.getArrayPref(
|
||||
firetray.StatusIcon.prefAppIconNames);
|
||||
appIconNames.push(firetray.StatusIcon.defaultAppIconName);
|
||||
return appIconNames;
|
||||
},
|
||||
getNewMailIconNames: function() {
|
||||
let newMailIconNames = firetray.Utils.getArrayPref(
|
||||
firetray.StatusIcon.prefNewMailIconNames);
|
||||
newMailIconNames.push(firetray.StatusIcon.defaultNewMailIconName);
|
||||
return newMailIconNames;
|
||||
},
|
||||
|
||||
loadImageCustom: function() { }, // done in setIconImageCustom
|
||||
|
||||
getAppIconNames: function() {
|
||||
let appIconNames = firetray.Utils.getArrayPref(this.prefAppIconNames);
|
||||
appIconNames.push(this.defaultAppIconName);
|
||||
return appIconNames;
|
||||
},
|
||||
getNewMailIconNames: function() {
|
||||
let newMailIconNames = firetray.Utils.getArrayPref(this.prefNewMailIconNames);
|
||||
newMailIconNames.push(this.defaultNewMailIconName);
|
||||
return newMailIconNames;
|
||||
dbusNotificationWatcherReady: function() {
|
||||
let watcherReady = false;
|
||||
|
||||
function error(e) {
|
||||
if (!e.isNull()) {
|
||||
log.error(e.contents.message);
|
||||
glib.g_error_free(e);
|
||||
}
|
||||
}
|
||||
|
||||
let conn = new gio.GDBusConnection.ptr;
|
||||
let err = new glib.GError.ptr(null);
|
||||
conn = gio.g_bus_get_sync(gio.G_BUS_TYPE_SESSION, null, err.address());
|
||||
if (error(err)) return watcherReady;
|
||||
|
||||
if (!conn.isNull()) {
|
||||
let flags = gio.G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
|
||||
gio.G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
gio.G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS;
|
||||
|
||||
let proxy = gio.g_dbus_proxy_new_for_bus_sync(
|
||||
gio.G_BUS_TYPE_SESSION,
|
||||
flags,
|
||||
null, /* GDBusInterfaceInfo */
|
||||
appind3.NOTIFICATION_WATCHER_DBUS_ADDR,
|
||||
appind3.NOTIFICATION_WATCHER_DBUS_OBJ,
|
||||
appind3.NOTIFICATION_WATCHER_DBUS_IFACE,
|
||||
null, /* GCancellable */
|
||||
err.address());
|
||||
if (error(err)) return watcherReady;
|
||||
|
||||
if (!proxy.isNull()) {
|
||||
let owner = gio.g_dbus_proxy_get_name_owner(proxy);
|
||||
if (!owner.isNull()) {
|
||||
watcherReady = true;
|
||||
}
|
||||
gobject.g_object_unref(proxy);
|
||||
}
|
||||
|
||||
gobject.g_object_unref(conn);
|
||||
}
|
||||
|
||||
return watcherReady;
|
||||
},
|
||||
|
||||
initThemedIcon: function(names) {
|
||||
if (!firetray.js.isArray(names)) throw new TypeError();
|
||||
log.debug("themedIconNames="+names);
|
||||
let namesLen = names.length;
|
||||
log.debug("themedIconNamesLen="+namesLen);
|
||||
let themedIconNames = ctypes.char.ptr.array(namesLen)();
|
||||
for (let i=0; i<namesLen; ++i)
|
||||
themedIconNames[i] = ctypes.char.array()(names[i]);
|
||||
log.debug("themedIconNames="+themedIconNames);
|
||||
let themedIcon = gio.g_themed_icon_new_from_names(themedIconNames, namesLen);
|
||||
log.debug("themedIcon="+themedIcon);
|
||||
return themedIcon;
|
||||
},
|
||||
|
||||
addCallbacks: function() {
|
||||
/* NOTE: here we do use a function handler (instead of a function
|
||||
definition) because we need the args passed to it ! As a consequence, we
|
||||
need to abandon 'this' in PopupMenu.popup() */
|
||||
this.callbacks.menuPopup = gtk.GCallbackMenuPopup_t(firetray.PopupMenu.popup);
|
||||
gobject.g_signal_connect(this.trayIcon, "popup-menu",
|
||||
firetray.StatusIcon.callbacks.menuPopup, firetray.PopupMenu.menu);
|
||||
this.callbacks.onScroll = gtk.GCallbackOnScroll_t(firetray.StatusIcon.onScroll);
|
||||
gobject.g_signal_connect(this.trayIcon, "scroll-event",
|
||||
firetray.StatusIcon.callbacks.onScroll, null);
|
||||
|
||||
log.debug("showHideAllWindows: "+firetray.Handler.hasOwnProperty("showHideAllWindows"));
|
||||
this.callbacks.iconActivate = gtk.GCallbackStatusIconActivate_t(
|
||||
firetray.StatusIcon.onClick);
|
||||
let handlerId = gobject.g_signal_connect(firetray.StatusIcon.trayIcon,
|
||||
"activate", firetray.StatusIcon.callbacks.iconActivate, null);
|
||||
log.debug("g_connect activate="+handlerId);
|
||||
|
||||
this.callbacks.iconMiddleClick = gtk.GCallbackStatusIconMiddleClick_t(
|
||||
firetray.Handler.activateLastWindowCb);
|
||||
handlerId = gobject.g_signal_connect(firetray.StatusIcon.trayIcon,
|
||||
"button-press-event", firetray.StatusIcon.callbacks.iconMiddleClick, null);
|
||||
log.debug("g_connect middleClick="+handlerId);
|
||||
},
|
||||
|
||||
onScroll: function(icon, event, data) {
|
||||
onScroll: function(direction) {
|
||||
if (!firetray.Utils.prefService.getBoolPref("scroll_hides"))
|
||||
return;
|
||||
return false;
|
||||
|
||||
let iconGpointer = ctypes.cast(icon, gobject.gpointer);
|
||||
let gdkEventScroll = ctypes.cast(event, gdk.GdkEventScroll.ptr);
|
||||
let scroll_mode = firetray.Utils.prefService.getCharPref("scroll_mode");
|
||||
|
||||
let direction = gdkEventScroll.contents.direction;
|
||||
switch(direction) {
|
||||
case gdk.GDK_SCROLL_UP:
|
||||
log.debug("SCROLL UP");
|
||||
|
@ -176,65 +166,12 @@ firetray.StatusIcon = {
|
|||
default:
|
||||
log.error("SCROLL UNKNOWN");
|
||||
}
|
||||
},
|
||||
|
||||
onClick: function(gtkStatusIcon, userData) {
|
||||
firetray.Handler.showHideAllWindows();
|
||||
let stopPropagation = true;
|
||||
return stopPropagation;
|
||||
},
|
||||
|
||||
setIconImageFromFile: function(filename) {
|
||||
if (!firetray.StatusIcon.trayIcon)
|
||||
log.error("Icon missing");
|
||||
log.debug(filename);
|
||||
gtk.gtk_status_icon_set_from_file(firetray.StatusIcon.trayIcon,
|
||||
filename);
|
||||
},
|
||||
|
||||
setIconImageFromGIcon: function(gicon) {
|
||||
if (!firetray.StatusIcon.trayIcon || !gicon)
|
||||
log.error("Icon missing");
|
||||
log.debug(gicon);
|
||||
gtk.gtk_status_icon_set_from_gicon(firetray.StatusIcon.trayIcon, gicon);
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // firetray.StatusIcon
|
||||
|
||||
firetray.Handler.setIconImageDefault = function() {
|
||||
log.debug("setIconImageDefault");
|
||||
if (!firetray.StatusIcon.themedIconApp)
|
||||
throw "Default application themed icon not set";
|
||||
let appIconType = firetray.Utils.prefService.getIntPref("app_icon_type");
|
||||
if (appIconType === FIRETRAY_APPLICATION_ICON_TYPE_THEMED)
|
||||
firetray.StatusIcon.setIconImageFromGIcon(firetray.StatusIcon.themedIconApp);
|
||||
else if (appIconType === FIRETRAY_APPLICATION_ICON_TYPE_CUSTOM)
|
||||
firetray.Handler.setIconImageCustom("app_icon_custom");
|
||||
};
|
||||
|
||||
firetray.Handler.setIconImageNewMail = function() {
|
||||
firetray.StatusIcon.setIconImageFromGIcon(firetray.StatusIcon.themedIconNewMail);
|
||||
};
|
||||
|
||||
firetray.Handler.setIconImageCustom = function(prefname) {
|
||||
let prefCustomIconPath = firetray.Utils.prefService.getCharPref(prefname);
|
||||
firetray.StatusIcon.setIconImageFromFile(prefCustomIconPath);
|
||||
};
|
||||
|
||||
// GTK bug: Gdk-CRITICAL **: IA__gdk_window_get_root_coords: assertion `GDK_IS_WINDOW (window)' failed
|
||||
firetray.Handler.setIconTooltip = function(toolTipStr) {
|
||||
if (!firetray.StatusIcon.trayIcon)
|
||||
return false;
|
||||
|
||||
try {
|
||||
gtk.gtk_status_icon_set_tooltip_text(firetray.StatusIcon.trayIcon,
|
||||
toolTipStr);
|
||||
} catch (x) {
|
||||
log.error(x);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
firetray.Handler.setIconTooltipDefault = function() {
|
||||
if (!this.appName)
|
||||
|
@ -242,117 +179,4 @@ firetray.Handler.setIconTooltipDefault = function() {
|
|||
this.setIconTooltip(this.appName);
|
||||
};
|
||||
|
||||
firetray.Handler.setIconText = function(text, color) { // FIXME: function too long
|
||||
log.debug("setIconText, color="+color);
|
||||
if (typeof(text) != "string")
|
||||
throw new TypeError();
|
||||
|
||||
try {
|
||||
// build background from image
|
||||
let specialIcon = gdk.gdk_pixbuf_new_from_file(
|
||||
firetray.StatusIcon.FILENAME_BLANK, null); // GError **error);
|
||||
let dest = gdk.gdk_pixbuf_copy(specialIcon);
|
||||
let w = gdk.gdk_pixbuf_get_width(specialIcon);
|
||||
let h = gdk.gdk_pixbuf_get_height(specialIcon);
|
||||
|
||||
// prepare colors/alpha
|
||||
let colorMap = gdk.gdk_screen_get_system_colormap(gdk.gdk_screen_get_default());
|
||||
let visual = gdk.gdk_colormap_get_visual(colorMap);
|
||||
let visualDepth = visual.contents.depth;
|
||||
log.debug("colorMap="+colorMap+" visual="+visual+" visualDepth="+visualDepth);
|
||||
let fore = new gdk.GdkColor;
|
||||
fore.pixel = fore.red = fore.green = fore.blue = 0;
|
||||
let alpha = new gdk.GdkColor;
|
||||
alpha.pixel = alpha.red = alpha.green = alpha.blue = 0xFFFF;
|
||||
if (!fore || !alpha)
|
||||
log.warn("Undefined GdkColor fore or alpha");
|
||||
gdk.gdk_color_parse(color, fore.address());
|
||||
if(fore.red == alpha.red && fore.green == alpha.green && fore.blue == alpha.blue) {
|
||||
alpha.red=0; // make sure alpha is different from fore
|
||||
}
|
||||
gdk.gdk_colormap_alloc_color(colorMap, fore.address(), true, true);
|
||||
gdk.gdk_colormap_alloc_color(colorMap, alpha.address(), true, true);
|
||||
|
||||
// build pixmap with rectangle
|
||||
let pm = gdk.gdk_pixmap_new(null, w, h, visualDepth);
|
||||
let pmDrawable = ctypes.cast(pm, gdk.GdkDrawable.ptr);
|
||||
let cr = gdk.gdk_cairo_create(pmDrawable);
|
||||
gdk.gdk_cairo_set_source_color(cr, alpha.address());
|
||||
cairo.cairo_rectangle(cr, 0, 0, w, h);
|
||||
cairo.cairo_set_source_rgb(cr, 1, 1, 1);
|
||||
cairo.cairo_fill(cr);
|
||||
|
||||
// build text
|
||||
let scratch = gtk.gtk_window_new(gtk.GTK_WINDOW_TOPLEVEL);
|
||||
let layout = gtk.gtk_widget_create_pango_layout(scratch, null);
|
||||
gtk.gtk_widget_destroy(scratch);
|
||||
let fnt = pango.pango_font_description_from_string("Sans 18");
|
||||
pango.pango_font_description_set_weight(fnt,pango.PANGO_WEIGHT_SEMIBOLD);
|
||||
pango.pango_layout_set_spacing(layout,0);
|
||||
pango.pango_layout_set_font_description(layout, fnt);
|
||||
log.debug("layout="+layout);
|
||||
log.debug("text="+text);
|
||||
pango.pango_layout_set_text(layout, text,-1);
|
||||
let tw = new ctypes.int;
|
||||
let th = new ctypes.int;
|
||||
let sz;
|
||||
let border = 4;
|
||||
pango.pango_layout_get_pixel_size(layout, tw.address(), th.address());
|
||||
log.debug("tw="+tw.value+" th="+th.value);
|
||||
// fit text to the icon by decreasing font size
|
||||
while ( tw.value > (w - border) || th.value > (h - border) ) {
|
||||
sz = pango.pango_font_description_get_size(fnt);
|
||||
if(sz < firetray.StatusIcon.MIN_FONT_SIZE) {
|
||||
sz = firetray.StatusIcon.MIN_FONT_SIZE;
|
||||
break;
|
||||
}
|
||||
sz -= pango.PANGO_SCALE;
|
||||
pango.pango_font_description_set_size(fnt,sz);
|
||||
pango.pango_layout_set_font_description(layout, fnt);
|
||||
pango.pango_layout_get_pixel_size(layout, tw.address(), th.address());
|
||||
}
|
||||
log.debug("tw="+tw.value+" th="+th.value);
|
||||
pango.pango_font_description_free(fnt);
|
||||
// center text
|
||||
let px = (w-tw.value)/2;
|
||||
let py = (h-th.value)/2;
|
||||
|
||||
// draw text on pixmap
|
||||
gdk.gdk_cairo_set_source_color(cr, fore.address());
|
||||
cairo.cairo_move_to(cr, px, py);
|
||||
pangocairo.pango_cairo_show_layout(cr, layout);
|
||||
cairo.cairo_destroy(cr);
|
||||
gobject.g_object_unref(layout);
|
||||
|
||||
let buf = gdk.gdk_pixbuf_get_from_drawable(null, pmDrawable, null, 0, 0, 0, 0, w, h);
|
||||
gobject.g_object_unref(pm);
|
||||
log.debug("alpha="+alpha);
|
||||
let alphaRed = gobject.guint16(alpha.red);
|
||||
let alphaRed_guchar = ctypes.cast(alphaRed, gobject.guchar);
|
||||
let alphaGreen = gobject.guint16(alpha.green);
|
||||
let alphaGreen_guchar = ctypes.cast(alphaGreen, gobject.guchar);
|
||||
let alphaBlue = gobject.guint16(alpha.blue);
|
||||
let alphaBlue_guchar = ctypes.cast(alphaBlue, gobject.guchar);
|
||||
let bufAlpha = gdk.gdk_pixbuf_add_alpha(buf, true, alphaRed_guchar, alphaGreen_guchar, alphaBlue_guchar);
|
||||
gobject.g_object_unref(buf);
|
||||
|
||||
// merge the rendered text on top
|
||||
gdk.gdk_pixbuf_composite(bufAlpha,dest,0,0,w,h,0,0,1,1,gdk.GDK_INTERP_BILINEAR,255);
|
||||
gobject.g_object_unref(bufAlpha);
|
||||
|
||||
log.debug("gtk_status_icon_set_from_pixbuf="+dest);
|
||||
gtk.gtk_status_icon_set_from_pixbuf(firetray.StatusIcon.trayIcon, dest);
|
||||
} catch (x) {
|
||||
log.error(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
firetray.Handler.setIconVisibility = function(visible) {
|
||||
if (!firetray.StatusIcon.trayIcon)
|
||||
return false;
|
||||
gtk.gtk_status_icon_set_visible(firetray.StatusIcon.trayIcon, visible);
|
||||
return true;
|
||||
};
|
||||
firetray.Handler.setIconTooltip = function(toolTipStr) { };
|
||||
|
|
|
@ -86,7 +86,7 @@ firetray.Window.shutdown = function() {
|
|||
* Iterate over all Gtk toplevel windows to find a window. We rely on
|
||||
* Service.wm to watch windows correctly: we should find only one window.
|
||||
*
|
||||
* @author Nils Maier (stolen from MiniTrayR)
|
||||
* @author Nils Maier (stolen from MiniTrayR), himself inspired by Windows docs
|
||||
* @param window nsIDOMWindow from Services.wm
|
||||
* @return a gtk.GtkWindow.ptr
|
||||
*/
|
||||
|
@ -105,7 +105,7 @@ firetray.Window.getGtkWindowFromChromeWindow = function(window) {
|
|||
// Search the window by the *temporary* title
|
||||
let widgets = gtk.gtk_window_list_toplevels();
|
||||
let that = this;
|
||||
let findGtkWindowByTitleCb = gobject.GFunc_t(that._findGtkWindowByTitle);
|
||||
let findGtkWindowByTitleCb = gobject.GFunc_t(that._findGtkWindowByTitle); // void return, no sentinel
|
||||
var userData = new _find_data_t(
|
||||
ctypes.char.array()(baseWindow.title),
|
||||
null
|
||||
|
@ -391,6 +391,7 @@ firetray.Window.xSendClientMessgeEvent = function(xid, atom, data, dataSize) {
|
|||
* raises window on top and give focus.
|
||||
*/
|
||||
firetray.Window.activate = function(xid) {
|
||||
// broken in KDE ?
|
||||
gtk.gtk_window_present(firetray.Handler.gtkWindows.get(xid));
|
||||
log.debug("window raised");
|
||||
};
|
||||
|
@ -590,18 +591,22 @@ firetray.Window.showAllWindowsAndActivate = function() {
|
|||
|
||||
firetray.Window.attachOnFocusInCallback = function(xid) {
|
||||
log.debug("attachOnFocusInCallback xid="+xid);
|
||||
this.signals['focus-in'].callback[xid] =
|
||||
gtk.GCallbackWidgetFocusEvent_t(firetray.Window.onFocusIn);
|
||||
this.signals['focus-in'].handler[xid] = gobject.g_signal_connect(
|
||||
firetray.Handler.gtkWindows.get(xid), "focus-in-event",
|
||||
firetray.Window.signals['focus-in'].callback[xid], null);
|
||||
log.debug("focus-in handler="+this.signals['focus-in'].handler[xid]);
|
||||
let callback = gtk.GCallbackWidgetFocusEvent_t(
|
||||
firetray.Window.onFocusIn, null, FIRETRAY_CB_SENTINEL);
|
||||
this.signals['focus-in'].callback[xid] = callback;
|
||||
let handlerId = gobject.g_signal_connect(
|
||||
firetray.Handler.gtkWindows.get(xid), "focus-in-event", callback, null);
|
||||
log.debug("focus-in handler="+handlerId);
|
||||
this.signals['focus-in'].handler[xid] = handlerId;
|
||||
};
|
||||
|
||||
firetray.Window.detachOnFocusInCallback = function(xid) {
|
||||
log.debug("detachOnFocusInCallback xid="+xid);
|
||||
let gtkWin = firetray.Handler.gtkWindows.get(xid);
|
||||
gobject.g_signal_handler_disconnect(gtkWin, this.signals['focus-in'].handler[xid]);
|
||||
gobject.g_signal_handler_disconnect(
|
||||
gtkWin,
|
||||
gobject.gulong(this.signals['focus-in'].handler[xid])
|
||||
);
|
||||
delete this.signals['focus-in'].callback[xid];
|
||||
delete this.signals['focus-in'].handler[xid];
|
||||
};
|
||||
|
@ -619,6 +624,9 @@ firetray.Window.onFocusIn = function(widget, event, data) {
|
|||
if (firetray.Handler.isChatEnabled() && firetray.Chat.initialized) {
|
||||
firetray.Chat.stopGetAttentionMaybe(xid);
|
||||
}
|
||||
|
||||
let stopPropagation = false;
|
||||
return stopPropagation;
|
||||
};
|
||||
|
||||
|
||||
|
@ -660,10 +668,12 @@ firetray.Handler.registerWindow = function(win) {
|
|||
// delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
|
||||
// provided 'close' JS event
|
||||
|
||||
this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow);
|
||||
this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(
|
||||
firetray.Window.filterWindow, null, FIRETRAY_CB_SENTINEL);
|
||||
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null);
|
||||
if (!firetray.Handler.appStarted) {
|
||||
this.windows[xid].startupFilterCb = gdk.GdkFilterFunc_t(firetray.Window.startupFilter);
|
||||
this.windows[xid].startupFilterCb = gdk.GdkFilterFunc_t(
|
||||
firetray.Window.startupFilter, null, FIRETRAY_CB_SENTINEL);
|
||||
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].startupFilterCb, null);
|
||||
}
|
||||
|
||||
|
@ -673,8 +683,8 @@ firetray.Handler.registerWindow = function(win) {
|
|||
}
|
||||
|
||||
} catch (x) {
|
||||
firetray.Window.unregisterWindowByXID(xid);
|
||||
log.error(x);
|
||||
firetray.Window.unregisterWindowByXID(xid);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -335,7 +335,7 @@ BasicFormatter.prototype = Object.create(Formatter.prototype);
|
|||
BasicFormatter.prototype.constructor = BasicFormatter;
|
||||
BasicFormatter.prototype.format = function BF_format(message) {
|
||||
return message.time + "\t" + message.loggerName + "\t" + message.levelDesc
|
||||
+ "\t" + message.message + "\n";
|
||||
+ "\t" + message.message;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -373,7 +373,7 @@ function DumpAppender(formatter) {
|
|||
DumpAppender.prototype = Object.create(Appender.prototype);
|
||||
DumpAppender.prototype.constructor = DumpAppender;
|
||||
DumpAppender.prototype.doAppend = function DApp_doAppend(message) {
|
||||
dump(message);
|
||||
dump(message + "\n");
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -47,11 +47,11 @@ var colorTermLogColors = {
|
|||
if ("undefined" == typeof(firetray)) {
|
||||
var firetray = {};
|
||||
};
|
||||
var LogMod;
|
||||
|
||||
// https://wiki.mozilla.org/Labs/JS_Modules#Logging
|
||||
firetray.Logging = {
|
||||
initialized: false,
|
||||
LogMod: null,
|
||||
|
||||
init: function() {
|
||||
if (this.initialized) return;
|
||||
|
@ -65,9 +65,9 @@ firetray.Logging = {
|
|||
}, this);
|
||||
|
||||
if ("undefined" != typeof(Log)) {
|
||||
LogMod = Log;
|
||||
this.LogMod = Log;
|
||||
} else if ("undefined" != typeof(Log4Moz)) {
|
||||
LogMod = Log4Moz;
|
||||
this.LogMod = Log4Moz;
|
||||
} else {
|
||||
let errMsg = "Log module not found";
|
||||
dump(errMsg+"\n");
|
||||
|
@ -85,8 +85,8 @@ firetray.Logging = {
|
|||
setupLogging: function(loggerName) {
|
||||
|
||||
// lifted from log4moz.js
|
||||
function SimpleFormatter() {LogMod.Formatter.call(this);}
|
||||
SimpleFormatter.prototype = Object.create(LogMod.Formatter.prototype);
|
||||
function SimpleFormatter() {firetray.Logging.LogMod.Formatter.call(this);}
|
||||
SimpleFormatter.prototype = Object.create(firetray.Logging.LogMod.Formatter.prototype);
|
||||
SimpleFormatter.prototype.constructor = SimpleFormatter;
|
||||
SimpleFormatter.prototype.format = function(message) {
|
||||
let messageString = "";
|
||||
|
@ -104,7 +104,7 @@ firetray.Logging = {
|
|||
date.getSeconds() + "." + date.getMilliseconds();
|
||||
let stringLog = dateStr + " " +
|
||||
message.levelDesc + " " + message.loggerName + " " +
|
||||
messageString + "\n";
|
||||
messageString;
|
||||
|
||||
if (message.exception)
|
||||
stringLog += message.stackTrace + "\n";
|
||||
|
@ -124,14 +124,14 @@ firetray.Logging = {
|
|||
};
|
||||
|
||||
// Loggers are hierarchical, affiliation is handled by a '.' in the name.
|
||||
this._logger = LogMod.repository.getLogger(loggerName);
|
||||
this._logger = this.LogMod.repository.getLogger(loggerName);
|
||||
// Lowering this log level will affect all of our addon output
|
||||
this._logger.level = LogMod.Level[FIRETRAY_LOG_LEVEL];
|
||||
this._logger.level = this.LogMod.Level[FIRETRAY_LOG_LEVEL];
|
||||
|
||||
// A console appender outputs to the JS Error Console
|
||||
let simpleFormatter = new SimpleFormatter();
|
||||
let capp = new LogMod.ConsoleAppender(simpleFormatter);
|
||||
capp.level = LogMod.Level["Debug"];
|
||||
let capp = new this.LogMod.ConsoleAppender(simpleFormatter);
|
||||
capp.level = this.LogMod.Level["Debug"];
|
||||
this._logger.addAppender(capp);
|
||||
|
||||
// A dump appender outputs to standard out
|
||||
|
@ -141,13 +141,13 @@ firetray.Logging = {
|
|||
} else {
|
||||
dumpFormatter = new SimpleFormatter();
|
||||
}
|
||||
let dapp = new LogMod.DumpAppender(dumpFormatter);
|
||||
dapp.level = LogMod.Level["Debug"];
|
||||
let dapp = new this.LogMod.DumpAppender(dumpFormatter);
|
||||
dapp.level = this.LogMod.Level["Debug"];
|
||||
this._logger.addAppender(dapp);
|
||||
},
|
||||
|
||||
getLogger: function(loggerName){
|
||||
return LogMod.repository.getLogger(loggerName);
|
||||
return this.LogMod.repository.getLogger(loggerName);
|
||||
}
|
||||
|
||||
}; // firetray.Logging
|
||||
|
|
|
@ -81,8 +81,6 @@ firetray.StatusIcon = {
|
|||
return true;
|
||||
},
|
||||
|
||||
loadThemedIcons: function() { },
|
||||
|
||||
loadImages: function() {
|
||||
let topmost = firetray.Handler.getWindowInterface(
|
||||
Services.wm.getMostRecentWindow(null), "nsIBaseWindow");
|
||||
|
@ -260,6 +258,14 @@ firetray.StatusIcon = {
|
|||
user32.SetForegroundWindow(hWnd);
|
||||
user32.TrackPopupMenu(firetray.PopupMenu.menu, user32.TPM_RIGHTALIGN|user32.TPM_BOTTOMALIGN, xPos, yPos, 0, hWnd, null);
|
||||
break;
|
||||
case win32.WM_MBUTTONUP:
|
||||
log.debug("WM_MBUTTONUP");
|
||||
break;
|
||||
// case win32.WM_VSCROLL:
|
||||
// case win32.WM_MOUSEWHEEL:
|
||||
/* getting scroll event from the icon is not straight-forward:
|
||||
SetWindowsHookEx, http://stackoverflow.com/a/90793/421846,
|
||||
http://www.codeproject.com/Articles/21218/Tray-Me */
|
||||
default:
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,8 @@ firetray.Window.wndProc = function(hWnd, uMsg, wParam, lParam) { // filterWindow
|
|||
}
|
||||
|
||||
let procPrev = firetray.Handler.wndProcsOrig.get(wid);
|
||||
return user32.CallWindowProcW(user32.WNDPROC(procPrev), hWnd, uMsg, wParam, lParam); // or DefWindowProcW
|
||||
return user32.CallWindowProcW(
|
||||
user32.WNDPROC(procPrev), hWnd, uMsg, wParam, lParam); // or DefWindowProcW
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -81,22 +82,27 @@ firetray.Window.wndProc = function(hWnd, uMsg, wParam, lParam) { // filterWindow
|
|||
* - a WH_CALLWNDPROC hook doesn't catch SWP_SHOWWINDOW
|
||||
* - chaining WNDPROCs crashes the app (UserCallWinProcCheckWow or ffi_call)
|
||||
*/
|
||||
firetray.Window.startupShowCount = 0;
|
||||
firetray.Window.wndProcStartup = function(hWnd, uMsg, wParam, lParam) {
|
||||
let wid = firetray.Win32.hwndToHexStr(hWnd);
|
||||
|
||||
if (uMsg === win32.WM_WINDOWPOSCHANGING) {
|
||||
let posStruct = ctypes.cast(win32.LPARAM(lParam), user32.WINDOWPOS.ptr).contents;
|
||||
let posStruct = ctypes.cast(win32.LPARAM(lParam),
|
||||
user32.WINDOWPOS.ptr).contents;
|
||||
|
||||
let isShowing = ((posStruct.flags & user32.SWP_SHOWWINDOW) != 0);
|
||||
if (isShowing) {
|
||||
log.debug("wndProcStartup CALLED with WM_WINDOWPOSCHANGING/SWP_SHOWWINDOW");
|
||||
firetray.Window.startupShowCount += 1;
|
||||
firetray.Window.startup.showCount += 1;
|
||||
|
||||
if (firetray.Window.startupShowCount < 2) { // hide
|
||||
if (firetray.Window.startup.showCount < 2) { // hide
|
||||
log.debug("start_hidden");
|
||||
// Modifying a JS posStruct field does really modify the WINDOWPOS C
|
||||
// struct behind lParam !
|
||||
posStruct.flags &= ~user32.SWP_SHOWWINDOW;
|
||||
// Modifying posStruct is modifying lParam, which is passed onwards!
|
||||
if (firetray.Window.startup.showSpecial) {
|
||||
posStruct.flags &= user32.SWP_NOSIZE|user32.SWP_NOMOVE;
|
||||
}
|
||||
else {
|
||||
posStruct.flags &= ~user32.SWP_SHOWWINDOW;
|
||||
}
|
||||
let force = true;
|
||||
firetray.Handler.addPopupMenuWindowItemAndSeparatorMaybe(wid, force);
|
||||
}
|
||||
|
@ -108,8 +114,17 @@ firetray.Window.wndProcStartup = function(hWnd, uMsg, wParam, lParam) {
|
|||
mapBak: null
|
||||
});
|
||||
firetray.Handler.wndProcsStartup.remove(wid);
|
||||
|
||||
if (firetray.Window.startup.showSpecial) {
|
||||
let placement = new user32.WINDOWPLACEMENT;
|
||||
let ret = user32.GetWindowPlacement(hWnd, placement.address());
|
||||
firetray.js.assert(ret, "GetWindowPlacement failed.");
|
||||
placement.showCmd = firetray.Window.startup.showSpecial;
|
||||
user32.SetWindowPlacement(hWnd, placement.address());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let procPrev = firetray.Handler.wndProcsOrig.get(wid);
|
||||
|
@ -197,6 +212,13 @@ firetray.Handler.registerWindow = function(win) {
|
|||
let proc, map;
|
||||
if (!firetray.Handler.appStarted &&
|
||||
firetray.Utils.prefService.getBoolPref('start_hidden')) {
|
||||
let startupInfo = new kernel32.STARTUPINFO;
|
||||
kernel32.GetStartupInfoW(startupInfo.address());
|
||||
let showSpecial = ([
|
||||
user32.SW_SHOWMINNOACTIVE, user32.SW_SHOWMINIMIZED,
|
||||
user32.SW_SHOWMAXIMIZED
|
||||
].indexOf(startupInfo.wShowWindow) > -1) ? startupInfo.wShowWindow : 0;
|
||||
firetray.Window.startup = {showCount: 0, showSpecial: showSpecial};
|
||||
proc = firetray.Window.wndProcStartup; map = firetray.Handler.wndProcsStartup;
|
||||
} else {
|
||||
proc = firetray.Window.wndProc; map = firetray.Handler.wndProcs;
|
||||
|
|
Loading…
Reference in New Issue