Advertisement
Guest User

main.lua (modified)

a guest
Jan 11th, 2022
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 42.66 KB | None | 0 0
  1. --[[ *************************************************************
  2. * Menu defintions and script-message registration
  3. * Thomas Carmichael (carmanaught) https://gitlab.com/carmanaught
  4. *
  5. * Used in concert with menu-builder.lua to create a menu. The script-message registration
  6. * and calling of the createMenu script are done from the definitions here as trying to
  7. * pass the menu definitions to the menu builder with the script-message register there
  8. * doesn't allow for the unloaded/loaded state to work propertly.
  9. *
  10. * Specify the menu type in the createMenu function call below. Current options are:
  11. * tk
  12. *
  13. * 2017-08-04 - Version 0.1 - Separation of menu building from definitions.
  14. * 2017-08-07 - Version 0.2 - Added second mp.register_script_message and changed original
  15. * to allow the use of different menu types by using the related
  16. * script-message name.
  17. * 2020-06-19 - Version 0.3 - Add script directory detection for mpv 0.32. Change video-aspect
  18. * to video-aspect-override due to deprecation.
  19. * 2020-11-28 - Version 0.4 - Remove script directory detection added for mpv 0.32.0. Change
  20. * filename to support mpv 0.33.0 script folders and move
  21. * menu script files into 'mpvcontextmenu' folder. Also pull in the
  22. * gui-dialogs.lua here so that all script files are kept in the new
  23. * script directory.
  24. * 2021-05-29 - Version 0.5 - Add file_loaded_menu value to help with showing menu when the
  25. * pseudo-gui is being used.
  26. *
  27. ***************************************************************
  28. --]]
  29.  
  30. local guiDialogs = require "gui-dialogs"
  31.  
  32. local langcodes = require "langcodes"
  33. local function mpdebug(x) mp.msg.info(x) end
  34. local propNative = mp.get_property_native
  35.  
  36. -- Set options
  37. local options = require "mp.options"
  38. local opt = {
  39. -- Play > Speed - Percentage
  40. playSpeed = 5,
  41. -- Play > Seek - Seconds
  42. seekSmall = 5,
  43. seekMedium = 30,
  44. seekLarge = 60,
  45. -- Video > Aspect - Percentage
  46. vidAspect = 0.1,
  47. -- Video > Zoom - Percentage
  48. vidZoom = 0.1,
  49. -- Video > Screen Position - Percentage
  50. vidPos = 0.1,
  51. -- Video > Color - Percentage
  52. vidColor = 1,
  53. -- Audio > Sync - Milliseconds
  54. audSync = 100,
  55. -- Audio > Volume - Percentage
  56. audVol = 2,
  57. -- Subtitle > Position - Percentage
  58. subPos = 1,
  59. -- Subtitle > Scale - Percentage
  60. subScale = 1,
  61. -- Subtitle > Sync
  62. subSync = 100, -- Milliseconds
  63. }
  64. options.read_options(opt)
  65.  
  66. -- Set some constant values
  67. local SEP = "separator"
  68. local CASCADE = "cascade"
  69. local COMMAND = "command"
  70. local CHECK = "checkbutton"
  71. local RADIO = "radiobutton"
  72. local AB = "ab-button"
  73.  
  74. local function round(num, numDecimalPlaces)
  75. return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
  76. end
  77.  
  78. -- Edition menu functions
  79. local function enableEdition()
  80. local editionState = false
  81. if (propNative("edition-list/count") < 1) then editionState = true end
  82. return editionState
  83. end
  84.  
  85. local function checkEdition(editionNum)
  86. local editionEnable, editionCur = false, propNative("edition")
  87. if (editionNum == editionCur) then editionEnable = true end
  88. return editionEnable
  89. end
  90.  
  91. local function editionMenu()
  92. local editionCount = propNative("edition-list/count")
  93. local editionMenuVal = {}
  94.  
  95. if not (editionCount == 0) then
  96. for editionNum=0, (editionCount - 1), 1 do
  97. local editionTitle = propNative("edition-list/" .. editionNum .. "/title")
  98. if not (editionTitle) then editionTitle = "Edition " .. (editionNum + 1) end
  99.  
  100. local editionCommand = "set edition " .. editionNum
  101. table.insert(editionMenuVal, {RADIO, editionTitle, "", editionCommand, function() return checkEdition(editionNum) end, false, true})
  102. end
  103. else
  104. table.insert(editionMenuVal, {COMMAND, "No Editions", "", "", "", true})
  105. end
  106.  
  107. return editionMenuVal
  108. end
  109.  
  110. -- Chapter menu functions
  111. local function enableChapter()
  112. local chapterEnable = false
  113. if (propNative("chapter-list/count") < 1) then chapterEnable = true end
  114. return chapterEnable
  115. end
  116.  
  117. local function checkChapter(chapterNum)
  118. local chapterState, chapterCur = false, propNative("chapter")
  119. if (chapterNum == chapterCur) then chapterState = true end
  120. return chapterState
  121. end
  122.  
  123. local function chapterMenu()
  124. local chapterCount = propNative("chapter-list/count")
  125. local chapterMenuVal = {}
  126.  
  127. chapterMenuVal = {
  128. {COMMAND, "Previous", "PgUp", "no-osd add chapter -1", "", false, true},
  129. {COMMAND, "Next", "PgDown", "no-osd add chapter 1", "", false, true},
  130. }
  131. if not (chapterCount == 0) then
  132. for chapterNum=0, (chapterCount - 1), 1 do
  133. local chapterTitle = propNative("chapter-list/" .. chapterNum .. "/title")
  134. if not (chapterTitle) then chapterTitle = "Chapter " .. (chapterNum + 1) end
  135.  
  136. local chapterCommand = "set chapter " .. chapterNum
  137. if (chapterNum == 0) then table.insert(chapterMenuVal, {SEP}) end
  138. table.insert(chapterMenuVal, {RADIO, chapterTitle, "", chapterCommand, function() return checkChapter(chapterNum) end, false, true})
  139. end
  140. end
  141.  
  142. return chapterMenuVal
  143. end
  144.  
  145. -- Track type count function to iterate through the track-list and get the number of
  146. -- tracks of the type specified. Types are: video / audio / sub. This actually
  147. -- returns a table of track numbers of the given type so that the track-list/N/
  148. -- properties can be obtained.
  149.  
  150. local function trackCount(checkType)
  151. local tracksCount = propNative("track-list/count")
  152. local trackCountVal = {}
  153.  
  154. if not (tracksCount < 1) then
  155. for i = 0, (tracksCount - 1), 1 do
  156. local trackType = propNative("track-list/" .. i .. "/type")
  157. if (trackType == checkType) then table.insert(trackCountVal, i) end
  158. end
  159. end
  160.  
  161. return trackCountVal
  162. end
  163.  
  164. -- Track check function, to check if a track is selected. This isn't specific to a set
  165. -- track type and can be used for the video/audio/sub tracks, since they're all part
  166. -- of the track-list.
  167.  
  168. local function checkTrack(trackNum)
  169. local trackState, trackCur = false, propNative("track-list/" .. trackNum .. "/selected")
  170. if (trackCur == true) then trackState = true end
  171. return trackState
  172. end
  173.  
  174. -- Video > Track menu functions
  175. local function enableVidTrack()
  176. local vidTrackEnable, vidTracks = false, trackCount("video")
  177. if (#vidTracks < 1) then vidTrackEnable = true end
  178. return vidTrackEnable
  179. end
  180.  
  181. local function vidTrackMenu()
  182. local vidTrackMenuVal, vidTrackCount = {}, trackCount("video")
  183.  
  184. if not (#vidTrackCount == 0) then
  185. for i = 1, #vidTrackCount, 1 do
  186. local vidTrackNum = vidTrackCount[i]
  187. local vidTrackID = propNative("track-list/" .. vidTrackNum .. "/id")
  188. local vidTrackTitle = propNative("track-list/" .. vidTrackNum .. "/title")
  189. if not (vidTrackTitle) then vidTrackTitle = "Video Track " .. i end
  190.  
  191. local vidTrackCommand = "set vid " .. vidTrackID
  192. table.insert(vidTrackMenuVal, {RADIO, vidTrackTitle, "", vidTrackCommand, function() return checkTrack(vidTrackNum) end, false, true})
  193. end
  194. else
  195. table.insert(vidTrackMenuVal, {RADIO, "No Video Tracks", "", "", "", true})
  196. end
  197.  
  198. return vidTrackMenuVal
  199. end
  200.  
  201. -- Convert ISO 639-1/639-2 codes to be full length language names. The full length names
  202. -- are obtained by using the property accessor with the iso639_1/_2 tables stored in
  203. -- the langcodes.lua file (require "langcodes" above).
  204. function getLang(trackLang)
  205. trackLang = string.upper(trackLang)
  206. if (string.len(trackLang) == 2) then trackLang = langcodes.iso639_1(trackLang)
  207. elseif (string.len(trackLang) == 3) then trackLang = langcodes.iso639_2(trackLang) end
  208. return trackLang
  209. end
  210.  
  211. function noneCheck(checkType)
  212. local checkVal, trackID = false, propNative(checkType)
  213. if (type(trackID) == "boolean") then
  214. if (trackID == false) then checkVal = true end
  215. end
  216. return checkVal
  217. end
  218.  
  219. -- Audio > Track menu functions
  220. local function audTrackMenu()
  221. local audTrackMenuVal, audTrackCount = {}, trackCount("audio")
  222.  
  223. audTrackMenuVal = {
  224. --{COMMAND, "Open File", "", "script-binding add_audio_dialog", "", false},
  225. --{COMMAND, "Reload File", "", "audio-reload", "", false},
  226. --{COMMAND, "Remove", "", "audio-remove", "", false},
  227. --{SEP},
  228. --{COMMAND, "Select Next", "Ctrl+A", "cycle audio", "", false, true},
  229. }
  230. if not (#audTrackCount == 0) then
  231. for i = 1, (#audTrackCount), 1 do
  232. local audTrackNum = audTrackCount[i]
  233. local audTrackID = propNative("track-list/" .. audTrackNum .. "/id")
  234. local audTrackTitle = propNative("track-list/" .. audTrackNum .. "/title")
  235. local audTrackLang = propNative("track-list/" .. audTrackNum .. "/lang")
  236. -- Convert ISO 639-1/2 codes
  237. if not (audTrackLang == nil) then audTrackLang = getLang(audTrackLang) and getLang(audTrackLang) or audTrackLang end
  238.  
  239. --if (audTrackTitle) then audTrackTitle = audTrackTitle .. ((audTrackLang ~= nil) and " (" .. audTrackLang .. ")" or "")
  240. local isext = propNative("track-list/" .. audTrackNum .. "/external")
  241. local isext2 = ""
  242. if isext == true then isext2 = " (ext)" end
  243. --local showcodec = "unknown"
  244. local showcodec = mp.get_property("current-tracks/audio/codec")
  245. local showchannels = mp.get_property('current-tracks/audio/demux-channel-count') .. "ch"
  246. if (audTrackTitle) then audTrackTitle = audTrackTitle .. ((audTrackLang ~= nil) and " (" .. audTrackLang .. ")" or "") .. ": " .. showcodec .. ", " .. showchannels .. isext2
  247. elseif (audTrackLang) then audTrackTitle = ((audTrackLang ~= nil) and " (" .. audTrackLang .. ")" or "") .. ": " .. showcodec .. ", " .. showchannels .. isext2
  248. --else audTrackTitle = "Audio Track " .. i end
  249. else audTrackTitle = ((audTrackLang ~= nil) and " (" .. audTrackLang .. ")" or "") .. ": " .. showcodec .. ", " .. showchannels .. isext2 end
  250.  
  251. local audTrackCommand = "set aid " .. audTrackID
  252. if (i == 1) then
  253. --table.insert(audTrackMenuVal, {SEP})
  254. table.insert(audTrackMenuVal, {RADIO, "Select None", "", "set aid 0", function() return noneCheck("aid") end, false, true})
  255. table.insert(audTrackMenuVal, {SEP})
  256. end
  257. table.insert(audTrackMenuVal, {RADIO, audTrackTitle, "", audTrackCommand, function() return checkTrack(audTrackNum) end, false, true})
  258. end
  259. end
  260.  
  261. return audTrackMenuVal
  262. end
  263.  
  264. -- Subtitle label
  265. local function subVisLabel() return propNative("sub-visibility") and "Hide" or "Un-hide" end
  266.  
  267. -- Subtitle > Track menu functions
  268.  
  269. local function subTrackMenu()
  270. local subTrackMenuVal, subTrackCount = {}, trackCount("sub")
  271.  
  272. subTrackMenuVal = {
  273. --{COMMAND, "Open File", "(Shift+F)", "script-binding add_subtitle_dialog", "", false},
  274. --{COMMAND, "Reload File", "", "sub-reload", "", false},
  275. --{COMMAND, "Clear File", "", "sub-remove", "", false},
  276. --{SEP},
  277. --{COMMAND, "Select Next", "Shift+N", "cycle sub", "", false, true},
  278. --{COMMAND, "Select Previous", "Ctrl+Shift+N", "cycle sub down", "", false, true},
  279. --{CHECK, function() return subVisLabel() end, "V", "cycle sub-visibility", function() return not propNative("sub-visibility") end, false, true},
  280. }
  281. if not (#subTrackCount == 0) then
  282. for i = 1, (#subTrackCount), 1 do
  283. local subTrackNum = subTrackCount[i]
  284. local subTrackID = propNative("track-list/" .. subTrackNum .. "/id")
  285. local subTrackTitle = propNative("track-list/" .. subTrackNum .. "/title")
  286. local subTrackLang = propNative("track-list/" .. subTrackNum .. "/lang")
  287. -- Convert ISO 639-1/2 codes
  288. if not (subTrackLang == nil) then subTrackLang = getLang(subTrackLang) and getLang(subTrackLang) or subTrackLang end
  289.  
  290. --if (subTrackTitle) then subTrackTitle = subTrackTitle .. ((subTrackLang ~= nil) and " (" .. subTrackLang .. ")" or "")
  291. local isextsub = propNative("track-list/" .. subTrackNum .. "/external")
  292. if isextsub == true then isextsub2 = " (ext)" end
  293. local showcodecsub = mp.get_property("current-tracks/sub/codec")
  294. local isextsub2 = ""
  295. if (subTrackTitle) then subTrackTitle = subTrackTitle .. ((subTrackLang ~= nil) and " (" .. subTrackLang .. ")" or "") .. ": " .. showcodecsub .. ", " .. isextsub2
  296. --elseif (subTrackLang) then subTrackTitle = subTrackLang
  297. elseif (subTrackLang) then subTrackTitle = "- " .. ((subTrackLang ~= nil) and " (" .. subTrackLang .. ")" or "") .. ": " .. showcodecsub .. ", " .. isextsub2
  298. --else subTrackTitle = "Subtitle Track " .. i end
  299. else subTrackTitle = subTrackTitle .. ((subTrackLang ~= nil) and " (" .. subTrackLang .. ")" or "") .. ": " .. showcodecsub .. ", " .. isextsub2 end
  300.  
  301. local subTrackCommand = "set sid " .. subTrackID
  302. if (i == 1) then
  303. --table.insert(subTrackMenuVal, {SEP})
  304. table.insert(subTrackMenuVal, {RADIO, "Select None", "", "set sid 0", function() return noneCheck("sid") end, false, true})
  305. table.insert(subTrackMenuVal, {SEP})
  306. end
  307. table.insert(subTrackMenuVal, {RADIO, subTrackTitle, "", subTrackCommand, function() return checkTrack(subTrackNum) end, false, true})
  308. end
  309. end
  310.  
  311. return subTrackMenuVal
  312. end
  313.  
  314. local function stateABLoop()
  315. local abLoopState = ""
  316. local abLoopA, abLoopB = propNative("ab-loop-a"), propNative("ab-loop-b")
  317.  
  318. if (abLoopA == "no") and (abLoopB == "no") then abLoopState = "off"
  319. elseif not (abLoopA == "no") and (abLoopB == "no") then abLoopState = "a"
  320. elseif not (abLoopA == "no") and not (abLoopB == "no") then abLoopState = "b" end
  321.  
  322. return abLoopState
  323. end
  324.  
  325. local function stateFileLoop()
  326. local loopState, loopval = false, propNative("loop-file")
  327. if (loopval == "inf") then loopState = true end
  328. return loopState
  329. end
  330.  
  331. -- Aspect Ratio radio item check
  332. local function stateRatio(ratioVal)
  333. -- Ratios and Decimal equivalents
  334. -- Ratios: "4:3" "16:10" "16:9" "1.85:1" "2.35:1"
  335. -- Decimal: "1.333" "1.600" "1.778" "1.850" "2.350"
  336. local ratioState = false
  337. local ratioCur = round(propNative("video-aspect-override"), 3)
  338.  
  339. if (ratioVal == "4:3") and (ratioCur == round(4/3, 3)) then ratioState = true
  340. elseif (ratioVal == "16:10") and (ratioVal == round(16/10, 3)) then ratioState = true
  341. elseif (ratioVal == "16:9") and (ratioVal == round(16/9, 3)) then ratioState = true
  342. elseif (ratioVal == "1.85:1") and (ratioVal == round(1.85/1, 3)) then ratioState = true
  343. elseif (ratioVal == "2.35:1") and (ratioVal == round(2.35/1, 3)) then ratioState = true
  344. end
  345.  
  346. return ratioState
  347. end
  348.  
  349. -- Video Rotate radio item check
  350. local function stateRotate(rotateVal)
  351. local rotateState, rotateCur = false, propNative("video-rotate")
  352. if (rotateVal == rotateCur) then rotateState = true end
  353. return rotateState
  354. end
  355.  
  356. -- Video Alignment radio item checks
  357. local function stateAlign(alignAxis, alignPos)
  358. local alignState = false
  359. local alignValY, alignValX = propNative("video-align-y"), propNative("video-align-x")
  360.  
  361. -- This seems a bit unwieldy. Should look at simplifying if possible.
  362. if (alignAxis == "y") then
  363. if (alignPos == alignValY) then alignState = true end
  364. elseif (alignAxis == "x") then
  365. if (alignPos == alignValX) then alignState = true end
  366. end
  367.  
  368. return alignState
  369. end
  370.  
  371. -- Deinterlacing radio item check
  372. local function stateDeInt(deIntVal)
  373. local deIntState, deIntCur = false, propNative("deinterlace")
  374. if (deIntVal == deIntCur) then deIntState = true end
  375. return deIntState
  376. end
  377.  
  378. local function stateFlip(flipVal)
  379. local vfState, vfVals = false, propNative("vf")
  380. for i, vf in pairs(vfVals) do
  381. if (vf["name"] == flipVal) then vfState = true end
  382. end
  383. return vfState
  384. end
  385.  
  386. -- Mute label
  387. local function muteLabel() return propNative("mute") and "Un-mute" or "Mute" end
  388.  
  389. -- Based on "mpv --audio-channels=help", reordered/renamed in part as per Bomi
  390. local audio_channels = { {"Auto", "auto"}, {"Auto (Safe)", "auto-safe"}, {"Empty", "empty"}, {"Mono", "mono"}, {"Stereo", "stereo"}, {"2.1ch", "2.1"}, {"3.0ch", "3.0"}, {"3.0ch (Back)", "3.0(back)"}, {"3.1ch", "3.1"}, {"3.1ch (Back)", "3.1(back)"}, {"4.0ch", "quad"}, {"4.0ch (Side)", "quad(side)"}, {"4.0ch (Diamond)", "4.0"}, {"4.1ch", "4.1(alsa)"}, {"4.1ch (Diamond)", "4.1"}, {"5.0ch", "5.0(alsa)"}, {"5.0ch (Alt.)", "5.0"}, {"5.0ch (Side)", "5.0(side)"}, {"5.1ch", "5.1(alsa)"}, {"5.1ch (Alt.)", "5.1"}, {"5.1ch (Side)", "5.1(side)"}, {"6.0ch", "6.0"}, {"6.0ch (Front)", "6.0(front)"}, {"6.0ch (Hexagonal)", "hexagonal"}, {"6.1ch", "6.1"}, {"6.1ch (Top)", "6.1(top)"}, {"6.1ch (Back)", "6.1(back)"}, {"6.1ch (Front)", "6.1(front)"}, {"7.0ch", "7.0"}, {"7.0ch (Back)", "7.0(rear)"}, {"7.0ch (Front)", "7.0(front)"}, {"7.1ch", "7.1(alsa)"}, {"7.1ch (Alt.)", "7.1"}, {"7.1ch (Wide)", "7.1(wide)"}, {"7.1ch (Side)", "7.1(wide-side)"}, {"7.1ch (Back)", "7.1(rear)"}, {"8.0ch (Octagonal)", "octagonal"} }
  391.  
  392. -- Create audio key/value pairs to check against the native property
  393. -- e.g. audio_pair["2.1"] = "2.1", etc.
  394. local audio_pair = {}
  395. for i = 1, #audio_channels do
  396. audio_pair[audio_channels[i][2]] = audio_channels[i][2]
  397. end
  398.  
  399. -- Audio channel layout radio item check
  400. local function stateAudChannel(audVal)
  401. local audState, audLayout = false, propNative("audio-channels")
  402.  
  403. audState = (audio_pair[audVal] == audLayout) and true or false
  404. return audState
  405. end
  406.  
  407. -- Audio channel layout menu creation
  408. local function audLayoutMenu()
  409. local audLayoutMenuVal = {}
  410.  
  411. for i = 1, #audio_channels do
  412. if (i == 3) then table.insert(audLayoutMenuVal, {SEP}) end
  413. table.insert(audLayoutMenuVal, {RADIO, audio_channels[i][1], "", "set audio-channels \"" .. audio_channels[i][2] .. "\"", function() return stateAudChannel(audio_channels[i][2]) end, false, true})
  414. end
  415.  
  416. return audLayoutMenuVal
  417. end
  418.  
  419. -- Subtitle Alignment radio item check
  420. local function stateSubAlign(subAlignVal)
  421. local subAlignState, subAlignCur = false, propNative("sub-align-y")
  422. subAlignState = (subAlignVal == subAlignCur) and true or false
  423. return subAlignState
  424. end
  425.  
  426. -- Subtitle Position radio item check
  427. local function stateSubPos(subPosVal)
  428. local subPosState, subPosCur = false, propNative("image-subs-video-resolution")
  429. subPosState = (subPosVal == subPosCur) and true or false
  430. return subPosState
  431. end
  432.  
  433. local function movePlaylist(direction)
  434. local playlistPos, newPos = propNative("playlist-pos"), 0
  435. -- We'll remove 1 here to "0 index" the value since we're using it with playlist-pos
  436. local playlistCount = propNative("playlist-count") - 1
  437.  
  438. if (direction == "up") then
  439. newPos = playlistPos - 1
  440. if not (playlistPos == 0) then
  441. mp.commandv("plalist-move", playlistPos, newPos)
  442. else mp.osd_message("Can't move item up any further") end
  443. elseif (direction == "down") then
  444. if not (playlistPos == playlistCount) then
  445. newPos = playlistPos + 2
  446. mp.commandv("plalist-move", playlistPos, newPos)
  447. else mp.osd_message("Can't move item down any further") end
  448. end
  449. end
  450.  
  451. local function statePlayLoop()
  452. local loopState, loopVal = false, propNative("loop-playlist")
  453. if not (tostring(loopVal) == "false") then loopState = true end
  454. return loopState
  455. end
  456.  
  457. local function stateOnTop(onTopVal)
  458. local onTopState, onTopCur = false, propNative("ontop")
  459. onTopState = (onTopVal == onTopCur) and true or false
  460. return onTopState
  461. end
  462.  
  463. --[[ ************ CONFIG: start ************ ]]--
  464.  
  465. local menuList = {}
  466.  
  467. -- Format for object tables
  468. -- {Item Type, Label, Accelerator, Command, Item State, Item Disable, Repost Menu (Optional)}
  469.  
  470. -- Item Type - The type of item, e.g. CASCADE, COMMAND, CHECK, RADIO, etc
  471. -- Label - The label for the item
  472. -- Accelerator - The text shortcut/accelerator for the item
  473. -- Command - This is the command to run when the item is clicked
  474. -- Item State - The state of the item (selected/unselected). A/B Repeat is a special case.
  475. -- Item Disable - Whether to disable
  476. -- Repost Menu (Optional) - This is only for use with the Tk menu and is optional (only needed
  477. -- if the intent is for the menu item to cause the menu to repost)
  478.  
  479. -- Item Type, Label and Accelerator should all evaluate to strings as a result of the return
  480. -- from a function or be strings themselves.
  481. -- Command can be a function or string, this will be handled after a click.
  482. -- Item State and Item Disable should normally be boolean but can be a string for A/B Repeat.
  483. -- Repost Menu (Optional) should only be boolean and is only needed if the value is true.
  484.  
  485. -- The 'file_loaded_menu' value is used when the table is passed to the menu-engine to handle the
  486. -- behavior of the 'playback_only' (cancellable) argument.
  487.  
  488. -- This is to be shown when nothing is open yet and is a small subset of the greater menu that
  489. -- will be overwritten when the full menu is created.
  490. menuList = {
  491. file_loaded_menu = false,
  492.  
  493. context_menu = {
  494. {CASCADE, "Open", "open_menu", "", "", false},
  495. {SEP},
  496. {CASCADE, "Window", "window_menu", "", "", false},
  497. {SEP},
  498. {COMMAND, "Dismiss Menu", "", "", "", false},
  499. --{COMMAND, "Quit", "", "quit", "", false},
  500. },
  501.  
  502. open_menu = {
  503. {COMMAND, "File", "Ctrl+F", "script-binding add_files_dialog", "", false},
  504. {COMMAND, "Folder", "Ctrl+G", "script-binding add_folder_dialog", "", false},
  505. {COMMAND, "URL", "", "script-binding open_url_dialog", "", false},
  506. },
  507.  
  508. window_menu = {
  509. {CASCADE, "Stays on Top", "staysontop_menu", "", "", false},
  510. {CHECK, "Remove Frame", "", "cycle border", function() return not propNative("border") end, false, true},
  511. {SEP},
  512. {COMMAND, "Toggle Fullscreen", "F", "cycle fullscreen", "", false, true},
  513. {COMMAND, "Enter Fullscreen", "", "set fullscreen \"yes\"", "", false, true},
  514. {COMMAND, "Exit Fullscreen", "Escape", "set fullscreen \"no\"", "", false, true},
  515. {SEP},
  516. {COMMAND, "Close", "Ctrl+W", "quit", "", false},
  517. },
  518.  
  519. staysontop_menu = {
  520. {COMMAND, "Select Next", "", "cycle ontop", "", false, true},
  521. {SEP},
  522. {RADIO, "Off", "", "set ontop \"yes\"", function() return stateOnTop(false) end, false, true},
  523. {RADIO, "On", "", "set ontop \"no\"", function() return stateOnTop(true) end, false, true},
  524. },
  525. }
  526.  
  527. -- DO NOT create the "playing" menu tables until AFTER the file has loaded as we're unable to
  528. -- dynamically create some menus if it tries to build the table before the file is loaded.
  529. -- A prime example is the chapter-list or track-list values, which are unavailable until
  530. -- the file has been loaded.
  531.  
  532. etcmenushow = mp.observe_property("speed")
  533.  
  534. mp.register_event("file-loaded", function()
  535. menuList = {
  536. file_loaded_menu = true,
  537.  
  538. context_menu = {
  539. --{CASCADE, "Open", "open_menu", "", "", false},
  540. --{SEP},
  541. --{CASCADE, "Play", "play_menu", "", "", false},
  542. --{CASCADE, "Video", "video_menu", "", "", false},
  543. --{CASCADE, "Audio", "audio_menu", "", "", false},
  544. {CASCADE, "Audio", "audtrack_menu", "", "", false},
  545. {SEP},
  546. --{CASCADE, "Subtitle", "subtitle_menu", "", "", false},
  547. {CASCADE, "Subtitle", "subtrack_menu", "", "", false},
  548. --{SEP},
  549. --{CASCADE, "Tools", "tools_menu", "", "", false},
  550. --{CASCADE, "Window", "window_menu", "", "", false},
  551. {SEP},
  552. {COMMAND, "Dismiss Menu", "", "", "", false},
  553. --{COMMAND, "Quit", "", "quit", "", false},
  554.  
  555. --{CASCADE, etcmenushow, "etc_menu", "", "", false},
  556. },
  557.  
  558. open_menu = {
  559. {COMMAND, "File", "Ctrl+F", "script-binding add_files_dialog", "", false},
  560. {COMMAND, "Folder", "Ctrl+G", "script-binding add_folder_dialog", "", false},
  561. {COMMAND, "URL", "", "script-binding open_url_dialog", "", false},
  562. },
  563.  
  564. play_menu = {
  565. {COMMAND, "Play/Pause", "Space", "cycle pause", "", false, true},
  566. {COMMAND, "Stop", "Ctrl+Space", "stop", "", false},
  567. {SEP},
  568. {COMMAND, "Previous", "<", "playlist-prev", "", false, true},
  569. {COMMAND, "Next", ">", "playlist-next", "", false, true},
  570. {SEP},
  571. {CASCADE, "Speed", "speed_menu", "", "", false},
  572. {CASCADE, "A-B Repeat", "abrepeat_menu", "", "", false},
  573. {SEP},
  574. {CASCADE, "Seek", "seek_menu", "", "", false},
  575. {CASCADE, "Title/Edition", "edition_menu", "", "", function() return enableEdition() end},
  576. {CASCADE, "Chapter", "chapter_menu", "", "", function() return enableChapter() end},
  577. },
  578.  
  579. speed_menu = {
  580. {COMMAND, "Reset", "Backspace", "no-osd set speed 1.0 ; show-text \"Play Speed - Reset\"", "", false, true},
  581. {SEP},
  582. {COMMAND, "+" .. opt.playSpeed .. "%", "=", "multiply speed " .. (1 + (opt.playSpeed / 100)), "", false, true},
  583. {COMMAND, "-" .. opt.playSpeed .. "%", "-", "multiply speed " .. (1 - (opt.playSpeed / 100)), "", false, true},
  584. },
  585.  
  586. abrepeat_menu = {
  587. {AB, "Set/Clear A-B Loop", "R", "ab-loop", function() return stateABLoop() end, false, true},
  588. {CHECK, "Toggle Infinite Loop", "", "cycle-values loop-file \"inf\" \"no\"", function() return stateFileLoop() end, false, true},
  589. },
  590.  
  591. seek_menu = {
  592. {COMMAND, "Beginning", "Ctrl+Home", "no-osd seek 0 absolute", "", false, true},
  593. {SEP},
  594. {COMMAND, "+" .. opt.seekSmall .. " Sec", "Right", "no-osd seek " .. opt.seekSmall, "", false, true},
  595. {COMMAND, "-" .. opt.seekSmall .. " Sec", "Left", "no-osd seek -" .. opt.seekSmall, "", false, true},
  596. {COMMAND, "+" .. opt.seekMedium .. " Sec", "Up", "no-osd seek " .. opt.seekMedium, "", false, true},
  597. {COMMAND, "-" .. opt.seekMedium .. " Sec", "Down", "no-osd seek -" .. opt.seekMedium, "", false, true},
  598. {COMMAND, "+" .. opt.seekLarge .. " Sec", "End", "no-osd seek " .. opt.seekLarge, "", false, true},
  599. {COMMAND, "-" .. opt.seekLarge .. " Sec", "Home", "no-osd seek -" .. opt.seekLarge, "", false, true},
  600. {SEP},
  601. {COMMAND, "Previous Frame", "Alt+Left", "frame-back-step", "", false, true},
  602. {COMMAND, "Next Frame", "Alt+Right", "frame-step", "", false, true},
  603. {COMMAND, "Next Black Frame", "Alt+b", "script-binding skip_scene", "", false, true},
  604. {SEP},
  605. {COMMAND, "Previous Subtitle", "", "no-osd sub-seek -1", "", false, true},
  606. {COMMAND, "Current Subtitle", "", "no-osd sub-seek 0", "", false, true},
  607. {COMMAND, "Next Subtitle", "", "no-osd sub-seek 1", "", false, true},
  608. },
  609.  
  610. -- Use functions returning tables, since we don't need these menus if there
  611. -- aren't any editions or any chapters to seek through.
  612. edition_menu = editionMenu(),
  613. chapter_menu = chapterMenu(),
  614.  
  615. video_menu = {
  616. {CASCADE, "Track", "vidtrack_menu", "", "", function() return enableVidTrack() end},
  617. --{SEP},
  618. --{CASCADE, "Take Screenshot", "screenshot_menu", "", "", false},
  619. {SEP},
  620. {CASCADE, "Aspect Ratio", "aspect_menu", "", "", false},
  621. {CASCADE, "Zoom", "zoom_menu", "", "", false},
  622. {CASCADE, "Rotate", "rotate_menu", "", "", false},
  623. {CASCADE, "Screen Position", "screenpos_menu", "", "", false},
  624. {CASCADE, "Screen Alignment", "screenalign_menu", "", "", false},
  625. {SEP},
  626. {CASCADE, "Deinterlacing", "deint_menu", "", "", false},
  627. {CASCADE, "Filter", "filter_menu", "", "", false},
  628. {CASCADE, "Adjust Color", "color_menu", "", "", false},
  629. },
  630.  
  631. -- Use function to return list of Video Tracks
  632. vidtrack_menu = vidTrackMenu(),
  633.  
  634. screenshot_menu = {
  635. {COMMAND, "Screenshot", "Ctrl+S", "async screenshot", "", false},
  636. {COMMAND, "Screenshot (No Subs)", "Alt+S", "async screenshot video", "", false},
  637. {COMMAND, "Screenshot (Subs/OSD/Scaled)", "", "async screenshot window", "", false},
  638. },
  639.  
  640. aspect_menu = {
  641. {COMMAND, "Reset", "Ctrl+Shift+R", "no-osd set video-aspect-override \"-1\" ; no-osd set video-aspect-override \"-1\" ; show-text \"Video Aspect Ratio - Reset\"", "", false, true},
  642. {COMMAND, "Select Next", "", "cycle-values video-aspect-override \"4:3\" \"16:10\" \"16:9\" \"1.85:1\" \"2.35:1\" \"-1\" \"-1\"", "", false, true},
  643. {SEP},
  644. {RADIO, "4:3 (TV)", "", "set video-aspect-override \"4:3\"", function() return stateRatio("4:3") end, false, true},
  645. {RADIO, "16:10 (Wide Monitor)", "", "set video-aspect-override \"16:10\"", function() return stateRatio("16:10") end, false, true},
  646. {RADIO, "16:9 (HDTV)", "", "set video-aspect-override \"16:9\"", function() return stateRatio("16:9") end, false, true},
  647. {RADIO, "1.85:1 (Wide Vision)", "", "set video-aspect-override \"1.85:1\"", function() return stateRatio("1.85:1") end, false, true},
  648. {RADIO, "2.35:1 (CinemaScope)", "", "set video-aspect-override \"2.35:1\"", function() return stateRatio("2.35:1") end, false, true},
  649. {SEP},
  650. {COMMAND, "+" .. opt.vidAspect .. "%", "Ctrl+Shift+A", "add video-aspect-override " .. (opt.vidAspect / 100), "", false, true},
  651. {COMMAND, "-" .. opt.vidAspect .. "%", "Ctrl+Shift+D", "add video-aspect-override -" .. (opt.vidAspect / 100), "", false, true},
  652. },
  653.  
  654. zoom_menu = {
  655. {COMMAND, "Reset", "Shift+R", "no-osd set panscan 0 ; show-text \"Pan/Scan - Reset\"", "", false, true},
  656. {SEP},
  657. {COMMAND, "+" .. opt.vidZoom .. "%", "Shift+T", "add panscan " .. (opt.vidZoom / 100), "", false, true},
  658. {COMMAND, "-" .. opt.vidZoom .. "%", "Shift+G", "add panscan -" .. (opt.vidZoom / 100), "", false, true},
  659. },
  660.  
  661. rotate_menu = {
  662. {COMMAND, "Reset", "", "set video-rotate \"0\"", "", false, true},
  663. {COMMAND, "Select Next", "", "cycle-values video-rotate \"0\" \"90\" \"180\" \"270\"", "", false, true},
  664. {SEP},
  665. {RADIO, "0°", "", "set video-rotate \"0\"", function() return stateRotate(0) end, false, true},
  666. {RADIO, "90°", "", "set video-rotate \"90\"", function() return stateRotate(90) end, false, true},
  667. {RADIO, "180°", "", "set video-rotate \"180\"", function() return stateRotate(180) end, false, true},
  668. {RADIO, "270°", "", "set video-rotate \"270\"", function() return stateRotate(270) end, false, true},
  669. },
  670.  
  671. screenpos_menu = {
  672. {COMMAND, "Reset", "Shift+X", "no-osd set video-pan-x 0 ; no-osd set video-pan-y 0 ; show-text \"Video Pan - Reset\"", "", false, true},
  673. {SEP},
  674. {COMMAND, "Horizontally +" .. opt.vidPos .. "%", "Shift+D", "add video-pan-x " .. (opt.vidPos / 100), "", false, true},
  675. {COMMAND, "Horizontally -" .. opt.vidPos .. "%", "Shift+A", "add video-pan-x -" .. (opt.vidPos / 100), "", false, true},
  676. {SEP},
  677. {COMMAND, "Vertically +" .. opt.vidPos .. "%", "Shift+S", "add video-pan-y -" .. (opt.vidPos / 100), "", false, true},
  678. {COMMAND, "Vertically -" .. opt.vidPos .. "%", "Shift+W", "add video-pan-y " .. (opt.vidPos / 100), "", false, true},
  679. },
  680.  
  681. screenalign_menu = {
  682. -- Y Values: -1 = Top, 0 = Vertical Center, 1 = Bottom
  683. -- X Values: -1 = Left, 0 = Horizontal Center, 1 = Right
  684. {RADIO, "Top", "", "no-osd set video-align-y -1", function() return stateAlign("y",-1) end, false, true},
  685. {RADIO, "Vertical Center", "", "no-osd set video-align-y 0", function() return stateAlign("y",0) end, false, true},
  686. {RADIO, "Bottom", "", "no-osd set video-align-y 1", function() return stateAlign("y",1) end, false, true},
  687. {SEP},
  688. {RADIO, "Left", "", "no-osd set video-align-x -1", function() return stateAlign("x",-1) end, false, true},
  689. {RADIO, "Horizontal Center", "", "no-osd set video-align-x 0", function() return stateAlign("x",0) end, false, true},
  690. {RADIO, "Right", "", "no-osd set video-align-x 1", function() return stateAlign("x",1) end, false, true},
  691. },
  692.  
  693. deint_menu = {
  694. {COMMAND, "Toggle", "Ctrl+D", "cycle deinterlace", "", false, true},
  695. {COMMAND, "Auto", "", "set deinterlace \"auto\"", "", false, true},
  696. {SEP},
  697. {RADIO, "Off", "", "no-osd set deinterlace \"no\"", function() return stateDeInt(false) end, false, true},
  698. {RADIO, "On", "", "no-osd set deinterlace \"yes\"", function() return stateDeInt(true) end, false, true},
  699. },
  700.  
  701. filter_menu = {
  702. {CHECK, "Flip Vertically", "", "no-osd vf toggle vflip", function() return stateFlip("vflip") end, false, true},
  703. {CHECK, "Flip Horizontally", "", "no-osd vf toggle hflip", function() return stateFlip("hflip") end, false, true}
  704. },
  705.  
  706. color_menu = {
  707. {COMMAND, "Reset", "O", "no-osd set brightness 0 ; no-osd set contrast 0 ; no-osd set hue 0 ; no-osd set saturation 0 ; show-text \"Colors - Reset\"", "", false, true},
  708. {SEP},
  709. {COMMAND, "Brightness +" .. opt.vidColor .. "%", "T", "add brightness " .. opt.vidColor, "", false, true},
  710. {COMMAND, "Brightness -" .. opt.vidColor .. "%", "G", "add brightness -" .. opt.vidColor, "", false, true},
  711. {COMMAND, "Contrast +" .. opt.vidColor .. "%", "Y", "add contrast " .. opt.vidColor, "", false, true},
  712. {COMMAND, "Contrast -" .. opt.vidColor .. "%", "H", "add contrast -" .. opt.vidColor, "", false, true},
  713. {COMMAND, "Saturation +" .. opt.vidColor .. "%", "U", "add saturation " .. opt.vidColor, "", false, true},
  714. {COMMAND, "Saturation -" .. opt.vidColor .. "%", "J", "add saturation -" .. opt.vidColor, "", false, true},
  715. {COMMAND, "Hue +" .. opt.vidColor .. "%", "I", "add hue " .. opt.vidColor, "", false, true},
  716. {COMMAND, "Hue -" .. opt.vidColor .. "%", "K", "add hue -" .. opt.vidColor, "", false, true},
  717. },
  718.  
  719. audio_menu = {
  720. {CASCADE, "Track", "audtrack_menu", "", "", false},
  721. --{CASCADE, "Sync", "audsync_menu", "", "", false},
  722. --{SEP},
  723. --{CASCADE, "Volume", "volume_menu", "", "", false},
  724. --{CASCADE, "Channel Layout", "channel_layout", "", "", false},
  725. },
  726.  
  727. -- Use function to return list of Audio Tracks
  728. audtrack_menu = audTrackMenu(),
  729.  
  730. audsync_menu = {
  731. {COMMAND, "Reset", "\\", "no-osd set audio-delay 0 ; show-text \"Audio Sync - Reset\"", "", false, true},
  732. {SEP},
  733. {COMMAND, "+" .. opt.audSync .. " ms", "]", "add audio-delay " .. (opt.audSync / 1000) .. "", "", false, true},
  734. {COMMAND, "-" .. opt.audSync .. " ms", "[", "add audio-delay -" .. (opt.audSync / 1000) .. "", "", false, true},
  735. },
  736.  
  737. volume_menu = {
  738. {CHECK, function() return muteLabel() end, "", "cycle mute", function() return propNative("mute") end, false, true},
  739. {SEP},
  740. {COMMAND, "+" .. opt.audVol.. "%", "Shift+Up", "add volume " .. opt.audVol, "", false, true},
  741. {COMMAND, "-" .. opt.audVol.. "%", "Shift+Down", "add volume -" .. opt.audVol, "", false, true},
  742. },
  743.  
  744. channel_layout = audLayoutMenu(),
  745.  
  746. subtitle_menu = {
  747. {CASCADE, "Track", "subtrack_menu", "", "", false},
  748. {SEP},
  749. {CASCADE, "Alightment", "subalign_menu", "", "", false},
  750. {CASCADE, "Position", "subpos_menu", "", "", false},
  751. {CASCADE, "Scale", "subscale_menu", "", "", false},
  752. {SEP},
  753. {CASCADE, "Sync", "subsync_menu", "", "", false},
  754. },
  755.  
  756. -- Use function to return list of Subtitle Tracks
  757. subtrack_menu = subTrackMenu(),
  758.  
  759. subalign_menu = {
  760. {COMMAND, "Select Next", "", "cycle-values sub-align-y \"top\" \"bottom\"", "", false, true},
  761. {SEP},
  762. {RADIO, "Top", "", "set sub-align-y \"top\"", function() return stateSubAlign("top") end, false, true},
  763. {RADIO, "Bottom", "","set sub-align-y \"bottom\"", function() return stateSubAlign("bottom") end, false, true},
  764. },
  765.  
  766. subpos_menu = {
  767. {COMMAND, "Reset", "Alt+S", "no-osd set sub-pos 100 ; no-osd set sub-scale 1 ; show-text \"Subtitle Position - Reset\"", "", false, true},
  768. {SEP},
  769. {COMMAND, "+" .. opt.subPos .. "%", "S", "add sub-pos " .. opt.subPos, "", false, true},
  770. {COMMAND, "-" .. opt.subPos .. "%", "W", "add sub-pos -" .. opt.subPos, "", false, true},
  771. {SEP},
  772. {RADIO, "Display on Letterbox", "", "set image-subs-video-resolution \"no\"", function() return stateSubPos(false) end, false, true},
  773. {RADIO, "Display in Video", "", "set image-subs-video-resolution \"yes\"", function() return stateSubPos(true) end, false, true},
  774. },
  775.  
  776. subscale_menu = {
  777. {COMMAND, "Reset", "", "no-osd set sub-pos 100 ; no-osd set sub-scale 1 ; show-text \"Subtitle Position - Reset\"", "", false, true},
  778. {SEP},
  779. {COMMAND, "+" .. opt.subScale .. "%", "Shift+K", "add sub-scale " .. (opt.subScale / 100), "", false, true},
  780. {COMMAND, "-" .. opt.subScale .. "%", "Shift+J", "add sub-scale -" .. (opt.subScale / 100), "", false, true},
  781. },
  782.  
  783. subsync_menu = {
  784. {COMMAND, "Reset", "Q", "no-osd set sub-delay 0 ; show-text \"Subtitle Delay - Reset\"", "", false, true},
  785. {SEP},
  786. {COMMAND, "+" .. opt.subSync .. " ms", "D", "add sub-delay +" .. (opt.subSync / 1000) .. "", "", false, true},
  787. {COMMAND, "-" .. opt.subSync .. " ms", "A", "add sub-delay -" .. (opt.subSync / 1000) .. "", "", false, true},
  788. },
  789.  
  790. etc_menu = {
  791. {CASCADE, etcmenushow , "playlist_menu", "", "", false},
  792. --{COMMAND, "Find Subtitle (Subit)", "", "script-binding subit", "", false},
  793. --{COMMAND, "Playback Information", "Tab", "script-binding display-stats-toggle", "", false, true},
  794. },
  795.  
  796. tools_menu = {
  797. {CASCADE, "Playlist", "playlist_menu", "", "", false},
  798. {COMMAND, "Find Subtitle (Subit)", "", "script-binding subit", "", false},
  799. {COMMAND, "Playback Information", "Tab", "script-binding display-stats-toggle", "", false, true},
  800. },
  801.  
  802. playlist_menu = {
  803. {COMMAND, "Show", "L", "script-binding showplaylist", "", false},
  804. {SEP},
  805. {COMMAND, "Open", "", "script-binding open_playlist_dialog", "", false},
  806. {COMMAND, "Save", "", "script-binding saveplaylist", "", false},
  807. {COMMAND, "Regenerate", "", "script-binding loadfiles", "", false},
  808. {COMMAND, "Clear", "Shift+L", "playlist-clear", "", false},
  809. {SEP},
  810. {COMMAND, "Append File", "", "script-binding append_files_dialog", "", false},
  811. {COMMAND, "Append URL", "", "script_binding append_url_dialog", "", false},
  812. {COMMAND, "Remove", "", "playlist-remove current", "", false, true},
  813. {SEP},
  814. {COMMAND, "Move Up", "", function() movePlaylist("up") end, "", function() return (propNative("playlist-count") < 2) and true or false end, true},
  815. {COMMAND, "Move Down", "", function() movePlaylist("down") end, "", function() return (propNative("playlist-count") < 2) and true or false end, true},
  816. {SEP},
  817. {CHECK, "Shuffle", "", "cycle shuffle", function() return propNative("shuffle") end, false, true},
  818. {CHECK, "Repeat", "", "cycle-values loop-playlist \"inf\" \"no\"", function() return statePlayLoop() end, false, true},
  819. },
  820.  
  821. window_menu = {
  822. {CASCADE, "Stays on Top", "staysontop_menu", "", "", false},
  823. {CHECK, "Remove Frame", "", "cycle border", function() return not propNative("border") end, false, true},
  824. {SEP},
  825. {COMMAND, "Toggle Fullscreen", "F", "cycle fullscreen", "", false, true},
  826. {COMMAND, "Enter Fullscreen", "", "set fullscreen \"yes\"", "", false, true},
  827. {COMMAND, "Exit Fullscreen", "Escape", "set fullscreen \"no\"", "", false, true},
  828. {SEP},
  829. {COMMAND, "Close", "Ctrl+W", "quit", "", false},
  830. },
  831.  
  832. staysontop_menu = {
  833. {COMMAND, "Select Next", "", "cycle ontop", "", false, true},
  834. {SEP},
  835. {RADIO, "Off", "", "set ontop \"yes\"", function() return stateOnTop(false) end, false, true},
  836. {RADIO, "On", "", "set ontop \"no\"", function() return stateOnTop(true) end, false, true},
  837. },
  838. }
  839.  
  840. -- This check ensures that all tables of data without SEP in them are 6 or 7 items long.
  841. for key, value in pairs(menuList) do
  842. -- Skip the 'file_loaded_menu' key as the following for loop will fail due to an
  843. -- attempt to get the length of a boolean value.
  844. if (key == "file_loaded_menu") then goto keyjump end
  845.  
  846. for i = 1, #value do
  847. if (value[i][1] ~= SEP) then
  848. if (#value[i] < 6 or #value[i] > 7) then mpdebug("Menu item at index of " .. i .. " is " .. #value[i] .. " items long for: " .. key) end
  849. end
  850. end
  851.  
  852. ::keyjump::
  853. end
  854. end)
  855.  
  856. --[[ ************ CONFIG: end ************ ]]--
  857.  
  858. local menuEngine = require "menu-engine"
  859.  
  860. mp.register_script_message("mpv_context_menu_tk", function()
  861. menuEngine.createMenu(menuList, "context_menu", -1, -1, "tk")
  862. end)
  863.  
  864. mp.register_script_message("mpv_context_menu_tk_static", function()
  865. menuEngine.createMenu(menuList, "context_menu", 2800, 1400, "tk")
  866. end)
  867.  
  868. mp.register_script_message("mpv_context_menu_gtk", function()
  869. menuEngine.createMenu(menuList, "context_menu", -1, -1, "gtk")
  870. end)
  871.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement