[nvda-addons] Re: Developing Addons - The best way to get started?

  • From: "Joseph Lee" <joseph.lee22590@xxxxxxxxx>
  • To: <nvda-addons@xxxxxxxxxxxxx>
  • Date: Fri, 8 Apr 2016 07:13:11 -0700

Hi,
May I offer some thoughts...
As James and others have pointed out, learning Python is essential, chiefly 
because NVDA's front end is written using Python (some parts of its back end 
are written in C++). When you write add-ons, you are effectively composing 
Python libraries NVDA will use as it runs. It could be as simple as announcing 
something (ui.message) when you press a key, or quite complex as some of the 
add-ons (SPL add-on (I'm the maintainer) is a very complex add-on, and it took 
me several days to explain its internals in my blog; these days, whenever I 
commit an important commit, I explain what I did in hopes that people would 
appreciate the work required to bring such an add-on to life).
As for object-oriented features: yes, you do need to know what classes, objects 
and modules are. This stems from the fact that GUI elements are objects (as far 
as NVDA sees them). Each control is an object (a class coming to life), such as 
a checkbox, a radio button, an edit field, a window or even the desktop. As 
these elements are objects, they hold various properties (termed attributes) 
such as name, handle (an opaque reference), type of object (MSAA, UIA, MSHTML 
and so on) and so forth. For some folks, writing an app module or a global 
plugin is equivalent to defining these classes and telling NVDA what to do (the 
other part is filtering various controls to make sure one is dealing with the 
right object).
As for documentation: I do know that we lack some important pieces of 
information, one of them being a series of articles detailing NVDA's internals 
(at a higher level). In order to write such docs, one needs to become familiar 
with NVDA source code and willing to investigate how NVDA Core does its job so 
well (you need to devote some months to study NVDA's code, and we're talking 
about ten years' worth of code changes). Let me give you an example of such a 
documentation:
Suppose you are working with an app module. Have you wondered how NVDA can 
locate an app module "magically"? The way it works is as follows (defined in 
appModuleHandler.py):
1. NVDA will keep an eye on events fired by apps (NVDA itself is event-driven).
2. If an event comes from an app that has just started, NVDA will look for its 
process ID (PID for short). This is a must, as the PID will be used as a key to 
a dictionary that records app modules in use and as the argument to be used 
when creating the app module (termed "constructing").
3. Once the PID is found, NVDA will look for the name of the executable 
associated with this PID. This is used to locate the corresponding app module 
and load it.
A more sophisticated scenario is as follows:
Have you wondered how configuration profiles work? Configuration profiles (the 
data structure itself; config.conf) uses an internal stack (a Python list) to 
manage profile switching routines. Whenever you use a profile associated with 
say all, an app-specific profile and so on, NVDA will push the profile for this 
context to the activation stack and will do the opposite (pop) when this 
profile is no longer needed. In reality, each profile is a collection of 
settings NVDA uses during its operation, and each profile records different 
settings (all but three can be profile-specific: general settings, upgrade 
notifications and update control). This is the inspiration behind broadcast 
profiles introduced in StationPlaylist Studio add-on 6.0 (last year, and I'm in 
the midst of designing a possible rewrite of how broadcast profiles are stored 
internally as part of add-on 8 or later, using a module located at Python 
Package Index (PyPI for short)).
As you can see, learning Python is an important aspect of writing add-ons (and 
in extension, when writing changes to NVDA screen reader itself). Also, if you 
are writing complex add-ons, it is vital that you understand how NVDA works (at 
least at a glance) so you can take advantage of this (one of the most 
interesting one being support for audio ducking by various speech synthesizers, 
and some synth developers have started working on this as we speak).
In regards to integrating Python and NVDA concepts together: in my opinion, one 
of the best strategies is writing code and seeing how Python concepts apply in 
NVDA Core and add-on code. Of course you do need to become familiar with 
concepts by writing actual Python code, and you also need to find a way to say, 
"aha, NVDA uses this Python concept in this interesting way". In theory you can 
write an add-on using a boiler plate and without knowing what classes are, but 
I think it is important that people should "sweat a little" when coming up with 
interesting add-ons (ultimately, your add-on could be used by anyone).
Lastly, although not spelled out here, I'd like to take a moment to stress 
something not many may have thought about: I think, often beginners worry too 
much about code to notice that they are going nowhere, or concentrate too much 
on making their code perfect and neglect design decisions. Seasoned add-on 
writers such as Mick, Jamie, Noelia, I and others can tell the quality of an 
add-on and its potential (and power) by examining source code, such as whether 
an add-on would be embraced by many, design problems and so on. The other day 
we had to ask an add-on author to "rephrase" the solution due to 
inconsistencies in code and due to what I would term "big picture assumptions" 
- assumptions that worked well for this author but not for others (for this 
reason, one of the things I do when designing new features is ask "what if" 
questions a lot as part of requirements analysis and design). In short, as a 
community add-ons reviewer, what I look for the most is not the complexity of 
the code or tricks the add-on employs, but the overall design (and more 
recently, user interface such as GUI's, messages to be presented to the user 
and so on).
I do understand that, at times, we don't know how to translate what's going on 
in our heads to actual artifact (code). When this happens, don't rush, don't 
strive for perfection, and ready to say you need help. Also, you do need to 
take some breaks so that what you've learned can sink in. Lastly, you should be 
willing to explain what's going on in your add-on and be ready to defend your 
position - after all, add-on construction is like writing an essay (I think not 
many computer science students and programmers realize this).
Regarding my last point: this can be extended to NVDA Core itself: when you do 
write a feature to be included into NVDA Core, you are effectively writing an 
essay or a part of a story NVDA seeks to impart: equal access to technology. 
Because NVDA has become part of lives of over a hundred thousand people, it is 
vital to remember that design matters (for this reason, Mick, Jamie, I, Derek 
and many others will not code until we explain our "essay" outline, and this is 
one of the reasons why NVDA developers have instituted code reviews for NVDA 
Core and add-on code; the current status of code reviews deserves a thread of 
its own, part of it being that we need more code reviewers for NVDA Core).
Hope this helps.
Cheers,
Joseph


-----Original Message-----
From: nvda-addons-bounce@xxxxxxxxxxxxx 
[mailto:nvda-addons-bounce@xxxxxxxxxxxxx] On Behalf Of Damien Sykes-Pendleton
Sent: Friday, April 8, 2016 4:56 AM
To: nvda-addons@xxxxxxxxxxxxx
Subject: [nvda-addons] Re: Developing Addons - The best way to get started?

Hi James,
Again. This proves just how much, or little, knowledge I have on this subject. 
I always assumed that the information that NVDA uses to evaluate the 
functionality or purpose of a control was through the Windows API. When I wrote 
my first addon that didn't involve copying and pasting from an example, it was 
to read content that NVDA didn't recognise on its own for whatever reason, that 
other screen readers did. This didn't work. My theory for this is that I was 
pretty much guessing what I had to do to get it to work, and of course that is 
not the way to understand your own code. It helps to understand what your code 
needs to do, something of which I understood very little, if not nothing at 
all. If you can't understand that, you need to be able to understand what you 
want to do. Although I know what I want to do in terms of functionality, 
translating that into code is very difficult, given that I don't know about all 
the underlying structures such as in-depth control information (ID, handle, 
class etc), NVDA objects, accessibility platforms, the list goes on and on.
As for learning Python itself, this is not so much the problem as remembering 
every single thing I'm reading. When I look at a Python tutorial, I'm thinking, 
yes this makes sense. Sounds good to me. Oh wow, I've finished the tutorial. 
Let's go back to addons. Oh wait, what did the tutorial say about this? I don't 
remember that part...Look back at the tutorial. Oh, it's not in here. This must 
be an NVDA specific reference. 
Either that, or, Ah yes, I remember this now. Now how was the addon guide 
referencing this?
I'm trying to explain it the best way I can, because there isn't one specific 
example or situation that I can pinpoint without referencing something else, 
it's all linked, hence the massive confusion which, if we're talking code, is 
making my brain go into an infinite loop.
Kind regards,
Damien.
-----Original Message-----
From: James Scholes
Sent: Friday, April 08, 2016 12:25 PM
To: nvda-addons@xxxxxxxxxxxxx
Subject: [nvda-addons] Re: Developing Addons - The best way to get started?

Replies inline.

Damien Sykes-Pendleton wrote:

Well if we're constraining ourselves to the facts, I can only really  
say what I have said before, in that the developer guide assumes a 
good working knowledge of Python and NVDA's internal workings, neither 
of which I feel I have enough of to really get going.

First, tackle Python.  You need a good, working knowledge of the language to 
write NVDA add-ons.  This will never change, no matter how much documentation 
is written.  Create some small Python projects which make use of 
object-oriented programming, inheritance, wxPython.

It is incredibly important to understand that creating NVDA add-ons is not at 
all like writing JAWS scripts.  With JAWS scripting, the language is 
proprietary and the creators of that language decide in advance what 
functionality you have access to.  NVDA not only gives you the full power of 
the Python language, but also lets you write code which runs in the same 
environment as NVDA's core, meaning that you can literally do whatever you 
like, only constrained by your imagination and knowledge.
Naturally, this provides a lot of room for error, so NVDA add-on writing often 
comes with a  lot of responsibility.  That is why there is a higher barrier to 
entry.  It's up to you to decide whether that barrier is worth scaling or not.  
But nobody, on this list or otherwise, will ever be able to create 
documentation that explains every possible aspect of creating NVDA add-ons.  
Having said that, the community has created some extra documentation, which I 
will leave it up to them to share.

I have looked into Python, both on the official language tutorial and 
from Learn Python the Hard Way. Although these are both good 
resources, they are also very extensive to the point that by the time 
I have read them and gone back to the developer guide, I'm trying to 
conceptualise everything else into Python terms rather than NVDA terms

I'm not entirely sure what you mean here.  NVDA is Python.  Granted, to write a 
good add-on, you have to be aware of some of NVDA's internals, but really, you 
need to give us examples of what you're trying to do and why it's posing a 
problem.  If you have a good understanding of Python as I said above, writing 
NVDA add-on boilerplate will be easy.

some of which can be done but easily forgotten, or others which can't 
be done at all.

Again, I have no idea what you mean.  What Python features, functionality or 
concepts are you having difficulty translating into valid concepts to be used 
in an NVDA add-on?

Then, as I have also said before, there is the vagueness of 
references, such as "Refer to the NVDA code documentation". I cannot 
find this documentation anywhere, even in the NVDA source code.

If you check out the NVDA source code and read the accompanying readme files, 
you will see instructions on generating the NVDA code documentation.  You can 
also browse an online copy, although I don't think it's updated on a regular 
basis, at:
https://files.derekriemer.com/nvda/module-tree.html

Honestly though, I think most NVDA developers will tell you that reading the 
code itself is usually better than the documentation.  If you're hoping that 
the code documentation will shine a light on everything that has hitherto 
seemed confusing, you'll be seriously disappointed.  The code documentation is 
constructed from Python docstrings.  It's a terse reference, not a guide.

Even so, I doubt I'd be able to glean much from it, since NVDA has a 
lot of in-depth interaction with the operating system which, when it 
comes to development, I know hardly anything about the workings of. 
This then also adds the Windows API to my reference list, and now I 
feel like I am on a road of information overload.

Any portions of the Windows API that are used by NVDA have already been wrapped 
as simple Python functions for use in higher level abstractions.
Unless you need to use a part of it that hasn't already been defined as such, 
you don't need to understand the ins and outs of that.
Additionally, it's highly unlikely that, for your first add-ons, you'll even 
need to use such functionality.  Rather, you'll interact with the abstractions 
that NVDA provides.

To sum up:
1. Learn Python.  If you don't know the language, if you can't write scripts or 
small programs in it, you will have a hard time writing code for NVDA.
2. Get familiar with reading other people's Python code.  You'll be doing a lot 
of that if you want to create high quality add-ons.
3. Give us examples of things you're finding hard.  We don't need an article, 
we just need you to explain what you don't understand so we can point you in 
the right direction.
4. Don't run before you can walk.  If you're struggling with how to create the 
most basic of add-ons, the Windows API isn't even a distant concern.
--
James Scholes
http://twitter.com/JamesScholes
----------------------------------------------------------------
NVDA add-ons: A list to discuss add-on code enhancements and for reporting bugs.

Community addons are available from: http://addons.nvda-project.org To send a ;
message to the list: nvda-addons@xxxxxxxxxxxxx To change your list 
settings/unsubscribe: 
//www.freelists.org/list/nvda-addons
To contact list moderators: nvda-addons-moderators@xxxxxxxxxxxxx 

----------------------------------------------------------------
NVDA add-ons: A list to discuss add-on code enhancements and for reporting 
bugs. 

Community addons are available from: http://addons.nvda-project.org To send a ;
message to the list: nvda-addons@xxxxxxxxxxxxx To change your list 
settings/unsubscribe: //www.freelists.org/list/nvda-addons
To contact list moderators: nvda-addons-moderators@xxxxxxxxxxxxx

----------------------------------------------------------------
NVDA add-ons: A list to discuss add-on code enhancements and for reporting bugs.

Community addons are available from: http://addons.nvda-project.org
To send a message to the list: nvda-addons@xxxxxxxxxxxxx
To change your list settings/unsubscribe: 
//www.freelists.org/list/nvda-addons
To contact list moderators: nvda-addons-moderators@xxxxxxxxxxxxx

Other related posts: