Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

command: make script-binding command scalable #15316

Merged
merged 9 commits into from
Nov 27, 2024
1 change: 1 addition & 0 deletions DOCS/interface-changes/script-binding-scalable.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
make `script-binding` command scalable; add `nonscalable` command prefix to restore the old behavior
28 changes: 24 additions & 4 deletions DOCS/man/input.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ Comments on some symbolic names:
``MBTN*`` are aliases for ``MOUSE_BTN*``.

``WHEEL_*``
Mouse wheels (typically).
Mouse wheels and touch pads (typically).

These key are scalable when used with scalable commands if the underlying
device supports high-resolution scrolling (e.g. touch pads).

``AXIS_*``
Deprecated aliases for ``WHEEL_*``.
Expand Down Expand Up @@ -293,6 +296,9 @@ Playback Control
3rd parameter (essentially using a space instead of ``+``). The 3rd
parameter is still parsed, but is considered deprecated.

This is a scalable command. See the documentation of ``nonscalable`` input
command prefix in `Input Command Prefixes`_ for details.

``revert-seek [<flags>]``
Undoes the ``seek`` command, and some other commands that seek (but not
necessarily all of them). Calling this command once will jump to the
Expand Down Expand Up @@ -372,6 +378,9 @@ Property Manipulation
Add the given value to the property or option. On overflow or underflow,
clamp the property to the maximum. If ``<value>`` is omitted, assume ``1``.

This is a scalable command. See the documentation of ``nonscalable`` input
command prefix in `Input Command Prefixes`_ for details.

``multiply <name> <value>``
Similar to ``add``, but multiplies the property or option with the numeric
value.
Expand All @@ -386,6 +395,9 @@ Property Manipulation
Currently properties with continuous values are repeatable by default (like
``volume``), while discrete values are not (like ``osd-level``).

This is a scalable command. See the documentation of ``nonscalable`` input
command prefix in `Input Command Prefixes`_ for details.

``cycle-values [<"!reverse">] <property> <value1> [<value2> [...]]``
Cycle through a list of values. Each invocation of the command will set the
given property to the next value in the list. The command will use the
Expand Down Expand Up @@ -1261,11 +1273,12 @@ Scripting Commands
This command has a variable number of arguments, and cannot be used with
named arguments.

``script-binding <name>``
``script-binding <name> [<arg>]``
Invoke a script-provided key binding. This can be used to remap key
bindings provided by external Lua scripts.

The argument is the name of the binding.
``<name>`` is the name of the binding. ``<arg>`` is a user-provided
arbitrary string which can be used to provide extra information.

It can optionally be prefixed with the name of the script, using ``/`` as
separator, e.g. ``script-binding scriptname/bindingname``. Note that script
Expand All @@ -1274,13 +1287,17 @@ Scripting Commands
For completeness, here is how this command works internally. The details
could change any time. On any matching key event, ``script-message-to``
or ``script-message`` is called (depending on whether the script name is
included), with the following arguments:
included), with the following arguments in string format:

1. The string ``key-binding``.
2. The name of the binding (as established above).
3. The key state as string (see below).
4. The key name (since mpv 0.15.0).
5. The text the key would produce, or empty string if not applicable.
6. The scale of the key, such as the ones produced by ``WHEEL_*`` keys.
The scale is 1 if the key is nonscalable.
7. The user-provided string ``<arg>``, or empty string if the argument is
not used.

The 5th argument is only set if no modifiers are present (using the shift
key with a letter is normally not emitted as having a modifier, and results
Expand All @@ -1300,6 +1317,9 @@ Scripting Commands
Future versions can add more arguments and more key state characters to
support more input peculiarities.

This is a scalable command. See the documentation of ``nonscalable`` input
command prefix in `Input Command Prefixes`_ for details.

``load-script <filename>``
Load a script, similar to the ``--script`` option. Whether this waits for
the script to finish initialization or not changed multiple times, and the
Expand Down
20 changes: 18 additions & 2 deletions DOCS/man/lua.rst
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,20 @@ The ``mp`` module is preloaded, although it can be loaded manually with
or pass the ``fn`` argument in place of the name. The latter is not
recommended and is handled for compatibility only.)

The last argument is used for optional flags. This is a table, which can
have the following entries:
The ``flags`` argument is used for optional parameters. This is a table,
which can have the following entries:

``repeatable``
If set to ``true``, enables key repeat for this specific binding.
This option only makes sense when ``complex`` is not set to ``true``.

``scalable``
If set to ``true``, enables key scaling for this specific binding.
This option only makes sense when ``complex`` is set to ``true``.
Note that this has no effect if the key binding is invoked by
``script-binding`` command, where the scalability of the command
takes precedence.

``complex``
If set to ``true``, then ``fn`` is called on key down, repeat and up
events, with the first argument being a table. This table has the
Expand Down Expand Up @@ -350,6 +357,15 @@ The ``mp`` module is preloaded, although it can be loaded manually with
description of ``script-binding`` command for details (this
field is equivalent to the 5th argument).

``scale``
The scale of the key, such as the ones produced by ``WHEEL_*``
keys. The scale is 1 if the key is nonscalable.

``arg``
User-provided string in the ``arg`` argument in the
``script-binding`` command if the key binding is invoked
by that command.

Internally, key bindings are dispatched via the ``script-message-to`` or
``script-binding`` input commands and ``mp.register_script_message``.

Expand Down
4 changes: 2 additions & 2 deletions input/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ struct mp_cmd_def {
bool allow_auto_repeat; // react to repeated key events
bool on_updown; // always emit it on both up and down key events
bool vararg; // last argument can be given 0 to multiple times
bool scalable;
bool is_ignore;
bool scalable; // command called with scale for high resolution input
bool is_ignore; // used by ignore command only, avoids queuing commands
bool is_noisy; // reduce log level
bool default_async; // default to MP_ASYNC flag if none set by user
// If you set this, handler() must ensure mp_cmd_ctx_complete() is called
Expand Down
43 changes: 31 additions & 12 deletions player/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -6429,17 +6429,31 @@ static void cmd_script_binding(void *p)
incmd->canceled ? 'c' : '-'};
if (incmd->is_up_down)
state[0] = incmd->repeated ? 'r' : (incmd->is_up ? 'u' : 'd');
event.num_args = 5;
event.args = (const char*[5]){"key-binding", name, state,
incmd->key_name ? incmd->key_name : "",
incmd->key_text ? incmd->key_text : ""};
if (mp_client_send_event_dup(mpctx, target,
MPV_EVENT_CLIENT_MESSAGE, &event) < 0)
{
MP_VERBOSE(mpctx, "Can't find script '%s' when handling input.\n",
target ? target : "-");
cmd->success = false;

double scale = 1;
int scale_units = incmd->scale_units;
if (mp_input_is_scalable_cmd(incmd)) {
scale = incmd->scale;
scale_units = 1;
}
char *scale_s = mp_format_double(NULL, scale, 6, false, false, false);

for (int i = 0; i < scale_units; i++) {
event.num_args = 7;
event.args = (const char*[7]){"key-binding", name, state,
incmd->key_name ? incmd->key_name : "",
incmd->key_text ? incmd->key_text : "",
scale_s, cmd->args[1].v.s};
if (mp_client_send_event_dup(mpctx, target,
MPV_EVENT_CLIENT_MESSAGE, &event) < 0)
{
MP_VERBOSE(mpctx, "Can't find script '%s' when handling input.\n",
target ? target : "-");
cmd->success = false;
break;
}
}
talloc_free(scale_s);
}

