mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-04-21 20:15:04 +00:00
feat: Adapt to qt6
This commit is contained in:
parent
d444f26282
commit
bdc543da31
10 changed files with 140 additions and 188 deletions
|
@ -79,11 +79,10 @@ set(CMAKE_AUTOUIC ON)
|
|||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets Network Multimedia REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Network Multimedia REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets Network Multimedia OpenGL OpenGLWidgets REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Network Multimedia OpenGL OpenGLWidgets REQUIRED)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS X11Extras REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS X11Extras REQUIRED)
|
||||
find_package(X11 REQUIRED)
|
||||
endif()
|
||||
|
||||
message(STATUS "[${PROJECT_NAME}] Qt version is: ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}")
|
||||
|
@ -310,13 +309,15 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
include_directories(${X11_INCLUDE_DIR})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
# qx11
|
||||
Qt${QT_VERSION_MAJOR}::X11Extras
|
||||
Qt${QT_VERSION_MAJOR}::CorePrivate
|
||||
# xcb https://doc.qt.io/qt-5/linux-requirements.html
|
||||
xcb
|
||||
# pthread
|
||||
${X11_LIBRARIES}
|
||||
Threads::Threads
|
||||
)
|
||||
|
||||
|
@ -334,5 +335,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
|
|||
Qt${QT_VERSION_MAJOR}::Widgets
|
||||
Qt${QT_VERSION_MAJOR}::Network
|
||||
Qt${QT_VERSION_MAJOR}::Multimedia
|
||||
Qt${QT_VERSION_MAJOR}::OpenGL
|
||||
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
|
||||
QtScrcpyCore
|
||||
)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit cb9da00b4ac4e855b6cb8a9033fe45a1fabfd05b
|
||||
Subproject commit 4ca295f2648cd41a0634d89c076908c63f3d5949
|
|
@ -1,31 +1,37 @@
|
|||
#include <QTcpSocket>
|
||||
#include <QHostAddress>
|
||||
#include <QAudioOutput>
|
||||
#include <QTime>
|
||||
#include <QAudioSink>
|
||||
#include <QMediaDevices>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include <QProcess>
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
#include <QByteArray>
|
||||
#include "audiooutput.h"
|
||||
|
||||
AudioOutput::AudioOutput(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_outputDevice(nullptr)
|
||||
, m_running(false)
|
||||
, m_audioSink(nullptr)
|
||||
{
|
||||
connect(&m_sndcpy, &QProcess::readyReadStandardOutput, this, [this]() {
|
||||
qInfo() << QString("AudioOutput::") << QString(m_sndcpy.readAllStandardOutput());
|
||||
qInfo() << QString("AudioOutput::") << m_sndcpy.readAllStandardOutput();
|
||||
});
|
||||
connect(&m_sndcpy, &QProcess::readyReadStandardError, this, [this]() {
|
||||
qInfo() << QString("AudioOutput::") << QString(m_sndcpy.readAllStandardError());
|
||||
qInfo() << QString("AudioOutput::") << m_sndcpy.readAllStandardError();
|
||||
});
|
||||
}
|
||||
|
||||
AudioOutput::~AudioOutput()
|
||||
{
|
||||
if (QProcess::NotRunning != m_sndcpy.state()) {
|
||||
if (m_sndcpy.state() != QProcess::NotRunning) {
|
||||
m_sndcpy.kill();
|
||||
}
|
||||
stop();
|
||||
}
|
||||
|
||||
bool AudioOutput::start(const QString& serial, int port)
|
||||
bool AudioOutput::start(const QString &serial, int port)
|
||||
{
|
||||
if (m_running) {
|
||||
stop();
|
||||
|
@ -36,7 +42,7 @@ bool AudioOutput::start(const QString& serial, int port)
|
|||
bool ret = runSndcpyProcess(serial, port);
|
||||
qInfo() << "AudioOutput::run sndcpy cost:" << timeConsumeCount.elapsed() << "milliseconds";
|
||||
if (!ret) {
|
||||
return ret;
|
||||
return false;
|
||||
}
|
||||
|
||||
startAudioOutput();
|
||||
|
@ -64,20 +70,15 @@ void AudioOutput::installonly(const QString &serial, int port)
|
|||
|
||||
bool AudioOutput::runSndcpyProcess(const QString &serial, int port, bool wait)
|
||||
{
|
||||
if (QProcess::NotRunning != m_sndcpy.state()) {
|
||||
if (m_sndcpy.state() != QProcess::NotRunning) {
|
||||
m_sndcpy.kill();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
QStringList params;
|
||||
params << serial;
|
||||
params << QString("%1").arg(port);
|
||||
QStringList params{serial, QString::number(port)};
|
||||
m_sndcpy.start("sndcpy.bat", params);
|
||||
#else
|
||||
QStringList params;
|
||||
params << "sndcpy.sh";
|
||||
params << serial;
|
||||
params << QString("%1").arg(port);
|
||||
QStringList params{"sndcpy.sh", serial, QString::number(port)};
|
||||
m_sndcpy.start("bash", params);
|
||||
#endif
|
||||
|
||||
|
@ -86,11 +87,11 @@ bool AudioOutput::runSndcpyProcess(const QString &serial, int port, bool wait)
|
|||
}
|
||||
|
||||
if (!m_sndcpy.waitForStarted()) {
|
||||
qWarning() << "AudioOutput::start sndcpy.bat failed";
|
||||
qWarning() << "AudioOutput::start sndcpy process failed";
|
||||
return false;
|
||||
}
|
||||
if (!m_sndcpy.waitForFinished()) {
|
||||
qWarning() << "AudioOutput::sndcpy.bat crashed";
|
||||
qWarning() << "AudioOutput::sndcpy process crashed";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -99,41 +100,39 @@ bool AudioOutput::runSndcpyProcess(const QString &serial, int port, bool wait)
|
|||
|
||||
void AudioOutput::startAudioOutput()
|
||||
{
|
||||
if (m_audioOutput) {
|
||||
if (m_audioSink) {
|
||||
return;
|
||||
}
|
||||
|
||||
QAudioFormat format;
|
||||
format.setSampleRate(48000);
|
||||
format.setChannelCount(2);
|
||||
format.setSampleSize(16);
|
||||
format.setCodec("audio/pcm");
|
||||
format.setByteOrder(QAudioFormat::LittleEndian);
|
||||
format.setSampleType(QAudioFormat::SignedInt);
|
||||
format.setSampleFormat(QAudioFormat::Int16); // 16-bit signed integer format
|
||||
|
||||
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
|
||||
if (!info.isFormatSupported(format)) {
|
||||
QAudioDevice defaultDevice = QMediaDevices::defaultAudioOutput();
|
||||
if (!defaultDevice.isFormatSupported(format)) {
|
||||
qWarning() << "AudioOutput::audio format not supported, cannot play audio.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_audioOutput = new QAudioOutput(format, this);
|
||||
connect(m_audioOutput, &QAudioOutput::stateChanged, this, [](QAudio::State state) {
|
||||
qInfo() << "AudioOutput::audio state changed:" << state;
|
||||
});
|
||||
m_audioOutput->setBufferSize(48000*2*15/1000 * 20);
|
||||
m_outputDevice = m_audioOutput->start();
|
||||
m_audioSink = new QAudioSink(defaultDevice, format, this);
|
||||
m_outputDevice = m_audioSink->start();
|
||||
if (!m_outputDevice) {
|
||||
qWarning() << "AudioOutput::failed to start audio sink.";
|
||||
delete m_audioSink;
|
||||
m_audioSink = nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioOutput::stopAudioOutput()
|
||||
{
|
||||
if (!m_audioOutput) {
|
||||
return;
|
||||
if (m_audioSink) {
|
||||
m_audioSink->stop();
|
||||
delete m_audioSink;
|
||||
m_audioSink = nullptr;
|
||||
}
|
||||
|
||||
m_audioOutput->stop();
|
||||
delete m_audioOutput;
|
||||
m_audioOutput = nullptr;
|
||||
m_outputDevice = nullptr;
|
||||
}
|
||||
|
||||
void AudioOutput::startRecvData(int port)
|
||||
|
@ -156,7 +155,6 @@ void AudioOutput::startRecvData(int port)
|
|||
});
|
||||
connect(audioSocket, &QIODevice::readyRead, audioSocket, [this, audioSocket]() {
|
||||
qint64 recv = audioSocket->bytesAvailable();
|
||||
//qDebug() << "AudioOutput::recv data:" << recv;
|
||||
|
||||
if (!m_outputDevice) {
|
||||
return;
|
||||
|
@ -165,22 +163,16 @@ void AudioOutput::startRecvData(int port)
|
|||
m_buffer.reserve(recv);
|
||||
}
|
||||
|
||||
qint64 count = audioSocket->read(m_buffer.data(), audioSocket->bytesAvailable());
|
||||
qint64 count = audioSocket->read(m_buffer.data(), recv);
|
||||
m_outputDevice->write(m_buffer.data(), count);
|
||||
});
|
||||
connect(audioSocket, &QTcpSocket::stateChanged, audioSocket, [](QAbstractSocket::SocketState state) {
|
||||
qInfo() << "AudioOutput::audio socket state changed:" << state;
|
||||
|
||||
});
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
|
||||
connect(audioSocket, &QTcpSocket::errorOccurred, audioSocket, [](QAbstractSocket::SocketError error) {
|
||||
qInfo() << "AudioOutput::audio socket error occurred:" << error;
|
||||
});
|
||||
#else
|
||||
connect(audioSocket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), audioSocket, [](QAbstractSocket::SocketError error) {
|
||||
qInfo() << "AudioOutput::audio socket error occurred:" << error;
|
||||
});
|
||||
#endif
|
||||
|
||||
m_workerThread.start();
|
||||
emit connectTo(port);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QPointer>
|
||||
#include <QVector>
|
||||
|
||||
class QAudioSink;
|
||||
class QAudioOutput;
|
||||
class QIODevice;
|
||||
class AudioOutput : public QObject
|
||||
|
@ -36,6 +37,7 @@ private:
|
|||
QProcess m_sndcpy;
|
||||
QVector<char> m_buffer;
|
||||
bool m_running = false;
|
||||
QAudioSink *m_audioSink = nullptr;
|
||||
};
|
||||
|
||||
#endif // AUDIOOUTPUT_H
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "dialog.h"
|
||||
#include "mousetap/mousetap.h"
|
||||
|
||||
static Dialog *g_mainDlg = Q_NULLPTR;
|
||||
static QtMessageHandler g_oldMessageHandler = Q_NULLPTR;
|
||||
|
@ -55,7 +54,6 @@ int main(int argc, char *argv[])
|
|||
QApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
|
||||
}
|
||||
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
|
@ -142,7 +140,7 @@ void installTranslator()
|
|||
break;
|
||||
}
|
||||
|
||||
translator.load(languagePath);
|
||||
qInfo() << "Loading translation result =" << translator.load(languagePath);
|
||||
qApp->installTranslator(&translator);
|
||||
}
|
||||
|
||||
|
|
|
@ -618,9 +618,11 @@ void Dialog::on_usbConnectBtn_clicked()
|
|||
|
||||
int Dialog::findDeviceFromeSerialBox(bool wifi)
|
||||
{
|
||||
QRegExp regIP("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\:([0-9]|[1-9]\\d|[1-9]\\d{2}|[1-9]\\d{3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])\\b");
|
||||
QRegularExpression regIP(R"(^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\:(?:[0-9]|[1-9]\d{1,4}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$)");
|
||||
|
||||
for (int i = 0; i < ui->serialBox->count(); ++i) {
|
||||
bool isWifi = regIP.exactMatch(ui->serialBox->itemText(i));
|
||||
QRegularExpressionMatch match = regIP.match(ui->serialBox->itemText(i));
|
||||
bool isWifi = match.hasMatch();
|
||||
bool found = wifi ? isWifi : !isWifi;
|
||||
if (found) {
|
||||
return i;
|
||||
|
|
|
@ -68,7 +68,7 @@ void ToolForm::updateGroupControl()
|
|||
void ToolForm::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
m_dragPosition = event->globalPos() - frameGeometry().topLeft();
|
||||
m_dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ void ToolForm::mouseReleaseEvent(QMouseEvent *event)
|
|||
void ToolForm::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
move(event->globalPos() - m_dragPosition);
|
||||
move(event->globalPosition().toPoint() - m_dragPosition);
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include <QDesktopWidget>
|
||||
#include <QFileInfo>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
|
@ -363,21 +362,10 @@ void VideoForm::installShortcut()
|
|||
QRect VideoForm::getScreenRect()
|
||||
{
|
||||
QRect screenRect;
|
||||
QWidget *win = window();
|
||||
if (!win) {
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
QWindow *winHandle = win->windowHandle();
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
if (winHandle) {
|
||||
screen = winHandle->screen();
|
||||
if (screen) {
|
||||
screenRect = screen->availableGeometry();
|
||||
}
|
||||
if (!screen) {
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
screenRect = screen->availableGeometry();
|
||||
return screenRect;
|
||||
}
|
||||
|
||||
|
@ -572,23 +560,25 @@ void VideoForm::mousePressEvent(QMouseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_videoWidget->geometry().contains(event->pos())) {
|
||||
if (m_videoWidget->geometry().contains(event->position().toPoint())) {
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
event->setLocalPos(m_videoWidget->mapFrom(this, event->localPos().toPoint()));
|
||||
emit device->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
QPointF mappedPos = m_videoWidget->mapFrom(this, event->position().toPoint());
|
||||
emit device->mouseEvent(new QMouseEvent(
|
||||
event->type(), mappedPos, event->globalPosition(),
|
||||
event->button(), event->buttons(), event->modifiers()),
|
||||
m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
|
||||
// debug keymap pos
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
qreal x = event->localPos().x() / m_videoWidget->size().width();
|
||||
qreal y = event->localPos().y() / m_videoWidget->size().height();
|
||||
qreal x = mappedPos.x() / m_videoWidget->size().width();
|
||||
qreal y = mappedPos.y() / m_videoWidget->size().height();
|
||||
QString posTip = QString(R"("pos": {"x": %1, "y": %2})").arg(x).arg(y);
|
||||
qInfo() << posTip.toStdString().c_str();
|
||||
qInfo() << posTip;
|
||||
}
|
||||
} else {
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
m_dragPosition = event->globalPos() - frameGeometry().topLeft();
|
||||
m_dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
@ -601,23 +591,18 @@ void VideoForm::mouseReleaseEvent(QMouseEvent *event)
|
|||
if (!device) {
|
||||
return;
|
||||
}
|
||||
event->setLocalPos(m_videoWidget->mapFrom(this, event->localPos().toPoint()));
|
||||
// local check
|
||||
QPointF local = event->localPos();
|
||||
if (local.x() < 0) {
|
||||
local.setX(0);
|
||||
}
|
||||
if (local.x() > m_videoWidget->width()) {
|
||||
local.setX(m_videoWidget->width());
|
||||
}
|
||||
if (local.y() < 0) {
|
||||
local.setY(0);
|
||||
}
|
||||
if (local.y() > m_videoWidget->height()) {
|
||||
local.setY(m_videoWidget->height());
|
||||
}
|
||||
event->setLocalPos(local);
|
||||
emit device->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
|
||||
QPointF mappedPos = m_videoWidget->mapFrom(this, event->position().toPoint());
|
||||
QPointF local = mappedPos;
|
||||
if (local.x() < 0) local.setX(0);
|
||||
if (local.x() > m_videoWidget->width()) local.setX(m_videoWidget->width());
|
||||
if (local.y() < 0) local.setY(0);
|
||||
if (local.y() > m_videoWidget->height()) local.setY(m_videoWidget->height());
|
||||
|
||||
emit device->mouseEvent(new QMouseEvent(
|
||||
event->type(), local, event->globalPosition(),
|
||||
event->button(), event->buttons(), event->modifiers()),
|
||||
m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
} else {
|
||||
m_dragPosition = QPoint(0, 0);
|
||||
}
|
||||
|
@ -626,24 +611,25 @@ void VideoForm::mouseReleaseEvent(QMouseEvent *event)
|
|||
void VideoForm::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
auto device = qsc::IDeviceManage::getInstance().getDevice(m_serial);
|
||||
if (m_videoWidget->geometry().contains(event->pos())) {
|
||||
if (m_videoWidget->geometry().contains(event->position().toPoint())) {
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
event->setLocalPos(m_videoWidget->mapFrom(this, event->localPos().toPoint()));
|
||||
emit device->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
} else if (!m_dragPosition.isNull()) {
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
move(event->globalPos() - m_dragPosition);
|
||||
event->accept();
|
||||
}
|
||||
QPointF mappedPos = m_videoWidget->mapFrom(this, event->position().toPoint());
|
||||
emit device->mouseEvent(new QMouseEvent(
|
||||
event->type(), mappedPos, event->globalPosition(),
|
||||
event->button(), event->buttons(), event->modifiers()),
|
||||
m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
} else if (!m_dragPosition.isNull() && (event->buttons() & Qt::LeftButton)) {
|
||||
move(event->globalPosition().toPoint() - m_dragPosition);
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void VideoForm::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
auto device = qsc::IDeviceManage::getInstance().getDevice(m_serial);
|
||||
if (event->button() == Qt::LeftButton && !m_videoWidget->geometry().contains(event->pos())) {
|
||||
if (event->button() == Qt::LeftButton && !m_videoWidget->geometry().contains(event->position().toPoint())) {
|
||||
if (!isMaximized()) {
|
||||
removeBlackRect();
|
||||
}
|
||||
|
@ -653,38 +639,30 @@ void VideoForm::mouseDoubleClickEvent(QMouseEvent *event)
|
|||
emit device->postBackOrScreenOn(event->type() == QEvent::MouseButtonPress);
|
||||
}
|
||||
|
||||
if (m_videoWidget->geometry().contains(event->pos())) {
|
||||
if (m_videoWidget->geometry().contains(event->position().toPoint())) {
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
event->setLocalPos(m_videoWidget->mapFrom(this, event->localPos().toPoint()));
|
||||
emit device->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
QPointF mappedPos = m_videoWidget->mapFrom(this, event->position().toPoint());
|
||||
emit device->mouseEvent(new QMouseEvent(
|
||||
event->type(), mappedPos, event->globalPosition(),
|
||||
event->button(), event->buttons(), event->modifiers()),
|
||||
m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
}
|
||||
}
|
||||
|
||||
void VideoForm::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
auto device = qsc::IDeviceManage::getInstance().getDevice(m_serial);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
if (m_videoWidget->geometry().contains(event->position().toPoint())) {
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
QPointF pos = m_videoWidget->mapFrom(this, event->position().toPoint());
|
||||
QWheelEvent wheelEvent(
|
||||
pos, event->globalPosition(), event->pixelDelta(), event->angleDelta(), event->buttons(), event->modifiers(), event->phase(), event->inverted());
|
||||
#else
|
||||
if (m_videoWidget->geometry().contains(event->pos())) {
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
QPointF pos = m_videoWidget->mapFrom(this, event->pos());
|
||||
|
||||
QWheelEvent wheelEvent(
|
||||
pos, event->globalPosF(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(),
|
||||
event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted());
|
||||
#endif
|
||||
emit device->wheelEvent(&wheelEvent, m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
QWheelEvent adjustedEvent(
|
||||
pos, event->globalPosition(), event->pixelDelta(), event->angleDelta(),
|
||||
event->buttons(), event->modifiers(), event->phase(), event->inverted());
|
||||
emit device->wheelEvent(&adjustedEvent, m_videoWidget->frameSize(), m_videoWidget->size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -714,7 +692,6 @@ void VideoForm::paintEvent(QPaintEvent *paint)
|
|||
{
|
||||
Q_UNUSED(paint)
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
|
|
@ -113,10 +113,8 @@ QString Config::s_configPath = "";
|
|||
Config::Config(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_settings = new QSettings(getConfigPath() + "/config.ini", QSettings::IniFormat);
|
||||
m_settings->setIniCodec("UTF-8");
|
||||
|
||||
m_userData = new QSettings(getConfigPath() + "/userdata.ini", QSettings::IniFormat);
|
||||
m_userData->setIniCodec("UTF-8");
|
||||
|
||||
qDebug()<<m_userData->childGroups();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
#include <QX11Info>
|
||||
|
||||
#include <xcb/xproto.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QRect>
|
||||
#include <xcb/xproto.h>
|
||||
#include <QGuiApplication>
|
||||
#include <QRect>
|
||||
|
||||
#include "xmousetap.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/XTest.h>
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
XMouseTap::XMouseTap() {}
|
||||
|
||||
XMouseTap::~XMouseTap() {}
|
||||
|
@ -14,71 +22,43 @@ void XMouseTap::initMouseEventTap() {}
|
|||
|
||||
void XMouseTap::quitMouseEventTap() {}
|
||||
|
||||
static void find_grab_window_recursive(xcb_connection_t *dpy, xcb_window_t window,
|
||||
QRect rc, int16_t offset_x, int16_t offset_y,
|
||||
xcb_window_t *grab_window, uint32_t *grab_window_size) {
|
||||
xcb_query_tree_cookie_t tree_cookie;
|
||||
xcb_query_tree_reply_t *tree;
|
||||
tree_cookie = xcb_query_tree(dpy, window);
|
||||
tree = xcb_query_tree_reply(dpy, tree_cookie, NULL);
|
||||
|
||||
xcb_window_t *children = xcb_query_tree_children(tree);
|
||||
for (int i = 0; i < xcb_query_tree_children_length(tree); i++) {
|
||||
xcb_get_geometry_cookie_t gg_cookie;
|
||||
xcb_get_geometry_reply_t *gg;
|
||||
gg_cookie = xcb_get_geometry(dpy, children[i]);
|
||||
gg = xcb_get_geometry_reply(dpy, gg_cookie, NULL);
|
||||
|
||||
if (gg->x + offset_x <= rc.left() && gg->x + offset_x + gg->width >= rc.right() &&
|
||||
gg->y + offset_y <= rc.top() && gg->y + offset_y + gg->height >= rc.bottom()) {
|
||||
if (!*grab_window || gg->width * gg->height <= *grab_window_size) {
|
||||
*grab_window = children[i];
|
||||
*grab_window_size = gg->width * gg->height;
|
||||
}
|
||||
}
|
||||
|
||||
find_grab_window_recursive(dpy, children[i], rc,
|
||||
gg->x + offset_x, gg->y + offset_y,
|
||||
grab_window, grab_window_size);
|
||||
|
||||
free(gg);
|
||||
}
|
||||
|
||||
free(tree);
|
||||
}
|
||||
|
||||
void XMouseTap::enableMouseEventTap(QRect rc, bool enabled) {
|
||||
if (enabled && rc.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
xcb_connection_t *dpy = QX11Info::connection();
|
||||
auto *x11Interface = qApp->nativeInterface<QNativeInterface::QX11Application>();
|
||||
if (!x11Interface) {
|
||||
qWarning() << "X11 interface is not available. Ensure the application is running on X11.";
|
||||
return;
|
||||
}
|
||||
|
||||
Display *display = reinterpret_cast<Display*>(x11Interface->display());
|
||||
if (!display) {
|
||||
qWarning() << "Failed to get X Display.";
|
||||
return;
|
||||
}
|
||||
|
||||
int screenNumber = DefaultScreen(display);
|
||||
|
||||
Window rootWindow = RootWindow(display, screenNumber);
|
||||
|
||||
XRectangle xRect;
|
||||
xRect.x = static_cast<short>(rc.x());
|
||||
xRect.y = static_cast<short>(rc.y());
|
||||
xRect.width = static_cast<unsigned short>(rc.width());
|
||||
xRect.height = static_cast<unsigned short>(rc.height());
|
||||
|
||||
if (enabled) {
|
||||
// We grab the top-most smallest window
|
||||
xcb_window_t grab_window = 0;
|
||||
uint32_t grab_window_size = 0;
|
||||
|
||||
find_grab_window_recursive(dpy, QX11Info::appRootWindow(QX11Info::appScreen()),
|
||||
rc, 0, 0, &grab_window, &grab_window_size);
|
||||
|
||||
if (grab_window) {
|
||||
xcb_grab_pointer_cookie_t grab_cookie;
|
||||
xcb_grab_pointer_reply_t *grab;
|
||||
grab_cookie = xcb_grab_pointer(dpy, /* owner_events = */ 1,
|
||||
grab_window, /* event_mask = */ 0,
|
||||
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
|
||||
grab_window, XCB_NONE, XCB_CURRENT_TIME);
|
||||
grab = xcb_grab_pointer_reply(dpy, grab_cookie, NULL);
|
||||
|
||||
free(grab);
|
||||
int result = XGrabPointer(display, rootWindow, True,
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
None, None, CurrentTime);
|
||||
if (result != GrabSuccess) {
|
||||
qWarning() << "Failed to grab pointer.";
|
||||
}
|
||||
} else {
|
||||
xcb_void_cookie_t ungrab_cookie;
|
||||
xcb_generic_error_t *error;
|
||||
ungrab_cookie = xcb_ungrab_pointer_checked(dpy, XCB_CURRENT_TIME);
|
||||
error = xcb_request_check(dpy, ungrab_cookie);
|
||||
|
||||
free(error);
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
}
|
||||
XFlush(display);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue