Files
z-bar-qt/Plugins/ZShell/Components/wheelinverter.hpp
T
2026-08-26 17:10:34 +02:00

91 lines
1.8 KiB
C++

#pragma once
#include <QQuickItem>
#include <QQuickWindow>
#include <QWheelEvent>
#include <QCoreApplication>
#include <QPointer>
#include <QDebug>
namespace ZShell::components {
class WheelInverter : public QQuickItem {
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(
QQuickItem* target READ target WRITE setTarget NOTIFY targetChanged)
public:
using QQuickItem::QQuickItem;
QQuickItem* target() const { return m_target; }
void setTarget(QQuickItem* target) {
if (m_target == target) return;
if (m_target) m_target->removeEventFilter(this);
m_target = target;
if (m_target) m_target->installEventFilter(this);
emit targetChanged();
}
protected:
class InvertedWheelEvent : public QWheelEvent {
public:
using QWheelEvent::QWheelEvent;
bool invertedByWheelInverter = true;
};
bool eventFilter(QObject* watched, QEvent* event) override {
if (watched != m_target || event->type() != QEvent::Wheel)
return QQuickItem::eventFilter(watched, event);
auto* wheel = static_cast<QWheelEvent*>(event);
const bool inverted = dynamic_cast<InvertedWheelEvent*>(wheel) !=
nullptr;
if (inverted) return false;
auto* window = m_target ? m_target->window() : nullptr;
if (!window) {
qInfo() << "[WheelInverter] no window";
return false;
}
const QPointF windowPos =
window->mapFromGlobal(wheel->globalPosition());
auto* invertedEvent = new InvertedWheelEvent(
windowPos,
wheel->globalPosition(),
-wheel->pixelDelta(),
-wheel->angleDelta(),
wheel->buttons(),
wheel->modifiers(),
wheel->phase(),
wheel->inverted(),
wheel->source(),
wheel->pointingDevice());
invertedEvent->setTimestamp(wheel->timestamp());
QCoreApplication::postEvent(window, invertedEvent);
return true;
}
signals:
void targetChanged();
private:
QPointer<QQuickItem> m_target;
};
} // namespace ZShell::components