diff --git a/input/input.c b/input/input.c index 90cd439779..da1f85b829 100644 --- a/input/input.c +++ b/input/input.c @@ -73,6 +73,7 @@ struct cmd_bind { }; struct cmd_bind_section { + char *owner; struct cmd_bind *binds; int num_binds; char *section; @@ -1009,13 +1010,19 @@ static void remove_binds(struct cmd_bind_section *bs, bool builtin) } void mp_input_define_section(struct input_ctx *ictx, char *name, char *location, - char *contents, bool builtin) + char *contents, bool builtin, char *owner) { if (!name || !name[0]) return; // parse_config() changes semantics with restrict_section==empty input_lock(ictx); // Delete: struct cmd_bind_section *bs = get_bind_section(ictx, bstr0(name)); + if ((!bs->owner || (owner && strcmp(bs->owner, owner) != 0)) && + strcmp(bs->section, "default") != 0) + { + talloc_free(bs->owner); + bs->owner = talloc_strdup(bs, owner); + } remove_binds(bs, builtin); if (contents && contents[0]) { // Redefine: @@ -1027,6 +1034,21 @@ void mp_input_define_section(struct input_ctx *ictx, char *name, char *location, input_unlock(ictx); } +void mp_input_remove_sections_by_owner(struct input_ctx *ictx, char *owner) +{ + input_lock(ictx); + struct cmd_bind_section *bs = ictx->cmd_bind_sections; + while (bs) { + if (bs->owner && owner && strcmp(bs->owner, owner) == 0) { + mp_input_disable_section(ictx, bs->section); + remove_binds(bs, false); + remove_binds(bs, true); + } + bs = bs->next; + } + input_unlock(ictx); +} + static bool bind_matches_key(struct cmd_bind *bind, int num_keys, const int *keys) { if (bind->num_keys != num_keys) diff --git a/input/input.h b/input/input.h index cc523efc62..16262efbe5 100644 --- a/input/input.h +++ b/input/input.h @@ -196,9 +196,13 @@ void mp_input_disable_all_sections(struct input_ctx *ictx); // builtin: create as builtin section; this means if the user defines bindings // using "{name}", they won't be ignored or overwritten - instead, // they are preferred to the bindings defined with this call +// owner: string ID of the client which defined this, or NULL // If the section already exists, its bindings are removed and replaced. void mp_input_define_section(struct input_ctx *ictx, char *name, char *location, - char *contents, bool builtin); + char *contents, bool builtin, char *owner); + +// Remove all sections that have been defined by the given owner. +void mp_input_remove_sections_by_owner(struct input_ctx *ictx, char *owner); // Define where on the screen the named input section should receive. // Setting a rectangle of size 0 unsets the mouse area. diff --git a/player/client.c b/player/client.c index f95ad372b5..51cc0c9dac 100644 --- a/player/client.c +++ b/player/client.c @@ -416,6 +416,8 @@ void mpv_detach_destroy(mpv_handle *ctx) ctx->num_events--; } mp_msg_log_buffer_destroy(ctx->messages); + osd_set_external(ctx->mpctx->osd, ctx, 0, 0, NULL); + mp_input_remove_sections_by_owner(ctx->mpctx->input, ctx->name); pthread_cond_destroy(&ctx->wakeup); pthread_mutex_destroy(&ctx->wakeup_lock); pthread_mutex_destroy(&ctx->lock); @@ -759,6 +761,9 @@ mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout) { mpv_event *event = ctx->cur_event; + if (!ctx->mpctx->initialized) + return NULL; + pthread_mutex_lock(&ctx->lock); if (!ctx->fuzzy_initialized) diff --git a/player/command.c b/player/command.c index d5d95602a6..721a79df83 100644 --- a/player/command.c +++ b/player/command.c @@ -5282,7 +5282,8 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re case MP_CMD_DEFINE_INPUT_SECTION: mp_input_define_section(mpctx->input, cmd->args[0].v.s, "", - cmd->args[1].v.s, !!cmd->args[2].v.i); + cmd->args[1].v.s, !!cmd->args[2].v.i, + cmd->sender); break; case MP_CMD_AB_LOOP: { diff --git a/player/lua.c b/player/lua.c index 964ba7c07a..1c3d526349 100644 --- a/player/lua.c +++ b/player/lua.c @@ -391,7 +391,6 @@ static int load_lua(struct mpv_handle *client, const char *fname) r = 0; error_out: - osd_set_external(ctx->mpctx->osd, client, 0, 0, NULL); // remove overlay mp_resume_all(client); if (ctx->state) lua_close(ctx->state);