mirror of
https://github.com/mpv-player/mpv
synced 2025-01-30 19:52:14 +00:00
m_option: add a force_update boolean
mpv's core does not propagate option notifications unless they actually change to the rest of the player. Most of the time, this makes perfect sense. If the user sets fullscreen multiple times, there's no reason to care about anything other than the change in state. However, there are certain options where it makes sense to always broadcast a notification even if the value doesn't change. For example, consider the window-scale case. A user may set window-scale to some value, resize the window further through some other means (such as mouse resizing) and then want to set the window-scale again to the same value as earlier. The window-scale value did not change from before so no notification is sent and nothing happens even though it is desirable and expected that it operates again. This was solved by making the current-window-scale property writable a few years ago, but actually the easier solution is to just always force the option to update on any write. For the big callback, the needed changes are trivial. Unfortunately, it requires a hot mess in order to have this work with the m_config_cache_update APIs. Spooky stuff in there, but it does send the notification now.
This commit is contained in:
parent
db6b195f3f
commit
bc28f7693d
@ -101,8 +101,10 @@ struct config_cache {
|
||||
|
||||
// Per m_config_data state for each m_config_group.
|
||||
struct m_group_data {
|
||||
char *udata; // pointer to group user option struct
|
||||
uint64_t ts; // timestamp of the data copy
|
||||
char *udata; // pointer to group user option struct
|
||||
uint64_t ts; // timestamp of the data copy
|
||||
char **force_updates; // track if any opt in group was written with force_update
|
||||
int force_updates_len;
|
||||
};
|
||||
|
||||
static void add_sub_group(struct m_config_shadow *shadow, const char *name_prefix,
|
||||
@ -588,6 +590,27 @@ struct m_config_cache *m_config_cache_alloc(void *ta_parent,
|
||||
return m_config_cache_from_shadow(ta_parent, global->config, group);
|
||||
}
|
||||
|
||||
static void clear_force_update_list(struct m_group_data *gsrc)
|
||||
{
|
||||
int index = 0;
|
||||
while (index < gsrc->force_updates_len) {
|
||||
TA_FREEP(&gsrc->force_updates[index]);
|
||||
++index;
|
||||
}
|
||||
gsrc->force_updates_len = 0;
|
||||
}
|
||||
|
||||
static bool check_force_update_list(struct m_group_data *gsrc, const char *opt_name)
|
||||
{
|
||||
int index = 0;
|
||||
while (index < gsrc->force_updates_len) {
|
||||
if (strcmp(opt_name, gsrc->force_updates[index]) == 0)
|
||||
return true;
|
||||
++index;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void update_next_option(struct m_config_cache *cache, void **p_opt)
|
||||
{
|
||||
struct config_cache *in = cache->internal;
|
||||
@ -609,16 +632,18 @@ static void update_next_option(struct m_config_cache *cache, void **p_opt)
|
||||
|
||||
while (opts && opts[in->upd_opt].name) {
|
||||
const struct m_option *opt = &opts[in->upd_opt];
|
||||
void *dsrc = gsrc->udata + opt->offset;
|
||||
void *ddst = gdst->udata + opt->offset;
|
||||
|
||||
if (opt->offset >= 0 && opt->type->size) {
|
||||
void *dsrc = gsrc->udata + opt->offset;
|
||||
void *ddst = gdst->udata + opt->offset;
|
||||
|
||||
if (!m_option_equal(opt, ddst, dsrc)) {
|
||||
bool opt_equal = m_option_equal(opt, ddst, dsrc);
|
||||
bool force_update = opt->force_update && gsrc->force_updates_len &&
|
||||
check_force_update_list(gsrc, opt->name);
|
||||
if (!opt_equal || force_update) {
|
||||
uint64_t ch = get_opt_change_mask(dst->shadow,
|
||||
in->upd_group, dst->group_index, opt);
|
||||
|
||||
if (cache->debug) {
|
||||
if (cache->debug && !opt_equal) {
|
||||
char *vdst = m_option_print(opt, ddst);
|
||||
char *vsrc = m_option_print(opt, dsrc);
|
||||
mp_warn(cache->debug, "Option '%s' changed from "
|
||||
@ -641,6 +666,8 @@ static void update_next_option(struct m_config_cache *cache, void **p_opt)
|
||||
}
|
||||
|
||||
gdst->ts = gsrc->ts;
|
||||
} else {
|
||||
clear_force_update_list(gsrc);
|
||||
}
|
||||
|
||||
in->upd_group++;
|
||||
@ -750,7 +777,8 @@ bool m_config_cache_write_opt(struct m_config_cache *cache, void *ptr)
|
||||
struct m_group_data *gsrc = m_config_gdata(in->src, group_idx);
|
||||
assert(gdst && gsrc);
|
||||
|
||||
bool changed = !m_option_equal(opt, gsrc->udata + opt->offset, ptr);
|
||||
bool changed = !m_option_equal(opt, gsrc->udata + opt->offset, ptr) ||
|
||||
opt->force_update;
|
||||
if (changed) {
|
||||
m_option_copy(opt, gsrc->udata + opt->offset, ptr);
|
||||
|
||||
@ -763,6 +791,11 @@ bool m_config_cache_write_opt(struct m_config_cache *cache, void *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
if (opt->force_update) {
|
||||
MP_TARRAY_APPEND(shadow, gsrc->force_updates, gsrc->force_updates_len,
|
||||
talloc_strdup(shadow, opt->name));
|
||||
}
|
||||
|
||||
mp_mutex_unlock(&shadow->lock);
|
||||
|
||||
return changed;
|
||||
|
@ -384,6 +384,9 @@ struct m_option {
|
||||
// See \ref OptionFlags.
|
||||
unsigned int flags;
|
||||
|
||||
// Always force an option update even if the written value does not change.
|
||||
bool force_update;
|
||||
|
||||
int offset;
|
||||
|
||||
// Most numeric types restrict the range to [min, max] if min<max (this
|
||||
|
Loading…
Reference in New Issue
Block a user