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.
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
some of which can be done but easily forgotten, or others which can't
be done at all.
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.
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.