Standardize macOS detection and prompt on close

Unify platform checks to use Q_OS_MACOS for Qt6 compatibility and switch the QtScrcpyCore submodule URL to HTTPS for easier cloning.
Introduce a confirmation dialog on window close that lets users choose between minimizing to tray or exiting the app.

Improve project hygiene by extending .gitignore rules for IDE and cache files, adding missing QDebug includes, and applying minor formatting tweaks for consistency.

Standardize macOS detection and add close prompt

Unify all platform checks to Q_OS_MACOS for Qt6 compatibility.
Switch submodule URL to HTTPS for easier cloning.
Introduce a close confirmation dialog letting users minimize to tray or exit.
Improve project hygiene: extend .gitignore for IDE/cache files, add missing QDebug includes, and apply formatting tweaks.
This commit is contained in:
hupochun 2025-05-03 01:41:40 +08:00
commit efa41142b4
7 changed files with 79 additions and 45 deletions

4
.gitignore vendored
View file

@ -15,3 +15,7 @@ build-*
userdata.ini userdata.ini
Info_Mac.plist Info_Mac.plist
/ci/build_temp /ci/build_temp
.vscode/
.gitignore
.gitmodules
.cache/

2
.gitmodules vendored
View file

@ -1,3 +1,3 @@
[submodule "QtScrcpy/QtScrcpyCore"] [submodule "QtScrcpy/QtScrcpyCore"]
path = QtScrcpy/QtScrcpyCore path = QtScrcpy/QtScrcpyCore
url = git@github.com:barry-ran/QtScrcpyCore.git url = https://github.com/barry-ran/QtScrcpyCore.git

View file

@ -28,7 +28,7 @@ int main(int argc, char *argv[])
qputenv("QTSCRCPY_CONFIG_PATH", "../../../config"); qputenv("QTSCRCPY_CONFIG_PATH", "../../../config");
#endif #endif
#ifdef Q_OS_OSX #ifdef Q_OS_MACOS
qputenv("QTSCRCPY_ADB_PATH", "../../../../../../QtScrcpy/QtScrcpyCore/src/third_party/adb/mac/adb"); qputenv("QTSCRCPY_ADB_PATH", "../../../../../../QtScrcpy/QtScrcpyCore/src/third_party/adb/mac/adb");
qputenv("QTSCRCPY_SERVER_PATH", "../../../../../../QtScrcpy/QtScrcpyCore/src/third_party/scrcpy-server"); qputenv("QTSCRCPY_SERVER_PATH", "../../../../../../QtScrcpy/QtScrcpyCore/src/third_party/scrcpy-server");
qputenv("QTSCRCPY_KEYMAP_PATH", "../../../../../../keymap"); qputenv("QTSCRCPY_KEYMAP_PATH", "../../../../../../keymap");
@ -92,7 +92,7 @@ int main(int argc, char *argv[])
} }
installTranslator(); installTranslator();
#if defined(Q_OS_WIN32) || defined(Q_OS_OSX) #if defined(Q_OS_WIN32) || defined(Q_OS_MACOS)
MouseTap::getInstance()->initMouseEventTap(); MouseTap::getInstance()->initMouseEventTap();
#endif #endif
@ -126,7 +126,7 @@ int main(int argc, char *argv[])
int ret = a.exec(); int ret = a.exec();
delete g_mainDlg; delete g_mainDlg;
#if defined(Q_OS_WIN32) || defined(Q_OS_OSX) #if defined(Q_OS_WIN32) || defined(Q_OS_MACOS)
MouseTap::getInstance()->quitMouseEventTap(); MouseTap::getInstance()->quitMouseEventTap();
#endif #endif
return ret; return ret;

View file

