[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    [Patch] Fixing the Access Key system
From:       bj () altern ! org
Date:       2004-07-12 12:46:46
Message-ID: 200407121452.54237.bj () altern ! org
[Download RAW message or body]

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 ? 


["accesskey_ctrl.diff" (text/x-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 <qobjectlist.h>
 #include <qtimer.h>
 #include <kdialogbase.h>
+#include <kpassivepopup.h>
 #include <qptrdict.h>
 
 //#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<DOM::ElementImpl*>(n)->getRect();
+	    rec.moveBy(-contentsX(),-contentsY());
+	    if (rec.left()>0 && rec.top()>0 && (rec.right()<contentsX()+visibleWidth()) && \
(rec.bottom()<contentsY()+visibleHeight())) +		{
+		rec=QRect(this->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);



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic