Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ComposePanel focus traversal on windows with nvda (Windows) #1363

Merged

Conversation

m-sasha
Copy link

@m-sasha m-sasha commented May 20, 2024

ComposePanel keeps its own _isFocusable and _isRequestFocusEnabled flags, and doesn't call the superclass' methods on setFocusable and setRequestFocusEnabled. Unfortunately Swing is not a well-behaved object-oriented library, and calling the superclass' methods has side effects which are needed.

Component.setFocusable sets an isFocusTraversableOverridden flag which is consulted when determining the "next" focusable component (see DefaultFocusTraversalPolicy.accept()). This flag's value is, by default, FOCUS_TRAVERSABLE_UNKNOWN, causing isFocusTraversableOverridden() to return true, which causes the ComposePanel to be accepted by DefaultFocusTraversalPolicy.accept().

When NVDA is turned on, however, the accessibility system calls ComposePanel.isFocusTraversable, which sets this flag to FOCUS_TRAVERSABLE_DEFAULT, causing isFocusTraversableOverridden() to return false, which causes DefaultFocusTraversalPolicy.accept() to reject the ComposePanel. If Component.setFocusable has been called before that, this doesn't happen because the flag is set with:

        if (isFocusTraversableOverridden == FOCUS_TRAVERSABLE_UNKNOWN) {
            isFocusTraversableOverridden = FOCUS_TRAVERSABLE_DEFAULT;
        }

An alternative solution here would be for ComposePanel to override isFocusTraversable in addition to isFocusable, thus preventing the isFocusTraversableOverridden from being set. This would be a less disruptive change, but I think the more correct way is to call the superclass' methods, as they have additional side effects (setFocusable fires a property change, for example).

Fixes https://youtrack.jetbrains.com/issue/COMPOSE-1398/Make-ComposePanel-transparent-to-accessibility

Testing

Run the app below on Windows, with NVDA turned on, and try traversing the buttons using (ctrl)-shift-tab.
Before this PR, the focus would jump only between the Swing buttons. After it, it will correctly go onto the Compose Button.

fun main() {
    SwingUtilities.invokeLater {
        val frame = JFrame()
        val panel = JPanel(GridLayout(3, 1))
        frame.contentPane.add(panel)

        panel.add(JPanel().apply {
            add(JButton("Swing Button 1"))
        })
        panel.add(ComposePanel().apply {
            setContent {
                Column {
                    Button(onClick = {}) { Text("Compose Button") }
                }
            }
        })
        panel.add(JPanel(GridLayout(2, 1)).apply {
            add(JButton("Swing Button 2"))
        })
        frame.size = Dimension(400, 500)
        frame.isVisible = true
    }
}

This could be tested by QA

Release Notes

Fixes - Desktop

  • When using ComposePanel inside a Swing application on Windows with NVDA turned on, focus will now correctly go into the ComposePanel when traversing with (ctrl)-shift-tab.

@m-sasha m-sasha requested a review from igordmn May 20, 2024 12:13
@m-sasha m-sasha force-pushed the m-sasha/fix-ComposePanel-focus-traversal-on-windows-with-nvda branch from 6f18c02 to 752ca3a Compare May 21, 2024 10:54
Base automatically changed from m-sasha/allow-a11y-to-ignore-root-containers to jb-main May 22, 2024 09:38
…usEnabled methods, because they have side effects needed for correct focus traversal (isFocusTraversableOverridden).
@m-sasha m-sasha force-pushed the m-sasha/fix-ComposePanel-focus-traversal-on-windows-with-nvda branch from 752ca3a to 7ba51a4 Compare May 22, 2024 09:41
Copy link
Collaborator

@igordmn igordmn left a comment

Choose a reason for hiding this comment

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

Tested on Windows - works as expected with/without NVDA, unit test pass.

@m-sasha m-sasha merged commit ed8c8d1 into jb-main May 22, 2024
6 checks passed
@m-sasha m-sasha deleted the m-sasha/fix-ComposePanel-focus-traversal-on-windows-with-nvda branch May 22, 2024 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants