Destroy InputField::Inner before InputField.

Inner has a pointer to parent and uses it assuming it is InputField.
If Inner lives longer than InputField (till ~QWidget) then in some
cases it accesses InputField as a (not completely) destroyed object.
This commit is contained in:
John Preston 2018-07-18 22:22:07 +03:00
parent c48937a2f5
commit ffd2817d18
2 changed files with 14 additions and 8 deletions

View File

@ -1137,7 +1137,7 @@ InputField::InputField(
, _mode(mode)
, _minHeight(st.heightMin)
, _maxHeight(st.heightMax)
, _inner(this)
, _inner(std::make_unique<Inner>(this))
, _lastTextWithTags(value)
, _placeholderFactory(std::move(placeholderFactory)) {
_inner->setAcceptRichText(false);
@ -1182,10 +1182,12 @@ InputField::InputField(
connect(&_touchTimer, SIGNAL(timeout()), this, SLOT(onTouchTimer()));
connect(_inner->document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(onDocumentContentsChange(int,int,int)));
connect(_inner, SIGNAL(undoAvailable(bool)), this, SLOT(onUndoAvailable(bool)));
connect(_inner, SIGNAL(redoAvailable(bool)), this, SLOT(onRedoAvailable(bool)));
connect(_inner, SIGNAL(cursorPositionChanged()), this, SLOT(onCursorPositionChanged()));
if (App::wnd()) connect(_inner, SIGNAL(selectionChanged()), App::wnd(), SLOT(updateGlobalMenu()));
connect(_inner.get(), SIGNAL(undoAvailable(bool)), this, SLOT(onUndoAvailable(bool)));
connect(_inner.get(), SIGNAL(redoAvailable(bool)), this, SLOT(onRedoAvailable(bool)));
connect(_inner.get(), SIGNAL(cursorPositionChanged()), this, SLOT(onCursorPositionChanged()));
if (App::wnd()) {
connect(_inner.get(), SIGNAL(selectionChanged()), App::wnd(), SLOT(updateGlobalMenu()));
}
const auto bar = _inner->verticalScrollBar();
_scrollTop = bar->value();
@ -2463,11 +2465,11 @@ void InputField::clearFocus() {
}
not_null<QTextEdit*> InputField::rawTextEdit() {
return _inner;
return _inner.get();
}
not_null<const QTextEdit*> InputField::rawTextEdit() const {
return _inner;
return _inner.get();
}
void InputField::keyPressEventInner(QKeyEvent *e) {
@ -3376,6 +3378,8 @@ void InputField::setErrorShown(bool error) {
}
}
InputField::~InputField() = default;
MaskedInputField::MaskedInputField(
QWidget *parent,
const style::InputField &st,

View File

@ -297,6 +297,8 @@ public:
int scrollTopMax() const;
void scrollTo(int top);
~InputField();
private slots:
void onTouchTimer();
@ -413,7 +415,7 @@ private:
bool _forcePlaceholderHidden = false;
bool _reverseMarkdownReplacement = false;
object_ptr<Inner> _inner;
const std::unique_ptr<Inner> _inner;
TextWithTags _lastTextWithTags;
std::vector<MarkdownTag> _lastMarkdownTags;