mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-06-13 04:11:39 -05:00
Add option to check for mouse button press
Implemented only for Windows for now.
This commit is contained in:
parent
f7afb9c446
commit
ea826f1be0
|
|
@ -119,9 +119,13 @@ AdvSceneSwitcher.condition.audio.entry="{{checkType}} of {{audioSources}} is {{c
|
|||
AdvSceneSwitcher.condition.cursor="Cursor"
|
||||
AdvSceneSwitcher.condition.cursor.type.region="is in region"
|
||||
AdvSceneSwitcher.condition.cursor.type.moving="is moving"
|
||||
AdvSceneSwitcher.condition.cursor.type.click="clicked"
|
||||
AdvSceneSwitcher.condition.cursor.button.left="Left mouse button"
|
||||
AdvSceneSwitcher.condition.cursor.button.middle="Middle mouse button"
|
||||
AdvSceneSwitcher.condition.cursor.button.right="Right mouse button"
|
||||
AdvSceneSwitcher.condition.cursor.showFrame="Show frame"
|
||||
AdvSceneSwitcher.condition.cursor.hideFrame="Hide frame"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line1="Cursor is {{conditions}} {{minX}} {{minY}} {{maxX}} {{maxY}} - {{toggleFrameButton}}"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line1="Cursor is {{conditions}}{{buttons}}{{minX}}{{minY}}{{maxX}}{{maxY}}{{toggleFrameButton}}"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line2="Cursor is currently at {{xPos}} x {{yPos}}"
|
||||
AdvSceneSwitcher.condition.scene="Scene"
|
||||
AdvSceneSwitcher.condition.scene.type.current="Current scene is"
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@ AdvSceneSwitcher.macroTab.minimize="Minimizar"
|
|||
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Resaltar macros ejecutadas recientemente"
|
||||
AdvSceneSwitcher.macroTab.highlightTrueConditions="Resaltar condiciones de la macro seleccionada, que se evaluaron como verdaderas recientemente"
|
||||
AdvSceneSwitcher.macroTab.highlightPerformedActions="Resaltar acciones realizadas recientemente de la macro seleccionada actualmente"
|
||||
AdvSceneSwitcher.macroTab.disableHotkeys="Registre teclas de acceso rápido para controlar el estado de pausa de la macro seleccionada"
|
||||
|
||||
; Lógica de macros
|
||||
AdvSceneSwitcher.logic.none="Omitir entrada"
|
||||
|
|
@ -111,7 +110,7 @@ AdvSceneSwitcher.condition.cursor.type.region="está en la región"
|
|||
AdvSceneSwitcher.condition.cursor.type.moving="se está moviendo"
|
||||
AdvSceneSwitcher.condition.cursor.showFrame="Mostrar cuadro"
|
||||
AdvSceneSwitcher.condition.cursor.hideFrame="Ocultar cuadro"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line1="El cursor es {{conditions}} {{minX}} {{minY}} {{maxX}} {{maxY}} - {{toggleFrameButton}}"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line1="El cursor es {{conditions}}{{buttons}}{{minX}}{{minY}}{{maxX}}{{maxY}}{{toggleFrameButton}}"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line2="El cursor se encuentra actualmente en {{xPos}} x {{yPos}}"
|
||||
AdvSceneSwitcher.condition.scene="Escena"
|
||||
AdvSceneSwitcher.condition.scene.type.current="La escena actual es"
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ AdvSceneSwitcher.condition.cursor.type.region="alanında"
|
|||
AdvSceneSwitcher.condition.cursor.type.moving="hareketlidir"
|
||||
AdvSceneSwitcher.condition.cursor.showFrame="Çerçeveyi Göster"
|
||||
AdvSceneSwitcher.condition.cursor.hideFrame="Çerçeveyi Gizle"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line1="İmleç {{conditions}} {{minX}} {{minY}} {{maxX}} {{maxY}} - {{toggleFrameButton}}"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line1="İmleç {{conditions}}{{buttons}}{{minX}}{{minY}}{{maxX}}{{maxY}}{{toggleFrameButton}}"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line2="İmleç şuanda {{xPos}} x {{yPos}}"
|
||||
AdvSceneSwitcher.condition.scene="Sahne"
|
||||
AdvSceneSwitcher.condition.scene.type.current="Mevcut Sahne"
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ AdvSceneSwitcher.condition.cursor.type.region="当前位置"
|
|||
AdvSceneSwitcher.condition.cursor.type.moving="正在移动"
|
||||
AdvSceneSwitcher.condition.cursor.showFrame="显示帧率"
|
||||
AdvSceneSwitcher.condition.cursor.hideFrame="隐藏帧率"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line1="鼠标 处于{{conditions}} {{minX}} {{minY}} {{maxX}} {{maxY}} - {{toggleFrameButton}}"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line1="鼠标 处于{{conditions}}{{buttons}}{{minX}}{{minY}}{{maxX}}{{maxY}}{{toggleFrameButton}}"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line2="鼠标当前位于 {{xPos}} x {{yPos}}"
|
||||
AdvSceneSwitcher.condition.scene="场景"
|
||||
AdvSceneSwitcher.condition.scene.type.current="当前场景是"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "platform-funcs.hpp"
|
||||
#include "hotkey.hpp"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
|
@ -46,6 +47,10 @@ static XScreenSaverAllocInfoFunc allocSSFunc = nullptr;
|
|||
static XScreenSaverQueryInfoFunc querySSFunc = nullptr;
|
||||
bool canGetIdleTime = false;
|
||||
|
||||
std::chrono::high_resolution_clock::time_point lastMouseLeftClickTime{};
|
||||
std::chrono::high_resolution_clock::time_point lastMouseMiddleClickTime{};
|
||||
std::chrono::high_resolution_clock::time_point lastMouseRightClickTime{};
|
||||
|
||||
Display *disp()
|
||||
{
|
||||
if (!xdisplay) {
|
||||
|
|
|
|||
|
|
@ -10,32 +10,65 @@ bool MacroConditionCursor::_registered = MacroConditionFactory::Register(
|
|||
{MacroConditionCursor::Create, MacroConditionCursorEdit::Create,
|
||||
"AdvSceneSwitcher.condition.cursor"});
|
||||
|
||||
static std::map<CursorCondition, std::string> cursorConditionTypes = {
|
||||
{CursorCondition::REGION,
|
||||
"AdvSceneSwitcher.condition.cursor.type.region"},
|
||||
{CursorCondition::MOVING,
|
||||
"AdvSceneSwitcher.condition.cursor.type.moving"},
|
||||
static std::map<MacroConditionCursor::Condition, std::string>
|
||||
cursorConditionTypes = {
|
||||
{MacroConditionCursor::Condition::REGION,
|
||||
"AdvSceneSwitcher.condition.cursor.type.region"},
|
||||
{MacroConditionCursor::Condition::MOVING,
|
||||
"AdvSceneSwitcher.condition.cursor.type.moving"},
|
||||
#ifdef _WIN32 // Not implemented for MacOS and Linux
|
||||
{MacroConditionCursor::Condition::CLICK,
|
||||
"AdvSceneSwitcher.condition.cursor.type.click"},
|
||||
#endif
|
||||
};
|
||||
|
||||
static std::map<MacroConditionCursor::Button, std::string> buttonTypes = {
|
||||
{MacroConditionCursor::Button::LEFT,
|
||||
"AdvSceneSwitcher.condition.cursor.button.left"},
|
||||
{MacroConditionCursor::Button::MIDDLE,
|
||||
"AdvSceneSwitcher.condition.cursor.button.middle"},
|
||||
{MacroConditionCursor::Button::RIGHT,
|
||||
"AdvSceneSwitcher.condition.cursor.button.right"},
|
||||
};
|
||||
|
||||
bool MacroConditionCursor::CheckClick()
|
||||
{
|
||||
switch (_button) {
|
||||
case MacroConditionCursor::Button::LEFT:
|
||||
return _lastCheckTime < lastMouseLeftClickTime;
|
||||
case MacroConditionCursor::Button::MIDDLE:
|
||||
return _lastCheckTime < lastMouseMiddleClickTime;
|
||||
case MacroConditionCursor::Button::RIGHT:
|
||||
return _lastCheckTime < lastMouseRightClickTime;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MacroConditionCursor::CheckCondition()
|
||||
{
|
||||
bool ret = false;
|
||||
std::pair<int, int> cursorPos = getCursorPos();
|
||||
switch (_condition) {
|
||||
case CursorCondition::REGION:
|
||||
return cursorPos.first >= _minX && cursorPos.second >= _minY &&
|
||||
cursorPos.first <= _maxX && cursorPos.second <= _maxY;
|
||||
case CursorCondition::MOVING:
|
||||
return switcher->cursorPosChanged;
|
||||
default:
|
||||
case Condition::REGION:
|
||||
ret = cursorPos.first >= _minX && cursorPos.second >= _minY &&
|
||||
cursorPos.first <= _maxX && cursorPos.second <= _maxY;
|
||||
break;
|
||||
case Condition::MOVING:
|
||||
ret = switcher->cursorPosChanged;
|
||||
break;
|
||||
case Condition::CLICK:
|
||||
ret = CheckClick();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
_lastCheckTime = std::chrono::high_resolution_clock::now();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool MacroConditionCursor::Save(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
obs_data_set_int(obj, "button", static_cast<int>(_button));
|
||||
obs_data_set_int(obj, "minX", _minX);
|
||||
obs_data_set_int(obj, "minY", _minY);
|
||||
obs_data_set_int(obj, "maxX", _maxX);
|
||||
|
|
@ -46,8 +79,8 @@ bool MacroConditionCursor::Save(obs_data_t *obj)
|
|||
bool MacroConditionCursor::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_condition = static_cast<CursorCondition>(
|
||||
obs_data_get_int(obj, "condition"));
|
||||
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||
_button = static_cast<Button>(obs_data_get_int(obj, "button"));
|
||||
_minX = obs_data_get_int(obj, "minX");
|
||||
_minY = obs_data_get_int(obj, "minY");
|
||||
_maxX = obs_data_get_int(obj, "maxX");
|
||||
|
|
@ -57,8 +90,17 @@ bool MacroConditionCursor::Load(obs_data_t *obj)
|
|||
|
||||
static inline void populateConditionSelection(QComboBox *list)
|
||||
{
|
||||
for (auto entry : cursorConditionTypes) {
|
||||
list->addItem(obs_module_text(entry.second.c_str()));
|
||||
for (const auto &[condition, name] : cursorConditionTypes) {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(condition));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void populateButtonSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[button, name] : buttonTypes) {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(button));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,14 +112,17 @@ MacroConditionCursorEdit::MacroConditionCursorEdit(
|
|||
_maxX(new QSpinBox()),
|
||||
_maxY(new QSpinBox()),
|
||||
_conditions(new QComboBox()),
|
||||
_buttons(new QComboBox()),
|
||||
_frameToggle(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.cursor.showFrame"))),
|
||||
_xPos(new QLabel("-")),
|
||||
_yPos(new QLabel("-"))
|
||||
_yPos(new QLabel("-")),
|
||||
_curentPosLayout(new QHBoxLayout())
|
||||
{
|
||||
_frame.setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
populateConditionSelection(_conditions);
|
||||
populateButtonSelection(_buttons);
|
||||
|
||||
_minX->setPrefix("Min X: ");
|
||||
_minY->setPrefix("Min Y: ");
|
||||
|
|
@ -96,6 +141,8 @@ MacroConditionCursorEdit::MacroConditionCursorEdit(
|
|||
|
||||
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(_buttons, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ButtonChanged(int)));
|
||||
QWidget::connect(_minX, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(MinXChanged(int)));
|
||||
QWidget::connect(_minY, SIGNAL(valueChanged(int)), this,
|
||||
|
|
@ -109,6 +156,7 @@ MacroConditionCursorEdit::MacroConditionCursorEdit(
|
|||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{conditions}}", _conditions},
|
||||
{"{{buttons}}", _buttons},
|
||||
{"{{minX}}", _minX},
|
||||
{"{{minY}}", _minY},
|
||||
{"{{maxX}}", _maxX},
|
||||
|
|
@ -121,13 +169,12 @@ MacroConditionCursorEdit::MacroConditionCursorEdit(
|
|||
placeWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.cursor.entry.line1"),
|
||||
line1, widgetPlaceholders);
|
||||
QHBoxLayout *line2 = new QHBoxLayout;
|
||||
placeWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.cursor.entry.line2"),
|
||||
line2, widgetPlaceholders);
|
||||
_curentPosLayout, widgetPlaceholders);
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(line1);
|
||||
mainLayout->addLayout(line2);
|
||||
mainLayout->addLayout(_curentPosLayout);
|
||||
setLayout(mainLayout);
|
||||
|
||||
connect(&_timer, &QTimer::timeout, this,
|
||||
|
|
@ -146,9 +193,20 @@ void MacroConditionCursorEdit::ConditionChanged(int index)
|
|||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_condition = static_cast<CursorCondition>(index);
|
||||
SetRegionSelectionVisible(_entryData->_condition ==
|
||||
CursorCondition::REGION);
|
||||
_entryData->_condition = static_cast<MacroConditionCursor::Condition>(
|
||||
_conditions->itemData(index).toInt());
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionCursorEdit::ButtonChanged(int index)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_button = static_cast<MacroConditionCursor::Button>(
|
||||
_buttons->itemData(index).toInt());
|
||||
}
|
||||
|
||||
void MacroConditionCursorEdit::MinXChanged(int pos)
|
||||
|
|
@ -216,17 +274,23 @@ void MacroConditionCursorEdit::ToggleFrame()
|
|||
}
|
||||
}
|
||||
|
||||
void MacroConditionCursorEdit::SetRegionSelectionVisible(bool visible)
|
||||
void MacroConditionCursorEdit::SetWidgetVisibility()
|
||||
{
|
||||
_minX->setVisible(visible);
|
||||
_minY->setVisible(visible);
|
||||
_maxX->setVisible(visible);
|
||||
_maxY->setVisible(visible);
|
||||
_frameToggle->setVisible(visible);
|
||||
const bool isRegionCondition = _entryData->_condition ==
|
||||
MacroConditionCursor::Condition::REGION;
|
||||
_minX->setVisible(isRegionCondition);
|
||||
_minY->setVisible(isRegionCondition);
|
||||
_maxX->setVisible(isRegionCondition);
|
||||
_maxY->setVisible(isRegionCondition);
|
||||
_frameToggle->setVisible(isRegionCondition);
|
||||
setLayoutVisible(_curentPosLayout, isRegionCondition);
|
||||
if (_frame.isVisible()) {
|
||||
ToggleFrame();
|
||||
}
|
||||
|
||||
_buttons->setVisible(_entryData->_condition ==
|
||||
MacroConditionCursor::Condition::CLICK);
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
|
|
@ -253,10 +317,10 @@ void MacroConditionCursorEdit::UpdateEntryData()
|
|||
}
|
||||
|
||||
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
_buttons->setCurrentIndex(static_cast<int>(_entryData->_button));
|
||||
_minX->setValue(_entryData->_minX);
|
||||
_minY->setValue(_entryData->_minY);
|
||||
_maxX->setValue(_entryData->_maxX);
|
||||
_maxY->setValue(_entryData->_maxY);
|
||||
SetRegionSelectionVisible(_entryData->_condition ==
|
||||
CursorCondition::REGION);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,6 @@
|
|||
#include <QTimer>
|
||||
#include <QFrame>
|
||||
|
||||
enum class CursorCondition {
|
||||
REGION,
|
||||
MOVING,
|
||||
};
|
||||
|
||||
class MacroConditionCursor : public MacroCondition {
|
||||
public:
|
||||
MacroConditionCursor(Macro *m) : MacroCondition(m) {}
|
||||
|
|
@ -24,10 +19,26 @@ public:
|
|||
return std::make_shared<MacroConditionCursor>(m);
|
||||
}
|
||||
|
||||
CursorCondition _condition = CursorCondition::REGION;
|
||||
enum class Condition {
|
||||
REGION,
|
||||
MOVING,
|
||||
CLICK,
|
||||
};
|
||||
|
||||
enum class Button {
|
||||
LEFT,
|
||||
MIDDLE,
|
||||
RIGHT,
|
||||
};
|
||||
|
||||
Condition _condition = Condition::REGION;
|
||||
Button _button = Button::LEFT;
|
||||
int _minX = 0, _minY = 0, _maxX = 0, _maxY = 0;
|
||||
|
||||
private:
|
||||
bool CheckClick();
|
||||
std::chrono::high_resolution_clock::time_point _lastCheckTime{};
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
|
@ -49,7 +60,8 @@ public:
|
|||
}
|
||||
|
||||
private slots:
|
||||
void ConditionChanged(int cond);
|
||||
void ConditionChanged(int idx);
|
||||
void ButtonChanged(int idx);
|
||||
void MinXChanged(int pos);
|
||||
void MinYChanged(int pos);
|
||||
void MaxXChanged(int pos);
|
||||
|
|
@ -63,13 +75,15 @@ protected:
|
|||
QSpinBox *_maxX;
|
||||
QSpinBox *_maxY;
|
||||
QComboBox *_conditions;
|
||||
QComboBox *_buttons;
|
||||
QPushButton *_frameToggle;
|
||||
QLabel *_xPos;
|
||||
QLabel *_yPos;
|
||||
QHBoxLayout *_curentPosLayout;
|
||||
std::shared_ptr<MacroConditionCursor> _entryData;
|
||||
|
||||
private:
|
||||
void SetRegionSelectionVisible(bool);
|
||||
void SetWidgetVisibility();
|
||||
void SetupFrame();
|
||||
QTimer _timer;
|
||||
QFrame _frame;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "platform-funcs.hpp"
|
||||
#include "hotkey.hpp"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
|
|
@ -14,6 +15,10 @@
|
|||
|
||||
bool canSimulateKeyPresses = false;
|
||||
|
||||
std::chrono::high_resolution_clock::time_point lastMouseLeftClickTime{};
|
||||
std::chrono::high_resolution_clock::time_point lastMouseMiddleClickTime{};
|
||||
std::chrono::high_resolution_clock::time_point lastMouseRightClickTime{};
|
||||
|
||||
void GetWindowList(std::vector<std::string> &windows)
|
||||
{
|
||||
windows.resize(0);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
#pragma once
|
||||
#include "hotkey.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <QStringList>
|
||||
#include <chrono>
|
||||
|
||||
enum class HotkeyType;
|
||||
|
||||
// TODO: Implement for MacOS and Linux
|
||||
extern std::chrono::high_resolution_clock::time_point lastMouseLeftClickTime;
|
||||
extern std::chrono::high_resolution_clock::time_point lastMouseMiddleClickTime;
|
||||
extern std::chrono::high_resolution_clock::time_point lastMouseRightClickTime;
|
||||
|
||||
void GetWindowList(std::vector<std::string> &windows);
|
||||
void GetWindowList(QStringList &windows);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "platform-funcs.hpp"
|
||||
#include "hotkey.hpp"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
|
@ -11,11 +12,22 @@
|
|||
#include <vector>
|
||||
#include <QStringList>
|
||||
#include <QRegularExpression>
|
||||
#include <obs-frontend-api.h>
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
|
||||
#define MAX_SEARCH 1000
|
||||
|
||||
// Hotkeys
|
||||
bool canSimulateKeyPresses = true;
|
||||
|
||||
// Mouse click
|
||||
class RawMouseInputFilter;
|
||||
RawMouseInputFilter *mouseInputFilter;
|
||||
std::chrono::high_resolution_clock::time_point lastMouseLeftClickTime{};
|
||||
std::chrono::high_resolution_clock::time_point lastMouseMiddleClickTime{};
|
||||
std::chrono::high_resolution_clock::time_point lastMouseRightClickTime{};
|
||||
|
||||
static bool GetWindowTitle(HWND window, std::string &title)
|
||||
{
|
||||
size_t len = (size_t)GetWindowTextLengthW(window);
|
||||
|
|
@ -446,6 +458,87 @@ int secondsSinceLastInput()
|
|||
return (getTime() - getLastInputTime()) / 1000;
|
||||
}
|
||||
|
||||
void PlatformInit() {}
|
||||
static void handleRawMouseInput(LPARAM lParam)
|
||||
{
|
||||
UINT dwSize;
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize,
|
||||
sizeof(RAWINPUTHEADER));
|
||||
LPBYTE lpb = new BYTE[dwSize];
|
||||
if (lpb == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
void PlatformCleanup() {}
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize,
|
||||
sizeof(RAWINPUTHEADER)) != dwSize)
|
||||
OutputDebugString(TEXT(
|
||||
"GetRawInputData does not return correct size !\n"));
|
||||
|
||||
RAWINPUT *raw = (RAWINPUT *)lpb;
|
||||
if (raw->header.dwType == RIM_TYPEMOUSE) {
|
||||
switch (raw->data.mouse.usButtonFlags) {
|
||||
case RI_MOUSE_BUTTON_1_DOWN:
|
||||
lastMouseLeftClickTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
break;
|
||||
case RI_MOUSE_BUTTON_3_DOWN:
|
||||
lastMouseMiddleClickTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
break;
|
||||
case RI_MOUSE_BUTTON_2_DOWN:
|
||||
lastMouseRightClickTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete[] lpb;
|
||||
}
|
||||
|
||||
class RawMouseInputFilter : public QAbstractNativeEventFilter {
|
||||
public:
|
||||
virtual bool nativeEventFilter(const QByteArray &eventType,
|
||||
void *message, qintptr *) Q_DECL_OVERRIDE
|
||||
{
|
||||
if (eventType != "windows_generic_MSG") {
|
||||
return false;
|
||||
}
|
||||
MSG *msg = reinterpret_cast<MSG *>(message);
|
||||
|
||||
if (msg->message != WM_INPUT) {
|
||||
return false;
|
||||
}
|
||||
handleRawMouseInput(msg->lParam);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
static void SetupMouseEeventFilter()
|
||||
{
|
||||
mouseInputFilter = new RawMouseInputFilter;
|
||||
QAbstractEventDispatcher::instance()->installNativeEventFilter(
|
||||
mouseInputFilter);
|
||||
|
||||
RAWINPUTDEVICE rid;
|
||||
rid.dwFlags = RIDEV_INPUTSINK;
|
||||
rid.usUsagePage = 1;
|
||||
rid.usUsage = 2;
|
||||
rid.hwndTarget = (HWND)obs_frontend_get_main_window_handle();
|
||||
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) {
|
||||
blog(LOG_WARNING, "Registering for raw mouse input failed!\n"
|
||||
"Mouse click detection not functional!");
|
||||
}
|
||||
}
|
||||
|
||||
void PlatformInit()
|
||||
{
|
||||
SetupMouseEeventFilter();
|
||||
}
|
||||
|
||||
void PlatformCleanup()
|
||||
{
|
||||
if (mouseInputFilter) {
|
||||
delete mouseInputFilter;
|
||||
mouseInputFilter = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user