Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to get proper position for createStandardContextMenu for actions that are sensitive to the position where the user clicked inside customContextMenuRequested handler?
Qt 6.12 LTS is out! See what's new in the release blog

How to get proper position for createStandardContextMenu for actions that are sensitive to the position where the user clicked inside customContextMenuRequested handler?

Scheduled Pinned Locked Moved Unsolved General and Desktop
19 Posts 3 Posters 3.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Christian EhrlicherC Christian Ehrlicher

    @Rian-Firth said in How to get proper position for createStandardContextMenu for actions that are sensitive to the position where the user clicked inside customContextMenuRequested handler?:

    qDebug() << viewport->mapToGlobal(pos);

    That's the correct one.

    R Offline
    R Offline
    Rian Firth
    wrote on last edited by Rian Firth
    #5

    @Christian-Ehrlicher viewport->mapToGlobal(pos) returns screen position [0-1366; 0-768] but createStandardContextMenu(const QPoint &pos) takes local position of scrollarea [0-areaWidth; 0-areaHeight].

    As I already said, for example, if viewport has [500; 200] size but the whole document in QTextBrowser (scrollarea itself) is way more in size [500; 2000], vertical scrollbar will be created and createStandardContextMenu(const QPoint &pos) have to take coordinates [500; 2000] but not [500; 200] or [1366; 768].

    1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #6

      Please post some code where we can see what you're really doing. From your post above you see that viewport->mapToGlobal(pos); returns the same screen coordinates no matter if you scroll or not. Now you're telling me it does not work - this does not match.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      R 2 Replies Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        Please post some code where we can see what you're really doing. From your post above you see that viewport->mapToGlobal(pos); returns the same screen coordinates no matter if you scroll or not. Now you're telling me it does not work - this does not match.

        R Offline
        R Offline
        Rian Firth
        wrote on last edited by
        #7

        @Christian-Ehrlicher I don't understand. I've already posted the code.
        That's how literally it is now:

        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
            , ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
            ui->textBrowser->setContextMenuPolicy(Qt::CustomContextMenu);
        
            connect(ui->textBrowser, &QTextBrowser::customContextMenuRequested, this, &MainWindow::OnShowContextMenu);
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        
        void MainWindow::OnShowContextMenu(const QPoint& pos)
        {
            QMenu* menu = ui->textBrowser->createStandardContextMenu(pos);
            QAction* defaultCopyLink = menu->actions()[1];
        
            auto viewport = ui->textBrowser->viewport();
            qDebug() << viewport->mapToGlobal(pos);
            qDebug() << viewport->mapFromGlobal(pos);
            qDebug() << viewport->mapToParent(pos);
            qDebug() << viewport->mapFromParent(pos);
            qDebug() << viewport->mapTo(ui->textBrowser, pos);
            qDebug() << viewport->mapFrom(ui->textBrowser, pos);
        
            connect(defaultCopyLink, &QAction::triggered, [](){
                auto clipboard = QApplication::clipboard();
                clipboard->setText("prefix." + clipboard->text());
            });
        
            menu->exec(ui->textBrowser->mapToGlobal(pos));
            delete menu;
        }
        

        Yes, I see that viewport->mapToGlobal(pos); returns the same screen coordinates no matter if I scroll or not. And it makes sense because it's screen coordinates, it's not related to scroll area anyhow. But I don't need screen coordinates. createStandardContextMenu doesn't take screen position.
        Passing screen position from viewport->mapToGlobal(pos); to createStandardContextMenu doesn't work. Actions that are sensitive to the position where the user clicked ("Copy Link Location") won't work like that.

        Sorry if I'm confusing you.
        Please, tell me if you need anything else, I'll try my best.

        1 Reply Last reply
        0
        • Christian EhrlicherC Christian Ehrlicher

          Please post some code where we can see what you're really doing. From your post above you see that viewport->mapToGlobal(pos); returns the same screen coordinates no matter if you scroll or not. Now you're telling me it does not work - this does not match.

          R Offline
          R Offline
          Rian Firth
          wrote on last edited by Rian Firth
          #8

          @Christian-Ehrlicher I created handler for customContextMenuRequested signal so I could create my own QMenu for QTextBrowser:

          MainWindow::MainWindow(QWidget *parent)
              : QMainWindow(parent)
              , ui(new Ui::MainWindow)
          {
              ui->setupUi(this);
          
              ui->textBrowser->setContextMenuPolicy(Qt::CustomContextMenu);
              connect(ui->textBrowser, &QTextBrowser::customContextMenuRequested, this, &MainWindow::OnShowContextMenu);
          }
          
          void MainWindow::OnShowContextMenu(const QPoint& pos)
          {
              QMenu* menu = ui->textBrowser->createStandardContextMenu(pos);
              menu->exec(ui->textBrowser->mapToGlobal(pos));
              delete menu;
          }
          

          createStandardContextMenu just creates standard menu for QTextBrowser:

          Copy
          Copy Link Location
          ------------------
          Select All
          

          But this code doesn't work properly because I'm passing pos from OnShowContextMenu(const QPoint& pos) function like this createStandardContextMenu(pos). So "Copy Link Location" action from menu doesn't work when I'm trying to right click on any link in QTextBrowser when I scrolled down.
          a98da421-a787-44d9-a720-9fbb552dfd53-image.png

          The problem is that:

          The position pos is the position of the context menu event that the widget receives. Normally this is in widget coordinates. The exception to this rule is QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport().
          

          QTextBrowser is a subclass of QAbstractScrollArea so pos is just in viewport() coordinates which is [0-vpWidth;0-vpHeight].
          But createStandardContextMenu needs coordinates [0-scrollAreaWidth;0-scrollAreaHeight]. I might be calling it wrong but by scrollArea I mean the whole document that is in QTextBrowser.

          1 Reply Last reply
          0
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by mrjj
            #9

            Hi
            just call createStandardContextMenu with the translated pos :)

            void MainWindow::OnShowContextMenu(const QPoint& pos)
            {
                QPoint globalPos = ui->textBrowser->mapToGlobal(pos);
                QMenu* menu = ui->textBrowser->createStandardContextMenu(globalPos); <<<<
                QAction* defaultCopyLink = menu->actions()[1];
            
                auto viewport = ui->textBrowser->viewport();
                qDebug() << viewport->mapToGlobal(pos);
                qDebug() << viewport->mapFromGlobal(pos);
                qDebug() << viewport->mapToParent(pos);
                qDebug() << viewport->mapFromParent(pos);
                qDebug() << viewport->mapTo(ui->textBrowser, pos);
                qDebug() << viewport->mapFrom(ui->textBrowser, pos);
            
                connect(defaultCopyLink, &QAction::triggered, [](){
                    auto clipboard = QApplication::clipboard();
                    clipboard->setText("prefix." + clipboard->text());
                });
            
                menu->exec(globalPos);
                delete menu;
            
            

            alt text

            R 1 Reply Last reply
            2
            • mrjjM mrjj

              Hi
              just call createStandardContextMenu with the translated pos :)

              void MainWindow::OnShowContextMenu(const QPoint& pos)
              {
                  QPoint globalPos = ui->textBrowser->mapToGlobal(pos);
                  QMenu* menu = ui->textBrowser->createStandardContextMenu(globalPos); <<<<
                  QAction* defaultCopyLink = menu->actions()[1];
              
                  auto viewport = ui->textBrowser->viewport();
                  qDebug() << viewport->mapToGlobal(pos);
                  qDebug() << viewport->mapFromGlobal(pos);
                  qDebug() << viewport->mapToParent(pos);
                  qDebug() << viewport->mapFromParent(pos);
                  qDebug() << viewport->mapTo(ui->textBrowser, pos);
                  qDebug() << viewport->mapFrom(ui->textBrowser, pos);
              
                  connect(defaultCopyLink, &QAction::triggered, [](){
                      auto clipboard = QApplication::clipboard();
                      clipboard->setText("prefix." + clipboard->text());
                  });
              
                  menu->exec(globalPos);
                  delete menu;
              
              

              alt text

              R Offline
              R Offline
              Rian Firth
              wrote on last edited by Rian Firth
              #10

              @mrjj I just literally copied your example but it doesn't work for me even when I don't scroll down. :c

              746ec745-382b-44c8-be73-8b7e27189023-image.png

              mrjjM 1 Reply Last reply
              0
              • R Rian Firth

                @mrjj I just literally copied your example but it doesn't work for me even when I don't scroll down. :c

                746ec745-382b-44c8-be73-8b7e27189023-image.png

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #11

                @Rian-Firth
                Hi
                I just used your code.
                I did check it calls your QAction::triggered lambda and all seems ok.

                This is Qt 5.15.1 on windows.

                And we are 100% sure those are actual links ?
                If you click them page is changed ?

                R 1 Reply Last reply
                0
                • mrjjM mrjj

                  @Rian-Firth
                  Hi
                  I just used your code.
                  I did check it calls your QAction::triggered lambda and all seems ok.

                  This is Qt 5.15.1 on windows.

                  And we are 100% sure those are actual links ?
                  If you click them page is changed ?

                  R Offline
                  R Offline
                  Rian Firth
                  wrote on last edited by Rian Firth
                  #12

                  @mrjj it's not about QAction::triggered lambda. It's about that my "Copy Link Location" is not even highlighted when I right click on any link. So I can't even press "Copy Link Location". Basically it has the same behavior when you press in any empty space: you can't press it and it's gray (not highlighted) as if it's disabled. And it's like this even if you click on links.

                  They're 100% actual links and if I click on them page is changed (becomes empty).

                  mrjjM 1 Reply Last reply
                  0
                  • R Rian Firth

                    @mrjj it's not about QAction::triggered lambda. It's about that my "Copy Link Location" is not even highlighted when I right click on any link. So I can't even press "Copy Link Location". Basically it has the same behavior when you press in any empty space: you can't press it and it's gray (not highlighted) as if it's disabled. And it's like this even if you click on links.

                    They're 100% actual links and if I click on them page is changed (becomes empty).

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #13

                    @Rian-Firth
                    Hi
                    I understand the issue that Copy Link is not enabled. ( so it can't be clicked)

                    Ok so could be a platform thing as it clearly works here.

                    What Qt version and platform are you on?

                    Would it be possible to zip your project and paste link here ?
                    I could then run it and if that still dont work its something else that Qt version/ platform.

                    R 1 Reply Last reply
                    0
                    • Christian EhrlicherC Online
                      Christian EhrlicherC Online
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #14

                      @mrjj said in How to get proper position for createStandardContextMenu for actions that are sensitive to the position where the user clicked inside customContextMenuRequested handler?:

                      createStandardContextMenu

                      this function needs local coordinates: "This function creates the standard context menu which is shown when the user clicks on the text edit with the right mouse button. It is called from the default contextMenuEvent() handler and it takes the position in document coordinates where the mouse click was. This can enable actions that are sensitive to the position where the user clicked. The popup menu's ownership is transferred to the caller."

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      2
                      • mrjjM mrjj

                        @Rian-Firth
                        Hi
                        I understand the issue that Copy Link is not enabled. ( so it can't be clicked)

                        Ok so could be a platform thing as it clearly works here.

                        What Qt version and platform are you on?

                        Would it be possible to zip your project and paste link here ?
                        I could then run it and if that still dont work its something else that Qt version/ platform.

                        R Offline
                        R Offline
                        Rian Firth
                        wrote on last edited by
                        #15

                        @mrjj I've tried it on 5.12.9 and 5.15.1, Windows 10.
                        Here you are: https://mega.nz/file/Ik8x1SZS#I6UpE-M-1nWurI1KgUN6esbgcYdpfxh88rPTkLVbUZM

                        1 Reply Last reply
                        0
                        • Christian EhrlicherC Online
                          Christian EhrlicherC Online
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on last edited by Christian Ehrlicher
                          #16
                          
                          void MainWindow::OnShowContextMenu(const QPoint& pos)
                          {
                              QMenu* menu = ui->textBrowser->createStandardContextMenu(pos);
                          

                          'Normally this is in widget coordinates'
                          ...
                          'and it takes the position in document coordinates where the mouse click was'

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          R 1 Reply Last reply
                          0
                          • Christian EhrlicherC Christian Ehrlicher
                            
                            void MainWindow::OnShowContextMenu(const QPoint& pos)
                            {
                                QMenu* menu = ui->textBrowser->createStandardContextMenu(pos);
                            

                            'Normally this is in widget coordinates'
                            ...
                            'and it takes the position in document coordinates where the mouse click was'

                            R Offline
                            R Offline
                            Rian Firth
                            wrote on last edited by
                            #17

                            @Christian-Ehrlicher true. How to get that position in document coordinates considering scrolling tho.

                            1 Reply Last reply
                            0
                            • Christian EhrlicherC Online
                              Christian EhrlicherC Online
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on last edited by Christian Ehrlicher
                              #18

                              Ok, now I've a problem or we found a bug. Looks like createStandardContextMenu(QPoint) is not adding the viewport offset. anchorAt() and cursorForPosition() are doing right.
                              Here the working code (only adjusted y, x must be done the same)

                              void MainWindow::OnShowContextMenu(const QPoint& pos)
                              {
                                  QPoint p = pos;
                                  p.ry() += ui->textBrowser->verticalScrollBar()->value();
                                  qDebug() << p;
                                  QMenu* menu = ui->textBrowser->createStandardContextMenu(p);
                              

                              /edit: and no bug report for this... strange
                              /edit2: Using actions()[1] is not good - better search the object with menu->qFindChild<QAction*>("link-copy")
                              /edit3: at least it was known (also not fixed/explained how to fix it by yourself): https://codereview.qt-project.org/c/qt/qtbase/+/105486
                              /edit4: https://bugreports.qt.io/browse/QTBUG-89439

                              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                              Visit the Qt Academy at https://academy.qt.io/catalog

                              R 1 Reply Last reply
                              3
                              • Christian EhrlicherC Christian Ehrlicher

                                Ok, now I've a problem or we found a bug. Looks like createStandardContextMenu(QPoint) is not adding the viewport offset. anchorAt() and cursorForPosition() are doing right.
                                Here the working code (only adjusted y, x must be done the same)

                                void MainWindow::OnShowContextMenu(const QPoint& pos)
                                {
                                    QPoint p = pos;
                                    p.ry() += ui->textBrowser->verticalScrollBar()->value();
                                    qDebug() << p;
                                    QMenu* menu = ui->textBrowser->createStandardContextMenu(p);
                                

                                /edit: and no bug report for this... strange
                                /edit2: Using actions()[1] is not good - better search the object with menu->qFindChild<QAction*>("link-copy")
                                /edit3: at least it was known (also not fixed/explained how to fix it by yourself): https://codereview.qt-project.org/c/qt/qtbase/+/105486
                                /edit4: https://bugreports.qt.io/browse/QTBUG-89439

                                R Offline
                                R Offline
                                Rian Firth
                                wrote on last edited by
                                #19

                                @Christian-Ehrlicher thank you so much for workaround, menu->qFindChild<QAction*>("link-copy") advise and bug report!

                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt
                                • Unsolved