diff --git a/QtScrcpy/QtScrcpy.pro b/QtScrcpy/QtScrcpy.pro index fb41029..39b697c 100644 --- a/QtScrcpy/QtScrcpy.pro +++ b/QtScrcpy/QtScrcpy.pro @@ -5,7 +5,7 @@ #------------------------------------------------- QT += core gui -QT += network quickwidgets +QT += network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -24,6 +24,11 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 #DEFINES += SKIP_FRAMES +#DEFINES += USE_QTQUICK + +contains(DEFINES, USE_QTQUICK) { + QT += quickwidgets +} # 源码 SOURCES += \ @@ -54,6 +59,7 @@ include ($$PWD/uibase/uibase.pri) include ($$PWD/fontawesome/fontawesome.pri) include ($$PWD/filehandler/filehandler.pri) include ($$PWD/recorder/recorder.pri) +include ($$PWD/util/util.pri) # 附加包含路径 INCLUDEPATH += \ @@ -68,6 +74,7 @@ INCLUDEPATH += \ $$PWD/uibase \ $$PWD/filehandler \ $$PWD/recorder \ + $$PWD/util \ $$PWD/fontawesome @@ -87,8 +94,7 @@ win32 { -L$$PWD/../third_party/ffmpeg/lib -lavformat \ -L$$PWD/../third_party/ffmpeg/lib -lavcodec \ -L$$PWD/../third_party/ffmpeg/lib -lavutil \ - -L$$PWD/../third_party/ffmpeg/lib -lswscale \ - -lUser32 + -L$$PWD/../third_party/ffmpeg/lib -lswscale # windows rc file RC_FILE = $$PWD/res/QtScrcpy.rc diff --git a/QtScrcpy/inputcontrol/inputconvertgame.cpp b/QtScrcpy/inputcontrol/inputconvertgame.cpp index 2f7eeb6..bfb3f1f 100644 --- a/QtScrcpy/inputcontrol/inputconvertgame.cpp +++ b/QtScrcpy/inputcontrol/inputconvertgame.cpp @@ -413,9 +413,9 @@ bool InputConvertGame::processMouseMove(const QMouseEvent *from) m_mouseMoveLastConverPos.setY(m_mouseMoveLastConverPos.y() + distance.y() / m_showSize.height()); if (m_mouseMoveLastConverPos.x() < 0.1 - || m_mouseMoveLastConverPos.x() > 0.9 + || m_mouseMoveLastConverPos.x() > 0.8 || m_mouseMoveLastConverPos.y() < 0.1 - || m_mouseMoveLastConverPos.y() > 0.9) { + || m_mouseMoveLastConverPos.y() > 0.8) { mouseMoveStopTouch(); mouseMoveStartTouch(from); } diff --git a/QtScrcpy/main.cpp b/QtScrcpy/main.cpp index 6e208e8..e0628d6 100644 --- a/QtScrcpy/main.cpp +++ b/QtScrcpy/main.cpp @@ -6,6 +6,7 @@ #include "dialog.h" #include "decoder.h" +#include "mousetap/mousetap.h" Dialog* g_mainDlg = Q_NULLPTR; @@ -25,6 +26,8 @@ int main(int argc, char *argv[]) installTranslator(); + MouseTap::getInstance()->initMouseEventTap(); + #ifdef Q_OS_WIN32 qputenv("QTSCRCPY_ADB_PATH", "../../../third_party/adb/win/adb.exe"); qputenv("QTSCRCPY_SERVER_PATH", "../../../third_party/scrcpy-server.jar"); @@ -50,6 +53,7 @@ int main(int argc, char *argv[]) int ret = a.exec(); + MouseTap::getInstance()->quitMouseEventTap(); Decoder::deInit(); return ret; } diff --git a/QtScrcpy/qml/pinwheel.qml b/QtScrcpy/qml/pinwheel.qml index 61c328b..8893b99 100644 --- a/QtScrcpy/qml/pinwheel.qml +++ b/QtScrcpy/qml/pinwheel.qml @@ -9,11 +9,12 @@ Image { RotationAnimation { id:rotationAnimation target: wheel - to:360000 + to:360 direction: RotationAnimation.Clockwise - duration: 800000 + duration: 800 + loops:Animation.Infinite } onStatusChanged: if (wheel.status == Image.Ready) rotationAnimation.start() } -} \ No newline at end of file +} diff --git a/QtScrcpy/toolform.cpp b/QtScrcpy/toolform.cpp index 49678e8..60c2b21 100644 --- a/QtScrcpy/toolform.cpp +++ b/QtScrcpy/toolform.cpp @@ -1,4 +1,7 @@ #include +#include +#include +#include #include "toolform.h" #include "ui_toolform.h" @@ -58,6 +61,16 @@ void ToolForm::mouseMoveEvent(QMouseEvent *event) } } +void ToolForm::showEvent(QShowEvent *event) +{ + qDebug() << "show event"; +} + +void ToolForm::hideEvent(QHideEvent *event) +{ + qDebug() << "hide event"; +} + void ToolForm::on_fullScreenBtn_clicked() { if (m_videoForm) { diff --git a/QtScrcpy/toolform.h b/QtScrcpy/toolform.h index 2c09f37..5e2ace6 100644 --- a/QtScrcpy/toolform.h +++ b/QtScrcpy/toolform.h @@ -24,6 +24,9 @@ protected: void mouseReleaseEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); + void showEvent(QShowEvent *event); + void hideEvent(QHideEvent *event); + private slots: void on_fullScreenBtn_clicked(); diff --git a/QtScrcpy/util/mousetap/cocoamousetap.h b/QtScrcpy/util/mousetap/cocoamousetap.h new file mode 100644 index 0000000..2346a2e --- /dev/null +++ b/QtScrcpy/util/mousetap/cocoamousetap.h @@ -0,0 +1,29 @@ +#ifndef COCOAMOUSETAP_H +#define COCOAMOUSETAP_H +#include +#include + +#include "mousetap.h" + +struct MouseEventTapData; +class QWidget; +class CocoaMouseTap : public MouseTap, public QThread +{ +private: + CocoaMouseTap(QObject *parent = Q_NULLPTR); + virtual ~CocoaMouseTap(); + +public: + void initMouseEventTap() override; + void quitMouseEventTap() override; + void enableMouseEventTap(QWidget* widget, bool enabled) override; + +protected: + void run() override; + +private: + MouseEventTapData *m_tapData = Q_NULLPTR; + QSemaphore m_runloopStartedSemaphore; +}; + +#endif // COCOAMOUSETAP_H diff --git a/QtScrcpy/util/mousetap/cocoamousetap.mm b/QtScrcpy/util/mousetap/cocoamousetap.mm new file mode 100644 index 0000000..fdcd129 --- /dev/null +++ b/QtScrcpy/util/mousetap/cocoamousetap.mm @@ -0,0 +1,227 @@ +#import +#include +#include + +#include "cocoamousetap.h" + +static const CGEventMask movementEventsMask = + CGEventMaskBit(kCGEventLeftMouseDragged) + | CGEventMaskBit(kCGEventRightMouseDragged) + | CGEventMaskBit(kCGEventMouseMoved); + +static const CGEventMask allGrabbedEventsMask = + CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp) + | CGEventMaskBit(kCGEventRightMouseDown) | CGEventMaskBit(kCGEventRightMouseUp) + | CGEventMaskBit(kCGEventOtherMouseDown) | CGEventMaskBit(kCGEventOtherMouseUp) + | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged) + | CGEventMaskBit(kCGEventMouseMoved); + +typedef struct MouseEventTapData{ + CFMachPortRef tap = Q_NULLPTR; + CFRunLoopRef runloop = Q_NULLPTR; + CFRunLoopSourceRef runloopSource = Q_NULLPTR; + QWidget* widget = Q_NULLPTR; +} MouseEventTapData; + +static CGEventRef Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) +{ + Q_UNUSED(proxy); + MouseEventTapData *tapdata = (MouseEventTapData*)refcon; + + NSView *nsview; + NSWindow *nswindow; + NSRect windowRect; + NSRect newWindowRect; + CGPoint eventLocation; + + switch (type) { + case kCGEventTapDisabledByTimeout: + { + CGEventTapEnable(tapdata->tap, true); + return NULL; + } + case kCGEventTapDisabledByUserInput: + { + return NULL; + } + default: + break; + } + + + if (!tapdata->widget) { + return event; + } + // get nswindow from qt widget + nsview = (NSView *)tapdata->widget->window()->winId(); + if (!nsview) { + return event; + } + nswindow = [nsview window]; + + eventLocation = CGEventGetUnflippedLocation(event); + windowRect = [nswindow contentRectForFrameRect:[nswindow frame]]; + + newWindowRect = NSMakeRect(windowRect.origin.x, windowRect.origin.y, + windowRect.size.width - 10, windowRect.size.height - 10); + qDebug() << newWindowRect.origin.x << newWindowRect.origin.y + << newWindowRect.size.width << newWindowRect.size.height; + + if (!NSMouseInRect(NSPointFromCGPoint(eventLocation), newWindowRect, NO)) { + + /* This is in CGs global screenspace coordinate system, which has a + * flipped Y. + */ + CGPoint newLocation = CGEventGetLocation(event); + + if (eventLocation.x < NSMinX(windowRect)) { + newLocation.x = NSMinX(windowRect); + } else if (eventLocation.x >= NSMaxX(windowRect)) { + newLocation.x = NSMaxX(windowRect) - 1.0; + } + + if (eventLocation.y <= NSMinY(windowRect)) { + newLocation.y -= (NSMinY(windowRect) - eventLocation.y + 1); + } else if (eventLocation.y > NSMaxY(windowRect)) { + newLocation.y += (eventLocation.y - NSMaxY(windowRect)); + } + + CGWarpMouseCursorPosition(newLocation); + CGAssociateMouseAndMouseCursorPosition(YES); + + if ((CGEventMaskBit(type) & movementEventsMask) == 0) { + /* For click events, we just constrain the event to the window, so + * no other app receives the click event. We can't due the same to + * movement events, since they mean that our warp cursor above + * behaves strangely. + */ + CGEventSetLocation(event, newLocation); + } + } + + return event; +} + +static void SemaphorePostCallback(CFRunLoopTimerRef timer, void *info) +{ + Q_UNUSED(timer); + QSemaphore *runloopStartedSemaphore = (QSemaphore *)info; + if (runloopStartedSemaphore) { + runloopStartedSemaphore->release(); + } +} + +CocoaMouseTap::CocoaMouseTap(QObject *parent) + : QThread(parent) +{ + m_tapData = new MouseEventTapData; +} + +CocoaMouseTap::~CocoaMouseTap() +{ + if (m_tapData) { + delete m_tapData; + m_tapData = Q_NULLPTR; + } +} + +void CocoaMouseTap::initMouseEventTap() +{ + if (!m_tapData) { + return; + } + + m_tapData->tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, + kCGEventTapOptionDefault, allGrabbedEventsMask, + &Cocoa_MouseTapCallback, m_tapData); + if (!m_tapData->tap) { + return; + } + /* Tap starts disabled, until app requests mouse grab */ + CGEventTapEnable(m_tapData->tap, false); + start(); +} + +void CocoaMouseTap::quitMouseEventTap() +{ + bool status; + if (m_tapData == Q_NULLPTR || m_tapData->tap == Q_NULLPTR) { + /* event tap was already cleaned up (possibly due to CGEventTapCreate + * returning null.) + */ + return; + } + + /* Ensure that the runloop has been started first. + * TODO: Move this to InitMouseEventTap, check for error conditions that can + * happen in Cocoa_MouseTapThread, and fall back to the non-EventTap way of + * grabbing the mouse if it fails to Init. + */ + status = m_runloopStartedSemaphore.tryAcquire(1, 5000); + if (status) { + /* Then stop it, which will cause Cocoa_MouseTapThread to return. */ + CFRunLoopStop(m_tapData->runloop); + /* And then wait for Cocoa_MouseTapThread to finish cleaning up. It + * releases some of the pointers in tapdata. */ + wait(); + } +} + +void CocoaMouseTap::enableMouseEventTap(QWidget* widget, bool enabled) +{ + if (m_tapData && m_tapData->tap) + { + enabled ? m_tapData->widget = widget : m_tapData->widget = Q_NULLPTR; + CGEventTapEnable(m_tapData->tap, enabled); + } +} + +void CocoaMouseTap::run() +{ + /* Tap was created on main thread but we own it now. */ + CFMachPortRef eventTap = m_tapData->tap; + if (eventTap) { + /* Try to create a runloop source we can schedule. */ + CFRunLoopSourceRef runloopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0); + if (runloopSource) { + m_tapData->runloopSource = runloopSource; + } else { + CFRelease(eventTap); + m_runloopStartedSemaphore.release(); + /* TODO: Both here and in the return below, set some state in + * tapdata to indicate that initialization failed, which we should + * check in InitMouseEventTap, after we move the semaphore check + * from Quit to Init. + */ + return; + } + } else { + m_runloopStartedSemaphore.release(); + return; + } + + m_tapData->runloop = CFRunLoopGetCurrent(); + CFRunLoopAddSource(m_tapData->runloop, m_tapData->runloopSource, kCFRunLoopCommonModes); + CFRunLoopTimerContext context = {.info = &m_runloopStartedSemaphore}; + /* We signal the runloop started semaphore *after* the run loop has started, indicating it's safe to CFRunLoopStop it. */ + CFRunLoopTimerRef timer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0, 0, 0, &SemaphorePostCallback, &context); + CFRunLoopAddTimer(m_tapData->runloop, timer, kCFRunLoopCommonModes); + CFRelease(timer); + + /* Run the event loop to handle events in the event tap. */ + CFRunLoopRun(); + /* Make sure this is signaled so that SDL_QuitMouseEventTap knows it can safely SDL_WaitThread for us. */ + if (m_runloopStartedSemaphore.available() < 1) { + m_runloopStartedSemaphore.release(); + } + CFRunLoopRemoveSource(m_tapData->runloop, m_tapData->runloopSource, kCFRunLoopCommonModes); + + /* Clean up. */ + CGEventTapEnable(m_tapData->tap, false); + CFRelease(m_tapData->runloopSource); + CFRelease(m_tapData->tap); + m_tapData->runloopSource = Q_NULLPTR; + m_tapData->tap = Q_NULLPTR; + + return; +} diff --git a/QtScrcpy/util/mousetap/mousetap.cpp b/QtScrcpy/util/mousetap/mousetap.cpp new file mode 100644 index 0000000..da1bc13 --- /dev/null +++ b/QtScrcpy/util/mousetap/mousetap.cpp @@ -0,0 +1,26 @@ +#include + +#include "mousetap.h" +#ifdef Q_OS_WIN32 +#include "winmousetap.h" +#endif +#ifdef Q_OS_OSX +#include "cocoamousetap.h" +#endif + +MouseTap *MouseTap::s_instance = Q_NULLPTR; +MouseTap *MouseTap::getInstance() +{ + if (s_instance == Q_NULLPTR) { +#ifdef Q_OS_WIN32 + s_instance = new WinMouseTap(); +#endif +#ifdef Q_OS_OSX + s_instance = new CocoaMouseTap(); +#endif +#ifdef Q_OS_LINUX + Q_ASSERT(false); +#endif + } + return s_instance; +} diff --git a/QtScrcpy/util/mousetap/mousetap.h b/QtScrcpy/util/mousetap/mousetap.h new file mode 100644 index 0000000..eab1389 --- /dev/null +++ b/QtScrcpy/util/mousetap/mousetap.h @@ -0,0 +1,14 @@ +#ifndef MOUSETAP_H +#define MOUSETAP_H +class QWidget; +class MouseTap { +public: + static MouseTap* getInstance(); + virtual void initMouseEventTap() = 0; + virtual void quitMouseEventTap() = 0; + virtual void enableMouseEventTap(QWidget* widget, bool enabled) = 0; + +private: + static MouseTap *s_instance; +}; +#endif // MOUSETAP_H diff --git a/QtScrcpy/util/mousetap/mousetap.pri b/QtScrcpy/util/mousetap/mousetap.pri new file mode 100644 index 0000000..e2d7d09 --- /dev/null +++ b/QtScrcpy/util/mousetap/mousetap.pri @@ -0,0 +1,18 @@ +HEADERS += \ + $$PWD/mousetap.h + +SOURCES += \ + $$PWD/mousetap.cpp + +win32 { + HEADERS += $$PWD/winmousetap.h + SOURCES += $$PWD/winmousetap.cpp + LIBS += -lUser32 +} + +mac { + HEADERS += $$PWD/cocoamousetap.h + OBJECTIVE_SOURCES += $$PWD/cocoamousetap.mm + LIBS += -framework Appkit + QMAKE_CFLAGS += -mmacosx-version-min=10.6 +} diff --git a/QtScrcpy/util/mousetap/winmousetap.cpp b/QtScrcpy/util/mousetap/winmousetap.cpp new file mode 100644 index 0000000..7467b89 --- /dev/null +++ b/QtScrcpy/util/mousetap/winmousetap.cpp @@ -0,0 +1,43 @@ +#include +#include + +#include "winmousetap.h" + +WinMouseTap::WinMouseTap() +{ + +} + +WinMouseTap::~WinMouseTap() +{ + +} + +void WinMouseTap::initMouseEventTap() +{ + +} + +void WinMouseTap::quitMouseEventTap() +{ + +} + +void WinMouseTap::enableMouseEventTap(QWidget *widget, bool enabled) +{ + if (!widget) { + return; + } + if(enabled) { + QRect rc(widget->mapToGlobal(widget->pos()) + , widget->size()); + RECT mainRect; + mainRect.left = (LONG)rc.left(); + mainRect.right = (LONG)rc.right(); + mainRect.top = (LONG)rc.top(); + mainRect.bottom = (LONG)rc.bottom(); + ClipCursor(&mainRect); + } else { + ClipCursor(Q_NULLPTR); + } +} diff --git a/QtScrcpy/util/mousetap/winmousetap.h b/QtScrcpy/util/mousetap/winmousetap.h new file mode 100644 index 0000000..9b23f68 --- /dev/null +++ b/QtScrcpy/util/mousetap/winmousetap.h @@ -0,0 +1,17 @@ +#ifndef WINMOUSETAP_H +#define WINMOUSETAP_H + +#include "mousetap.h" + +class WinMouseTap : public MouseTap +{ +public: + WinMouseTap(); + virtual ~WinMouseTap(); + + void initMouseEventTap() override; + void quitMouseEventTap() override; + void enableMouseEventTap(QWidget* widget, bool enabled) override; +}; + +#endif // WINMOUSETAP_H diff --git a/QtScrcpy/util/util.pri b/QtScrcpy/util/util.pri new file mode 100644 index 0000000..8756e35 --- /dev/null +++ b/QtScrcpy/util/util.pri @@ -0,0 +1 @@ +include ($$PWD/mousetap/mousetap.pri) diff --git a/QtScrcpy/videoform.cpp b/QtScrcpy/videoform.cpp index b98fe5e..14416e1 100644 --- a/QtScrcpy/videoform.cpp +++ b/QtScrcpy/videoform.cpp @@ -4,10 +4,10 @@ #include #include #include -#ifdef Q_OS_WIN32 -#include -#endif +#ifdef USE_QTQUICK #include +#endif +#include #include #include #include @@ -18,6 +18,7 @@ #include "toolform.h" #include "controlevent.h" #include "recorder.h" +#include "mousetap/mousetap.h" VideoForm::VideoForm(const QString& serial, quint16 maxSize, quint32 bitRate, const QString& fileName, QWidget *parent) : QWidget(parent), @@ -73,27 +74,52 @@ VideoForm::~VideoForm() void VideoForm::initUI() { + setAttribute(Qt::WA_DeleteOnClose); QPixmap phone; if (phone.load(":/res/phone.png")) { m_widthHeightRatio = 1.0f * phone.width() / phone.height(); } - setAttribute(Qt::WA_DeleteOnClose); +#ifdef USE_QTQUICK + // qml animation + QWidget *loadingWidget; + QHBoxLayout *horizontalLayout; + QQuickWidget *quickWidget; + loadingWidget = new QWidget(this); + loadingWidget->setObjectName(QStringLiteral("loadingWidget")); + loadingWidget->setAutoFillBackground(false); + loadingWidget->setStyleSheet(QStringLiteral("")); + loadingWidget->setAttribute(Qt::WA_DeleteOnClose); + m_loadingWidget = loadingWidget; + horizontalLayout = new QHBoxLayout(loadingWidget); + horizontalLayout->setSpacing(0); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); + horizontalLayout->setContentsMargins(0, 0, 0, 0); + quickWidget = new QQuickWidget(loadingWidget); + quickWidget->setObjectName(QStringLiteral("quickWidget")); + quickWidget->setAutoFillBackground(false); + quickWidget->setStyleSheet(QStringLiteral("")); + quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + quickWidget->setSource(QUrl(QStringLiteral("qrc:/qml/pinwheel.qml"))); + // 最后绘制,不设置最后绘制会影响父窗体异形异常(quickWidget的透明通道会形成穿透) + quickWidget->setAttribute(Qt::WA_AlwaysStackOnTop); + // 背景透明 + quickWidget->setClearColor(QColor(Qt::transparent)); + horizontalLayout->addWidget(quickWidget); + ui->verticalLayout->addWidget(loadingWidget); +#endif + // mac下去掉标题栏影响showfullscreen +#ifndef Q_OS_OSX // 去掉标题栏 setWindowFlags(windowFlags() | Qt::FramelessWindowHint); // 根据图片构造异形窗口 setAttribute(Qt::WA_TranslucentBackground); +#endif - setMouseTracking(true); - ui->loadingWidget->setAttribute(Qt::WA_DeleteOnClose); + setMouseTracking(true); ui->videoWidget->setMouseTracking(true); - ui->videoWidget->hide(); - - // 最后绘制,不设置最后绘制会影响父窗体异形异常(quickWidget的透明通道会形成穿透) - ui->quickWidget->setAttribute(Qt::WA_AlwaysStackOnTop); - // 背景透明 - ui->quickWidget->setClearColor(QColor(Qt::transparent)); + ui->videoWidget->hide(); } void VideoForm::initSignals() @@ -110,19 +136,12 @@ void VideoForm::initSignals() } }); connect(&m_inputConvert, &InputConvertGame::grabCursor, this, [this](bool grab){ + #ifdef Q_OS_WIN32 - if(grab) { - QRect rc(mapToGlobal(ui->videoWidget->pos()) - , ui->videoWidget->size()); - RECT mainRect; - mainRect.left = (LONG)rc.left(); - mainRect.right = (LONG)rc.right(); - mainRect.top = (LONG)rc.top(); - mainRect.bottom = (LONG)rc.bottom(); - ClipCursor(&mainRect); - } else { - ClipCursor(Q_NULLPTR); - } + MouseTap::getInstance()->enableMouseEventTap(ui->videoWidget, grab); +#endif +#ifdef Q_OS_OSX + MouseTap::getInstance()->enableMouseEventTap(ui->videoWidget, grab); #endif }); connect(m_server, &Server::serverStartResult, this, [this](bool success){ @@ -138,7 +157,6 @@ void VideoForm::initSignals() float diff = m_startTimeCount.elapsed() / 1000.0f; qInfo(QString("server start finish in %1s").arg(diff).toStdString().c_str()); - // update ui setWindowTitle(deviceName); updateShowSize(size); @@ -170,7 +188,9 @@ void VideoForm::initSignals() // must be Qt::QueuedConnection, ui update must be main thread connect(&m_decoder, &Decoder::onNewFrame, this, [this](){ if (ui->videoWidget->isHidden()) { - ui->loadingWidget->close(); + if (m_loadingWidget) { + m_loadingWidget->close(); + } ui->videoWidget->show(); } m_frames.lock(); @@ -257,9 +277,10 @@ void VideoForm::switchFullScreen() { if (isFullScreen()) { showNormal(); + #ifdef Q_OS_OSX - setWindowFlags(windowFlags() | Qt::FramelessWindowHint); - show(); + //setWindowFlags(windowFlags() | Qt::FramelessWindowHint); + //show(); #endif updateStyleSheet(height() > width()); showToolFrom(true); @@ -267,9 +288,10 @@ void VideoForm::switchFullScreen() ::SetThreadExecutionState(ES_CONTINUOUS); #endif } else { + // 这种临时增加标题栏再全屏的方案会导致收不到mousemove事件,导致setmousetrack失效 // mac fullscreen must show title bar #ifdef Q_OS_OSX - setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); + //setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); #endif showToolFrom(false); layout()->setContentsMargins(0, 0, 0, 0); @@ -410,6 +432,7 @@ void VideoForm::keyPressEvent(QKeyEvent *event) && isFullScreen()) { switchFullScreen(); } + //qDebug() << "keyPressEvent" << event->isAutoRepeat(); m_inputConvert.keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); } @@ -432,7 +455,9 @@ void VideoForm::paintEvent(QPaintEvent *paint) void VideoForm::showEvent(QShowEvent *event) { Q_UNUSED(event); - showToolFrom(); + if (!isFullScreen()) { + showToolFrom(); + } } void VideoForm::dragEnterEvent(QDragEnterEvent *event) diff --git a/QtScrcpy/videoform.h b/QtScrcpy/videoform.h index 49b49ef..3cd7994 100644 --- a/QtScrcpy/videoform.h +++ b/QtScrcpy/videoform.h @@ -79,6 +79,7 @@ private: QPointer m_toolForm; Recorder* m_recorder = Q_NULLPTR; QTime m_startTimeCount; + QPointer m_loadingWidget; }; #endif // VIDEOFORM_H diff --git a/QtScrcpy/videoform.ui b/QtScrcpy/videoform.ui index 539e5b5..9c393cc 100644 --- a/QtScrcpy/videoform.ui +++ b/QtScrcpy/videoform.ui @@ -38,62 +38,12 @@ 62 - - - - false - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - false - - - - - - QQuickWidget::SizeRootObjectToView - - - - qrc:/qml/pinwheel.qml - - - - - - - - - QQuickWidget - QWidget -
QtQuickWidgets/QQuickWidget
-
QYUVOpenGLWidget QWidget diff --git a/TODO.txt b/TODO.txt index 0cf3e19..159bbb2 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,12 +1,12 @@ // TODO mac: Qt::FramelessWindowHit full screen is abnormal - +linuxƶ +MacϷʱƶ⡣ չģָȣ ģָ(ע⣺Ͷû) - +루serverҪΪapkΪһ뷨ݲʵ֣ - - 7764a836f1ee02a4540cfc4118c20729018daaac +scrcpy 7764a836f1ee02a4540cfc4118c20729018daaac mark: