From 404a8f110d66416fa86fe20d74b6baaed2b6b7c6 Mon Sep 17 00:00:00 2001 From: stax76 Date: Thu, 8 Oct 2020 17:34:27 +0200 Subject: [PATCH 1/3] global media keys --- mpv.net/Misc/App.cs | 20 +++++++++++--------- mpv.net/Native/Native.cs | 11 ++++++++++- mpv.net/Resources/editor.toml.txt | 9 +++++++++ mpv.net/WinForms/MainForm.cs | 28 ++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/mpv.net/Misc/App.cs b/mpv.net/Misc/App.cs index 3255560..c766b71 100644 --- a/mpv.net/Misc/App.cs +++ b/mpv.net/Misc/App.cs @@ -14,7 +14,7 @@ namespace mpvnet { public static string[] VideoTypes { get; } = "264 265 asf avc avi avs flv h264 h265 hevc m2ts m2v m4v mkv mov mp4 mpeg mpg mpv mts ts vob vpy webm wmv y4m".Split(' '); public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(' '); - public static string[] ImageTypes { get; } = {"jpg", "bmp", "gif", "png"}; + public static string[] ImageTypes { get; } = { "jpg", "bmp", "gif", "png" }; public static string[] SubtitleTypes { get; } = { "srt", "ass", "idx", "sup", "ttxt", "ssa", "smi" }; public static string RegPath { get; } = @"HKCU\Software\" + Application.ProductName; @@ -32,6 +32,7 @@ namespace mpvnet public static bool AutoLoadFolder { get; set; } = true; public static bool Queue { get; set; } public static bool UpdateCheck { get; set; } + public static bool GlobalMediaKeys { get; set; } public static int StartThreshold { get; set; } = 1500; public static int RecentCount { get; set; } = 15; @@ -52,7 +53,7 @@ namespace mpvnet foreach (var i in Conf) ProcessProperty(i.Key, i.Value, true); - if (App.DebugMode) + if (DebugMode) { try { @@ -106,14 +107,14 @@ namespace mpvnet { if (obj is Exception e) { - if (App.IsStartedFromTerminal) + if (IsStartedFromTerminal) ConsoleHelp.WriteError(e.ToString()); else Msg.ShowException(e); } else { - if (App.IsStartedFromTerminal) + if (IsStartedFromTerminal) ConsoleHelp.WriteError(obj.ToString()); else Msg.ShowError(obj.ToString()); @@ -122,7 +123,7 @@ namespace mpvnet public static void ShowError(string title, string msg) { - if (App.IsStartedFromTerminal) + if (IsStartedFromTerminal) { ConsoleHelp.WriteError(title); ConsoleHelp.WriteError(msg); @@ -135,8 +136,8 @@ namespace mpvnet { if (RememberVolume) { - core.set_property_int("volume", RegistryHelp.GetInt(App.RegPath, "Volume", 70)); - core.set_property_string("mute", RegistryHelp.GetString(App.RegPath, "Mute", "no")); + core.set_property_int("volume", RegistryHelp.GetInt(RegPath, "Volume", 70)); + core.set_property_string("mute", RegistryHelp.GetString(RegPath, "Mute", "no")); } } @@ -144,8 +145,8 @@ namespace mpvnet { if (RememberVolume) { - RegistryHelp.SetValue(App.RegPath, "Volume", core.get_property_int("volume")); - RegistryHelp.SetValue(App.RegPath, "Mute", core.get_property_string("mute")); + RegistryHelp.SetValue(RegPath, "Volume", core.get_property_int("volume")); + RegistryHelp.SetValue(RegPath, "Mute", core.get_property_string("mute")); } } @@ -170,6 +171,7 @@ namespace mpvnet { switch (name) { + case "global-media-keys": GlobalMediaKeys = value == "yes"; return true; case "remember-position": RememberPosition = value == "yes"; return true; case "debug-mode": DebugMode = value == "yes"; return true; case "remember-volume": RememberVolume = value == "yes"; return true; diff --git a/mpv.net/Native/Native.cs b/mpv.net/Native/Native.cs index 2f8982f..e3d39de 100644 --- a/mpv.net/Native/Native.cs +++ b/mpv.net/Native/Native.cs @@ -5,6 +5,11 @@ using System.Runtime.InteropServices; public class WinAPI { + public const int VK_MEDIA_NEXT_TRACK = 0xB0; + public const int VK_MEDIA_PREV_TRACK = 0xB1; + public const int VK_MEDIA_STOP = 0xB2; + public const int VK_MEDIA_PLAY_PAUSE = 0xB3; + [DllImport("kernel32.dll")] public static extern bool AttachConsole(int dwProcessId); @@ -14,8 +19,12 @@ public class WinAPI [DllImport("kernel32.dll")] public static extern IntPtr LoadLibrary(string path); + [DllImport("user32")] + public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); + [DllImport("user32.dll", CharSet = CharSet.Unicode)] - public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle); + public static extern IntPtr FindWindowEx( + IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle); [DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); diff --git a/mpv.net/Resources/editor.toml.txt b/mpv.net/Resources/editor.toml.txt index ad746f3..52568fd 100644 --- a/mpv.net/Resources/editor.toml.txt +++ b/mpv.net/Resources/editor.toml.txt @@ -516,6 +516,15 @@ help = "For single files automatically load the entire directory into the playli options = [{ name = "yes" }, { name = "no" }] +[[settings]] +name = "global-media-keys" +file = "mpvnet" +default = "no" +filter = "Input" +help = "Enable global media keys next track, previous track, play/pause, stop. (mpv.net specific setting)" +options = [{ name = "yes" }, + { name = "no" }] + [[settings]] name = "input-ar-delay" file = "mpv" diff --git a/mpv.net/WinForms/MainForm.cs b/mpv.net/WinForms/MainForm.cs index 2504be4..dacca81 100644 --- a/mpv.net/WinForms/MainForm.cs +++ b/mpv.net/WinForms/MainForm.cs @@ -49,6 +49,9 @@ namespace mpvnet ConsoleHelp.Padding = 60; core.Init(); + if (App.GlobalMediaKeys) + RegisterGlobalMediaKeys(); + core.Shutdown += Shutdown; core.VideoSizeChanged += VideoSizeChanged; core.FileLoaded += FileLoaded; @@ -562,6 +565,23 @@ namespace mpvnet } } break; + case 0x0312: // WM_HOTKEY + switch (m.WParam.ToInt64()) + { + case WinAPI.VK_MEDIA_NEXT_TRACK: + core.command("keypress NEXT"); + break; + case WinAPI.VK_MEDIA_PREV_TRACK: + core.command("keypress PREV"); + break; + case WinAPI.VK_MEDIA_PLAY_PAUSE: + core.command("keypress PLAYPAUSE"); + break; + case WinAPI.VK_MEDIA_STOP: + core.command("keypress STOP"); + break; + } + break; case 0x0200: // WM_MOUSEMOVE if (Environment.TickCount - LastCycleFullscreen > 500) { @@ -750,6 +770,14 @@ namespace mpvnet } } + void RegisterGlobalMediaKeys() + { + WinAPI.RegisterHotKey(Handle, WinAPI.VK_MEDIA_NEXT_TRACK, 0, (uint)WinAPI.VK_MEDIA_NEXT_TRACK); + WinAPI.RegisterHotKey(Handle, WinAPI.VK_MEDIA_PREV_TRACK, 0, (uint)WinAPI.VK_MEDIA_PREV_TRACK); + WinAPI.RegisterHotKey(Handle, WinAPI.VK_MEDIA_PLAY_PAUSE, 0, (uint)WinAPI.VK_MEDIA_PLAY_PAUSE); + WinAPI.RegisterHotKey(Handle, WinAPI.VK_MEDIA_STOP, 0, (uint)WinAPI.VK_MEDIA_STOP); + } + protected override void OnLoad(EventArgs e) { base.OnLoad(e); From 94eaf8144fe0fecfeed6dafd0ac72582f46ace99 Mon Sep 17 00:00:00 2001 From: stax76 Date: Thu, 8 Oct 2020 17:56:49 +0200 Subject: [PATCH 2/3] cleanup --- mpv.net/Native/NativeHelp.cs | 36 +++++++++++++------------ mpv.net/WinForms/MainForm.cs | 52 ++++++++++++++++++------------------ mpv.net/mpv/Core.cs | 1 + 3 files changed, 46 insertions(+), 43 deletions(-) diff --git a/mpv.net/Native/NativeHelp.cs b/mpv.net/Native/NativeHelp.cs index f12d011..4522676 100644 --- a/mpv.net/Native/NativeHelp.cs +++ b/mpv.net/Native/NativeHelp.cs @@ -1,6 +1,8 @@  using System; +using static WinAPI; + namespace mpvnet { public static class NativeHelp @@ -9,31 +11,31 @@ namespace mpvnet { switch (v) { - case 1 /* WMSZ_LEFT */ : return 3; - case 3 /* WMSZ_TOP */ : return 2; - case 2 /* WMSZ_RIGHT */ : return 3; - case 6 /* WMSZ_BOTTOM */ : return 2; - case 4 /* WMSZ_TOPLEFT */ : return 1; - case 5 /* WMSZ_TOPRIGHT */ : return 1; - case 7 /* WMSZ_BOTTOMLEFT */ : return 3; - case 8 /* WMSZ_BOTTOMRIGHT */: return 3; + case 1 /* WMSZ_LEFT */ : return 3; + case 3 /* WMSZ_TOP */ : return 2; + case 2 /* WMSZ_RIGHT */ : return 3; + case 6 /* WMSZ_BOTTOM */ : return 2; + case 4 /* WMSZ_TOPLEFT */ : return 1; + case 5 /* WMSZ_TOPRIGHT */ : return 1; + case 7 /* WMSZ_BOTTOMLEFT */ : return 3; + case 8 /* WMSZ_BOTTOMRIGHT */ : return 3; default: return -1; } } - public static void SubtractWindowBorders(IntPtr hwnd, ref WinAPI.RECT rc) + public static void SubtractWindowBorders(IntPtr hwnd, ref RECT rc) { - var b = new WinAPI.RECT(0, 0, 0, 0); - AddWindowBorders(hwnd, ref b); - rc.Left -= b.Left; - rc.Top -= b.Top; - rc.Right -= b.Right; - rc.Bottom -= b.Bottom; + RECT r = new RECT(0, 0, 0, 0); + AddWindowBorders(hwnd, ref r); + rc.Left -= r.Left; + rc.Top -= r.Top; + rc.Right -= r.Right; + rc.Bottom -= r.Bottom; } - public static void AddWindowBorders(IntPtr hwnd, ref WinAPI.RECT rc) + public static void AddWindowBorders(IntPtr hwnd, ref RECT rc) { - WinAPI.AdjustWindowRect(ref rc, (uint)WinAPI.GetWindowLong(hwnd, -16 /* GWL_STYLE */), false); + AdjustWindowRect(ref rc, (uint)GetWindowLong(hwnd, -16 /* GWL_STYLE */), false); } } } diff --git a/mpv.net/WinForms/MainForm.cs b/mpv.net/WinForms/MainForm.cs index dacca81..27b63d5 100644 --- a/mpv.net/WinForms/MainForm.cs +++ b/mpv.net/WinForms/MainForm.cs @@ -12,6 +12,7 @@ using System.Diagnostics; using System.Threading.Tasks; using static mpvnet.Core; +using static WinAPI; namespace mpvnet { @@ -50,7 +51,12 @@ namespace mpvnet core.Init(); if (App.GlobalMediaKeys) - RegisterGlobalMediaKeys(); + { + RegisterGlobalKey(VK_MEDIA_NEXT_TRACK); + RegisterGlobalKey(VK_MEDIA_PREV_TRACK); + RegisterGlobalKey(VK_MEDIA_PLAY_PAUSE); + RegisterGlobalKey(VK_MEDIA_STOP); + } core.Shutdown += Shutdown; core.VideoSizeChanged += VideoSizeChanged; @@ -79,7 +85,7 @@ namespace mpvnet Application.ThreadException += (sender, e) => App.ShowException(e.Exception); Msg.SupportURL = "https://github.com/stax76/mpv.net#support"; Text = "mpv.net " + Application.ProductVersion; - TaskbarButtonCreatedMessage = WinAPI.RegisterWindowMessage("TaskbarButtonCreated"); + TaskbarButtonCreatedMessage = RegisterWindowMessage("TaskbarButtonCreated"); ContextMenu = new ContextMenuStripEx(components); ContextMenu.Opened += ContextMenu_Opened; @@ -370,7 +376,7 @@ namespace mpvnet } Point middlePos = new Point(Left + Width / 2, Top + Height / 2); - var rect = new WinAPI.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height)); + var rect = new RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height)); NativeHelp.AddWindowBorders(Handle, ref rect); int left = middlePos.X - rect.Width / 2; int top = middlePos.Y - rect.Height / 2; @@ -393,7 +399,7 @@ namespace mpvnet if (top + rect.Height > maxBottom) top = maxBottom - rect.Height; - WinAPI.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, + SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */); } @@ -414,7 +420,7 @@ namespace mpvnet Rectangle b = Screen.FromControl(this).Bounds; uint SWP_SHOWWINDOW = 0x0040; IntPtr HWND_TOP= IntPtr.Zero; - WinAPI.SetWindowPos(Handle, HWND_TOP, b.X, b.Y, b.Width, b.Height, SWP_SHOWWINDOW); + SetWindowPos(Handle, HWND_TOP, b.X, b.Y, b.Width, b.Height, SWP_SHOWWINDOW); } } } @@ -549,7 +555,7 @@ namespace mpvnet (Environment.TickCount - LastAppCommand) < 1000; if (core.WindowHandle != IntPtr.Zero && !skip) - m.Result = WinAPI.SendMessage(core.WindowHandle, m.Msg, m.WParam, m.LParam); + m.Result = SendMessage(core.WindowHandle, m.Msg, m.WParam, m.LParam); } break; case 0x319: // WM_APPCOMMAND @@ -568,16 +574,16 @@ namespace mpvnet case 0x0312: // WM_HOTKEY switch (m.WParam.ToInt64()) { - case WinAPI.VK_MEDIA_NEXT_TRACK: + case VK_MEDIA_NEXT_TRACK: core.command("keypress NEXT"); break; - case WinAPI.VK_MEDIA_PREV_TRACK: + case VK_MEDIA_PREV_TRACK: core.command("keypress PREV"); break; - case WinAPI.VK_MEDIA_PLAY_PAUSE: + case VK_MEDIA_PLAY_PAUSE: core.command("keypress PLAYPAUSE"); break; - case WinAPI.VK_MEDIA_STOP: + case VK_MEDIA_STOP: core.command("keypress STOP"); break; } @@ -607,13 +613,13 @@ namespace mpvnet if (!WasShown()) break; - WinAPI.RECT rect = Marshal.PtrToStructure(m.LParam); - WinAPI.SetWindowPos(Handle, IntPtr.Zero, rect.Left, rect.Top, rect.Width, rect.Height, 0); + RECT rect = Marshal.PtrToStructure(m.LParam); + SetWindowPos(Handle, IntPtr.Zero, rect.Left, rect.Top, rect.Width, rect.Height, 0); } break; case 0x0214: // WM_SIZING { - var rc = Marshal.PtrToStructure(m.LParam); + var rc = Marshal.PtrToStructure(m.LParam); var r = rc; NativeHelp.SubtractWindowBorders(Handle, ref r); int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top; @@ -633,13 +639,13 @@ namespace mpvnet if (corner >= 0) corners[corner] -= d_corners[corner]; - Marshal.StructureToPtr(new WinAPI.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false); + Marshal.StructureToPtr(new RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false); m.Result = new IntPtr(1); } return; case 0x004A: // WM_COPYDATA { - var copyData = (WinAPI.COPYDATASTRUCT)m.GetLParam(typeof(WinAPI.COPYDATASTRUCT)); + var copyData = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT)); string[] files = copyData.lpData.Split('\n'); string mode = files[0]; files = files.Skip(1).ToArray(); @@ -693,6 +699,8 @@ namespace mpvnet Taskbar.SetValue(core.get_property_number("time-pos"), core.Duration.TotalSeconds); } + void RegisterGlobalKey(int key) => RegisterHotKey(Handle, key, 0, (uint)key); + void PropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value)); void PropChangeAid(string value) => core.Aid = value; @@ -770,14 +778,6 @@ namespace mpvnet } } - void RegisterGlobalMediaKeys() - { - WinAPI.RegisterHotKey(Handle, WinAPI.VK_MEDIA_NEXT_TRACK, 0, (uint)WinAPI.VK_MEDIA_NEXT_TRACK); - WinAPI.RegisterHotKey(Handle, WinAPI.VK_MEDIA_PREV_TRACK, 0, (uint)WinAPI.VK_MEDIA_PREV_TRACK); - WinAPI.RegisterHotKey(Handle, WinAPI.VK_MEDIA_PLAY_PAUSE, 0, (uint)WinAPI.VK_MEDIA_PLAY_PAUSE); - WinAPI.RegisterHotKey(Handle, WinAPI.VK_MEDIA_STOP, 0, (uint)WinAPI.VK_MEDIA_STOP); - } - protected override void OnLoad(EventArgs e) { base.OnLoad(e); @@ -820,7 +820,7 @@ namespace mpvnet { base.OnActivated(e); Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP - WinAPI.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam); + SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam); } protected override void OnResize(EventArgs e) @@ -877,8 +877,8 @@ namespace mpvnet e.Button == MouseButtons.Left && !IsMouseInOSC()) { var HTCAPTION = new IntPtr(2); - WinAPI.ReleaseCapture(); - WinAPI.PostMessage(Handle, 0xA1 /* WM_NCLBUTTONDOWN */, HTCAPTION, IntPtr.Zero); + ReleaseCapture(); + PostMessage(Handle, 0xA1 /* WM_NCLBUTTONDOWN */, HTCAPTION, IntPtr.Zero); } if (Width - e.Location.X < 10 && e.Location.Y < 10) diff --git a/mpv.net/mpv/Core.cs b/mpv.net/mpv/Core.cs index e17cb30..d7d6afb 100644 --- a/mpv.net/mpv/Core.cs +++ b/mpv.net/mpv/Core.cs @@ -14,6 +14,7 @@ using System.Windows.Forms; using static libmpv; using static NewLine; + using System.Globalization; namespace mpvnet From 538e91aaa943fca1f380c92f57369129a2627a20 Mon Sep 17 00:00:00 2001 From: stax76 Date: Thu, 8 Oct 2020 18:07:23 +0200 Subject: [PATCH 3/3] New option global-media-keys --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index b170dd6..ea917a3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ - Load AviSynth DLL from environment variable AviSynthDLL in order to support AviSynth portable mode. +- New option global-media-keys (next, previous, play/pause, stop) 5.4.8.4 Beta