Compare commits

...

4 Commits

Author SHA1 Message Date
stax76
49f22a1f81 misc 2023-12-13 03:38:23 +01:00
stax76
7cd5686488 Trying getting decent menu input display 2023-12-13 00:57:59 +01:00
stax76
0d63feec57 Remove MS Store package from solution 2023-12-12 18:29:35 +01:00
stax76
0ee8318ca4 some bug fixes 2023-12-12 18:15:20 +01:00
20 changed files with 155 additions and 61 deletions

View File

@@ -1,4 +1,13 @@
# v7.0.0.2 Beta (2023-12-??)
- Fix dynamic menu items missing in context menu.
- Fix certain binding setups shown poorly or incorrect in the main menu.
- Fix conf editor not remembering the search text.
- Fix quit-watch-later not working.
- New option `menu-syntax`. Default: `#menu:`
- New zhongfly libmpv build.
# v7.0.0.1 Beta (2023-12-11)
- [.NET 6 is a new requirement](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)

View File

@@ -390,6 +390,10 @@ For single files automatically load the entire directory into the playlist.
### General
#### --menu-syntax=\<yes|no\>
Used menu syntax, typically `#menu:` or `#!`. Default: `#menu:`
#### --process-instance=\<value\>
Defines if more then one mpv.net process is allowed.

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -23,13 +23,13 @@
<TargetPlatformMinVersion>10.0.14393.0</TargetPlatformMinVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
<EntryPointProjectUniqueName>..\mpv.net.csproj</EntryPointProjectUniqueName>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
<GenerateTestArtifacts>True</GenerateTestArtifacts>
<AppxBundlePlatforms>x64</AppxBundlePlatforms>
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
<EntryPointProjectUniqueName>..\MpvNet.Windows\MpvNet.Windows.csproj</EntryPointProjectUniqueName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<AppxBundle>Always</AppxBundle>
@@ -43,20 +43,16 @@
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="..\bin\MediaInfo.dll">
<Link>mpv.net\MediaInfo.dll</Link>
<Content Include="..\MpvNet.Windows\bin\Debug\libmpv-2.dll">
<Link>libmpv-2.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\bin\Microsoft.Management.Infrastructure.dll">
<Link>mpv.net\Microsoft.Management.Infrastructure.dll</Link>
<Content Include="..\MpvNet.Windows\bin\Debug\MediaInfo.dll">
<Link>MediaInfo.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\bin\libmpv-2.dll">
<Link>mpv.net\libmpv-2.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\bin\mpvnet.com">
<Link>mpv.net\mpvnet.com</Link>
<Content Include="..\MpvNet.Windows\bin\Debug\mpvnet.com">
<Link>mpvnet.com</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\SplashScreen.scale-200.png" />
@@ -66,13 +62,12 @@
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\StoreLogo.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
<None Include="Package.StoreAssociation.xml" />
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
<ItemGroup>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.19041.8" PrivateAssets="all" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\mpv.net.csproj" />
<ProjectReference Include="..\MpvNet.Windows\MpvNet.Windows.csproj" />
</ItemGroup>
</Project>

View File

@@ -11,11 +11,19 @@
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>mpv-icon.ico</ApplicationIcon>
<Product>mpv.net</Product>
<AssemblyVersion>7.0.0.1</AssemblyVersion>
<FileVersion>7.0.0.1</FileVersion>
<AssemblyVersion>7.0.0.1</AssemblyVersion>
<InformationalVersion>7.0.0.1</InformationalVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Misc\**" />
<EmbeddedResource Remove="Misc\**" />
<None Remove="Misc\**" />
<Page Remove="Misc\**" />
</ItemGroup>
<ItemGroup>
<Content Include="mpv-icon.ico" />
</ItemGroup>
@@ -38,8 +46,4 @@
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.77" />
</ItemGroup>
<ItemGroup>
<Folder Include="Misc\" />
</ItemGroup>
</Project>

View File

@@ -38,9 +38,9 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
InitialContent = GetCompareString();
if (string.IsNullOrEmpty(App.Settings.ConfigEditorSearch))
SearchControl.Text = "General:";
SearchText = "General:";
else
SearchControl.Text = App.Settings.ConfigEditorSearch;
SearchText = App.Settings.ConfigEditorSearch;
foreach (var node in Nodes)
SelectNodeFromSearchText(node);
@@ -155,7 +155,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
App.Settings.ConfigEditorSearch = SearchControl.Text;
App.Settings.ConfigEditorSearch = SearchText;
if (InitialContent == GetCompareString())
return;
@@ -319,9 +319,6 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
}
}
if (!sb.ToString().Contains("# Editor"))
sb.AppendLine("# Editor");
foreach (Setting setting in Settings)
{
if (filename != setting.File || namesWritten.Contains(setting.Name!))
@@ -443,7 +440,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
void SelectNodeFromSearchText(NodeViewModel node)
{
if (node.Path + ":" == SearchControl.Text)
if (node.Path + ":" == SearchText)
{
node.IsSelected = true;
return;
@@ -470,7 +467,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged
ExpandNode(it);
}
[RelayCommand] void ShowMpvNetSpecificSettings() => SearchControl.Text = "mpv.net";
[RelayCommand] void ShowMpvNetSpecificSettings() => SearchText = "mpv.net";
[RelayCommand] void PreviewMpvConfFile() => Msg.ShowInfo(GetContent("mpv"));

View File

@@ -109,7 +109,7 @@ public partial class InputWindow : Window
else
{
newContent = InputHelp.ConvertToString(InputHelp.GetReducedBindings(Bindings));
newContent = newContent.Replace("#menu: ", "# ");
newContent = newContent.Replace(App.MenuSyntax + " ", "# ");
File.WriteAllText(App.InputConf.Path, App.InputConf.Content = newContent);
}

View File

@@ -27,7 +27,6 @@ public partial class MainForm : Form
public SnapManager SnapManager = new SnapManager();
public IntPtr MpvWindowHandle { get; set; }
public ElementHost? CommandPaletteHost { get; set; }
public Dictionary<string, WpfControls.MenuItem> MenuItemDuplicate = new Dictionary<string, WpfControls.MenuItem>();
public bool WasShown { get; set; }
public static MainForm? Instance { get; set; }
WpfControls.ContextMenu ContextMenu { get; } = new WpfControls.ContextMenu();
@@ -286,7 +285,7 @@ public partial class MainForm : Form
lock (Player.MediaTracksLock)
{
var trackMenuItem = FindMenuItem(_("Track"));
var trackMenuItem = FindMenuItem(_("Track"), "Track");
if (trackMenuItem != null)
{
@@ -348,7 +347,7 @@ public partial class MainForm : Form
}
}
var chaptersMenuItem = FindMenuItem(_("Chapter"));
var chaptersMenuItem = FindMenuItem(_("Chapter"), "Chapters");
if (chaptersMenuItem != null)
{
@@ -369,7 +368,7 @@ public partial class MainForm : Form
}
}
var recentMenuItem = FindMenuItem(_("Recent Files"));
var recentMenuItem = FindMenuItem(_("Recent Files"), "Recent");
if (recentMenuItem != null)
{
@@ -391,7 +390,7 @@ public partial class MainForm : Form
recentMenuItem.Items.Add(clearMenuItem);
}
var titlesMenuItem = FindMenuItem(_("Title"));
var titlesMenuItem = FindMenuItem(_("Title"), "Titles");
if (titlesMenuItem != null)
{
@@ -424,7 +423,7 @@ public partial class MainForm : Form
}
}
var profilesMenuItem = FindMenuItem(_("Profile"));
var profilesMenuItem = FindMenuItem(_("Profile"), "Profile");
if (profilesMenuItem != null && !profilesMenuItem.HasItems)
{
@@ -446,7 +445,7 @@ public partial class MainForm : Form
}
}
var customMenuItem = FindMenuItem(_("Custom"));
var customMenuItem = FindMenuItem(_("Custom"), "Custom");
if (customMenuItem != null)
{
@@ -476,7 +475,14 @@ public partial class MainForm : Form
}
}
public WpfControls.MenuItem? FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items);
public WpfControls.MenuItem? FindMenuItem(string text, string text2 = "") {
var ret = FindMenuItem(text, ContextMenu.Items);
if (ret == null && text2 != "")
return FindMenuItem(text2, ContextMenu.Items);
return ret;
}
WpfControls.MenuItem? FindMenuItem(string text, WpfControls.ItemCollection? items)
{
@@ -767,17 +773,12 @@ public partial class MainForm : Form
var (menuBindings, confBindings) = App.InputConf.GetBindings();
_confBindings = confBindings;
var activeBindings = InputHelp.GetActiveBindings(menuBindings);
foreach (Binding binding in menuBindings)
{
Binding tempBinding = binding;
if (MenuItemDuplicate.ContainsKey(tempBinding.Command) && tempBinding.Input != "")
{
var mi = MenuItemDuplicate[tempBinding.Command];
mi.InputGestureText = mi.InputGestureText + ", " + tempBinding.Input;
}
if (!binding.IsMenu)
continue;
@@ -785,9 +786,6 @@ public partial class MainForm : Form
if (menuItem != null)
{
if (tempBinding.Input != "")
MenuItemDuplicate[tempBinding.Command] = menuItem;
menuItem.Click += (sender, args) => {
try {
TaskHelp.Run(() => {
@@ -803,7 +801,7 @@ public partial class MainForm : Form
}
};
menuItem.InputGestureText = tempBinding.Input;
menuItem.InputGestureText = InputHelp.GetBindingsForCommand(activeBindings, tempBinding.Command);
}
}

View File

@@ -20,21 +20,77 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|ARM.ActiveCfg = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|ARM.Build.0 = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|ARM64.Build.0 = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|x64.ActiveCfg = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|x64.Build.0 = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|x86.ActiveCfg = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Debug|x86.Build.0 = Debug|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|Any CPU.Build.0 = Release|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|ARM.ActiveCfg = Release|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|ARM.Build.0 = Release|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|ARM64.ActiveCfg = Release|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|ARM64.Build.0 = Release|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|x64.ActiveCfg = Release|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|x64.Build.0 = Release|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|x86.ActiveCfg = Release|Any CPU
{ADC341B5-863A-4DFB-9352-475518FABE91}.Release|x86.Build.0 = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|ARM.ActiveCfg = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|ARM.Build.0 = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|ARM64.Build.0 = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|x64.ActiveCfg = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|x64.Build.0 = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|x86.ActiveCfg = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Debug|x86.Build.0 = Debug|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|Any CPU.Build.0 = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|ARM.ActiveCfg = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|ARM.Build.0 = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|ARM64.ActiveCfg = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|ARM64.Build.0 = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|x64.ActiveCfg = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|x64.Build.0 = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|x86.ActiveCfg = Release|Any CPU
{0B524801-DA28-433F-808D-3F74EF81EB53}.Release|x86.Build.0 = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|ARM.ActiveCfg = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|ARM.Build.0 = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|ARM64.Build.0 = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|x64.ActiveCfg = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|x64.Build.0 = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|x86.ActiveCfg = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Debug|x86.Build.0 = Debug|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|Any CPU.Build.0 = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|ARM.ActiveCfg = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|ARM.Build.0 = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|ARM64.ActiveCfg = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|ARM64.Build.0 = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|x64.ActiveCfg = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|x64.Build.0 = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|x86.ActiveCfg = Release|Any CPU
{0B7958FD-2138-482A-A21B-481AE7A0F851}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -20,6 +20,7 @@ public class AppClass
public string StartSize { get; set; } = "height-session";
public string Language { get; set; } = "system";
public string CommandLine { get; set; } = Environment.CommandLine;
public string MenuSyntax { get; set; } = "#menu:";
public bool AutoLoadFolder { get; set; } = true;
public bool DebugMode { get; set; }
@@ -145,6 +146,7 @@ public class AppClass
case "language": Language = value; return true;
case "light-theme": LightTheme = value.Trim('\'', '"'); return true;
case "media-info": MediaInfo = value == "yes"; return true;
case "menu-syntax": MenuSyntax = value; return true;
case "minimum-aspect-ratio-audio": MinimumAspectRatioAudio = value.ToFloat(); return true;
case "minimum-aspect-ratio": MinimumAspectRatio = value.ToFloat(); return true;
case "process-instance": ProcessInstance = value; return true;

View File

@@ -20,7 +20,7 @@ public class InputConf
}
}
public bool HasMenu => Content.Contains("#menu:") || Content.Contains("#! ");
public bool HasMenu => Content.Contains(App.MenuSyntax + " ");
public (List<Binding> menuBindings, List<Binding>? confBindings) GetBindings()
{

View File

@@ -321,18 +321,11 @@ public static class InputHelp
line = line[(line.IndexOf(" ") + 1)..];
if (line.Contains("#menu:"))
if (line.Contains(App.MenuSyntax))
{
binding.Comment = line[(line.IndexOf("#menu:") + 6)..].Trim();
binding.Comment = line[(line.IndexOf(App.MenuSyntax) + App.MenuSyntax.Length)..].Trim();
binding.IsMenu = true;
line = line[..line.IndexOf("#menu:")];
}
else if (line.Contains("#!"))
{
binding.Comment = line[(line.IndexOf("#!") + 2)..].Trim();
binding.IsMenu = true;
binding.IsShortMenuSyntax = true;
line = line[..line.IndexOf("#!")];
line = line[..line.IndexOf(App.MenuSyntax)];
}
else if (line.Contains("#custom-menu:"))
{
@@ -432,10 +425,10 @@ public static class InputHelp
value = value[(value.IndexOf(" ") + 1)..];
if (value.Contains("#menu:"))
if (value.Contains(App.MenuSyntax))
{
binding.Comment = value[(value.IndexOf("#menu:") + 6)..].Trim();
value = value[..value.IndexOf("#menu:")];
binding.Comment = value[(value.IndexOf(App.MenuSyntax) + App.MenuSyntax.Length)..].Trim();
value = value[..value.IndexOf(App.MenuSyntax)];
if (binding.Comment.Contains(';'))
binding.Comment = binding.Comment[(binding.Comment.IndexOf(";") + 1)..].Trim();
@@ -454,4 +447,41 @@ public static class InputHelp
}
return bindings;
}
public static Dictionary<string, Binding> GetActiveBindings(List<Binding> bindings)
{
Dictionary<string, Binding> ret = new();
foreach (Binding binding in bindings)
{
if (binding.Input == "" || binding.Command == "")
continue;
ret[binding.Input] = binding;
}
return ret;
}
public static string GetBindingsForCommand(Dictionary<string, Binding> activeBindings, string command)
{
List<string> keys = new();
int charCount = 0;
foreach (var it in activeBindings)
{
if (it.Value.Command != command)
continue;
Binding binding = it.Value;
if (!keys.Contains(binding.Input) && (charCount + binding.Input.Length) < 20 && keys.Count < 2)
{
keys.Add(binding.Input);
charCount += binding.Input.Length;
}
}
return string.Join(", ", keys);
}
}

View File

@@ -98,7 +98,6 @@ public class MainPlayer : MpvClient
SetPropertyBool("input-default-bindings", true);
SetPropertyBool("input-builtin-bindings", false);
SetPropertyString("watch-later-options", "mute");
SetPropertyString("screenshot-directory", "~~desktop/");
SetPropertyString("osd-playing-msg", "${media-title}");
SetPropertyString("osc", "yes");