From 548ba7d712f1d58a9e47f69b86dd669a48649d2f Mon Sep 17 00:00:00 2001
From: LightTreasure <meshram.alok@gmail.com>
Date: Tue, 7 May 2024 02:57:02 -0700
Subject: [PATCH] Desktop: Resolves #1752: Added capability to toggle
 visibility of the Menu Bar from the View menu (#10324)

---
 .eslintignore                                    |  1 +
 .gitignore                                       |  1 +
 .../app-desktop/gui/MainScreen/commands/index.ts |  2 ++
 .../gui/MainScreen/commands/toggleMenuBar.ts     | 16 ++++++++++++++++
 packages/app-desktop/gui/MenuBar.tsx             | 13 +++++++++++++
 packages/app-desktop/gui/menuCommandNames.ts     |  1 +
 packages/lib/models/Setting.ts                   |  7 +++++++
 packages/lib/services/KeymapService.ts           |  1 +
 8 files changed, 42 insertions(+)
 create mode 100644 packages/app-desktop/gui/MainScreen/commands/toggleMenuBar.ts

diff --git a/.eslintignore b/.eslintignore
index 4c6d7de055..27f8a719b5 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -242,6 +242,7 @@ packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.test.js
 packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.js
 packages/app-desktop/gui/MainScreen/commands/toggleEditors.js
 packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.js
+packages/app-desktop/gui/MainScreen/commands/toggleMenuBar.js
 packages/app-desktop/gui/MainScreen/commands/toggleNoteList.js
 packages/app-desktop/gui/MainScreen/commands/toggleNoteType.js
 packages/app-desktop/gui/MainScreen/commands/toggleNotesSortOrderField.js
diff --git a/.gitignore b/.gitignore
index 3a8c8e28b6..f4e945e0da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -222,6 +222,7 @@ packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.test.js
 packages/app-desktop/gui/MainScreen/commands/showSpellCheckerMenu.js
 packages/app-desktop/gui/MainScreen/commands/toggleEditors.js
 packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.js
+packages/app-desktop/gui/MainScreen/commands/toggleMenuBar.js
 packages/app-desktop/gui/MainScreen/commands/toggleNoteList.js
 packages/app-desktop/gui/MainScreen/commands/toggleNoteType.js
 packages/app-desktop/gui/MainScreen/commands/toggleNotesSortOrderField.js
diff --git a/packages/app-desktop/gui/MainScreen/commands/index.ts b/packages/app-desktop/gui/MainScreen/commands/index.ts
index 8cb231aa17..b2e5034726 100644
--- a/packages/app-desktop/gui/MainScreen/commands/index.ts
+++ b/packages/app-desktop/gui/MainScreen/commands/index.ts
@@ -39,6 +39,7 @@ import * as showShareNoteDialog from './showShareNoteDialog';
 import * as showSpellCheckerMenu from './showSpellCheckerMenu';
 import * as toggleEditors from './toggleEditors';
 import * as toggleLayoutMoveMode from './toggleLayoutMoveMode';
+import * as toggleMenuBar from './toggleMenuBar';
 import * as toggleNoteList from './toggleNoteList';
 import * as toggleNoteType from './toggleNoteType';
 import * as toggleNotesSortOrderField from './toggleNotesSortOrderField';
@@ -88,6 +89,7 @@ const index: any[] = [
 	showSpellCheckerMenu,
 	toggleEditors,
 	toggleLayoutMoveMode,
+	toggleMenuBar,
 	toggleNoteList,
 	toggleNoteType,
 	toggleNotesSortOrderField,
diff --git a/packages/app-desktop/gui/MainScreen/commands/toggleMenuBar.ts b/packages/app-desktop/gui/MainScreen/commands/toggleMenuBar.ts
new file mode 100644
index 0000000000..3910d2183a
--- /dev/null
+++ b/packages/app-desktop/gui/MainScreen/commands/toggleMenuBar.ts
@@ -0,0 +1,16 @@
+import { CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService';
+import Setting from '@joplin/lib/models/Setting';
+import { _ } from '@joplin/lib/locale';
+
+export const declaration: CommandDeclaration = {
+	name: 'toggleMenuBar',
+	label: () => _('Toggle menu bar'),
+};
+
+export const runtime = (): CommandRuntime => {
+	return {
+		execute: async () => {
+			Setting.toggle('showMenuBar');
+		},
+	};
+};
diff --git a/packages/app-desktop/gui/MenuBar.tsx b/packages/app-desktop/gui/MenuBar.tsx
index abf793c191..6024a6e5d8 100644
--- a/packages/app-desktop/gui/MenuBar.tsx
+++ b/packages/app-desktop/gui/MenuBar.tsx
@@ -172,6 +172,7 @@ interface Props {
 	pluginSettings: PluginSettings;
 	noteListRendererIds: string[];
 	noteListRendererId: string;
+	showMenuBar: boolean;
 }
 
 const commandNames: string[] = menuCommandNames();
@@ -190,6 +191,15 @@ function menuItemSetEnabled(id: string, enabled: boolean) {
 	menuItem.enabled = enabled;
 }
 
+const applyMenuBarVisibility = (showMenuBar: boolean) => {
+	// The menu bar cannot be hidden on macOS
+	if (shim.isMac()) return;
+
+	const window = bridge().window();
+	window.setAutoHideMenuBar(!showMenuBar);
+	window.setMenuBarVisibility(showMenuBar);
+};
+
 // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
 function useMenuStates(menu: any, props: Props) {
 	useEffect(() => {
@@ -760,6 +770,7 @@ function useMenu(props: Props) {
 						menuItemDic.resetLayout,
 						separator(),
 						menuItemDic.toggleSideBar,
+						shim.isMac() ? noItem : menuItemDic.toggleMenuBar,
 						menuItemDic.toggleNoteList,
 						menuItemDic.toggleVisiblePanes,
 						{
@@ -1083,6 +1094,7 @@ function useMenu(props: Props) {
 function MenuBar(props: Props): any {
 	const menu = useMenu(props);
 	if (menu) Menu.setApplicationMenu(menu);
+	applyMenuBarVisibility(props.showMenuBar);
 	return null;
 }
 
@@ -1112,6 +1124,7 @@ const mapStateToProps = (state: AppState) => {
 		profileConfig: state.profileConfig,
 		noteListRendererIds: state.noteListRendererIds,
 		noteListRendererId: state.settings['notes.listRendererId'],
+		showMenuBar: state.settings.showMenuBar,
 	};
 };
 
diff --git a/packages/app-desktop/gui/menuCommandNames.ts b/packages/app-desktop/gui/menuCommandNames.ts
index 66c4b463cb..2306dfbf9f 100644
--- a/packages/app-desktop/gui/menuCommandNames.ts
+++ b/packages/app-desktop/gui/menuCommandNames.ts
@@ -34,6 +34,7 @@ export default function() {
 		'toggleExternalEditing',
 		'toggleLayoutMoveMode',
 		'resetLayout',
+		'toggleMenuBar',
 		'toggleNoteList',
 		'toggleNotesSortOrderField',
 		'toggleNotesSortOrderReverse',
diff --git a/packages/lib/models/Setting.ts b/packages/lib/models/Setting.ts
index ebd60d8ba5..b096aec919 100644
--- a/packages/lib/models/Setting.ts
+++ b/packages/lib/models/Setting.ts
@@ -1298,6 +1298,13 @@ class Setting extends BaseModel {
 				isGlobal: true,
 			},
 
+			showMenuBar: {
+				value: true, // Show the menu bar by default
+				type: SettingItemType.Bool,
+				public: false,
+				appTypes: [AppType.Desktop],
+			},
+
 			startMinimized: { value: false, type: SettingItemType.Bool, storage: SettingStorage.File, isGlobal: true, section: 'application', public: true, appTypes: [AppType.Desktop], label: () => _('Start application minimised in the tray icon') },
 
 			collapsedFolderIds: { value: [], type: SettingItemType.Array, public: false },
diff --git a/packages/lib/services/KeymapService.ts b/packages/lib/services/KeymapService.ts
index 4f529ba20f..b78a2365e0 100644
--- a/packages/lib/services/KeymapService.ts
+++ b/packages/lib/services/KeymapService.ts
@@ -85,6 +85,7 @@ const defaultKeymapItems = {
 		{ accelerator: 'Ctrl+Shift+N', command: 'focusElementNoteTitle' },
 		{ accelerator: 'Ctrl+Shift+B', command: 'focusElementNoteBody' },
 		{ accelerator: 'F10', command: 'toggleSideBar' },
+		{ accelerator: 'Ctrl+Shift+M', command: 'toggleMenuBar' },
 		{ accelerator: 'F11', command: 'toggleNoteList' },
 		{ accelerator: 'Ctrl+L', command: 'toggleVisiblePanes' },
 		{ accelerator: 'Ctrl+0', command: 'zoomActualSize' },