Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@morning4coffe-dev
Copy link
Member

GitHub Issue: #22032

PR Type:

  • 🐞 Bugfix

PR Checklist βœ…

Please check if your PR fulfills the following requirements:

Copilot AI review requested due to automatic review settings December 14, 2025 14:07
@github-actions github-actions bot added the platform/macos 🍏 Categorizes an issue or PR as relevant to the macOS platform label Dec 14, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements macOS standard keyboard shortcuts (Command+W to close windows and Command+Q to quit the application) for the Uno Platform's Skia.MacOS runtime. The implementation addresses issue #22032 by adding both menu-based shortcuts and custom keyboard event handling to ensure these shortcuts work consistently across different application configurations.

Key changes:

  • Adds default application menu with Command+W (Close Window) and Command+Q (Quit) menu items when no menu exists
  • Implements custom performKeyEquivalent: method in UNOWindow to handle keyboard shortcuts directly
  • Refactors the applicationShouldTerminate: delegate method for improved code clarity

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/Uno.UI.Runtime.Skia.MacOS/UnoNativeMac/UnoNativeMac/UNOApplication.m Creates default menu with Command+W and Command+Q shortcuts when mainMenu is nil; refactors terminate callback logic
src/Uno.UI.Runtime.Skia.MacOS/UnoNativeMac/UnoNativeMac/UNOWindow.m Adds performKeyEquivalent method to handle Command+W (close) and Command+Q (quit) keyboard shortcuts
src/Uno.UI.Runtime.Skia.MacOS/UnoNativeMac/UnoNativeMac/UNOWindow.h Adds performKeyEquivalent method declaration to the UNOWindow interface

Comment on lines +40 to +71
if (app.mainMenu == nil) {
NSMenu *mainMenu = [[NSMenu alloc] init];

// App menu
NSMenuItem *appMenuItem = [[NSMenuItem alloc] init];
NSMenu *appMenu = [[NSMenu alloc] init];

// Quit menu item with Command+Q
NSMenuItem *quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
action:@selector(terminate:)
keyEquivalent:@"q"];
[appMenu addItem:quitMenuItem];
[appMenuItem setSubmenu:appMenu];
[mainMenu addItem:appMenuItem];

// File menu
NSMenuItem *fileMenuItem = [[NSMenuItem alloc] initWithTitle:@"File" action:nil keyEquivalent:@""];
NSMenu *fileMenu = [[NSMenu alloc] initWithTitle:@"File"];

// Close window menu item with Command+W
NSMenuItem *closeMenuItem = [[NSMenuItem alloc] initWithTitle:@"Close Window"
action:@selector(performClose:)
keyEquivalent:@"w"];
[fileMenu addItem:closeMenuItem];
[fileMenuItem setSubmenu:fileMenu];
[mainMenu addItem:fileMenuItem];

[app setMainMenu:mainMenu];
#if DEBUG
NSLog(@"uno_app_initialize: Created default menu with Command+Q and Command+W shortcuts");
#endif
}
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The menu creation logic creates a duplicate handling mechanism for keyboard shortcuts. The menu items define Command+W and Command+Q with keyEquivalent properties, but the performKeyEquivalent method in UNOWindow.m also handles these same shortcuts directly. This creates two separate code paths for the same functionality, which can lead to maintenance issues.

Consider removing the redundant performKeyEquivalent implementation in UNOWindow.m and relying solely on the menu system to handle these shortcuts. macOS will automatically route menu keyboard equivalents to their associated actions (performClose: and terminate:) without requiring manual event handling.

Copilot uses AI. Check for mistakes.
Comment on lines +176 to +180
if (!uno_get_application_can_exit_callback()()) {
return NSTerminateCancel;
}

return NSTerminateNow;
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The refactoring of applicationShouldTerminate is functionally equivalent to the original ternary expression but more verbose. The original code was clear and concise. The new version with early return for NSTerminateCancel followed by returning NSTerminateNow adds lines without improving readability or functionality.

Consider reverting to the original ternary expression format as it was more concise and equally readable.

Suggested change
if (!uno_get_application_can_exit_callback()()) {
return NSTerminateCancel;
}
return NSTerminateNow;
return uno_get_application_can_exit_callback()() ? NSTerminateNow : NSTerminateCancel;

Copilot uses AI. Check for mistakes.
Comment on lines +1097 to +1122
- (BOOL)performKeyEquivalent:(NSEvent *)event {
// Handle Command+W (close window) and Command+Q (quit app)
if ([event type] == NSEventTypeKeyDown && ([event modifierFlags] & NSEventModifierFlagCommand)) {
NSString *characters = [event charactersIgnoringModifiers];

// Command+W - Close window
if ([characters isEqualToString:@"w"]) {
#if DEBUG
NSLog(@"UNOWindow %p performKeyEquivalent Command+W", self);
#endif
[self performClose:self];
return YES;
}

// Command+Q - Quit application
if ([characters isEqualToString:@"q"]) {
#if DEBUG
NSLog(@"UNOWindow %p performKeyEquivalent Command+Q", self);
#endif
[[NSApplication sharedApplication] terminate:self];
return YES;
}
}

return [super performKeyEquivalent:event];
}
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The performKeyEquivalent implementation may intercept keyboard shortcuts before they reach the menu system, potentially bypassing menu validation and delegate methods. When both a menu item with a keyEquivalent and a custom performKeyEquivalent handler exist for the same shortcut, the custom handler in the window takes precedence, which can cause inconsistent behavior.

If the menu approach doesn't work in all scenarios (e.g., when no menu is present), consider documenting why both mechanisms are needed, or ensure the menu creation is mandatory rather than conditional on app.mainMenu == nil.

Copilot uses AI. Check for mistakes.
@unodevops
Copy link
Contributor

πŸ€– Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-22134/wasm-skia-net9/index.html

@unodevops
Copy link
Contributor

πŸ€– Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-22134/docs/index.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform/macos 🍏 Categorizes an issue or PR as relevant to the macOS platform

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants