summaryrefslogtreecommitdiffstats
path: root/player/lua/defaults.lua
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-11-23 15:08:49 +0100
committerwm4 <wm4@nowhere>2014-11-23 15:13:35 +0100
commitae5df9be98e4193342321f30285655fcf88e7e63 (patch)
tree3f327acc1c25f3e48bebfc13c0d0061823c282e0 /player/lua/defaults.lua
parent7b47f12f8f1cae385060741e4e7f758297515225 (diff)
downloadmpv-ae5df9be98e4193342321f30285655fcf88e7e63.tar.bz2
mpv-ae5df9be98e4193342321f30285655fcf88e7e63.tar.xz
input, lua: redo input handling
Much of it is the same, but now there's the possibility to distinguish key down/up events in the Lua API.
Diffstat (limited to 'player/lua/defaults.lua')
-rw-r--r--player/lua/defaults.lua132
1 files changed, 98 insertions, 34 deletions
diff --git a/player/lua/defaults.lua b/player/lua/defaults.lua
index 4b3be12ac9..812bb71afe 100644
--- a/player/lua/defaults.lua
+++ b/player/lua/defaults.lua
@@ -22,7 +22,27 @@ function mp.get_opt(key, def)
return val
end
-local callbacks = {}
+-- For dispatching script_binding. This is sent as:
+-- script_message_to $script_name $binding_name $keystate
+-- The array is indexed by $binding_name, and has functions like this as value:
+-- fn($binding_name, $keystate)
+local dispatch_key_bindings = {}
+
+local message_id = 0
+local function reserve_binding()
+ message_id = message_id + 1
+ return "__keybinding" .. tostring(message_id)
+end
+
+local function dispatch_key_binding(name, state)
+ local fn = dispatch_key_bindings[name]
+ if fn then
+ fn(name, state)
+ end
+end
+
+-- "Old", deprecated API
+
-- each script has its own section, so that they don't conflict
local default_section = "input_dispatch_" .. mp.script_name
@@ -34,13 +54,8 @@ local default_section = "input_dispatch_" .. mp.script_name
-- Note: the bindings are not active by default. Use enable_key_bindings().
--
-- list is an array of key bindings, where each entry is an array as follow:
--- {key, callback}
--- {key, callback, callback_down}
+-- {key, callback_press, callback_down, callback_up}
-- key is the key string as used in input.conf, like "ctrl+a"
--- callback is a Lua function that is called when the key binding is used.
--- callback_down can be given too, and is called when a mouse button is pressed
--- if the key is a mouse button. (The normal callback will be for mouse button
--- down.)
--
-- callback can be a string too, in which case the following will be added like
-- an input.conf line: key .. " " .. callback
@@ -52,10 +67,29 @@ function mp.set_key_bindings(list, section, flags)
local key = entry[1]
local cb = entry[2]
local cb_down = entry[3]
- if type(cb) == "function" then
- callbacks[#callbacks + 1] = {press=cb, before_press=cb_down}
- cfg = cfg .. key .. " script_dispatch " .. mp.script_name
- .. " " .. #callbacks .. "\n"
+ local cb_up = entry[4]
+ if type(cb) ~= "string" then
+ local mangle = reserve_binding()
+ dispatch_key_bindings[mangle] = function(name, state)
+ local event = state:sub(1, 1)
+ local is_mouse = state:sub(2, 2) == "m"
+ local def = (is_mouse and "u") or "d"
+ if event == "r" then
+ event = "d"
+ end
+ if event == "p" and cb then
+ cb()
+ elseif event == "d" and cb_down then
+ cb_down()
+ elseif event == "u" and cb_up then
+ cb_up()
+ elseif event == def and cb then
+ print("whooo")
+ cb()
+ end
+ end
+ cfg = cfg .. key .. " script_binding " ..
+ mp.script_name .. "/" .. mangle .. "\n"
else
cfg = cfg .. key .. " " .. cb .. "\n"
end
@@ -75,21 +109,9 @@ function mp.set_mouse_area(x0, y0, x1, y1, section)
mp.input_set_section_mouse_area(section or default_section, x0, y0, x1, y1)
end
-local function script_dispatch(event)
- local cb = callbacks[event.arg0]
- if cb then
- if event.type == "press" and cb.press then
- cb.press()
- elseif event.type == "keyup_follows" and cb.before_press then
- cb.before_press()
- end
- end
-end
-
-- "Newer" and more convenient API
local key_bindings = {}
-local message_id = 1
local function update_key_bindings()
for i = 1, 2 do
@@ -105,9 +127,7 @@ local function update_key_bindings()
local cfg = ""
for k, v in pairs(key_bindings) do
if v.forced ~= def then
- local flags = (v.repeatable and " repeatable") or ""
- cfg = cfg .. v.key .. " " .. flags .. " script_message_to "
- .. mp.script_name .. " " .. v.name .. "\n"
+ cfg = cfg .. v.bind .. "\n"
end
end
mp.input_define_section(section, cfg, flags)
@@ -117,19 +137,61 @@ local function update_key_bindings()
end
local function add_binding(attrs, key, name, fn, rp)
+ rp = rp or ""
if (type(name) ~= "string") and (not fn) then
fn = name
- name = "message" .. tostring(message_id)
- message_id = message_id + 1
+ name = reserve_binding()
+ end
+ local bind = key
+ if rp == "repeatable" or rp["repeatable"] then
+ bind = bind .. " repeatable"
+ end
+ if rp["forced"] then
+ attrs.forced = true
+ end
+ local key_cb, msg_cb
+ if not fn then
+ fn = function() end
+ end
+ if rp["complex"] then
+ local key_states = {
+ ["u"] = "up",
+ ["d"] = "down",
+ ["r"] = "repeat",
+ ["p"] = "press",
+ }
+ key_cb = function(name, state)
+ fn({
+ event = key_states[state:sub(1, 1)] or "unknown",
+ is_mouse = state:sub(2, 2) == "m"
+ })
+ end
+ msg_cb = function()
+ fn({event = "press", is_mouse = false})
+ end
+ else
+ key_cb = function(name, state)
+ -- Emulate the same semantics as input.c uses for most bindings:
+ -- For keyboard, "down" runs the command, "up" does nothing;
+ -- for mouse, "down" does nothing, "up" runs the command.
+ -- Also, key repeat triggers the binding again.
+ local event = state:sub(1, 1)
+ local is_mouse = state:sub(2, 2) == "m"
+ if is_mouse and event == "u" then
+ fn()
+ elseif (not is_mouse) and (event == "d" or event == "r") then
+ fn()
+ end
+ end
+ msg_cb = fn
end
- attrs.repeatable = rp == "repeatable"
- attrs.key = key
+ attrs.bind = bind .. " script_binding " .. mp.script_name .. "/" .. name
attrs.name = name
key_bindings[name] = attrs
update_key_bindings()
- if fn then
- mp.register_script_message(name, fn)
- end
+ dispatch_key_bindings[name] = key_cb
+ mp.unregister_script_message(name)
+ mp.register_script_message(name, msg_cb)
end
function mp.add_key_binding(...)
@@ -322,10 +384,12 @@ end
-- default handlers
mp.register_event("shutdown", function() mp.keep_running = false end)
-mp.register_event("script-input-dispatch", script_dispatch)
mp.register_event("client-message", message_dispatch)
mp.register_event("property-change", property_change)
+-- sent by "script_binding"
+mp.register_script_message("key-binding", dispatch_key_binding)
+
mp.msg = {
log = mp.log,
fatal = function(...) return mp.log("fatal", ...) end,