Linux-specific: don't force X11 focus unnecessarily

Focus is already transferred to GoldenDict in toggleMainWindow() only
the first time the main window is shown. At all subsequent requests to
show the main window, focus has to be forced with the workaround.
Checking focus asynchronously allows to resort to the workaround less
often.

Under Xfce: the timeout of 0 ms is almost always sufficient in the Qt 5
version, but is never enough in the Qt 4 version. The timeout of 4 ms is
always sufficient in both versions.

Under KDE Plasma: the timeout of 0 ms is rarely sufficient in the Qt 5
version. Unfortunately, with any timeout other than 0 ms, the Qt 5
version does not always get focus, which would be a serious regression,
so no other timeout can be used. The Qt 4 version does not always get
focus both with and without the timeout.
This commit is contained in:
Igor Kushnir 2022-11-05 18:21:28 +02:00 committed by Abs62
parent a321593ed1
commit 5f96f1f26e
2 changed files with 38 additions and 26 deletions

View file

@ -3078,36 +3078,44 @@ void MainWindow::toggleMainWindow( bool onlyShow )
focusTranslateLine();
#ifdef X11_MAIN_WINDOW_FOCUS_WORKAROUNDS
Window wh = 0;
int rev = 0;
XGetInputFocus( QX11Info::display(), &wh, &rev );
if( wh != internalWinId() && !byIconClick )
{
QPoint const pointRelativeToRoot = mapToGlobal( QPoint( 0, 0 ) );
XEvent event;
memset( &event, 0, sizeof( event) );
event.type = ButtonPress;
event.xbutton.x = 0;
event.xbutton.y = 0;
event.xbutton.x_root = pointRelativeToRoot.x();
event.xbutton.y_root = pointRelativeToRoot.y();
event.xbutton.window = internalWinId();
event.xbutton.root = QX11Info::appRootWindow( QX11Info::appScreen() );
event.xbutton.state = Button1Mask;
event.xbutton.button = Button1;
event.xbutton.same_screen = true;
event.xbutton.time = CurrentTime;
XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event );
XFlush( QX11Info::display() );
event.type = ButtonRelease;
XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event );
XFlush( QX11Info::display() );
}
if( !byIconClick )
QTimer::singleShot( 0, this, SLOT( forceX11Focus() ) );
#endif
}
}
#ifdef X11_MAIN_WINDOW_FOCUS_WORKAROUNDS
void MainWindow::forceX11Focus()
{
Window wh = 0;
int rev = 0;
XGetInputFocus( QX11Info::display(), &wh, &rev );
if( wh != internalWinId() )
{
QPoint const pointRelativeToRoot = mapToGlobal( QPoint( 0, 0 ) );
XEvent event;
memset( &event, 0, sizeof( event) );
event.type = ButtonPress;
event.xbutton.x = 0;
event.xbutton.y = 0;
event.xbutton.x_root = pointRelativeToRoot.x();
event.xbutton.y_root = pointRelativeToRoot.y();
event.xbutton.window = internalWinId();
event.xbutton.root = QX11Info::appRootWindow( QX11Info::appScreen() );
event.xbutton.state = Button1Mask;
event.xbutton.button = Button1;
event.xbutton.same_screen = true;
event.xbutton.time = CurrentTime;
XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event );
XFlush( QX11Info::display() );
event.type = ButtonRelease;
XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event );
XFlush( QX11Info::display() );
}
}
#endif
void MainWindow::installHotKeys()
{
hotkeyWrapper.reset(); // Remove the old one

View file

@ -280,6 +280,10 @@ private:
private slots:
#ifdef X11_MAIN_WINDOW_FOCUS_WORKAROUNDS
void forceX11Focus();
#endif
void hotKeyActivated( int );
/// If new release checks are on, santizies the next check time and starts