From 946e1aa5a29a811bb13a988e57c45ba2e79c25d5 Mon Sep 17 00:00:00 2001 From: Shun-ichi Goto Date: Thu, 9 Apr 2026 11:14:12 +0900 Subject: [PATCH] feature: add Ctrl+O global hotkey to open/init repository This fix add a global hotkey, Ctrl-O, that allows you to perform actions that were previously only possible on the Welcome screen, from anywhere. - Add global Ctrl+O (Cmd+O on macOS) hotkey for opening a repository. - Move dialog operation logic `OpenLocalRepository()` from WelcomeToolbar to Launcher, and use it by global hotkey and button action in WlcomeToolbar. - Add hotkey text to "Open repository" button tooltip in welcome view. - Add new hotkey text in Hotkeys dialog as resource (en_US, ja_JP). --- src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/ja_JP.axaml | 1 + src/Views/Hotkeys.axaml | 21 ++++++----- src/Views/Launcher.axaml.cs | 60 +++++++++++++++++++++++++++++++ src/Views/WelcomeToolbar.axaml | 9 ++++- src/Views/WelcomeToolbar.axaml.cs | 45 ++--------------------- 6 files changed, 84 insertions(+), 53 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index a14c66a16..8f80d2f88 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -499,6 +499,7 @@ Go to next tab Go to previous tab Create new tab + Open repository Open Preferences dialog Show workspace dropdown menu Switch active tab diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml index 5d4969abe..27628b5cb 100644 --- a/src/Resources/Locales/ja_JP.axaml +++ b/src/Resources/Locales/ja_JP.axaml @@ -491,6 +491,7 @@ 次のタブに移動 前のタブに移動 新しいタブを作成 + リポジトリを開く 設定ダイアログを開く ワークスペースのドロップダウンメニューを表示 アクティブなタブを切り替え diff --git a/src/Views/Hotkeys.axaml b/src/Views/Hotkeys.axaml index 855e205b5..b3f3f83d6 100644 --- a/src/Views/Hotkeys.axaml +++ b/src/Views/Hotkeys.axaml @@ -45,7 +45,7 @@ FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Increase}}" Margin="0,0,0,8"/> - + @@ -64,17 +64,20 @@ - - + + - - + + - - + + - - + + + + + - diff --git a/src/Views/WelcomeToolbar.axaml.cs b/src/Views/WelcomeToolbar.axaml.cs index d949c0955..beefdf337 100644 --- a/src/Views/WelcomeToolbar.axaml.cs +++ b/src/Views/WelcomeToolbar.axaml.cs @@ -1,9 +1,5 @@ -using System; -using System.IO; - using Avalonia.Controls; using Avalonia.Interactivity; -using Avalonia.Platform.Storage; namespace SourceGit.Views { @@ -21,47 +17,10 @@ private async void OpenLocalRepository(object _1, RoutedEventArgs e) return; var topLevel = TopLevel.GetTopLevel(this); - if (topLevel == null) + if (topLevel is not Launcher launcher) return; - var preference = ViewModels.Preferences.Instance; - var workspace = preference.GetActiveWorkspace(); - var initDir = workspace.DefaultCloneDir; - if (string.IsNullOrEmpty(initDir) || !Directory.Exists(initDir)) - initDir = preference.GitDefaultCloneDir; - - var options = new FolderPickerOpenOptions() { AllowMultiple = false }; - if (Directory.Exists(initDir)) - { - var folder = await topLevel.StorageProvider.TryGetFolderFromPathAsync(initDir); - options.SuggestedStartLocation = folder; - } - - try - { - var selected = await topLevel.StorageProvider.OpenFolderPickerAsync(options); - if (selected.Count == 1) - { - var folder = selected[0]; - var folderPath = folder is { Path: { IsAbsoluteUri: true } path } ? path.LocalPath : folder?.Path.ToString(); - var repoPath = await ViewModels.Welcome.Instance.GetRepositoryRootAsync(folderPath); - if (!string.IsNullOrEmpty(repoPath)) - { - await ViewModels.Welcome.Instance.AddRepositoryAsync(repoPath, null, false, true); - ViewModels.Welcome.Instance.Refresh(); - } - else if (Directory.Exists(folderPath)) - { - var test = await new Commands.QueryRepositoryRootPath(folderPath).GetResultAsync(); - ViewModels.Welcome.Instance.InitRepository(folderPath, null, test.StdErr); - } - } - } - catch (Exception exception) - { - Models.Notification.Send(null, $"Failed to open repository: {exception.Message}", true); - } - + await launcher.OpenLocalRepository(); e.Handled = true; } }