inputpanelv1window: fix showing and hiding

Instead of InputMethod directly calling showClient() on the input panel,
call methods that properly show or hide the panel as needed, with readyForPainting
set appropriately. This removes the cases where it's shown without being ready for
painting, which causes crashes.

BUG: 459404
This commit is contained in:
Xaver Hugl 2022-09-21 14:17:06 +02:00
parent 1c6a95bceb
commit b4e9443820
4 changed files with 47 additions and 8 deletions

View file

@ -139,16 +139,18 @@ void InputMethod::init()
void InputMethod::show() void InputMethod::show()
{ {
m_shouldShowPanel = true;
if (m_panel) { if (m_panel) {
m_panel->showClient(); m_panel->show();
updateInputPanelState(); updateInputPanelState();
} }
} }
void InputMethod::hide() void InputMethod::hide()
{ {
m_shouldShowPanel = false;
if (m_panel) { if (m_panel) {
m_panel->hideClient(); m_panel->hide();
updateInputPanelState(); updateInputPanelState();
} }
} }
@ -214,6 +216,10 @@ void InputMethod::setPanel(InputPanelV1Window *panel)
Q_EMIT visibleChanged(); Q_EMIT visibleChanged();
updateInputPanelState(); updateInputPanelState();
Q_EMIT panelChanged(); Q_EMIT panelChanged();
if (m_shouldShowPanel) {
show();
}
} }
void InputMethod::setTrackedWindow(Window *trackedWindow) void InputMethod::setTrackedWindow(Window *trackedWindow)

View file

@ -138,6 +138,7 @@ private:
bool m_hasPendingModifiers = false; bool m_hasPendingModifiers = false;
bool m_activeClientSupportsTextInput = false; bool m_activeClientSupportsTextInput = false;
bool m_shouldShowPanel = false;
}; };
} }

View file

@ -47,9 +47,11 @@ void InputPanelV1Window::showOverlayPanel()
{ {
setOutput(nullptr); setOutput(nullptr);
m_mode = Overlay; m_mode = Overlay;
reposition(); if (m_shouldBeShown && surface()->isMapped()) {
showClient(); setReadyForPainting();
setReadyForPainting(); reposition();
showClient();
}
} }
void InputPanelV1Window::showTopLevel(OutputInterface *output, InputPanelSurfaceV1Interface::Position position) void InputPanelV1Window::showTopLevel(OutputInterface *output, InputPanelSurfaceV1Interface::Position position)
@ -57,13 +59,39 @@ void InputPanelV1Window::showTopLevel(OutputInterface *output, InputPanelSurface
Q_UNUSED(position); Q_UNUSED(position);
m_mode = Toplevel; m_mode = Toplevel;
setOutput(output); setOutput(output);
showClient(); if (m_allowed && m_shouldBeShown && surface()->isMapped()) {
setReadyForPainting();
reposition();
showClient();
}
} }
void InputPanelV1Window::allow() void InputPanelV1Window::allow()
{ {
setReadyForPainting(); m_allowed = true;
reposition(); if (m_shouldBeShown && surface()->isMapped()) {
setReadyForPainting();
reposition();
showClient();
}
}
void InputPanelV1Window::show()
{
m_shouldBeShown = true;
if (m_allowed && surface()->isMapped()) {
setReadyForPainting();
reposition();
showClient();
}
}
void InputPanelV1Window::hide()
{
m_shouldBeShown = false;
if (readyForPainting()) {
hideClient();
}
} }
void KWin::InputPanelV1Window::reposition() void KWin::InputPanelV1Window::reposition()

View file

@ -77,6 +77,8 @@ public:
return m_mode; return m_mode;
} }
void allow(); void allow();
void show();
void hide();
protected: protected:
void moveResizeInternal(const QRectF &rect, MoveResizeMode mode) override; void moveResizeInternal(const QRectF &rect, MoveResizeMode mode) override;
@ -89,6 +91,8 @@ private:
QPointer<Output> m_output; QPointer<Output> m_output;
Mode m_mode = Toplevel; Mode m_mode = Toplevel;
bool m_allowed = false;
bool m_shouldBeShown = false;
const QPointer<KWaylandServer::InputPanelSurfaceV1Interface> m_panelSurface; const QPointer<KWaylandServer::InputPanelSurfaceV1Interface> m_panelSurface;
}; };