diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2022-04-06 18:59:10 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2022-04-07 15:04:22 +0200 |
commit | e81385277c091dabb1f6542a94229d7dcc77289b (patch) | |
tree | 357b3f50631e8f6454e20bdae9d52518b961bcd5 /vcl/qt5 | |
parent | 5aa7b65c882019b74cfab95e5e9c77150b2876b0 (diff) |
tdf#143135 Qt break recursive IM QueryCursorRect
To reproduce the Impress crash, you need an IM, e.g. fcitx / ibus.
This is triggered by having an active input, like double-clicking
one of a presentations text fields, then leaving the window and
switching back to it.
This results in a stack exhaustion in a few seconds. The backtrace
is basically:
QWidget::setFocus
QtFrame::ToTop
sd::Window::GrabFocus
ImplHandleExtTextInputPos
QtWidget::inputMethodQuery
QInputMethod::cursorRectangle
QWidget::setFocus
QApplication::setActiveWindow
QtInstance::DoYield
main
I scratched my head over the longer backtrace for while, but there
seems to be no good way to prevent this from LO's POV. The only
alternative from the Qt VCL plugin is QtFrame::ToTop. That code
is less ugly (no mutable or cached result), but QtWidget::
inputMethodQuery is earlier in the backtrace.
Change-Id: Ief3a8e44bca295cc676e75050d52d70a1da98a88
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132643
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl/qt5')
-rw-r--r-- | vcl/qt5/QtFrame.cxx | 5 | ||||
-rw-r--r-- | vcl/qt5/QtWidget.cxx | 18 |
2 files changed, 16 insertions, 7 deletions
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx index 2e396fa8ce07..b8f649e64b78 100644 --- a/vcl/qt5/QtFrame.cxx +++ b/vcl/qt5/QtFrame.cxx @@ -799,8 +799,9 @@ void QtFrame::ToTop(SalFrameToTop nFlags) pWidget->activateWindow(); else if ((nFlags & SalFrameToTop::GrabFocus) || (nFlags & SalFrameToTop::GrabFocusOnly)) { - pWidget->activateWindow(); - pWidget->setFocus(); + if (!(nFlags & SalFrameToTop::GrabFocusOnly)) + pWidget->activateWindow(); + pWidget->setFocus(Qt::OtherFocusReason); } } diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx index 6362a1353d54..cd47492808cc 100644 --- a/vcl/qt5/QtWidget.cxx +++ b/vcl/qt5/QtWidget.cxx @@ -625,6 +625,7 @@ QtWidget::QtWidget(QtFrame& rFrame, Qt::WindowFlags f) : QWidget(Q_NULLPTR, f) , m_rFrame(rFrame) , m_bNonEmptyIMPreeditSeen(false) + , m_bInInputMethodQueryCursorRectangle(false) , m_nDeltaX(0) , m_nDeltaY(0) { @@ -800,11 +801,18 @@ QVariant QtWidget::inputMethodQuery(Qt::InputMethodQuery property) const } case Qt::ImCursorRectangle: { - const qreal fRatio = m_rFrame.devicePixelRatioF(); - SalExtTextInputPosEvent aPosEvent; - m_rFrame.CallCallback(SalEvent::ExtTextInputPos, &aPosEvent); - return QVariant(QRect(aPosEvent.mnX / fRatio, aPosEvent.mnY / fRatio, - aPosEvent.mnWidth / fRatio, aPosEvent.mnHeight / fRatio)); + if (!m_bInInputMethodQueryCursorRectangle) + { + m_bInInputMethodQueryCursorRectangle = true; + SalExtTextInputPosEvent aPosEvent; + m_rFrame.CallCallback(SalEvent::ExtTextInputPos, &aPosEvent); + const qreal fRatio = m_rFrame.devicePixelRatioF(); + m_aImCursorRectangle.setRect(aPosEvent.mnX / fRatio, aPosEvent.mnY / fRatio, + aPosEvent.mnWidth / fRatio, + aPosEvent.mnHeight / fRatio); + m_bInInputMethodQueryCursorRectangle = false; + } + return QVariant(m_aImCursorRectangle); } case Qt::ImAnchorPosition: { |