What the model holds

Consumers never read picture-uri-list directly, and never match monitors to entries themselves. A CinnamonBgList is a GListModel holding exactly what should be presented: one CinnamonBgItem per connected monitor in independent mode, exactly one in mirror and spanned. Editing the model is editing the configuration; there is no resolved view sitting in front of a separate authoritative one.

The key can still hold more than the model does — an entry for a monitor that is not currently connected has nowhere to appear. That is the whole difference between the two ways of persisting: cinnamon_bg_list_save() replaces the key with the model and so drops those entries, while cinnamon_bg_list_save_pictures() leaves them alone.

The model is derived whenever either key or the monitor layout moves. In independent mode each monitor is matched to a stored entry by:

  1. its connector (for example eDP-1);

  2. otherwise its logical-monitor index, so a layout survives connectors being renamed between X11 and Wayland sessions;

  3. otherwise the nearest matched neighbor, so a newly plugged monitor shows something sensible instead of black.

Mirror and spanned do not match per monitor at all. They present one item, seeded from the representative entry — the one carrying no connector, or failing that the primary monitor's.

Items are reused across rebuilds, matched by connector, so a reference a consumer holds stays live across an edit made in another process and its properties notify in place.

The layout arrives asynchronously from the window manager, so a list that has just been created holds nothing at all. It starts loading on construction, so a consumer only has to wait rather than ask for it; cinnamon_bg_list_get_monitor_infos() is empty until the reply lands. Watch config-changed and re-read from there.