Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
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?

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 2.0k 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

    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 Offline
                Christian EhrlicherC Offline
                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 Offline
                    Christian EhrlicherC Offline
                    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 Offline
                        Christian EhrlicherC Offline
                        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 Extensions
                          • Unsolved