重构:移除 RDP 管线并完善会话退出与串流过场
变更详情:删除 RDP 渲染管线,协议统一 Moonlight;退出三层设计与串流过场层落地 - 移除 rdp_session.*、FreeRDP 构建依赖与代码内协议概念,Moonlight 为唯一会话通道 - Ctrl+Alt+Shift+Q 退串流回列表(kiosk 兜底 + moonlight-qt 主路径);登录页去退出按钮 - 新增 TransitionOverlay:全屏过场层盖住串流启动闪烁,进程 CPU 首帧检测后淡出 - Sunshine 写入 sw_preset=ultrafast;实测推翻 x264 瓶颈结论(21.6FPS 帽子在虚拟显示/捕获节奏,CPU≈0%) - 文档:麒麟(101/.71)/Ubuntu(102/.72) 接入信息与四件事落地记录;MEMORY 根因修正
This commit is contained in:
1 parent
56b9f1faf3
commit
26fde0369e
21 files changed
+364
-923
No files matched your search
@@ -0,0 +1,131 @@
|
||||
#include "transition_overlay.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QFont>
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#include <QVariant>
|
||||
|
||||
namespace vdi {
|
||||
namespace {
|
||||
|
||||
constexpr int kTickMs = 400; // 省略号/旋轮动画与置顶保活周期
|
||||
constexpr int kFadeStepMs = 40; // 淡出步进周期
|
||||
constexpr int kFadeSteps = 25; // 全程约 1 秒淡出
|
||||
|
||||
const char* kSpinnerFrames[] = {"◐", "◓", "◑", "◒"};
|
||||
|
||||
} // namespace
|
||||
|
||||
TransitionOverlay::TransitionOverlay(QWidget* parent) : QWidget(parent) {
|
||||
// 独立置顶无边框窗口:串流启动后 moonlight-qt 会盖住 kiosk 主窗口,
|
||||
// 过场层必须压在它之上才起作用(onTick 周期性 raise 兜底)。
|
||||
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
|
||||
setStyleSheet(QStringLiteral("TransitionOverlay { background-color: #000000; }"));
|
||||
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
layout->setSpacing(28);
|
||||
|
||||
labelSpinner_ = new QLabel(this);
|
||||
QFont spinFont = labelSpinner_->font();
|
||||
spinFont.setPointSize(44);
|
||||
labelSpinner_->setFont(spinFont);
|
||||
labelSpinner_->setAlignment(Qt::AlignCenter);
|
||||
labelSpinner_->setStyleSheet(QStringLiteral("color: #2f6feb; background: transparent;"));
|
||||
layout->addStretch(1);
|
||||
layout->addWidget(labelSpinner_);
|
||||
|
||||
labelTitle_ = new QLabel(this);
|
||||
QFont titleFont = labelTitle_->font();
|
||||
titleFont.setPointSize(20);
|
||||
labelTitle_->setFont(titleFont);
|
||||
labelTitle_->setAlignment(Qt::AlignCenter);
|
||||
labelTitle_->setStyleSheet(QStringLiteral("color: #e6e9ef; background: transparent;"));
|
||||
layout->addWidget(labelTitle_);
|
||||
layout->addStretch(2);
|
||||
|
||||
tickTimer_ = new QTimer(this);
|
||||
connect(tickTimer_, &QTimer::timeout, this, &TransitionOverlay::onTick);
|
||||
fadeTimer_ = new QTimer(this);
|
||||
connect(fadeTimer_, &QTimer::timeout, this, &TransitionOverlay::onFadeStep);
|
||||
|
||||
// 活动期间吞掉本窗口的键盘/鼠标事件,避免误触下层页面
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
void TransitionOverlay::start(const QString& title) {
|
||||
tickTimer_->stop();
|
||||
fadeTimer_->stop();
|
||||
dots_ = 0;
|
||||
setWindowOpacity(1.0);
|
||||
setProperty("baseTitle", title);
|
||||
labelTitle_->setText(title);
|
||||
labelSpinner_->setText(QString::fromUtf8(kSpinnerFrames[0]));
|
||||
|
||||
showFullScreen();
|
||||
raise();
|
||||
activateWindow();
|
||||
grabKeyboard();
|
||||
grabMouse();
|
||||
tickTimer_->start(kTickMs);
|
||||
}
|
||||
|
||||
void TransitionOverlay::finish() {
|
||||
tickTimer_->stop();
|
||||
fadeTimer_->stop();
|
||||
releaseKeyboard();
|
||||
releaseMouse();
|
||||
hide();
|
||||
setWindowOpacity(1.0);
|
||||
}
|
||||
|
||||
void TransitionOverlay::onFirstFrame() {
|
||||
// 首帧已出画:停止动画并淡出;若尚未显示/已在淡出则忽略
|
||||
if (!isVisible() || fadeTimer_->isActive()) {
|
||||
return;
|
||||
}
|
||||
tickTimer_->stop();
|
||||
releaseKeyboard();
|
||||
releaseMouse();
|
||||
fadeTimer_->start(kFadeStepMs);
|
||||
}
|
||||
|
||||
void TransitionOverlay::onTick() {
|
||||
dots_ = (dots_ + 1) % 4;
|
||||
const QString base = property("baseTitle").toString();
|
||||
if (!base.isEmpty()) {
|
||||
labelTitle_->setText(base + QString(dots_, QLatin1Char('.')));
|
||||
}
|
||||
labelSpinner_->setText(QString::fromUtf8(kSpinnerFrames[dots_]));
|
||||
// X11 下 moonlight 的全屏窗口可能后映射,周期性抬回最上层
|
||||
raise();
|
||||
}
|
||||
|
||||
void TransitionOverlay::onFadeStep() {
|
||||
const double opacity = windowOpacity() - 1.0 / kFadeSteps;
|
||||
if (opacity <= 0.0) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
setWindowOpacity(opacity);
|
||||
}
|
||||
|
||||
bool TransitionOverlay::eventFilter(QObject* watched, QEvent* event) {
|
||||
if (watched == this && isVisible()) {
|
||||
switch (event->type()) {
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::KeyRelease:
|
||||
case QEvent::MouseButtonPress:
|
||||
case QEvent::MouseButtonRelease:
|
||||
case QEvent::MouseMove:
|
||||
case QEvent::Wheel:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
} // namespace vdi
|
||||
Reference in new issue
Block a user