From kde-accessibility Tue Jul 08 09:20:15 2003 From: Gunnar Schmi Dt Date: Tue, 08 Jul 2003 09:20:15 +0000 To: kde-accessibility Subject: Re: [Kde-accessibility] On Qt accessibility and a on-screen X-MARC-Message: https://marc.info/?l=kde-accessibility&m=105765610432068 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_PzoC/LwhJGoN8fX" --Boundary-00=_PzoC/LwhJGoN8fX Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Description: clearsigned data Content-Disposition: inline -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, On Tuesday 08 July 2003 06:25, Maks Orlovich wrote: > On Friday 04 July 2003 05:35 pm, you wrote: > > Hi Maks! > > > > Thank you very much for your work on Klaviatura. > > My pleasure. > > > I didn't have time to > > look at your code, but getting QAccessible working is very high on our > > agenda right now. I am really impressed that menus and toolbars are > > working. > > Well, I took the time to do a quick look at the code. You seem to use explicit knowledge about the widgets. Is that right? In that case it is more a demonstration what will be cleanly possible if QAccessible gets extended and not a demonstration of what QAccessible can do (or not do). > > Gunnar will give a speech on accessibility at the KDE developers meeting. > > I think that showing your program at the conference would be a very good > > way to illustrate what getting QAccessible to work is about. > > Well, may be I should make it more complete by then :-). That would be good. Your current version (the one you sent, not the one in CVS if there are differences) has only support for menu bars and tool bars. What I would like to see is the support for the other GUI elements as far as it is possible without explicit knowledge of the widget types (e.g., in that case a real demonstration what QAccessibleInterface can do and where it lacks)? > Anyway, I've put it into kdenonbeta, which makes updating things easier, > and fixed some bugs.. Still, there are quite a few major gaps and issues.. > The #1 is that it occasionally locks up, but that's not very reproducible, > making it hard to deal with Other than that, the big thing is the lack of > support of toolbuttons with drop downs; I think this probably needs a new > QAccessible plugin to handle KToolBarButtons, which do drop downs quite > differently from their Qt counterpart. Other things are just more a matter > of a lack of completeness. (i.e. it doesn't draw separators other than > empty buttons now, only handles one keyboard layout, although backend just > loads it from a file, etc.). > During the (few) tests that I did, I had no lock ups. Also I did not find any missing features in KToolBarButtons. Maybe the popup handling is not that different between the two? (Or is it because I used KDE 3.1 branch instead of head?) One feature that I miss is the possibility to close an open pop up. Is it possible to add that feature? > > So please have a look at http://accessibility.kde.org/developer/ > > > > If you have any ideas or suggestions or improvements concerning these > > documents, please let us know. > > One major concern of mine is an apparent (correct me if I am wrong) lack of > plans for a native API. I think past experiences with projects like aRts > show that systems that have their own way of doing things, which is not > consistent with the rest of KDE tend to stagnate severely, as few people > are willing to deal with them. Permanent requirements on ATK or AT-SPI also > seem > undesirable, although quite less severe than the API issue. > Well, we have a native (Qt-)API: QAccessible and its derived classes. From an application programmers view you do not need any other API. The only case where a native API could be helpfull is when writing an assistive technology for KDE. However, as that assistive technology probably wants to help GNOME applications as well, it needs to speak AT-SPI in either case (unless we build a library that is based on AT-SPI and can be used by assistive technologies under KDE). Please keep in mind that AT-SPI is very likely to become a standard on Unix systems. > > Your idea to use DCOP as a way to provide information to an external > > application is interesting. We had also discussed this possibility, but > > I must also add that DCOP offers a very easy to use programming > environment, requiring close to 0 code to support. > > > then thought that full interoperability with GNOME would be of larger > > benefit for us, since there are already very good assistive technologies > > for which it would be great to have them compatible with KDE. > > Are there any more other than GOK and Gnopernicus? BTW, I have not been > able to get anything but the vanilla input mode in GOK to work; which is > not very impressive since just sending keystrokes doesn't require an > accessibility infrastructure. > Even if there currently are not many assistive technologies that make use of AT-SPI it makes sense to only have one standard for accessibility information. If there are two standards the developers of assistive technologies need either to implement both or they need to choose which one they support. If one is only for KDE and the other one is for the rest of the world (currently GNOME applications, Java applications, mozilla and OpenOffice.org support AT-SPI) it is not difficult to guess which one they choose, right? > > We will look at your code soon, if my impression is right, your hacks > > would fit very fell to our plans to bridge to AT-SPI, as we hadn't > > dreamed of having QAccessible already usable. > > Some of them may be of use, but in general the code that takes a somewhat > restricted view of UIs (and it often bypasses QAccessible, when it's easier > to work with the widgets). What does worry me is that the technique used to > bypass mouse grabs (crucial when dealing with popups) does not seem like > it'd generalize easily [currently, the plugin intercepts mouse clicks to > popup menus (it inserts an event filter on accessibility events), and > checks whether it falls on top of a window with an appropriate WM_CLASS, if > so, it tells it over DCOP to simulate a mouse event, and squashes it > locally). > Sorry, but I don't get what you mean. If the user clicks on a popup entry, you do not have to do anything. And when the user clicks on a button in Klaviatura you only need to call the appropriate QAccessibleInterface::doAction() method. Or do I miss something? Gunnar Schmi Dt P.S.: Your patch for Qt does not work correctly. When compiling the example programs of Qt it produces linking errors (I suppose that it did not include qaccessible_x11.o in the Qt library). I have produced a cleaner patch for Qt. This patch adds the options -accessibility and -no-accessibility to the configure script (default is -accessibility). However, that option is not passed to KDE, so I need to add CXXFLAGS=-DQT_ACCESSIBILITY_SUPPORT and CFLAGS=-DQT_ACCESSIBILITY_SUPPORT to the calls of the configure scripts of the KDE parts that depend on QAccessible and its derived classes. Currently this is only the Klaviatura plug in, but it might become more if we regularly call QAccessible::updateAccessibility. However, in that case it is better to add a patch to the KDE Makefile system. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE/CozWsxZ93p+gHn4RAh9bAJsGyXwXNgFDgLalnVvU6tqCX119gQCg0ZG+ tD4AGYLlVu/dfltf1Hyz04Y= =ERrR -----END PGP SIGNATURE----- --Boundary-00=_PzoC/LwhJGoN8fX Content-Type: text/x-diff; charset="iso-8859-1"; name="qt_xaccess_concept.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qt_xaccess_concept.diff" Index: configure =================================================================== RCS file: /home/kde/qt-copy/configure,v retrieving revision 1.51 diff -u -p -r1.51 configure --- configure 16 May 2003 12:55:37 -0000 1.51 +++ configure 8 Jul 2003 08:02:26 -0000 @@ -268,6 +268,7 @@ CFG_CUPS=auto CFG_LARGEFILE=auto CFG_NEWABI=no ### need to break ABI for full Large File support... CFG_STL=auto +CFG_ACCESSIBILITY=yes CFG_NAS=no CFG_QWS_DEPTHS=prompted CFG_USER_BUILD_KEY= @@ -332,7 +333,7 @@ while [ "$#" -gt 0 ]; do VAL=no ;; #Qt style yes options - -incremental|-qvfb|-profile|-shared|-static|-sm|-thread|-xinerama|-tablet|-stl|-freetype|-big-codecs|-xcursor|-xrandr|-xrender|-xft|-xkb|-nis|-cups|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-version-script) + -incremental|-qvfb|-profile|-shared|-static|-sm|-thread|-xinerama|-tablet|-stl|-accessibility|-freetype|-big-codecs|-xcursor|-xrandr|-xrender|-xft|-xkb|-nis|-cups|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-version-script) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` VAL=yes ;; @@ -649,6 +650,13 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + accessibility) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_ACCESSIBILITY="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; freetype) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_QWS_FREETYPE="$VAL" @@ -1873,6 +1881,9 @@ Configure options: $SHN -no-stl ............ Do not compile STL support. $SHY -stl ............... Compile STL support. + -no-accessibility ..... Do not compile accessibility support. + -accessibility ........ Compile accessibility support. + -verbose .............. Print verbose information about each step of the -v .................... configure process. @@ -2509,6 +2520,9 @@ if [ "$CFG_STL" = "no" ]; then else QMAKE_CONFIG="$QMAKE_CONFIG stl" fi +if [ "$CFG_ACCESSIBILITY" = "yes" ]; then + QMAKE_CONFIG="$QMAKE_CONFIG accessibility" +fi # don't add the link line if we build the image formats as a plugin if [ "$CFG_LIBMNG" = "system" ]; then QMAKE_CONFIG="$QMAKE_CONFIG system-mng" @@ -2723,6 +2737,7 @@ esac # # Options: # stl +# accessibility # # Things that do not affect the Qt API/ABI: # system-jpeg no-jpeg jpeg @@ -3005,6 +3020,7 @@ fi [ "$CFG_INCREMENTAL" = "yes" ] && [ '!' -z "$INCREMENTAL" ] && echo "Incremental ......... $INCREMENTAL" echo "Configuration ....... $QMAKE_CONFIG" echo "STL support ......... $CFG_STL" +echo "Accessibility support $CFG_ACCESSIBILITY" echo "Thread support ...... $CFG_THREAD" echo "NIS support ......... $CFG_NIS" echo "CUPS support ........ $CFG_CUPS" diff -N src/kernel/qaccessible_x11.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/kernel/qaccessible_x11.cpp 3 Jul 2003 03:46:40 -0000 @@ -0,0 +1,92 @@ +#include "qaccessible.h" +#include "qxaccessprovider.h" +#include +#include + + +#ifndef QT_NO_COMPONENT + +#include "qxaccessprovider_p.h" // up here for GCC 2.7.* compatibility +#include + + +class QXAccessProviderFactoryPrivate : public QObject +{ +public: + QXAccessProviderFactoryPrivate(); + ~QXAccessProviderFactoryPrivate(); + + static QPluginManager *manager; +}; + +static QXAccessProviderFactoryPrivate *instance = 0; +QPluginManager *QXAccessProviderFactoryPrivate::manager = 0; + +QXAccessProviderFactoryPrivate::QXAccessProviderFactoryPrivate() +: QObject( qApp ) +{ + manager = new QPluginManager( IID_QXAccessProviderFactory, QApplication::libraryPaths(), "/xaccess", FALSE ); +} + +QXAccessProviderFactoryPrivate::~QXAccessProviderFactoryPrivate() +{ + delete manager; + manager = 0; + + instance = 0; +} + +#endif //QT_NO_COMPONENT + + +static QXAccessProvider *qt_x11_create_xaccess_provider( const QString& key ) +{ + QXAccessProvider* ret = 0; + QString xk = key.lower(); + if ( !instance ) + instance = new QXAccessProviderFactoryPrivate; + + QInterfacePtr iface; + QXAccessProviderFactoryPrivate::manager->queryInterface( xk, &iface ); + + if ( iface ) + ret = iface->create( xk ); + if(ret) + ret->setName(key); + return ret; +} + + + +static int qt_x11_accessible_inited = 0; +static QValueList qt_x11_accessible_providers; + +#include + +static void qt_x11_accessible_init() +{ + QSettings s; //### Should use global QSettings + QStringList keys = s.readListEntry("/qt/accessProviders"); + QStringList::Iterator it = keys.begin(); + while( it != keys.end() ) { + QXAccessProvider* p = qt_x11_create_xaccess_provider(*it); + qDebug("Trying to crate:%s got:%x", (*it).latin1(), p); + if (p) + qt_x11_accessible_providers.append(p); + ++it; + } + qt_x11_accessible_inited = 1; +} + +void QAccessible::updateAccessibility( QObject* obj, int who, Event reason ) +{ + if (!qt_x11_accessible_inited) + qt_x11_accessible_init(); + + for (QValueList::iterator iter = qt_x11_accessible_providers.begin(); + iter != qt_x11_accessible_providers.end(); ++iter) + { + (*iter)->updateAccessibility(obj, who, reason); + } +} + Index: src/kernel/qt_kernel.pri =================================================================== RCS file: /home/kde/qt-copy/src/kernel/qt_kernel.pri,v retrieving revision 1.10 diff -u -p -r1.10 qt_kernel.pri --- src/kernel/qt_kernel.pri 16 May 2003 13:02:53 -0000 1.10 +++ src/kernel/qt_kernel.pri 8 Jul 2003 08:02:28 -0000 @@ -267,5 +267,7 @@ kernel { SOURCES += $$KERNEL_CPP/qaccessible.cpp win32:SOURCES += $$KERNEL_CPP/qaccessible_win.cpp + unix:x11:SOURCES += $$KERNEL_CPP/qaccessible_x11.cpp $$KERNEL_CPP/qxaccessproviderplugin.cpp + unix:x11:SOURCES += $$KERNEL_H/qxaccessprovider.h $$KERNEL_H/qxaccessproviderplugin.h } } Index: src/kernel/qxaccessprovider.h =================================================================== RCS file: src/kernel/qxaccessprovider.h diff -N src/kernel/qxaccessprovider.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/kernel/qxaccessprovider.h 3 Jul 2003 03:46:42 -0000 @@ -0,0 +1,15 @@ +#ifndef Q_XACCESS_PROVIDER_H +#define Q_XACCESS_PROVIDER_H + +#include +#include + + +class QXAccessProvider:public QObject +{ +public: + virtual void updateAccessibility( QObject *, int who, QAccessible::Event reason ) = 0; +}; + + +#endif Index: src/kernel/qxaccessprovider_p.h =================================================================== RCS file: src/kernel/qxaccessprovider_p.h diff -N src/kernel/qxaccessprovider_p.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/kernel/qxaccessprovider_p.h 3 Jul 2003 03:46:42 -0000 @@ -0,0 +1,23 @@ +#ifndef QXACCESS_PROVIDER_INTERFACE_P_H +#define QXACCESS_PROVIDER_INTERFACE_P_H + +#ifndef QT_H +#include +#endif // QT_H + +#ifndef QT_NO_COMPONENT + +class QXAccessProvider; +// {411a409d-679b-4577-b048-cf4edbaad448} +#ifndef IID_QXAccessProviderFactory +#define IID_QXAccessProviderFactory QUuid(0x411a409d, 0x679b, 0x4577, 0xb0, 0x48, 0xcf, 0x4e, 0xbd, 0xaa, 0xd4, 0xd8) +#endif + +struct Q_EXPORT QXAccessProviderFactoryInterface : public QFeatureListInterface +{ + virtual QXAccessProvider* create( const QString& id ) = 0; +}; + +#endif //QT_NO_COMPONENT + +#endif //QXACCESS_PROVIDER_INTERFACE_P_H Index: src/kernel/qxaccessproviderplugin.cpp =================================================================== RCS file: src/kernel/qxaccessproviderplugin.cpp diff -N src/kernel/qxaccessproviderplugin.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/kernel/qxaccessproviderplugin.cpp 3 Jul 2003 03:46:42 -0000 @@ -0,0 +1,109 @@ +#include "qxaccessproviderplugin.h" + +#ifndef QT_NO_COMPONENT + +#include "qxaccessprovider_p.h" +#include "qobjectcleanuphandler.h" +#include "qxaccessprovider.h" + +//M.O:Var names + +class QXAccessProviderPluginPrivate : public QXAccessProviderFactoryInterface, public QLibraryInterface +{ +public: + QXAccessProviderPluginPrivate( QXAccessProviderPlugin *p ) + : plugin( p ) + { + } + + virtual ~QXAccessProviderPluginPrivate(); + + QRESULT queryInterface( const QUuid &iid, QUnknownInterface **iface ); + Q_REFCOUNT; + + QStringList featureList() const; + QXAccessProvider *create( const QString &key ); + + bool init(); + void cleanup(); + bool canUnload() const; + +private: + QXAccessProviderPlugin *plugin; + QObjectCleanupHandler styles; +}; + +QRESULT QXAccessProviderPluginPrivate::queryInterface( const QUuid &iid, QUnknownInterface **iface ) +{ + *iface = 0; + + if ( iid == IID_QUnknown ) + *iface = (QXAccessProviderFactoryInterface*)this; + else if ( iid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( iid == IID_QXAccessProviderFactory ) + *iface = (QXAccessProviderFactoryInterface*)this; + else if ( iid == IID_QLibrary ) + *iface = (QLibraryInterface*) this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QXAccessProviderPluginPrivate::~QXAccessProviderPluginPrivate() +{ + delete plugin; +} + +QStringList QXAccessProviderPluginPrivate::featureList() const +{ + return plugin->keys(); +} + +QXAccessProvider *QXAccessProviderPluginPrivate::create( const QString &key ) +{ + QXAccessProvider *st = plugin->create( key ); + styles.add( st ); + return st; +} + +bool QXAccessProviderPluginPrivate::init() +{ + return TRUE; +} + +void QXAccessProviderPluginPrivate::cleanup() +{ + styles.clear(); +} + +bool QXAccessProviderPluginPrivate::canUnload() const +{ + return styles.isEmpty(); +} + + +/*! + Constructs a style plugin. This is invoked automatically by the + \c Q_EXPORT_PLUGIN macro. +*/ +QXAccessProviderPlugin::QXAccessProviderPlugin() + : QGPlugin( (QXAccessProviderFactoryInterface*)(d = new QXAccessProviderPluginPrivate( this )) ) +{ +} + +/*! + Destroys the style plugin. + + You never have to call this explicitly. Qt destroys a plugin + automatically when it is no longer used. +*/ +QXAccessProviderPlugin::~QXAccessProviderPlugin() +{ + // don't delete d, as this is deleted by d +} + +#endif // QT_NO_COMPONENT + Index: src/kernel/qxaccessproviderplugin.h =================================================================== RCS file: src/kernel/qxaccessproviderplugin.h diff -N src/kernel/qxaccessproviderplugin.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/kernel/qxaccessproviderplugin.h 3 Jul 2003 03:46:42 -0000 @@ -0,0 +1,31 @@ +#ifndef Q_XACCESS_PROVIDER_PLUGIN_H +#define Q_XACCESS_PROVIDER_PLUGIN_H + +#ifndef QT_H +#include "qgplugin.h" +#endif // QT_H + +#ifndef QT_NO_COMPONENT + +class QXAccessProvider; +class QXAccessProviderPluginPrivate; + +class Q_EXPORT QXAccessProviderPlugin : public QGPlugin +{ + Q_OBJECT +public: + QXAccessProviderPlugin(); + ~QXAccessProviderPlugin(); + + virtual QStringList keys() const = 0; + virtual QXAccessProvider *create( const QString &key ) = 0; + +private: + QXAccessProviderPluginPrivate *d; +}; + +#endif // QT_NO_COMPONENT + + +#endif // Q_XACCESS_PROVIDER_H + --Boundary-00=_PzoC/LwhJGoN8fX Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kde-accessibility mailing list kde-accessibility@mail.kde.org http://mail.kde.org/mailman/listinfo/kde-accessibility --Boundary-00=_PzoC/LwhJGoN8fX--