meta-monitor-manager: current_switch_config value immediately lost upon config change
When pressing Super+P or the display switch media key, we reach handle_switch_monitor
:
handle_switch_monitor (MetaDisplay *display,
MetaWindow *window,
ClutterKeyEvent *event,
MetaKeyBinding *binding,
gpointer dummy)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaMonitorSwitchConfigType config_type =
meta_monitor_manager_get_switch_config (monitor_manager);
if (!meta_monitor_manager_can_switch_config (monitor_manager))
return;
config_type = (config_type + 1) % (META_MONITOR_SWITCH_CONFIG_UNKNOWN);
meta_monitor_manager_switch_config (monitor_manager, config_type);
}
That clearly tries to implement cyclic behaviour, i.e. press the key and the current switch_config
should be incremented, press it again and it increments again, until we get to the last mode (builtin display only) at which point the next increment should go back to the start of the list (mirror mode).
However what happens, at least under X11, is:
-
meta_monitor_manager_switch_config
is called as above. It asks X to make the relevant changes via xrandr and also updatescurrent_switch_config
to the new value - An X RRScreenChangeNotify event is raised.
-
meta_monitor_manager_xrandr_handle_event
fires, and even though it realises it was our own config change that generated this event, it proceeds... - ...and calls
meta_monitor_manager_xrandr_rebuild_derived
- ...which calls
meta_monitor_manager_rebuild_derived
- ...which calls
meta_monitor_manager_notify_monitors_changed
- ...which sets current_switch_config to
META_MONITOR_MANAGER_SWITCH_CONFIG_UNKNOWN
So next time Super+P is pressed, meta_monitor_manager_get_switch_config
returns UNKNOWN
, so we end up setting config 1 (linear), and then we repeat the above.
At least in the GNOME case, this bug is hidden by the fact that gnome-shell doesn't rely on mutter's implementation of the display config cycle here. It appears to have its own UI control which cycles through the display configs, ignoring the fact that meta_monitor_manager_get_switch_config
does not return a meaningful value.