mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-04-19 19:15:07 +00:00
feat: Adapt to qt6
This commit is contained in:
parent
96776ed415
commit
8bac421b20
15 changed files with 170 additions and 217 deletions
3
.github/workflows/macos.yml
vendored
3
.github/workflows/macos.yml
vendored
|
@ -16,7 +16,7 @@ jobs:
|
|||
runs-on: macos-14
|
||||
strategy:
|
||||
matrix:
|
||||
qt-ver: [5.15.2]
|
||||
qt-ver: [6.5.3]
|
||||
qt-arch-install: [clang_64]
|
||||
clang-arch: [x64]
|
||||
env:
|
||||
|
@ -34,6 +34,7 @@ jobs:
|
|||
uses: jurplel/install-qt-action@v4.1.1
|
||||
with:
|
||||
version: ${{ matrix.qt-ver }}
|
||||
modules: qtmultimedia
|
||||
cached: ${{ steps.cache-qt.outputs.cache-hit }}
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
5
.github/workflows/ubuntu.yml
vendored
5
.github/workflows/ubuntu.yml
vendored
|
@ -18,7 +18,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04]
|
||||
qt-ver: [5.15.2]
|
||||
qt-ver: [6.5.3]
|
||||
qt-arch-install: [gcc_64]
|
||||
gcc-arch: [x64]
|
||||
env:
|
||||
|
@ -30,6 +30,7 @@ jobs:
|
|||
uses: jurplel/install-qt-action@v4.1.1
|
||||
with:
|
||||
version: ${{ matrix.qt-ver }}
|
||||
modules: qtmultimedia
|
||||
cached: ${{ steps.cache-qt.outputs.cache-hit }}
|
||||
- name: Cache Qt
|
||||
id: cache-qt
|
||||
|
@ -38,7 +39,7 @@ jobs:
|
|||
path: ${{ env.qt-install-path }}/${{ matrix.qt-arch-install }}
|
||||
key: ${{ runner.os }}/${{ matrix.qt-ver }}/${{ matrix.qt-arch-install }}
|
||||
- name: Install GL library
|
||||
run: sudo apt-get install -y libglew-dev libglfw3-dev
|
||||
run: sudo apt-get install -y libglew-dev libglfw3-dev libopengl-dev libx11-dev libxtst-dev
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
|
8
.github/workflows/windows.yml
vendored
8
.github/workflows/windows.yml
vendored
|
@ -24,16 +24,13 @@ jobs:
|
|||
# 矩阵配置 https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix
|
||||
strategy:
|
||||
matrix:
|
||||
qt-ver: [5.15.2]
|
||||
qt-arch: [win64_msvc2019_64, win32_msvc2019]
|
||||
qt-ver: [6.5.3]
|
||||
qt-arch: [win64_msvc2019_64]
|
||||
# 配置qt-arch的额外设置msvc-arch,qt-arch-install
|
||||
include:
|
||||
- qt-arch: win64_msvc2019_64
|
||||
msvc-arch: x64
|
||||
qt-arch-install: msvc2019_64
|
||||
- qt-arch: win32_msvc2019
|
||||
msvc-arch: x86
|
||||
qt-arch-install: msvc2019
|
||||
# job env,所有steps都可以访问
|
||||
# 不同级别env详解 https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#env
|
||||
# 使用表达式语法${{}}访问上下文 https://help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions
|
||||
|
@ -62,6 +59,7 @@ jobs:
|
|||
target: desktop
|
||||
# Architecture for Windows/Android
|
||||
arch: ${{ matrix.qt-arch }}
|
||||
modules: qtmultimedia
|
||||
cached: ${{ steps.cache-qt.outputs.cache-hit }}
|
||||
# 拉取代码
|
||||
- uses: actions/checkout@v2
|
||||
|
|
|
@ -11,7 +11,9 @@ cmake_minimum_required(VERSION 3.19 FATAL_ERROR)
|
|||
# QC Custom config
|
||||
set(QC_PROJECT_NAME "QtScrcpy")
|
||||
# Read version numbers from file
|
||||
file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/appversion QC_FILE_VERSION)
|
||||
file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/appversion QC_FILE_VERSION_UNSTRIPPED)
|
||||
string(STRIP "${QC_FILE_VERSION_UNSTRIPPED}" QC_FILE_VERSION)
|
||||
|
||||
set(QC_PROJECT_VERSION ${QC_FILE_VERSION})
|
||||
|
||||
# Project declare
|
||||
|
@ -52,13 +54,13 @@ if (MSVC)
|
|||
add_compile_options(/W3 /WX /wd4566)
|
||||
|
||||
# avoid warning C4819
|
||||
add_compile_options(-source-charset:utf-8)
|
||||
#add_compile_options(-source-charset:utf-8)
|
||||
#add_compile_options(/utf-8)
|
||||
|
||||
# ensure we use minimal "windows.h" lib without the crazy min max macros
|
||||
add_compile_definitions(NOMINMAX WIN32_LEAN_AND_MEAN)
|
||||
|
||||
# disable SAFESEH - avoid "LNK2026: module unsafe"(Qt5.15&&vs2019)
|
||||
|
||||
# disable SAFESEH - avoid "LNK2026: module unsafe"(Qt5.15&&vs2019)
|
||||
add_link_options(/SAFESEH:NO)
|
||||
endif()
|
||||
|
||||
|
@ -79,11 +81,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}")
|
||||
|
@ -146,7 +147,7 @@ set(QC_UTIL_SOURCES
|
|||
util/mousetap/mousetap.cpp
|
||||
)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(QC_UTIL_SOURCES ${QC_UTIL_SOURCES}
|
||||
set(QC_UTIL_SOURCES ${QC_UTIL_SOURCES}
|
||||
util/mousetap/winmousetap.h
|
||||
util/mousetap/winmousetap.cpp
|
||||
util/winutils.h
|
||||
|
@ -154,13 +155,13 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||
)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(QC_UTIL_SOURCES ${QC_UTIL_SOURCES}
|
||||
set(QC_UTIL_SOURCES ${QC_UTIL_SOURCES}
|
||||
util/mousetap/xmousetap.h
|
||||
util/mousetap/xmousetap.cpp
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(QC_UTIL_SOURCES ${QC_UTIL_SOURCES}
|
||||
set(QC_UTIL_SOURCES ${QC_UTIL_SOURCES}
|
||||
util/mousetap/cocoamousetap.h
|
||||
util/mousetap/cocoamousetap.mm
|
||||
util/path.h
|
||||
|
@ -263,6 +264,8 @@ endif()
|
|||
|
||||
# MacOS
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")
|
||||
|
||||
# copy bundle file
|
||||
get_target_property(MACOS_BUNDLE_PATH ${PROJECT_NAME} RUNTIME_OUTPUT_DIRECTORY)
|
||||
set(MACOS_BUNDLE_PATH ${MACOS_BUNDLE_PATH}/${PROJECT_NAME}.app/Contents)
|
||||
|
@ -310,13 +313,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 +339,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 6beab5c967f7f77ddcfabe79757dc01202653ab7
|
||||
Subproject commit c82e88e1f46da00125f8297b663195ddad2bf3b3
|
|
@ -1 +1 @@
|
|||
0.0.0
|
||||
0.0.0
|
|
@ -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,10 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "dialog.h"
|
||||
#include "mousetap/mousetap.h"
|
||||
|
||||
#if defined(Q_OS_WIN32) || defined(Q_OS_OSX)
|
||||
#include "mousetap/mousetap.h"
|
||||
#endif
|
||||
|
||||
static Dialog *g_mainDlg = Q_NULLPTR;
|
||||
static QtMessageHandler g_oldMessageHandler = Q_NULLPTR;
|
||||
|
@ -55,7 +58,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 +144,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,37 @@ 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -2,19 +2,18 @@ import sys
|
|||
import os
|
||||
|
||||
if __name__ == '__main__':
|
||||
p = os.popen('git rev-list --tags --max-count=1')
|
||||
commit = p.read()
|
||||
p.close()
|
||||
commit = os.popen('git rev-list --tags --max-count=1').read().strip()
|
||||
|
||||
if commit:
|
||||
tag = os.popen('git describe --tags ' + commit).read().strip()
|
||||
version = tag[1:] if tag else "0.0.0"
|
||||
else:
|
||||
version = "0.0.0"
|
||||
|
||||
p = os.popen('git describe --tags ' + commit)
|
||||
tag = p.read()
|
||||
p.close()
|
||||
|
||||
# print('get tag:', tag)
|
||||
|
||||
version = str(tag[1:])
|
||||
# Write version to file
|
||||
version_file = os.path.abspath(os.path.join(os.path.dirname(__file__), "../QtScrcpy/appversion"))
|
||||
file=open(version_file, 'w')
|
||||
file.write(version)
|
||||
file.close()
|
||||
with open(version_file, 'w') as file:
|
||||
file.write(version)
|
||||
|
||||
print(f"Version written: {version}")
|
||||
sys.exit(0)
|
Loading…
Add table
Reference in a new issue