diff options
author | wm4 <wm4@nowhere> | 2017-06-16 21:31:13 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2017-06-16 21:31:24 +0200 |
commit | 986e10901dad89eed89ae79d2bc0f1634d1cacbd (patch) | |
tree | 20f32a618232c746907d9a9796cced271754df23 | |
parent | b7d9b7268680b1f65f73f1d60546570d0693211a (diff) | |
download | mpv-986e10901dad89eed89ae79d2bc0f1634d1cacbd.tar.bz2 mpv-986e10901dad89eed89ae79d2bc0f1634d1cacbd.tar.xz |
command: avoid going through prop->opt bridge from opt->prop bridge
The option->property bridge can't (and shouldn't) preserve option flags.
This is a problem if the flags are actually used by the option
implementation, beyond calling m_config_mark_co_flags().
This was true so far, but b8193e40719 changed this. Now setting the
--profile option (usually from a config file or as recursive profile)
can have side-effects that depend on the flags contents. Solve this by
avoiding going through the "double bridge" altogether.
This fixes a regression if an auto-profile is active, and the user
specifies an option on the command line that is supposed to override an
item in a profile recursively referenced by the auto-profile. The
command line option will not override it, because the auto-profile is
set later, and during application of the auto-profile, the
M_SETOPT_PRESERVE_CMDLINE flag gets lost.
Having to add something to m_property is not nice, and I'll probbaly
regret later. On the other hand, there is a chance that this helps
towards true option/property unification.
-rw-r--r-- | options/m_property.h | 2 | ||||
-rw-r--r-- | player/command.c | 11 |
2 files changed, 13 insertions, 0 deletions
diff --git a/options/m_property.h b/options/m_property.h index 9a1e3295dc..0e2d13c7e2 100644 --- a/options/m_property.h +++ b/options/m_property.h @@ -132,6 +132,8 @@ struct m_property { // returns: one of enum mp_property_return int (*call)(void *ctx, struct m_property *prop, int action, void *arg); void *priv; + // Special-case: mark options for which command.c uses the option-bridge + bool is_option; }; struct m_property *m_property_list_find(const struct m_property *list, diff --git a/player/command.c b/player/command.c index cdef20d7a3..9839185ac5 100644 --- a/player/command.c +++ b/player/command.c @@ -348,6 +348,7 @@ static char *format_delay(double time) int mp_on_set_option(void *ctx, struct m_config_option *co, void *data, int flags) { struct MPContext *mpctx = ctx; + struct command_ctx *cmd = mpctx->command_ctx; // Normalize "vf*" to "vf" const char *name = co->name; @@ -358,6 +359,14 @@ int mp_on_set_option(void *ctx, struct m_config_option *co, void *data, int flag name = tmp; } + // Skip going through mp_property_generic_option (typically), because the + // property implementation is trivial, and can break some obscure features + // like --profile and --include if non-trivial flags are involved (which + // the bridge would drop). + struct m_property *prop = m_property_list_find(cmd->properties, name); + if (prop && prop->is_option) + goto direct_option; + struct m_option type = {0}; int r = mp_property_do_silent(name, M_PROPERTY_GET_TYPE, &type, mpctx); @@ -5680,11 +5689,13 @@ void command_init(struct MPContext *mpctx) .call = co->opt->deprecation_message ? mp_property_deprecated_alias : mp_property_alias, .priv = (void *)alias, + .is_option = true, }; } else { prop = (struct m_property){ .name = co->name, .call = mp_property_generic_option, + .is_option = true, }; bstr bname = bstr0(prop.name); |