Skip to content

Menu Modification Mechanism Fails on macOS While Functioning on Rocky9 and Windows11 #25

@mariapanneerrajan-spi

Description

@mariapanneerrajan-spi

Menu Modification Mechanism Fails on macOS While Functioning on Rocky9 and Windows11

Problem Summary

We have implemented a dynamic menu modification mechanism in OpenRV that successfully works on Rocky9 and Windows11 platforms, but fails to function properly on macOS. The mechanism uses Qt event filters to intercept and modify menu bar events, but macOS's different menu handling approach prevents these modifications from taking effect.

Affected Functionality

The RPA (Review Plugin API) mode in OpenRV relies on this menu modification mechanism to:

  • Add a "Switch to RPA" menu item under the "Open RV" menu
  • Dynamically modify menu options when entering/exiting RPA mode
  • Hide/show specific menu items and toolbars based on the current mode

Technical Context

File Location: rpa/open_rv/pkgs/rpa_widgets_pkg/rpa_widgets_mode.py

Core Implementation:

def eventFilter(self, object, event):
    if isinstance(object, QtWidgets.QMenuBar) and \
    event.type() == QtCore.QEvent.Paint:
        self.__setup_switch_mode_action()

    if not self.__is_rpa_mode:
        return False

    if isinstance(object, QtWidgets.QMenuBar) and \
    event.type() == QtCore.QEvent.Paint:
        self.__setup_rpa_mode_menus(object)

    if isinstance(object, QtWidgets.QMenu) and \
    event.type() == QtCore.QEvent.Show:
        parent = object.parent()
        if parent is self.__main_window:
            self.__setup_rpa_mode_menus(object)
    
    # ... additional event handling
    return False

Menu Setup Method:

def __setup_switch_mode_action(self):
    menu = self.__main_window.menuBar()
    if menu is None: return
    open_rv_action = None
    for action in menu.actions():
        if action.text() == "Open RV":
            open_rv_action = action
            break
    else: return
    menu = open_rv_action.menu()
    if not menu: return

    switch_mode_action = None
    quit_open_rv_action = None
    for action in menu.actions():
        if action.property("is_rpa_switch_action"):
            switch_mode_action = action
        elif action.text() == "Quit Open RV":
            quit_open_rv_action = action

    if switch_mode_action is None:
        action = QAction("Switch to RPA", parent=self.__main_window)
        action.triggered.connect(self.__switch_mode)
        action.setProperty("is_rpa_switch_action", True)
        menu.insertAction(quit_open_rv_action, action)

Platform-Specific Behavior

Working Platforms (Rocky9 & Windows11):

  • QEvent.Paint events fire reliably for QMenuBar
  • Menu modifications are applied immediately and persist
  • Event filter successfully intercepts menu-related events
  • Dynamic menu item addition works as expected

macOS Issues:

  • QEvent.Paint events for QMenuBar may not fire consistently
  • Menu modifications are not applied or don't persist
  • The global menu bar integration on macOS affects event handling
  • Menu items may not appear or become unresponsive

Root Cause Analysis

Based on Qt community reports and macOS-specific behavior:

  1. Global Menu Bar Integration: macOS integrates application menus into the system's global menu bar, which changes how Qt handles menu events
  2. Event Timing: The timing of QEvent.Paint events differs on macOS due to the global menu bar architecture
  3. Native Menu Handling: macOS uses native menu rendering which can interfere with Qt's event system
  4. Focus Management: Menu responsiveness on macOS often requires proper application focus management

Steps to Reproduce

  1. Environment Setup:

    # macOS environment
    OS: macOS (tested on Monterey 12.5.1, Ventura 13.x)
    OpenRV: Built from source (latest main branch)
    Python: 3.11 (as bundled with OpenRV)
    Qt/PySide: PySide2 (as bundled with OpenRV)
  2. Installation Steps:

    # Clone and build RPA package
    cd /path/to/ori-shared-platform
    ./rpa/build_scripts/build.sh
    ./rpa/build_scripts/install.sh
  3. Reproduction Steps:

    • Launch OpenRV on macOS
    • Navigate to the menu bar
    • Look for "Open RV" menu
    • Expected: Should see "Switch to RPA" menu item
    • Actual: Menu item is missing or not functional

Expected vs Actual Behavior

Expected Behavior:

  • "Switch to RPA" menu item appears under "Open RV" menu
  • Clicking the menu item shows confirmation dialog
  • Menu modifications persist across application sessions
  • RPA mode activation works through menu interaction

Actual Behavior on macOS:

  • "Switch to RPA" menu item does not appear
  • Menu modifications are not applied
  • No visual indication of RPA mode availability
  • Users cannot access RPA functionality through the menu

Potential Solutions to Investigate

  1. Environment Variable Fix:

    import os
    os.environ['QT_MAC_WANTS_LAYER'] = '1'
  2. Native Menu Bar Handling:

    menubar.setNativeMenuBar(True)  # or False
  3. Application Focus Management:

    self.__main_window.activateWindow()
    self.__main_window.raise_()
  4. Alternative Event Handling for macOS:

    if platform.system() == 'Darwin':
        # Use different events for macOS
        if event.type() == QtCore.QEvent.Show:
            self.__setup_switch_mode_action()
  5. Timer-Based Menu Updates:

    # Force menu updates periodically on macOS
    timer = QtCore.QTimer()
    timer.timeout.connect(self.__force_menu_update)
    timer.start(100)  # Update every 100ms

Debugging Information

Current Debug Output:

  • No error messages or exceptions are thrown
  • Event filter is installed successfully
  • Menu bar object is found and accessible
  • The issue is silent - modifications simply don't appear

Useful Debug Commands:

# Add to eventFilter for debugging
if platform.system() == 'Darwin':
    logger = create_logger()
    if isinstance(object, QtWidgets.QMenuBar):
        logger.info(f"macOS MenuBar event: {event.type()}")

Related Issues and References

Files to Examine

  1. Primary: rpa/open_rv/pkgs/rpa_widgets_pkg/rpa_widgets_mode.py
  2. Related: rpa/open_rv/pkgs/rpa_core_pkg/rpa_core_mode.py
  3. Build: rpa/build_scripts/build.sh, rpa/build_scripts/install.sh

Testing Approach

  1. Cross-Platform Testing: Verify the issue only occurs on macOS
  2. Event Monitoring: Add logging to track which events fire on macOS vs other platforms
  3. Menu State Inspection: Examine menu bar state before and after modification attempts
  4. Alternative Event Types: Test different Qt events for menu modification triggers

Impact

This issue prevents macOS users from accessing RPA functionality through the standard menu interface, creating a significant usability barrier and platform inconsistency. The RPA mode is a core feature that should work uniformly across all supported platforms.

Additional Context

This issue appears to be specific to macOS, as the same mechanism operates correctly on Rocky9 and Windows11 platforms. The problem stems from macOS's unique approach to menu handling and Qt's integration with the global menu bar system.

OpenRV GitHub Repository: https://github.com/AcademySoftwareFoundation/OpenRV

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions