CARVIEW |
Select Language
HTTP/2 302
date: Sat, 26 Jul 2025 04:16:05 GMT
content-type: text/html; charset=utf-8
content-length: 0
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
access-control-allow-origin:
location: https://raw.githubusercontent.com/christoph-heinrich/mpv-pointer-event/master/pointer-event.lua
cache-control: no-cache
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: no-referrer-when-downgrade
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
x-github-request-id: E72C:29FD1F:14AB4E:1F3269:68845684
HTTP/2 200
cache-control: max-age=300
content-security-policy: default-src 'none'; style-src 'unsafe-inline'; sandbox
content-type: text/plain; charset=utf-8
etag: W/"f099cdf655102f48cf659c35f9cc2d5f7ee4dcdc377882702567e0d4914d7e8f"
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
x-frame-options: deny
x-xss-protection: 1; mode=block
x-github-request-id: DBDC:87891:2A59A:A0AF2:68845682
content-encoding: gzip
accept-ranges: bytes
date: Sat, 26 Jul 2025 04:16:05 GMT
via: 1.1 varnish
x-served-by: cache-bom-vanm7210072-BOM
x-cache: MISS
x-cache-hits: 0
x-timer: S1753503365.237176,VS0,VE260
vary: Authorization,Accept-Encoding
access-control-allow-origin: *
cross-origin-resource-policy: cross-origin
x-fastly-request-id: cbc519d1a46d1073b4d18f1a717bcd416ee086cf
expires: Sat, 26 Jul 2025 04:21:05 GMT
source-age: 0
content-length: 2009
-- pointer-event 1.2.1 - 2023-Feb-03
-- https://github.com/christoph-heinrich/mpv-pointer-event
--
-- Low latency detection of single-click, double-click, long-click and dragging.
-- workaround https://github.com/mpv-player/mpv/issues/11154
mp.add_key_binding('mouse_move', nil, function() end)
local msg = require('mp.msg')
local options = require('mp.options')
local opts = {
long_click_time = 500,
double_click_time = 0,
drag_distance = 10,
margin_left = 0,
margin_right = 0,
margin_top = 50,
margin_bottom = 90,
ignore_left_single_long_while_window_dragging = true,
left_single = '',
left_double = '',
left_long = '',
left_drag_start = '',
left_drag_end = '',
left_drag = '',
right_single = '',
right_double = '',
right_long = '',
right_drag_start = '',
right_drag_end = '',
right_drag = '',
mid_single = '',
mid_double = '',
mid_long = '',
mid_drag_start = '',
mid_drag_end = '',
mid_drag = '',
}
options.read_options(opts, 'pointer-event')
for k, v in pairs(opts) do
if v == '' then opts[k] = nil end
end
opts.long_click_time = opts.long_click_time / 1000
local window_dragging_enabled = mp.get_property_bool('window-dragging')
if window_dragging_enabled then
msg.warn('window dragging is enabled and can interfere with gesture detection')
end
local fullscreen, maximized, windowed = false, false, true
local function update_windowed()
windowed = not (fullscreen or maximized)
end
local prop_double_time = mp.get_property_number('input-doubleclick-time', 300)
local double_time
local function update_double_time()
local time = opts.double_click_time <= 0 and prop_double_time or opts.double_click_time
double_time = time / 1000
end
update_double_time()
local scale = 1
local scale_sq = 1
local width, height = 0, 0
local area_x0, area_x1, area_y0, area_y1
local function update_area()
area_x0, area_y0 = opts.margin_left * scale, opts.margin_top * scale
area_x1, area_y1 = width - opts.margin_right * scale, height - opts.margin_bottom * scale
end
local function analyze_mouse(key)
local mbtn = key:match('_(.+)$')
local cmd_single = opts[mbtn .. '_single']
local cmd_double = opts[mbtn .. '_double']
local cmd_long = opts[mbtn .. '_long']
local cmd_drag_start = opts[mbtn .. '_drag_start']
local cmd_drag_end = opts[mbtn .. '_drag_end']
local cmd_drag = opts[mbtn .. '_drag']
if not cmd_single and
not cmd_double and
not cmd_long and
not cmd_drag_start and
not cmd_drag_end and
not cmd_drag then
return
end
local nop = function() end
local single_click = cmd_single and function()
msg.verbose('single_click')
mp.command(cmd_single)
end or nop
local double_click = cmd_double and function()
msg.verbose('double_click')
mp.command(cmd_double)
end or nop
local long_click = cmd_long and function()
msg.verbose('long_click')
mp.command(cmd_long)
end or nop
local drag_start = cmd_drag_start and function()
msg.verbose('drag_start')
mp.command(cmd_drag_start)
end or nop
local drag_end = cmd_drag_end and function()
msg.verbose('drag_end')
mp.command(cmd_drag_end)
end or nop
local drag = cmd_drag and function(dx, dy)
msg.verbose('drag', dx, dy)
mp.command(cmd_drag .. ' ' .. dx .. ' ' .. dy)
end or nop
local drag_distance_sq = opts.drag_distance * opts.drag_distance
local last_drag_x = nil
local last_drag_y = nil
local dragging = false
local drag_possible = true
local last_down_x = 0
local last_down_y = 0
local down_start = nil
local function recognized_event(fun, dx, dy)
if (fun == single_click or fun == long_click)
and mbtn == 'left' and windowed and window_dragging_enabled
and opts.ignore_left_single_long_while_window_dragging then
return
end
if last_down_x >= area_x0 and last_down_x < area_x1 and
last_down_y >= area_y0 and last_down_y < area_y1 then
fun(dx, dy)
end
end
local long_click_timeout = mp.add_timeout(opts.long_click_time, function()
recognized_event(long_click)
drag_possible = false
end)
long_click_timeout:kill()
local double_click_timeout = mp.add_timeout(double_time, function()
if down_start then return end
recognized_event(single_click)
end)
double_click_timeout:kill()
local function btn_down(x, y)
msg.debug('btn_down', x, y)
if double_click_timeout:is_enabled() then
double_click_timeout:kill()
long_click_timeout:kill()
recognized_event(double_click)
drag_possible = false
else
double_click_timeout.timeout = double_time
double_click_timeout:resume()
long_click_timeout:resume()
drag_possible = true
end
last_drag_x, last_drag_y = x, y
last_down_x, last_down_y = x, y
down_start = mp.get_time()
end
local function btn_up()
msg.debug('btn_up')
if not double_click_timeout:is_enabled() and long_click_timeout:is_enabled() and
not dragging and drag_possible then
recognized_event(single_click)
end
long_click_timeout:kill()
if dragging then recognized_event(drag_end) end
dragging = false
down_start = nil
end
local function drag_to(x, y)
msg.debug('drag_to', x, y)
if dragging then
local dx, dy = x - last_drag_x, y - last_drag_y
recognized_event(drag, dx, dy)
else
local dx, dy = x - last_down_x, y - last_down_y
local sq_dist = dx * dx + dy * dy
if drag_possible and sq_dist >= drag_distance_sq * scale_sq then
double_click_timeout:kill()
long_click_timeout:kill()
recognized_event(drag_start)
recognized_event(drag, dx, dy)
dragging = true
end
end
last_drag_x, last_drag_y = x, y
end
local mouse_x, mouse_y = 0, 0
mp.add_forced_key_binding(key, 'pe_' .. mbtn, function(tab)
local mouse = mp.get_property_native('mouse-pos')
mouse_x, mouse_y = mouse.x, mouse.y
msg.trace(key, mouse.x, mouse.y, mouse.hover, tab.event)
if tab.event == 'up' then btn_up()
else btn_down(mouse_x, mouse_y) end
end, {complex = true})
mp.observe_property('mouse-pos', 'native', function(name, mouse)
if not mouse then return end
msg.trace(name, mouse.x, mouse.y, mouse.hover)
if down_start then drag_to(mouse.x, mouse.y) end
mouse_x, mouse_y = mouse.x, mouse.y
end)
if cmd_double then
mp.add_key_binding(key .. '_dbl', 'pe_' .. mbtn .. '_dbl', function()
-- to prevent warning about double click not being assigned
end)
end
end
analyze_mouse('mbtn_left')
analyze_mouse('mbtn_right')
analyze_mouse('mbtn_mid')
mp.observe_property('display-hidpi-scale', 'number', function(name, val)
msg.trace(name, val)
if val then
scale = val
scale_sq = val * val
else
scale = 1
scale_sq = 1
end
update_area()
end)
mp.observe_property('osd-dimensions', 'native', function(name, dim)
msg.trace(name, dim and dim.w or nil, dim and dim.h or nil)
if not dim then return end
width, height = dim.w, dim.h
update_area()
end)
mp.observe_property('input-doubleclick-time', 'number', function(name, val)
msg.trace(name, val)
if val then prop_double_time = val
else prop_double_time = 300 end
update_double_time()
end)
mp.observe_property('fullscreen', 'bool', function(name, val)
msg.trace(name, val)
if val == nil then return end
fullscreen = val
update_windowed()
end)
mp.observe_property('window-maximized', 'bool', function(name, val)
msg.trace(name, val)
if val == nil then return end
maximized = val
update_windowed()
end)