PDA

View Full Version : QMdiArea unwanted actvation



fullmetalcoder
6th November 2007, 19:37
I'm using a QMdiArea as the central widget of my application and one of its subwindow itself contains another QMdiArea. As long as I keep my application on top of others everything *looks* fine but when I switch to another window and switch back to my app I face the weirdest (and among the most annoying) issue I've ever faced in Qt : QMdiArea automatically changes the active subwindow to the one owning another QMdiArea... I've any sort of software lock (signals based) I could think of, even tried to force the QMdiArea to set back the previous subwindow by keeping track of it but it just does not work...
I read the docs again and again and found no clues... Just to make sure the problem does not come from my code I checked another app using the same QMdiArea nesting and was able to reproduce the bug... Does anyone have a magic trick or do I need to go on the tracker and wait for a couple of releases to have it fixed? :(

jpn
6th November 2007, 19:44
Would you mind attaching the test app so we can play around with it? Looks like QMdiArea does some nasty activation tricks upon QEvent::WindowActivate. Perhaps you could try filtering it (and possibly QEvent::WindowDeactivate too) out from the inner QMdiArea...

mchara
7th November 2007, 08:03
hi,
does it happens also when mdiArea in child window have no children? i would suspect that activation of child window may bring mdiArea to front, but it's only a speculation...

fullmetalcoder
9th November 2007, 18:57
Would you mind attaching the test app so we can play around with it? Looks like QMdiArea does some nasty activation tricks upon QEvent::WindowActivate. Perhaps you could try filtering it (and possibly QEvent::WindowDeactivate too) out from the inner QMdiArea...
Thanks for the hint I'll try that. FYI the test apps are Edyuk 1.0.0 (SVN HEAD) and Monkey Studio 2 (still in private beta test so I can't redistribute it) but I'm willing to bet that the simplest subset of nested QMdiArea will yeld the same activation behavior...


does it happens also when mdiArea in child window have no children? i would suspect that activation of child window may bring mdiArea to front, but it's only a speculation...
I have no idea... The child mdi area always have at least a child (always a single one in Edyuk and one or more in Monkey Studio...)

jpn
9th November 2007, 23:00
Just to make sure the problem does not come from my code I checked another app using the same QMdiArea nesting and was able to reproduce the bug...
I somehow expected this to be a minimal compilable example or something like that. :)


Does anyone have a magic trick or do I need to go on the tracker and wait for a couple of releases to have it fixed? :(
The "magic trick" goes here:


class InnerMdiArea : public QMdiArea
{
public:
InnerMdiArea(QWidget* parent = 0)
: QMdiArea(parent) { }

bool eventFilter(QObject* object, QEvent* event)
{
return event->type() == QEvent::ApplicationActivate
|| event->type() == QEvent::ApplicationDeactivate;
}
};

As the class name suggests, use this as the inner MDI area and everything should be fine. ;)

PS. The reason this works is that QMdiArea installs an event filter on QApplication and QObject::eventFilter() is virtual..

fullmetalcoder
10th November 2007, 08:43
Neat! :) It works just fine but the only limitation is that it take place in the inner area which is loaded from a plugin so it will put some restrictions on plugins development. Better than nothing anyway...

jpn
10th November 2007, 09:30
It works just fine but the only limitation is that it take place in the inner area which is loaded from a plugin so it will put some restrictions on plugins development.
Well, in that case you could do it differently. Just detect such nested mdi area in a way or another and do:

qApp->removeEventFilter(innerMdiArea);

mchara
12th November 2007, 08:09
You may also implement eventFilter in some external QObject and install it after QMdiArea creation from plugin.