Skip to content

Commit ca8df1f

Browse files
committed
panel.js: Improve handling of invalid/duplicate panel definitions.
Similar what the preceding commit (e6fe42cd9c79bd4) changed for cinnamon-settings, definitions will be checked during startup, and definitions with duplicate IDs or monitor:position combinations will be removed.
1 parent da30af3 commit ca8df1f

File tree

1 file changed

+60
-17
lines changed

1 file changed

+60
-17
lines changed

js/ui/panel.js

+60-17
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ var PanelLoc = {
9595
right : 3
9696
};
9797

98+
const PanelDefElement = {
99+
ID : 0,
100+
MONITOR : 1,
101+
POSITION: 2
102+
};
103+
98104
// To make sure the panel corners blend nicely with the panel,
99105
// we draw background and borders the same way, e.g. drawing
100106
// them as filled shapes from the outside inwards instead of
@@ -395,6 +401,7 @@ PanelManager.prototype = {
395401
this._setMainPanel();
396402

397403
this.addPanelMode = false;
404+
this.handling_panels_changed = false;
398405

399406
this._panelsEnabledId = global.settings.connect("changed::panels-enabled", Lang.bind(this, this._onPanelsEnabledChanged));
400407
this._panelEditModeId = global.settings.connect("changed::panel-edit-mode", Lang.bind(this, this._onPanelEditModeChanged));
@@ -421,25 +428,59 @@ PanelManager.prototype = {
421428
let monitor = 0;
422429
let stash = []; // panel id, monitor, panel type
423430

424-
let monitorCount = -1;
431+
let monitorCount = global.display.get_n_monitors();
425432
let panels_used = []; // [monitor] [top, bottom, left, right]. Used to keep track of which panel types are in use,
426433
// as we need knowledge of the combinations in order to instruct the correct panel to create a corner
427434

428-
let panelProperties = getPanelsEnabledList();
435+
let panel_defs = getPanelsEnabledList();
429436
//
430437
// First pass through just to count the monitors, as there is no ordering to rely on
431438
//
432-
for (let i = 0, len = panelProperties.length; i < len; i++) {
433-
let elements = panelProperties[i].split(":");
439+
let good_defs = [];
440+
let removals = [];
441+
for (let i = 0, len = panel_defs.length; i < len; i++) {
442+
let elements = panel_defs[i].split(":");
434443
if (elements.length != 3) {
435-
global.log("Invalid panel definition: " + panelProperties[i]);
444+
global.log("Invalid panel definition: " + panel_defs[i]);
445+
removals.push(i);
436446
continue;
437447
}
438448

439-
monitor = parseInt(elements[1]);
440-
if (monitor > monitorCount)
441-
monitorCount = monitor;
449+
if (elements[PanelDefElement.MONITOR] >= monitorCount) {
450+
// Ignore, but don't remove. Less monitors can be a temporary condition.
451+
global.log("Ignoring panel definition for nonexistent monitor: " + panel_defs[i]);
452+
continue;
453+
}
454+
455+
// Some sanitizing
456+
if (good_defs.find((good_def) => {
457+
const good_elements = good_def.split(":");
458+
// Ignore any duplicate IDs
459+
if (good_elements[PanelDefElement.ID] === elements[PanelDefElement.ID]) {
460+
global.log("Duplicate ID detected in panel definition: " + panel_defs[i]);
461+
return true;
462+
}
463+
// Ignore any duplicate monitor/position combinations
464+
if ((good_elements[PanelDefElement.MONITOR] === elements[PanelDefElement.MONITOR]) && (good_elements[PanelDefElement.POSITION] === elements[PanelDefElement.POSITION])) {
465+
global.log("Duplicate monitor+position detected in panel definition: " + panel_defs[i]);
466+
return true;
467+
}
468+
469+
return false;
470+
})) {
471+
removals.push(panel_defs[i]);
472+
continue;
473+
}
474+
475+
good_defs.push(panel_defs[i]);
476+
}
477+
478+
if (removals.length > 0) {
479+
let clean_defs = panel_defs.filter((def) => !removals.includes(def));
480+
global.log("Removing invalid panel definitions: " + removals);
481+
setPanelsEnabledList(clean_defs);
442482
}
483+
443484
//
444485
// initialise the array that records which panels are used (so combinations can be used to select corners)
445486
//
@@ -453,19 +494,15 @@ PanelManager.prototype = {
453494
//
454495
// set up the list of panels
455496
//
456-
for (let i = 0, len = panelProperties.length; i < len; i++) {
457-
let elements = panelProperties[i].split(":");
458-
if (elements.length != 3) {
459-
global.log("Invalid panel definition: " + panelProperties[i]);
460-
continue;
461-
}
462-
let jj = getPanelLocFromName(elements[2]); // panel orientation
497+
for (let i = 0, len = good_defs.length; i < len; i++) {
498+
let elements = good_defs[i].split(":");
463499

464-
monitor = parseInt(elements[1]);
500+
let jj = getPanelLocFromName(elements[PanelDefElement.POSITION]); // panel orientation
465501

502+
monitor = parseInt(elements[PanelDefElement.MONITOR]);
466503
panels_used[monitor][jj] = true;
467504

468-
stash[i] = [parseInt(elements[0]),monitor,jj]; // load what we are going to use to call loadPanel into an array
505+
stash[i] = [parseInt(elements[PanelDefElement.ID]), monitor, jj]; // load what we are going to use to call loadPanel into an array
469506
}
470507

471508
//
@@ -886,6 +923,10 @@ PanelManager.prototype = {
886923
* i.e. when panels are added, moved or removed.
887924
*/
888925
_onPanelsEnabledChanged: function() {
926+
if (this.handling_panels_changed)
927+
return;
928+
this.handling_panels_changed = true;
929+
889930
let newPanels = new Array(this.panels.length);
890931
let newMeta = new Array(this.panels.length);
891932
let drawcorner = [false,false];
@@ -980,6 +1021,8 @@ PanelManager.prototype = {
9801021
Lang.bind(this, function() { Util.spawnCommandLine("cinnamon-settings panel"); }));
9811022
lastPanelRemovedDialog.open();
9821023
}
1024+
1025+
this.handling_panels_changed = false;
9831026
},
9841027

9851028
/**

0 commit comments

Comments
 (0)