diff options
Diffstat (limited to 'src/yuzu')
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 71 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.h | 10 | 
2 files changed, 73 insertions, 8 deletions
| diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 4e4c108ab..e8ab23326 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -110,6 +110,7 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)      std::string window_title = fmt::format("yuzu {} | {}-{}", Common::g_build_name,                                             Common::g_scm_branch, Common::g_scm_desc);      setWindowTitle(QString::fromStdString(window_title)); +    setAttribute(Qt::WA_AcceptTouchEvents);      InputCommon::Init();      InputCommon::StartJoystickEventHandler(); @@ -190,11 +191,17 @@ QByteArray GRenderWindow::saveGeometry() {          return geometry;  } -qreal GRenderWindow::windowPixelRatio() { +qreal GRenderWindow::windowPixelRatio() const {      // windowHandle() might not be accessible until the window is displayed to screen.      return windowHandle() ? windowHandle()->screen()->devicePixelRatio() : 1.0f;  } +std::pair<unsigned, unsigned> GRenderWindow::ScaleTouch(const QPointF pos) const { +    const qreal pixel_ratio = windowPixelRatio(); +    return {static_cast<unsigned>(std::max(std::round(pos.x() * pixel_ratio), qreal{0.0})), +            static_cast<unsigned>(std::max(std::round(pos.y() * pixel_ratio), qreal{0.0}))}; +} +  void GRenderWindow::closeEvent(QCloseEvent* event) {      emit Closed();      QWidget::closeEvent(event); @@ -209,31 +216,81 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {  }  void GRenderWindow::mousePressEvent(QMouseEvent* event) { +    if (event->source() == Qt::MouseEventSynthesizedBySystem) +        return; // touch input is handled in TouchBeginEvent +      auto pos = event->pos();      if (event->button() == Qt::LeftButton) { -        qreal pixelRatio = windowPixelRatio(); -        this->TouchPressed(static_cast<unsigned>(pos.x() * pixelRatio), -                           static_cast<unsigned>(pos.y() * pixelRatio)); +        const auto [x, y] = ScaleTouch(pos); +        this->TouchPressed(x, y);      } else if (event->button() == Qt::RightButton) {          InputCommon::GetMotionEmu()->BeginTilt(pos.x(), pos.y());      }  }  void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { +    if (event->source() == Qt::MouseEventSynthesizedBySystem) +        return; // touch input is handled in TouchUpdateEvent +      auto pos = event->pos(); -    qreal pixelRatio = windowPixelRatio(); -    this->TouchMoved(std::max(static_cast<unsigned>(pos.x() * pixelRatio), 0u), -                     std::max(static_cast<unsigned>(pos.y() * pixelRatio), 0u)); +    const auto [x, y] = ScaleTouch(pos); +    this->TouchMoved(x, y);      InputCommon::GetMotionEmu()->Tilt(pos.x(), pos.y());  }  void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { +    if (event->source() == Qt::MouseEventSynthesizedBySystem) +        return; // touch input is handled in TouchEndEvent +      if (event->button() == Qt::LeftButton)          this->TouchReleased();      else if (event->button() == Qt::RightButton)          InputCommon::GetMotionEmu()->EndTilt();  } +void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) { +    // TouchBegin always has exactly one touch point, so take the .first() +    const auto [x, y] = ScaleTouch(event->touchPoints().first().pos()); +    this->TouchPressed(x, y); +} + +void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) { +    QPointF pos; +    int active_points = 0; + +    // average all active touch points +    for (const auto tp : event->touchPoints()) { +        if (tp.state() & (Qt::TouchPointPressed | Qt::TouchPointMoved | Qt::TouchPointStationary)) { +            active_points++; +            pos += tp.pos(); +        } +    } + +    pos /= active_points; + +    const auto [x, y] = ScaleTouch(pos); +    this->TouchMoved(x, y); +} + +void GRenderWindow::TouchEndEvent() { +    this->TouchReleased(); +} + +bool GRenderWindow::event(QEvent* event) { +    if (event->type() == QEvent::TouchBegin) { +        TouchBeginEvent(static_cast<QTouchEvent*>(event)); +        return true; +    } else if (event->type() == QEvent::TouchUpdate) { +        TouchUpdateEvent(static_cast<QTouchEvent*>(event)); +        return true; +    } else if (event->type() == QEvent::TouchEnd || event->type() == QEvent::TouchCancel) { +        TouchEndEvent(); +        return true; +    } + +    return QWidget::event(event); +} +  void GRenderWindow::focusOutEvent(QFocusEvent* event) {      QWidget::focusOutEvent(event);      InputCommon::GetKeyboard()->ReleaseAllKeys(); diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index f133bfadf..873985564 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -15,6 +15,7 @@  class QKeyEvent;  class QScreen; +class QTouchEvent;  class GGLWidgetInternal;  class GMainWindow; @@ -119,7 +120,7 @@ public:      void restoreGeometry(const QByteArray& geometry); // overridden      QByteArray saveGeometry();                        // overridden -    qreal windowPixelRatio(); +    qreal windowPixelRatio() const;      void closeEvent(QCloseEvent* event) override; @@ -130,6 +131,8 @@ public:      void mouseMoveEvent(QMouseEvent* event) override;      void mouseReleaseEvent(QMouseEvent* event) override; +    bool event(QEvent* event) override; +      void focusOutEvent(QFocusEvent* event) override;      void OnClientAreaResized(unsigned width, unsigned height); @@ -148,6 +151,11 @@ signals:      void Closed();  private: +    std::pair<unsigned, unsigned> ScaleTouch(const QPointF pos) const; +    void TouchBeginEvent(const QTouchEvent* event); +    void TouchUpdateEvent(const QTouchEvent* event); +    void TouchEndEvent(); +      void OnMinimalClientAreaChangeRequest(          const std::pair<unsigned, unsigned>& minimal_size) override; | 