static void cmd_script_message_to(void *p)
Expand Down Expand Up @@ -7142,8 +7156,13 @@ const struct mp_cmd_def mp_cmds[] = {

{ "ao-reload", cmd_ao_reload },

{ "script-binding", cmd_script_binding, { {"name", OPT_STRING(v.s)} },
.allow_auto_repeat = true, .on_updown = true},
{ "script-binding", cmd_script_binding,
{
{"name", OPT_STRING(v.s)},
{"arg", OPT_STRING(v.s), OPTDEF_STR(""),
.flags = MP_CMD_OPT_ARG},
},
.allow_auto_repeat = true, .on_updown = true, .scalable = true },

{ "script-message", cmd_script_message, { {"args", OPT_STRING(v.s)} },
.vararg = true },
Expand Down
13 changes: 8 additions & 5 deletions player/javascript/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,10 @@ mp.get_osd_margins = function get_osd_margins() {
// {cb: fn, forced: bool, maybe input: str, repeatable: bool, complex: bool}
var binds = new_cache();

function dispatch_key_binding(name, state, key_name, key_text) {
function dispatch_key_binding(name, state, key_name, key_text, scale, arg) {
var cb = binds[name] ? binds[name].cb : false;
if (cb) // "script-binding [<script_name>/]<name>" command was invoked
cb(state, key_name, key_text);
cb(state, key_name, key_text, scale, arg);
}

var binds_tid = 0; // flush timer id. actual id's are always true-thy
Expand Down Expand Up @@ -307,13 +307,15 @@ function add_binding(forced, key, name, fn, opts) {
fn({event: "press", is_mouse: false});
});
var KEY_STATES = { u: "up", d: "down", r: "repeat", p: "press" };
key_data.cb = function key_cb(state, key_name, key_text) {
key_data.cb = function key_cb(state, key_name, key_text, scale, arg) {
fn({
event: KEY_STATES[state[0]] || "unknown",
is_mouse: state[1] == "m",
canceled: state[2] == "c",
key_name: key_name || undefined,
key_text: key_text || undefined
key_text: key_text || undefined,
scale: scale ? parseFloat(scale) : 1.0,
arg: arg,
});
}
} else {
Expand All @@ -331,8 +333,9 @@ function add_binding(forced, key, name, fn, opts) {
}
}

var prefix = key_data.scalable ? "" : " nonscalable";
if (key)
key_data.input = key + " script-binding " + mp.script_name + "/" + name;
key_data.input = key + prefix + " script-binding " + mp.script_name + "/" + name;
binds[name] = key_data; // used by user and/or our (key) script-binding
sched_bindings_flush();
}
Expand Down
12 changes: 8 additions & 4 deletions player/lua/defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ local function reserve_binding()
return "__keybinding" .. tostring(message_id)
end

local function dispatch_key_binding(name, state, key_name, key_text)
local function dispatch_key_binding(name, state, key_name, key_text, scale, arg)
local fn = dispatch_key_bindings[name]
if fn then
fn(name, state, key_name, key_text)
fn(name, state, key_name, key_text, scale, arg)
end
end

Expand Down Expand Up @@ -186,6 +186,7 @@ local function add_binding(attrs, key, name, fn, rp)
name = reserve_binding()
end
local repeatable = rp == "repeatable" or rp["repeatable"]
local scalable = rp == "scalable" or rp["scalable"]
if rp["forced"] then
attrs.forced = true
end
Expand All @@ -200,7 +201,7 @@ local function add_binding(attrs, key, name, fn, rp)
["r"] = "repeat",
["p"] = "press",
}
key_cb = function(_, state, key_name, key_text)
key_cb = function(_, state, key_name, key_text, scale, arg)
if key_text == "" then
key_text = nil
end
Expand All @@ -210,6 +211,8 @@ local function add_binding(attrs, key, name, fn, rp)
canceled = state:sub(3, 3) == "c",
key_name = key_name,
key_text = key_text,
scale = tonumber(scale),
arg = arg,
})
end
msg_cb = function()
Expand All @@ -235,8 +238,9 @@ local function add_binding(attrs, key, name, fn, rp)
end
msg_cb = fn
end
local prefix = scalable and "" or " nonscalable"
if key and #key > 0 then
attrs.bind = key .. " script-binding " .. mp.script_name .. "/" .. name
attrs.bind = key .. prefix .. " script-binding " .. mp.script_name .. "/" .. name
end
attrs.name = name
-- new bindings override old ones (but do not overwrite them)
Expand Down
Loading