diff --git a/QtScrcpy/QtScrcpy.pro b/QtScrcpy/QtScrcpy.pro index f4ed3f7..6656d79 100644 --- a/QtScrcpy/QtScrcpy.pro +++ b/QtScrcpy/QtScrcpy.pro @@ -59,7 +59,7 @@ INCLUDEPATH += \ # 统一版本号入口,只修改这一个地方即可 VERSION_MAJOR = 1 VERSION_MINOR = 2 -VERSION_PATCH = 0 +VERSION_PATCH = 1 # qmake变量的方式定义版本号 VERSION = $${VERSION_MAJOR}.$${VERSION_MINOR}.$${VERSION_PATCH} diff --git a/QtScrcpy/device/device.cpp b/QtScrcpy/device/device.cpp index 83e057f..9b4f0e5 100644 --- a/QtScrcpy/device/device.cpp +++ b/QtScrcpy/device/device.cpp @@ -163,7 +163,6 @@ void Device::initSignals() // update ui if (m_videoForm) { m_videoForm->setWindowTitle(deviceName); - m_videoForm->updateScreenRatio(size); m_videoForm->updateShowSize(size); } diff --git a/QtScrcpy/device/ui/videoform.cpp b/QtScrcpy/device/ui/videoform.cpp index 834703d..82a51e2 100644 --- a/QtScrcpy/device/ui/videoform.cpp +++ b/QtScrcpy/device/ui/videoform.cpp @@ -10,6 +10,7 @@ #include #include "videoform.h" +#include "qyuvopenglwidget.h" #include "mousetap/mousetap.h" #include "ui_videoform.h" #include "iconhelper.h" @@ -59,15 +60,20 @@ void VideoForm::initUI() #endif } + m_videoWidget = new QYUVOpenGLWidget(); + m_videoWidget->hide(); + ui->keepRadioWidget->setWidget(m_videoWidget); + ui->keepRadioWidget->setWidthHeightRadio(m_widthHeightRatio); + setMouseTracking(true); - ui->videoWidget->setMouseTracking(true); - ui->videoWidget->hide(); + m_videoWidget->setMouseTracking(true); + ui->keepRadioWidget->setMouseTracking(true); } void VideoForm::onGrabCursor(bool grab) { #if defined(Q_OS_WIN32) || defined(Q_OS_OSX) - MouseTap::getInstance()->enableMouseEventTap(ui->videoWidget, grab); + MouseTap::getInstance()->enableMouseEventTap(m_videoWidget, grab); #else Q_UNUSED(grab) #endif @@ -75,16 +81,16 @@ void VideoForm::onGrabCursor(bool grab) void VideoForm::updateRender(const AVFrame *frame) { - if (ui->videoWidget->isHidden()) { + if (m_videoWidget->isHidden()) { if (m_loadingWidget) { m_loadingWidget->close(); } - ui->videoWidget->show(); + m_videoWidget->show(); } updateShowSize(QSize(frame->width, frame->height)); - ui->videoWidget->setFrameSize(QSize(frame->width, frame->height)); - ui->videoWidget->updateTextures(frame->data[0], frame->data[1], frame->data[2], + m_videoWidget->setFrameSize(QSize(frame->width, frame->height)); + m_videoWidget->updateTextures(frame->data[0], frame->data[1], frame->data[2], frame->linesize[0], frame->linesize[1], frame->linesize[2]); } @@ -98,6 +104,18 @@ void VideoForm::showToolForm(bool show) m_toolForm->setVisible(show); } +void VideoForm::moveCenter() +{ + QDesktopWidget* desktop = QApplication::desktop(); + if (!desktop) { + qWarning() << "QApplication::desktop() is nullptr"; + return; + } + QRect screenRect = desktop->availableGeometry(); + // 窗口居中 + move(screenRect.center() - QRect(0, 0, size().width(), size().height()).center()); +} + void VideoForm::updateStyleSheet(bool vertical) { if (vertical) { @@ -129,45 +147,37 @@ QMargins VideoForm::getMargins(bool vertical) return margins; } -void VideoForm::updateScreenRatio(const QSize &newSize) -{ - m_widthHeightRatio = 1.0f * qMin(newSize.width(),newSize.height()) / qMax(newSize.width(),newSize.height()); -} - void VideoForm::updateShowSize(const QSize &newSize) { if (m_frameSize != newSize) { m_frameSize = newSize; - bool vertical = newSize.height() > newSize.width(); + + m_widthHeightRatio = 1.0f * newSize.width() / newSize.height(); + ui->keepRadioWidget->setWidthHeightRadio(m_widthHeightRatio); + + bool vertical = m_widthHeightRatio < 1.0f ? true : false; QSize showSize = newSize; QDesktopWidget* desktop = QApplication::desktop(); - if (desktop) { - QRect screenRect = desktop->availableGeometry(); - if (vertical) { - showSize.setHeight(qMin(newSize.height(), screenRect.height() - 200)); - showSize.setWidth(showSize.height() * m_widthHeightRatio); - } else { - showSize.setWidth(qMin(newSize.width(), screenRect.width()/2)); - showSize.setHeight(showSize.width() * m_widthHeightRatio); - } - - if (isFullScreen()) { - switchFullScreen(); - } - if (m_skin) { - QMargins m = getMargins(vertical); - showSize.setWidth(showSize.width() + m.left() + m.right()); - showSize.setHeight(showSize.height() + m.top() + m.bottom()); - } - - // 窗口居中 - move(screenRect.center() - QRect(0, 0, showSize.width(), showSize.height()).center()); + if (!desktop) { + qWarning() << "QApplication::desktop() is nullptr"; + return; + } + QRect screenRect = desktop->availableGeometry(); + if (vertical) { + showSize.setHeight(qMin(newSize.height(), screenRect.height() - 200)); + showSize.setWidth(showSize.height() * m_widthHeightRatio); + } else { + showSize.setWidth(qMin(newSize.width(), screenRect.width()/2)); + showSize.setHeight(showSize.width() / m_widthHeightRatio); } - if (!m_skin) { - // 减去标题栏高度 - int titleBarHeight = style()->pixelMetric(QStyle::PM_TitleBarHeight); - showSize.setHeight(showSize.height() - titleBarHeight); + if (isFullScreen()) { + switchFullScreen(); + } + if (m_skin) { + QMargins m = getMargins(vertical); + showSize.setWidth(showSize.width() + m.left() + m.right()); + showSize.setHeight(showSize.height() + m.top() + m.bottom()); } if (showSize != size()) { @@ -175,6 +185,7 @@ void VideoForm::updateShowSize(const QSize &newSize) if (m_skin) { updateStyleSheet(vertical); } + moveCenter(); } } } @@ -182,7 +193,14 @@ void VideoForm::updateShowSize(const QSize &newSize) void VideoForm::switchFullScreen() { if (isFullScreen()) { + // 横屏全屏铺满全屏,恢复时,恢复保持宽高比 + if (m_widthHeightRatio > 1.0f) { + ui->keepRadioWidget->setWidthHeightRadio(m_widthHeightRatio); + } + showNormal(); + // fullscreen window will move (0,0). qt bug? + move(m_fullScreenBeforePos); #ifdef Q_OS_OSX //setWindowFlags(windowFlags() | Qt::FramelessWindowHint); @@ -196,6 +214,12 @@ void VideoForm::switchFullScreen() ::SetThreadExecutionState(ES_CONTINUOUS); #endif } else { + // 横屏全屏铺满全屏,不保持宽高比 + if (m_widthHeightRatio > 1.0f) { + ui->keepRadioWidget->setWidthHeightRadio(-1.0f); + } + + m_fullScreenBeforePos = pos(); // 这种临时增加标题栏再全屏的方案会导致收不到mousemove事件,导致setmousetrack失效 // mac fullscreen must show title bar #ifdef Q_OS_OSX @@ -256,12 +280,12 @@ void VideoForm::setController(Controller *controller) void VideoForm::mousePressEvent(QMouseEvent *event) { - if (ui->videoWidget->geometry().contains(event->pos())) { + if (m_videoWidget->geometry().contains(event->pos())) { if (!m_controller) { return; } - event->setLocalPos(ui->videoWidget->mapFrom(this, event->localPos().toPoint())); - m_controller->mouseEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); + event->setLocalPos(m_videoWidget->mapFrom(this, event->localPos().toPoint())); + m_controller->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size()); } else { if (event->button() == Qt::LeftButton) { m_dragPosition = event->globalPos() - frameGeometry().topLeft(); @@ -276,23 +300,23 @@ void VideoForm::mouseReleaseEvent(QMouseEvent *event) if (!m_controller) { return; } - event->setLocalPos(ui->videoWidget->mapFrom(this, event->localPos().toPoint())); + 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() > ui->videoWidget->width()) { - local.setX(ui->videoWidget->width()); + if (local.x() > m_videoWidget->width()) { + local.setX(m_videoWidget->width()); } if (local.y() < 0) { local.setY(0); } - if (local.y() > ui->videoWidget->height()) { - local.setY(ui->videoWidget->height()); + if (local.y() > m_videoWidget->height()) { + local.setY(m_videoWidget->height()); } event->setLocalPos(local); - m_controller->mouseEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); + m_controller->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size()); } else { m_dragPosition = QPoint(0, 0); } @@ -300,12 +324,12 @@ void VideoForm::mouseReleaseEvent(QMouseEvent *event) void VideoForm::mouseMoveEvent(QMouseEvent *event) { - if (ui->videoWidget->geometry().contains(event->pos())) { + if (m_videoWidget->geometry().contains(event->pos())) { if (!m_controller) { return; } - event->setLocalPos(ui->videoWidget->mapFrom(this, event->localPos().toPoint())); - m_controller->mouseEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); + event->setLocalPos(m_videoWidget->mapFrom(this, event->localPos().toPoint())); + m_controller->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size()); } else if (!m_dragPosition.isNull()){ if (event->buttons() & Qt::LeftButton) { move(event->globalPos() - m_dragPosition); @@ -316,11 +340,11 @@ void VideoForm::mouseMoveEvent(QMouseEvent *event) void VideoForm::wheelEvent(QWheelEvent *event) { - if (ui->videoWidget->geometry().contains(event->pos())) { + if (m_videoWidget->geometry().contains(event->pos())) { if (!m_controller) { return; } - QPointF pos = ui->videoWidget->mapFrom(this, event->pos()); + QPointF pos = m_videoWidget->mapFrom(this, event->pos()); /* QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, @@ -328,7 +352,7 @@ void VideoForm::wheelEvent(QWheelEvent *event) */ QWheelEvent wheelEvent(pos, event->globalPosF(), event->delta(), event->buttons(), event->modifiers(), event->orientation()); - m_controller->wheelEvent(&wheelEvent, ui->videoWidget->frameSize(), ui->videoWidget->size()); + m_controller->wheelEvent(&wheelEvent, m_videoWidget->frameSize(), m_videoWidget->size()); } } @@ -354,7 +378,7 @@ void VideoForm::keyPressEvent(QKeyEvent *event) return; } - m_controller->keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); + m_controller->keyEvent(event, m_videoWidget->frameSize(), m_videoWidget->size()); } void VideoForm::keyReleaseEvent(QKeyEvent *event) @@ -362,7 +386,7 @@ void VideoForm::keyReleaseEvent(QKeyEvent *event) if (!m_controller) { return; } - m_controller->keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); + m_controller->keyEvent(event, m_videoWidget->frameSize(), m_videoWidget->size()); } void VideoForm::paintEvent(QPaintEvent *paint) @@ -382,6 +406,32 @@ void VideoForm::showEvent(QShowEvent *event) } } +void VideoForm::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + QSize goodSize = ui->keepRadioWidget->goodSize(); + if (goodSize.isEmpty()) { + return; + } + QSize curSize = size(); + // 限制VideoForm尺寸不能小于keepRadioWidget good size + if (m_widthHeightRatio > 1.0f) { + // hor + if (curSize.height() <= goodSize.height()) { + setMinimumHeight(goodSize.height()); + } else { + setMinimumHeight(0); + } + } else { + // ver + if (curSize.width() <= goodSize.width()) { + setMinimumWidth(goodSize.width()); + } else { + setMinimumWidth(0); + } + } +} + void VideoForm::dragEnterEvent(QDragEnterEvent *event) { event->acceptProposedAction(); diff --git a/QtScrcpy/device/ui/videoform.h b/QtScrcpy/device/ui/videoform.h index 782775d..aaf598a 100644 --- a/QtScrcpy/device/ui/videoform.h +++ b/QtScrcpy/device/ui/videoform.h @@ -12,6 +12,7 @@ struct AVFrame; class ToolForm; class Controller; class FileHandler; +class QYUVOpenGLWidget; class VideoForm : public QWidget { Q_OBJECT @@ -21,7 +22,6 @@ public: void switchFullScreen(); void staysOnTop(bool top = true); - void updateScreenRatio(const QSize &newSize); void updateShowSize(const QSize &newSize); void updateRender(const AVFrame *frame); void setController(Controller *controller); @@ -42,6 +42,7 @@ private: void initUI(); void showToolForm(bool show = true); + void moveCenter(); protected: void mousePressEvent(QMouseEvent *event); @@ -53,6 +54,7 @@ protected: void paintEvent(QPaintEvent *); void showEvent(QShowEvent *event); + void resizeEvent(QResizeEvent *event); void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); @@ -64,12 +66,14 @@ private: Ui::videoForm *ui; QPointer m_toolForm; QPointer m_loadingWidget; + QPointer m_videoWidget; //inside member QSize m_frameSize; QPoint m_dragPosition; float m_widthHeightRatio = 0.5f; bool m_skin = true; + QPoint m_fullScreenBeforePos; //outside member QString m_serial = ""; diff --git a/QtScrcpy/device/ui/videoform.ui b/QtScrcpy/device/ui/videoform.ui index e0e2230..6de4468 100644 --- a/QtScrcpy/device/ui/videoform.ui +++ b/QtScrcpy/device/ui/videoform.ui @@ -39,15 +39,15 @@ 0 - + - QYUVOpenGLWidget + KeepRadioWidget QWidget -
qyuvopenglwidget.h
+
keepradiowidget.h
1
diff --git a/QtScrcpy/res/Info_mac.plist b/QtScrcpy/res/Info_mac.plist index 6a10390..2ee571c 100644 --- a/QtScrcpy/res/Info_mac.plist +++ b/QtScrcpy/res/Info_mac.plist @@ -19,17 +19,17 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.2.0 + 1.2.1 CFBundleSupportedPlatforms MacOSX CFBundleVersion - 1.2.0 + 1.2.1 LSMinimumSystemVersion 10.10 NSAppleEventsUsageDescription - + NSHumanReadableCopyright Copyright © 2018-2038 rankun. All rights reserved. NSMainStoryboardFile diff --git a/QtScrcpy/uibase/keepradiowidget.cpp b/QtScrcpy/uibase/keepradiowidget.cpp new file mode 100644 index 0000000..cd86516 --- /dev/null +++ b/QtScrcpy/uibase/keepradiowidget.cpp @@ -0,0 +1,75 @@ +#include +#include + +#include "keepradiowidget.h" + +KeepRadioWidget::KeepRadioWidget(QWidget *parent) : + QWidget(parent) +{ + +} + +KeepRadioWidget::~KeepRadioWidget() +{ + +} + +void KeepRadioWidget::setWidget(QWidget *w) +{ + if (!w) { + return; + } + w->setParent(this); + m_subWidget = w; +} + +void KeepRadioWidget::setWidthHeightRadio(float widthHeightRadio) +{ + if (abs(m_widthHeightRadio - widthHeightRadio) < 0.000001f) { + return; + } + m_widthHeightRadio = widthHeightRadio; + adjustSubWidget(); +} + +const QSize KeepRadioWidget::goodSize() +{ + if (!m_subWidget || m_widthHeightRadio < 0.0f) { + return QSize(); + } + return m_subWidget->size(); +} + +void KeepRadioWidget::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + adjustSubWidget(); +} + +void KeepRadioWidget::adjustSubWidget() +{ + if (!m_subWidget) { + return; + } + + QSize curSize = size(); + QPoint pos(0, 0); + int width = 0; + int height = 0; + if (m_widthHeightRadio > 1.0f) { + // base width + width = curSize.width(); + height = curSize.width() / m_widthHeightRadio; + pos.setY((curSize.height() - height) / 2); + } else if (m_widthHeightRadio > 0.0f) { + // base height + height = curSize.height(); + width = curSize.height() * m_widthHeightRadio; + pos.setX((curSize.width() - width) / 2); + } else { + // full widget + height = curSize.height(); + width = curSize.width(); + } + m_subWidget->setGeometry(pos.x(), pos.y(), width, height); +} diff --git a/QtScrcpy/uibase/keepradiowidget.h b/QtScrcpy/uibase/keepradiowidget.h new file mode 100644 index 0000000..8baa992 --- /dev/null +++ b/QtScrcpy/uibase/keepradiowidget.h @@ -0,0 +1,29 @@ +#ifndef KEEPRADIOWIDGET_H +#define KEEPRADIOWIDGET_H + +#include +#include + +class KeepRadioWidget : public QWidget +{ + Q_OBJECT +public: + explicit KeepRadioWidget(QWidget *parent = nullptr); + ~KeepRadioWidget(); + + void setWidget(QWidget* w); + void setWidthHeightRadio(float widthHeightRadio); + const QSize goodSize(); + +protected: + void resizeEvent(QResizeEvent *event); + void adjustSubWidget(); + +private: + float m_widthHeightRadio = -1.0f; + QPointer m_subWidget; + QSize m_goodSize; + +}; + +#endif // KEEPRADIOWIDGET_H diff --git a/QtScrcpy/uibase/magneticwidget.cpp b/QtScrcpy/uibase/magneticwidget.cpp index 7a61b81..6fd29be 100644 --- a/QtScrcpy/uibase/magneticwidget.cpp +++ b/QtScrcpy/uibase/magneticwidget.cpp @@ -3,7 +3,6 @@ #include #include "magneticwidget.h" -#include "ui_magneticwidget.h" MagneticWidget::MagneticWidget(QWidget* adsorbWidget, AdsorbPositions adsorbPos) : QWidget(Q_NULLPTR) diff --git a/QtScrcpy/uibase/magneticwidget.ui b/QtScrcpy/uibase/magneticwidget.ui deleted file mode 100644 index 0b3e9eb..0000000 --- a/QtScrcpy/uibase/magneticwidget.ui +++ /dev/null @@ -1,19 +0,0 @@ - - - MagneticWidget - - - - 0 - 0 - 400 - 300 - - - - - - - - - diff --git a/QtScrcpy/uibase/uibase.pri b/QtScrcpy/uibase/uibase.pri index 75c0643..ae4858b 100644 --- a/QtScrcpy/uibase/uibase.pri +++ b/QtScrcpy/uibase/uibase.pri @@ -1,8 +1,9 @@ -FORMS += \ - $$PWD/magneticwidget.ui +FORMS += HEADERS += \ + $$PWD/keepradiowidget.h \ $$PWD/magneticwidget.h SOURCES += \ + $$PWD/keepradiowidget.cpp \ $$PWD/magneticwidget.cpp diff --git a/QtScrcpy/util/config.cpp b/QtScrcpy/util/config.cpp index 6fb2e52..630faea 100644 --- a/QtScrcpy/util/config.cpp +++ b/QtScrcpy/util/config.cpp @@ -169,6 +169,8 @@ int Config::getDesktopOpenGL() int Config::getSkin() { + // force disable skin + return 0; int skin = 1; m_settings->beginGroup(GROUP_COMMON); skin = m_settings->value(COMMON_SKIN_KEY, COMMON_SKIN_DEF).toInt(); diff --git a/config/config.ini b/config/config.ini index d13d8cd..b77dcf2 100644 --- a/config/config.ini +++ b/config/config.ini @@ -1,4 +1,4 @@ -[common] +[common] # 窗口标题 WindowTitle=QtScrcpy # 录制文件保存路径(必须以/作为分隔符) @@ -7,8 +7,6 @@ RecordPath= PushFilePath=/sdcard/ # 最大fps(仅支持Android 10以上) MaxFps=60 -# 是否显示手机皮肤,0不显示 -UseSkin=1 # 是否渲染过期视频帧(跳过过期视频帧意味着更低的延迟) RenderExpiredFrames=0 # 视频解码方式:-1 自动,0 软解,1 dx硬解,2 opengl硬解 diff --git a/docs/TODO.md b/docs/TODO.md index 4453c80..cfec2f0 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -8,7 +8,6 @@ ## 中优先级 - 脚本 - 群控 -- 竖屏全屏不拉伸画面 - 软解 - opengles 3.0 兼容性参考[这里](https://github.com/libretro/glsl-shaders/blob/master/nnedi3/shaders/yuv-to-rgb-2x.glsl) @@ -16,8 +15,6 @@ - linux打包以及版本号 - 关于 - 旋转 -- 全屏画面拉伸 -- 拖拽保持窗口比例 # mark ## ffmpeg