full implementation for window-minimized and window-maximized
This commit is contained in:
@@ -2,9 +2,10 @@
|
||||
5.4.4.4 Beta (not yet released)
|
||||
============
|
||||
|
||||
- with `border=no` the osc top bar window buttons min, max, close did not work.
|
||||
- some anamorphic videos were shown with black bars
|
||||
- crash fixed when PowerShell 5.1 is not available
|
||||
- with `border=no` the OSC top bar window buttons min, max and close are supported.
|
||||
- anamorphic videos are shown without black bars, the window is resized according to the ascpect ratio.
|
||||
- PowerShell 5.1 was made optional.
|
||||
- full implementation for `window-minimized` and `window-maximized`
|
||||
|
||||
|
||||
5.4.4.3 Beta
|
||||
|
||||
31
Manual.md
31
Manual.md
@@ -102,8 +102,9 @@ Table of contents
|
||||
+ [Exit](#exit)
|
||||
+ [Exit Watch Later](#exit-watch-later)
|
||||
|
||||
About mpv.net
|
||||
-------------
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
mpv.net is a modern desktop media player for Windows. mpv is similar to VLC not based on DirectShow like MPC, mpv.net is based on libmpv which in return is based on ffmpeg.
|
||||
|
||||
@@ -189,7 +190,8 @@ The config folder can be opened from the context menu.
|
||||
Command Line Interface
|
||||
----------------------
|
||||
|
||||
`mpvnet --mute=yes <file|URL>`
|
||||
mpvnet [options] [file|URL|PLAYLIST|-]
|
||||
mpvnet [options] files
|
||||
|
||||
|
||||
mpv properties can be set with the same syntax as mpv, that is:
|
||||
@@ -352,17 +354,21 @@ Pressing the shift key while opening a single file will suppress loading all fil
|
||||
Differences
|
||||
-----------
|
||||
|
||||
mpv.net was designed to work exactly like mpv, there are few limitations:
|
||||
mpv.net is designed to work exactly like mpv, there are a few limitations:
|
||||
|
||||
|
||||
### Window Limitations
|
||||
|
||||
mpv.net implements an own main window and because of that all window related features of mpv are not available unless mpv.net has an own implementation. Find the documentation of mpvs window related features here:
|
||||
mpv.net implements an own main window which means only mpv window features are supported that have an own implementation in mpv.net.
|
||||
|
||||
A window free mode is currently not supported.
|
||||
|
||||
The documentation of mpvs window features can be found here:
|
||||
|
||||
<https://mpv.io/manual/master/#window>
|
||||
|
||||
|
||||
mpv.net has currently implemented the following window related features:
|
||||
mpv.net has currently implemented the following window features:
|
||||
|
||||
[screen](https://mpv.io/manual/master/#options-screen)
|
||||
|
||||
@@ -372,15 +378,18 @@ mpv.net has currently implemented the following window related features:
|
||||
|
||||
[border](https://mpv.io/manual/master/#options-border)
|
||||
|
||||
[autofit](https://mpv.io/manual/master/#options-autofit) (only partly implemented)
|
||||
[window-minimized](https://mpv.io/manual/master/#options-window-minimized)
|
||||
|
||||
[autofit-smaller](https://mpv.io/manual/master/#options-autofit-smaller) (only partly implemented)
|
||||
[window-maximized](https://mpv.io/manual/master/#options-window-maximized)
|
||||
|
||||
[autofit-larger](https://mpv.io/manual/master/#options-autofit-larger) (only partly implemented)
|
||||
|
||||
[window-minimized](https://mpv.io/manual/master/#options-window-minimized) (only partly implemented, use Win+Up and Win+Down)
|
||||
**Partly implemented are:**
|
||||
|
||||
[window-maximized](https://mpv.io/manual/master/#options-window-maximized) (only partly implemented, use Win+Up and Win+Down)
|
||||
[autofit](https://mpv.io/manual/master/#options-autofit)
|
||||
|
||||
[autofit-smaller](https://mpv.io/manual/master/#options-autofit-smaller)
|
||||
|
||||
[autofit-larger](https://mpv.io/manual/master/#options-autofit-larger)
|
||||
|
||||
|
||||
### Command Line Limitations
|
||||
|
||||
@@ -8,7 +8,6 @@ using System.Windows.Forms;
|
||||
using UI;
|
||||
|
||||
using static libmpv;
|
||||
using static NewLine;
|
||||
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public class WinAPI
|
||||
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
||||
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
@@ -21,10 +21,11 @@ namespace mpvnet
|
||||
public static MainForm Instance { get; set; }
|
||||
public static IntPtr Hwnd { get; set; }
|
||||
public new ContextMenuStripEx ContextMenu { get; set; }
|
||||
Point LastCursorPosChanged;
|
||||
int LastCursorChangedTickCount;
|
||||
Point LastCursorPosition;
|
||||
int LastCursorChanged;
|
||||
int TaskbarButtonCreatedMessage;
|
||||
int ShownTickCount;
|
||||
|
||||
DateTime LastCycleFullscreen;
|
||||
Taskbar Taskbar;
|
||||
List<string> RecentFiles;
|
||||
@@ -54,8 +55,8 @@ namespace mpvnet
|
||||
mp.Idle += Idle;
|
||||
mp.Seek += () => UpdateProgressBar();
|
||||
|
||||
mp.observe_property_bool("window-maximized", PropChangeWindowMaximized);
|
||||
mp.observe_property_bool("window-minimized", PropChangeWindowMinimized);
|
||||
mp.observe_property("window-maximized", PropChangeWindowMaximized);
|
||||
mp.observe_property("window-minimized", PropChangeWindowMinimized);
|
||||
mp.observe_property_bool("pause", PropChangePause);
|
||||
mp.observe_property_bool("fullscreen", PropChangeFullscreen);
|
||||
mp.observe_property_bool("ontop", PropChangeOnTop);
|
||||
@@ -112,6 +113,15 @@ namespace mpvnet
|
||||
SetFormPosAndSize(1, true);
|
||||
WindowState = FormWindowState.Maximized;
|
||||
}
|
||||
|
||||
if (mp.WindowMinimized)
|
||||
{
|
||||
SetFormPosAndSize(1, true);
|
||||
WindowState = FormWindowState.Minimized;
|
||||
}
|
||||
|
||||
if (!mp.Border)
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -276,7 +286,7 @@ namespace mpvnet
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
if (WindowState == FormWindowState.Maximized)
|
||||
if (WindowState == FormWindowState.Maximized || WindowState == FormWindowState.Minimized)
|
||||
return;
|
||||
|
||||
if (mp.Fullscreen)
|
||||
@@ -379,6 +389,14 @@ namespace mpvnet
|
||||
{
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
WindowState = FormWindowState.Maximized;
|
||||
|
||||
if (WasMaximized)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -466,6 +484,16 @@ namespace mpvnet
|
||||
RecentFiles.RemoveAt(App.RecentCount);
|
||||
}
|
||||
|
||||
void SaveWindowProperties()
|
||||
{
|
||||
if (WindowState == FormWindowState.Normal)
|
||||
{
|
||||
RegistryHelp.SetValue(App.RegPath, "PosX", Left + Width / 2);
|
||||
RegistryHelp.SetValue(App.RegPath, "PosY", Top + Height / 2);
|
||||
RegistryHelp.SetValue(App.RegPath, "Height", ClientSize.Height);
|
||||
}
|
||||
}
|
||||
|
||||
protected override CreateParams CreateParams {
|
||||
get {
|
||||
CreateParams cp = base.CreateParams;
|
||||
@@ -503,7 +531,7 @@ namespace mpvnet
|
||||
mp.command($"mouse {pos.X} {pos.Y}");
|
||||
}
|
||||
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosition))
|
||||
CursorHelp.Show();
|
||||
}
|
||||
break;
|
||||
@@ -585,12 +613,12 @@ namespace mpvnet
|
||||
|
||||
void CursorTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosition))
|
||||
{
|
||||
LastCursorPosChanged = Control.MousePosition;
|
||||
LastCursorChangedTickCount = Environment.TickCount;
|
||||
LastCursorPosition = Control.MousePosition;
|
||||
LastCursorChanged = Environment.TickCount;
|
||||
}
|
||||
else if (Environment.TickCount - LastCursorChangedTickCount > 1500 &&
|
||||
else if (Environment.TickCount - LastCursorChanged > 1500 &&
|
||||
!IsMouseInOSC() && ClientRectangle.Contains(PointToClient(MousePosition)) &&
|
||||
Form.ActiveForm == this && !ContextMenu.Visible)
|
||||
|
||||
@@ -624,15 +652,15 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
|
||||
void PropChangeWindowMaximized(bool enabled)
|
||||
void PropChangeWindowMaximized()
|
||||
{
|
||||
if (!WasShown())
|
||||
return;
|
||||
|
||||
mp.WindowMaximized = enabled;
|
||||
|
||||
BeginInvoke(new Action(() =>
|
||||
{
|
||||
mp.WindowMaximized = mp.get_property_bool("window-maximized");
|
||||
|
||||
if (mp.WindowMaximized && WindowState != FormWindowState.Maximized)
|
||||
WindowState = FormWindowState.Maximized;
|
||||
else if (!mp.WindowMaximized && WindowState == FormWindowState.Maximized)
|
||||
@@ -640,16 +668,18 @@ namespace mpvnet
|
||||
}));
|
||||
}
|
||||
|
||||
void PropChangeWindowMinimized(bool enabled)
|
||||
void PropChangeWindowMinimized()
|
||||
{
|
||||
if (!WasShown())
|
||||
return;
|
||||
|
||||
BeginInvoke(new Action(() =>
|
||||
{
|
||||
if (enabled && WindowState != FormWindowState.Minimized)
|
||||
mp.WindowMinimized = mp.get_property_bool("window-minimized");
|
||||
|
||||
if (mp.WindowMinimized && WindowState != FormWindowState.Minimized)
|
||||
WindowState = FormWindowState.Minimized;
|
||||
else if (!enabled && WindowState == FormWindowState.Minimized)
|
||||
else if (!mp.WindowMinimized && WindowState == FormWindowState.Minimized)
|
||||
WindowState = FormWindowState.Normal;
|
||||
}));
|
||||
}
|
||||
@@ -729,12 +759,32 @@ namespace mpvnet
|
||||
if (mp.IsLogoVisible)
|
||||
mp.ShowLogo();
|
||||
|
||||
if (WindowState == FormWindowState.Maximized && FormBorderStyle != FormBorderStyle.None)
|
||||
if (FormBorderStyle != FormBorderStyle.None)
|
||||
{
|
||||
if (WindowState == FormWindowState.Maximized)
|
||||
WasMaximized = true;
|
||||
else if (WindowState == FormWindowState.Normal && FormBorderStyle != FormBorderStyle.None)
|
||||
else if (WindowState == FormWindowState.Normal)
|
||||
WasMaximized = false;
|
||||
}
|
||||
|
||||
if (WasShown())
|
||||
{
|
||||
if (WindowState == FormWindowState.Minimized)
|
||||
{
|
||||
mp.set_property_string("window-minimized", "yes");
|
||||
}
|
||||
else if (WindowState == FormWindowState.Normal)
|
||||
{
|
||||
mp.set_property_string("window-maximized", "no");
|
||||
mp.set_property_string("window-minimized", "no");
|
||||
}
|
||||
else if (WindowState == FormWindowState.Maximized)
|
||||
{
|
||||
mp.set_property_string("window-maximized", "yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
{
|
||||
base.OnFormClosing(e);
|
||||
@@ -756,16 +806,6 @@ namespace mpvnet
|
||||
} catch {}
|
||||
}
|
||||
|
||||
void SaveWindowProperties()
|
||||
{
|
||||
if (WindowState == FormWindowState.Normal)
|
||||
{
|
||||
RegistryHelp.SetValue(App.RegPath, "PosX", Left + Width / 2);
|
||||
RegistryHelp.SetValue(App.RegPath, "PosY", Top + Height / 2);
|
||||
RegistryHelp.SetValue(App.RegPath, "Height", ClientSize.Height);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace mpvnet
|
||||
|
||||
public static event Action Initialized;
|
||||
|
||||
public static List<KeyValuePair<string, Action>> PropChangeActions { get; set; } = new List<KeyValuePair<string, Action>>();
|
||||
public static List<KeyValuePair<string, Action<bool>>> BoolPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<bool>>>();
|
||||
public static List<KeyValuePair<string, Action<int>>> IntPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<int>>>();
|
||||
public static List<KeyValuePair<string, Action<double>>> DoublePropChangeActions { get; set; } = new List<KeyValuePair<string, Action<double>>>();
|
||||
@@ -87,6 +88,7 @@ namespace mpvnet
|
||||
public static bool IsQuitNeeded { set; get; } = true;
|
||||
public static bool TaskbarProgress { get; set; } = true;
|
||||
public static bool WindowMaximized { get; set; }
|
||||
public static bool WindowMinimized { get; set; }
|
||||
|
||||
public static int Screen { get; set; } = -1;
|
||||
public static int Edition { get; set; }
|
||||
@@ -153,6 +155,7 @@ namespace mpvnet
|
||||
case "fullscreen": Fullscreen = value == "yes"; break;
|
||||
case "border": Border = value == "yes"; break;
|
||||
case "window-maximized": WindowMaximized = value == "yes"; break;
|
||||
case "window-minimized": WindowMinimized = value == "yes"; break;
|
||||
case "taskbar-progress": TaskbarProgress = value == "yes"; break;
|
||||
case "screen": Screen = Convert.ToInt32(value); break;
|
||||
case "gpu-api": GPUAPI = value; break;
|
||||
@@ -466,6 +469,13 @@ namespace mpvnet
|
||||
if (i.Key == data.name)
|
||||
i.Value.Invoke(Marshal.PtrToStructure<int>(data.data));
|
||||
}
|
||||
else if (data.format == mpv_format.MPV_FORMAT_NONE)
|
||||
{
|
||||
lock (PropChangeActions)
|
||||
foreach (var i in PropChangeActions)
|
||||
if (i.Key == data.name)
|
||||
i.Value.Invoke();
|
||||
}
|
||||
else if (data.format == mpv_format.MPV_FORMAT_DOUBLE)
|
||||
{
|
||||
lock (DoublePropChangeActions)
|
||||
@@ -598,6 +608,17 @@ namespace mpvnet
|
||||
return lpBuffer.ToInt32();
|
||||
}
|
||||
|
||||
public static bool get_property_bool(string name, bool throwException = false)
|
||||
{
|
||||
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||
mpv_format.MPV_FORMAT_FLAG, out IntPtr lpBuffer);
|
||||
|
||||
if (err < 0)
|
||||
HandleError(err, throwException, $"error getting property: {name}");
|
||||
|
||||
return lpBuffer.ToInt32() != 0;
|
||||
}
|
||||
|
||||
public static double get_property_number(string name, bool throwException = false)
|
||||
{
|
||||
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||
@@ -666,6 +687,18 @@ namespace mpvnet
|
||||
StringPropChangeActions.Add(new KeyValuePair<string, Action<string>>(name, action));
|
||||
}
|
||||
|
||||
public static void observe_property(string name, Action action)
|
||||
{
|
||||
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||
name, mpv_format.MPV_FORMAT_NONE);
|
||||
|
||||
if (err < 0)
|
||||
HandleError(err, true, $"error observing property: {name}");
|
||||
else
|
||||
lock (PropChangeActions)
|
||||
PropChangeActions.Add(new KeyValuePair<string, Action>(name, action));
|
||||
}
|
||||
|
||||
public static void HandleError(mpv_error err, bool throwException, params string[] messages)
|
||||
{
|
||||
if (throwException)
|
||||
|
||||
37
scripts/examples/dynamic-context-menu-items.cs
Normal file
37
scripts/examples/dynamic-context-menu-items.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
// creates context menu items dynamically
|
||||
|
||||
using mpvnet;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
class Script
|
||||
{
|
||||
MainForm MainForm;
|
||||
|
||||
public Script()
|
||||
{
|
||||
MainForm = mpvnet.MainForm.Instance;
|
||||
MainForm.ContextMenu.Opening += ContextMenu_Opening;
|
||||
}
|
||||
|
||||
void ContextMenu_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
// edit input.conf and add 'Edition' menu item there
|
||||
MenuItem menuItem = MainForm.FindMenuItem("Edition");
|
||||
|
||||
if (menuItem == null)
|
||||
return;
|
||||
|
||||
menuItem.DropDownItems.Clear();
|
||||
var editionTracks = mp.MediaTracks.Where(track => track.Type == "e");
|
||||
|
||||
foreach (MediaTrack track in editionTracks)
|
||||
{
|
||||
MenuItem mi = new MenuItem(track.Text);
|
||||
mi.Action = () => { mp.commandv("set", "edition", track.ID.ToString()); };
|
||||
mi.Checked = mp.Edition == track.ID;
|
||||
menuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
}
|
||||
}
|
||||
19
scripts/examples/pause-when-minimize.lua
Normal file
19
scripts/examples/pause-when-minimize.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
local did_minimize = false
|
||||
|
||||
mp.observe_property("window-minimized", "bool", function(name, value)
|
||||
local pause = mp.get_property_bool("pause")
|
||||
|
||||
if value == true then
|
||||
if pause == false then
|
||||
mp.set_property_bool("pause", true)
|
||||
did_minimize = true
|
||||
end
|
||||
elseif value == false then
|
||||
if did_minimize and (pause == true) then
|
||||
mp.set_property_bool("pause", false)
|
||||
end
|
||||
|
||||
did_minimize = false
|
||||
end
|
||||
end)
|
||||
Reference in New Issue
Block a user