Hi Joseph,
This is very helpful indeed, and already explains some of my confusions. I
was thinking of an NVDA object as part of the physical interface design - a
physical control on the screen was being converted to something else by NVDA
so it could read it. I never linked it with object-oriented programming,
because I have also heard of controls themselves, referred to as objects.
Having worked with other languages I am familiar with object-oriented
programming (though I seem to remember Python somehow differentiated between
classes and objects). Python also has other concepts not shared by some
other languages such as list and dictionaries as opposed to arrays, packaged
statements, packaged scripts and modules, its import statement I believe
works slightly different to, for instance, an include preprocessor
statement, and the way it works with classes seems different as well (take
for instance the class of AppModule(appModuleHandler.AppModule) which I
believe refers to a class inheritance, looks like it is inheriting from a
class property instead of another class).
For the most part learning a new language has been easy for me, since its
only difference is usually with syntactical differences, but Python seems to
change more concepts than just syntax, hence the reason I find it more
confusing.
I think that perhaps the other problem I am facing is that, because I
generally wouldn't consider writing in Python in an everyday setting and
thus would only use it for NVDA addons, and NVDA can automatically create
the relevant files based on the source code, I haven't installed Python and
therefore only have NVDA as a testing mechanism. I may be wrong, but I have
thought before now that installing a whole component when you would possibly
only use a minor percentage of it is rather pointless, especially if you
then have to learn to run it as a full system. In this case Python, which
relies on command line usage to run scripts, separate compilers to compile
them to binary, and other dependencies for extra functionality etc. When it
comes to NVDA, you also have these various unrelated subdependencies like
Git, documentation and packaging systems which then start to go way above my
head.
Kind regards,
Damien.
-----Original Message-----
From: Joseph Lee
Sent: Friday, April 08, 2016 3:13 PM
To: nvda-addons@xxxxxxxxxxxxx
Subject: [nvda-addons] Re: Developing Addons - The best way to get started?
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.