-
-
Notifications
You must be signed in to change notification settings - Fork 607
Description
Feature Request: Add Support for Custom Menu Items in Main App Menu (macOS)
Description
Currently, pywebview allows creating custom menus through the menu
parameter, but these menus are always added as separate top-level menus in the menu bar. There is no way to add custom menu items to the main application menu (the first menu that shows the app name on macOS).
The main app menu currently only contains the standard system items:
- About
- Services
- Hide/Show
- Quit
This limitation prevents developers from adding app-specific items like:
- Preferences/Settings
- Check for Updates
- License Information
- Custom app-specific actions
Use Case
Many macOS applications have custom items in their main app menu. For example:
- Preferences (⌘,) - Standard location for app settings
- Check for Updates - Common for apps with auto-update functionality
- Registration/License - For commercial applications
- Custom Actions - App-specific global actions
Proposed Solutions
I'd like to propose several approaches and get feedback on which would be most appropriate:
Option 1: Special Flag in Menu Class (Minimal API Change)
Add an is_app_menu
parameter to the Menu class:
import webview
from webview import Menu, MenuAction
def open_preferences():
print("Opening preferences...")
def check_updates():
print("Checking for updates...")
# Special menu with is_app_menu flag
app_menu_items = Menu('', [
MenuAction('Preferences...', open_preferences),
MenuSeparator(),
MenuAction('Check for Updates', check_updates)
], is_app_menu=True)
# Regular menus
file_menu = Menu('File', [
MenuAction('New', new_file),
MenuAction('Open', open_file)
])
window = webview.create_window('App', menu=[app_menu_items, file_menu])
Pros:
- Minimal API change
- Backward compatible
- Clear intent with the flag
Cons:
- The
title
parameter is ignored whenis_app_menu=True
- Might be confusing to have a Menu object that doesn't create a menu
Option 2: Separate Parameter for App Menu Items
Add a new app_menu_items
parameter to create_window
:
import webview
from webview import MenuAction, MenuSeparator
def open_preferences():
print("Opening preferences...")
app_items = [
MenuAction('Preferences...', open_preferences),
MenuSeparator(),
MenuAction('Check for Updates', check_updates)
]
regular_menus = [
Menu('File', [MenuAction('New', new_file)])
]
window = webview.create_window(
'App',
menu=regular_menus,
app_menu_items=app_items # New parameter
)
Pros:
- Clear separation of concerns
- No ambiguity about menu titles
- More explicit API
Cons:
- Adds another parameter to
create_window
- Breaks existing API pattern
Option 3: Special Menu Title Convention
Use a special title (like __app__
or empty string) to indicate app menu items:
import webview
from webview import Menu, MenuAction
# Empty title or special string means app menu
app_menu = Menu('', [ # or Menu('__app__', [...])
MenuAction('Preferences...', open_preferences),
MenuAction('Check for Updates', check_updates)
])
file_menu = Menu('File', [
MenuAction('New', new_file)
])
window = webview.create_window('App', menu=[app_menu, file_menu])
Pros:
- No API changes needed
- Works with existing code structure
Cons:
- Implicit behavior based on magic strings
- Less discoverable
Option 4: Platform-Specific Menu Configuration
Create a more comprehensive menu system that handles platform differences:
import webview
from webview import MenuConfig, MenuAction
menu_config = MenuConfig()
menu_config.add_to_app_menu([ # macOS only, ignored on other platforms
MenuAction('Preferences...', open_preferences),
MenuAction('Check for Updates', check_updates)
])
menu_config.add_menu('File', [
MenuAction('New', new_file)
])
window = webview.create_window('App', menu_config=menu_config)
Pros:
- Can handle platform-specific differences elegantly
- More extensible for future menu features
- Could support shortcuts, accelerators, etc.
Cons:
- Larger API change
- More complex implementation
Implementation Considerations
Platform Compatibility
- macOS: Full support - has a distinct app menu
- Windows/Linux: These platforms don't have a separate app menu. Options:
- Ignore app menu items on these platforms
- Add them to a "File" or first menu
- Create a synthetic app menu
Menu Item Positioning
Where should custom items be placed in the app menu?
- After "About" but before system items
- Before "Quit" at the bottom
- Configurable position
Separator Handling
Should we automatically add separators between custom items and system items, or leave it to the developer?
Questions for Maintainers
- Which approach aligns best with pywebview's design philosophy?
- Are there any concerns about platform compatibility?
- Should this be macOS-only or have fallback behavior for other platforms?
- Any preferences for the implementation approach?
Willing to Contribute
I'm happy to implement this feature once we agree on the approach. I've already explored the codebase and understand how the current menu system works in the Cocoa implementation.
Related Issues
- This could potentially relate to keyboard shortcuts/accelerators support
- May benefit from a more comprehensive menu system redesign
Environment:
- pywebview version: [latest master]
- Platform: macOS
- Python version: 3.x