summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2017-09-28 11:34:33 -0400
committerJonas Ådahl <jadahl@gmail.com>2017-10-02 15:34:24 -0400
commitea4dbd14bcc2d814479f5fe3399c5075e251c6a7 (patch)
treebe4b3d8d08604e36be33fd1ea8a9e4e4d0148b88
parent838df4b00b775b15dc17f8a590ff5bed38bda13c (diff)
downloadmutter-ea4dbd14bcc2d814479f5fe3399c5075e251c6a7.tar.gz
monitor-config: Keep track of disabled monitors for stored configs
When saving and restoring monitor configurations, we must take disabled monitors into account, as otherwise one cannot store/restore a configuration where one or more monitors are explicitly disabled. Make this possible by adding a <disabled> element to the <configure> element which lists the monitors that are explicitly disabled. These ones are included when generating the configuration key, meaning they'll be picked up correctly. https://bugzilla.gnome.org/show_bug.cgi?id=787629
-rw-r--r--src/backends/meta-monitor-config-manager.c135
-rw-r--r--src/backends/meta-monitor-config-manager.h17
-rw-r--r--src/backends/meta-monitor-config-migration.c38
-rw-r--r--src/backends/meta-monitor-config-store.c70
-rw-r--r--src/backends/meta-monitor-manager.c4
5 files changed, 241 insertions, 23 deletions
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index d40c2e0c4..cdc9fb775 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -612,7 +612,9 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
x += logical_monitor_config->layout.width;
}
- return meta_monitors_config_new (logical_monitor_configs, layout_mode,
+ return meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
+ layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
}
@@ -641,7 +643,9 @@ meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_ma
logical_monitor_configs = g_list_append (NULL,
primary_logical_monitor_config);
- return meta_monitors_config_new (logical_monitor_configs, layout_mode,
+ return meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
+ layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
}
@@ -717,7 +721,9 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
if (!logical_monitor_configs)
return NULL;
- return meta_monitors_config_new (logical_monitor_configs, layout_mode,
+ return meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
+ layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
}
@@ -726,8 +732,11 @@ create_for_builtin_display_rotation (MetaMonitorConfigManager *config_manager,
gboolean rotate,
MetaMonitorTransform transform)
{
+ MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
MetaLogicalMonitorConfig *logical_monitor_config;
MetaLogicalMonitorConfig *current_logical_monitor_config;
+ GList *logical_monitor_configs;
+ MetaLogicalMonitorLayoutMode layout_mode;
MetaMonitorConfig *monitor_config;
MetaMonitorConfig *current_monitor_config;
@@ -772,8 +781,11 @@ create_for_builtin_display_rotation (MetaMonitorConfigManager *config_manager,
logical_monitor_config->layout.height = temp;
}
- return meta_monitors_config_new (g_list_append (NULL, logical_monitor_config),
- config_manager->current_config->layout_mode,
+ logical_monitor_configs = g_list_append (NULL, logical_monitor_config);
+ layout_mode = config_manager->current_config->layout_mode;
+ return meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
+ layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
}
@@ -796,6 +808,7 @@ create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager)
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
MetaLogicalMonitorLayoutMode layout_mode;
MetaLogicalMonitorConfig *logical_monitor_config = NULL;
+ GList *logical_monitor_configs;
GList *monitor_configs = NULL;
gint common_mode_w = 0, common_mode_h = 0;
float best_scale = 1.0;
@@ -893,8 +906,10 @@ create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager)
.monitor_configs = monitor_configs
};
+ logical_monitor_configs = g_list_append (NULL, logical_monitor_config);
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
- return meta_monitors_config_new (g_list_append (NULL, logical_monitor_config),
+ return meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
}
@@ -935,7 +950,9 @@ create_for_switch_config_external (MetaMonitorConfigManager *config_manager)
x += logical_monitor_config->layout.width;
}
- return meta_monitors_config_new (logical_monitor_configs, layout_mode,
+ return meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
+ layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
}
@@ -964,7 +981,9 @@ create_for_switch_config_builtin (MetaMonitorConfigManager *config_manager)
logical_monitor_configs = g_list_append (NULL,
primary_logical_monitor_config);
- return meta_monitors_config_new (logical_monitor_configs, layout_mode,
+ return meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
+ layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
}
@@ -1087,7 +1106,8 @@ meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor_conf
}
static MetaMonitorsConfigKey *
-meta_monitors_config_key_new (GList *logical_monitor_configs)
+meta_monitors_config_key_new (GList *logical_monitor_configs,
+ GList *disabled_monitor_specs)
{
MetaMonitorsConfigKey *config_key;
GList *monitor_specs;
@@ -1109,6 +1129,14 @@ meta_monitors_config_key_new (GList *logical_monitor_configs)
}
}
+ for (l = disabled_monitor_specs; l; l = l->next)
+ {
+ MetaMonitorSpec *monitor_spec = l->data;
+
+ monitor_spec = meta_monitor_spec_clone (monitor_spec);
+ monitor_specs = g_list_prepend (monitor_specs, monitor_spec);
+ }
+
monitor_specs = g_list_sort (monitor_specs,
(GCompareFunc) meta_monitor_spec_compare);
@@ -1175,21 +1203,56 @@ meta_monitors_config_key_equal (gconstpointer data_a,
}
MetaMonitorsConfig *
-meta_monitors_config_new (GList *logical_monitor_configs,
- MetaLogicalMonitorLayoutMode layout_mode,
- MetaMonitorsConfigFlag flags)
+meta_monitors_config_new_full (GList *logical_monitor_configs,
+ GList *disabled_monitor_specs,
+ MetaLogicalMonitorLayoutMode layout_mode,
+ MetaMonitorsConfigFlag flags)
{
MetaMonitorsConfig *config;
config = g_object_new (META_TYPE_MONITORS_CONFIG, NULL);
config->logical_monitor_configs = logical_monitor_configs;
- config->key = meta_monitors_config_key_new (logical_monitor_configs);
+ config->disabled_monitor_specs = disabled_monitor_specs;
+ config->key = meta_monitors_config_key_new (logical_monitor_configs,
+ disabled_monitor_specs);
config->layout_mode = layout_mode;
config->flags = flags;
return config;
}
+MetaMonitorsConfig *
+meta_monitors_config_new (MetaMonitorManager *monitor_manager,
+ GList *logical_monitor_configs,
+ MetaLogicalMonitorLayoutMode layout_mode,
+ MetaMonitorsConfigFlag flags)
+{
+ GList *disabled_monitor_specs = NULL;
+ GList *monitors;
+ GList *l;
+
+ monitors = meta_monitor_manager_get_monitors (monitor_manager);
+ for (l = monitors; l; l = l->next)
+ {
+ MetaMonitor *monitor = l->data;
+ MetaMonitorSpec *monitor_spec;
+
+ monitor_spec = meta_monitor_get_spec (monitor);
+ if (meta_logical_monitor_configs_have_monitor (logical_monitor_configs,
+ monitor_spec))
+ continue;
+
+ disabled_monitor_specs =
+ g_list_prepend (disabled_monitor_specs,
+ meta_monitor_spec_clone (monitor_spec));
+ }
+
+ return meta_monitors_config_new_full (logical_monitor_configs,
+ disabled_monitor_specs,
+ layout_mode,
+ flags);
+}
+
static void
meta_monitors_config_finalize (GObject *object)
{
@@ -1198,6 +1261,8 @@ meta_monitors_config_finalize (GObject *object)
meta_monitors_config_key_free (config->key);
g_list_free_full (config->logical_monitor_configs,
(GDestroyNotify) meta_logical_monitor_config_free);
+ g_list_free_full (config->disabled_monitor_specs,
+ (GDestroyNotify) meta_monitor_spec_free);
G_OBJECT_CLASS (meta_monitors_config_parent_class)->finalize (object);
}
@@ -1376,6 +1441,38 @@ has_adjecent_neighbour (MetaMonitorsConfig *config,
}
gboolean
+meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs,
+ MetaMonitorSpec *monitor_spec)
+{
+ GList *l;
+
+ for (l = logical_monitor_configs; l; l = l->next)
+ {
+ MetaLogicalMonitorConfig *logical_monitor_config = l->data;
+ GList *k;
+
+ for (k = logical_monitor_config->monitor_configs; k; k = k->next)
+ {
+ MetaMonitorConfig *monitor_config = k->data;
+
+ if (meta_monitor_spec_equals (monitor_spec,
+ monitor_config->monitor_spec))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static gboolean
+meta_monitors_config_is_monitor_enabled (MetaMonitorsConfig *config,
+ MetaMonitorSpec *monitor_spec)
+{
+ return meta_logical_monitor_configs_have_monitor (config->logical_monitor_configs,
+ monitor_spec);
+}
+
+gboolean
meta_verify_monitors_config (MetaMonitorsConfig *config,
MetaMonitorManager *monitor_manager,
GError **error)
@@ -1456,6 +1553,18 @@ meta_verify_monitors_config (MetaMonitorsConfig *config,
g_list_free (region);
+ for (l = config->disabled_monitor_specs; l; l = l->next)
+ {
+ MetaMonitorSpec *monitor_spec = l->data;
+
+ if (meta_monitors_config_is_monitor_enabled (config, monitor_spec))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Assigned monitor explicitly disabled");
+ return FALSE;
+ }
+ }
+
if (min_x != 0 || min_y != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index 04501eebd..b99cdaba2 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -64,6 +64,8 @@ struct _MetaMonitorsConfig
MetaMonitorsConfigKey *key;
GList *logical_monitor_configs;
+ GList *disabled_monitor_specs;
+
MetaMonitorsConfigFlag flags;
MetaLogicalMonitorLayoutMode layout_mode;
@@ -112,9 +114,15 @@ void meta_monitor_config_manager_clear_history (MetaMonitorConfigManager *config
void meta_monitor_config_manager_save_current (MetaMonitorConfigManager *config_manager);
-MetaMonitorsConfig * meta_monitors_config_new (GList *logical_monitor_configs,
- MetaLogicalMonitorLayoutMode layout_mode,
- MetaMonitorsConfigFlag flags);
+MetaMonitorsConfig * meta_monitors_config_new_full (GList *logical_monitor_configs,
+ GList *disabled_monitors,
+ MetaLogicalMonitorLayoutMode layout_mode,
+ MetaMonitorsConfigFlag flags);
+
+MetaMonitorsConfig * meta_monitors_config_new (MetaMonitorManager *monitor_manager,
+ GList *logical_monitor_configs,
+ MetaLogicalMonitorLayoutMode layout_mode,
+ MetaMonitorsConfigFlag flags);
unsigned int meta_monitors_config_key_hash (gconstpointer config_key);
@@ -127,6 +135,9 @@ void meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor
void meta_monitor_config_free (MetaMonitorConfig *monitor_config);
+gboolean meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs,
+ MetaMonitorSpec *monitor_spec);
+
gboolean meta_verify_monitor_mode_spec (MetaMonitorModeSpec *monitor_mode_spec,
GError **error);
diff --git a/src/backends/meta-monitor-config-migration.c b/src/backends/meta-monitor-config-migration.c
index 6164d9fc0..c862168a2 100644
--- a/src/backends/meta-monitor-config-migration.c
+++ b/src/backends/meta-monitor-config-migration.c
@@ -1056,6 +1056,35 @@ generate_config_name (MetaLegacyMonitorsConfig *config)
return key_name;
}
+static GList *
+find_disabled_monitor_specs (MetaLegacyMonitorsConfig *legacy_config)
+{
+ GList *disabled_monitors = NULL;
+ unsigned int i;
+
+ for (i = 0; i < legacy_config->n_outputs; i++)
+ {
+ MetaOutputKey *output_key = &legacy_config->keys[i];
+ MetaOutputConfig *output_config = &legacy_config->outputs[i];
+ MetaMonitorSpec *monitor_spec;
+
+ if (output_config->enabled)
+ continue;
+
+ monitor_spec = g_new0 (MetaMonitorSpec, 1);
+ *monitor_spec = (MetaMonitorSpec) {
+ .connector = output_key->connector,
+ .vendor = output_key->vendor,
+ .product = output_key->product,
+ .serial = output_key->serial
+ };
+
+ disabled_monitors = g_list_prepend (disabled_monitors, monitor_spec);
+ }
+
+ return disabled_monitors;
+}
+
static void
migrate_config (gpointer key,
gpointer value,
@@ -1068,6 +1097,7 @@ migrate_config (gpointer key,
GList *logical_monitor_configs;
MetaLogicalMonitorLayoutMode layout_mode;
GError *error = NULL;
+ GList *disabled_monitor_specs;
MetaMonitorsConfig *config;
logical_monitor_configs = derive_logical_monitor_configs (legacy_config,
@@ -1083,9 +1113,13 @@ migrate_config (gpointer key,
return;
}
+ disabled_monitor_specs = find_disabled_monitor_specs (legacy_config);
+
layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
- config = meta_monitors_config_new (logical_monitor_configs, layout_mode,
- META_MONITORS_CONFIG_FLAG_MIGRATED);
+ config = meta_monitors_config_new_full (logical_monitor_configs,
+ disabled_monitor_specs,
+ layout_mode,
+ META_MONITORS_CONFIG_FLAG_MIGRATED);
if (!meta_verify_monitors_config (config, monitor_manager, &error))
{
g_autofree char *config_name = NULL;
diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c
index 351cb65a7..ed0ce34f0 100644
--- a/src/backends/meta-monitor-config-store.c
+++ b/src/backends/meta-monitor-config-store.c
@@ -83,6 +83,14 @@
* </monitor>
* <presentation>yes</presentation>
* </logicalmonitor>
+ * <disabled>
+ * <monitorspec>
+ * <connector>LVDS3</connector>
+ * <vendor>Vendor C</vendor>
+ * <product>Product C</product>
+ * <serial>Serial C</serial>
+ * </monitorspec>
+ * </disabled>
* </configuration>
* </monitors>
*
@@ -151,7 +159,8 @@ typedef enum
STATE_MONITOR_MODE_HEIGHT,
STATE_MONITOR_MODE_RATE,
STATE_MONITOR_MODE_FLAG,
- STATE_MONITOR_UNDERSCANNING
+ STATE_MONITOR_UNDERSCANNING,
+ STATE_DISABLED,
} ParserState;
typedef struct
@@ -169,6 +178,7 @@ typedef struct
MetaMonitorModeSpec *current_monitor_mode_spec;
MetaMonitorConfig *current_monitor_config;
MetaLogicalMonitorConfig *current_logical_monitor_config;
+ GList *current_disabled_monitor_specs;
} ConfigParser;
G_DEFINE_TYPE (MetaMonitorConfigStore, meta_monitor_config_store,
@@ -256,6 +266,10 @@ handle_start_element (GMarkupParseContext *context,
parser->state = STATE_MIGRATED;
}
+ else if (g_str_equal (element_name, "disabled"))
+ {
+ parser->state = STATE_DISABLED;
+ }
else
{
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
@@ -458,6 +472,22 @@ handle_start_element (GMarkupParseContext *context,
"Invalid element '%s' under underscanning", element_name);
return;
}
+
+ case STATE_DISABLED:
+ {
+ if (!g_str_equal (element_name, "monitorspec"))
+ {
+ g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ "Invalid element '%s' under disabled", element_name);
+ return;
+ }
+
+ parser->current_monitor_spec = g_new0 (MetaMonitorSpec, 1);
+ parser->monitor_spec_parent_state = STATE_DISABLED;
+ parser->state = STATE_MONITOR_SPEC;
+
+ return;
+ }
}
}
@@ -528,6 +558,15 @@ finish_monitor_spec (ConfigParser *parser)
return;
}
+ case STATE_DISABLED:
+ {
+ parser->current_disabled_monitor_specs =
+ g_list_prepend (parser->current_disabled_monitor_specs,
+ parser->current_monitor_spec);
+ parser->current_monitor_spec = NULL;
+
+ return;
+ }
default:
g_assert_not_reached ();
@@ -684,6 +723,14 @@ handle_end_element (GMarkupParseContext *context,
return;
}
+ case STATE_DISABLED:
+ {
+ g_assert (g_str_equal (element_name, "disabled"));
+
+ parser->state = STATE_CONFIGURATION;
+ return;
+ }
+
case STATE_CONFIGURATION:
{
MetaMonitorConfigStore *store = parser->config_store;
@@ -720,11 +767,13 @@ handle_end_element (GMarkupParseContext *context,
config_flags |= META_MONITORS_CONFIG_FLAG_MIGRATED;
config =
- meta_monitors_config_new (parser->current_logical_monitor_configs,
- layout_mode,
- config_flags);
+ meta_monitors_config_new_full (parser->current_logical_monitor_configs,
+ parser->current_disabled_monitor_specs,
+ layout_mode,
+ config_flags);
parser->current_logical_monitor_configs = NULL;
+ parser->current_disabled_monitor_specs = NULL;
if (!meta_verify_monitors_config (config, store->monitor_manager,
error))
@@ -868,6 +917,7 @@ handle_text (GMarkupParseContext *context,
case STATE_MONITOR_SPEC:
case STATE_MONITOR_MODE:
case STATE_TRANSFORM:
+ case STATE_DISABLED:
{
if (!is_all_whitespace (text, text_len))
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
@@ -1236,6 +1286,18 @@ generate_config_xml (MetaMonitorConfigStore *config_store)
append_logical_monitor_xml (buffer, config, logical_monitor_config);
}
+ if (config->disabled_monitor_specs)
+ {
+ g_string_append (buffer, " <disabled>\n");
+ for (l = config->disabled_monitor_specs; l; l = l->next)
+ {
+ MetaMonitorSpec *monitor_spec = l->data;
+
+ append_monitor_spec (buffer, monitor_spec, " ");
+ }
+ g_string_append (buffer, " </disabled>\n");
+ }
+
g_string_append (buffer, " </configuration>\n");
}
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 3e0d980fb..2caec1b57 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -1934,7 +1934,9 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
logical_monitor_config);
}
- config = meta_monitors_config_new (logical_monitor_configs, layout_mode,
+ config = meta_monitors_config_new (manager,
+ logical_monitor_configs,
+ layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
if (!meta_verify_monitors_config (config, manager, &error))
{