mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-28 22:53:09 +00:00
Use SDL button labels so shell prompts match the connected controller instead of always using Xbox-style wording. Expose trigger rumble, touchpad count, gyro, and accelerometer support through the gamepad wrapper and surface the relevant capability labels in the overlay. Enable background gamepad events and add short rumble feedback for major shell actions such as opening quick settings, opening the exit prompt, and launching a game.
106 lines
2.7 KiB
C++
106 lines
2.7 KiB
C++
// SPDX-FileCopyrightText: 2026 Marco Allegretti
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
#pragma once
|
|
|
|
#include <QAbstractListModel>
|
|
#include <QTimer>
|
|
#include <qqmlregistration.h>
|
|
|
|
class QQmlEngine;
|
|
class QJSEngine;
|
|
class GamepadDevice;
|
|
|
|
class GamepadManager : public QAbstractListModel
|
|
{
|
|
Q_OBJECT
|
|
QML_ELEMENT
|
|
QML_SINGLETON
|
|
|
|
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
|
|
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
|
Q_PROPERTY(GamepadDevice *primaryGamepad READ primaryGamepad NOTIFY primaryGamepadChanged)
|
|
Q_PROPERTY(bool hasGamepad READ hasGamepad NOTIFY countChanged)
|
|
|
|
public:
|
|
explicit GamepadManager(QObject *parent = nullptr);
|
|
~GamepadManager() override;
|
|
|
|
static GamepadManager *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine);
|
|
|
|
enum Roles {
|
|
DeviceRole = Qt::UserRole + 1,
|
|
NameRole,
|
|
TypeRole,
|
|
BatteryRole,
|
|
};
|
|
Q_ENUM(Roles)
|
|
|
|
// Buttons matching SDL_GamepadButton, re-exported for QML
|
|
enum Button {
|
|
ButtonA,
|
|
ButtonB,
|
|
ButtonX,
|
|
ButtonY,
|
|
ButtonBack,
|
|
ButtonGuide,
|
|
ButtonStart,
|
|
ButtonLeftStick,
|
|
ButtonRightStick,
|
|
ButtonLeftShoulder,
|
|
ButtonRightShoulder,
|
|
ButtonDPadUp,
|
|
ButtonDPadDown,
|
|
ButtonDPadLeft,
|
|
ButtonDPadRight,
|
|
ButtonMisc1,
|
|
};
|
|
Q_ENUM(Button)
|
|
|
|
// Axes matching SDL_GamepadAxis
|
|
enum Axis {
|
|
AxisLeftX,
|
|
AxisLeftY,
|
|
AxisRightX,
|
|
AxisRightY,
|
|
AxisLeftTrigger,
|
|
AxisRightTrigger,
|
|
};
|
|
Q_ENUM(Axis)
|
|
|
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
QVariant data(const QModelIndex &index, int role) const override;
|
|
QHash<int, QByteArray> roleNames() const override;
|
|
|
|
bool active() const;
|
|
void setActive(bool active);
|
|
int count() const;
|
|
bool hasGamepad() const;
|
|
GamepadDevice *primaryGamepad() const;
|
|
|
|
Q_INVOKABLE GamepadDevice *gamepadAt(int index) const;
|
|
Q_INVOKABLE QString buttonLabel(int button, int gamepadIndex = -1) const;
|
|
|
|
Q_SIGNALS:
|
|
void activeChanged();
|
|
void countChanged();
|
|
void primaryGamepadChanged();
|
|
|
|
void buttonPressed(int button, int gamepadIndex);
|
|
void buttonReleased(int button, int gamepadIndex);
|
|
void axisChanged(int axis, float value, int gamepadIndex);
|
|
|
|
private:
|
|
void start();
|
|
void stop();
|
|
void poll();
|
|
void addGamepad(int instanceId);
|
|
void removeGamepad(int instanceId);
|
|
int indexForInstanceId(int instanceId) const;
|
|
|
|
bool m_active = false;
|
|
bool m_sdlInitialized = false;
|
|
int m_batteryCounter = 0;
|
|
QTimer m_pollTimer;
|
|
QList<GamepadDevice *> m_gamepads;
|
|
};
|