Merge pull request #14118 from luiscuenca/handTouchLMFix

Disable Hand Touch when Leap Motion is running
This commit is contained in:
John Conklin II 2018-10-03 09:03:43 -07:00 committed by GitHub
commit 8bd8d05409
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 92 additions and 19 deletions

View file

@ -1061,6 +1061,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
auto controllerScriptingInterface = DependencyManager::get<controller::ScriptingInterface>().data();
_controllerScriptingInterface = dynamic_cast<ControllerScriptingInterface*>(controllerScriptingInterface);
connect(PluginManager::getInstance().data(), &PluginManager::inputDeviceRunningChanged,
controllerScriptingInterface, &controller::ScriptingInterface::updateRunningInputDevices);
_entityClipboard->createRootElement();

View file

@ -178,6 +178,17 @@ namespace controller {
return inputRecorder->getSaveDirectory();
}
QStringList ScriptingInterface::getRunningInputDeviceNames() {
QMutexLocker locker(&_runningDevicesMutex);
return _runningInputDeviceNames;
}
void ScriptingInterface::updateRunningInputDevices(const QString& deviceName, bool isRunning, const QStringList& runningDevices) {
QMutexLocker locker(&_runningDevicesMutex);
_runningInputDeviceNames = runningDevices;
emit inputDeviceRunningChanged(deviceName, isRunning);
}
bool ScriptingInterface::triggerHapticPulseOnDevice(unsigned int device, float strength, float duration, controller::Hand hand) const {
return DependencyManager::get<UserInputMapper>()->triggerHapticPulseOnDevice(device, strength, duration, hand);
}

View file

