Difference between revisions of "Cocoa Internals/Menu"

From Lazarus wiki
Jump to navigationJump to search
 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Menu logic in macOS is different from the one in Windows (and other systems). The entire application only has one menu on top. That's it. There are no "per window" menus attached. (instead a window could use a Toolbar instead)
+
The menu logic in macOS is different from the one in Windows and other systems. The menu bar runs along the top of the screen on the Mac. Sub-menus and icons in the menu bar let the user choose commands, perform tasks and check status. There is an option to automatically hide the menu bar so it's shown only when you move the pointer to the top of the screen. There are no "per window" menus attached (an application window could use a Toolbar instead). Only the Apple menu, system status menus (including third-party ones eg fan monitoring) and the '''active''' application's menu appear in the menu bar.
  
 
==Basic Logic==
 
==Basic Logic==
 +
This is how the contents of the menu is defined:
 
* The TMainMenu of the active window is set as the Application menu
 
* The TMainMenu of the active window is set as the Application menu
 
* If active window doesn't have TMainMenu the last active window with TMainMenu is still used
 
* If active window doesn't have TMainMenu the last active window with TMainMenu is still used
 
* The Window running as modal disables the main menu, UNLESS it has its own main menu.
 
* The Window running as modal disables the main menu, UNLESS it has its own main menu.
 +
 
==Implementation==
 
==Implementation==
used classes are
+
Used classes are:
 
* NSMenu  
 
* NSMenu  
 
* NSMenuItem
 
* NSMenuItem
 +
 
===Application Menu===
 
===Application Menu===
If there's TMainMenu allocated for LCL form, WSCocoa internally allocates the "Application" menu. The "Application" menu is macOS convention, that any app should do it. Since there's no logical concept of "Application" menu in LCL, CocoaWS simply always creates it for you.
+
If there's a TMainMenu allocated for LCL form, WSCocoa internally allocates the "Application" menu. The "Application" menu is a macOS convention that any app should use. Since there's no logical concept of "Application" menu in the LCL, CocoaWS simply always creates it for you.
 +
 
 
===Application Menu Translation===
 
===Application Menu Translation===
The titles (caption) of the Application menus are stored as "resourcestring" and could be translated by a translation module.
+
The titles (caption) of the Application menus are stored as [[IDE Window: Make ResourceString|"resourcestring"]] and could be translated by a translation module.
  
==See Also==
+
===Menus and Menu Items Clicks===
 +
There's a difference between Menus and MenuItems. "Menus" is simply a "MenuItem" with a submenu (and other subitems).
 +
 
 +
The difference is how CocoaWS is reporting "clicks" to the LCL.
 +
 
 +
For "Menus" the clicks are reported when a mouse HOVERs over the menuitem. (this is due to the fact of the click is called at '''menuNeedUpdate:'''. Calling at '''menuWillOpen:''' is too late, as macOS directly forbids changing the submenu items at that time).
 +
 
 +
"Clicks" for "MenuItems" are called only when the menu is already closed (the released the mouse). Yet, visually, it looks the as if the action takes place immediately.
 +
 
 +
==Popup (Context) Menu==
 +
Cocoa provides NSView - based  mechanism for handling context menus. The mechanism is not used by LCL.
 +
 
 +
Instead, mouse events are listened. When either "right" click or "ctrl+click" is detected LM_ContextMenu event would be fired.
 +
 
 +
Note: unlike Windows, macOS context menus are shown on "mouse-down" event. (on Windows, context menu event follows "mouse up" event).
 +
 
 +
MacOS context menu doesn't have a corresponding keyboard short cut. "Context Menu" button (VK_APPS) is recognized as a button (and corresponding KeyDown, KeyUp events are called), but it doesn't cause the context menu to be shown up (anywhere in macOS system).
 +
 
 +
==See also==
 +
 
 +
* [[Cocoa Internals]] - Overview.
 
* [[Cocoa Internals/Application]]
 
* [[Cocoa Internals/Application]]
 
* [[Cocoa Internals/Forms]]
 
* [[Cocoa Internals/Forms]]
 +
* [[Cocoa Internals/Input]]
 +
 
[[Category:Cocoa]]
 
[[Category:Cocoa]]
 
[[Category:Lazarus internals]]
 
[[Category:Lazarus internals]]
 
[[Category:macOS]]
 
[[Category:macOS]]

Latest revision as of 19:33, 14 May 2022

The menu logic in macOS is different from the one in Windows and other systems. The menu bar runs along the top of the screen on the Mac. Sub-menus and icons in the menu bar let the user choose commands, perform tasks and check status. There is an option to automatically hide the menu bar so it's shown only when you move the pointer to the top of the screen. There are no "per window" menus attached (an application window could use a Toolbar instead). Only the Apple menu, system status menus (including third-party ones eg fan monitoring) and the active application's menu appear in the menu bar.

Basic Logic

This is how the contents of the menu is defined:

  • The TMainMenu of the active window is set as the Application menu
  • If active window doesn't have TMainMenu the last active window with TMainMenu is still used
  • The Window running as modal disables the main menu, UNLESS it has its own main menu.

Implementation

Used classes are:

  • NSMenu
  • NSMenuItem

Application Menu

If there's a TMainMenu allocated for LCL form, WSCocoa internally allocates the "Application" menu. The "Application" menu is a macOS convention that any app should use. Since there's no logical concept of "Application" menu in the LCL, CocoaWS simply always creates it for you.

Application Menu Translation

The titles (caption) of the Application menus are stored as "resourcestring" and could be translated by a translation module.

Menus and Menu Items Clicks

There's a difference between Menus and MenuItems. "Menus" is simply a "MenuItem" with a submenu (and other subitems).

The difference is how CocoaWS is reporting "clicks" to the LCL.

For "Menus" the clicks are reported when a mouse HOVERs over the menuitem. (this is due to the fact of the click is called at menuNeedUpdate:. Calling at menuWillOpen: is too late, as macOS directly forbids changing the submenu items at that time).

"Clicks" for "MenuItems" are called only when the menu is already closed (the released the mouse). Yet, visually, it looks the as if the action takes place immediately.

Popup (Context) Menu

Cocoa provides NSView - based mechanism for handling context menus. The mechanism is not used by LCL.

Instead, mouse events are listened. When either "right" click or "ctrl+click" is detected LM_ContextMenu event would be fired.

Note: unlike Windows, macOS context menus are shown on "mouse-down" event. (on Windows, context menu event follows "mouse up" event).

MacOS context menu doesn't have a corresponding keyboard short cut. "Context Menu" button (VK_APPS) is recognized as a button (and corresponding KeyDown, KeyUp events are called), but it doesn't cause the context menu to be shown up (anywhere in macOS system).

See also