227 lines
8.1 KiB
JavaScript
227 lines
8.1 KiB
JavaScript
/* -*- 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/Services.jsm");
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
Cu.import("resource://gre/modules/ctypes.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.PopupMenu");
|
|
|
|
if ("undefined" == typeof(firetray.StatusIcon))
|
|
log.error("This module MUST be imported from/after StatusIcon !");
|
|
|
|
|
|
firetray.PopupMenu = {
|
|
initialized: false,
|
|
callbacks: {menuItemWindowActivate: {}}, // FIXME: try to store them into a ctypes array/struct.
|
|
menu: null,
|
|
menuShell: null,
|
|
menuSeparatorWindows: null,
|
|
|
|
init: function() {
|
|
this.menu = gtk.gtk_menu_new();
|
|
this.menuShell = ctypes.cast(this.menu, gtk.GtkMenuShell.ptr);
|
|
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);
|
|
addMenuSeparator = true;
|
|
}
|
|
|
|
if (firetray.Handler.inBrowserApp) {
|
|
this.addItem("NewWindow", "gtk-new", "activate",
|
|
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));
|
|
}
|
|
|
|
this.addItem("Preferences", "gtk-preferences", "activate",
|
|
firetray.Handler.openPrefWindow);
|
|
menuSeparator = gtk.gtk_separator_menu_item_new();
|
|
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuSeparator,
|
|
gtk.GtkWidget.ptr));
|
|
|
|
this.addItem("Quit", "gtk-quit", "activate",
|
|
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;
|
|
|
|
this.initialized = true;
|
|
return true;
|
|
},
|
|
|
|
shutdown: function() {
|
|
log.debug("Disabling 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
|
|
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);
|
|
gtk.gtk_image_menu_item_set_image(menuItem, menuItemIcon);
|
|
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuItem, gtk.GtkWidget.ptr));
|
|
|
|
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); // void return, no sentinel
|
|
gobject.g_signal_connect(menuItem, action,
|
|
firetray.PopupMenu.callbacks[cbName], null);
|
|
},
|
|
|
|
popup: function(icon, button, activateTime, menu) {
|
|
log.debug("menu-popup");
|
|
log.debug("ARGS="+icon+", "+button+", "+activateTime+", "+menu);
|
|
|
|
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
|
|
log.debug("addWindowItem");
|
|
var menuItemWindow = this.createAndAddItemToMenu();
|
|
firetray.Handler.gtkPopupMenuWindowItems.insert(xid, menuItemWindow);
|
|
this.setWindowItemLabel(menuItemWindow, xid.toString()); // default to xid
|
|
|
|
let callback = gobject.GCallback_t(
|
|
function(){firetray.Handler.showWindow(xid);}, null, FIRETRAY_CB_SENTINEL); // 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() {
|
|
var menuItem = gtk.gtk_image_menu_item_new();
|
|
gtk.gtk_menu_shell_prepend(this.menuShell, ctypes.cast(menuItem,
|
|
gtk.GtkWidget.ptr));
|
|
return menuItem;
|
|
},
|
|
|
|
removeWindowItem: function(xid) { // on unregisterWindow
|
|
let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
|
|
firetray.Handler.gtkPopupMenuWindowItems.remove(xid);
|
|
this.removeItem(menuItemWindow);
|
|
log.debug("remove gtkPopupMenuWindowItems: "+firetray.Handler.gtkPopupMenuWindowItems.count);
|
|
},
|
|
removeItem: function(item) {
|
|
gtk.gtk_widget_destroy(ctypes.cast(item, gtk.GtkWidget.ptr));
|
|
},
|
|
|
|
showAllWindowItemsOnlyVisibleWindows: function() {
|
|
for (let xid in firetray.Handler.windows)
|
|
if (!firetray.Handler.windows[xid].visible)
|
|
this.showWindowItem(xid);
|
|
},
|
|
|
|
showWindowItem: function(xid) {
|
|
if (!this.windowItemsHandled())
|
|
return;
|
|
|
|
log.debug("showWindowItem");
|
|
let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
|
|
this.showItem(menuItemWindow);
|
|
this.setWindowItemLabel(menuItemWindow, firetray.Window.getWindowTitle(xid));
|
|
this.showWindowSeparator();
|
|
},
|
|
|
|
showItem: function(menuItem) {
|
|
gtk.gtk_widget_show(ctypes.cast(menuItem, gtk.GtkWidget.ptr));
|
|
},
|
|
|
|
setWindowItemLabel: 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);
|
|
},
|
|
|
|
hideAllWindowItems: function() {
|
|
for (let xid in firetray.Handler.windows)
|
|
this.hideWindowItemAndSeparator(xid);
|
|
},
|
|
|
|
hideWindowItemAndSeparator: function(xid) {
|
|
this.hideWindowItem(xid);
|
|
this.hideWindowSeparator();
|
|
},
|
|
|
|
hideWindowItemAndSeparatorMaybe: function(xid) {
|
|
if (!this.windowItemsHandled()) return;
|
|
|
|
this.hideWindowItem(xid);
|
|
if (firetray.Handler.visibleWindowsCount === firetray.Handler.windowsCount)
|
|
this.hideWindowSeparator();
|
|
},
|
|
|
|
hideWindowItem: function(xid) {
|
|
log.debug("hideWindowItem");
|
|
let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
|
|
this.hideItem(menuItemWindow);
|
|
},
|
|
|
|
hideItem: function(menuItem) {
|
|
gtk.gtk_widget_hide(ctypes.cast(menuItem, gtk.GtkWidget.ptr));
|
|
},
|
|
|
|
showWindowSeparator: function() {
|
|
log.debug("showing menuSeparatorWindows");
|
|
gtk.gtk_widget_show(ctypes.cast(this.menuSeparatorWindows, gtk.GtkWidget.ptr));
|
|
},
|
|
hideWindowSeparator: function() {
|
|
log.debug("hiding menuSeparatorWindows");
|
|
gtk.gtk_widget_hide(ctypes.cast(this.menuSeparatorWindows, gtk.GtkWidget.ptr));
|
|
},
|
|
|
|
showHideWindowItems: function() {
|
|
if (this.windowItemsHandled())
|
|
this.showAllWindowItemsOnlyVisibleWindows();
|
|
else
|
|
this.hideAllWindowItems();
|
|
},
|
|
|
|
windowItemsHandled: function() {
|
|
return firetray.Utils.prefService.getBoolPref('hides_single_window');
|
|
}
|
|
|
|
}; // firetray.PopupMenu
|
|
|
|
firetray.Handler.showHidePopupMenuItems =
|
|
firetray.PopupMenu.showHideWindowItems.bind(firetray.PopupMenu);
|