From kfm-devel Mon Jul 12 12:46:46 2004 From: bj () altern ! org Date: Mon, 12 Jul 2004 12:46:46 +0000 To: kfm-devel Subject: [Patch] Fixing the Access Key system Message-Id: <200407121452.54237.bj () altern ! org> X-MARC-Message: https://marc.info/?l=kfm-devel&m=108963640629020 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_GXq8AkoUUe3aCZD" --Boundary-00=_GXq8AkoUUe3aCZD Content-Type: text/plain; charset="us-ascii"; boundary="" Content-Transfer-Encoding: 7bit Content-Disposition: inline Currently, the accesskey support is broken since it conflicts with system wide shortcuts. If you have an accesskey="l" in a web page, you end up with a locked Desktop! I created a patch that changes the behaviour to this: To enable accesskey, you need to press "Ctrl" and then the accesskey. Example: Pressing "Ctrl+a" will behave as a normal konqueror shortcut. Pressing "Ctrl" and then key "a" will activate the "a" accesskey (there is a 5 second timeout for the second key). Additionnaly, (and this can be removed from the patch if necessary), If you press "Ctrl" again, small passive popups will appear in front of each element in the page with an accesskey, showing that accesskey. (I must say i love that feature, and it is a nice way to "emphasize" the role of the accesskey as recommanded by the W3) This new behaviour could be advertised in konqueror's about: page. It would fix #45788 and #83053 What do you think about it ? --Boundary-00=_GXq8AkoUUe3aCZD Content-Type: text/x-diff; charset="us-ascii"; name="accesskey_ctrl.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="accesskey_ctrl.diff" Index: khtmlview.cpp =================================================================== RCS file: /home/kde/kdelibs/khtml/khtmlview.cpp,v retrieving revision 1.640 diff -u -3 -r1.640 khtmlview.cpp --- khtmlview.cpp 30 Jun 2004 16:20:34 -0000 1.640 +++ khtmlview.cpp 12 Jul 2004 12:23:17 -0000 @@ -79,6 +79,7 @@ #include #include #include +#include #include //#define DEBUG_NO_PAINT_BUFFER @@ -99,6 +100,7 @@ using namespace khtml; class KHTMLToolTip; + #ifndef QT_NO_TOOLTIP class KHTMLToolTip : public QToolTip @@ -109,7 +111,7 @@ m_view = view; m_viewprivate = vp; }; - + protected: virtual void maybeTip(const QPoint &); @@ -209,6 +211,8 @@ #ifndef KHTML_NO_TYPE_AHEAD_FIND typeAheadActivated = false; #endif // KHTML_NO_TYPE_AHEAD_FIND + accessKeysActivated = false; + accessKeysPreActivate = false; } void newScrollTimer(QWidget *view, int tid) { @@ -321,6 +325,9 @@ bool findLinksOnly; bool typeAheadActivated; #endif // KHTML_NO_TYPE_AHEAD_FIND + bool accessKeysActivated; + bool accessKeysPreActivate; + QTimer accessKeysTimer; }; #ifndef QT_NO_TOOLTIP @@ -374,6 +381,7 @@ #ifndef KHTML_NO_TYPE_AHEAD_FIND connect(&d->timer, SIGNAL(timeout()), this, SLOT(findTimeout())); #endif // KHTML_NO_TYPE_AHEAD_FIND + connect(&d->accessKeysTimer, SIGNAL(timeout()), this, SLOT(accessKeysTimeout())); init(); @@ -1048,6 +1056,10 @@ } #endif // KHTML_NO_CARET + // If CTRL was hit, be prepared for access keys + if (_ke->key() == Key_Control) + d->accessKeysPreActivate=true; + // accesskey handling needs to be done before dispatching, otherwise e.g. lineedits // may eat the event if( handleAccessKey( _ke )) { @@ -1130,7 +1142,7 @@ return; } #endif // KHTML_NO_TYPE_AHEAD_FIND - + int offs = (clipper()->height() < 30) ? clipper()->height() : 30; if (_ke->state() & Qt::ShiftButton) switch(_ke->key()) @@ -1342,6 +1354,16 @@ _ke->accept(); return; } + + if (_ke->key() == Key_Control && d->accessKeysPreActivate) + { + m_part->setStatusBarText(i18n("Access Keys activated -- press Ctrl again to display all available access keys"),KHTMLPart::BarDefaultText); + d->accessKeysActivated = true; + d->accessKeysPreActivate = false; + d->accessKeysTimer.start(5000, true); + grabKeyboard(); + } + QScrollView::keyReleaseEvent(_ke); } @@ -1435,6 +1457,7 @@ bool KHTMLView::eventFilter(QObject *o, QEvent *e) { if ( e->type() == QEvent::AccelOverride ) { + d->accessKeysPreActivate=false; QKeyEvent* ke = (QKeyEvent*) e; //kdDebug(6200) << "QEvent::AccelOverride" << endl; if (m_part->isEditable() || m_part->isCaretMode() @@ -1796,12 +1819,51 @@ } } +void KHTMLView::displayAccessKeys() +{ +for( NodeImpl* n = m_part->xmlDocImpl(); + n != NULL; + n = n->traverseNextNode()) { + if( n->isElementNode()) { + ElementImpl* en = static_cast< ElementImpl* >( n ); + DOMString s = en->getAttribute( ATTR_ACCESSKEY ); + if( s.length() == 1) + { + QRect rec=static_cast(n)->getRect(); + rec.moveBy(-contentsX(),-contentsY()); + if (rec.left()>0 && rec.top()>0 && (rec.right()mapToGlobal(rec.topLeft()),this->mapToGlobal(rec.bottomRight())); + KPassivePopup *pop=new KPassivePopup(this); + pop->setTimeout(4000); + pop->setView(s.string()); + pop->show(); + pop->move(rec.center ()); + } + } + } + } +} + + +void KHTMLView::accessKeysTimeout() +{ +d->accessKeysActivated=false; +d->accessKeysPreActivate = false; +releaseKeyboard(); +m_part->setStatusBarText(QString::null, KHTMLPart::BarDefaultText); +} + // Handling of the HTML accesskey attribute. bool KHTMLView::handleAccessKey( const QKeyEvent* ev ) { - const int mods = Qt::AltButton | Qt::ControlButton; - if( ( ev->state() & mods ) != mods ) - return false; +if (!d->accessKeysActivated) return false; +if (ev->key() == Key_Control) + { + displayAccessKeys(); + return true; + } + // Qt interprets the keyevent also with the modifiers, and ev->text() matches that, // but this code must act as if the modifiers weren't pressed QChar c; @@ -1817,6 +1879,8 @@ } if( c.isNull()) return false; + d->accessKeysActivated=false; + accessKeysTimeout(); return focusNodeWithAccessKey( c ); } Index: khtmlview.h =================================================================== RCS file: /home/kde/kdelibs/khtml/khtmlview.h,v retrieving revision 1.209 diff -u -3 -r1.209 khtmlview.h --- khtmlview.h 30 Jun 2004 16:20:34 -0000 1.209 +++ khtmlview.h 12 Jul 2004 12:23:17 -0000 @@ -194,7 +194,7 @@ void keyReleaseEvent ( QKeyEvent *_ke ); void contentsContextMenuEvent ( QContextMenuEvent *_ce ); void doAutoScroll(); - + void displayAccessKeys(); void timerEvent ( QTimerEvent * ); protected slots: @@ -206,7 +206,8 @@ #ifndef KHTML_NO_TYPE_AHEAD_FIND void findTimeout(); #endif // KHTML_NO_TYPE_AHEAD_FIND - + void accessKeysTimeout(); + private: void scheduleRelayout(khtml::RenderObject* clippedObj=0); --Boundary-00=_GXq8AkoUUe3aCZD--