Repository: electron/electron
Pull request: fix: allow NSMenuItems to be disabled

#### Description of Change
Electron allows their menu items to enabled or disabled based on a boolean flag for key `enabled` (details [here](https://www.electronjs.org/docs/latest/api/menu-item)). From the `context-menu` event, an engineer can check if a menu item _should_ be disabled or enabled by reading the [editFlags object](https://www.electronjs.org/docs/latest/api/web-contents#:~:text=can%20be%20looped.-,editFlags%20Object,-%2D%20These%20flags%20indicate), which determines if an action is available such as `canCopy` and `canPaste`. 

However, the `enabled` key is not being honored when set to `false`, as shown in Image 1. 

This PR addresses this issue, by setting NSMenu's `setAutoenablesItem` to `No`. By default, it was set to `Yes`; as a result, when a user event occurred, it would override the `No` value to `Yes`. For more details, see Image 2, and relevant links [here](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.html) and [here](https://stackoverflow.com/questions/9368654/cannot-seem-to-setenabledno-on-nsmenuitem). 


**Image 1: `enabled` key not working as expected, as `Cut` and `Paste` should be disabled**
<img width="650" alt="disabledNotWorking" src="https://github.com/user-attachments/assets/a9d2235f-f987-4be5-9ab9-658d14f4433a" />

**Image 2: `enabled` key being honored after setting `setAutoenablesItem` to `No`**
<img width="650" alt="disabledWorking" src="https://github.com/user-attachments/assets/02f08ee3-7b02-4acc-9ab8-7f3439052eb6" />

#### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

- [ ] PR description included and stakeholders cc'd
- [ ] `npm test` passes
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
- [ ] relevant API documentation, tutorials, and examples are updated and follow the [documentation style guide](https://github.com/electron/electron/blob/main/docs/development/style-guide.md)

#### Release Notes

Notes: When a menu item on macOS is disabled (`enabled = false`), it is now greyed out.


Changed files:
filename: shell/browser/ui/cocoa/electron_menu_controller.mm
patch: @@ -320,6 +320,10 @@ - (NSMenuItem*)makeMenuItemForIndex:(NSInteger)index
   NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:label
                                                 action:@selector(itemSelected:)
                                          keyEquivalent:@""];
+  if (model->IsEnabledAt(index))
+    [item setEnabled:YES];
+  else
+    [item setEnabled:NO];
 
   // If the menu item has an icon, set it.
   ui::ImageModel icon = model->GetIconAt(index);
@@ -349,11 +353,6 @@ - (NSMenuItem*)makeMenuItemForIndex:(NSInteger)index
     [item setSubmenu:[self createShareMenuForItem:sharing_item]];
   } else if (type == electron::ElectronMenuModel::TYPE_SUBMENU &&
              model->IsVisibleAt(index)) {
-    // We need to specifically check that the submenu top-level item has been
-    // enabled as it's not validated by validateUserInterfaceItem
-    if (!model->IsEnabledAt(index))
-      [item setEnabled:NO];
-
     // Recursively build a submenu from the sub-model at this index.
     [item setTarget:nil];
     [item setAction:nil];
@@ -493,8 +492,10 @@ - (void)performShare:(NSMenuItem*)sender {
 }
 
 - (NSMenu*)menu {
-  if (menu_)
+  if (menu_) {
+    [menu_ setAutoenablesItems:NO];
     return menu_;
+  }
 
   if (model_ && model_->sharing_item()) {
     NSMenu* menu = [self createShareMenuForItem:*model_->sharing_item()];
@@ -504,6 +505,8 @@ - (NSMenu*)menu {
     if (model_)
       [self populateWithModel:model_.get()];
   }
+
+  [menu_ setAutoenablesItems:NO];
   [menu_ setDelegate:self];
   return menu_;
 }