Qt-interest Archive, March 2002
FileDialog + double click == crash
Message 1 in thread
Using Qt 2.2.3 on Linux.
For a modeless file dialog we have set destruct on close widget flag.
This works except when the user double clicks on a file to accept it.
The code looks like :
void LyXFileDialog::done(int what)
{
lyxerr[Debug::GUI] << "Done FileDialog, value " << what << std::endl;
if (what == QDialog::Accepted) {
QString const & qfile = selectedFile();
string file;
if (!qfile.isNull())
file = qfile.latin1();
QFileDialog::done(what);
if (!file.empty())
lv_->getLyXFunc()->dispatch(action_, file);
}
}
#6 0x404c0fbb in QFileDialog::mode (this=0x83a6538) at dialogs/qfiledialog.cpp:3919
#7 0x404beb5f in QFileDialog::selectDirectoryOrFile (this=0x83a6538, newItem=0x83c23f8) at dialogs/qfiledialog.cpp:3485
#8 0x404bec49 in QFileDialog::selectDirectoryOrFile (this=0x83a6538, newItem=0x83c2470) at dialogs/qfiledialog.cpp:3496
#9 0x4046885c in QListBox::selected (this=0x83aef00, t0=0x83c2470) at widgets/moc_qlistbox.cpp:557
#10 0x403b24fc in QListBox::mouseDoubleClickEvent (this=0x83aef00, e=0xbfffee90) at widgets/qlistbox.cpp:1852
#11 0x403b23f5 in QListBox::viewportMouseDoubleClickEvent (this=0x83aef00, e=0xbfffee90) at widgets/qlistbox.cpp:1833
#12 0x404b1c2d in QFileListBox::viewportMouseDoubleClickEvent (this=0x83aef00, e=0xbfffee90) at dialogs/qfiledialog.cpp:1116
#13 0x4040d7bc in QScrollView::eventFilter (this=0x83aef00, obj=0x83af290, e=0xbfffee90) at widgets/qscrollview.cpp:1229
#14 0x403186d4 in QObject::activate_filters (this=0x83af290, e=0xbfffee90) at kernel/qobject.cpp:764
#15 0x40362db3 in QWidget::event (this=0x83af290, e=0xbfffee90) at kernel/qwidget.cpp:3889
#16 0x402dab8a in QApplication::notify (this=0x82e3ea0, receiver=0x83af290, event=0xbfffee90) at kernel/qapplication.cpp:1675
#17 0x4058c2c5 in QApplication::sendEvent (receiver=0x83af290, event=0xbfffee90) at kernel/qapplication.h:395
#18 0x402a32f7 in QETWidget::translateMouseEvent (this=0x83af290, event=0xbffff300) at kernel/qapplication_x11.cpp:3909
#19 0x4029fe18 in QApplication::x11ProcessEvent (this=0x82e3ea0, event=0xbffff300) at kernel/qapplication_x11.cpp:2788
#20 0x4029ef7d in QApplication::processNextEvent (this=0x82e3ea0, canWait=false) at kernel/qapplication_x11.cpp:2459
#21 0x402a0c5c in QApplication::processEvents (this=0x82e3ea0, maxtime=3000) at kernel/qapplication_x11.cpp:3035
#22 0x402dac10 in QApplication::processEvents (this=0x82e3ea0) at kernel/qapplication.cpp:1712
#23 0x814dd04 in GUIRunTime::processEvents () at GUIRunTime.C:48
The last line indicates that this mouse event is appearing in the event
queue after the file dialog has finished (And presumably, destructed).
Adding some qApp->processEvents() calls in the method above didn't help at
all.
I'm mystified as to why this event appears /after/ all this stuff, and fairly
obviously I need to fix it. Can someone give me some hints ?
thanks
john
--
[ signature omitted ]
Message 2 in thread
John,
We experienced a similar problem here. It's a bug in Qt that, according to
a comment in our code, was reported to TrollTech by another customer in
1999.
The problem (for us anyway) is that the widget under the open file dialog
can get a 'button up' event without any prior, corresponding 'button down'
event. In our case the widget we had under the file open dialog responded
to mouse events using logic we had written and that was expecting all
'button up' events were proceeded with a 'button down' event. To fix it we
simply guarded against this case. It would be nice if the underlying Qt
problem was fixed but I wouldn't remove the guard even if it were.
HTH,
-psj.
> -----Original Message-----
> From: owner-qt-interest@trolltech.com
> [mailto:owner-qt-interest@trolltech.com]On Behalf Of John Levon
> Sent: Thursday, March 21, 2002 6:46 PM
> To: qt-interest@trolltech.com
> Subject: FileDialog + double click == crash
>
>
> Using Qt 2.2.3 on Linux.
>
> For a modeless file dialog we have set destruct on close widget flag.
> This works except when the user double clicks on a file to accept it.
> The code looks like :
>
> void LyXFileDialog::done(int what)
> {
> lyxerr[Debug::GUI] << "Done FileDialog, value " << what
> << std::endl;
>
> if (what == QDialog::Accepted) {
> QString const & qfile = selectedFile();
> string file;
> if (!qfile.isNull())
> file = qfile.latin1();
>
> QFileDialog::done(what);
>
> if (!file.empty())
> lv_->getLyXFunc()->dispatch(action_, file);
> }
> }
>
> #6 0x404c0fbb in QFileDialog::mode (this=0x83a6538) at
> dialogs/qfiledialog.cpp:3919
> #7 0x404beb5f in QFileDialog::selectDirectoryOrFile
> (this=0x83a6538, newItem=0x83c23f8) at dialogs/qfiledialog.cpp:3485
> #8 0x404bec49 in QFileDialog::selectDirectoryOrFile
> (this=0x83a6538, newItem=0x83c2470) at dialogs/qfiledialog.cpp:3496
> #9 0x4046885c in QListBox::selected (this=0x83aef00,
> t0=0x83c2470) at widgets/moc_qlistbox.cpp:557
> #10 0x403b24fc in QListBox::mouseDoubleClickEvent
> (this=0x83aef00, e=0xbfffee90) at widgets/qlistbox.cpp:1852
> #11 0x403b23f5 in QListBox::viewportMouseDoubleClickEvent
> (this=0x83aef00, e=0xbfffee90) at widgets/qlistbox.cpp:1833
> #12 0x404b1c2d in QFileListBox::viewportMouseDoubleClickEvent
> (this=0x83aef00, e=0xbfffee90) at dialogs/qfiledialog.cpp:1116
> #13 0x4040d7bc in QScrollView::eventFilter (this=0x83aef00,
> obj=0x83af290, e=0xbfffee90) at widgets/qscrollview.cpp:1229
> #14 0x403186d4 in QObject::activate_filters (this=0x83af290,
> e=0xbfffee90) at kernel/qobject.cpp:764
> #15 0x40362db3 in QWidget::event (this=0x83af290, e=0xbfffee90)
> at kernel/qwidget.cpp:3889
> #16 0x402dab8a in QApplication::notify (this=0x82e3ea0,
> receiver=0x83af290, event=0xbfffee90) at kernel/qapplication.cpp:1675
> #17 0x4058c2c5 in QApplication::sendEvent (receiver=0x83af290,
> event=0xbfffee90) at kernel/qapplication.h:395
> #18 0x402a32f7 in QETWidget::translateMouseEvent (this=0x83af290,
> event=0xbffff300) at kernel/qapplication_x11.cpp:3909
> #19 0x4029fe18 in QApplication::x11ProcessEvent (this=0x82e3ea0,
> event=0xbffff300) at kernel/qapplication_x11.cpp:2788
> #20 0x4029ef7d in QApplication::processNextEvent (this=0x82e3ea0,
> canWait=false) at kernel/qapplication_x11.cpp:2459
> #21 0x402a0c5c in QApplication::processEvents (this=0x82e3ea0,
> maxtime=3000) at kernel/qapplication_x11.cpp:3035
> #22 0x402dac10 in QApplication::processEvents (this=0x82e3ea0) at
> kernel/qapplication.cpp:1712
> #23 0x814dd04 in GUIRunTime::processEvents () at GUIRunTime.C:48
>
> The last line indicates that this mouse event is appearing in the event
> queue after the file dialog has finished (And presumably, destructed).
>
> Adding some qApp->processEvents() calls in the method above didn't help at
> all.
>
> I'm mystified as to why this event appears /after/ all this
> stuff, and fairly
> obviously I need to fix it. Can someone give me some hints ?
>
> thanks
> john
>
> --
> "What *is* your fascination with my forbidden closet of mystery ?"
> - Chief Wiggum
>
> --
> List archive and information: http://qt-interest.trolltech.com
>
>
Message 3 in thread
"Paul St. John" <pstjohn@igotechnologies.com>
> John,
>
> We experienced a similar problem here. It's a bug in Qt that, according to
> a comment in our code, was reported to TrollTech by another customer in
> 1999.
And even earlier.
> The problem (for us anyway) is that the widget under the open file dialog
> can get a 'button up' event without any prior, corresponding 'button down'
> event. In our case the widget we had under the file open dialog responded
> to mouse events using logic we had written and that was expecting all
> 'button up' events were proceeded with a 'button down' event. To fix it we
> simply guarded against this case. It would be nice if the underlying Qt
> problem was fixed but I wouldn't remove the guard even if it were.
I'll answer that, since that happened on my watch, so to speak. I've left
Trolltech since, but it was I who became aware of the basic problem and
mostly I who decided how to handle it.
First let be describe an an extreme case.
Suppose that there are two applications running, and that one has a window
on top of the other. The user clicks on something in the topmost window,
and the mouse press handling crashes. Segfaults. The application's
windows abruptly go away.
The mouse is, however, still pressed, and eventually will be released. At
that point, the window system will send a mouse release to the other
application. That application uses Qt, and Qt has to decide whether to
deliver or suppress the event.
Hard choice.
In this case it's "obvious" that the even should be suppressed: the user
didn't mean to send a mouse release to the underlying application. But
there are also cases where the event "obviously" should be delivered, and
from the viewpoint of the receiving Qt, the decision is not an easy one.
Initially, we didn't think much about these strange cases, and Qt just
passed the window systems' events on to the widgets. However, we soon ran
into them. At that point, we had to either make QApplication be basically
restrictive (pass on only events that it knows to be meaningful), or
basically permissive (pass on all events that the window system
generates). Restrictive would have its advantages:
- we could provide documented event invariants (e.g. no mouse release
without prior mouse press)
- applications could be less paranoid
But also its disadvantages:
- while we had fairly good knowledge of the event system and the possible
invariants, we probably did not have _complete_ knowledge, and
suppressing events by default sounded very risky, even if the default
is very uncommon
- one of the early customers might be depending on something we didn't
know about, and we might break code
- the code, documentation and testing would be a lot of work, for small
benefit
We decided to generally be permissive, and in principle let applications
fend for themselves. In two particular cases (the two that made the most
problems for application programmers) we decided to provide invariants.
Both invariants have provided benefits - and a fair share of problems. On
the whole I think the balance we struck was about right. Not perfect, but
then perfection wasn't on the table.
--Arnt
Message 4 in thread
On Sat, Mar 23, 2002 at 03:57:30PM +0100, Arnt Gulbrandsen wrote:
> And even earlier.
Do you know where this might be documented ? qt-interest searches showed
nothing.
> I'll answer that, since that happened on my watch, so to speak. I've left
> Trolltech since, but it was I who became aware of the basic problem and
> mostly I who decided how to handle it.
Thanks Arnt.
> Suppose that there are two applications running, and that one has a window
> on top of the other. The user clicks on something in the topmost window,
> and the mouse press handling crashes. Segfaults. The application's
> windows abruptly go away.
>
> The mouse is, however, still pressed, and eventually will be released. At
> that point, the window system will send a mouse release to the other
> application. That application uses Qt, and Qt has to decide whether to
> deliver or suppress the event.
This is indeed an extreme case I would say. But you appear to have
answered Paul's problem, not mine. In particular, there are not two
applications involved, and it is not a problem with non-matching events
(this would still not crash lyx, and the backtrace would not show what
it does). The problem seems to be that QFileDialog is destructed, hence
::mode() is crashing. Thanks to the source I can investigate further, it
looks like I shall have to.
Arnt, (or even better, a current troll), can you comment on my original
report ?
I will see if I can distill the problem into a stand-alone application.
I've spent days of time dealing with xforms bugs, it is a littl
disappointing that I have to do the same with Qt.
thanks
john
--
[ signature omitted ]
Message 5 in thread
John Levon <moz@compsoc.man.ac.uk>
> On Sat, Mar 23, 2002 at 03:57:30PM +0100, Arnt Gulbrandsen wrote:
>
> > And even earlier.
>
> Do you know where this might be documented ? qt-interest searches showed
> nothing.
Probably nowhere.
The others at Trolltech used to occasionally complain about the amount of
information that was stored only in my head. (In my defence, I will point
out that I also wrote a great deal of the documentation - I just didn't
write enough.)
> This is indeed an extreme case I would say. But you appear to have
> answered Paul's problem, not mine. In particular, there are not two
> applications involved, and it is not a problem with non-matching events
> (this would still not crash lyx, and the backtrace would not show what
> it does). The problem seems to be that QFileDialog is destructed, hence
> ::mode() is crashing. Thanks to the source I can investigate further, it
> looks like I shall have to.
It sounds like someone's deleting a widget (the QFD) in response to a
mousePressEvent(), and whatever receives the corresponding
mouseReleaseEvent() still accesses the widget.
I suggest putting a breakpoint in QFD::~QFD and looking for clues that a
pointer may be used after the object's destruction. Or you might try
running valgrind. Valgrind rocks.
> I will see if I can distill the problem into a stand-alone application.
That's by far the best way to get developer attention. Almost the only.
> I've spent days of time dealing with xforms bugs, it is a littl
> disappointing that I have to do the same with Qt.
Qt may be good, but only an advokid would claim it's perfect.
--Arnt
Message 6 in thread
On Sat, Mar 23, 2002 at 05:38:16PM +0100, Arnt Gulbrandsen wrote:
> out that I also wrote a great deal of the documentation - I just didn't
> write enough.)
Indeed, it's always a perennial problem all develoeprs struggle
against...
> It sounds like someone's deleting a widget (the QFD) in response to a
> mousePressEvent(), and whatever receives the corresponding
> mouseReleaseEvent() still accesses the widget.
Yep, that would explain what I see.
> I suggest putting a breakpoint in QFD::~QFD and looking for clues that a
> pointer may be used after the object's destruction. Or you might try
> running valgrind. Valgrind rocks.
valgrind does indeed rock. Now I know there's no simple pat answer to my
problem, I can certainly investigate further (and even try Qt 3 ...)
regards
john
--
[ signature omitted ]
Message 7 in thread
On Sat, Mar 23, 2002 at 05:38:16PM +0100, Arnt Gulbrandsen wrote:
> > I will see if I can distill the problem into a stand-alone application.
>
> That's by far the best way to get developer attention. Almost the only.
And the 20-line or so testcase is attached. It will crash on
double-click. It looks like I can't use destructive close and I will
have to rework my code to reap instances after some "safe" time :((
This was tested with qt 2.2.3 and qt 2.3.1. I sincerly hope it's not a
problem in 3.x too ...
I would appreciate any workaround suggestions.
> Qt may be good, but only an advokid would claim it's perfect.
sure, but I wouldn't have expected such an obvious bug like this to have
lasted so long :/
> Probably nowhere.
For what it's worth, Trolltech would do much to endear develoeprs if
they were honest about the bugs in their product. That means: a public
bug tracker. As it is, the Qt website makes no mention of bugs, until
they get fixed.
This is particularly galling with embarrassing bugs like the one
demonstrated above.
thanks
john
--
[ signature omitted ]
#include "picture.h"
/* test case showing that destructive close of file dialogs is
* totally broken in Qt. Try double-clicking a file (on linux)
*/
#include <qfiledialog.h>
// #include <X11/Xlib.h>
PictureDisplay::PictureDisplay( const char *fileName )
{
butt = new QPushButton("click me", this);
connect(butt, SIGNAL(pressed()), this, SLOT(bpressed()));
}
class QFD : public QFileDialog
{
public: QFD() {
setWFlags(getWFlags() | WDestructiveClose);
}
virtual ~QFD() {
//XSync(x11Display(), 1); // doesn't help
qApp->processEvents(); // doesn't help
}
};
void PictureDisplay::bpressed()
{
QFD * d = new QFD();
d->show();
}
int main( int argc, char **argv )
{
QApplication a( argc, argv );
PictureDisplay test( "blah" );
a.setMainWidget( &test);
test.show();
return a.exec();
}
#include <qapplication.h>
#include <qwidget.h>
#include <qpushbutton.h>
class PictureDisplay : public QWidget // picture display widget
{
Q_OBJECT
public:
PictureDisplay( const char *fileName );
protected slots:
void bpressed();
private:
QPushButton * butt;
};
all: picture.cpp picture.moc.o
g++ -o picture -I$(QTDIR)/include picture.cpp picture.moc.o -L$(QTDIR)/lib -lqt
picture.moc.o: picture.moc.cpp
g++ -c -I$(QTDIR)/include $<
picture.moc.cpp: picture.h
moc -o $@ $<
Message 8 in thread
>
> For what it's worth, Trolltech would do much to endear develoeprs if
> they were honest about the bugs in their product. That means: a public
> bug tracker. As it is, the Qt website makes no mention of bugs, until
> they get fixed.
>
> This is particularly galling with embarrassing bugs like the one
> demonstrated above.
>
I'd like to see this too.
I have reported a bug in styles on Windows 98. I'm told that it is a known
bug and should be fixed in the 3.0.4 release, but I can't find out.
What other flavours of Windows if, any, are affected.
Any documented details about the bug
Any possible workaround I could use in the meantime
--
[ signature omitted ]