From b4e94438209e66e5fd303483f8e32147fb19f5ef Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Wed, 21 Sep 2022 14:17:06 +0200 Subject: [PATCH] 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 --- src/inputmethod.cpp | 10 ++++++++-- src/inputmethod.h | 1 + src/inputpanelv1window.cpp | 40 ++++++++++++++++++++++++++++++++------ src/inputpanelv1window.h | 4 ++++ 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/inputmethod.cpp b/src/inputmethod.cpp index a44cc40e50..5d2109223b 100644 --- a/src/inputmethod.cpp +++ b/src/inputmethod.cpp @@ -139,16 +139,18 @@ void InputMethod::init() void InputMethod::show() { + m_shouldShowPanel = true; if (m_panel) { - m_panel->showClient(); + m_panel->show(); updateInputPanelState(); } } void InputMethod::hide() { + m_shouldShowPanel = false; if (m_panel) { - m_panel->hideClient(); + m_panel->hide(); updateInputPanelState(); } } @@ -214,6 +216,10 @@ void InputMethod::setPanel(InputPanelV1Window *panel) Q_EMIT visibleChanged(); updateInputPanelState(); Q_EMIT panelChanged(); + + if (m_shouldShowPanel) { + show(); + } } void InputMethod::setTrackedWindow(Window *trackedWindow) diff --git a/src/inputmethod.h b/src/inputmethod.h index ee17151786..9ff09c7e13 100644 --- a/src/inputmethod.h +++ b/src/inputmethod.h @@ -138,6 +138,7 @@ private: bool m_hasPendingModifiers = false; bool m_activeClientSupportsTextInput = false; + bool m_shouldShowPanel = false; }; } diff --git a/src/inputpanelv1window.cpp b/src/inputpanelv1window.cpp index 88fa38e186..c8e8d4bd1d 100644 --- a/src/inputpanelv1window.cpp +++ b/src/inputpanelv1window.cpp @@ -47,9 +47,11 @@ void InputPanelV1Window::showOverlayPanel() { setOutput(nullptr); m_mode = Overlay; - reposition(); - showClient(); - setReadyForPainting(); + if (m_shouldBeShown && surface()->isMapped()) { + setReadyForPainting(); + reposition(); + showClient(); + } } void InputPanelV1Window::showTopLevel(OutputInterface *output, InputPanelSurfaceV1Interface::Position position) @@ -57,13 +59,39 @@ void InputPanelV1Window::showTopLevel(OutputInterface *output, InputPanelSurface Q_UNUSED(position); m_mode = Toplevel; setOutput(output); - showClient(); + if (m_allowed && m_shouldBeShown && surface()->isMapped()) { + setReadyForPainting(); + reposition(); + showClient(); + } } void InputPanelV1Window::allow() { - setReadyForPainting(); - reposition(); + m_allowed = true; + 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() diff --git a/src/inputpanelv1window.h b/src/inputpanelv1window.h index 577a820555..b4ffce4ec3 100644 --- a/src/inputpanelv1window.h +++ b/src/inputpanelv1window.h @@ -77,6 +77,8 @@ public: return m_mode; } void allow(); + void show(); + void hide(); protected: void moveResizeInternal(const QRectF &rect, MoveResizeMode mode) override; @@ -89,6 +91,8 @@ private: QPointer m_output; Mode m_mode = Toplevel; + bool m_allowed = false; + bool m_shouldBeShown = false; const QPointer m_panelSurface; };