prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  in tabbed notepad when switching between tabs nvda should announce some way to differentiate between tabs
  
  ### Steps to reproduce:
  download the new tabbed notepad.
  now using the menu create a new tab
  now switch between tabs with ctrl+tabe
  ### Actual behavior:
  nvda announces blank edition text editor
  ### Expected behavior:
  Before writing what I want, I would like to talk about my discoveries, sorry if it doesn't make sense.
  I typed a different word into the first line of text on each tab.
  guide example 1
  Fernando
  guide 2
  silva
  using object navigation I found the list of tabs and within this list there was each tab named with what was written in the first line of text.
  Now I left the first line of text empty in tab 1
  in the list of tabs tab 1 appears with the name of untitled
  from what i understand if the first line of text is characters this text will be the title of the tab.
  If the first line of text is empty, the tab will have an untitled title.
  so my suggestion is:
  when switching between tabs in notepad in this example by pressing ctrl+tab nvda should announce the title of the tab which will be what is typed in the first line.
  But this doesn't work if the first line of the tabs is empty, so I suggest that nvda also announce the position of the tab within the list.
  example
  guide 1
  first line
  Fernando
  guide 2
  first line
  empty
  guide 3
  first line
  silva
  when switching between tabs nvda would announce:
  guide 1 of 3 fernando
  guide 2 of 3 untitled
  guide 3 of 3 silva
  Tab name and tab count could also be announced by command nvda + t to read window name.
  ### NVDA logs, crash dumps and other attachments:
  
  ### System configuration
  #### NVDA installed/portable/running from source:
  instaled
  #### NVDA version:
  nvda.exe, NVDA alpha-27590,180c9f2b
  #### Windows version:
  11 22.623.1095
  #### Name and version of other software in use when reproducing the issue:
  Notepad.exe, Microsoft.WindowsNotepad 11.2212.33.0
  
  #### Other information about your system:
  
  ### Other questions
  #### Does the issue still occur after restarting your computer?
  yes
  #### Have you tried any other versions of NVDA? If so, please report their behaviors.
  no
  #### If NVDA add-ons are disabled, is your problem still occurring?
  yes
  #### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?
  yes
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `source/appModules/notepad.py`
  Content:
  ```
  1 # A part of NonVisual Desktop Access (NVDA)
  2 # Copyright (C) 2022-2023 NV Access Limited, Joseph Lee
  3 # This file is covered by the GNU General Public License.
  4 # See the file COPYING for more details.
  5 
  6 """App module for Windows Notepad.
  7 While this app module also covers older Notepad releases,
  8 this module provides workarounds for Windows 11 Notepad."""
  9 
  10 from comtypes import COMError
  11 import appModuleHandler
  12 import api
  13 import UIAHandler
  14 from NVDAObjects.UIA import UIA
  15 from NVDAObjects import NVDAObject
  16 
  17 
  18 class AppModule(appModuleHandler.AppModule):
  19 
  20 	def _get_statusBar(self) -> NVDAObject:
  21 		"""Retrieves Windows 11 Notepad status bar.
  22 		In Windows 10 and earlier, status bar can be obtained by looking at the bottom of the screen.
  23 		Windows 11 Notepad uses Windows 11 UI design (top-level window is labeled "DesktopWindowXamlSource",
  24 		therefore status bar cannot be obtained by position alone.
  25 		If visible, a child of the foreground window hosts the status bar elements.
  26 		Status bar child position must be checked whenever Notepad is updated on stable Windows 11 releases
  27 		as Notepad is updated through Microsoft Store as opposed to tied to specific Windows releases.
  28 		L{api.getStatusBar} will resort to position lookup if C{NotImplementedError} is raised.
  29 		"""
  30 		# #13688: Notepad 11 uses Windows 11 user interface, therefore status bar is harder to obtain.
  31 		# This does not affect earlier versions.
  32 		notepadVersion = int(self.productVersion.split(".")[0])
  33 		if notepadVersion < 11:
  34 			raise NotImplementedError()
  35 		# And no, status bar is shown when editing documents.
  36 		# Thankfully, of all the UIA objects encountered, document window has a unique window class name.
  37 		if api.getFocusObject().windowClassName != "RichEditD2DPT":
  38 			raise NotImplementedError()
  39 		# Obtain status bar text across Notepad 11 releases.
  40 		clientObject = UIAHandler.handler.clientObject
  41 		condition = clientObject.createPropertyCondition(UIAHandler.UIA_AutomationIdPropertyId, "ContentTextBlock")
  42 		walker = clientObject.createTreeWalker(condition)
  43 		notepadWindow = clientObject.elementFromHandle(api.getForegroundObject().windowHandle)
  44 		try:
  45 			element = walker.getFirstChildElement(notepadWindow)
  46 			# Is status bar even showing?
  47 			element = element.buildUpdatedCache(UIAHandler.handler.baseCacheRequest)
  48 		except (ValueError, COMError):
  49 			raise NotImplementedError
  50 		statusBar = UIA(UIAElement=element).parent
  51 		return statusBar
  52
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/source/appModules/notepad.py b/source/appModules/notepad.py
  --- a/source/appModules/notepad.py
  +++ b/source/appModules/notepad.py
  @@ -10,13 +10,38 @@
   from comtypes import COMError
   import appModuleHandler
   import api
  +import braille
  +import controlTypes
  +import eventHandler
  +import speech
   import UIAHandler
   from NVDAObjects.UIA import UIA
   from NVDAObjects import NVDAObject
  +from typing import Callable
   
   
   class AppModule(appModuleHandler.AppModule):
   
  +	def event_UIA_elementSelected(self, obj: NVDAObject, nextHandler: Callable[[], None]):
  +		# Announce currently selected tab when it changes.
  +		if (
  +			obj.role == controlTypes.Role.TAB
  +			# this is done because 2 selection events are sent for the same object, so to prevent double speaking.
  +			and not eventHandler.isPendingEvents("UIA_elementSelected")
  +			and controlTypes.State.SELECTED in obj.states
  +		):
  +			speech.cancelSpeech()
  +			speech.speakObject(obj, reason=controlTypes.OutputReason.FOCUS)
  +			braille.handler.message(
  +				braille.getPropertiesBraille(
  +					name=obj.name,
  +					role=obj.role,
  +					states=obj.states,
  +					positionInfo=obj.positionInfo
  +				)
  +			)
  +		nextHandler()
  +
   	def _get_statusBar(self) -> NVDAObject:
   		"""Retrieves Windows 11 Notepad status bar.
   		In Windows 10 and earlier, status bar can be obtained by looking at the bottom of the screen.
  
verification_info: {"golden_diff": "diff --git a/source/appModules/notepad.py b/source/appModules/notepad.py\n--- a/source/appModules/notepad.py\n+++ b/source/appModules/notepad.py\n@@ -10,13 +10,38 @@\n from comtypes import COMError\n import appModuleHandler\n import api\n+import braille\n+import controlTypes\n+import eventHandler\n+import speech\n import UIAHandler\n from NVDAObjects.UIA import UIA\n from NVDAObjects import NVDAObject\n+from typing import Callable\n \n \n class AppModule(appModuleHandler.AppModule):\n \n+\tdef event_UIA_elementSelected(self, obj: NVDAObject, nextHandler: Callable[[], None]):\n+\t\t# Announce currently selected tab when it changes.\n+\t\tif (\n+\t\t\tobj.role == controlTypes.Role.TAB\n+\t\t\t# this is done because 2 selection events are sent for the same object, so to prevent double speaking.\n+\t\t\tand not eventHandler.isPendingEvents(\"UIA_elementSelected\")\n+\t\t\tand controlTypes.State.SELECTED in obj.states\n+\t\t):\n+\t\t\tspeech.cancelSpeech()\n+\t\t\tspeech.speakObject(obj, reason=controlTypes.OutputReason.FOCUS)\n+\t\t\tbraille.handler.message(\n+\t\t\t\tbraille.getPropertiesBraille(\n+\t\t\t\t\tname=obj.name,\n+\t\t\t\t\trole=obj.role,\n+\t\t\t\t\tstates=obj.states,\n+\t\t\t\t\tpositionInfo=obj.positionInfo\n+\t\t\t\t)\n+\t\t\t)\n+\t\tnextHandler()\n+\n \tdef _get_statusBar(self) -> NVDAObject:\n \t\t\"\"\"Retrieves Windows 11 Notepad status bar.\n \t\tIn Windows 10 and earlier, status bar can be obtained by looking at the bottom of the screen.\n", "issue": "in tabbed notepad when switching between tabs nvda should announce some way to differentiate between tabs\n\r\n### Steps to reproduce:\r\ndownload the new tabbed notepad.\r\nnow using the menu create a new tab\r\nnow switch between tabs with ctrl+tabe\r\n### Actual behavior:\r\nnvda announces blank edition text editor\r\n### Expected behavior:\r\nBefore writing what I want, I would like to talk about my discoveries, sorry if it doesn't make sense.\r\nI typed a different word into the first line of text on each tab.\r\nguide example 1\r\nFernando\r\nguide 2\r\nsilva\r\nusing object navigation I found the list of tabs and within this list there was each tab named with what was written in the first line of text.\r\nNow I left the first line of text empty in tab 1\r\nin the list of tabs tab 1 appears with the name of untitled\r\nfrom what i understand if the first line of text is characters this text will be the title of the tab.\r\nIf the first line of text is empty, the tab will have an untitled title.\r\nso my suggestion is:\r\nwhen switching between tabs in notepad in this example by pressing ctrl+tab nvda should announce the title of the tab which will be what is typed in the first line.\r\nBut this doesn't work if the first line of the tabs is empty, so I suggest that nvda also announce the position of the tab within the list.\r\nexample\r\nguide 1\r\nfirst line\r\nFernando\r\nguide 2\r\nfirst line\r\nempty\r\nguide 3\r\nfirst line\r\nsilva\r\nwhen switching between tabs nvda would announce:\r\nguide 1 of 3 fernando\r\nguide 2 of 3 untitled\r\nguide 3 of 3 silva\r\nTab name and tab count could also be announced by command nvda + t to read window name.\r\n### NVDA logs, crash dumps and other attachments:\r\n\r\n### System configuration\r\n#### NVDA installed/portable/running from source:\r\ninstaled\r\n#### NVDA version:\r\nnvda.exe, NVDA alpha-27590,180c9f2b\r\n#### Windows version:\r\n11 22.623.1095\r\n#### Name and version of other software in use when reproducing the issue:\r\nNotepad.exe, Microsoft.WindowsNotepad 11.2212.33.0\r\n\r\n#### Other information about your system:\r\n\r\n### Other questions\r\n#### Does the issue still occur after restarting your computer?\r\nyes\r\n#### Have you tried any other versions of NVDA? If so, please report their behaviors.\r\nno\r\n#### If NVDA add-ons are disabled, is your problem still occurring?\r\nyes\r\n#### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?\r\nyes\n", "before_files": [{"content": "# A part of NonVisual Desktop Access (NVDA)\n# Copyright (C) 2022-2023 NV Access Limited, Joseph Lee\n# This file is covered by the GNU General Public License.\n# See the file COPYING for more details.\n\n\"\"\"App module for Windows Notepad.\nWhile this app module also covers older Notepad releases,\nthis module provides workarounds for Windows 11 Notepad.\"\"\"\n\nfrom comtypes import COMError\nimport appModuleHandler\nimport api\nimport UIAHandler\nfrom NVDAObjects.UIA import UIA\nfrom NVDAObjects import NVDAObject\n\n\nclass AppModule(appModuleHandler.AppModule):\n\n\tdef _get_statusBar(self) -> NVDAObject:\n\t\t\"\"\"Retrieves Windows 11 Notepad status bar.\n\t\tIn Windows 10 and earlier, status bar can be obtained by looking at the bottom of the screen.\n\t\tWindows 11 Notepad uses Windows 11 UI design (top-level window is labeled \"DesktopWindowXamlSource\",\n\t\ttherefore status bar cannot be obtained by position alone.\n\t\tIf visible, a child of the foreground window hosts the status bar elements.\n\t\tStatus bar child position must be checked whenever Notepad is updated on stable Windows 11 releases\n\t\tas Notepad is updated through Microsoft Store as opposed to tied to specific Windows releases.\n\t\tL{api.getStatusBar} will resort to position lookup if C{NotImplementedError} is raised.\n\t\t\"\"\"\n\t\t# #13688: Notepad 11 uses Windows 11 user interface, therefore status bar is harder to obtain.\n\t\t# This does not affect earlier versions.\n\t\tnotepadVersion = int(self.productVersion.split(\".\")[0])\n\t\tif notepadVersion < 11:\n\t\t\traise NotImplementedError()\n\t\t# And no, status bar is shown when editing documents.\n\t\t# Thankfully, of all the UIA objects encountered, document window has a unique window class name.\n\t\tif api.getFocusObject().windowClassName != \"RichEditD2DPT\":\n\t\t\traise NotImplementedError()\n\t\t# Obtain status bar text across Notepad 11 releases.\n\t\tclientObject = UIAHandler.handler.clientObject\n\t\tcondition = clientObject.createPropertyCondition(UIAHandler.UIA_AutomationIdPropertyId, \"ContentTextBlock\")\n\t\twalker = clientObject.createTreeWalker(condition)\n\t\tnotepadWindow = clientObject.elementFromHandle(api.getForegroundObject().windowHandle)\n\t\ttry:\n\t\t\telement = walker.getFirstChildElement(notepadWindow)\n\t\t\t# Is status bar even showing?\n\t\t\telement = element.buildUpdatedCache(UIAHandler.handler.baseCacheRequest)\n\t\texcept (ValueError, COMError):\n\t\t\traise NotImplementedError\n\t\tstatusBar = UIA(UIAElement=element).parent\n\t\treturn statusBar\n", "path": "source/appModules/notepad.py"}], "after_files": [{"content": "# A part of NonVisual Desktop Access (NVDA)\n# Copyright (C) 2022-2023 NV Access Limited, Joseph Lee\n# This file is covered by the GNU General Public License.\n# See the file COPYING for more details.\n\n\"\"\"App module for Windows Notepad.\nWhile this app module also covers older Notepad releases,\nthis module provides workarounds for Windows 11 Notepad.\"\"\"\n\nfrom comtypes import COMError\nimport appModuleHandler\nimport api\nimport braille\nimport controlTypes\nimport eventHandler\nimport speech\nimport UIAHandler\nfrom NVDAObjects.UIA import UIA\nfrom NVDAObjects import NVDAObject\nfrom typing import Callable\n\n\nclass AppModule(appModuleHandler.AppModule):\n\n\tdef event_UIA_elementSelected(self, obj: NVDAObject, nextHandler: Callable[[], None]):\n\t\t# Announce currently selected tab when it changes.\n\t\tif (\n\t\t\tobj.role == controlTypes.Role.TAB\n\t\t\t# this is done because 2 selection events are sent for the same object, so to prevent double speaking.\n\t\t\tand not eventHandler.isPendingEvents(\"UIA_elementSelected\")\n\t\t\tand controlTypes.State.SELECTED in obj.states\n\t\t):\n\t\t\tspeech.cancelSpeech()\n\t\t\tspeech.speakObject(obj, reason=controlTypes.OutputReason.FOCUS)\n\t\t\tbraille.handler.message(\n\t\t\t\tbraille.getPropertiesBraille(\n\t\t\t\t\tname=obj.name,\n\t\t\t\t\trole=obj.role,\n\t\t\t\t\tstates=obj.states,\n\t\t\t\t\tpositionInfo=obj.positionInfo\n\t\t\t\t)\n\t\t\t)\n\t\tnextHandler()\n\n\tdef _get_statusBar(self) -> NVDAObject:\n\t\t\"\"\"Retrieves Windows 11 Notepad status bar.\n\t\tIn Windows 10 and earlier, status bar can be obtained by looking at the bottom of the screen.\n\t\tWindows 11 Notepad uses Windows 11 UI design (top-level window is labeled \"DesktopWindowXamlSource\",\n\t\ttherefore status bar cannot be obtained by position alone.\n\t\tIf visible, a child of the foreground window hosts the status bar elements.\n\t\tStatus bar child position must be checked whenever Notepad is updated on stable Windows 11 releases\n\t\tas Notepad is updated through Microsoft Store as opposed to tied to specific Windows releases.\n\t\tL{api.getStatusBar} will resort to position lookup if C{NotImplementedError} is raised.\n\t\t\"\"\"\n\t\t# #13688: Notepad 11 uses Windows 11 user interface, therefore status bar is harder to obtain.\n\t\t# This does not affect earlier versions.\n\t\tnotepadVersion = int(self.productVersion.split(\".\")[0])\n\t\tif notepadVersion < 11:\n\t\t\traise NotImplementedError()\n\t\t# And no, status bar is shown when editing documents.\n\t\t# Thankfully, of all the UIA objects encountered, document window has a unique window class name.\n\t\tif api.getFocusObject().windowClassName != \"RichEditD2DPT\":\n\t\t\traise NotImplementedError()\n\t\t# Obtain status bar text across Notepad 11 releases.\n\t\tclientObject = UIAHandler.handler.clientObject\n\t\tcondition = clientObject.createPropertyCondition(UIAHandler.UIA_AutomationIdPropertyId, \"ContentTextBlock\")\n\t\twalker = clientObject.createTreeWalker(condition)\n\t\tnotepadWindow = clientObject.elementFromHandle(api.getForegroundObject().windowHandle)\n\t\ttry:\n\t\t\telement = walker.getFirstChildElement(notepadWindow)\n\t\t\t# Is status bar even showing?\n\t\t\telement = element.buildUpdatedCache(UIAHandler.handler.baseCacheRequest)\n\t\texcept (ValueError, COMError):\n\t\t\traise NotImplementedError\n\t\tstatusBar = UIA(UIAElement=element).parent\n\t\treturn statusBar\n", "path": "source/appModules/notepad.py"}]}