QMDIArea, addSubWindow steals the focus from other applications
-
Hi,
I am using QT Version 4.6.3.
I am creating new QMdiSubWindow and adding them to QMdiArea using the method addSubWindow. The method steals the focus from the other applications.
My application has TCL interface and the sub windows will be called accordingly. So if i start to work on some other application as emacs (or any other), once the addSubWindow method is called it steals the Focus from the current working application and gives it to the new sub window created.
I tried setFocusPolicy(Qt::NoFocus) and setAttribute(Qt::WA_ShowWithoutActivating) on the new QMdiSubWindow created but it did not help.
Please send across how i can stop my QT application from stealing the focus.
Thanks & regards,
Subagha -
Hi Subagha,
which OS are you using?
-
Linux RedHat
-
Can anybody please help me solve this issue
-
Hi,
Please send across if anybody knows the solution to this issue.
I have been facing this issue from quite some time now.regards
-
It could well be, that nobody else came across this behavior. Do you have a small, yet complete and compilable example that demonstrates this?
-
I share the exact same problem. I tried to build a small example for a whole day without success.
In my application the focus is definitely stolen within addSubWindow(). Depending whether or not I call setWindowState( Qt::WindowMaximized ) the steal happens a little earlier (second call to addSubWindow()) or a little later (third call to addSubWindow()). I'll dig deeper into this and let you know. -
I could reproduce a bunch of focus and display problems in QMdiArea with Qt 4.6.3 and 4.7.
I could not test Qt 4.8 yet as I have problems to compile it (another issue).I'll upload my demo app to the Qt bugtracker via my company's support account and
add link to that issue right here afterwards. -
I added an issue in the Qt commercial bugtracker -> -> bug no. 285221
Here's a copy for you, as I don't know whether the bugtracker is public:
<hr>
Dear support team,I've got some serious problems with QMdiArea. In my application it steals the focus from other applications when I add subwindows to it. This is not always the case, but depends on some incomprehensible state of QMdiArea.
I created a tiny demo app, that exposes a few issues with QMdiArea. I assume, that my application will work if these issues are fixed in Qt.
When you compiled the app, run it as follows:
./test_gui 0 0 0 -> empty main window, starts with focus (OK)
./test_gui 1 0 0 -> why is the subwindow not maximized? (BUG)
./test_gui 2 0 0 -> both subwindows are maximized, starts without focus (initial focus? bug?)
./test_gui 1 1 0 -> 1 subwindow, maximized, starts with focus (OK)
./test_gui 2 1 0 -> 2 subwindows, maximized, starts without focus (initial focus? bug?)
./test_gui 1 1 1 -> 1 subwindow at startup, maximized, starts with focus, adds 3 windows after 5 seconds (OK)
./test_gui 2 1 1 -> 2 subwindows at startup, maximized, starts without focus, STEALS focus after 5 seconds when windows are added (BUG, big problem in real world application)
./test_gui 2 0 1 -> 2 subwindows at startup, maximized, starts without focus, doesn't steal focus when windows are added, but the windows don't work correctly -> click on the tabs and see that they get grey and unusable (BUG)With all these problems in QMdiArea, I can not build a tabbed view that works as expected and doesn't steal the focus all the time (which is really annoying).
As we have an own build process, you may need to change the includes from
#include "QtGui/QMainWindow"
to
#include <QMainWindow>
before using the usual qmake -
test_gui.C
@/* -- C++ -- */
#include "QtGui/QAction"
#include "QtGui/QApplication"
#include "QtCore/QString"
#include "QtCore/QTimer"#include <cstdio>
#include <iostream>
#include <X11/Xlib.h>#include "TestMainWindow.h"
// X Event Error Handler
static int myXErrorHandler( Display* d, XErrorEvent* ev )
{
const int bufSize = 1024;
char buffer[bufSize];
XGetErrorText(d, ev->error_code, buffer, bufSize);
std::cerr << "-E- X/Windows error " << (int)ev->error_code
<< ": " << buffer << std::endl;
char buf2[100];
if (ev->minor_code != 0) {
snprintf(buf2, sizeof(buf2), "%d.%d",
ev->request_code, ev->minor_code);
}
else {
snprintf(buf2, sizeof(buf2), "%d", ev->request_code);
}
std::cerr << "\top_code: " << buf2;
XGetErrorDatabaseText(d, "XRequest", buf2, "cannot decode",
buffer, bufSize);
std::cerr << " (" << buffer << ")" << std::endl;
return 1;
}int main( int argc, char* argv[] )
{
XSetErrorHandler(myXErrorHandler);QApplication app(argc, argv);
if( argc < 3 )
{
std::cerr << "wrong number of arguments" << std::endl;
exit(1);
}int no_windows = QString( argv[1] ).toInt();
int do_show_max = QString( argv[2] ).toInt();
int add_another_three = QString( argv[3] ).toInt();TestMainWindow mw( do_show_max );
if( no_windows > 0 )
{
mw.addNewSubWindows( no_windows );
}
mw.show();if( add_another_three )
{
QTimer::singleShot( 5000, &mw, SLOT( addThreeWindows() ) );
}return app.exec();
}
@ -
TestMainWindow.h
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include "QtGui/QMainWindow"
#include "QtGui/QMdiArea"
#include "QtGui/QMdiSubWindow"
#include "QtGui/QLabel"class TestMainWindow : public QMainWindow
{
Q_OBJECTpublic:
TestMainWindow( bool do_show_max )
: mDoShowMax(do_show_max)
, mMdiArea(0)
, mCounter(0)
{
mMdiArea = new QMdiArea(this);
mMdiArea->setViewMode( QMdiArea::TabbedView );
setCentralWidget(mMdiArea);
//showMinimized(); // activate this to reproduce X11 Error -> BadMatch(8)
}public slots:
void addNewSubWindows( size_t num )
{
for( size_t i = 0 ; i < num ; ++i )
{
QMdiSubWindow* sub = new QMdiSubWindow();
sub->setWindowTitle( "Title_" + QString::number(++mCounter) );
sub->setWidget( new QLabel( "MdiSubWindow_" + QString::number(mCounter) ) );
mMdiArea->addSubWindow(sub);
if( mDoShowMax )
{
sub->showMaximized(); // looks good, but steals focus
}
}
}void addThreeWindows()
{
addNewSubWindows(3);
}private:
bool mDoShowMax;
QMdiArea* mMdiArea;
unsigned mCounter;
};#endif // MAINWINDOW_H
@ -
Just to keep you up to date:
2 issues were accepted by my qt support contact (./test_gui 1 0 0 and ./test_gui 2 0 1)
The focus stealing problem is still under discussion.
Using the X error handler, it's pretty easy to find the buggy spots in qt's focus handling.
Just uncomment line 23 in TestMainWindow.h and run the demo app.
You will see messages like:
-E- X/Windows error 8: BadMatch (invalid parameter attributes)
op_code: 42 (X_SetInputFocus)
in your console, which want to tell you that Qt's communication with X11 doesn't work properly. -
Update:
Add the following line right after line 53 in test_gui.C:
mw.setAttribute( Qt::WA_X11DoNotAcceptFocus );This will prevent Qt from stealing the keyboard focus (Qt 4.7 and later, Qt 4.6.3 needs to be patched for this).
Unfortunately the demo app still pops to the front in your window manager (just without keyboard focus).
-> not perfect yetIf you also add:
mw.setWindowFlags( Qt::WindowStaysOnBottomHint );
then the window won't pop up any more, but unfortunately you can not get it to the front at all any more. :(
-> bad ideaAnother issue in QMdiArea can be reproduced when one adds the following line right after sub->showMaximized() in line 38 in TestMainWindow.h:
sub->lower();
When you now call ./test_gui 2 1 1, then you will see a tabbed view with 1 subwindow maximized and 3 windows on top of it.Best regards,
Mirko