Planned maintenance has been done but it did not solve the problem. So work will continue on this and a new time for trying updates will be announced asap.

Strange mouse press events in lower right corner of window widgets Mac only



  • Hi!
    Inside a QApplication, I want to create non resizable QMainwindow. I don't want the widget to be resizable by the built-in Qt way (meaning, I don't want the size grip to show up and let the user resize the Window). Now the problem: When I press in the lower right corner of the new window, my mouse press events don't come in as expected (when the mouse is pressed), but rather, when the mouse is released. This does not happen, when I press anywhere else on the window, i.e. the mouse press event shows when I actually press the mouse. See attached example code.
    I am using Qt 5.12.0 and my OS version is 10.14.3. It seems to happen only on Mac OS
    Does anybody know what I might be doing wrong? Or maybe there is a workaround?
    Kind regards
    Konrad

    #include <QApplication>
    #include <QMainWindow>
    #include <iostream>
    
    //Reproduction:
    //Press mouse in the new window in the lower right corner. The press mouse event print will show up on mouse release, not on mouse press. This only happens in the lower right corner.
    
    class MainWindow : public QMainWindow
    {
    public:
        explicit MainWindow(QWidget *parent = nullptr) :
            QMainWindow(parent)
        {
            //this will get rid of the size grip widget showing
            setFixedSize(500, 500);
        }
    
        void mousePressEvent(QMouseEvent *) override
        {
            // When your mouse is in the lower right corner, tthis will print not when you press, but when you RELEASE the mouse
            std::cout<<"mouse pressed"<<std::endl;
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    
    


  • In case anybody is wondering: this also happens with Qt 5.12.1.



  • @KonradGl
    Hi,
    I tried your code in Windows 10 with Qt 5.12.0 but it seems to work well.

    class NonResizeableWidget : public QWidget
    {
    using QWidget::QWidget;
    // QWidget interface
    protected:
    void mousePressEvent(QMouseEvent *) override
    {
    qDebug() << "mouse pressed";
    }

    void mouseReleaseEvent(QMouseEvent *) override
    {
        qDebug() << "mouse released";
    }
    

    };



  • @CP71 🙏 I was suspecting that it's a Mac only issue :-/


  • Lifetime Qt Champion

    Hi,

    Why not use setFixedSize ?



  • @SGaist Thanks for looking over the code! I did however use your suggestion in the first place. See:

    //this will get rid of the size grip widget showing
            nonResizeableWidget->setFixedSize(300, 300);
    

    Maybe I misunderstood?


  • Lifetime Qt Champion

    Not my bad, I missed that line.

    I've tested with this:

    #include <QApplication>
    #include <QWidgets>
    
    int main(int argc, char * argv[])
    {
        QApplication app(argc, argv);
        QWidget widget(0, Qt::Dialog);
        widget.setFixedSize(300, 300);
        widget.show();
        return app.exec();
    }
    

    And it's working as expected.



  • @SGaist Hm.... I don't see from your code any mouse press event override. How would you know if it works as expected? The problem I am experiencing is the actual event that triggers the mouse press event in the lower right corner of the new widget. Compile my code and set a breakpoint on the widget's mouse press function. If you are on Mac, you will see that only in the lower right corner mouse press happens when you release the mouse. If you would also override mouse release you could also see that mouse release event is sent directly after mouse press, also when you release the mouse. If you press anywhere else in the widget, everything works as expected. I hope I made my problem more clear now? Thank you very much for taking the time!


  • Lifetime Qt Champion

    Therese's none because there's no need for any.

    You overwrite methods but don't even call the base class implementation so it's expected that "surprising" behaviour happens.


  • Moderators

    @KonradGl
    I can somewhat reproduce that,

    for me the entire lower part of the window reacts to the Mouse event only on release, But pressed and released are coming, but only on mouse release.

    strange, and I did pass on the event.

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    protected:
        virtual void mousePressEvent(QMouseEvent *);
        virtual void mouseReleaseEvent(QMouseEvent *);
    };
    
    #endif // MAINWINDOW_H
    
    
    -----
    #include "mainwindow.h"
    #include <QDebug>
    #include <QTime>
    
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        setFixedSize(500,500);
    }
    
    MainWindow::~MainWindow()
    {
    
    }
    
    void MainWindow::mousePressEvent(QMouseEvent *e)
    {
        QMainWindow::mousePressEvent(e);
        qDebug() << "Mouse Pressed" << QTime::currentTime();
    }
    
    void MainWindow::mouseReleaseEvent(QMouseEvent *e)
    {
        QMainWindow::mouseReleaseEvent(e);
        qDebug() << "Mouse Released" << QTime::currentTime();
    }
    
    

    Also true for QWidget not only QMainWindow



  • @J.Hilk Thanks for confirming! And you are right in both ways. In fact, I did stumble upon this while using a QWidget. I really think this has to be a bug, so I filed a bug report https://bugreports.qt.io/browse/QTBUG-74023
    I was hoping that anybody knew some workaround... Or maybe even something that I missed entirely. I really need those mouse events passed to the methods properly...



  • @SGaist Thank you for still taking the time. I wanted to create a minimum working example to reproduce the bug. As you can see from another post, the behaviour is not changed in the slightest when you call the base class's implementation. I do really need to override my window's mouse press events. Also, if anybody is wondering, the same behaviour can be observed, when you install an event filter on that widget and look for any mouse press events. Strange stuff...



  • @J.Hilk

    for me the entire lower part of the window reacts to the Mouse event only on release
    

    Hm... I just tested again, but this really only happens for me in the lower right corner, not the entire lower part. That's why I was suspecting some hidden resizing functionality to be spooking around.



  • We found a solution to that bug. The Cocoa window itself isn't set to non resizeable.
    If you do this, everything works as expected.

    class MainWindow : public QMainWindow
    {
    public:
        explicit MainWindow(QWidget *parent = nullptr) :
            QMainWindow(parent)
        {
            //this will get rid of the size grip widget showing
            setFixedSize(500, 500);
        }
    
        void mousePressEvent(QMouseEvent *) override
        {
            std::cout<<"mouse pressed"<<std::endl;
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        NSWindow* window = [(NSView*)w.window()->winId() window];
    //IMTPORTANT. Otherwise the lower right mouse events will not be passed on correctly by cocoa
        window.styleMask &= ~NSWindowStyleMaskResizable;
    
        w.show();
    
        return a.exec();
    }