From d802416daeb2f9bfd25132e6465ccf022074c5b9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 23 Apr 2013 17:33:54 -0400 Subject: [PATCH] userMenu: Implement new user menu design For now, turn it into another system status button with a simple icon. We'll revamp this when we revamp how panel menus work in general. https://bugzilla.gnome.org/show_bug.cgi?id=704368 --- data/theme/gnome-shell.css | 36 --- js/ui/userMenu.js | 597 +------------------------------------ 2 files changed, 5 insertions(+), 628 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index 3c5aa49e0..cd31541cb 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -605,42 +605,6 @@ StScrollBar StButton#vhandle:active { spacing: 8px; } -/* User Menu */ - -#panelUserMenu { - spacing: 4px; -} - -.status-chooser { - spacing: .4em; -} - -.status-chooser .popup-menu-item, -.status-chooser-combo .popup-menu-item { - padding: .4em; -} - -.status-chooser-user-name { - font-weight: bold; - font-size: 1.3em; - min-width: 120pt; -} - -.status-chooser-combo { - border: 1px solid transparent; -} - -.status-chooser-combo.popup-combo-menu { - padding: .4em 0em; - border-radius: 4px; - border: 1px solid #5f5f5f; -} - -.status-chooser-status-item, -.status-chooser-combo .popup-combobox-item { - spacing: .4em; -} - .system-status-icon { icon-size: 1.09em; } diff --git a/js/ui/userMenu.js b/js/ui/userMenu.js index 820a0b8b0..66173d5ef 100644 --- a/js/ui/userMenu.js +++ b/js/ui/userMenu.js @@ -6,11 +6,7 @@ const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const Gtk = imports.gi.Gtk; const Lang = imports.lang; -const Pango = imports.gi.Pango; -const Shell = imports.gi.Shell; const St = imports.gi.St; -const Tp = imports.gi.TelepathyGLib; -const Atk = imports.gi.Atk; const Clutter = imports.gi.Clutter; const BoxPointer = imports.ui.boxpointer; @@ -30,21 +26,9 @@ const DISABLE_USER_SWITCH_KEY = 'disable-user-switching'; const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen'; const DISABLE_LOG_OUT_KEY = 'disable-log-out'; const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out'; -const SHOW_FULL_NAME_IN_TOP_BAR_KEY = 'show-full-name-in-top-bar'; const MAX_USERS_IN_SESSION_DIALOG = 5; -const IMStatus = { - AVAILABLE: 0, - BUSY: 1, - HIDDEN: 2, - AWAY: 3, - IDLE: 4, - OFFLINE: 5, - LAST: 6 -}; - - const SystemdLoginSessionIface = @@ -55,463 +39,26 @@ const SystemdLoginSessionIface = 0 && this._networkMonitor.network_available; - this._combo.setSensitive(sensitive); - }, - - _IMStatusChanged: function(accountMgr, presence, status, message) { - if (!this._imPresenceRestored) - this._imPresenceRestored = true; - - if (presence == this._currentPresence) - return; - - this._currentPresence = presence; - this._setComboboxPresence(presence); - - if (!this._sessionPresenceRestored) { - this._sessionStatusChanged(this._presence.status); - return; - } - - if (presence == Tp.ConnectionPresenceType.AVAILABLE) - this._presence.status = GnomeSession.PresenceStatus.AVAILABLE; - - // 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) - global.settings.set_int('saved-im-presence', presence); - else - this._expectedPresence = undefined; - }, - - _setComboboxPresence: function(presence) { - 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); - msg = msg ? msg : ''; - this._accountMgr.set_all_requested_presences(newPresence, status, msg); - }, - - getIMPresenceForSessionStatus: function(sessionStatus) { - // Restore the last user-set presence when coming back from - // BUSY/IDLE (otherwise the last user-set presence matches - // the current one) - if (sessionStatus == GnomeSession.PresenceStatus.AVAILABLE) - return global.settings.get_int('saved-im-presence'); - - if (sessionStatus == GnomeSession.PresenceStatus.BUSY) { - // Only change presence if the current one is "more present" than - // busy, or if coming back from idle - if (this._currentPresence == Tp.ConnectionPresenceType.AVAILABLE || - this._currentPresence == Tp.ConnectionPresenceType.EXTENDED_AWAY) - return Tp.ConnectionPresenceType.BUSY; - } - - if (sessionStatus == GnomeSession.PresenceStatus.IDLE) { - // Only change presence if the current one is "more present" than - // idle - if (this._currentPresence != Tp.ConnectionPresenceType.OFFLINE && - this._currentPresence != Tp.ConnectionPresenceType.HIDDEN) - return Tp.ConnectionPresenceType.EXTENDED_AWAY; - } - - return this._currentPresence; - }, - - _sessionStatusChanged: function(sessionStatus) { - if (!this._imPresenceRestored) - return; - - let savedStatus = global.settings.get_int('saved-session-presence'); - if (!this._sessionPresenceRestored) { - - // 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; - - if (sessionStatus != savedStatus) { - this._presence.status = savedStatus; - return; - } - this._sessionPresenceRestored = true; - } - - if ((sessionStatus == GnomeSession.PresenceStatus.AVAILABLE || - sessionStatus == GnomeSession.PresenceStatus.BUSY) && - savedStatus != sessionStatus) - global.settings.set_int('saved-session-presence', sessionStatus); - - let [presence, s, msg] = this._accountMgr.get_most_available_presence(); - let newPresence, status; - - let newPresence = this.getIMPresenceForSessionStatus(sessionStatus); - - if (!newPresence || newPresence == presence) - return; - - status = this._statusForPresence(newPresence); - msg = msg ? msg : ''; - - this._expectedPresence = newPresence; - this._accountMgr.set_all_requested_presences(newPresence, status, msg); - } -}); - - const UserMenuButton = new Lang.Class({ Name: 'UserMenuButton', - Extends: PanelMenu.Button, + Extends: PanelMenu.SystemStatusButton, _init: function() { - this.parent(0.0); - - this.actor.accessible_role = Atk.Role.MENU; - - let box = new St.BoxLayout({ name: 'panelUserMenu' }); - this.actor.add_actor(box); + this.parent('user-available-symbolic', _("User Menu")); this._screenSaverSettings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA }); this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA }); this._privacySettings = new Gio.Settings({ schema: PRIVACY_SCHEMA }); - this._userManager = AccountsService.UserManager.get_default(); - - this._user = this._userManager.get_user(GLib.get_user_name()); - this._presence = new GnomeSession.Presence(); this._session = new GnomeSession.SessionManager(); this._haveShutdown = true; this._haveSuspend = true; - this._accountMgr = Tp.AccountManager.dup(); - - this._loginManager = LoginManager.getLoginManager(); - this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); - - this._iconBox = new St.Bin(); - box.add(this._iconBox, { y_align: St.Align.MIDDLE, y_fill: false }); - - let textureCache = St.TextureCache.get_default(); - this._offlineIcon = new St.Icon({ icon_name: 'user-offline-symbolic', - style_class: 'popup-menu-icon' }); - this._availableIcon = new St.Icon({ icon_name: 'user-available-symbolic', - style_class: 'popup-menu-icon' }); - this._busyIcon = new St.Icon({ icon_name: 'user-busy-symbolic', - style_class: 'popup-menu-icon' }); - this._invisibleIcon = new St.Icon({ icon_name: 'user-invisible-symbolic', - style_class: 'popup-menu-icon' }); - this._awayIcon = new St.Icon({ icon_name: 'user-away-symbolic', - style_class: 'popup-menu-icon' }); - this._idleIcon = new St.Icon({ icon_name: 'user-idle-symbolic', - style_class: 'popup-menu-icon' }); - this._pendingIcon = new St.Icon({ icon_name: 'user-status-pending-symbolic', - style_class: 'popup-menu-icon' }); - this._lockedIcon = new St.Icon({ icon_name: 'changes-prevent-symbolic', - style_class: 'popup-menu-icon' }); - - this._accountMgr.connect('most-available-presence-changed', - Lang.bind(this, this._updatePresenceIcon)); - this._accountMgr.connect('account-enabled', - Lang.bind(this, this._onAccountEnabled)); - this._accountMgr.connect('account-removed', - Lang.bind(this, this._onAccountRemoved)); - this._accountMgr.prepare_async(null, Lang.bind(this, - function(mgr) { - let [presence, s, msg] = mgr.get_most_available_presence(); - this._updatePresenceIcon(mgr, presence, s, msg); - this._setupAccounts(); - })); - - this._name = new St.Label(); - this.actor.label_actor = this._name; - box.add(this._name, { y_align: St.Align.MIDDLE, y_fill: false }); - this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, this._updateUserName)); - this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUserName)); - this._updateUserName(); - this._createSubMenu(); - this._updateSwitch(this._presence.status); - this._presence.connectSignal('StatusChanged', Lang.bind(this, function (proxy, senderName, [status]) { - this._updateSwitch(status); - })); - + this._loginManager = LoginManager.getLoginManager(); + this._userManager = AccountsService.UserManager.get_default(); + this._user = this._userManager.get_user(GLib.get_user_name()); this._userManager.connect('notify::is-loaded', Lang.bind(this, this._updateMultiUser)); this._userManager.connect('notify::has-multiple-users', @@ -528,10 +75,6 @@ const UserMenuButton = new Lang.Class({ Lang.bind(this, this._updateLockScreen)); global.settings.connect('changed::' + ALWAYS_SHOW_LOG_OUT_KEY, Lang.bind(this, this._updateLogout)); - this._screenSaverSettings.connect('changed::' + SHOW_FULL_NAME_IN_TOP_BAR_KEY, - Lang.bind(this, this._updateUserName)); - this._privacySettings.connect('changed::' + SHOW_FULL_NAME_IN_TOP_BAR_KEY, - Lang.bind(this, this._updateUserName)); this._updateSwitchUser(); this._updateLogout(); this._updateLockScreen(); @@ -556,35 +99,12 @@ const UserMenuButton = new Lang.Class({ Lang.bind(this, this._updateHaveShutdown)); Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); - if (Main.screenShield) - Main.screenShield.connect('locked-changed', Lang.bind(this, this._updatePresenceIcon)); this._sessionUpdated(); }, _sessionUpdated: function() { this.actor.visible = !Main.sessionMode.isGreeter; - - let allowSettings = Main.sessionMode.allowSettings; - this._statusChooser.setSensitive(allowSettings); - this.setSensitive(!Main.sessionMode.isLocked); - this._updatePresenceIcon(); - this._updateUserName(); - }, - - _onDestroy: function() { - this._user.disconnect(this._userLoadedId); - this._user.disconnect(this._userChangedId); - }, - - _updateUserName: function() { - let settings = this._privacySettings; - if (Main.sessionMode.isLocked) - settings = this._screenSaverSettings; - if (this._user.is_loaded && settings.get_boolean(SHOW_FULL_NAME_IN_TOP_BAR_KEY)) - this._name.set_text(this._user.get_real_name()); - else - this._name.set_text(""); }, _updateMultiUser: function() { @@ -656,91 +176,9 @@ const UserMenuButton = new Lang.Class({ } }, - _updateSwitch: function(status) { - let active = status == GnomeSession.PresenceStatus.AVAILABLE; - this._notificationsSwitch.setToggleState(active); - }, - - _updatePresenceIcon: function(accountMgr, presence, status, message) { - if (Main.sessionMode.isLocked) - this._iconBox.child = this._lockedIcon; - else if (presence == Tp.ConnectionPresenceType.AVAILABLE) - this._iconBox.child = this._availableIcon; - else if (presence == Tp.ConnectionPresenceType.BUSY) - this._iconBox.child = this._busyIcon; - else if (presence == Tp.ConnectionPresenceType.HIDDEN) - this._iconBox.child = this._invisibleIcon; - else if (presence == Tp.ConnectionPresenceType.AWAY) - this._iconBox.child = this._awayIcon; - else if (presence == Tp.ConnectionPresenceType.EXTENDED_AWAY) - this._iconBox.child = this._idleIcon; - else - this._iconBox.child = this._offlineIcon; - - if (Main.sessionMode.isLocked) - this._iconBox.visible = Main.screenShield.locked; - else - this._iconBox.visible = true; - }, - - _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(); - }, - - _onAccountRemoved: function(accountMgr, account) { - if (account._changingId) { - account.disconnect(account._changingId); - account._changingId = 0; - } - 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); - } - }, - _createSubMenu: function() { let item; - item = new IMStatusChooserItem(); - item.connect('activate', Lang.bind(this, this._onMyAccountActivate)); - this.menu.addMenuItem(item); - this._statusChooser = item; - - item = new PopupMenu.PopupSwitchMenuItem(_("Notifications")); - item.connect('toggled', Lang.bind(this, this._updatePresenceStatus)); - this.menu.addMenuItem(item); - this._notificationsSwitch = item; - - item = new PopupMenu.PopupSeparatorMenuItem(); - this.menu.addMenuItem(item); - this.menu.addSettingsAction(_("Settings"), 'gnome-control-center.desktop'); item = new PopupMenu.PopupSeparatorMenuItem(); @@ -777,31 +215,6 @@ const UserMenuButton = new Lang.Class({ this._installUpdatesItem = item; }, - _updatePresenceStatus: function(item, event) { - let status; - - if (item.state) { - status = GnomeSession.PresenceStatus.AVAILABLE; - } else { - status = GnomeSession.PresenceStatus.BUSY; - - let [presence, s, msg] = this._accountMgr.get_most_available_presence(); - 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.")); - } - - this._presence.status = status; - }, - - _onMyAccountActivate: function() { - Main.overview.hide(); - let app = Shell.AppSystem.get_default().lookup_app('gnome-user-accounts-panel.desktop'); - app.activate(); - }, - _onLockScreenActivate: function() { this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); Main.overview.hide();