2011-09-28 13:16:26 +00:00
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
2009-11-10 17:13:58 +00:00
2011-05-10 14:13:05 +00:00
const AccountsService = imports . gi . AccountsService ;
2012-05-19 23:19:25 +00:00
const Gdm = imports . gi . Gdm ;
2011-03-21 12:51:46 +00:00
const Gio = imports . gi . Gio ;
2009-11-10 17:13:58 +00:00
const GLib = imports . gi . GLib ;
2013-02-11 16:39:29 +00:00
const Gtk = imports . gi . Gtk ;
2009-11-10 17:13:58 +00:00
const Lang = imports . lang ;
2011-08-23 17:15:31 +00:00
const Pango = imports . gi . Pango ;
2009-11-10 17:13:58 +00:00
const Shell = imports . gi . Shell ;
const St = imports . gi . St ;
2011-02-28 16:03:35 +00:00
const Tp = imports . gi . TelepathyGLib ;
2012-02-27 16:31:10 +00:00
const Atk = imports . gi . Atk ;
2013-02-11 16:39:29 +00:00
const Clutter = imports . gi . Clutter ;
2009-11-10 17:13:58 +00:00
2012-09-19 03:02:15 +00:00
const BoxPointer = imports . ui . boxpointer ;
2010-04-29 17:13:20 +00:00
const GnomeSession = imports . misc . gnomeSession ;
2012-10-19 15:41:10 +00:00
const LoginManager = imports . misc . loginManager ;
2010-06-03 23:21:08 +00:00
const Main = imports . ui . main ;
2013-02-11 16:39:29 +00:00
const ModalDialog = imports . ui . modalDialog ;
2010-06-22 21:02:26 +00:00
const PanelMenu = imports . ui . panelMenu ;
2010-05-20 15:18:46 +00:00
const PopupMenu = imports . ui . popupMenu ;
2012-08-16 20:21:14 +00:00
const Params = imports . misc . params ;
2010-11-17 16:43:08 +00:00
const Util = imports . misc . util ;
2009-11-10 17:13:58 +00:00
2011-03-21 12:51:46 +00:00
const LOCKDOWN _SCHEMA = 'org.gnome.desktop.lockdown' ;
2012-08-13 23:51:51 +00:00
const SCREENSAVER _SCHEMA = 'org.gnome.desktop.screensaver' ;
2013-01-15 08:30:43 +00:00
const PRIVACY _SCHEMA = 'org.gnome.desktop.privacy'
2011-03-21 12:51:46 +00:00
const DISABLE _USER _SWITCH _KEY = 'disable-user-switching' ;
const DISABLE _LOCK _SCREEN _KEY = 'disable-lock-screen' ;
const DISABLE _LOG _OUT _KEY = 'disable-log-out' ;
2012-10-29 04:27:18 +00:00
const ALWAYS _SHOW _LOG _OUT _KEY = 'always-show-log-out' ;
2013-01-15 08:30:43 +00:00
const SHOW _FULL _NAME _IN _TOP _BAR _KEY = 'show-full-name-in-top-bar' ;
2011-03-21 12:51:46 +00:00
2011-07-28 14:59:03 +00:00
const DIALOG _ICON _SIZE = 64 ;
2013-02-11 16:39:29 +00:00
const MAX _USERS _IN _SESSION _DIALOG = 5 ;
2011-07-28 14:59:03 +00:00
const IMStatus = {
AVAILABLE : 0 ,
BUSY : 1 ,
HIDDEN : 2 ,
AWAY : 3 ,
IDLE : 4 ,
OFFLINE : 5 ,
LAST : 6
} ;
2013-02-11 16:39:29 +00:00
const SystemdLoginSessionIface = < interface name = 'org.freedesktop.login1.Session' >
2013-02-18 17:03:13 +00:00
< property name = "Id" type = "s" access = "read" / >
2013-02-11 16:39:29 +00:00
< property name = "Remote" type = "b" access = "read" / >
< property name = "Class" type = "s" access = "read" / >
< property name = "Type" type = "s" access = "read" / >
2013-03-02 15:53:50 +00:00
< property name = "State" type = "s" access = "read" / >
2013-02-11 16:39:29 +00:00
< / i n t e r f a c e > ;
const SystemdLoginSession = Gio . DBusProxy . makeProxyWrapper ( SystemdLoginSessionIface ) ;
2009-11-10 17:13:58 +00:00
// Adapted from gdm/gui/user-switch-applet/applet.c
//
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
// Copyright (C) 2008,2009 Red Hat, Inc.
2012-07-14 15:12:54 +00:00
const UserAvatarWidget = new Lang . Class ( {
Name : 'UserAvatarWidget' ,
2012-08-16 20:21:14 +00:00
_init : function ( user , params ) {
2012-07-14 15:12:54 +00:00
this . _user = user ;
2012-08-31 21:18:26 +00:00
params = Params . parse ( params , { reactive : false ,
iconSize : DIALOG _ICON _SIZE ,
styleClass : 'status-chooser-user-icon' } ) ;
this . _iconSize = params . iconSize ;
2012-07-14 15:12:54 +00:00
2012-08-31 21:18:26 +00:00
this . actor = new St . Bin ( { style _class : params . styleClass ,
2012-08-16 20:21:14 +00:00
track _hover : params . reactive ,
reactive : params . reactive } ) ;
2012-07-14 15:12:54 +00:00
} ,
2012-09-01 12:42:53 +00:00
setSensitive : function ( sensitive ) {
this . actor . can _focus = sensitive ;
this . actor . reactive = sensitive ;
} ,
2012-07-14 15:12:54 +00:00
update : function ( ) {
let iconFile = this . _user . get _icon _file ( ) ;
2013-02-11 16:16:44 +00:00
if ( iconFile && ! GLib . file _test ( iconFile , GLib . FileTest . EXISTS ) )
2012-07-14 15:12:54 +00:00
iconFile = null ;
if ( iconFile ) {
let file = Gio . File . new _for _path ( iconFile ) ;
this . actor . child = null ;
this . actor . style = 'background-image: url("%s");' . format ( iconFile ) ;
} else {
this . actor . style = null ;
2012-08-30 11:23:00 +00:00
this . actor . child = new St . Icon ( { icon _name : 'avatar-default-symbolic' ,
2012-08-31 21:18:26 +00:00
icon _size : this . _iconSize } ) ;
2012-07-14 15:12:54 +00:00
}
}
} ) ;
2011-07-28 14:59:03 +00:00
2011-11-20 13:10:48 +00:00
const IMStatusItem = new Lang . Class ( {
Name : 'IMStatusItem' ,
Extends : PopupMenu . PopupBaseMenuItem ,
2011-07-28 14:59:03 +00:00
_init : function ( label , iconName ) {
2011-11-20 13:10:48 +00:00
this . parent ( ) ;
2011-07-28 14:59:03 +00:00
this . actor . add _style _class _name ( 'status-chooser-status-item' ) ;
this . _icon = new St . Icon ( { style _class : 'popup-menu-icon' } ) ;
this . addActor ( this . _icon ) ;
if ( iconName )
this . _icon . icon _name = iconName ;
this . label = new St . Label ( { text : label } ) ;
2012-03-15 18:04:54 +00:00
this . actor . label _actor = this . label ;
2011-07-28 14:59:03 +00:00
this . addActor ( this . label ) ;
}
2011-11-20 13:10:48 +00:00
} ) ;
2011-07-28 14:59:03 +00:00
2011-11-20 13:10:48 +00:00
const IMUserNameItem = new Lang . Class ( {
Name : 'IMUserNameItem' ,
Extends : PopupMenu . PopupBaseMenuItem ,
2011-07-28 14:59:03 +00:00
_init : function ( ) {
2011-11-20 13:10:48 +00:00
this . parent ( { reactive : false ,
2012-08-21 15:39:01 +00:00
can _focus : false ,
2011-11-20 13:10:48 +00:00
style _class : 'status-chooser-user-name' } ) ;
2011-07-28 14:59:03 +00:00
this . _wrapper = new Shell . GenericContainer ( ) ;
this . _wrapper . connect ( 'get-preferred-width' ,
Lang . bind ( this , this . _wrapperGetPreferredWidth ) ) ;
this . _wrapper . connect ( 'get-preferred-height' ,
Lang . bind ( this , this . _wrapperGetPreferredHeight ) ) ;
this . _wrapper . connect ( 'allocate' ,
Lang . bind ( this , this . _wrapperAllocate ) ) ;
this . addActor ( this . _wrapper , { expand : true , span : - 1 } ) ;
this . label = new St . Label ( ) ;
this . label . clutter _text . set _line _wrap ( true ) ;
2011-08-23 17:15:31 +00:00
this . label . clutter _text . set _ellipsize ( Pango . EllipsizeMode . NONE ) ;
2011-07-28 14:59:03 +00:00
this . _wrapper . add _actor ( this . label ) ;
} ,
_wrapperGetPreferredWidth : function ( actor , forHeight , alloc ) {
2011-08-23 17:15:31 +00:00
alloc . min _size = 1 ;
alloc . natural _size = 1 ;
2011-07-28 14:59:03 +00:00
} ,
_wrapperGetPreferredHeight : function ( actor , forWidth , alloc ) {
[ alloc . min _size , alloc . natural _size ] = this . label . get _preferred _height ( forWidth ) ;
} ,
_wrapperAllocate : function ( actor , box , flags ) {
this . label . allocate ( box , flags ) ;
}
2011-11-20 13:10:48 +00:00
} ) ;
2011-07-28 14:59:03 +00:00
2011-11-20 13:10:48 +00:00
const IMStatusChooserItem = new Lang . Class ( {
Name : 'IMStatusChooserItem' ,
Extends : PopupMenu . PopupBaseMenuItem ,
2011-07-28 14:59:03 +00:00
_init : function ( ) {
2011-11-20 13:10:48 +00:00
this . parent ( { reactive : false ,
2012-08-21 15:39:01 +00:00
can _focus : false ,
2011-11-20 13:10:48 +00:00
style _class : 'status-chooser' } ) ;
2011-07-28 14:59:03 +00:00
2012-07-14 15:12:54 +00:00
this . _userManager = AccountsService . UserManager . get _default ( ) ;
this . _user = this . _userManager . get _user ( GLib . get _user _name ( ) ) ;
2012-08-31 21:18:26 +00:00
this . _avatar = new UserAvatarWidget ( this . _user , { reactive : true } ) ;
2012-07-14 15:12:54 +00:00
this . _iconBin = new St . Button ( { child : this . _avatar . actor } ) ;
2011-07-28 14:59:03 +00:00
this . addActor ( this . _iconBin ) ;
this . _iconBin . connect ( 'clicked' , Lang . bind ( this ,
function ( ) {
this . activate ( ) ;
} ) ) ;
this . _section = new PopupMenu . PopupMenuSection ( ) ;
this . addActor ( this . _section . actor ) ;
this . _name = new IMUserNameItem ( ) ;
this . _section . addMenuItem ( this . _name ) ;
this . _combo = new PopupMenu . PopupComboBoxMenuItem ( { style _class : 'status-chooser-combo' } ) ;
this . _section . addMenuItem ( this . _combo ) ;
let item ;
2012-05-30 13:58:37 +00:00
item = new IMStatusItem ( _ ( "Available" ) , 'user-available-symbolic' ) ;
2011-07-28 14:59:03 +00:00
this . _combo . addMenuItem ( item , IMStatus . AVAILABLE ) ;
2012-05-30 13:58:37 +00:00
item = new IMStatusItem ( _ ( "Busy" ) , 'user-busy-symbolic' ) ;
2011-07-28 14:59:03 +00:00
this . _combo . addMenuItem ( item , IMStatus . BUSY ) ;
2012-05-30 13:58:37 +00:00
item = new IMStatusItem ( _ ( "Invisible" ) , 'user-invisible-symbolic' ) ;
2011-07-28 14:59:03 +00:00
this . _combo . addMenuItem ( item , IMStatus . HIDDEN ) ;
2012-05-30 13:58:37 +00:00
item = new IMStatusItem ( _ ( "Away" ) , 'user-away-symbolic' ) ;
2011-07-28 14:59:03 +00:00
this . _combo . addMenuItem ( item , IMStatus . AWAY ) ;
2012-05-30 13:58:37 +00:00
item = new IMStatusItem ( _ ( "Idle" ) , 'user-idle-symbolic' ) ;
2011-07-28 14:59:03 +00:00
this . _combo . addMenuItem ( item , IMStatus . IDLE ) ;
2012-10-30 20:56:06 +00:00
item = new IMStatusItem ( _ ( "Offline" ) , 'user-offline-symbolic' ) ;
2011-07-28 14:59:03 +00:00
this . _combo . addMenuItem ( item , IMStatus . OFFLINE ) ;
this . _combo . connect ( 'active-item-changed' ,
Lang . bind ( this , this . _changeIMStatus ) ) ;
this . _presence = new GnomeSession . Presence ( ) ;
2011-08-16 12:24:39 +00:00
this . _presence . connectSignal ( 'StatusChanged' , Lang . bind ( this , function ( proxy , senderName , [ status ] ) {
2011-11-11 21:41:47 +00:00
this . _sessionStatusChanged ( status ) ;
2011-08-16 12:24:39 +00:00
} ) ) ;
2011-07-28 14:59:03 +00:00
2011-10-06 00:47:18 +00:00
this . _sessionPresenceRestored = false ;
this . _imPresenceRestored = false ;
2011-09-02 12:15:31 +00:00
this . _currentPresence = undefined ;
2011-07-28 14:59:03 +00:00
2011-10-20 20:54:41 +00:00
this . _accountMgr = Tp . AccountManager . dup ( ) ;
2011-07-28 14:59:03 +00:00
this . _accountMgr . connect ( 'most-available-presence-changed' ,
Lang . bind ( this , this . _IMStatusChanged ) ) ;
2011-10-26 19:16:08 +00:00
this . _accountMgr . connect ( 'account-enabled' ,
Lang . bind ( this , this . _IMAccountsChanged ) ) ;
this . _accountMgr . connect ( 'account-disabled' ,
Lang . bind ( this , this . _IMAccountsChanged ) ) ;
this . _accountMgr . connect ( 'account-removed' ,
Lang . bind ( this , this . _IMAccountsChanged ) ) ;
2012-03-16 21:47:42 +00:00
this . _accountMgr . connect ( 'account-validity-changed' ,
Lang . bind ( this , this . _IMAccountsChanged ) ) ;
2011-07-28 14:59:03 +00:00
this . _accountMgr . prepare _async ( null , Lang . bind ( this ,
function ( mgr ) {
2011-10-26 19:16:08 +00:00
this . _IMAccountsChanged ( mgr ) ;
2012-06-12 23:03:33 +00:00
if ( this . _networkMonitor . network _available )
this . _restorePresence ( ) ;
else
this . _setComboboxPresence ( Tp . ConnectionPresenceType . OFFLINE ) ;
} ) ) ;
this . _networkMonitor = Gio . NetworkMonitor . get _default ( ) ;
this . _networkMonitor . connect ( 'network-changed' ,
Lang . bind ( this , function ( monitor , available ) {
2012-06-12 22:44:29 +00:00
this . _IMAccountsChanged ( this . _accountMgr ) ;
2012-06-12 23:03:33 +00:00
if ( available && ! this . _imPresenceRestored )
this . _restorePresence ( ) ;
2011-07-28 14:59:03 +00:00
} ) ) ;
this . _userLoadedId = this . _user . connect ( 'notify::is-loaded' ,
Lang . bind ( this ,
this . _updateUser ) ) ;
this . _userChangedId = this . _user . connect ( 'changed' ,
Lang . bind ( this ,
this . _updateUser ) ) ;
2011-09-08 21:11:45 +00:00
this . actor . connect ( 'notify::mapped' , Lang . bind ( this , function ( ) {
if ( this . actor . mapped )
this . _updateUser ( ) ;
} ) ) ;
2012-09-01 12:42:53 +00:00
this . connect ( 'sensitive-changed' , function ( sensitive ) {
this . _avatar . setSensitive ( sensitive ) ;
} ) ;
2011-07-28 14:59:03 +00:00
} ,
2012-06-12 23:03:33 +00:00
_restorePresence : function ( ) {
let [ presence , status , msg ] = this . _accountMgr . get _most _available _presence ( ) ;
let savedPresence = global . settings . get _int ( 'saved-im-presence' ) ;
if ( savedPresence == presence ) {
this . _IMStatusChanged ( this . _accountMgr , presence , status , msg ) ;
} else {
this . _setComboboxPresence ( savedPresence ) ;
status = this . _statusForPresence ( savedPresence ) ;
msg = msg ? msg : '' ;
this . _accountMgr . set _all _requested _presences ( savedPresence , status , msg ) ;
}
} ,
2011-10-17 13:18:25 +00:00
destroy : function ( ) {
// clean up signal handlers
if ( this . _userLoadedId != 0 ) {
this . _user . disconnect ( this . _userLoadedId ) ;
this . _userLoadedId = 0 ;
}
if ( this . _userChangedId != 0 ) {
this . _user . disconnect ( this . _userChangedId ) ;
this . _userChangedId = 0 ;
}
2011-11-20 13:10:48 +00:00
this . parent ( ) ;
2011-10-17 13:18:25 +00:00
} ,
2011-07-28 14:59:03 +00:00
// Override getColumnWidths()/setColumnWidths() to make the item
// independent from the overall column layout of the menu
getColumnWidths : function ( ) {
return [ ] ;
} ,
setColumnWidths : function ( widths ) {
} ,
_updateUser : function ( ) {
2012-07-14 15:12:54 +00:00
if ( this . _user . is _loaded )
2011-07-28 14:59:03 +00:00
this . _name . label . set _text ( this . _user . get _real _name ( ) ) ;
else
2012-07-14 15:12:54 +00:00
this . _name . label . set _text ( "" ) ;
2011-07-28 14:59:03 +00:00
2012-07-14 15:12:54 +00:00
this . _avatar . update ( ) ;
2011-07-28 14:59:03 +00:00
} ,
_statusForPresence : function ( presence ) {
switch ( presence ) {
case Tp . ConnectionPresenceType . AVAILABLE :
2011-08-30 12:35:20 +00:00
return 'available' ;
2011-07-28 14:59:03 +00:00
case Tp . ConnectionPresenceType . BUSY :
2011-08-30 12:35:20 +00:00
return 'busy' ;
2011-07-28 14:59:03 +00:00
case Tp . ConnectionPresenceType . OFFLINE :
2011-08-30 12:35:20 +00:00
return 'offline' ;
2011-07-28 14:59:03 +00:00
case Tp . ConnectionPresenceType . HIDDEN :
2011-08-30 12:35:20 +00:00
return 'hidden' ;
2011-07-28 14:59:03 +00:00
case Tp . ConnectionPresenceType . AWAY :
2011-08-30 12:35:20 +00:00
return 'away' ;
2011-07-28 14:59:03 +00:00
case Tp . ConnectionPresenceType . EXTENDED _AWAY :
2011-08-30 12:35:20 +00:00
return 'xa' ;
2011-07-28 14:59:03 +00:00
default :
2011-08-30 12:35:20 +00:00
return 'unknown' ;
2011-07-28 14:59:03 +00:00
}
} ,
2011-10-26 19:16:08 +00:00
_IMAccountsChanged : function ( mgr ) {
let accounts = mgr . get _valid _accounts ( ) . filter ( function ( account ) {
return account . enabled ;
} ) ;
2012-06-12 22:44:29 +00:00
let sensitive = accounts . length > 0 && this . _networkMonitor . network _available ;
this . _combo . setSensitive ( sensitive ) ;
2011-10-26 19:16:08 +00:00
} ,
2011-07-28 14:59:03 +00:00
_IMStatusChanged : function ( accountMgr , presence , status , message ) {
2011-10-06 00:47:18 +00:00
if ( ! this . _imPresenceRestored )
this . _imPresenceRestored = true ;
2011-09-02 12:15:31 +00:00
if ( presence == this . _currentPresence )
return ;
this . _currentPresence = presence ;
2011-09-30 16:54:45 +00:00
this . _setComboboxPresence ( presence ) ;
2011-09-02 12:15:31 +00:00
2011-10-06 00:47:18 +00:00
if ( ! this . _sessionPresenceRestored ) {
2011-11-11 21:41:47 +00:00
this . _sessionStatusChanged ( this . _presence . status ) ;
2011-10-06 00:47:18 +00:00
return ;
}
2011-07-28 14:59:03 +00:00
if ( presence == Tp . ConnectionPresenceType . AVAILABLE )
2011-11-11 21:41:47 +00:00
this . _presence . status = GnomeSession . PresenceStatus . AVAILABLE ;
2011-07-28 14:59:03 +00:00
2011-10-11 19:53:29 +00:00
// We ignore the actual value of _expectedPresence and never safe
// the first presence change after an "automatic" change, assuming
// that it is the response to our request; this is to account for
// mission control falling back to "similar" presences if an account
// type does not implement the requested presence.
if ( ! this . _expectedPresence )
2011-09-30 16:54:45 +00:00
global . settings . set _int ( 'saved-im-presence' , presence ) ;
2011-07-28 14:59:03 +00:00
else
this . _expectedPresence = undefined ;
2011-09-30 16:54:45 +00:00
} ,
2011-07-28 14:59:03 +00:00
2011-09-30 16:54:45 +00:00
_setComboboxPresence : function ( presence ) {
2011-07-28 14:59:03 +00:00
let activatedItem ;
if ( presence == Tp . ConnectionPresenceType . AVAILABLE )
activatedItem = IMStatus . AVAILABLE ;
else if ( presence == Tp . ConnectionPresenceType . BUSY )
activatedItem = IMStatus . BUSY ;
else if ( presence == Tp . ConnectionPresenceType . HIDDEN )
activatedItem = IMStatus . HIDDEN ;
else if ( presence == Tp . ConnectionPresenceType . AWAY )
activatedItem = IMStatus . AWAY ;
else if ( presence == Tp . ConnectionPresenceType . EXTENDED _AWAY )
activatedItem = IMStatus . IDLE ;
else
activatedItem = IMStatus . OFFLINE ;
this . _combo . setActiveItem ( activatedItem ) ;
for ( let i = 0 ; i < IMStatus . LAST ; i ++ ) {
if ( i == IMStatus . AVAILABLE || i == IMStatus . OFFLINE )
continue ; // always visible
this . _combo . setItemVisible ( i , i == activatedItem ) ;
}
} ,
_changeIMStatus : function ( menuItem , id ) {
let [ presence , s , msg ] = this . _accountMgr . get _most _available _presence ( ) ;
let newPresence , status ;
if ( id == IMStatus . AVAILABLE ) {
newPresence = Tp . ConnectionPresenceType . AVAILABLE ;
} else if ( id == IMStatus . OFFLINE ) {
newPresence = Tp . ConnectionPresenceType . OFFLINE ;
} else
return ;
status = this . _statusForPresence ( newPresence ) ;
2011-09-30 21:30:47 +00:00
msg = msg ? msg : '' ;
2011-07-28 14:59:03 +00:00
this . _accountMgr . set _all _requested _presences ( newPresence , status , msg ) ;
} ,
2011-09-09 16:49:04 +00:00
getIMPresenceForSessionStatus : function ( sessionStatus ) {
2011-09-30 16:54:45 +00:00
// Restore the last user-set presence when coming back from
// BUSY/IDLE (otherwise the last user-set presence matches
// the current one)
2011-09-09 16:49:04 +00:00
if ( sessionStatus == GnomeSession . PresenceStatus . AVAILABLE )
2011-09-30 16:54:45 +00:00
return global . settings . get _int ( 'saved-im-presence' ) ;
2011-07-28 14:59:03 +00:00
2011-09-09 16:49:04 +00:00
if ( sessionStatus == GnomeSession . PresenceStatus . BUSY ) {
2011-07-28 14:59:03 +00:00
// Only change presence if the current one is "more present" than
// busy, or if coming back from idle
2011-09-09 16:49:04 +00:00
if ( this . _currentPresence == Tp . ConnectionPresenceType . AVAILABLE ||
this . _currentPresence == Tp . ConnectionPresenceType . EXTENDED _AWAY )
return Tp . ConnectionPresenceType . BUSY ;
}
if ( sessionStatus == GnomeSession . PresenceStatus . IDLE ) {
2011-07-28 14:59:03 +00:00
// Only change presence if the current one is "more present" than
// idle
2011-10-19 13:15:14 +00:00
if ( this . _currentPresence != Tp . ConnectionPresenceType . OFFLINE &&
this . _currentPresence != Tp . ConnectionPresenceType . HIDDEN )
2011-09-09 16:49:04 +00:00
return Tp . ConnectionPresenceType . EXTENDED _AWAY ;
2011-07-28 14:59:03 +00:00
}
2011-09-09 16:49:04 +00:00
return this . _currentPresence ;
} ,
2011-08-16 12:24:39 +00:00
_sessionStatusChanged : function ( sessionStatus ) {
2011-10-06 00:47:18 +00:00
if ( ! this . _imPresenceRestored )
return ;
2012-01-19 18:04:56 +00:00
let savedStatus = global . settings . get _int ( 'saved-session-presence' ) ;
2011-10-06 00:47:18 +00:00
if ( ! this . _sessionPresenceRestored ) {
2012-03-03 07:35:03 +00:00
// We should never save/restore a status other than AVAILABLE
// or BUSY
if ( savedStatus != GnomeSession . PresenceStatus . AVAILABLE &&
savedStatus != GnomeSession . PresenceStatus . BUSY )
savedStatus = GnomeSession . PresenceStatus . AVAILABLE ;
2011-10-06 00:47:18 +00:00
if ( sessionStatus != savedStatus ) {
2011-08-16 12:24:39 +00:00
this . _presence . status = savedStatus ;
2011-10-06 00:47:18 +00:00
return ;
}
this . _sessionPresenceRestored = true ;
}
2012-01-19 18:04:56 +00:00
if ( ( sessionStatus == GnomeSession . PresenceStatus . AVAILABLE ||
sessionStatus == GnomeSession . PresenceStatus . BUSY ) &&
savedStatus != sessionStatus )
2012-03-03 07:35:03 +00:00
global . settings . set _int ( 'saved-session-presence' , sessionStatus ) ;
2011-10-06 00:47:18 +00:00
2011-09-09 16:49:04 +00:00
let [ presence , s , msg ] = this . _accountMgr . get _most _available _presence ( ) ;
let newPresence , status ;
let newPresence = this . getIMPresenceForSessionStatus ( sessionStatus ) ;
if ( ! newPresence || newPresence == presence )
2011-07-28 14:59:03 +00:00
return ;
status = this . _statusForPresence ( newPresence ) ;
2011-09-30 21:30:47 +00:00
msg = msg ? msg : '' ;
2011-07-28 14:59:03 +00:00
this . _expectedPresence = newPresence ;
this . _accountMgr . set _all _requested _presences ( newPresence , status , msg ) ;
}
2011-11-20 13:10:48 +00:00
} ) ;
2011-07-28 14:59:03 +00:00
2011-11-20 14:38:48 +00:00
const UserMenuButton = new Lang . Class ( {
Name : 'UserMenuButton' ,
Extends : PanelMenu . Button ,
2010-05-10 13:46:54 +00:00
2009-11-10 17:13:58 +00:00
_init : function ( ) {
2011-11-20 14:38:48 +00:00
this . parent ( 0.0 ) ;
2012-02-27 16:31:10 +00:00
this . actor . accessible _role = Atk . Role . MENU ;
2011-09-07 16:23:27 +00:00
let box = new St . BoxLayout ( { name : 'panelUserMenu' } ) ;
2011-06-09 15:50:24 +00:00
this . actor . add _actor ( box ) ;
2010-05-10 13:46:54 +00:00
2012-08-13 23:51:51 +00:00
this . _screenSaverSettings = new Gio . Settings ( { schema : SCREENSAVER _SCHEMA } ) ;
2011-03-21 12:51:46 +00:00
this . _lockdownSettings = new Gio . Settings ( { schema : LOCKDOWN _SCHEMA } ) ;
2013-01-15 08:30:43 +00:00
this . _privacySettings = new Gio . Settings ( { schema : PRIVACY _SCHEMA } ) ;
2011-03-21 12:51:46 +00:00
2011-05-10 14:13:05 +00:00
this . _userManager = AccountsService . UserManager . get _default ( ) ;
2010-10-07 22:22:20 +00:00
2011-05-10 14:13:05 +00:00
this . _user = this . _userManager . get _user ( GLib . get _user _name ( ) ) ;
2010-04-29 17:13:20 +00:00
this . _presence = new GnomeSession . Presence ( ) ;
2011-03-12 20:34:01 +00:00
this . _session = new GnomeSession . SessionManager ( ) ;
2011-06-03 22:10:55 +00:00
this . _haveShutdown = true ;
2012-10-19 15:41:10 +00:00
this . _haveSuspend = true ;
2009-11-10 17:13:58 +00:00
2011-10-20 20:54:41 +00:00
this . _accountMgr = Tp . AccountManager . dup ( ) ;
2011-02-28 16:03:35 +00:00
2012-10-19 15:41:10 +00:00
this . _loginManager = LoginManager . getLoginManager ( ) ;
2009-11-10 17:13:58 +00:00
this . actor . connect ( 'destroy' , Lang . bind ( this , this . _onDestroy ) ) ;
2009-11-10 21:34:13 +00:00
this . _iconBox = new St . Bin ( ) ;
2010-05-10 13:46:54 +00:00
box . add ( this . _iconBox , { y _align : St . Align . MIDDLE , y _fill : false } ) ;
2009-11-10 21:34:13 +00:00
2010-02-09 17:42:07 +00:00
let textureCache = St . TextureCache . get _default ( ) ;
2012-05-30 13:58:37 +00:00
this . _offlineIcon = new St . Icon ( { icon _name : 'user-offline-symbolic' ,
2011-07-28 14:59:03 +00:00
style _class : 'popup-menu-icon' } ) ;
2012-05-30 13:58:37 +00:00
this . _availableIcon = new St . Icon ( { icon _name : 'user-available-symbolic' ,
2011-07-28 14:59:03 +00:00
style _class : 'popup-menu-icon' } ) ;
2012-05-30 13:58:37 +00:00
this . _busyIcon = new St . Icon ( { icon _name : 'user-busy-symbolic' ,
2011-07-28 14:59:03 +00:00
style _class : 'popup-menu-icon' } ) ;
2012-05-30 13:58:37 +00:00
this . _invisibleIcon = new St . Icon ( { icon _name : 'user-invisible-symbolic' ,
2011-07-28 14:59:03 +00:00
style _class : 'popup-menu-icon' } ) ;
2012-05-30 13:58:37 +00:00
this . _awayIcon = new St . Icon ( { icon _name : 'user-away-symbolic' ,
2011-07-28 14:59:03 +00:00
style _class : 'popup-menu-icon' } ) ;
2012-05-30 13:58:37 +00:00
this . _idleIcon = new St . Icon ( { icon _name : 'user-idle-symbolic' ,
2011-07-28 14:59:03 +00:00
style _class : 'popup-menu-icon' } ) ;
2012-08-30 11:23:00 +00:00
this . _pendingIcon = new St . Icon ( { icon _name : 'user-status-pending-symbolic' ,
2011-09-14 13:06:48 +00:00
style _class : 'popup-menu-icon' } ) ;
2012-09-01 21:44:46 +00:00
this . _lockedIcon = new St . Icon ( { icon _name : 'changes-prevent-symbolic' ,
style _class : 'popup-menu-icon' } ) ;
2011-07-28 14:59:03 +00:00
2011-10-20 20:44:09 +00:00
this . _accountMgr . connect ( 'most-available-presence-changed' ,
2011-07-28 14:59:03 +00:00
Lang . bind ( this , this . _updatePresenceIcon ) ) ;
2011-09-14 13:06:48 +00:00
this . _accountMgr . connect ( 'account-enabled' ,
Lang . bind ( this , this . _onAccountEnabled ) ) ;
this . _accountMgr . connect ( 'account-removed' ,
2012-07-03 08:34:34 +00:00
Lang . bind ( this , this . _onAccountRemoved ) ) ;
2011-10-20 20:44:09 +00:00
this . _accountMgr . prepare _async ( null , Lang . bind ( this ,
2011-07-28 14:59:03 +00:00
function ( mgr ) {
let [ presence , s , msg ] = mgr . get _most _available _presence ( ) ;
this . _updatePresenceIcon ( mgr , presence , s , msg ) ;
2011-09-14 13:06:48 +00:00
this . _setupAccounts ( ) ;
2011-07-28 14:59:03 +00:00
} ) ) ;
2009-11-10 21:34:13 +00:00
2010-10-07 22:22:20 +00:00
this . _name = new St . Label ( ) ;
2012-01-05 18:00:06 +00:00
this . actor . label _actor = this . _name ;
2010-05-10 13:46:54 +00:00
box . add ( this . _name , { y _align : St . Align . MIDDLE , y _fill : false } ) ;
2010-10-07 22:22:20 +00:00
this . _userLoadedId = this . _user . connect ( 'notify::is-loaded' , Lang . bind ( this , this . _updateUserName ) ) ;
this . _userChangedId = this . _user . connect ( 'changed' , Lang . bind ( this , this . _updateUserName ) ) ;
2011-09-08 21:11:45 +00:00
this . _updateUserName ( ) ;
2009-11-10 17:13:58 +00:00
this . _createSubMenu ( ) ;
2011-11-11 21:41:47 +00:00
this . _updateSwitch ( this . _presence . status ) ;
this . _presence . connectSignal ( 'StatusChanged' , Lang . bind ( this , function ( proxy , senderName , [ status ] ) {
this . _updateSwitch ( status ) ;
} ) ) ;
2011-05-10 14:13:05 +00:00
this . _userManager . connect ( 'notify::is-loaded' ,
2012-05-10 11:16:15 +00:00
Lang . bind ( this , this . _updateMultiUser ) ) ;
2011-10-18 18:57:24 +00:00
this . _userManager . connect ( 'notify::has-multiple-users' ,
2012-05-10 11:16:15 +00:00
Lang . bind ( this , this . _updateMultiUser ) ) ;
2011-05-10 14:13:05 +00:00
this . _userManager . connect ( 'user-added' ,
2012-05-10 11:16:15 +00:00
Lang . bind ( this , this . _updateMultiUser ) ) ;
2011-05-10 14:13:05 +00:00
this . _userManager . connect ( 'user-removed' ,
2012-05-10 11:16:15 +00:00
Lang . bind ( this , this . _updateMultiUser ) ) ;
2011-03-21 12:51:46 +00:00
this . _lockdownSettings . connect ( 'changed::' + DISABLE _USER _SWITCH _KEY ,
Lang . bind ( this , this . _updateSwitchUser ) ) ;
this . _lockdownSettings . connect ( 'changed::' + DISABLE _LOG _OUT _KEY ,
Lang . bind ( this , this . _updateLogout ) ) ;
this . _lockdownSettings . connect ( 'changed::' + DISABLE _LOCK _SCREEN _KEY ,
Lang . bind ( this , this . _updateLockScreen ) ) ;
2013-01-30 14:19:54 +00:00
global . settings . connect ( 'changed::' + ALWAYS _SHOW _LOG _OUT _KEY ,
Lang . bind ( this , this . _updateLogout ) ) ;
2013-01-15 08:30:43 +00:00
this . _screenSaverSettings . connect ( 'changed::' + SHOW _FULL _NAME _IN _TOP _BAR _KEY ,
2012-11-18 04:51:06 +00:00
Lang . bind ( this , this . _updateUserName ) ) ;
2013-01-15 08:30:43 +00:00
this . _privacySettings . connect ( 'changed::' + SHOW _FULL _NAME _IN _TOP _BAR _KEY ,
Lang . bind ( this , this . _updateUserName ) ) ;
2011-03-21 12:51:46 +00:00
this . _updateSwitchUser ( ) ;
this . _updateLogout ( ) ;
this . _updateLockScreen ( ) ;
2011-02-04 23:37:54 +00:00
2012-06-03 15:35:37 +00:00
this . _updatesFile = Gio . File . new _for _path ( '/var/lib/PackageKit/prepared-update' ) ;
this . _updatesMonitor = this . _updatesFile . monitor ( Gio . FileMonitorFlags . NONE , null ) ;
this . _updatesMonitor . connect ( 'changed' , Lang . bind ( this , this . _updateInstallUpdates ) ) ;
2011-06-03 22:10:55 +00:00
// Whether shutdown is available or not depends on both lockdown
// settings (disable-log-out) and Polkit policy - the latter doesn't
// notify, so we update the menu item each time the menu opens or
// the lockdown setting changes, which should be close enough.
this . menu . connect ( 'open-state-changed' , Lang . bind ( this ,
function ( menu , open ) {
2012-10-19 15:41:10 +00:00
if ( ! open )
return ;
this . _updateHaveShutdown ( ) ;
this . _updateHaveSuspend ( ) ;
2011-06-03 22:10:55 +00:00
} ) ) ;
this . _lockdownSettings . connect ( 'changed::' + DISABLE _LOG _OUT _KEY ,
Lang . bind ( this , this . _updateHaveShutdown ) ) ;
2012-09-01 12:42:53 +00:00
Main . sessionMode . connect ( 'updated' , Lang . bind ( this , this . _sessionUpdated ) ) ;
2013-03-04 18:33:36 +00:00
if ( Main . screenShield )
Main . screenShield . connect ( 'locked-changed' , Lang . bind ( this , this . _updatePresenceIcon ) ) ;
2012-09-01 12:42:53 +00:00
this . _sessionUpdated ( ) ;
2009-11-10 17:13:58 +00:00
} ,
2012-09-01 12:42:53 +00:00
_sessionUpdated : function ( ) {
2012-09-10 09:34:49 +00:00
this . actor . visible = ! Main . sessionMode . isGreeter ;
2012-09-01 12:42:53 +00:00
let allowSettings = Main . sessionMode . allowSettings ;
this . _statusChooser . setSensitive ( allowSettings ) ;
this . _systemSettings . visible = allowSettings ;
2012-09-01 21:44:46 +00:00
this . setSensitive ( ! Main . sessionMode . isLocked ) ;
this . _updatePresenceIcon ( ) ;
2012-12-11 16:09:34 +00:00
this . _updateUserName ( ) ;
2012-05-22 22:27:06 +00:00
} ,
2009-11-10 17:13:58 +00:00
_onDestroy : function ( ) {
2010-10-07 22:22:20 +00:00
this . _user . disconnect ( this . _userLoadedId ) ;
this . _user . disconnect ( this . _userChangedId ) ;
2009-11-10 17:13:58 +00:00
} ,
_updateUserName : function ( ) {
2013-01-15 08:30:43 +00:00
let settings = this . _privacySettings ;
2012-11-18 04:51:06 +00:00
if ( Main . sessionMode . isLocked )
settings = this . _screenSaverSettings ;
2013-01-15 08:30:43 +00:00
if ( this . _user . is _loaded && settings . get _boolean ( SHOW _FULL _NAME _IN _TOP _BAR _KEY ) )
2011-07-28 14:59:03 +00:00
this . _name . set _text ( this . _user . get _real _name ( ) ) ;
2010-10-07 22:22:20 +00:00
else
2011-07-28 14:59:03 +00:00
this . _name . set _text ( "" ) ;
2009-11-10 17:13:58 +00:00
} ,
2012-05-10 11:16:15 +00:00
_updateMultiUser : function ( ) {
this . _updateSwitchUser ( ) ;
this . _updateLogout ( ) ;
} ,
2009-11-10 17:13:58 +00:00
_updateSwitchUser : function ( ) {
2011-03-21 12:51:46 +00:00
let allowSwitch = ! this . _lockdownSettings . get _boolean ( DISABLE _USER _SWITCH _KEY ) ;
2012-05-13 15:11:06 +00:00
let multiUser = this . _userManager . can _switch ( ) && this . _userManager . has _multiple _users ;
2012-09-28 16:52:12 +00:00
this . _loginScreenItem . actor . visible = allowSwitch && multiUser ;
2011-03-21 12:51:46 +00:00
} ,
_updateLogout : function ( ) {
let allowLogout = ! this . _lockdownSettings . get _boolean ( DISABLE _LOG _OUT _KEY ) ;
2012-10-29 04:27:18 +00:00
let alwaysShow = global . settings . get _boolean ( ALWAYS _SHOW _LOG _OUT _KEY ) ;
2012-10-29 03:55:43 +00:00
let systemAccount = this . _user . system _account ;
let localAccount = this . _user . local _account ;
2012-05-13 15:11:06 +00:00
let multiUser = this . _userManager . has _multiple _users ;
2012-05-19 23:19:25 +00:00
let multiSession = Gdm . get _session _ids ( ) . length > 1 ;
2012-05-13 15:11:06 +00:00
2012-10-29 04:27:18 +00:00
this . _logoutItem . actor . visible = allowLogout && ( alwaysShow || multiUser || multiSession || systemAccount || ! localAccount ) ;
2011-03-21 12:51:46 +00:00
} ,
_updateLockScreen : function ( ) {
let allowLockScreen = ! this . _lockdownSettings . get _boolean ( DISABLE _LOCK _SCREEN _KEY ) ;
2013-03-04 18:33:36 +00:00
this . _lockScreenItem . actor . visible = allowLockScreen && LoginManager . canLock ( ) ;
2009-11-10 17:13:58 +00:00
} ,
2012-06-03 15:35:37 +00:00
_updateInstallUpdates : function ( ) {
let haveUpdates = this . _updatesFile . query _exists ( null ) ;
this . _installUpdatesItem . actor . visible = haveUpdates && this . _haveShutdown ;
} ,
2011-06-03 22:10:55 +00:00
_updateHaveShutdown : function ( ) {
this . _session . CanShutdownRemote ( Lang . bind ( this ,
function ( result , error ) {
if ( ! error ) {
2012-06-26 15:44:24 +00:00
this . _haveShutdown = result [ 0 ] ;
2012-06-03 15:35:37 +00:00
this . _updateInstallUpdates ( ) ;
2011-06-03 22:10:55 +00:00
this . _updateSuspendOrPowerOff ( ) ;
}
} ) ) ;
} ,
2012-10-19 15:41:10 +00:00
_updateHaveSuspend : function ( ) {
this . _loginManager . canSuspend ( Lang . bind ( this ,
function ( result ) {
this . _haveSuspend = result ;
this . _updateSuspendOrPowerOff ( ) ;
} ) ) ;
} ,
2011-02-04 23:37:54 +00:00
2012-10-19 15:41:10 +00:00
_updateSuspendOrPowerOff : function ( ) {
2011-02-04 23:37:54 +00:00
if ( ! this . _suspendOrPowerOffItem )
return ;
2012-03-16 22:53:14 +00:00
this . _suspendOrPowerOffItem . actor . visible = this . _haveShutdown || this . _haveSuspend ;
2011-06-03 22:10:55 +00:00
2012-05-10 11:24:12 +00:00
// If we can't power off show Suspend instead
2011-02-04 23:37:54 +00:00
// and disable the alt key
2012-05-10 11:24:12 +00:00
if ( ! this . _haveShutdown ) {
2011-06-03 22:10:55 +00:00
this . _suspendOrPowerOffItem . updateText ( _ ( "Suspend" ) , null ) ;
2012-05-10 11:24:12 +00:00
} else if ( ! this . _haveSuspend ) {
this . _suspendOrPowerOffItem . updateText ( _ ( "Power Off" ) , null ) ;
2011-02-04 23:37:54 +00:00
} else {
2012-05-10 11:24:12 +00:00
this . _suspendOrPowerOffItem . updateText ( _ ( "Power Off" ) , _ ( "Suspend" ) ) ;
2011-02-04 23:37:54 +00:00
}
} ,
2011-08-16 12:24:39 +00:00
_updateSwitch : function ( status ) {
2011-09-04 16:39:37 +00:00
let active = status == GnomeSession . PresenceStatus . AVAILABLE ;
this . _notificationsSwitch . setToggleState ( active ) ;
2011-07-28 14:59:03 +00:00
} ,
_updatePresenceIcon : function ( accountMgr , presence , status , message ) {
2012-09-01 21:44:46 +00:00
if ( Main . sessionMode . isLocked )
this . _iconBox . child = this . _lockedIcon ;
else if ( presence == Tp . ConnectionPresenceType . AVAILABLE )
2009-11-10 21:34:13 +00:00
this . _iconBox . child = this . _availableIcon ;
2011-07-28 14:59:03 +00:00
else if ( presence == Tp . ConnectionPresenceType . BUSY )
2009-11-10 21:34:13 +00:00
this . _iconBox . child = this . _busyIcon ;
2011-07-28 14:59:03 +00:00
else if ( presence == Tp . ConnectionPresenceType . HIDDEN )
2009-11-10 21:34:13 +00:00
this . _iconBox . child = this . _invisibleIcon ;
2011-07-28 14:59:03 +00:00
else if ( presence == Tp . ConnectionPresenceType . AWAY )
this . _iconBox . child = this . _awayIcon ;
else if ( presence == Tp . ConnectionPresenceType . EXTENDED _AWAY )
2009-11-10 21:34:13 +00:00
this . _iconBox . child = this . _idleIcon ;
2011-07-28 14:59:03 +00:00
else
this . _iconBox . child = this . _offlineIcon ;
2013-02-02 16:30:06 +00:00
if ( Main . sessionMode . isLocked )
this . _iconBox . visible = Main . screenShield . locked ;
else
this . _iconBox . visible = true ;
2009-11-10 21:34:13 +00:00
} ,
2011-09-14 13:06:48 +00:00
_setupAccounts : function ( ) {
let accounts = this . _accountMgr . get _valid _accounts ( ) ;
for ( let i = 0 ; i < accounts . length ; i ++ ) {
accounts [ i ] . _changingId = accounts [ i ] . connect ( 'notify::connection-status' ,
Lang . bind ( this , this . _updateChangingPresence ) ) ;
}
this . _updateChangingPresence ( ) ;
} ,
_onAccountEnabled : function ( accountMgr , account ) {
if ( ! account . _changingId )
account . _changingId = account . connect ( 'notify::connection-status' ,
Lang . bind ( this , this . _updateChangingPresence ) ) ;
this . _updateChangingPresence ( ) ;
} ,
2012-07-03 08:34:34 +00:00
_onAccountRemoved : function ( accountMgr , account ) {
2012-08-07 14:33:02 +00:00
if ( account . _changingId ) {
account . disconnect ( account . _changingId ) ;
account . _changingId = 0 ;
}
2011-09-14 13:06:48 +00:00
this . _updateChangingPresence ( ) ;
} ,
_updateChangingPresence : function ( ) {
let accounts = this . _accountMgr . get _valid _accounts ( ) ;
let changing = false ;
for ( let i = 0 ; i < accounts . length ; i ++ ) {
if ( accounts [ i ] . connection _status == Tp . ConnectionStatus . CONNECTING ) {
changing = true ;
break ;
}
}
if ( changing ) {
this . _iconBox . child = this . _pendingIcon ;
} else {
let [ presence , s , msg ] = this . _accountMgr . get _most _available _presence ( ) ;
this . _updatePresenceIcon ( this . _accountMgr , presence , s , msg ) ;
}
} ,
2009-11-10 17:13:58 +00:00
_createSubMenu : function ( ) {
let item ;
2011-07-28 14:59:03 +00:00
item = new IMStatusChooserItem ( ) ;
2012-09-01 12:42:53 +00:00
item . connect ( 'activate' , Lang . bind ( this , this . _onMyAccountActivate ) ) ;
2010-05-10 13:46:54 +00:00
this . menu . addMenuItem ( item ) ;
2011-09-09 16:49:04 +00:00
this . _statusChooser = item ;
2009-11-10 21:34:13 +00:00
2011-09-04 16:39:37 +00:00
item = new PopupMenu . PopupSwitchMenuItem ( _ ( "Notifications" ) ) ;
2011-11-21 13:16:51 +00:00
item . connect ( 'toggled' , Lang . bind ( this , this . _updatePresenceStatus ) ) ;
2010-05-10 13:46:54 +00:00
this . menu . addMenuItem ( item ) ;
2011-09-04 16:39:37 +00:00
this . _notificationsSwitch = item ;
2009-11-10 21:34:13 +00:00
2010-05-20 15:18:46 +00:00
item = new PopupMenu . PopupSeparatorMenuItem ( ) ;
2010-05-10 13:46:54 +00:00
this . menu . addMenuItem ( item ) ;
2009-11-10 21:34:13 +00:00
2012-11-07 13:58:33 +00:00
item = new PopupMenu . PopupMenuItem ( _ ( "Settings" ) ) ;
2012-09-01 12:42:53 +00:00
item . connect ( 'activate' , Lang . bind ( this , this . _onPreferencesActivate ) ) ;
this . menu . addMenuItem ( item ) ;
this . _systemSettings = item ;
2009-11-10 17:13:58 +00:00
2012-05-10 11:24:12 +00:00
item = new PopupMenu . PopupSeparatorMenuItem ( ) ;
2010-05-10 13:46:54 +00:00
this . menu . addMenuItem ( item ) ;
2009-11-10 17:13:58 +00:00
2010-10-19 15:59:23 +00:00
item = new PopupMenu . PopupMenuItem ( _ ( "Switch User" ) ) ;
2009-11-10 17:13:58 +00:00
item . connect ( 'activate' , Lang . bind ( this , this . _onLoginScreenActivate ) ) ;
2010-05-10 13:46:54 +00:00
this . menu . addMenuItem ( item ) ;
2009-11-10 17:13:58 +00:00
this . _loginScreenItem = item ;
2012-05-10 11:24:12 +00:00
item = new PopupMenu . PopupMenuItem ( _ ( "Log Out" ) ) ;
2009-11-10 17:13:58 +00:00
item . connect ( 'activate' , Lang . bind ( this , this . _onQuitSessionActivate ) ) ;
2010-05-10 13:46:54 +00:00
this . menu . addMenuItem ( item ) ;
2011-03-21 12:51:46 +00:00
this . _logoutItem = item ;
2009-11-10 17:13:58 +00:00
2012-05-10 11:24:12 +00:00
item = new PopupMenu . PopupMenuItem ( _ ( "Lock" ) ) ;
item . connect ( 'activate' , Lang . bind ( this , this . _onLockScreenActivate ) ) ;
2010-05-10 13:46:54 +00:00
this . menu . addMenuItem ( item ) ;
2012-05-10 11:24:12 +00:00
this . _lockScreenItem = item ;
2012-06-28 10:22:17 +00:00
item = new PopupMenu . PopupSeparatorMenuItem ( ) ;
this . menu . addMenuItem ( item ) ;
item = new PopupMenu . PopupAlternatingMenuItem ( _ ( "Power Off" ) ,
_ ( "Suspend" ) ) ;
this . menu . addMenuItem ( item ) ;
item . connect ( 'activate' , Lang . bind ( this , this . _onSuspendOrPowerOffActivate ) ) ;
this . _suspendOrPowerOffItem = item ;
this . _updateSuspendOrPowerOff ( ) ;
2012-07-17 10:20:56 +00:00
item = new PopupMenu . PopupMenuItem ( _ ( "Install Updates & Restart" ) ) ;
item . connect ( 'activate' , Lang . bind ( this , this . _onInstallUpdatesActivate ) ) ;
this . menu . addMenuItem ( item ) ;
this . _installUpdatesItem = item ;
2009-11-10 17:13:58 +00:00
} ,
2011-07-28 14:59:03 +00:00
_updatePresenceStatus : function ( item , event ) {
2011-09-09 16:49:04 +00:00
let status ;
if ( item . state ) {
status = GnomeSession . PresenceStatus . AVAILABLE ;
} else {
status = GnomeSession . PresenceStatus . BUSY ;
2011-10-20 20:44:09 +00:00
let [ presence , s , msg ] = this . _accountMgr . get _most _available _presence ( ) ;
2011-09-09 16:49:04 +00:00
let newPresence = this . _statusChooser . getIMPresenceForSessionStatus ( status ) ;
if ( newPresence != presence &&
newPresence == Tp . ConnectionPresenceType . BUSY )
Main . notify ( _ ( "Your chat status will be set to busy" ) ,
_ ( "Notifications are now disabled, including chat messages. Your online status has been adjusted to let others know that you might not see their messages." ) ) ;
}
2011-11-11 21:41:47 +00:00
this . _presence . status = status ;
2009-11-10 21:34:13 +00:00
} ,
2010-10-19 16:04:58 +00:00
_onMyAccountActivate : function ( ) {
2010-06-03 23:21:08 +00:00
Main . overview . hide ( ) ;
2013-01-24 19:32:27 +00:00
let app = Shell . AppSystem . get _default ( ) . lookup _app ( 'gnome-user-accounts-panel.desktop' ) ;
2011-08-11 09:35:23 +00:00
app . activate ( ) ;
2009-11-10 17:13:58 +00:00
} ,
_onPreferencesActivate : function ( ) {
2010-06-03 23:21:08 +00:00
Main . overview . hide ( ) ;
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
let app = Shell . AppSystem . get _default ( ) . lookup _app ( 'gnome-control-center.desktop' ) ;
2011-08-11 09:35:23 +00:00
app . activate ( ) ;
2009-11-10 17:13:58 +00:00
} ,
_onLockScreenActivate : function ( ) {
2012-09-19 03:02:15 +00:00
this . menu . close ( BoxPointer . PopupAnimation . NONE ) ;
2010-06-03 23:21:08 +00:00
Main . overview . hide ( ) ;
2012-06-02 22:10:23 +00:00
Main . screenShield . lock ( true ) ;
2009-11-10 17:13:58 +00:00
} ,
_onLoginScreenActivate : function ( ) {
2012-09-20 21:18:51 +00:00
this . menu . close ( BoxPointer . PopupAnimation . NONE ) ;
2010-06-03 23:21:08 +00:00
Main . overview . hide ( ) ;
2013-03-04 18:33:36 +00:00
if ( Main . screenShield )
Main . screenShield . lock ( false ) ;
2012-08-14 15:49:46 +00:00
Gdm . goto _login _session _sync ( null ) ;
2009-11-10 17:13:58 +00:00
} ,
_onQuitSessionActivate : function ( ) {
2010-06-03 23:21:08 +00:00
Main . overview . hide ( ) ;
2011-03-12 20:34:01 +00:00
this . _session . LogoutRemote ( 0 ) ;
2009-11-10 17:13:58 +00:00
} ,
2012-06-03 15:35:37 +00:00
_onInstallUpdatesActivate : function ( ) {
Main . overview . hide ( ) ;
Util . spawn ( [ 'pkexec' , '/usr/libexec/pk-trigger-offline-update' ] ) ;
this . _session . RebootRemote ( ) ;
} ,
2013-02-11 16:39:29 +00:00
_openSessionWarnDialog : function ( sessions ) {
let dialog = new ModalDialog . ModalDialog ( ) ;
let subjectLabel = new St . Label ( { style _class : 'end-session-dialog-subject' ,
text : _ ( "Other users are logged in." ) } ) ;
dialog . contentLayout . add ( subjectLabel , { y _fill : true ,
y _align : St . Align . START } ) ;
let descriptionLabel = new St . Label ( { style _class : 'end-session-dialog-description' } ) ;
descriptionLabel . set _text ( _ ( "Shutting down might cause them to lose unsaved work." ) ) ;
2013-03-02 15:55:13 +00:00
descriptionLabel . clutter _text . line _wrap = true ;
2013-02-11 16:39:29 +00:00
dialog . contentLayout . add ( descriptionLabel , { x _fill : true ,
y _fill : true ,
y _align : St . Align . START } ) ;
let scrollView = new St . ScrollView ( { style _class : 'end-session-dialog-app-list' } ) ;
scrollView . add _style _class _name ( 'vfade' ) ;
scrollView . set _policy ( Gtk . PolicyType . NEVER , Gtk . PolicyType . AUTOMATIC ) ;
dialog . contentLayout . add ( scrollView , { x _fill : true , y _fill : true } ) ;
let userList = new St . BoxLayout ( { vertical : true } ) ;
scrollView . add _actor ( userList ) ;
for ( let i = 0 ; i < sessions . length ; i ++ ) {
let session = sessions [ i ] ;
let userEntry = new St . BoxLayout ( { style _class : 'login-dialog-user-list-item' ,
vertical : false } ) ;
let avatar = new UserAvatarWidget ( session . user ) ;
avatar . update ( ) ;
userEntry . add ( avatar . actor ) ;
let userLabelText = "" ; ;
let userName = session . user . get _real _name ( ) ?
session . user . get _real _name ( ) : session . username ;
if ( session . info . remote )
userLabelText = _ ( "%s (remote)" ) . format ( userName ) ;
else if ( session . info . type == "tty" )
userLabelText = _ ( "%s (console)" ) . format ( userName ) ;
else
userLabelText = userName ;
let textLayout = new St . BoxLayout ( { style _class : 'login-dialog-user-list-item-text-box' ,
vertical : true } ) ;
textLayout . add ( new St . Label ( { text : userLabelText } ) ,
{ y _fill : false ,
y _align : St . Align . MIDDLE ,
expand : true } ) ;
userEntry . add ( textLayout , { expand : true } ) ;
userList . add ( userEntry , { x _fill : true } ) ;
}
let cancelButton = { label : _ ( "Cancel" ) ,
action : function ( ) { dialog . close ( ) ; } ,
key : Clutter . Escape } ;
let powerOffButton = { label : _ ( "Power Off" ) , action : Lang . bind ( this , function ( ) {
dialog . close ( ) ;
this . _session . ShutdownRemote ( ) ;
} ) , default : true } ;
dialog . setButtons ( [ cancelButton , powerOffButton ] ) ;
dialog . open ( ) ;
} ,
2011-02-04 23:37:54 +00:00
_onSuspendOrPowerOffActivate : function ( ) {
2010-06-03 23:21:08 +00:00
Main . overview . hide ( ) ;
2011-02-04 23:37:54 +00:00
2012-05-10 11:24:12 +00:00
if ( this . _haveShutdown &&
2011-02-04 23:37:54 +00:00
this . _suspendOrPowerOffItem . state == PopupMenu . PopupAlternatingMenuItemState . DEFAULT ) {
2013-02-11 16:39:29 +00:00
this . _loginManager . listSessions ( Lang . bind ( this ,
function ( result ) {
let sessions = [ ] ;
let n = 0 ;
for ( let i = 0 ; i < result . length ; i ++ ) {
let [ id , uid , userName , seat , sessionPath ] = result [ i ] ;
let proxy = new SystemdLoginSession ( Gio . DBus . system ,
'org.freedesktop.login1' ,
sessionPath ) ;
2013-02-19 07:44:01 +00:00
if ( proxy . Class != 'user' )
2013-02-11 16:39:29 +00:00
continue ;
2013-03-02 15:53:50 +00:00
if ( proxy . State == 'closing' )
continue ;
2013-02-18 17:03:13 +00:00
if ( proxy . Id == GLib . getenv ( 'XDG_SESSION_ID' ) )
2013-02-11 16:39:29 +00:00
continue ;
sessions . push ( { user : this . _userManager . get _user ( userName ) ,
username : userName ,
2013-02-19 07:44:01 +00:00
info : { type : proxy . Type ,
remote : proxy . Remote }
2013-02-11 16:39:29 +00:00
} ) ;
// limit the number of entries
n ++ ;
if ( n == MAX _USERS _IN _SESSION _DIALOG )
break ;
}
if ( n != 0 )
this . _openSessionWarnDialog ( sessions ) ;
else
this . _session . ShutdownRemote ( ) ;
} ) ) ;
2012-05-10 11:24:12 +00:00
} else {
2012-10-23 13:49:25 +00:00
this . menu . close ( BoxPointer . PopupAnimation . NONE ) ;
this . _loginManager . suspend ( ) ;
2011-02-04 23:37:54 +00:00
}
2009-11-10 17:13:58 +00:00
}
2011-11-20 14:38:48 +00:00
} ) ;