0

In Python, using wxPython Phoenix 4.1.1 wx.html2 module's WebView, when the page loads, I want the keyboard focus to land on the first element on the page, so that I can start reading the page from its very begining with the Down arrow key using the JAWS or NVDA screen reader. But I am unable to achieve that, as upon page load the screen reader keyboard focus always jumps somewhere into the middle of the page instead. I have tried setting the focus with JavaScript manually to the first <h1> element on the page using the RunScript function which is called in the wx.html2.EVT_WEBVIEW_LOADED event handler, as demonstrated below, but that has no effect at all.

Note that in this code I am using the trick described here to move the screen reader focus into the WebView component after the WebView component is showed.

class HelpHTMLDialog(wx.Dialog):
  def __init__(self, title, parent = None):
    super(HelpHTMLDialog, self).__init__(parent = parent, title = title)
    
    self.addBrowser()
    
    self.SetSize((900, 700))
    self.Centre()
    self.ShowModal()
    
  # Adds the web browser to this dialog and binds the page load event.
  def addBrowser(self):
    vbox = wx.BoxSizer(wx.VERTICAL)
    
    self.browser = wx.html2.WebView.New(self)
    self.Bind(wx.html2.EVT_WEBVIEW_LOADED, self.onPageLoad, self.browser)
    html = self.getHTML()
    self.browser.SetPage(html, '')
    
    vbox.Add(self.browser, 1, wx.EXPAND, 10)
    self.SetSizer(vbox)
    
  # Handles the WebView page load.
  def onPageLoad(self, event):
    # Clicks on the left upper corner of the page to move screen reader focus to the page
    self.browser.SetFocus()
    position = self.browser.GetPosition()
    position = self.browser.ClientToScreen(position)
    robot = wx.UIActionSimulator()
    robot.MouseMove(position)
    robot.MouseClick()
    
    # Move the keyboard focus to the first <h1> heading on the page
    self.browser.RunScript('''
var first = document.getElementsByTagName('h1')[0];
first.tabIndex = -1;
first.focus();
// I know this code runs after page load without a problem, because I tried to put alert('test') here, and it worked.
''')
    
  # Gets the HTML of the page.
  def getHTML(self):
    html = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>Hello Python</h1>
<h2>First heading</h2>
<p>Here is some text just to demonstrate the use of wx.html2.WebView in Python.</p>
<ul>
<li>Firs item.</li>
<li>Second item.</li>
<li>Third item.</li>
<li>Fourth item.</li>
</ul>
<h2>Second heading</h2>
<p>Final paragraph is here just to make the page a bit longer.</p>
<script>
// I have also tried putting the JavaScript code for focusing the first <h1> element here instead, but with no success either.
</script>
</body>
</html>
'''
    return html

So, please do you have any ideas how to effectively control the screen reader keyboard focus after page load in the manner I have described?

Thanks

Adam
  • 1,926
  • 23
  • 21
  • I don't know whether this is related but in may help `So I can focus the Chromium window (and default input element) by calling WebView2.Focus() only when my form contains another focusable control.` https://github.com/MicrosoftEdge/WebView2Feedback/issues/185 – Rolf of Saxony Aug 15 '21 at 17:25
  • What is the exact syntax for using `WebView2`? `wx.html2.WebView2` does not exist, only `wx.html2.WebView` exists. I am using Windows 10. – Adam Aug 15 '21 at 22:42
  • The link is a jumping off point for what appears to be a related issue, nothing more. – Rolf of Saxony Aug 16 '21 at 09:29

0 Answers0