Panel: clean up button construction code
We already could build the right part of the panel declaratively according to the session mode. Extend that to handle the left and center parts. Also, move the mapping from the roles to the classes in panel.js, as it shared by all modes. https://bugzilla.gnome.org/show_bug.cgi?id=682546
This commit is contained in:
parent
e0ca572572
commit
e5534e86ab
@ -222,8 +222,7 @@ function start() {
|
|||||||
|
|
||||||
sessionMode.createSession();
|
sessionMode.createSession();
|
||||||
|
|
||||||
panel.startStatusArea();
|
panel.init();
|
||||||
|
|
||||||
layoutManager.init();
|
layoutManager.init();
|
||||||
keyboard.init();
|
keyboard.init();
|
||||||
overview.init();
|
overview.init();
|
||||||
|
136
js/ui/panel.js
136
js/ui/panel.js
@ -14,13 +14,14 @@ const St = imports.gi.St;
|
|||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Atk = imports.gi.Atk;
|
const Atk = imports.gi.Atk;
|
||||||
|
|
||||||
|
|
||||||
|
const Config = imports.misc.config;
|
||||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const Layout = imports.ui.layout;
|
const Layout = imports.ui.layout;
|
||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const DateMenu = imports.ui.dateMenu;
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
@ -221,14 +222,14 @@ const AppMenuButton = new Lang.Class({
|
|||||||
Name: 'AppMenuButton',
|
Name: 'AppMenuButton',
|
||||||
Extends: PanelMenu.Button,
|
Extends: PanelMenu.Button,
|
||||||
|
|
||||||
_init: function(menuManager) {
|
_init: function(panel) {
|
||||||
this.parent(0.0, null, true);
|
this.parent(0.0, null, true);
|
||||||
|
|
||||||
this.actor.accessible_role = Atk.Role.MENU;
|
this.actor.accessible_role = Atk.Role.MENU;
|
||||||
|
|
||||||
this._startingApps = [];
|
this._startingApps = [];
|
||||||
|
|
||||||
this._menuManager = menuManager;
|
this._menuManager = panel.menuManager;
|
||||||
this._targetApp = null;
|
this._targetApp = null;
|
||||||
this._appMenuNotifyId = 0;
|
this._appMenuNotifyId = 0;
|
||||||
this._actionGroupNotifyId = 0;
|
this._actionGroupNotifyId = 0;
|
||||||
@ -899,6 +900,29 @@ const PanelCorner = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const PANEL_ITEM_IMPLEMENTATIONS = {
|
||||||
|
'activities': ActivitiesButton,
|
||||||
|
'appMenu': AppMenuButton,
|
||||||
|
'dateMenu': imports.ui.dateMenu.DateMenuButton,
|
||||||
|
'a11y': imports.ui.status.accessibility.ATIndicator,
|
||||||
|
'volume': imports.ui.status.volume.Indicator,
|
||||||
|
'battery': imports.ui.status.power.Indicator,
|
||||||
|
'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
|
||||||
|
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
||||||
|
'powerMenu': imports.gdm.powerMenu.PowerMenuButton,
|
||||||
|
'userMenu': imports.ui.userMenu.UserMenuButton
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Config.HAVE_BLUETOOTH)
|
||||||
|
PANEL_ITEM_IMPLEMENTATIONS['bluetooth'] =
|
||||||
|
imports.ui.status.bluetooth.Indicator;
|
||||||
|
|
||||||
|
try {
|
||||||
|
PANEL_ITEM_IMPLEMENTATIONS['network'] =
|
||||||
|
imports.ui.status.network.NMApplet;
|
||||||
|
} catch(e) {
|
||||||
|
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
||||||
|
}
|
||||||
|
|
||||||
const Panel = new Lang.Class({
|
const Panel = new Lang.Class({
|
||||||
Name: 'Panel',
|
Name: 'Panel',
|
||||||
@ -919,7 +943,7 @@ const Panel = new Lang.Class({
|
|||||||
|
|
||||||
Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._onLockStateChanged));
|
Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._onLockStateChanged));
|
||||||
|
|
||||||
this._menus = new PopupMenu.PopupMenuManager(this);
|
this.menuManager = new PopupMenu.PopupMenuManager(this);
|
||||||
|
|
||||||
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
|
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
|
||||||
this.actor.add_actor(this._leftBox);
|
this.actor.add_actor(this._leftBox);
|
||||||
@ -946,27 +970,6 @@ const Panel = new Lang.Class({
|
|||||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||||
|
|
||||||
/* Button on the left side of the panel. */
|
|
||||||
if (Main.sessionMode.hasOverview) {
|
|
||||||
this._activitiesButton = new ActivitiesButton();
|
|
||||||
this._activities = this._activitiesButton.actor;
|
|
||||||
this._leftBox.add(this._activities);
|
|
||||||
|
|
||||||
// The activities button has a pretend menu, so as to integrate
|
|
||||||
// more cleanly with the rest of the panel
|
|
||||||
this._menus.addMenu(this._activitiesButton.menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Main.sessionMode.hasAppMenu) {
|
|
||||||
this._appMenu = new AppMenuButton(this._menus);
|
|
||||||
this._leftBox.add(this._appMenu.actor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* center */
|
|
||||||
this._dateMenu = new DateMenu.DateMenuButton();
|
|
||||||
this._centerBox.add(this._dateMenu.actor, { y_fill: true });
|
|
||||||
this._menus.addMenu(this._dateMenu.menu);
|
|
||||||
|
|
||||||
Main.layoutManager.panelBox.add(this.actor);
|
Main.layoutManager.panelBox.add(this.actor);
|
||||||
Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'start-here-symbolic',
|
Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'start-here-symbolic',
|
||||||
{ sortGroup: CtrlAltTab.SortGroup.TOP });
|
{ sortGroup: CtrlAltTab.SortGroup.TOP });
|
||||||
@ -1086,75 +1089,70 @@ const Panel = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
openAppMenu: function() {
|
openAppMenu: function() {
|
||||||
let menu = this._appMenu.menu;
|
let indicator = this.statusArea.appMenu;
|
||||||
if (!this._appMenu.actor.reactive || menu.isOpen)
|
if (!indicator) // appMenu not supported by current session mode
|
||||||
|
return;
|
||||||
|
|
||||||
|
let menu = indicator.menu;
|
||||||
|
if (!indicator.actor.reactive || menu.isOpen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
menu.open();
|
menu.open();
|
||||||
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
startStatusArea: function() {
|
init: function() {
|
||||||
for (let i = 0; i < Main.sessionMode.statusArea.order.length; i++) {
|
let panel = Main.sessionMode.panel;
|
||||||
let role = Main.sessionMode.statusArea.order[i];
|
this._initBox(panel.left, this._leftBox);
|
||||||
let constructor = Main.sessionMode.statusArea.implementation[role];
|
this._initBox(panel.center, this._centerBox);
|
||||||
|
this._initBox(panel.right, this._rightBox);
|
||||||
|
},
|
||||||
|
|
||||||
|
_initBox: function(elements, box) {
|
||||||
|
for (let i = 0; i < elements.length; i++) {
|
||||||
|
let role = elements[i];
|
||||||
|
let constructor = PANEL_ITEM_IMPLEMENTATIONS[role];
|
||||||
if (!constructor) {
|
if (!constructor) {
|
||||||
// This icon is not implemented (this is a bug)
|
// panel icon is not supported (can happen for
|
||||||
|
// bluetooth or network)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let indicator = new constructor();
|
let indicator = new constructor(this);
|
||||||
this.addToStatusArea(role, indicator, i);
|
this._addToPanelBox(role, indicator, i, box);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_insertStatusItem: function(actor, position) {
|
_addToPanelBox: function(role, indicator, position, box) {
|
||||||
let children = this._rightBox.get_children();
|
box.insert_child_at_index(indicator.actor, position);
|
||||||
let i;
|
if (indicator.menu)
|
||||||
for (i = children.length - 1; i >= 0; i--) {
|
this.menuManager.addMenu(indicator.menu);
|
||||||
let rolePosition = children[i]._rolePosition;
|
this.statusArea[role] = indicator;
|
||||||
if (position > rolePosition) {
|
let destroyId = indicator.connect('destroy', Lang.bind(this, function(emitter) {
|
||||||
this._rightBox.insert_child_at_index(actor, i + 1);
|
delete this.statusArea[role];
|
||||||
break;
|
emitter.disconnect(destroyId);
|
||||||
}
|
}));
|
||||||
}
|
|
||||||
if (i == -1) {
|
|
||||||
// If we didn't find a position, we must be first
|
|
||||||
this._rightBox.insert_child_at_index(actor, 0);
|
|
||||||
}
|
|
||||||
actor._rolePosition = position;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addToStatusArea: function(role, indicator, position) {
|
addToStatusArea: function(role, indicator, position, box) {
|
||||||
if (this.statusArea[role])
|
if (this.statusArea[role])
|
||||||
throw new Error('Extension point conflict: there is already a status indicator for role ' + role);
|
throw new Error('Extension point conflict: there is already a status indicator for role ' + role);
|
||||||
|
|
||||||
if (!(indicator instanceof PanelMenu.Button))
|
if (!(indicator instanceof PanelMenu.Button))
|
||||||
throw new TypeError('Status indicator must be an instance of PanelMenu.Button');
|
throw new TypeError('Status indicator must be an instance of PanelMenu.Button');
|
||||||
|
|
||||||
if (!position)
|
position = position || 0;
|
||||||
position = 0;
|
let boxes = {
|
||||||
this._insertStatusItem(indicator.actor, position);
|
left: this._leftBox,
|
||||||
if (indicator.menu)
|
center: this._centerBox,
|
||||||
this._menus.addMenu(indicator.menu);
|
right: this._rightBox
|
||||||
|
};
|
||||||
this.statusArea[role] = indicator;
|
let boxContainer = boxes[box] || this._rightBox;
|
||||||
let destroyId = indicator.connect('destroy', Lang.bind(this, function(emitter) {
|
this._addToPanelBox(role, indicator, position, boxContainer);
|
||||||
delete this.statusArea[role];
|
|
||||||
emitter.disconnect(destroyId);
|
|
||||||
}));
|
|
||||||
|
|
||||||
return indicator;
|
return indicator;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onLockStateChanged: function(shield, locked) {
|
_onLockStateChanged: function(shield, locked) {
|
||||||
if (this._activitiesButton)
|
|
||||||
this._activitiesButton.setLockedState(locked);
|
|
||||||
if (this._appMenu)
|
|
||||||
this._appMenu.setLockedState(locked);
|
|
||||||
if (this._dateMenu)
|
|
||||||
this._dateMenu.setLockedState(locked);
|
|
||||||
|
|
||||||
for (let id in this.statusArea)
|
for (let id in this.statusArea)
|
||||||
this.statusArea[id].setLockedState(locked);
|
this.statusArea[id].setLockedState(locked);
|
||||||
},
|
},
|
||||||
|
@ -2,37 +2,13 @@
|
|||||||
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
|
||||||
const Config = imports.misc.config;
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
|
|
||||||
|
|
||||||
const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
|
|
||||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
|
||||||
'volume': imports.ui.status.volume.Indicator,
|
|
||||||
'battery': imports.ui.status.power.Indicator,
|
|
||||||
'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
|
|
||||||
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
|
||||||
'userMenu': imports.ui.userMenu.UserMenuButton
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Config.HAVE_BLUETOOTH)
|
|
||||||
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] =
|
|
||||||
imports.ui.status.bluetooth.Indicator;
|
|
||||||
|
|
||||||
try {
|
|
||||||
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['network'] =
|
|
||||||
imports.ui.status.network.NMApplet;
|
|
||||||
} catch(e) {
|
|
||||||
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const DEFAULT_MODE = 'user';
|
const DEFAULT_MODE = 'user';
|
||||||
|
|
||||||
const _modes = {
|
const _modes = {
|
||||||
'gdm': { hasOverview: false,
|
'gdm': { hasOverview: false,
|
||||||
hasAppMenu: false,
|
|
||||||
showCalendarEvents: false,
|
showCalendarEvents: false,
|
||||||
allowSettings: false,
|
allowSettings: false,
|
||||||
allowExtensions: false,
|
allowExtensions: false,
|
||||||
@ -42,24 +18,15 @@ const _modes = {
|
|||||||
createSession: Main.createGDMSession,
|
createSession: Main.createGDMSession,
|
||||||
createUnlockDialog: Main.createGDMLoginDialog,
|
createUnlockDialog: Main.createGDMLoginDialog,
|
||||||
extraStylesheet: null,
|
extraStylesheet: null,
|
||||||
statusArea: {
|
panel: {
|
||||||
order: [
|
left: [],
|
||||||
'a11y', 'display', 'keyboard',
|
center: ['dateMenu'],
|
||||||
'volume', 'battery', 'lockScreen', 'powerMenu'
|
right: ['a11y', 'display', 'keyboard',
|
||||||
],
|
'volume', 'battery', 'lockScreen', 'powerMenu']
|
||||||
implementation: {
|
|
||||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
|
||||||
'volume': imports.ui.status.volume.Indicator,
|
|
||||||
'battery': imports.ui.status.power.Indicator,
|
|
||||||
'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
|
|
||||||
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
|
||||||
'powerMenu': imports.gdm.powerMenu.PowerMenuButton
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'initial-setup': { hasOverview: false,
|
'initial-setup': { hasOverview: false,
|
||||||
hasAppMenu: false,
|
|
||||||
showCalendarEvents: false,
|
showCalendarEvents: false,
|
||||||
allowSettings: false,
|
allowSettings: false,
|
||||||
allowExtensions: false,
|
allowExtensions: false,
|
||||||
@ -68,21 +35,14 @@ const _modes = {
|
|||||||
hasWorkspaces: false,
|
hasWorkspaces: false,
|
||||||
createSession: Main.createInitialSetupSession,
|
createSession: Main.createInitialSetupSession,
|
||||||
extraStylesheet: null,
|
extraStylesheet: null,
|
||||||
statusArea: {
|
panel: {
|
||||||
order: [
|
left: [],
|
||||||
'a11y', 'keyboard', 'volume', 'lockScreen',
|
center: ['dateMenu'],
|
||||||
],
|
right: ['a11y', 'keyboard', 'volume', 'lockScreen']
|
||||||
implementation: {
|
|
||||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
|
||||||
'keyboard': imports.ui.status.keyboard.XKBIndicator,
|
|
||||||
'volume': imports.ui.status.volume.Indicator,
|
|
||||||
'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'user': { hasOverview: true,
|
'user': { hasOverview: true,
|
||||||
hasAppMenu: true,
|
|
||||||
showCalendarEvents: true,
|
showCalendarEvents: true,
|
||||||
allowSettings: true,
|
allowSettings: true,
|
||||||
allowExtensions: true,
|
allowExtensions: true,
|
||||||
@ -92,12 +52,11 @@ const _modes = {
|
|||||||
createSession: Main.createUserSession,
|
createSession: Main.createUserSession,
|
||||||
createUnlockDialog: Main.createSessionUnlockDialog,
|
createUnlockDialog: Main.createSessionUnlockDialog,
|
||||||
extraStylesheet: null,
|
extraStylesheet: null,
|
||||||
statusArea: {
|
panel: {
|
||||||
order: [
|
left: ['activities', 'appMenu'],
|
||||||
'input-method', 'a11y', 'keyboard', 'volume', 'bluetooth',
|
center: ['dateMenu'],
|
||||||
'network', 'battery', 'lockScreen', 'userMenu'
|
right: ['a11y', 'keyboard', 'volume', 'bluetooth',
|
||||||
],
|
'network', 'battery', 'lockScreen', 'userMenu']
|
||||||
implementation: STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user