backends: Disambiguate output mapped to tablet with connector name

In some circumstances, we may end up with outputs with the same
vendor/product/serial, in which case we have a hard time finding the
right one to map tablets to, since configuration only has these 3
pieces of data.

Add the handling of a 4th argument containing the output name
based on the connector (e.g. HDMI-1), so that it can be used to
disambiguate the output if necessary.

This only kicks in if there actually are multiple outputs with the
same EDID data. A goal of the configuration as it was stored was to
remain useful if the user changed how the device is physically
connected to the computer, this remains true for the vast majority
of users having a single thing of each.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3556>
This commit is contained in:
Carlos Garnacho 2024-02-01 18:44:44 +01:00 committed by Marge Bot
parent ff38cf366d
commit bf89ada2c1

View File

@ -391,9 +391,33 @@ match_builtin (MetaInputMapper *mapper,
return monitor == meta_monitor_manager_get_laptop_panel (mapper->monitor_manager);
}
static gboolean
monitor_has_twin (MetaMonitor *monitor,
GList *monitors)
{
GList *l;
for (l = monitors; l; l = l->next)
{
if (l->data == monitor)
continue;
if (g_strcmp0 (meta_monitor_get_vendor (monitor),
meta_monitor_get_vendor (l->data)) == 0 &&
g_strcmp0 (meta_monitor_get_product (monitor),
meta_monitor_get_product (l->data)) == 0 &&
g_strcmp0 (meta_monitor_get_serial (monitor),
meta_monitor_get_serial (l->data)) == 0)
return TRUE;
}
return FALSE;
}
static gboolean
match_config (MetaMapperInputInfo *info,
MetaMonitor *monitor)
MetaMonitor *monitor,
GList *monitors)
{
gboolean match = FALSE;
char **edid;
@ -402,10 +426,10 @@ match_config (MetaMapperInputInfo *info,
edid = g_settings_get_strv (info->settings, "output");
n_values = g_strv_length (edid);
if (n_values != 3)
if (n_values < 3)
{
g_warning ("EDID configuration for device '%s' "
"is incorrect, must have 3 values",
"is incorrect, must have at least 3 values",
clutter_input_device_get_device_name (info->device));
goto out;
}
@ -417,6 +441,17 @@ match_config (MetaMapperInputInfo *info,
g_strcmp0 (meta_monitor_get_product (monitor), edid[1]) == 0 &&
g_strcmp0 (meta_monitor_get_serial (monitor), edid[2]) == 0);
if (match && n_values >= 4 && monitor_has_twin (monitor, monitors))
{
/* The 4th value if set contains the ID (e.g. HDMI-1), use it
* for disambiguation if multiple monitors with the same
* EDID data are found.
*/
MetaOutput *output;
output = meta_monitor_get_main_output (monitor);
match = g_strcmp0 (meta_output_get_name (output), edid[3]) == 0;
}
out:
g_strfreev (edid);
@ -482,7 +517,7 @@ guess_candidates (MetaInputMapper *mapper,
if (automatic && builtin && match_builtin (mapper, l->data))
match.score |= 1 << META_MATCH_IS_BUILTIN;
if (!automatic && match_config (input, l->data))
if (!automatic && match_config (input, l->data, monitors))
match.score |= 1 << META_MATCH_CONFIG;
if (match.score > 0)