@ -26,6 +26,7 @@
#include <QThread>
#include <QtCore/QObject>
#include <QtCore/QVariant>
#include <QMutex>
#include <QtQml/QJSValue>
#include <QtScript/QScriptValue>
@ -431,6 +432,13 @@ namespace controller {
*/
Q_INVOKABLE QString getInputRecorderSaveDirectory();
/**jsdoc
* Get all the active and enabled (running) input devices
* @function Controller.getRunningInputDevices
* @returns {string[]} An array of strings with the names
*/
Q_INVOKABLE QStringList getRunningInputDeviceNames();
bool isMouseCaptured() const { return _mouseCaptured; }
bool isTouchCaptured() const { return _touchCaptured; }
bool isWheelCaptured() const { return _wheelCaptured; }
@ -531,6 +539,8 @@ namespace controller {
*/
virtual void releaseActionEvents() { _actionsCaptured = false; }
void updateRunningInputDevices(const QString& deviceName, bool isRunning, const QStringList& runningDevices);
signals:
/**jsdoc
* Triggered when an action occurs.
@ -590,6 +600,17 @@ namespace controller {
*/
void hardwareChanged();
/**jsdoc
* Triggered when a device is enabled/disabled
* Enabling/Disabling Leapmotion on settings/controls will trigger this signal.
* @function Controller.deviceRunningChanged
* @param {string} deviceName - The name of the device that is getting enabled/disabled
* @param {boolean} isEnabled - Return if the device is enabled.
* @returns {Signal}
*/
void inputDeviceRunningChanged(QString deviceName, bool isRunning);
private:
// Update the exposed variant maps reporting active hardware
void updateMaps();
@ -598,10 +619,14 @@ namespace controller {
QVariantMap _actions;
QVariantMap _standard;
QStringList _runningInputDeviceNames;
std::atomic<bool> _mouseCaptured{ false };
std::atomic<bool> _touchCaptured { false };
std::atomic<bool> _wheelCaptured { false };
std::atomic<bool> _actionsCaptured { false };
QMutex _runningDevicesMutex;
};
}

View file

@ -75,8 +75,11 @@ public:
virtual void saveSettings() const {}
virtual void loadSettings() {}
virtual bool isRunning() const { return _active; }
signals:
void deviceStatusChanged(const QString& deviceName, bool isRunning) const;
// These signals should be emitted when a device is first known to be available. In some cases this will
// be in `init()`, in other cases, like Neuron, this isn't known until activation.
// SDL2 isn't a device itself, but can have 0+ subdevices. subdeviceConnected is used in this case.
@ -85,6 +88,7 @@ signals:
protected:
bool _active { false };
bool _enabled { false };
bool _sessionStatus { false };
PluginContainer* _container { nullptr };
static const char* UNKNOWN_PLUGIN_ID;

View file

@ -225,8 +225,11 @@ void PluginManager::disableDisplayPlugin(const QString& name) {
const InputPluginList& PluginManager::getInputPlugins() {
static std::once_flag once;
static auto deviceAddedCallback = [](QString deviceName) {
static auto deviceAddedCallback = [&](QString deviceName) {
qCDebug(plugins) << "Added device: " << deviceName;
QStringList runningDevices = getRunningInputDeviceNames();
bool isDeviceRunning = runningDevices.indexOf(deviceName) >= 0;
emit inputDeviceRunningChanged(deviceName, isDeviceRunning, runningDevices);
UserActivityLogger::getInstance().connectedDevice("input", deviceName);
};
static auto subdeviceAddedCallback = [](QString pluginName, QString deviceName) {
@ -252,6 +255,9 @@ const InputPluginList& PluginManager::getInputPlugins() {
for (auto plugin : _inputPlugins) {
connect(plugin.get(), &Plugin::deviceConnected, this, deviceAddedCallback, Qt::QueuedConnection);
connect(plugin.get(), &Plugin::subdeviceConnected, this, subdeviceAddedCallback, Qt::QueuedConnection);
connect(plugin.get(), &Plugin::deviceStatusChanged, this, [&](const QString& deviceName, bool isRunning) {
emit inputDeviceRunningChanged(deviceName, isRunning, getRunningInputDeviceNames());
}, Qt::QueuedConnection);
plugin->setContainer(_container);
plugin->init();
}
@ -259,6 +265,16 @@ const InputPluginList& PluginManager::getInputPlugins() {
return _inputPlugins;
}
QStringList PluginManager::getRunningInputDeviceNames() const {
QStringList runningDevices;
for (auto plugin: _inputPlugins) {
if (plugin->isRunning()) {
runningDevices << plugin->getName();
}
}
return runningDevices;
}
void PluginManager::setPreferredDisplayPlugins(const QStringList& displays) {
preferredDisplayPlugins = displays;
}

View file

@ -19,6 +19,7 @@ using PluginManagerPointer = QSharedPointer<PluginManager>;
class PluginManager : public QObject, public Dependency {
SINGLETON_DEPENDENCY
Q_OBJECT
public:
static PluginManagerPointer getInstance();
@ -44,6 +45,10 @@ public:
void setInputPluginProvider(const InputPluginProvider& provider);
void setCodecPluginProvider(const CodecPluginProvider& provider);
void setInputPluginSettingsPersister(const InputPluginSettingsPersister& persister);
QStringList getRunningInputDeviceNames() const;
signals:
void inputDeviceRunningChanged(const QString& pluginName, bool isRunning, const QStringList& runningDevices);
private:
PluginManager() = default;

View file

@ -21,7 +21,7 @@
Q_DECLARE_LOGGING_CATEGORY(inputplugins)
Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins")
const char* LeapMotionPlugin::NAME = "Leap Motion";
const char* LeapMotionPlugin::NAME = "LeapMotion";
const char* LeapMotionPlugin::LEAPMOTION_ID_STRING = "Leap Motion";
const bool DEFAULT_ENABLED = false;
@ -203,7 +203,6 @@ static const char* getControllerJointName(controller::StandardPoseChannel i) {
return "unknown";
}
void LeapMotionPlugin::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
if (!_enabled) {
return;
@ -312,13 +311,13 @@ void LeapMotionPlugin::InputDevice::update(float deltaTime, const controller::In
void LeapMotionPlugin::init() {
loadSettings();
auto preferences = DependencyManager::get<Preferences>();
static const QString LEAPMOTION_PLUGIN { "Leap Motion" };
{
auto getter = [this]()->bool { return _enabled; };
auto setter = [this](bool value) {
_enabled = value;
emit deviceStatusChanged(getName(), isRunning());
saveSettings();
if (!_enabled) {
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
@ -406,6 +405,7 @@ void LeapMotionPlugin::loadSettings() {
settings.beginGroup(idString);
{
_enabled = settings.value(SETTINGS_ENABLED_KEY, QVariant(DEFAULT_ENABLED)).toBool();
emit deviceStatusChanged(getName(), isRunning());
_sensorLocation = settings.value(SETTINGS_SENSOR_LOCATION_KEY, QVariant(DEFAULT_SENSOR_LOCATION)).toString();
_desktopHeightOffset =
settings.value(SETTINGS_DESKTOP_HEIGHT_OFFSET_KEY, QVariant(DEFAULT_DESKTOP_HEIGHT_OFFSET)).toFloat();

View file

@ -30,7 +30,7 @@ public:
// Plugin methods
virtual const QString getName() const override { return NAME; }
const QString getID() const override { return LEAPMOTION_ID_STRING; }
bool isRunning() const override { return _active && _enabled; }
virtual void init() override;
virtual bool activate() override;
@ -43,8 +43,6 @@ protected:
static const char* NAME;
static const char* LEAPMOTION_ID_STRING;
const float DEFAULT_DESKTOP_HEIGHT_OFFSET = 0.2f;
bool _enabled { false };
QString _sensorLocation;
float _desktopHeightOffset { DEFAULT_DESKTOP_HEIGHT_OFFSET };

View file

@ -369,7 +369,11 @@ void NeuronPlugin::init() {
static const QString NEURON_PLUGIN { "Perception Neuron" };
{
auto getter = [this]()->bool { return _enabled; };
auto setter = [this](bool value) { _enabled = value; saveSettings(); };
auto setter = [this](bool value) {
_enabled = value;
saveSettings();
emit deviceStatusChanged(getName(), _enabled && _active);
};
auto preference = new CheckPreference(NEURON_PLUGIN, "Enabled", getter, setter);
preferences->addPreference(preference);
}
@ -493,7 +497,7 @@ void NeuronPlugin::loadSettings() {
{
// enabled
_enabled = settings.value("enabled", QVariant(DEFAULT_ENABLED)).toBool();
emit deviceStatusChanged(getName(), _enabled && _active);
// serverAddress
_serverAddress = settings.value("serverAddress", QVariant(DEFAULT_SERVER_ADDRESS)).toString();

View file

@ -30,7 +30,7 @@ public:
virtual bool isSupported() const override;
virtual const QString getName() const override { return NAME; }
const QString getID() const override { return NEURON_ID_STRING; }
bool isRunning() const override { return _active && _enabled; }
virtual bool activate() override;
virtual void deactivate() override;
@ -67,7 +67,6 @@ protected:
static const char* NAME;
static const char* NEURON_ID_STRING;
bool _enabled;
QString _serverAddress;
int _serverPort;
void* _socketRef;

View file

@ -79,10 +79,11 @@ bool SDL2Manager::activate() {
auto preferences = DependencyManager::get<Preferences>();
static const QString SDL2_PLUGIN { "Game Controller" };
{
auto getter = [this]()->bool { return _isEnabled; };
auto getter = [this]()->bool { return _enabled; };
auto setter = [this](bool value) {
_isEnabled = value;
_enabled = value;
saveSettings();
emit deviceStatusChanged(getName(), isRunning());
};
auto preference = new CheckPreference(SDL2_PLUGIN, "Enabled", getter, setter);
preferences->addPreference(preference);
@ -147,7 +148,7 @@ void SDL2Manager::saveSettings() const {
QString idString = getID();
settings.beginGroup(idString);
{
settings.setValue(QString(SETTINGS_ENABLED_KEY), _isEnabled);
settings.setValue(QString(SETTINGS_ENABLED_KEY), _enabled);
}
settings.endGroup();
}
@ -157,7 +158,8 @@ void SDL2Manager::loadSettings() {
QString idString = getID();
settings.beginGroup(idString);
{
_isEnabled = settings.value(SETTINGS_ENABLED_KEY, QVariant(DEFAULT_ENABLED)).toBool();
_enabled = settings.value(SETTINGS_ENABLED_KEY, QVariant(DEFAULT_ENABLED)).toBool();
emit deviceStatusChanged(getName(), isRunning());
}
settings.endGroup();
}
@ -173,7 +175,7 @@ void SDL2Manager::pluginFocusOutEvent() {
}
void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
if (!_isEnabled) {
if (!_enabled) {
return;
}

View file

@ -26,7 +26,7 @@ public:
bool isSupported() const override;
const QString getName() const override { return NAME; }
const QString getID() const override { return SDL2_ID_STRING; }
bool isRunning() const override { return _active && _enabled; }
QStringList getSubdeviceNames() override;
void init() override;
@ -81,7 +81,6 @@ private:
int buttonRelease() const { return SDL_RELEASED; }
QMap<SDL_JoystickID, Joystick::Pointer> _openJoysticks;
bool _isEnabled { false };
bool _isInitialized { false };
static const char* NAME;
static const char* SDL2_ID_STRING;

View file

@ -16,7 +16,9 @@
(function () {
var LEAP_MOTION_NAME = "LeapMotion";
var handTouchEnabled = true;
var leapMotionEnabled = Controller.getRunningInputDeviceNames().indexOf(LEAP_MOTION_NAME) >= 0;
var MSECONDS_AFTER_LOAD = 2000;
var updateFingerWithIndex = 0;
var untouchableEntities = [];
@ -870,6 +872,12 @@
handTouchEnabled = !shouldDisable;
});
Controller.inputDeviceRunningChanged.connect(function (deviceName, isEnabled) {
if (deviceName == LEAP_MOTION_NAME) {
leapMotionEnabled = isEnabled;
}
});
MyAvatar.disableHandTouchForIDChanged.connect(function (entityID, disable) {
var entityIndex = untouchableEntities.indexOf(entityID);
if (disable) {
@ -902,7 +910,7 @@
Script.update.connect(function () {
if (!handTouchEnabled) {
if (!handTouchEnabled || leapMotionEnabled) {
return;
}