Skip to content

Commit 29cf5fc

Browse files
committed
feature: add Hide Others app menu on macOS and correct the behaviour of Show All
Signed-off-by: leo <longshuang@msn.cn>
1 parent 5114c43 commit 29cf5fc

9 files changed

Lines changed: 110 additions & 8 deletions

File tree

src/App.Commands.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,17 @@ public static bool IsCheckForUpdateCommandVisible
8181

8282
public static readonly Command HideAppCommand = new Command(_ =>
8383
{
84-
if (Current is App app && app.TryGetFeature(typeof(IActivatableLifetime)) is IActivatableLifetime lifetime)
85-
lifetime.TryEnterBackground();
84+
Native.OS.HideSelf();
8685
});
8786

88-
public static readonly Command ShowAppCommand = new Command(_ =>
87+
public static readonly Command HideOtherApplicationsCommand = new Command(_ =>
8988
{
90-
if (Current is App app && app.TryGetFeature(typeof(IActivatableLifetime)) is IActivatableLifetime lifetime)
91-
lifetime.TryLeaveBackground();
89+
Native.OS.HideOtherApplications();
90+
});
91+
92+
public static readonly Command ShowAllApplicationsCommand = new Command(_ =>
93+
{
94+
Native.OS.ShowAllApplications();
9295
});
9396
}
9497
}

src/App.axaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
<NativeMenuItem Header="{DynamicResource Text.OpenAppDataDir}" Command="{x:Static s:App.OpenAppDataDirCommand}"/>
4646
<NativeMenuItemSeparator/>
4747
<NativeMenuItem Header="{DynamicResource Text.App.Hide}" Command="{x:Static s:App.HideAppCommand}" Gesture="⌘+H"/>
48-
<NativeMenuItem Header="{DynamicResource Text.App.ShowAll}" Command="{x:Static s:App.ShowAppCommand}"/>
48+
<NativeMenuItem Header="{DynamicResource Text.App.HideOthers}" Command="{x:Static s:App.HideOtherApplicationsCommand}" Gesture="⌘+Alt+H"/>
49+
<NativeMenuItem Header="{DynamicResource Text.App.ShowAll}" Command="{x:Static s:App.ShowAllApplicationsCommand}"/>
4950
<NativeMenuItemSeparator/>
5051
<NativeMenuItem Header="{DynamicResource Text.Quit}" Command="{x:Static s:App.QuitCommand}" Gesture="⌘+Q"/>
5152
</NativeMenu>

src/Native/Linux.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@ public void SetupWindow(Window window)
3333
}
3434
}
3535

36+
public void HideSelf()
37+
{
38+
// Do Nothing. Never used.
39+
}
40+
41+
public void HideOtherApplications()
42+
{
43+
// Do Nothing. Never used.
44+
}
45+
46+
public void ShowAllApplications()
47+
{
48+
// Do Nothing. Never used.
49+
}
50+
3651
public string GetDataDir()
3752
{
3853
// AppImage supports portable mode

src/Native/MacOS.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.IO;
5+
using System.Runtime.InteropServices;
56
using System.Runtime.Versioning;
67

78
using Avalonia;
@@ -13,6 +14,18 @@ namespace SourceGit.Native
1314
[SupportedOSPlatform("macOS")]
1415
internal class MacOS : OS.IBackend
1516
{
17+
[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "objc_getClass")]
18+
public static extern IntPtr objc_getClass(string name);
19+
20+
[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "sel_registerName")]
21+
public static extern IntPtr sel_registerName(string name);
22+
23+
[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
24+
public static extern IntPtr objc_msgSend(IntPtr receiver, IntPtr selector);
25+
26+
[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
27+
public static extern IntPtr objc_msgSendWithArg(IntPtr receiver, IntPtr selector, IntPtr arg);
28+
1629
public void SetupApp(AppBuilder builder)
1730
{
1831
builder.With(new MacOSPlatformOptions()
@@ -44,6 +57,39 @@ public void SetupWindow(Window window)
4457
window.ExtendClientAreaToDecorationsHint = true;
4558
}
4659

60+
public void HideSelf()
61+
{
62+
IntPtr nsApplicationClass = objc_getClass("NSApplication");
63+
IntPtr nsSharedApplicationSelector = sel_registerName("sharedApplication");
64+
IntPtr nsApp = objc_msgSend(nsApplicationClass, nsSharedApplicationSelector);
65+
IntPtr nsMethodSelector = sel_registerName("hide:");
66+
IntPtr nsDelegateSelector = sel_registerName("delegate");
67+
IntPtr nsDelegate = objc_msgSend(nsApp, nsDelegateSelector);
68+
objc_msgSendWithArg(nsApp, nsMethodSelector, nsDelegate);
69+
}
70+
71+
public void HideOtherApplications()
72+
{
73+
IntPtr nsApplicationClass = objc_getClass("NSApplication");
74+
IntPtr nsSharedApplicationSelector = sel_registerName("sharedApplication");
75+
IntPtr nsApp = objc_msgSend(nsApplicationClass, nsSharedApplicationSelector);
76+
IntPtr nsMethodSelector = sel_registerName("hideOtherApplications:");
77+
IntPtr nsDelegateSelector = sel_registerName("delegate");
78+
IntPtr nsDelegate = objc_msgSend(nsApp, nsDelegateSelector);
79+
objc_msgSendWithArg(nsApp, nsMethodSelector, nsDelegate);
80+
}
81+
82+
public void ShowAllApplications()
83+
{
84+
IntPtr nsApplicationClass = objc_getClass("NSApplication");
85+
IntPtr nsSharedApplicationSelector = sel_registerName("sharedApplication");
86+
IntPtr nsApp = objc_msgSend(nsApplicationClass, nsSharedApplicationSelector);
87+
IntPtr nsMethodSelector = sel_registerName("unhideAllApplications:");
88+
IntPtr nsDelegateSelector = sel_registerName("delegate");
89+
IntPtr nsDelegate = objc_msgSend(nsApp, nsDelegateSelector);
90+
objc_msgSendWithArg(nsApp, nsMethodSelector, nsDelegate);
91+
}
92+
4793
public string GetDataDir()
4894
{
4995
return Path.Combine(

src/Native/OS.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public interface IBackend
1818
void SetupApp(AppBuilder builder);
1919
void SetupWindow(Window window);
2020

21+
void HideSelf();
22+
void HideOtherApplications();
23+
void ShowAllApplications();
24+
2125
string GetDataDir();
2226
string FindGitExecutable();
2327
string FindTerminal(Models.ShellOrTerminal shell);
@@ -154,6 +158,21 @@ public static void SetupForWindow(Window window)
154158
_backend.SetupWindow(window);
155159
}
156160

161+
public static void HideSelf()
162+
{
163+
_backend.HideSelf();
164+
}
165+
166+
public static void HideOtherApplications()
167+
{
168+
_backend.HideOtherApplications();
169+
}
170+
171+
public static void ShowAllApplications()
172+
{
173+
_backend.ShowAllApplications();
174+
}
175+
157176
public static void LogException(Exception ex)
158177
{
159178
if (ex == null)

src/Native/Windows.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ public void SetupWindow(Window window)
5858
window.BorderThickness = new Thickness(1);
5959
}
6060

61+
public void HideSelf()
62+
{
63+
// Do Nothing. Never used.
64+
}
65+
66+
public void HideOtherApplications()
67+
{
68+
// Do Nothing. Never used.
69+
}
70+
71+
public void ShowAllApplications()
72+
{
73+
// Do Nothing. Never used.
74+
}
75+
6176
public string GetDataDir()
6277
{
6378
var execFile = Process.GetCurrentProcess().MainModule!.FileName;

src/Resources/Locales/en_US.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<x:String x:Key="Text.AIAssistant.Tip" xml:space="preserve">Use AI to generate commit message</x:String>
2424
<x:String x:Key="Text.AIAssistant.Use" xml:space="preserve">Use</x:String>
2525
<x:String x:Key="Text.App.Hide" xml:space="preserve">Hide SourceGit</x:String>
26+
<x:String x:Key="Text.App.HideOthers" xml:space="preserve">Hide Others</x:String>
2627
<x:String x:Key="Text.App.ShowAll" xml:space="preserve">Show All</x:String>
2728
<x:String x:Key="Text.Apply" xml:space="preserve">Patch</x:String>
2829
<x:String x:Key="Text.Apply.3Way" xml:space="preserve">3-Way Merge</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
<x:String x:Key="Text.AIAssistant.Tip" xml:space="preserve">使用AI助手生成提交信息</x:String>
2828
<x:String x:Key="Text.AIAssistant.Use" xml:space="preserve">应用所选</x:String>
2929
<x:String x:Key="Text.App.Hide" xml:space="preserve">隐藏 SourceGit</x:String>
30-
<x:String x:Key="Text.App.ShowAll" xml:space="preserve">显示所有窗口</x:String>
30+
<x:String x:Key="Text.App.HideOthers" xml:space="preserve">隐藏其他</x:String>
31+
<x:String x:Key="Text.App.ShowAll" xml:space="preserve">显示全部</x:String>
3132
<x:String x:Key="Text.Apply" xml:space="preserve">应用补丁(apply)</x:String>
3233
<x:String x:Key="Text.Apply.3Way" xml:space="preserve">尝试三路合并</x:String>
3334
<x:String x:Key="Text.Apply.File" xml:space="preserve">补丁文件 :</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
<x:String x:Key="Text.AIAssistant.Tip" xml:space="preserve">使用 AI 產生提交訊息</x:String>
2828
<x:String x:Key="Text.AIAssistant.Use" xml:space="preserve">套用選取</x:String>
2929
<x:String x:Key="Text.App.Hide" xml:space="preserve">隱藏 SourceGit</x:String>
30-
<x:String x:Key="Text.App.ShowAll" xml:space="preserve">顯示所有</x:String>
30+
<x:String x:Key="Text.App.HideOthers" xml:space="preserve">隱藏其他</x:String>
31+
<x:String x:Key="Text.App.ShowAll" xml:space="preserve">顯示全部</x:String>
3132
<x:String x:Key="Text.Apply" xml:space="preserve">套用修補檔 (apply patch)</x:String>
3233
<x:String x:Key="Text.Apply.3Way" xml:space="preserve">嘗試三向合併</x:String>
3334
<x:String x:Key="Text.Apply.File" xml:space="preserve">修補檔:</x:String>

0 commit comments

Comments
 (0)