mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Fix possible crash in CalendarBox.
If month change notification was posted async there was a possibility to get a mousePressEvent() with already new Context field values, but with old _selected value. Those two could be inconsistent leading to an assert violation in (_selected + _context->daysShift() >= 0).
This commit is contained in:
parent
80bb6b65a7
commit
de8de84a33
1 changed files with 39 additions and 17 deletions
|
@ -117,11 +117,6 @@ void CalendarBox::Context::showMonth(QDate month) {
|
|||
}
|
||||
|
||||
void CalendarBox::Context::applyMonth(const QDate &month, bool forced) {
|
||||
if (forced) {
|
||||
_month.setForced(month);
|
||||
} else {
|
||||
_month.set(month);
|
||||
}
|
||||
_daysCount = month.daysInMonth();
|
||||
_daysShift = daysShiftForMonth(month);
|
||||
_rowsCount = rowsCountForMonth(month);
|
||||
|
@ -130,6 +125,11 @@ void CalendarBox::Context::applyMonth(const QDate &month, bool forced) {
|
|||
_highlightedIndex = month.daysTo(_highlighted);
|
||||
_minDayIndex = _min.isNull() ? INT_MIN : month.daysTo(_min);
|
||||
_maxDayIndex = _max.isNull() ? INT_MAX : month.daysTo(_max);
|
||||
if (forced) {
|
||||
_month.setForced(month, true);
|
||||
} else {
|
||||
_month.set(month, true);
|
||||
}
|
||||
}
|
||||
|
||||
void CalendarBox::Context::skipMonth(int skip) {
|
||||
|
@ -219,6 +219,7 @@ protected:
|
|||
|
||||
private:
|
||||
void monthChanged(QDate month);
|
||||
void setSelected(int selected);
|
||||
void setPressed(int pressed);
|
||||
|
||||
int rowsLeft() const;
|
||||
|
@ -239,16 +240,21 @@ private:
|
|||
|
||||
};
|
||||
|
||||
CalendarBox::Inner::Inner(QWidget *parent, Context *context) : TWidget(parent)
|
||||
CalendarBox::Inner::Inner(QWidget *parent, Context *context)
|
||||
: TWidget(parent)
|
||||
, _context(context) {
|
||||
setMouseTracking(true);
|
||||
subscribe(context->month(), [this](QDate month) { monthChanged(month); });
|
||||
subscribe(context->month(), [this](QDate month) {
|
||||
monthChanged(month);
|
||||
});
|
||||
}
|
||||
|
||||
void CalendarBox::Inner::monthChanged(QDate month) {
|
||||
setSelected(kEmptySelection);
|
||||
_ripples.clear();
|
||||
resizeToCurrent();
|
||||
update();
|
||||
sendSynteticMouseEvent(this, QEvent::MouseMove, Qt::NoButton);
|
||||
}
|
||||
|
||||
void CalendarBox::Inner::resizeToCurrent() {
|
||||
|
@ -343,19 +349,33 @@ void CalendarBox::Inner::paintRows(Painter &p, QRect clip) {
|
|||
}
|
||||
|
||||
void CalendarBox::Inner::mouseMoveEvent(QMouseEvent *e) {
|
||||
auto point = e->pos();
|
||||
auto row = floorclamp(point.y() - rowsTop(), st::calendarCellSize.height(), 0, _context->rowsCount());
|
||||
auto col = floorclamp(point.x() - rowsLeft(), st::calendarCellSize.width(), 0, kDaysInWeek);
|
||||
auto index = row * kDaysInWeek + col - _context->daysShift();
|
||||
if (_context->isEnabled(index)) {
|
||||
_selected = index;
|
||||
setCursor(style::cur_pointer);
|
||||
const auto size = st::calendarCellSize;
|
||||
const auto point = e->pos();
|
||||
const auto inner = QRect(
|
||||
rowsLeft(),
|
||||
rowsTop(),
|
||||
kDaysInWeek * size.width(),
|
||||
_context->rowsCount() * size.height());
|
||||
if (inner.contains(point)) {
|
||||
const auto row = (point.y() - rowsTop()) / size.height();
|
||||
const auto col = (point.x() - rowsLeft()) / size.width();
|
||||
const auto index = row * kDaysInWeek + col - _context->daysShift();
|
||||
setSelected(index);
|
||||
} else {
|
||||
_selected = kEmptySelection;
|
||||
setCursor(style::cur_default);
|
||||
setSelected(kEmptySelection);
|
||||
}
|
||||
}
|
||||
|
||||
void CalendarBox::Inner::setSelected(int selected) {
|
||||
if (selected != kEmptySelection && !_context->isEnabled(selected)) {
|
||||
selected = kEmptySelection;
|
||||
}
|
||||
_selected = selected;
|
||||
setCursor((_selected == kEmptySelection)
|
||||
? style::cur_default
|
||||
: style::cur_pointer);
|
||||
}
|
||||
|
||||
void CalendarBox::Inner::mousePressEvent(QMouseEvent *e) {
|
||||
setPressed(_selected);
|
||||
if (_selected != kEmptySelection) {
|
||||
|
@ -400,7 +420,9 @@ CalendarBox::Inner::~Inner() = default;
|
|||
|
||||
class CalendarBox::Title : public TWidget, private base::Subscriber {
|
||||
public:
|
||||
Title(QWidget *parent, Context *context) : TWidget(parent), _context(context) {
|
||||
Title(QWidget *parent, Context *context)
|
||||
: TWidget(parent)
|
||||
, _context(context) {
|
||||
subscribe(_context->month(), [this](QDate date) { monthChanged(date); });
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue