@@ -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