@ -5,6 +5,10 @@
#include <QRandomGenerator> #include <QRandomGenerator>
#include <QTime> #include <QTime>
#include <QTimer> #include <QTimer>
#include <QDialog>
#include <QVBoxLayout>
#include <QRadioButton>
#include <QDialogButtonBox>
#include "config.h" #include "config.h"
#include "dialog.h" #include "dialog.h"
@ -291,13 +295,32 @@ void Dialog::slotActivated(QSystemTrayIcon::ActivationReason reason)
void Dialog::closeEvent(QCloseEvent *event) void Dialog::closeEvent(QCloseEvent *event)
{ {
// 弹出选择对话框
QDialog choiceDialog(this);
choiceDialog.setWindowTitle(tr("关闭选项"));
QVBoxLayout *layout = new QVBoxLayout(&choiceDialog);
QRadioButton *minimizeRadio = new QRadioButton(tr("最小化窗口"), &choiceDialog);
QRadioButton *exitRadio = new QRadioButton(tr("退出窗口"), &choiceDialog);
minimizeRadio->setChecked(true);
layout->addWidget(minimizeRadio);
layout->addWidget(exitRadio);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &choiceDialog);
layout->addWidget(buttonBox);
// 设置按钮为“确认”和“取消”
buttonBox->button(QDialogButtonBox::Ok)->setText(tr("确认"));
buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("取消"));
connect(buttonBox, &QDialogButtonBox::accepted, &choiceDialog, &QDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, &choiceDialog, &QDialog::reject);
if (choiceDialog.exec() == QDialog::Accepted) {
if (minimizeRadio->isChecked()) {
this->hide(); this->hide();
if (!Config::getInstance().getTrayMessageShown()) { if (!Config::getInstance().getTrayMessageShown()) {
Config::getInstance().setTrayMessageShown(true); Config::getInstance().setTrayMessageShown(true);
m_hideIcon->showMessage(tr("Notice"), m_hideIcon->showMessage(tr("Notice"), tr("Hidden here!"), QSystemTrayIcon::Information, 3000);
tr("Hidden here!"), }
QSystemTrayIcon::Information, } else {
3000); qApp->quit();
}
} }
event->ignore(); event->ignore();
} }

View file

@ -19,9 +19,9 @@
#include "config.h" #include "config.h"
#include "iconhelper.h" #include "iconhelper.h"
#include "mousetap/mousetap.h"
#include "qyuvopenglwidget.h" #include "qyuvopenglwidget.h"
#include "toolform.h" #include "toolform.h"
#include "mousetap/mousetap.h"
#include "ui_videoform.h" #include "ui_videoform.h"
#include "videoform.h" #include "videoform.h"
@ -54,7 +54,7 @@ void VideoForm::initUI()
m_widthHeightRatio = 1.0f * phone.width() / phone.height(); m_widthHeightRatio = 1.0f * phone.width() / phone.height();
} }
#ifndef Q_OS_OSX #ifndef Q_OS_MACOS
// mac下去掉标题栏影响showfullscreen // mac下去掉标题栏影响showfullscreen
// 去掉标题栏 // 去掉标题栏
setWindowFlags(windowFlags() | Qt::FramelessWindowHint); setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
@ -96,7 +96,7 @@ QRect VideoForm::getGrabCursorRect()
rc.setY(rc.y() + 10); rc.setY(rc.y() + 10);
rc.setWidth(rc.width() - 20); rc.setWidth(rc.width() - 20);
rc.setHeight(rc.height() - 20); rc.setHeight(rc.height() - 20);
#elif defined(Q_OS_OSX) #elif defined(Q_OS_MACOS)
rc = m_videoWidget->geometry(); rc = m_videoWidget->geometry();
rc.setTopLeft(ui->keepRatioWidget->mapToGlobal(rc.topLeft())); rc.setTopLeft(ui->keepRatioWidget->mapToGlobal(rc.topLeft()));
rc.setBottomRight(ui->keepRatioWidget->mapToGlobal(rc.bottomRight())); rc.setBottomRight(ui->keepRatioWidget->mapToGlobal(rc.bottomRight()));
@ -474,7 +474,7 @@ void VideoForm::switchFullScreen()
// fullscreen window will move (0,0). qt bug? // fullscreen window will move (0,0). qt bug?
move(m_fullScreenBeforePos); move(m_fullScreenBeforePos);
#ifdef Q_OS_OSX #ifdef Q_OS_MACOS
//setWindowFlags(windowFlags() | Qt::FramelessWindowHint); //setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
//show(); //show();
#endif #endif
@ -497,7 +497,7 @@ void VideoForm::switchFullScreen()
m_fullScreenBeforePos = pos(); m_fullScreenBeforePos = pos();
// 这种临时增加标题栏再全屏的方案会导致收不到mousemove事件导致setmousetrack失效 // 这种临时增加标题栏再全屏的方案会导致收不到mousemove事件导致setmousetrack失效
// mac fullscreen must show title bar // mac fullscreen must show title bar
#ifdef Q_OS_OSX #ifdef Q_OS_MACOS
//setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); //setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint);
#endif #endif
showToolForm(false); showToolForm(false);
@ -713,8 +713,17 @@ void VideoForm::wheelEvent(QWheelEvent *event)
QPointF pos = m_videoWidget->mapFrom(this, event->pos()); QPointF pos = m_videoWidget->mapFrom(this, event->pos());
QWheelEvent wheelEvent( QWheelEvent wheelEvent(
pos, event->globalPosF(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), pos,
event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted()); event->globalPosF(),
event->pixelDelta(),
event->angleDelta(),
event->delta(),
event->orientation(),
event->buttons(),
event->modifiers(),
event->phase(),
event->source(),
event->inverted());
#endif #endif
emit device->wheelEvent(&wheelEvent, m_videoWidget->frameSize(), m_videoWidget->size()); emit device->wheelEvent(&wheelEvent, m_videoWidget->frameSize(), m_videoWidget->size());
} }
@ -759,9 +768,7 @@ void VideoForm::showEvent(QShowEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
if (!isFullScreen() && this->show_toolbar) { if (!isFullScreen() && this->show_toolbar) {
QTimer::singleShot(500, this, [this](){ QTimer::singleShot(500, this, [this]() { showToolForm(this->show_toolbar); });
showToolForm(this->show_toolbar);
});
} }
} }

View file

@ -1,10 +1,10 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug>
#include <QFileInfo> #include <QFileInfo>
#include <QSettings> #include <QSettings>
#include <QDebug>
#include "config.h" #include "config.h"
#ifdef Q_OS_OSX #ifdef Q_OS_MACOS
#include "path.h" #include "path.h"
#endif #endif
@ -145,7 +145,7 @@ const QString &Config::getConfigPath()
// default application dir // default application dir
// mac系统当从finder打开app时默认工作目录不再是可执行程序的目录了而是"/" // mac系统当从finder打开app时默认工作目录不再是可执行程序的目录了而是"/"
// 而Qt的获取工作目录的api都依赖QCoreApplication的初始化所以使用mac api获取当前目录 // 而Qt的获取工作目录的api都依赖QCoreApplication的初始化所以使用mac api获取当前目录
#ifdef Q_OS_OSX #ifdef Q_OS_MACOS
// get */QtScrcpy.app path // get */QtScrcpy.app path
s_configPath = Path::GetCurrentPath(); s_configPath = Path::GetCurrentPath();
s_configPath += "/Contents/MacOS/config"; s_configPath += "/Contents/MacOS/config";

View file

@ -4,7 +4,7 @@
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
#include "winmousetap.h" #include "winmousetap.h"
#endif #endif
#ifdef Q_OS_OSX #ifdef Q_OS_MACOS
#include "cocoamousetap.h" #include "cocoamousetap.h"
#endif #endif
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
@ -18,7 +18,7 @@ MouseTap *MouseTap::getInstance()
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
s_instance = new WinMouseTap(); s_instance = new WinMouseTap();
#endif #endif
#ifdef Q_OS_OSX #ifdef Q_OS_MACOS
s_instance = new CocoaMouseTap(); s_instance = new CocoaMouseTap();
#endif #endif
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX