Skip to content

Copy Text on a rich message with a table copies the word "Table" #31209

Description

@dev-aly3n

Steps to reproduce

  1. Get a rich message containing a table into a chat, for example from a bot using sendRichMessage.
  2. Right click the message and choose Copy Text. Do not select any text first.
  3. Paste into any plain text editor.

Expected behaviour

The table contents, rows and cells. Selecting the table by hand and copying already gives that, so both ways of copying should end up the same.

Actual behaviour

The clipboard contains the literal word "Table" instead of the contents.

Pasting into a rich target such as Word or a browser gives the correct grid, so only the text/plain flavour is wrong. Selecting the table with the mouse and copying is also correct. It is only whole message copy that breaks.

The same happens for other block kinds. A photo comes out as "Photo", a video as "Video".

From reading the source, for a rich message the item text is the chat list summary, history_item.cpp:520,560,2769,2783:

setText(Iv::FlattenRichPageSummary(richPage));

AppendSummaryBlock at iv_rich_page.cpp:2237 renders a table as tr::lng_in_dlg_table ("Table") and never reads block.tableRows. That is correct for a chat list row and wrong for a clipboard.

HistoryItem::clipboardText() at history_item.cpp:4004 has no rich page case, so it returns that summary. Whole message copy then calls SetRichBlocksClipboard(HistoryItemText(item), ...) at history_view_context_menu.cpp:1897 and history_inner_widget.cpp:4058, which builds correct HTML from the blocks but takes text/plain from the summary it was handed.

Selection copy is correct because it uses a different route. Message::selectedText at history_view_message.cpp:5022 goes through article.textForSelection, reaching CopyTextForTable in iv_markdown_article_selection.cpp:217. That one emits the caption, rows separated by newline and cells separated by tab, and resolves colspan and rowspan through BuildTableCopyGrid.

So the serializer already exists, the whole message path just does not use it.

I have a fix in mind for this. The direction would be to make whole message copy behave like select all copy, so both go through textForSelection and cannot disagree. MarkdownArticleSelection is segment based and I could not find a way to build one covering the whole article. There is no selectAll or fullSelection and no public segment count on MarkdownArticle, so that small helper looks like the missing piece.

I am ready to write this and open a PR. The only reason I am asking first is that it adds a method to MarkdownArticle, so I would rather confirm the direction is acceptable than send something you do not want. If you are happy with it, I will get it done.

Related to #31017, which reports selection problems on rich message lists. The comment there mentions this copy behaviour, filing it separately since it is a different path.

Operating system

macOS 26.5.1

Version of Telegram Desktop

7.1.3

Installation source

Downloaded from desktop.telegram.org or GitHub

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions