diff --git a/src/Models/CustomAction.cs b/src/Models/CustomAction.cs
index 2a400b02..8452a42d 100644
--- a/src/Models/CustomAction.cs
+++ b/src/Models/CustomAction.cs
@@ -30,7 +30,7 @@ namespace SourceGit.Models
public string Arguments
{
- get => _arguments;
+ get => _arguments;
set => SetProperty(ref _arguments, value);
}
diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs
index 3c56edd3..48fbb287 100644
--- a/src/Native/Windows.cs
+++ b/src/Native/Windows.cs
@@ -325,8 +325,8 @@ namespace SourceGit.Native
if (localMachine.OpenSubKey(@"SOFTWARE\Classes\VisualStudio.Launcher.sln\CLSID") is Microsoft.Win32.RegistryKey launcher)
{
// Get actual path to the executable
- if (launcher.GetValue(string.Empty) is string CLSID &&
- localMachine.OpenSubKey(@$"SOFTWARE\Classes\CLSID\{CLSID}\LocalServer32") is Microsoft.Win32.RegistryKey devenv &&
+ if (launcher.GetValue(string.Empty) is string CLSID &&
+ localMachine.OpenSubKey(@$"SOFTWARE\Classes\CLSID\{CLSID}\LocalServer32") is Microsoft.Win32.RegistryKey devenv &&
devenv.GetValue(string.Empty) is string localServer32)
{
return localServer32!.Trim('\"');
diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml
index b9371f2e..15c8b6ee 100644
--- a/src/Resources/Locales/en_US.axaml
+++ b/src/Resources/Locales/en_US.axaml
@@ -387,6 +387,8 @@
Interactive Rebase
Target Branch:
On:
+ Open in Browser
+ Copy Link
ERROR
NOTICE
Merge Branch
diff --git a/src/Views/Blame.axaml.cs b/src/Views/Blame.axaml.cs
index 164b89de..d32e4370 100644
--- a/src/Views/Blame.axaml.cs
+++ b/src/Views/Blame.axaml.cs
@@ -407,8 +407,8 @@ namespace SourceGit.Views
var menu = new ContextMenu();
menu.Items.Add(copy);
+ menu.Open(TextArea.TextView);
- TextArea.TextView.OpenContextMenu(menu);
e.Handled = true;
}
diff --git a/src/Views/BranchCompare.axaml.cs b/src/Views/BranchCompare.axaml.cs
index 90ec1af5..ca90a180 100644
--- a/src/Views/BranchCompare.axaml.cs
+++ b/src/Views/BranchCompare.axaml.cs
@@ -15,7 +15,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.BranchCompare vm && sender is ChangeCollectionView view)
{
var menu = vm.CreateChangeContextMenu();
- view.OpenContextMenu(menu);
+ menu?.Open(view);
}
e.Handled = true;
diff --git a/src/Views/BranchTree.axaml.cs b/src/Views/BranchTree.axaml.cs
index 081160d0..e96b2594 100644
--- a/src/Views/BranchTree.axaml.cs
+++ b/src/Views/BranchTree.axaml.cs
@@ -374,7 +374,7 @@ namespace SourceGit.Views
if (selected.Count == 1 && selected[0] is ViewModels.BranchTreeNode { Backend: Models.Remote remote })
{
var menu = repo.CreateContextMenuForRemote(remote);
- this.OpenContextMenu(menu);
+ menu?.Open(this);
return;
}
@@ -391,7 +391,7 @@ namespace SourceGit.Views
var menu = branch.IsLocal ?
repo.CreateContextMenuForLocalBranch(branch) :
repo.CreateContextMenuForRemoteBranch(branch);
- this.OpenContextMenu(menu);
+ menu?.Open(this);
}
else if (branches.Find(x => x.IsCurrent) == null)
{
@@ -405,7 +405,7 @@ namespace SourceGit.Views
ev.Handled = true;
};
menu.Items.Add(deleteMulti);
- this.OpenContextMenu(menu);
+ menu?.Open(this);
}
}
diff --git a/src/Views/CommitBaseInfo.axaml.cs b/src/Views/CommitBaseInfo.axaml.cs
index e31ddfba..7992b40d 100644
--- a/src/Views/CommitBaseInfo.axaml.cs
+++ b/src/Views/CommitBaseInfo.axaml.cs
@@ -68,7 +68,7 @@ namespace SourceGit.Views
private void OnOpenWebLink(object sender, RoutedEventArgs e)
{
- if (DataContext is ViewModels.CommitDetail detail)
+ if (DataContext is ViewModels.CommitDetail detail && sender is Control control)
{
var links = WebLinks;
if (links.Count > 1)
@@ -88,7 +88,7 @@ namespace SourceGit.Views
menu.Items.Add(item);
}
- (sender as Control)?.OpenContextMenu(menu);
+ menu?.Open(control);
}
else if (links.Count == 1)
{
diff --git a/src/Views/CommitChanges.axaml.cs b/src/Views/CommitChanges.axaml.cs
index f197bdd5..c3d30018 100644
--- a/src/Views/CommitChanges.axaml.cs
+++ b/src/Views/CommitChanges.axaml.cs
@@ -16,7 +16,7 @@ namespace SourceGit.Views
DataContext is ViewModels.CommitDetail vm)
{
var menu = vm.CreateChangeContextMenu(selected[0]);
- view.OpenContextMenu(menu);
+ menu?.Open(view);
}
e.Handled = true;
diff --git a/src/Views/CommitDetail.axaml.cs b/src/Views/CommitDetail.axaml.cs
index 999d1c07..f0599c66 100644
--- a/src/Views/CommitDetail.axaml.cs
+++ b/src/Views/CommitDetail.axaml.cs
@@ -26,7 +26,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.CommitDetail detail && sender is Grid grid && grid.DataContext is Models.Change change)
{
var menu = detail.CreateChangeContextMenu(change);
- grid.OpenContextMenu(menu);
+ menu?.Open(grid);
}
e.Handled = true;
diff --git a/src/Views/CommitMessagePresenter.cs b/src/Views/CommitMessagePresenter.cs
index 55e1dfb1..112c1f57 100644
--- a/src/Views/CommitMessagePresenter.cs
+++ b/src/Views/CommitMessagePresenter.cs
@@ -176,7 +176,41 @@ namespace SourceGit.Views
}
else
{
- Native.OS.OpenBrowser(_lastHover.Link);
+ var point = e.GetCurrentPoint(this);
+ var link = _lastHover.Link;
+
+ if (point.Properties.IsLeftButtonPressed)
+ {
+ Native.OS.OpenBrowser(link);
+ }
+ else if (point.Properties.IsRightButtonPressed)
+ {
+ var open = new MenuItem();
+ open.Header = App.Text("IssueLinkCM.OpenInBrowser");
+ open.Icon = App.CreateMenuIcon("Icons.OpenWith");
+ open.Click += (_, ev) =>
+ {
+ ev.Handled = true;
+
+ var parentView = this.FindAncestorOfType();
+ if (parentView is { DataContext: ViewModels.CommitDetail detail })
+ detail.NavigateTo(link);
+ };
+
+ var copy = new MenuItem();
+ copy.Header = App.Text("IssueLinkCM.CopyLink");
+ copy.Icon = App.CreateMenuIcon("Icons.Copy");
+ copy.Click += (_, ev) =>
+ {
+ App.CopyText(link);
+ ev.Handled = true;
+ };
+
+ var menu = new ContextMenu();
+ menu.Items.Add(open);
+ menu.Items.Add(copy);
+ menu.Open(this);
+ }
}
e.Handled = true;
diff --git a/src/Views/ContextMenuExtension.cs b/src/Views/ContextMenuExtension.cs
deleted file mode 100644
index 2abcf2b9..00000000
--- a/src/Views/ContextMenuExtension.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.ComponentModel;
-using Avalonia.Controls;
-
-namespace SourceGit.Views
-{
- public static class ContextMenuExtension
- {
- public static void OpenContextMenu(this Control control, ContextMenu menu)
- {
- if (menu == null)
- return;
-
- menu.PlacementTarget = control;
- menu.Closing += OnContextMenuClosing; // Clear context menu because it is dynamic.
-
- control.ContextMenu = menu;
- control.ContextMenu?.Open();
- }
-
- private static void OnContextMenuClosing(object sender, CancelEventArgs e)
- {
- if (sender is ContextMenu menu && menu.PlacementTarget != null)
- menu.PlacementTarget.ContextMenu = null;
- }
- }
-}
diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs
index 137fd298..43258dd7 100644
--- a/src/Views/Histories.axaml.cs
+++ b/src/Views/Histories.axaml.cs
@@ -706,7 +706,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.Histories histories && sender is ListBox { SelectedItems: { Count: > 0 } } list)
{
var menu = histories.MakeContextMenu(list);
- list.OpenContextMenu(menu);
+ menu?.Open(list);
}
e.Handled = true;
}
diff --git a/src/Views/Launcher.axaml.cs b/src/Views/Launcher.axaml.cs
index b4a44868..99916da3 100644
--- a/src/Views/Launcher.axaml.cs
+++ b/src/Views/Launcher.axaml.cs
@@ -250,7 +250,7 @@ namespace SourceGit.Views
if (sender is Button btn && DataContext is ViewModels.Launcher launcher)
{
var menu = launcher.CreateContextForWorkspace();
- btn.OpenContextMenu(menu);
+ menu?.Open(btn);
}
e.Handled = true;
diff --git a/src/Views/LauncherTabBar.axaml.cs b/src/Views/LauncherTabBar.axaml.cs
index 3258a09c..f8c9107c 100644
--- a/src/Views/LauncherTabBar.axaml.cs
+++ b/src/Views/LauncherTabBar.axaml.cs
@@ -234,7 +234,7 @@ namespace SourceGit.Views
if (sender is Border border && DataContext is ViewModels.Launcher vm)
{
var menu = vm.CreateContextForPageTab(border.DataContext as ViewModels.LauncherPage);
- border.OpenContextMenu(menu);
+ menu?.Open(border);
}
e.Handled = true;
diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs
index 499f5e62..dec3d447 100644
--- a/src/Views/Repository.axaml.cs
+++ b/src/Views/Repository.axaml.cs
@@ -189,7 +189,7 @@ namespace SourceGit.Views
if (sender is ListBox { SelectedItem: Models.Submodule submodule } grid && DataContext is ViewModels.Repository repo)
{
var menu = repo.CreateContextMenuForSubmodule(submodule.Path);
- grid.OpenContextMenu(menu);
+ menu?.Open(grid);
}
e.Handled = true;
@@ -210,7 +210,7 @@ namespace SourceGit.Views
if (sender is ListBox { SelectedItem: Models.Worktree worktree } grid && DataContext is ViewModels.Repository repo)
{
var menu = repo.CreateContextMenuForWorktree(worktree);
- grid.OpenContextMenu(menu);
+ menu?.Open(grid);
}
e.Handled = true;
diff --git a/src/Views/RepositoryToolbar.axaml.cs b/src/Views/RepositoryToolbar.axaml.cs
index 55132620..a4a05dc4 100644
--- a/src/Views/RepositoryToolbar.axaml.cs
+++ b/src/Views/RepositoryToolbar.axaml.cs
@@ -17,7 +17,7 @@ namespace SourceGit.Views
if (sender is Button button && DataContext is ViewModels.Repository repo)
{
var menu = repo.CreateContextMenuForExternalTools();
- button.OpenContextMenu(menu);
+ menu?.Open(button);
e.Handled = true;
}
}
@@ -72,10 +72,10 @@ namespace SourceGit.Views
private void OpenGitFlowMenu(object sender, RoutedEventArgs e)
{
- if (DataContext is ViewModels.Repository repo)
+ if (DataContext is ViewModels.Repository repo && sender is Control control)
{
var menu = repo.CreateContextMenuForGitFlow();
- (sender as Control)?.OpenContextMenu(menu);
+ menu?.Open(control);
}
e.Handled = true;
@@ -83,10 +83,10 @@ namespace SourceGit.Views
private void OpenGitLFSMenu(object sender, RoutedEventArgs e)
{
- if (DataContext is ViewModels.Repository repo)
+ if (DataContext is ViewModels.Repository repo && sender is Control control)
{
var menu = repo.CreateContextMenuForGitLFS();
- (sender as Control)?.OpenContextMenu(menu);
+ menu?.Open(control);
}
e.Handled = true;
@@ -94,10 +94,10 @@ namespace SourceGit.Views
private void OpenCustomActionMenu(object sender, RoutedEventArgs e)
{
- if (DataContext is ViewModels.Repository repo)
+ if (DataContext is ViewModels.Repository repo && sender is Control control)
{
var menu = repo.CreateContextMenuForCustomAction();
- (sender as Control)?.OpenContextMenu(menu);
+ menu?.Open(control);
}
e.Handled = true;
diff --git a/src/Views/RevisionCompare.axaml.cs b/src/Views/RevisionCompare.axaml.cs
index e3ecb2b7..b484b78f 100644
--- a/src/Views/RevisionCompare.axaml.cs
+++ b/src/Views/RevisionCompare.axaml.cs
@@ -15,7 +15,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.RevisionCompare vm && sender is ChangeCollectionView view)
{
var menu = vm.CreateChangeContextMenu();
- view.OpenContextMenu(menu);
+ menu?.Open(view);
}
e.Handled = true;
diff --git a/src/Views/RevisionFileTreeView.axaml.cs b/src/Views/RevisionFileTreeView.axaml.cs
index e198f6f0..af9beb7d 100644
--- a/src/Views/RevisionFileTreeView.axaml.cs
+++ b/src/Views/RevisionFileTreeView.axaml.cs
@@ -229,7 +229,7 @@ namespace SourceGit.Views
if (obj.Type != Models.ObjectType.Tree)
{
var menu = vm.CreateRevisionFileContextMenu(obj);
- grid.OpenContextMenu(menu);
+ menu?.Open(grid);
}
}
diff --git a/src/Views/RevisionFiles.axaml.cs b/src/Views/RevisionFiles.axaml.cs
index b76e1360..53c36b1c 100644
--- a/src/Views/RevisionFiles.axaml.cs
+++ b/src/Views/RevisionFiles.axaml.cs
@@ -95,8 +95,8 @@ namespace SourceGit.Views
var menu = new ContextMenu();
menu.Items.Add(copy);
+ menu.Open(TextArea.TextView);
- TextArea.TextView.OpenContextMenu(menu);
e.Handled = true;
}
diff --git a/src/Views/StashesPage.axaml.cs b/src/Views/StashesPage.axaml.cs
index f3048889..af32cb2c 100644
--- a/src/Views/StashesPage.axaml.cs
+++ b/src/Views/StashesPage.axaml.cs
@@ -28,7 +28,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.StashesPage vm && sender is Border border)
{
var menu = vm.MakeContextMenu(border.DataContext as Models.Stash);
- border.OpenContextMenu(menu);
+ menu?.Open(border);
}
e.Handled = true;
}
@@ -38,7 +38,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.StashesPage vm && sender is Grid grid)
{
var menu = vm.MakeContextMenuForChange(grid.DataContext as Models.Change);
- grid.OpenContextMenu(menu);
+ menu?.Open(grid);
}
e.Handled = true;
}
diff --git a/src/Views/TagsView.axaml.cs b/src/Views/TagsView.axaml.cs
index 29b591fb..8d4168b2 100644
--- a/src/Views/TagsView.axaml.cs
+++ b/src/Views/TagsView.axaml.cs
@@ -225,7 +225,7 @@ namespace SourceGit.Views
if (selected != null && DataContext is ViewModels.Repository repo)
{
var menu = repo.CreateContextMenuForTag(selected);
- control.OpenContextMenu(menu);
+ menu?.Open(control);
}
e.Handled = true;
diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs
index 63833fc1..99e499b0 100644
--- a/src/Views/TextDiffView.axaml.cs
+++ b/src/Views/TextDiffView.axaml.cs
@@ -589,8 +589,8 @@ namespace SourceGit.Views
var menu = new ContextMenu();
menu.Items.Add(copy);
+ menu.Open(TextArea.TextView);
- TextArea.TextView.OpenContextMenu(menu);
e.Handled = true;
}
diff --git a/src/Views/Welcome.axaml.cs b/src/Views/Welcome.axaml.cs
index a8045aa9..a292a6ef 100644
--- a/src/Views/Welcome.axaml.cs
+++ b/src/Views/Welcome.axaml.cs
@@ -117,7 +117,7 @@ namespace SourceGit.Views
if (sender is Grid { DataContext: ViewModels.RepositoryNode node } grid)
{
var menu = ViewModels.Welcome.Instance.CreateContextMenu(node);
- grid.OpenContextMenu(menu);
+ menu?.Open(grid);
e.Handled = true;
}
}
diff --git a/src/Views/WorkingCopy.axaml.cs b/src/Views/WorkingCopy.axaml.cs
index f64e1a30..df45a7f1 100644
--- a/src/Views/WorkingCopy.axaml.cs
+++ b/src/Views/WorkingCopy.axaml.cs
@@ -31,27 +31,27 @@ namespace SourceGit.Views
{
var menu = vm.CreateContextMenuForCommitMessages();
menu.Placement = PlacementMode.TopEdgeAlignedLeft;
- button.OpenContextMenu(menu);
+ menu?.Open(button);
e.Handled = true;
}
}
private void OnUnstagedContextRequested(object sender, ContextRequestedEventArgs e)
{
- if (DataContext is ViewModels.WorkingCopy vm)
+ if (DataContext is ViewModels.WorkingCopy vm && sender is Control control)
{
var menu = vm.CreateContextMenuForUnstagedChanges();
- (sender as Control)?.OpenContextMenu(menu);
+ menu?.Open(control);
e.Handled = true;
}
}
private void OnStagedContextRequested(object sender, ContextRequestedEventArgs e)
{
- if (DataContext is ViewModels.WorkingCopy vm)
+ if (DataContext is ViewModels.WorkingCopy vm && sender is Control control)
{
var menu = vm.CreateContextMenuForStagedChanges();
- (sender as Control)?.OpenContextMenu(menu);
+ menu?.Open(control);
e.Handled = true;
}
}
@@ -136,10 +136,10 @@ namespace SourceGit.Views
private void OnOpenOpenAIHelper(object sender, RoutedEventArgs e)
{
- if (DataContext is ViewModels.WorkingCopy vm)
+ if (DataContext is ViewModels.WorkingCopy vm && sender is Control control)
{
var menu = vm.CreateContextForOpenAI();
- (sender as Button)?.OpenContextMenu(menu);
+ menu?.Open(control);
}
e.Handled = true;