Fix possible stack overflow crash on Windows.
This commit is contained in:
parent
14cc3ff52b
commit
d5ec7cc296
2 changed files with 34 additions and 2 deletions
|
|
@ -7,6 +7,7 @@
|
||||||
#include "ui/widgets/time_input.h"
|
#include "ui/widgets/time_input.h"
|
||||||
|
|
||||||
#include "ui/widgets/fields/time_part_input.h"
|
#include "ui/widgets/fields/time_part_input.h"
|
||||||
|
#include "base/invoke_queued.h"
|
||||||
|
|
||||||
#include <QtCore/QRegularExpression>
|
#include <QtCore/QRegularExpression>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
@ -146,7 +147,7 @@ void TimeInput::putNext(const object_ptr<TimePart> &field, QChar ch) {
|
||||||
field->setCursorPosition(1);
|
field->setCursorPosition(1);
|
||||||
}
|
}
|
||||||
field->onTextEdited();
|
field->onTextEdited();
|
||||||
field->setFocus();
|
setFocusQueued(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeInput::erasePrevious(const object_ptr<TimePart> &field) {
|
void TimeInput::erasePrevious(const object_ptr<TimePart> &field) {
|
||||||
|
|
@ -155,7 +156,37 @@ void TimeInput::erasePrevious(const object_ptr<TimePart> &field) {
|
||||||
field->setCursorPosition(text.size() - 1);
|
field->setCursorPosition(text.size() - 1);
|
||||||
field->setText(text.mid(0, text.size() - 1));
|
field->setText(text.mid(0, text.size() - 1));
|
||||||
}
|
}
|
||||||
field->setFocus();
|
setFocusQueued(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeInput::setFocusQueued(const object_ptr<TimePart> &field) {
|
||||||
|
// There was a "Stack Overflow" crash in some input method handling.
|
||||||
|
//
|
||||||
|
// See https://github.com/telegramdesktop/tdesktop/issues/25129
|
||||||
|
//
|
||||||
|
// The stack is something like:
|
||||||
|
//
|
||||||
|
// ...
|
||||||
|
// QApplicationPrivate::sendMouseEvent
|
||||||
|
// ----
|
||||||
|
// QWidget::setFocus
|
||||||
|
// QWindow::focusObjectChanged
|
||||||
|
// QWindowsInputContext::setFocusObject
|
||||||
|
// QWindowsInputContext::reset
|
||||||
|
// QLineEdit::inputMethodEvent
|
||||||
|
// QWidgetLineControl::finishChange
|
||||||
|
// QLineEdit::textEdited
|
||||||
|
// MaskedInputField::onTextEdited
|
||||||
|
// TimePart::correctValue
|
||||||
|
// TimeInput::putNext
|
||||||
|
// ----
|
||||||
|
// QWidget::setFocus
|
||||||
|
// QWindow::focusObjectChanged
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// So we try to break this loop by focusing the widget async.
|
||||||
|
const auto raw = field.data();
|
||||||
|
InvokeQueued(raw, [raw] { raw->setFocus(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TimeInput::setFocusFast() {
|
bool TimeInput::setFocusFast() {
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ private:
|
||||||
void setInnerFocus();
|
void setInnerFocus();
|
||||||
void putNext(const object_ptr<TimePart> &field, QChar ch);
|
void putNext(const object_ptr<TimePart> &field, QChar ch);
|
||||||
void erasePrevious(const object_ptr<TimePart> &field);
|
void erasePrevious(const object_ptr<TimePart> &field);
|
||||||
|
void setFocusQueued(const object_ptr<TimePart> &field);
|
||||||
void setErrorShown(bool error);
|
void setErrorShown(bool error);
|
||||||
void setFocused(bool focused);
|
void setFocused(bool focused);
|
||||||
void startBorderAnimation();
|
void startBorderAnimation();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue