update keyboard focus when grabbing popup closed

For example, a wayland qt widget has an qlineedit with qcompleter.
    1. Input some words make qcompleter's popup window show. PopupInputFilter::keyEvent will set keyboard focus on the qcompleter's popup window.
    2. Continue to press a key which can make the qcompleter's popup window hidden and do not release it.
    3. Press the backspace key to make the qcompleter's popup window show again.
Result:
    Qcompleter's popup window will be created as an independent xdg_toplevel.This is because QT sets the surface of the focused window as the transient parent window of the popup window. If not found, QT will create a independent toplevel window.
After step 2, the focused window is the qcompleter's popup window which has be hidden. QT can not find the transient parent of the qcompleter's popup window, finally creat the popup window as a independent xdg_toplevel.

Signed-off-by: Liu Jie <liujie01@kylinos.cn>
This commit is contained in:
Liu Jie 2023-04-26 10:40:58 +08:00 committed by Vlad Zahorodnii
parent d2aee0a1a2
commit 9241252c67

View file

@ -7,6 +7,7 @@
#include "popup_input_filter.h"
#include "input_event.h"
#include "internalwindow.h"
#include "keyboard_input.h"
#include "wayland/seat_interface.h"
#include "wayland_server.h"
#include "window.h"
@ -31,6 +32,13 @@ void PopupInputFilter::handleWindowAdded(Window *window)
m_popupWindows << window;
connect(window, &Window::closed, this, [this, window]() {
m_popupWindows.removeOne(window);
// Move focus to the parent popup. If that's the last popup, then move focus back to the parent
if (!m_popupWindows.isEmpty() && m_popupWindows.last()->surface()) {
auto seat = waylandServer()->seat();
seat->setFocusedKeyboardSurface(m_popupWindows.last()->surface());
} else {
input()->keyboard()->update();
}
});
}
}