2012-01-22 22:04:05 -05:00
/* -*- 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" ) ;
2012-02-09 09:39:33 -05:00
Cu . import ( "resource://firetray/ctypes/linux/gobject.jsm" ) ;
Cu . import ( "resource://firetray/ctypes/linux/gtk.jsm" ) ;
2012-01-22 22:04:05 -05:00
Cu . import ( "resource://firetray/commons.js" ) ;
2012-08-07 17:37:32 -04:00
firetray . Handler . subscribeLibsForClosing ( [ gobject , gtk ] ) ;
2012-01-22 22:04:05 -05:00
2012-09-04 11:48:54 -04:00
let log = firetray . Logging . getLogger ( "firetray.PopupMenu" ) ;
2012-09-02 19:38:04 -04:00
2012-01-22 22:04:05 -05:00
if ( "undefined" == typeof ( firetray . StatusIcon ) )
2012-09-02 19:38:04 -04:00
log . error ( "This module MUST be imported from/after StatusIcon !" ) ;
2012-01-22 22:04:05 -05:00
firetray . PopupMenu = {
initialized : false ,
2012-01-26 05:37:41 -05:00
callbacks : { menuItemWindowActivate : { } } , // FIXME: try to store them into a ctypes array/struct.
2012-01-22 22:04:05 -05:00
menu : null ,
2012-06-01 07:01:54 -04:00
menuShell : null ,
2012-01-22 22:04:05 -05:00
menuSeparatorWindows : null ,
2012-06-01 07:01:54 -04:00
init : function ( ) {
2012-01-22 22:04:05 -05:00
this . menu = gtk . gtk _menu _new ( ) ;
2012-06-01 07:01:54 -04:00
this . menuShell = ctypes . cast ( this . menu , gtk . GtkMenuShell . ptr ) ;
2012-01-22 22:04:05 -05:00
var addMenuSeparator = false ;
2012-09-06 13:07:22 -04:00
if ( firetray . Handler . inMailApp ) {
2014-10-08 17:19:19 -04:00
this . addItem ( "ResetIcon" , "gtk-apply" , "activate" ,
firetray . Handler . setIconImageDefault ) ;
this . addItem ( "NewMessage" , "gtk-edit" , "activate" ,
firetray . Handler . openMailMessage ) ;
2012-01-22 22:04:05 -05:00
addMenuSeparator = true ;
}
2012-09-06 13:07:22 -04:00
if ( firetray . Handler . inBrowserApp ) {
2014-10-08 17:19:19 -04:00
this . addItem ( "NewWindow" , "gtk-new" , "activate" ,
firetray . Handler . openBrowserWindow ) ;
2012-01-22 22:04:05 -05:00
addMenuSeparator = true ;
}
2013-10-25 11:49:01 -04:00
var menuSeparator ;
2012-01-22 22:04:05 -05:00
if ( addMenuSeparator ) {
2013-10-25 11:49:01 -04:00
menuSeparator = gtk . gtk _separator _menu _item _new ( ) ;
2014-10-08 17:19:19 -04:00
gtk . gtk _menu _shell _append ( this . menuShell , ctypes . cast ( menuSeparator ,
gtk . GtkWidget . ptr ) ) ;
2012-01-22 22:04:05 -05:00
}
2014-10-08 17:19:19 -04:00
this . addItem ( "Preferences" , "gtk-preferences" , "activate" ,
firetray . Handler . openPrefWindow ) ;
2013-10-25 11:49:01 -04:00
menuSeparator = gtk . gtk _separator _menu _item _new ( ) ;
2014-10-08 17:19:19 -04:00
gtk . gtk _menu _shell _append ( this . menuShell , ctypes . cast ( menuSeparator ,
gtk . GtkWidget . ptr ) ) ;
2013-10-25 11:49:01 -04:00
2014-10-08 17:19:19 -04:00
this . addItem ( "Quit" , "gtk-quit" , "activate" ,
firetray . Handler . quitApplication ) ;
2012-01-22 22:04:05 -05:00
var menuWidget = ctypes . cast ( this . menu , gtk . GtkWidget . ptr ) ;
gtk . gtk _widget _show _all ( menuWidget ) ;
var menuSeparatorWindows = gtk . gtk _separator _menu _item _new ( ) ;
2014-10-08 17:19:19 -04:00
gtk . gtk _menu _shell _prepend ( this . menuShell , ctypes . cast ( menuSeparatorWindows ,
gtk . GtkWidget . ptr ) ) ;
2012-01-22 22:04:05 -05:00
this . menuSeparatorWindows = menuSeparatorWindows ;
this . initialized = true ;
return true ;
} ,
shutdown : function ( ) {
2012-09-03 18:25:29 -04:00
log . debug ( "Disabling PopupMenu" ) ;
2012-01-22 22:04:05 -05:00
this . initialized = false ;
} ,
2012-06-01 07:01:54 -04:00
addItem : function ( itemName , iconName , action , callback ) {
2013-10-25 11:49:01 -04:00
var menuItemLabel = firetray . Utils . strings . GetStringFromName ( "popupMenu.itemLabel." + itemName ) ; // shouldn't need to convert to utf8 later thank to js-ctypes
2012-06-01 07:01:54 -04:00
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 ) ;
2012-09-02 19:38:04 -04:00
log . debug ( "cbName=" + cbName ) ;
2014-10-08 17:19:19 -04:00
this . callbacks [ cbName ] = gobject . GCallback _t ( callback ) ; // void return, no sentinel
2012-06-01 07:01:54 -04:00
gobject . g _signal _connect ( menuItem , action ,
firetray . PopupMenu . callbacks [ cbName ] , null ) ;
} ,
2012-01-22 22:04:05 -05:00
popup : function ( icon , button , activateTime , menu ) {
2012-09-02 19:38:04 -04:00
log . debug ( "menu-popup" ) ;
log . debug ( "ARGS=" + icon + ", " + button + ", " + activateTime + ", " + menu ) ;
2012-01-22 22:04:05 -05:00
2014-10-08 17:19:19 -04:00
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 ;
2012-01-22 22:04:05 -05:00
} ,
// 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
2014-10-15 18:01:07 -04:00
log . debug ( "addWindowItem" ) ;
2012-03-28 11:57:02 -04:00
var menuItemWindow = this . createAndAddItemToMenu ( ) ;
2012-01-22 22:04:05 -05:00
firetray . Handler . gtkPopupMenuWindowItems . insert ( xid , menuItemWindow ) ;
2012-03-28 11:57:02 -04:00
this . setWindowItemLabel ( menuItemWindow , xid . toString ( ) ) ; // default to xid
2012-01-22 22:04:05 -05:00
2014-10-08 17:19:19 -04:00
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 ) ;
2012-01-22 22:04:05 -05:00
2012-09-02 19:38:04 -04:00
log . debug ( "added gtkPopupMenuWindowItems: " + firetray . Handler . gtkPopupMenuWindowItems . count ) ;
2012-01-22 22:04:05 -05:00
} ,
2012-03-28 11:57:02 -04:00
createAndAddItemToMenu : function ( ) {
2012-01-22 22:04:05 -05:00
var menuItem = gtk . gtk _image _menu _item _new ( ) ;
2014-10-08 17:19:19 -04:00
gtk . gtk _menu _shell _prepend ( this . menuShell , ctypes . cast ( menuItem ,
gtk . GtkWidget . ptr ) ) ;
2012-01-22 22:04:05 -05:00
return menuItem ;
} ,
removeWindowItem : function ( xid ) { // on unregisterWindow
let menuItemWindow = firetray . Handler . gtkPopupMenuWindowItems . get ( xid ) ;
firetray . Handler . gtkPopupMenuWindowItems . remove ( xid ) ;
this . removeItem ( menuItemWindow ) ;
2012-09-02 19:38:04 -04:00
log . debug ( "remove gtkPopupMenuWindowItems: " + firetray . Handler . gtkPopupMenuWindowItems . count ) ;
2012-01-22 22:04:05 -05:00
} ,
removeItem : function ( item ) {
gtk . gtk _widget _destroy ( ctypes . cast ( item , gtk . GtkWidget . ptr ) ) ;
} ,
showAllWindowItemsOnlyVisibleWindows : function ( ) {
for ( let xid in firetray . Handler . windows )
2012-04-30 15:24:27 -04:00
if ( ! firetray . Handler . windows [ xid ] . visible )
2012-07-23 20:00:44 -04:00
this . showWindowItem ( xid ) ;
2012-01-22 22:04:05 -05:00
} ,
2012-07-23 20:00:44 -04:00
showWindowItem : function ( xid ) {
2012-02-20 09:34:51 -05:00
if ( ! this . windowItemsHandled ( ) )
return ;
2012-09-02 19:38:04 -04:00
log . debug ( "showWindowItem" ) ;
2012-01-22 22:04:05 -05:00
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 ) {
2012-09-02 19:38:04 -04:00
log . debug ( "about to set title: " + label ) ;
2012-01-22 22:04:05 -05:00
if ( label )
gtk . gtk _menu _item _set _label ( ctypes . cast ( menuItem , gtk . GtkMenuItem . ptr ) , label ) ;
} ,
hideAllWindowItems : function ( ) {
for ( let xid in firetray . Handler . windows )
2012-07-23 20:00:44 -04:00
this . hideWindowItemAndSeparator ( xid ) ;
2012-01-22 22:04:05 -05:00
} ,
2012-07-23 20:00:44 -04:00
hideWindowItemAndSeparator : function ( xid ) {
this . hideWindowItem ( xid ) ;
2012-01-22 22:04:05 -05:00
this . hideWindowSeparator ( ) ;
} ,
2012-07-23 20:00:44 -04:00
hideWindowItemAndSeparatorMaybe : function ( xid ) {
2014-04-05 11:10:55 -04:00
if ( ! this . windowItemsHandled ( ) ) return ;
2012-02-20 09:34:51 -05:00
2012-07-23 20:00:44 -04:00
this . hideWindowItem ( xid ) ;
2012-01-22 22:04:05 -05:00
if ( firetray . Handler . visibleWindowsCount === firetray . Handler . windowsCount )
this . hideWindowSeparator ( ) ;
} ,
2012-07-23 20:00:44 -04:00
hideWindowItem : function ( xid ) {
2012-09-02 19:38:04 -04:00
log . debug ( "hideWindowItem" ) ;
2012-01-22 22:04:05 -05:00
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 ( ) {
2012-09-02 19:38:04 -04:00
log . debug ( "showing menuSeparatorWindows" ) ;
2012-01-22 22:04:05 -05:00
gtk . gtk _widget _show ( ctypes . cast ( this . menuSeparatorWindows , gtk . GtkWidget . ptr ) ) ;
} ,
hideWindowSeparator : function ( ) {
2012-09-02 19:38:04 -04:00
log . debug ( "hiding menuSeparatorWindows" ) ;
2012-01-22 22:04:05 -05:00
gtk . gtk _widget _hide ( ctypes . cast ( this . menuSeparatorWindows , gtk . GtkWidget . ptr ) ) ;
2012-02-20 09:34:51 -05:00
} ,
2012-01-22 22:04:05 -05:00
2012-02-20 09:34:51 -05:00
showHideWindowItems : function ( ) {
if ( this . windowItemsHandled ( ) )
this . showAllWindowItemsOnlyVisibleWindows ( ) ;
else
this . hideAllWindowItems ( ) ;
} ,
2012-01-22 22:04:05 -05:00
2012-02-20 09:34:51 -05:00
windowItemsHandled : function ( ) {
2013-03-10 17:21:02 -04:00
return firetray . Utils . prefService . getBoolPref ( 'hides_single_window' ) ;
2012-02-20 09:34:51 -05:00
}
2012-01-22 22:04:05 -05:00
2012-02-20 09:34:51 -05:00
} ; // firetray.PopupMenu
2012-01-22 22:04:05 -05:00
2014-04-05 11:10:55 -04:00
firetray . Handler . showHidePopupMenuItems =
firetray . PopupMenu . showHideWindowItems . bind ( firetray . PopupMenu ) ;