NVDA 2022.1 advisory: changes to handling command-line switches from add-ons


 

Hi all,

If you are maintaining add-ons with extra command-line switches, the following advisory is for you:

It is indeed possible to let add-ons take command-line switches in addition to ones included in NVDA itself. For example, a user can specify the operation of an add-on feature by opening Run dialog, type “nvda” followed by command-line switches for add-ons. For example, for StationPlaylist users, to load add-on settings from memory, type:

nvda --spl-configinmemory

 

In NVDA 2021.3 and earlier, extra command-line switches are housed in globalVars.appArgsExtra. NVDA 2022.1 changes this in several ways:

  • A new way to inform NVDA that your add-on can handle extra command-line switches.
  • Changes to add-on package structure for app module add-ons wishing to handle extra command-line switches.
  • globalVars.appArgsExtra is renamed to globalVars.unknownAppArgs.

 

If you are maintaining add-ons that uses extra command-line switches, you must:

  1. If you are maintaining app modules only, your add-on must now include a global plugin for handling command-line switches.
  2. From the global plugin, define a cumulative decider (a new extension point type) that will inform NVDA that the add-on needs certain command-line switches.
  3. From global plugin class constructor, tell NVDA that you wish to register the just defined function as a cumulative decider.

 

Complete code example: suppose you have a global plugin that can use command-line switches to toggle certain add-on features (or have an app module for this purpose). Then:

 

From global plugin (existing or new):

 

def commandLineHandler(cliArgument: str) -> bool:

if cliArgument == “somestring”:

    # Do extra processing

    return True

return False

 

You can also test for membership such as:

 

def commandLineHandler(cliArgument: str) -> bool:

if cliArgument in listOfSwitches:

    # Do extra processing

    return True

return False

 

Give the function whatever name you would like (I called mine “processArgs” after the new 2022.1 alpha dev guide example). Then from global plugin class constructor:

 

Class GlobalPlugin(globalPluginHandler.GLobalPlugin):

 

  def __init__(self):

    super(GlobalPlugin, self).__init__()

    if hasattr(addonHandler, "isCLIParamKnown"):

      addonHandler.isCLIParamKnown.register(commandLineHandler)

 

To support older releases, from the location where you need to handle command-line switches, try:

extraAppArgs = globalVars.appArgsExtra if hasattr(globalVars, “appArgsExtra”) else globalVars.unknownAppArgs

 

Flip this condition if you wish to check for 2022.1 attribute first. Of course if you are planning to set minimum API to NVDA 2022.1 and later, then you can just use globalVars.unknownAppArgs directly unless the API changes in the future. Also, if your add-on is an app module add-on and would like to accept additional command-line switches, then you must define a global plugin whose only purpose is informing NVDA about extra arguments.

 

The following add-ons are affected:

  • StationPlaylist (the next version of the add-on, which happens to be the last version under my maintenance (22.01) will support old and new ways of handling command-line switches)
  • Any add-on that defines and handles extra command-line switches

 

Thanks.

Cheers,

Joseph

Join nvda-addons@nvda-addons.groups.io to automatically receive all group messages.