Bug 96621 - Konqueror crash when closing tabs caused by KAccel
Summary: Konqueror crash when closing tabs caused by KAccel
Status: RESOLVED WORKSFORME
Alias: None
Product: kdelibs
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: unspecified
Platform: Debian testing Linux
: NOR crash
Target Milestone: ---
Assignee: Stephan Kulow
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-01-09 08:15 UTC by Nikita V. Youshchenko
Modified: 2008-03-02 11:35 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nikita V. Youshchenko 2005-01-09 08:15:24 UTC
Version:            (using KDE KDE 3.3.1)
Installed from:    Debian testing/unstable Packages
OS:                Linux

Hello,
we've run into konqueror crash, and after some investigation the problem boils down to a question about accelerator handling in KDE and QT.

When typing Ctrl-W in konqueror, it should close the current tab. However, in some cases, when I type that when keyboard is in russian layout, konqueror crashes.

Tracing the event handling in debugger shows some differences between handling of event in english and russian layouts.

When I type Ctrl-W in english layout, the QApplication::x11ProcessEvent arrives at this code block:

 if ( qt_x11EventFilter(event) )  // send through app filter
 return 1;

The qt_x11EventFilter indirectly calls KAccelEventHandler::x11Event, KAccel for Ctrl-W is invoked and tab is closed. The call to qt_x11EventFilter returns 1 and x11ProcessEvent immediately exits.

When I type Ctrl-W in russian layout, the call to KAccelEventHandle::x11Event does not find the accelerator, and the above "return" is not executed.

Later, QApplication::x11ProcessEvent calls QETWidget::translateKeyEvent, which has this code:

  if ( qt_tryAccelEvent( this, &a ) )
      return TRUE;
  }

This code finds the KAccel for Ctrl-W, and closes the tab. But, qt_tryAcelEvent returns false. The reason is unclear -- here's the relevant 
code:

  bool QAccelManager::tryAccelEvent( QWidget* w, QKeyEvent* e )
  {
    if ( Qt::NoMatch == currentState ) {
           ........
       QApplication::sendSpontaneousEvent( w, e );
       if ( e->isAccepted() )
          return FALSE;
    }

This "return FALSE" is actually executed. I'd expect that if event is accepted, it means accelerator is found, so TRUE should be returned. But if I change this to "return TRUE" this code is activated for every keypress, not only accelerators, and keyboard does not work at all.


So, tryAccelEvent and qt_tryAcelEvent return false, and QETWidget::translateKeyEvent goes on, 
and eventually ends with segfault in KApplication::notify:

    if ((t == QEvent::AccelOverride) || (t == QEvent::KeyPress))
    {
       static const KShortcut& _selectAll = KStdAccel::selectAll();
       QLineEdit *edit = ::qt_cast<QLineEdit *>(receiver);

The crash happens on the last line, supposedly because 'receiever' was part of just destroyed tab.

The reason why Qt finds the accelerator while KDE does not is that Qt, when searching the accelerator for KeyPress event with keycode==25, explicitly 
tries both Ctrl-W and Ctrl-CyrillicTse keys. As far as I can tell, KDE tries only Ctrl-CyrillicTse. Here's the relevant code:

  bool KAccelEventHandler::x11Event( XEvent* pEvent )
  {
     ....
     if( pEvent->type == XKeyPress ) {
       KKeyNative keyNative( pEvent );

Constructor of KKeyNative does XLookupString, which gives different result in english and cyrillic keyboard mode (XK_W for english keyboard, XK_Cyrillic_Tse for russian keyboard). If the code is modified to be:

  bool KAccelEventHandler::x11Event( XEvent* pEvent )
  {
     ....
     if( pEvent->type == XKeyPress ) {
        unsigned int tmp = pEvent->xkey.state;
        pEvent->xkey.state &= ~0x2000;
        KKeyNative keyNative( pEvent );
        pEvent->xkey.state = tmp;

Konqueror no longer crashes. However, this does not look like an acceptable solution.


Here are exact steps to reproduce the crash:

0. Ensure that Xserver is configured to support english/russian keyboard.
We use followinf lines in /etc/X11/XF86Config-4:
...
Option "XkbLayout"  "us,ru"
Option "XkbOptions" "grp:menu_toggle,grp_led:scroll"
...

1. Start konqueror
2. Open http://ya.ru/
3. Create a new tab (e.g. from menu)
4. Open http://ya.ru/ in the second tab
5. Switch keyboard to russian more (in the above config - by pressing "Menu" key)
6. Press Ctrl+W

And it crashes.
The http://ya.ru/ is not the only site that causes the crash; many do. We used this one while debugging because with it, crash was 100% 
reproducable.

We first reported this bug (and suggested workaround) to Debain. it is at http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=287566
Comment 1 Nikita V. Youshchenko 2005-01-09 08:16:58 UTC
Also, we tried to write to kde-devel, see http://lists.kde.org/?l=kde-devel&m=110425131804283
There was no reply for 2 weeks :(.

I am using packagews with suggested workaround on several computers for 2 weeks. No crashes, no related problems :).
Comment 2 Tristan Hoffmann 2008-03-02 11:08:31 UTC
I couldn't reproduce this bug, so I'll close it as worksforme.
Please reopen, if you still see this bug in a recent KDE version.
Comment 3 Nikita V. Youshchenko 2008-03-02 11:35:07 UTC
Same here. Looks like it is really fixed.