fix(airplay): refactor restart logic , update tutorial video and update settings UI

This commit is contained in:
uncor3
2026-01-25 07:44:26 +00:00
parent ff1ffb62d4
commit 8831ac95ee
9 changed files with 56 additions and 28 deletions
+1 -1
View File
@@ -61,7 +61,7 @@
<file>resources/iphone-mockups/iphone-15.png</file>
<file>resources/iphone-mockups/iphone-16.png</file>
<file>resources/connect.png</file>
<file>resources/airplayer-tutorial.mp4</file>
<file>resources/airplay-tutorial.mp4</file>
<file>resources/ipad-mockups/ipad.png</file>
<file>DeveloperDiskImages.json</file>
<file>resources/keychain.mp4</file>
Binary file not shown.
Binary file not shown.
+24 -8
View File
@@ -55,6 +55,8 @@
#include <uxplay/renderers/video_renderer.h>
#include <uxplay/uxplay.h>
#include "toolboxwidget.h"
AirPlaySettings::AirPlaySettings()
: fps(SettingsManager::sharedInstance()->airplayFps())
{
@@ -67,6 +69,9 @@ QStringList AirPlaySettings::toArgs() const
// FPS
args << "-fps" << QString::number(fps);
// Allow new connections to take over
args << "-nohold";
return args;
}
@@ -86,12 +91,23 @@ void AirPlaySettingsDialog::setupUI()
QGroupBox *videoGroup = new QGroupBox("Video Settings");
QFormLayout *videoLayout = new QFormLayout(videoGroup);
m_fpsSpinBox = new QSpinBox();
m_fpsSpinBox->setRange(1, 255);
m_fpsSpinBox->setValue(SettingsManager::sharedInstance()->airplayFps());
m_fpsSpinBox->setToolTip("Set maximum allowed streaming framerate");
videoLayout->addRow("Max FPS:", m_fpsSpinBox);
// FPS Layout
QVBoxLayout *fpsLayout = new QVBoxLayout();
m_fpsComboBox = new QComboBox();
m_fpsComboBox->addItems({"24", "30", "60", "120"});
m_fpsComboBox->setCurrentText(
QString::number(SettingsManager::sharedInstance()->airplayFps()));
m_fpsComboBox->setToolTip("Set maximum allowed streaming framerate");
QLabel *fpsFootnote =
new QLabel("Note: Older devices may not support higher framerates. If "
"you are experiencing issues, set this to 30 FPS or lower.");
fpsFootnote->setWordWrap(true);
fpsFootnote->setStyleSheet("color: #666; font-size: 12px;");
fpsLayout->addWidget(m_fpsComboBox);
fpsLayout->addWidget(fpsFootnote);
videoLayout->addRow("Max FPS:", fpsLayout);
mainLayout->addWidget(videoGroup);
// Buttons
@@ -105,7 +121,7 @@ void AirPlaySettingsDialog::setupUI()
AirPlaySettings AirPlaySettingsDialog::getSettings() const
{
AirPlaySettings settings;
settings.fps = m_fpsSpinBox->value();
settings.fps = m_fpsComboBox->currentText().toInt();
return settings;
}
@@ -218,7 +234,7 @@ void AirPlayWindow::setupTutorialVideo()
QSizePolicy::Expanding);
m_tutorialPlayer->setVideoOutput(m_tutorialVideoWidget);
m_tutorialPlayer->setSource(QUrl("qrc:/resources/airplayer-tutorial.mp4"));
m_tutorialPlayer->setSource(QUrl("qrc:/resources/airplay-tutorial.mp4"));
m_tutorialVideoWidget->setAspectRatioMode(
Qt::AspectRatioMode::KeepAspectRatioByExpanding);
m_tutorialVideoWidget->setStyleSheet(
@@ -273,7 +289,7 @@ void AirPlayWindow::showSettingsDialog()
QMessageBox::information(this, "Settings Saved",
"AirPlay will be restarted to apply the new "
"settings.");
emit restartRequested();
ToolboxWidget::sharedInstance()->restartAirPlayWindow();
}
}
+1 -6
View File
@@ -26,7 +26,6 @@
#include <QComboBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QDoubleSpinBox>
#include <QFormLayout>
#include <QGroupBox>
#include <QLabel>
@@ -34,7 +33,6 @@
#include <QMediaPlayer>
#include <QMutex>
#include <QPushButton>
#include <QSpinBox>
#include <QStackedWidget>
#include <QThread>
#include <QTimer>
@@ -89,7 +87,7 @@ public:
private:
void setupUI();
QSpinBox *m_fpsSpinBox;
QComboBox *m_fpsComboBox;
AirPlaySettings m_settings;
};
@@ -110,9 +108,6 @@ private slots:
void onV4L2CheckboxToggled(bool enabled);
#endif
signals:
void restartRequested();
private:
void setupUI();
void setupTutorialVideo();
+1 -1
View File
@@ -162,7 +162,7 @@ MainWindow::MainWindow(QWidget *parent)
m_ZTabWidget->addTab(m_mainStackedWidget, "iDevice");
auto *appsWidgetTab =
m_ZTabWidget->addTab(AppsWidget::sharedInstance(), "Apps");
m_ZTabWidget->addTab(new ToolboxWidget(this), "Toolbox");
m_ZTabWidget->addTab(ToolboxWidget::sharedInstance(), "Toolbox");
auto *jailbrokenWidget = new JailbrokenWidget(this);
m_ZTabWidget->addTab(jailbrokenWidget, "Jailbroken");
+26 -11
View File
@@ -79,6 +79,12 @@ bool enterRecoveryMode(iDescriptorDevice *device)
}
}
ToolboxWidget *ToolboxWidget::sharedInstance()
{
static ToolboxWidget *instance = new ToolboxWidget();
return instance;
}
ToolboxWidget::ToolboxWidget(QWidget *parent) : QWidget{parent}
{
setupUI();
@@ -428,17 +434,6 @@ void ToolboxWidget::onToolboxClicked(iDescriptorTool tool, bool requiresDevice)
m_airplayWindow = new AirPlayWindow();
connect(m_airplayWindow, &QObject::destroyed, this,
[this]() { m_airplayWindow = nullptr; });
connect(m_airplayWindow, &AirPlayWindow::restartRequested, this,
[this]() {
if (m_airplayWindow) {
m_airplayWindow->close();
}
m_airplayWindow = new AirPlayWindow();
m_airplayWindow->setAttribute(Qt::WA_DeleteOnClose);
m_airplayWindow->setWindowFlag(Qt::Window);
m_airplayWindow->resize(400, 300);
m_airplayWindow->show();
});
m_airplayWindow->setAttribute(Qt::WA_DeleteOnClose);
m_airplayWindow->setWindowFlag(Qt::Window);
m_airplayWindow->resize(400, 300);
@@ -645,4 +640,24 @@ void ToolboxWidget::_enterRecoveryMode(iDescriptorDevice *device)
_msgBox.setText("Failed to enter recovery mode.");
}
_msgBox.exec();
}
void ToolboxWidget::restartAirPlayWindow()
{
if (!m_airplayWindow) {
onToolboxClicked(iDescriptorTool::Airplayer, false);
return;
}
connect(
m_airplayWindow, &QObject::destroyed, this,
[this]() {
// give some time for cleanup
QTimer::singleShot(100, this, [this]() {
onToolboxClicked(iDescriptorTool::Airplayer, false);
});
},
Qt::SingleShotConnection);
m_airplayWindow->close();
}
+2
View File
@@ -47,6 +47,8 @@ public:
static void restartDevice(iDescriptorDevice *device);
static void shutdownDevice(iDescriptorDevice *device);
static void _enterRecoveryMode(iDescriptorDevice *device);
static ToolboxWidget *sharedInstance();
void restartAirPlayWindow();
private slots:
void onDeviceSelectionChanged();
void onToolboxClicked(iDescriptorTool tool, bool requiresDevice);