From a95d51b8b3ac707fb58e08f29dd98cea13248b0d Mon Sep 17 00:00:00 2001 From: donlaci Date: Wed, 8 Jan 2025 18:31:52 +0100 Subject: [PATCH 1/2] [Workspaces] implement Launch on startup feature --- .../WorkspacesEditor/Data/ProjectData.cs | 2 + .../WorkspacesEditor/Models/Project.cs | 4 ++ .../Properties/Resources.Designer.cs | 9 ++++ .../Properties/Resources.resx | 3 ++ .../WorkspacesEditor/Utils/FolderUtils.cs | 5 +++ .../Utils/WorkspacesEditorIO.cs | 1 + .../ViewModels/MainViewModel.cs | 43 ++++++++++++------- .../WorkspacesEditorPage.xaml | 6 +++ .../WorkspacesLib/WorkspacesData.cpp | 7 +++ .../Workspaces/WorkspacesLib/WorkspacesData.h | 1 + 10 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/modules/Workspaces/WorkspacesEditor/Data/ProjectData.cs b/src/modules/Workspaces/WorkspacesEditor/Data/ProjectData.cs index 050591591a04..a09b19794c00 100644 --- a/src/modules/Workspaces/WorkspacesEditor/Data/ProjectData.cs +++ b/src/modules/Workspaces/WorkspacesEditor/Data/ProjectData.cs @@ -89,6 +89,8 @@ public struct ProjectWrapper public bool IsShortcutNeeded { get; set; } + public bool IsLaunchOnStartup { get; set; } + public bool MoveExistingWindows { get; set; } public List MonitorConfiguration { get; set; } diff --git a/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs b/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs index 0c44440d394e..1713ff5d4340 100644 --- a/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs +++ b/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs @@ -45,6 +45,8 @@ public string Name public bool IsShortcutNeeded { get; set; } + public bool IsLaunchOnStartup { get; set; } + public bool MoveExistingWindows { get; set; } public string LastLaunched @@ -205,6 +207,7 @@ public Project(Project selectedProject) PreviewIcons = selectedProject.PreviewIcons; PreviewImage = selectedProject.PreviewImage; IsShortcutNeeded = selectedProject.IsShortcutNeeded; + IsLaunchOnStartup = selectedProject.IsLaunchOnStartup; MoveExistingWindows = selectedProject.MoveExistingWindows; int screenIndex = 1; @@ -233,6 +236,7 @@ public Project(ProjectData.ProjectWrapper project) CreationTime = project.CreationTime; LastLaunchedTime = project.LastLaunchedTime; IsShortcutNeeded = project.IsShortcutNeeded; + IsLaunchOnStartup = project.IsLaunchOnStartup; MoveExistingWindows = project.MoveExistingWindows; Monitors = []; Applications = []; diff --git a/src/modules/Workspaces/WorkspacesEditor/Properties/Resources.Designer.cs b/src/modules/Workspaces/WorkspacesEditor/Properties/Resources.Designer.cs index f444c1dd2f6e..673959832ebb 100644 --- a/src/modules/Workspaces/WorkspacesEditor/Properties/Resources.Designer.cs +++ b/src/modules/Workspaces/WorkspacesEditor/Properties/Resources.Designer.cs @@ -591,6 +591,15 @@ public static string SelectedAllInWorkspace { } } + /// + /// Looks up a localized string similar to Launch on startup. + /// + public static string ShouldLaunchOnStartup { + get { + return ResourceManager.GetString("ShouldLaunchOnStartup", resourceCulture); + } + } + /// /// Looks up a localized string similar to Edit your layout and click "Capture" when finished.. /// diff --git a/src/modules/Workspaces/WorkspacesEditor/Properties/Resources.resx b/src/modules/Workspaces/WorkspacesEditor/Properties/Resources.resx index fc7079e9b641..0af9aac6f64d 100644 --- a/src/modules/Workspaces/WorkspacesEditor/Properties/Resources.resx +++ b/src/modules/Workspaces/WorkspacesEditor/Properties/Resources.resx @@ -157,6 +157,9 @@ Create desktop shortcut + + Launch on startup + Custom diff --git a/src/modules/Workspaces/WorkspacesEditor/Utils/FolderUtils.cs b/src/modules/Workspaces/WorkspacesEditor/Utils/FolderUtils.cs index fc12593e0985..c911bc4b494f 100644 --- a/src/modules/Workspaces/WorkspacesEditor/Utils/FolderUtils.cs +++ b/src/modules/Workspaces/WorkspacesEditor/Utils/FolderUtils.cs @@ -14,6 +14,11 @@ public static string Desktop() return Environment.GetFolderPath(Environment.SpecialFolder.Desktop); } + public static string Startup() + { + return Environment.GetFolderPath(Environment.SpecialFolder.Startup); + } + public static string Temp() { return Path.GetTempPath(); diff --git a/src/modules/Workspaces/WorkspacesEditor/Utils/WorkspacesEditorIO.cs b/src/modules/Workspaces/WorkspacesEditor/Utils/WorkspacesEditorIO.cs index c467259521f5..8b5e81874d3c 100644 --- a/src/modules/Workspaces/WorkspacesEditor/Utils/WorkspacesEditorIO.cs +++ b/src/modules/Workspaces/WorkspacesEditor/Utils/WorkspacesEditorIO.cs @@ -87,6 +87,7 @@ public void SerializeWorkspaces(List workspaces, bool useTempFile = fal Name = project.Name, CreationTime = project.CreationTime, IsShortcutNeeded = project.IsShortcutNeeded, + IsLaunchOnStartup = project.IsLaunchOnStartup, MoveExistingWindows = project.MoveExistingWindows, LastLaunchedTime = project.LastLaunchedTime, Applications = [], diff --git a/src/modules/Workspaces/WorkspacesEditor/ViewModels/MainViewModel.cs b/src/modules/Workspaces/WorkspacesEditor/ViewModels/MainViewModel.cs index ccee84c9c516..d6c8fe3a5df4 100644 --- a/src/modules/Workspaces/WorkspacesEditor/ViewModels/MainViewModel.cs +++ b/src/modules/Workspaces/WorkspacesEditor/ViewModels/MainViewModel.cs @@ -181,6 +181,7 @@ public void SaveProject(Project projectToSave) editedProject.Name = projectToSave.Name; editedProject.IsShortcutNeeded = projectToSave.IsShortcutNeeded; + editedProject.IsLaunchOnStartup = projectToSave.IsLaunchOnStartup; editedProject.MoveExistingWindows = projectToSave.MoveExistingWindows; editedProject.PreviewIcons = projectToSave.PreviewIcons; editedProject.PreviewImage = projectToSave.PreviewImage; @@ -194,36 +195,52 @@ public void SaveProject(Project projectToSave) private void ApplyShortcut(Project project) { - string basePath = AppDomain.CurrentDomain.BaseDirectory; - string shortcutAddress = Path.Combine(FolderUtils.Desktop(), project.Name + ".lnk"); string shortcutIconFilename = Path.Combine(FolderUtils.Temp(), project.Id + ".ico"); - if (!project.IsShortcutNeeded) + if (!project.IsShortcutNeeded && !project.IsLaunchOnStartup) { if (File.Exists(shortcutIconFilename)) { File.Delete(shortcutIconFilename); } + } + else + { + Bitmap icon = WorkspacesIcon.DrawIcon(WorkspacesIcon.IconTextFromProjectName(project.Name), App.ThemeManager.GetCurrentTheme()); + WorkspacesIcon.SaveIcon(icon, shortcutIconFilename); + } + + try + { + CreateShortcut(project, project.IsShortcutNeeded, FolderUtils.Desktop(), shortcutIconFilename); + CreateShortcut(project, project.IsLaunchOnStartup, FolderUtils.Startup(), shortcutIconFilename); + } + catch (Exception ex) + { + Logger.LogError($"Shortcut creation error: {ex.Message}"); + } + } + private void CreateShortcut(Project project, bool isNeeded, string shortcutFolder, string shortcutIconFilename) + { + string shortcutAddress = Path.Combine(shortcutFolder, project.Name + ".lnk"); + if (!isNeeded) + { if (File.Exists(shortcutAddress)) { File.Delete(shortcutAddress); } - - return; } - - Bitmap icon = WorkspacesIcon.DrawIcon(WorkspacesIcon.IconTextFromProjectName(project.Name), App.ThemeManager.GetCurrentTheme()); - WorkspacesIcon.SaveIcon(icon, shortcutIconFilename); - - try + else { + string basePath = AppDomain.CurrentDomain.BaseDirectory; + // Workaround to be able to create a shortcut with unicode filename File.WriteAllBytes(shortcutAddress, Array.Empty()); // Create a ShellLinkObject that references the .lnk file Shell32.Shell shell = new Shell32.Shell(); - Shell32.Folder dir = shell.NameSpace(FolderUtils.Desktop()); + Shell32.Folder dir = shell.NameSpace(shortcutFolder); Shell32.FolderItem folderItem = dir.Items().Item($"{project.Name}.lnk"); Shell32.ShellLinkObject link = (Shell32.ShellLinkObject)folderItem.GetLink; @@ -236,10 +253,6 @@ private void ApplyShortcut(Project project) link.Save(shortcutAddress); } - catch (Exception ex) - { - Logger.LogError($"Shortcut creation error: {ex.Message}"); - } } public void SaveProjectName(Project project) diff --git a/src/modules/Workspaces/WorkspacesEditor/WorkspacesEditorPage.xaml b/src/modules/Workspaces/WorkspacesEditor/WorkspacesEditorPage.xaml index 6bc7bfe63798..2198e94aacce 100644 --- a/src/modules/Workspaces/WorkspacesEditor/WorkspacesEditorPage.xaml +++ b/src/modules/Workspaces/WorkspacesEditor/WorkspacesEditorPage.xaml @@ -380,6 +380,12 @@ Content="{x:Static props:Resources.CreateShortcut}" FontSize="14" IsChecked="{Binding IsShortcutNeeded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> + (data.lastLaunchedTime.value()))); } json.SetNamedValue(NonLocalizable::IsShortcutNeededID, json::value(data.isShortcutNeeded)); + json.SetNamedValue(NonLocalizable::IsLaunchOnStartupID, json::value(data.isLaunchOnStartup)); json.SetNamedValue(NonLocalizable::MoveExistingWindowsID, json::value(data.moveExistingWindows)); json.SetNamedValue(NonLocalizable::MonitorConfigurationID, monitorsArray); json.SetNamedValue(NonLocalizable::AppsID, appsArray); @@ -338,6 +340,11 @@ namespace WorkspacesData result.isShortcutNeeded = json.GetNamedBoolean(NonLocalizable::IsShortcutNeededID); } + if (json.HasKey(NonLocalizable::IsLaunchOnStartupID)) + { + result.isLaunchOnStartup = json.GetNamedBoolean(NonLocalizable::IsLaunchOnStartupID); + } + if (json.HasKey(NonLocalizable::MoveExistingWindowsID)) { result.moveExistingWindows = json.GetNamedBoolean(NonLocalizable::MoveExistingWindowsID); diff --git a/src/modules/Workspaces/WorkspacesLib/WorkspacesData.h b/src/modules/Workspaces/WorkspacesLib/WorkspacesData.h index 272cf65d5a06..ee1b21216db7 100644 --- a/src/modules/Workspaces/WorkspacesLib/WorkspacesData.h +++ b/src/modules/Workspaces/WorkspacesLib/WorkspacesData.h @@ -72,6 +72,7 @@ namespace WorkspacesData time_t creationTime; std::optional lastLaunchedTime; bool isShortcutNeeded; + bool isLaunchOnStartup; bool moveExistingWindows; std::vector monitors; std::vector apps; From 587bcae495697dbe9ee45a283aeccafe028908d4 Mon Sep 17 00:00:00 2001 From: donlaci Date: Thu, 9 Jan 2025 12:21:33 +0100 Subject: [PATCH 2/2] minor typo fix --- src/modules/Workspaces/WorkspacesLib/WorkspacesData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/Workspaces/WorkspacesLib/WorkspacesData.cpp b/src/modules/Workspaces/WorkspacesLib/WorkspacesData.cpp index e2dd55968eb3..62e4a9be86a2 100644 --- a/src/modules/Workspaces/WorkspacesLib/WorkspacesData.cpp +++ b/src/modules/Workspaces/WorkspacesLib/WorkspacesData.cpp @@ -283,7 +283,7 @@ namespace WorkspacesData const static wchar_t* CreationTimeID = L"creation-time"; const static wchar_t* LastLaunchedTimeID = L"last-launched-time"; const static wchar_t* IsShortcutNeededID = L"is-shortcut-needed"; - const static wchar_t* IsLaunchOnStartupID = L"is-Launch-on-startup"; + const static wchar_t* IsLaunchOnStartupID = L"is-launch-on-startup"; const static wchar_t* MoveExistingWindowsID = L"move-existing-windows"; const static wchar_t* MonitorConfigurationID = L"monitor-configuration"; const static wchar_t* AppsID = L"applications";