Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3954,7 +3954,34 @@ void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
if (_menu->empty()) {
_menu = nullptr;
} else {
_menu->popup(e->globalPos());
// A keyboard-invoked event carries the center of an empty input
// method rect for a position, which may sit nowhere near the row -
// anchor the menu under the selected row instead, at the position
// showPeerMenu computes for the events it synthesizes.
const auto rowBottom = [&] {
if (_state == WidgetState::Default) {
if (_selected) {
return _selected->top() + _selected->height();
}
} else if (_state == WidgetState::Filtered) {
if (base::in_range(_filteredSelected, 0, _filterResults.size())) {
const auto &result = _filterResults[_filteredSelected];
return filteredOffset() + result.top + result.row->height();
} else if (base::in_range(_previewSelected, 0, _previewResults.size())) {
return previewOffset() + (_previewSelected + 1) * _st->height;
} else if (base::in_range(_searchedSelected, 0, _searchResults.size())) {
return searchedOffset() + (_searchedSelected + 1) * _st->height;
}
}
return -1;
}();
const auto &padding = st::defaultDialogRow.padding;
const auto position = (fromMouse || rowBottom < 0)
? e->globalPos()
: mapToGlobal(QPoint(
width() - padding.right(),
rowBottom + padding.bottom()));
_menu->popup(position);
e->accept();
}
}
Expand Down Expand Up @@ -5763,7 +5790,15 @@ bool InnerWidget::chooseRow(
? &st::mediaPlayerMenuCheck
: nullptr);
}
_menu->popup(QCursor::pos());
// The filter link is chosen with Enter as well as with a click, and
// there is no event here to tell them apart - anchor the menu on the
// link itself, which is where a click's cursor sits anyway.
const auto left = width()
- _chatTypeFilterWidth
- 2 * st::searchedBarPosition.x();
_menu->popup(mapToGlobal(QPoint(
left + _chatTypeFilterWidth / 2,
searchedOffset() - st::searchedBarHeight / 2)));
return true;
}
const auto modifyChosenRow = [&](
Expand Down
31 changes: 31 additions & 0 deletions Telegram/SourceFiles/history/history_inner_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2748,6 +2748,37 @@ HistoryView::SelectedQuote HistoryInner::selectedQuote(
}

void HistoryInner::contextMenuEvent(QContextMenuEvent *e) {
// A keyboard-invoked event carries the center of an empty input method
// rect for a position, which may sit nowhere near the focused message -
// rebuild the event anchored on it, so everything in showContextMenu
// reading the event position (the menu, the reactions selector) lands
// on the message.
if (e->reason() == QContextMenuEvent::Keyboard
&& _accessibilityFocusedItem) {
const auto top = itemTop(_accessibilityFocusedItem);
const auto view = _accessibilityFocusedItem->mainView();
if (top >= 0 && view) {
auto rect = QRect(0, top, width(), view->height());
const auto visible = QRect(
0,
_visibleAreaTop,
width(),
_visibleAreaBottom - _visibleAreaTop);
if (rect.intersects(visible)) {
rect = rect.intersected(visible);
}
const auto global = Ui::ContextMenuPosition(this, e, rect);
auto adjusted = QContextMenuEvent(
QContextMenuEvent::Keyboard,
mapFromGlobal(global),
global);
showContextMenu(&adjusted);
if (adjusted.isAccepted()) {
e->accept();
}
return;
}
}
showContextMenu(e);
}

Expand Down
31 changes: 31 additions & 0 deletions Telegram/SourceFiles/history/view/history_view_list_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3942,6 +3942,37 @@ void ListWidget::validateTrippleClickStartTime() {
}

void ListWidget::contextMenuEvent(QContextMenuEvent *e) {
// A keyboard-invoked event carries the center of an empty input method
// rect for a position, which may sit nowhere near the focused message -
// rebuild the event anchored on it, so everything in showContextMenu
// reading the event position (the menu, the reactions selector) lands
// on the message.
if (e->reason() == QContextMenuEvent::Keyboard
&& _accessibilityFocusedItem) {
const auto view = viewForItem(_accessibilityFocusedItem);
const auto top = view ? itemTop(view) : -1;
if (view && top >= 0) {
auto rect = QRect(0, top, width(), view->height());
const auto visible = QRect(
0,
_visibleTop,
width(),
_visibleBottom - _visibleTop);
if (rect.intersects(visible)) {
rect = rect.intersected(visible);
}
const auto global = Ui::ContextMenuPosition(this, e, rect);
auto adjusted = QContextMenuEvent(
QContextMenuEvent::Keyboard,
mapFromGlobal(global),
global);
showContextMenu(&adjusted);
if (adjusted.isAccepted()) {
e->accept();
}
return;
}
}
showContextMenu(e);
}

Expand Down
Loading