diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c3e902d..7493b46 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(alakarte gamesortfiltermodel.cpp game.cpp gamepadmanager.cpp + inputmanager.cpp mediamanager.cpp screenshotmodel.cpp platformimporter.cpp @@ -118,6 +119,7 @@ ecm_add_qml_module(alakarte URI org.kde.alakarte gamesortfiltermodel.h game.h gamepadmanager.h + inputmanager.h platformimporter.h steamimporter.h lutrisimporter.h diff --git a/src/config.h b/src/config.h index 5ec87f6..0ab65c0 100644 --- a/src/config.h +++ b/src/config.h @@ -42,7 +42,7 @@ public: enum UiMode { Auto, Desktop, - Handheld + Couch }; Q_ENUM(UiMode) diff --git a/src/inputmanager.cpp b/src/inputmanager.cpp new file mode 100644 index 0000000..d792559 --- /dev/null +++ b/src/inputmanager.cpp @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2026 A-La-Karte Contributors + +#include "inputmanager.h" + +#include "gamepadmanager.h" + +#include +#include +#include + +InputManager *InputManager::s_instance = nullptr; + +InputManager::InputManager(QObject *parent) + : QObject(parent) +{ + if (QCoreApplication::instance()) { + QCoreApplication::instance()->installEventFilter(this); + } + + auto *pad = GamepadManager::instance(); + connect(pad, &GamepadManager::activeChanged, this, [this, pad]() { + if (pad->active()) { + if (!m_hasSeenGamepad) { + m_hasSeenGamepad = true; + Q_EMIT inputHistoryChanged(); + } + setActiveInput(Gamepad); + } + }); + + connect(pad, &GamepadManager::connectedChanged, this, [this, pad]() { + if (!pad->connected() && m_activeInput == Gamepad) { + setActiveInput(KeyboardMouse); + } + }); +} + +InputManager *InputManager::instance() +{ + if (!s_instance) { + s_instance = new InputManager(); + } + return s_instance; +} + +InputManager *InputManager::create(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + return instance(); +} + +InputManager::ActiveInput InputManager::activeInput() const +{ + return m_activeInput; +} + +bool InputManager::hasSeenKeyboardMouse() const +{ + return m_hasSeenKeyboardMouse; +} + +bool InputManager::hasSeenGamepad() const +{ + return m_hasSeenGamepad; +} + +void InputManager::setActiveInput(ActiveInput input) +{ + if (m_activeInput == input) { + return; + } + + m_activeInput = input; + Q_EMIT activeInputChanged(); +} + +bool InputManager::eventFilter(QObject *watched, QEvent *event) +{ + Q_UNUSED(watched) + + if (!event) { + return false; + } + + switch (event->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::Wheel: + if (!m_hasSeenKeyboardMouse) { + m_hasSeenKeyboardMouse = true; + Q_EMIT inputHistoryChanged(); + } + setActiveInput(KeyboardMouse); + break; + default: + break; + } + + return false; +} diff --git a/src/inputmanager.h b/src/inputmanager.h new file mode 100644 index 0000000..3170b85 --- /dev/null +++ b/src/inputmanager.h @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2026 A-La-Karte Contributors + +#pragma once + +#include +#include + +class QEvent; +class QJSEngine; + +class InputManager : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + + Q_PROPERTY(ActiveInput activeInput READ activeInput NOTIFY activeInputChanged) + Q_PROPERTY(bool hasSeenKeyboardMouse READ hasSeenKeyboardMouse NOTIFY inputHistoryChanged) + Q_PROPERTY(bool hasSeenGamepad READ hasSeenGamepad NOTIFY inputHistoryChanged) + +public: + enum ActiveInput { + KeyboardMouse = 0, + Gamepad = 1, + }; + Q_ENUM(ActiveInput) + + static InputManager *instance(); + static InputManager *create(QQmlEngine *engine, QJSEngine *scriptEngine); + + ActiveInput activeInput() const; + + bool hasSeenKeyboardMouse() const; + bool hasSeenGamepad() const; + +Q_SIGNALS: + void activeInputChanged(); + void inputHistoryChanged(); + +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + explicit InputManager(QObject *parent = nullptr); + + static InputManager *s_instance; + + ActiveInput m_activeInput = KeyboardMouse; + bool m_hasSeenKeyboardMouse = false; + bool m_hasSeenGamepad = false; + + void setActiveInput(ActiveInput input); +};