-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathboss-key.lua
104 lines (93 loc) · 3.76 KB
/
boss-key.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
--[[
* boss-key.lua v1.0.3
* (Older versions will lack a version number)
*
* AUTHOR: detuur, zaza42
* License: MIT
* link: https://github.com/detuur/mpv-scripts
*
* This script minimises and pauses the window when
* the boss key (default 'b') is pressed.
* Can be overwriten in input.conf as follows:
* KEY script-binding boss-key
* xdotool is required on Xorg(Linux)
--]]
utils = require 'mp.utils'
local platform = nil --set to 'linux', 'windows' or 'macos' to override automatic assign
if not platform then
local o = {}
if mp.get_property_native('options/vo-mmcss-profile', o) ~= o then
platform = 'windows'
elseif mp.get_property_native('options/macos-force-dedicated-gpu', o) ~= o then
platform = 'macos'
else
platform = 'linux'
end
end
-- TODO: macOS implementation?
function boss_key()
mp.set_property_native("pause", true)
if platform == 'windows' then
mp.command([[run cmd /c echo m > \\.\pipe\mpv-boss-key-]]..utils.getpid())
elseif platform == 'macos' then
utils.subprocess({ args = {'osascript', '-e', 'tell application "System Events" to set the visible of the first process whose frontmost is true to false'} })
elseif platform == 'linux' then
utils.subprocess({ args = {'xdotool', 'getactivewindow', 'windowminimize'} })
end
end
-- The only way to minimize the window in Windows is through a compiled Win32
-- API call. So we open an async powershell session, define the function call,
-- compile it, and then wait for a signal from this script to execute the call.
-- Signaling is done through named pipes, which to my surprise were present on
-- Windows. Not to my surprise, they didn't work reliably. Writing to the pipe
-- from PS or CMD yields different results, for example. In addition, PS's
-- Events and other async were extremely finnicky. Because of these reasons,
-- and after many, many rewrites, I've arrived at the unorthodox mess that is
-- the code below. It's not pretty, but at l(e)ast it works reliably.
if platform == 'windows' then
mp.command_native_async({
name = "subprocess",
playback_only = false,
detach = true,
args = {'powershell', '-NoProfile', '-Command', [[&{
$bosspid = ]]..utils.getpid()..[[
# Construct the named pipe's name
$pipename = -join('mpv-boss-key-',$bosspid)
$fullpipename = -join("\\.\pipe\", $pipename)
# This will run in a separate thread
$minimizeloop = {
param($pipename, $bosspid)
# Create the named pipe
$pipe = new-object System.IO.Pipes.NamedPipeServerStream($pipename)
# Compile the Win32 API function call
$signature='[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
$showWindowAsync = Add-Type -memberDefinition $signature -name "Win32ShowWindowAsync" -namespace Win32Functions -passThru
# The core loop
while($true) {
$pipe.WaitForConnection()
if ($pipe.ReadByte() -ne 109) {
break
}
$pipe.Disconnect()
$showWindowAsync::ShowWindowAsync((Get-Process -id $bosspid).MainWindowHandle, 2)
}
$pipe.Dispose()
}
# Exiting this monstrosity (THANKS POWERSHELL FOR BROKEN ASYNC) is surprisingly
# cumbersome. It took literal hours to find something that didn't spontaneously
# combust.
$bossproc = Get-Process -pid $bosspid -ErrorAction SilentlyContinue
$exitsequence = {
&{echo q > $fullpipename} 2> $null
[Environment]::Exit(0)
}
if ((-Not $bossproc) -or $bossproc.HasExited) { $exitsequence.Invoke() }
# Begin watching for events until boss closes
Start-Job -ScriptBlock $minimizeloop -Name "mpvminloop" -ArgumentList $pipename,$bosspid
while($true) {
Start-Sleep 1
if ($bossproc.HasExited) { $exitsequence.Invoke() }
}
}]]}}, function()end)
end
mp.add_key_binding('b', 'boss-key', boss_key)