visit-dav / visit

VisIt - Visualization and Data Analysis for Mesh-based Scientific Data
https://visit.llnl.gov
BSD 3-Clause "New" or "Revised" License
438 stars 116 forks source link

3.4.1 doesn't work with trackpad on macOS #19506

Closed markcmiller86 closed 2 weeks ago

markcmiller86 commented 6 months ago

Describe the bug

If a trackpad is being used instead of a mouse on a macOS laptop, the viewer window will not relinquish the pointer once it acquires it. If a mouse is used instead, it will work fine.

Desktop

This is for @iulian787 and @vijaysm at ANL

BenWibking commented 6 months ago

I am also seeing this. Just commenting here for update notifications on a fix or workaround.

markcmiller86 commented 6 months ago

@BenWibking or @vijaysm, I wonder does hitting escape key when using trackpad and the pointer seems to un-stick the stuck pointer?

Also, just capturing some notes from ChatGPT...

It sounds like your Qt application might be handling mouse events in a way that interferes with how trackpad events are managed on macOS. Here are a few steps and considerations to help you diagnose and potentially fix the issue:

  1. Check Event Handling: Verify how your application handles mouse events. If your application uses custom mouse event handling (e.g., overriding mousePressEvent, mouseReleaseEvent, mouseMoveEvent), ensure that events are being properly passed to the base class when not explicitly handled. For example:

    void MyWidget::mousePressEvent(QMouseEvent *event) {
        if (event->button() == Qt::LeftButton) {
            // Handle left button
        } else {
            QWidget::mousePressEvent(event); // Pass other events to the base class
        }
    }
  2. Focus Policy: Make sure the focus policy of the widgets is correctly set. A widget must accept focus to properly handle keyboard and mouse events. You can set the focus policy in the constructor or using the setFocusPolicy() method.

    setFocusPolicy(Qt::StrongFocus);
  3. Event Propagation: Check if mouse events are being stopped from propagating correctly in your application. If any widget consumes the mouse events without passing them to its parent, this might lead to unexpected behavior.

  4. Grabbing the Mouse: If your application explicitly grabs the mouse input (using grabMouse()), ensure it releases it appropriately with releaseMouse(). An incorrect or missing release call could explain why the application retains control of the pointer.

    grabMouse();
    // Later
    releaseMouse();
  5. Debugging: Add logging to the event handling methods to see how events are being processed when using the trackpad versus an external mouse. This might reveal differences in event sequences or types.

  6. Qt Version and macOS Compatibility: Verify that you are using a version of Qt that supports the version of macOS you are targeting. Sometimes, bugs or incompatibilities are specific to certain combinations of Qt and macOS versions. Checking the Qt release notes or forums might provide insights or patches.

  7. macOS-Specific Behavior: Since this issue is specific to macOS, look into whether macOS-specific flags or configurations are needed. For example, check if Qt's macOS-specific integration documentation suggests any configurations for trackpad support.

If you've checked these areas and the issue persists, it might be helpful to look into minimal reproducible examples and see if the problem occurs in a simpler context. Additionally, checking forums or filing a bug report with the Qt project, including details of your setup and code snippets, could also provide further assistance.

BenWibking commented 6 months ago

@BenWibking or @vijaysm, I wonder does hitting escape key when using trackpad and the pointer seems to un-stick the stuck pointer?

That didn't seem to help for me.

cyrush commented 5 months ago

@biagas suggests auditing the plugins built with qt6 to make sure those match the install. We should compare the release binaries with development build.

markcmiller86 commented 3 weeks ago

Looks like it could be down in VTK's Qt stuff, https://gitlab.kitware.com/vtk/vtk/-/issues/19073

markcmiller86 commented 3 weeks ago

https://discourse.vtk.org/t/qt6-vtk9-objects-always-rotating/9658

markcmiller86 commented 3 weeks ago

This seems like the issue or closely related down in bowesl of Qt, https://bugreports.qt.io/browse/QTBUG-77125?jql=text%20~%20%22trackpad%22

markcmiller86 commented 3 weeks ago

I instrumented src/viewer/main/viewer.C like so...

QString getEventTypeName(QEvent::Type type) {
    const QMetaObject &mo = QEvent::staticMetaObject;
    int index = mo.indexOfEnumerator("Type");
    QMetaEnum metaEnum = mo.enumerator(index);
    return metaEnum.valueToKey(type);
}

class EventFilter : public QObject {
protected:
    bool eventFilter(QObject *obj, QEvent *event) override {
        std::cerr << "Event type: " << getEventTypeName(event->type()).toStdString() << std::endl;
        if (event->type() == QEvent::MouseButtonPress ||
            event->type() == QEvent::MouseButtonRelease) {
            QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
            if (mouseEvent->buttons() == Qt::NoButton)
                std::cerr << "NO BUTTON" << std::endl;
        }
        return QObject::eventFilter(obj, event);
    }
};

And then installed the filter just after the lines instantiating the main QApplication...

            mainApp = new QCoreApplication(argc2, argv2);

with

        EventFilter *filter = new EventFilter();
        mainApp->installEventFilter(filter);

This appears to catch all the events in the viewer window and reports them. I then ran....

./bin/visit -o ../../data/silo_pdb_test_data/globe.silo >& junk.out

running once with a mouse and a second time with the trackpad. I just put up a mesh plot, rotate it a tad and then exit. I saved the event streams to two different .txt files...

events_with_trackpad.txt.gz events_with_mouse.txt.gz

Of course, I am not a robot and so the exact sequence of events are certainly not identical. But, diffing the two files sheds some light. There are TouchBegin, TouchEnd and TouchUpdate events in the trackpad log that are not in the mouse log.

On an entirely different front, I noticed that once the viewer is stuck on the trackpad, we see Timer events that never stop. That doesn't happen with the mouse. Also, I always see events in threes. Three MouseButtonPress events followed by three MouseButtonRelease events.

markcmiller86 commented 3 weeks ago

Ok, I have a hack that fixes this. Since we don't really handle Touch events, I just filter them out and the problem goes away...

class EventFilter : public QObject {
protected:
    bool eventFilter(QObject *obj, QEvent *event) override {
        switch (event->type()) {
            case QEvent::TouchBegin:
            case QEvent::TouchEnd:
            case QEvent::TouchUpdate:
                // Return true to indicate the event should be ignored
                return true;
            default:
                // Pass other events along in the event system
                return QObject::eventFilter(obj, event);
        }
        return QObject::eventFilter(obj, event);
    }
};

@visit-dav/visit-developers I am curious if other people have thoughts on wholly ignore the Touch kind of events on mac? Am wondering if @BradWhitlock might have opinions too.