Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add multi-instance support #380

Merged
merged 4 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Screenbox.Core/Services/ISettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public interface ISettingsService
int MaxVolume { get; set; }
string GlobalArguments { get; set; }
bool AdvancedMode { get; set; }
bool UseMultipleInstances { get; set; }
MediaPlaybackAutoRepeatMode PersistentRepeatMode { get; set; }
}
}
24 changes: 16 additions & 8 deletions Screenbox.Core/Services/SettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Screenbox.Core.Services
{
public sealed class SettingsService : ISettingsService
{
private readonly IPropertySet _settingsStorage = ApplicationData.Current.LocalSettings.Values;
private static IPropertySet SettingsStorage => ApplicationData.Current.LocalSettings.Values;

private const string PlayerAutoResizeKey = "Player/AutoResize";
private const string PlayerVolumeGestureKey = "Player/Gesture/Volume";
Expand All @@ -22,6 +22,7 @@ public sealed class SettingsService : ISettingsService
private const string LibrariesSearchRemovableStorageKey = "Libraries/SearchRemovableStorage";
private const string GeneralShowRecent = "General/ShowRecent";
private const string AdvancedModeKey = "Advanced/IsEnabled";
private const string AdvancedMultipleInstancesKey = "Advanced/MultipleInstances";
private const string GlobalArgumentsKey = "Values/GlobalArguments";
private const string PersistentVolumeKey = "Values/Volume";
private const string MaxVolumeKey = "Values/MaxVolume";
Expand Down Expand Up @@ -99,6 +100,12 @@ public bool AdvancedMode
set => SetValue(AdvancedModeKey, value);
}

public bool UseMultipleInstances
{
get => GetValue<bool>(AdvancedMultipleInstancesKey);
set => SetValue(AdvancedMultipleInstancesKey, value);
}

public SettingsService()
{
SetDefault(PlayerAutoResizeKey, (int)PlayerAutoResizeOption.Always);
Expand All @@ -112,6 +119,7 @@ public SettingsService()
SetDefault(GeneralShowRecent, true);
SetDefault(PersistentRepeatModeKey, (int)MediaPlaybackAutoRepeatMode.None);
SetDefault(AdvancedModeKey, false);
SetDefault(AdvancedMultipleInstancesKey, false);
SetDefault(GlobalArgumentsKey, string.Empty);

// Device family specific overrides
Expand All @@ -124,25 +132,25 @@ public SettingsService()
}
}

private T? GetValue<T>(string key)
private static T? GetValue<T>(string key)
{
if (_settingsStorage.TryGetValue(key, out object value))
if (SettingsStorage.TryGetValue(key, out object value))
{
return (T)value;
}

return default;
}

private void SetValue<T>(string key, T value)
private static void SetValue<T>(string key, T value)
{
_settingsStorage[key] = value;
SettingsStorage[key] = value;
}

private void SetDefault<T>(string key, T value)
private static void SetDefault<T>(string key, T value)
{
if (_settingsStorage.ContainsKey(key) && _settingsStorage[key] is T) return;
_settingsStorage[key] = value;
if (SettingsStorage.ContainsKey(key) && SettingsStorage[key] is T) return;
SettingsStorage[key] = value;
}

private static string SanitizeArguments(string raw)
Expand Down
7 changes: 7 additions & 0 deletions Screenbox.Core/ViewModels/SettingsPageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public sealed partial class SettingsPageViewModel : ObservableRecipient
[ObservableProperty] private bool _showRecent;
[ObservableProperty] private bool _searchRemovableStorage;
[ObservableProperty] private bool _advancedMode;
[ObservableProperty] private bool _useMultipleInstances;
[ObservableProperty] private string _globalArguments;
[ObservableProperty] private bool _isRelaunchRequired;

Expand Down Expand Up @@ -157,6 +158,12 @@ partial void OnAdvancedModeChanged(bool value)
IsRelaunchRequired = CheckForRelaunch();
}

partial void OnUseMultipleInstancesChanged(bool value)
{
_settingsService.UseMultipleInstances = value;
Messenger.Send(new SettingsChangedMessage(nameof(UseMultipleInstances)));
}

partial void OnGlobalArgumentsChanged(string value)
{
// No need to broadcast SettingsChangedMessage for this option
Expand Down
6 changes: 4 additions & 2 deletions Screenbox/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
IgnorableNamespaces="uap mp uap3">
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
IgnorableNamespaces="uap mp uap3 desktop4">

<Identity
Name="Screenbox"
Expand All @@ -32,7 +33,8 @@
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="Screenbox.App">
EntryPoint="Screenbox.App"
desktop4:SupportsMultipleInstances="true">
<uap:VisualElements
DisplayName="[Debug] Screenbox"
Square150x150Logo="Assets\Square150x150Logo.png"
Expand Down
7 changes: 7 additions & 0 deletions Screenbox/Pages/SettingsPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,13 @@

<!-- Advanced section -->
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{strings:Resources Key=SettingsCategoryAdvanced}" />
<ctc:SettingsCard
Margin="{StaticResource SettingsCardMargin}"
Description="{strings:Resources Key=SettingsUseMultipleInstancesDescription}"
Header="{strings:Resources Key=SettingsUseMultipleInstancesHeader}"
HeaderIcon="{ui:FontIcon Glyph=&#xE737;}">
<ToggleSwitch x:Name="UseMultipleInstancesToggleSwitch" IsOn="{x:Bind ViewModel.UseMultipleInstances, Mode=TwoWay}" />
</ctc:SettingsCard>
<ctc:SettingsExpander
Margin="{StaticResource SettingsCardMargin}"
Description="{strings:Resources Key=SettingsAdvancedModeDescription}"
Expand Down
58 changes: 58 additions & 0 deletions Screenbox/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#nullable enable

using Screenbox;
using Screenbox.Core.Helpers;
using Screenbox.Core.Services;
using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;

public static class Program
{
// This example code shows how you could implement the required Main method to
// support multi-instance redirection. The minimum requirement is to call
// Application.Start with a new App object. Beyond that, you may delete the
// rest of the example code and replace it with your custom code if you wish.

static void Main(string[] args)
{
// If the Windows shell indicates a recommended instance, then
// the app can choose to redirect this activation to that instance instead.
if (AppInstance.RecommendedInstance != null)
{
AppInstance.RecommendedInstance.RedirectActivationTo();
}
else
{
AppInstance instance;
var settingsService = new SettingsService();
var registeredInstances = AppInstance.GetInstances();
IActivatedEventArgs? activatedArgs = AppInstance.GetActivatedEventArgs(); // This is null on Xbox
bool isFileActivated = activatedArgs?.Kind == ActivationKind.File;
bool isFeatureEnabled = settingsService.UseMultipleInstances;
bool isXbox = SystemInformation.IsXbox;
if ((!isXbox && isFeatureEnabled && isFileActivated) || registeredInstances.Count == 0)
{
string key = Guid.NewGuid().ToString();
instance = AppInstance.FindOrRegisterInstanceForKey(key);
}
else
{
instance = registeredInstances[0];
}

if (instance.IsCurrentInstance)
{
// If we successfully registered this instance, we can now just
// go ahead and do normal XAML initialization.
Windows.UI.Xaml.Application.Start(p => new App());
}
else
{
// Some other instance has registered for this key, so we'll
// redirect this activation to that instance instead.
instance.RedirectActivationTo();
}
}
}
}
17 changes: 9 additions & 8 deletions Screenbox/Screenbox.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP;DISABLE_XAML_GENERATED_MAIN</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
Expand All @@ -42,7 +42,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP;DISABLE_XAML_GENERATED_MAIN</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
Expand All @@ -57,7 +57,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP;DISABLE_XAML_GENERATED_MAIN</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
Expand All @@ -69,7 +69,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP;DISABLE_XAML_GENERATED_MAIN</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
Expand All @@ -84,7 +84,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP;DISABLE_XAML_GENERATED_MAIN</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM64</PlatformTarget>
Expand All @@ -97,7 +97,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
<OutputPath>bin\ARM64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP;DISABLE_XAML_GENERATED_MAIN</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
Expand All @@ -112,7 +112,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<DefineConstants>TRACE;DEBUG;NETFX_CORE;WINDOWS_UWP;CODE_ANALYSIS;DISABLE_XAML_GENERATED_MAIN</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
Expand All @@ -124,7 +124,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP;DISABLE_XAML_GENERATED_MAIN</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
Expand Down Expand Up @@ -289,6 +289,7 @@
<Compile Include="Pages\VideosPage.xaml.cs">
<DependentUpon>VideosPage.xaml</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Secrets.cs" />
<Compile Include="Services\ResourceService.cs" />
Expand Down
28 changes: 28 additions & 0 deletions Screenbox/Strings/en-US/Resources.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2559,6 +2559,32 @@ public static string ActiveArguments
}
}
#endregion

#region SettingsUseMultipleInstancesHeader
/// <summary>
/// Looks up a localized string similar to: Allow multiple instances
/// </summary>
public static string SettingsUseMultipleInstancesHeader
{
get
{
return _resourceLoader.GetString("SettingsUseMultipleInstancesHeader");
}
}
#endregion

#region SettingsUseMultipleInstancesDescription
/// <summary>
/// Looks up a localized string similar to: Always open media files in a new instance
/// </summary>
public static string SettingsUseMultipleInstancesDescription
{
get
{
return _resourceLoader.GetString("SettingsUseMultipleInstancesDescription");
}
}
#endregion
}

[global::System.CodeDom.Compiler.GeneratedCodeAttribute("DotNetPlus.ReswPlus", "2.1.3")]
Expand Down Expand Up @@ -2765,6 +2791,8 @@ public enum KeyEnum
SettingsSearchRemovableStorageHeader,
SettingsSearchRemovableStorageDescription,
ActiveArguments,
SettingsUseMultipleInstancesHeader,
SettingsUseMultipleInstancesDescription,
}

private static ResourceLoader _resourceLoader;
Expand Down
6 changes: 6 additions & 0 deletions Screenbox/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -770,4 +770,10 @@
<data name="ActiveArguments" xml:space="preserve">
<value>Active arguments</value>
</data>
<data name="SettingsUseMultipleInstancesHeader" xml:space="preserve">
<value>Allow multiple instances</value>
</data>
<data name="SettingsUseMultipleInstancesDescription" xml:space="preserve">
<value>Always open media files in a new instance</value>
</data>
</root>
Loading