// Kiosk 主窗口 // // 产品流程编排:开机 -> 桌面列表 -> 获取连接票据 -> Moonlight 会话 -> 返回列表。 #ifndef KIOSK_SHELL_MAIN_WINDOW_H #define KIOSK_SHELL_MAIN_WINDOW_H #include #include #include #include #include "config.h" #include "desktop_service.h" #include "desktop_session.h" #include "moonlight_session.h" #include "state_machine.h" class QStackedWidget; class QStatusBar; class QTimer; class QEvent; class QShowEvent; class QWidget; namespace vdi { class LoginPage; class DesktopListPage; class TransitionOverlay; class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget* parent = nullptr); ~MainWindow() override; protected: void showEvent(QShowEvent* event) override; bool eventFilter(QObject* watched, QEvent* event) override; private slots: void onLoginRequested(const QString& username, const QString& password); void onDesktopSelected(const QString& desktopId); void onEditDesktopRequested(const QString& desktopId); void onQuitRequested(); void onMenuAction(int action); private: enum class ConnectionPhase { kIdle, kTicket, kProcessStart, kStreamReady, kSession, }; void setupUi(); void setupHotkey(); void setupHeartbeat(); void onStateChanged(vdi::State from, vdi::State to, const QString& detail); void refreshDesktopList(); bool startMoonlightSession(const ConnectionTicket& ticket, quint64 attempt); void onMoonlightEvent(quint64 attempt, const MoonlightSession::Event& event); void waitForMoonlightWindow(quint64 attempt); void stopSessions(); void stopSessions(bool invalidateAttempt); void releasePlatformSessionAfterStop(const QString& id); void failConnection(quint64 attempt, const QString& message); void armConnectionTimeout(quint64 attempt, ConnectionPhase phase, int timeoutMs); void logConnectionPhase(quint64 attempt, const QString& phase, const QString& result = QString(), const QString& error = QString()); void showLogin(); void showDesktopList(); void updateStatusBar(const QString& text); void setKioskInputGuard(bool enabled); void applyKioskSurface(); void presentKioskSurface(); void showReturnCover(); void hideReturnCover(); void releaseReturnCoverWhenReady(); void retryKeyboardGrab(); StateMachine fsm_; DesktopService desktopService_; std::unique_ptr moonlightSession_; ConnectionTicket activeTicket_; QString currentUser_; QString connectingDesktopId_; std::vector desktops_; QPointer loginPage_; QPointer desktopListPage_; QStackedWidget* stack_ = nullptr; QStatusBar* statusBar_ = nullptr; TransitionOverlay* overlay_ = nullptr; QTimer* connectionTimer_ = nullptr; QTimer* heartbeatTimer_ = nullptr; QElapsedTimer connectionClock_; QElapsedTimer phaseClock_; quint64 connectionAttempt_ = 0; ConnectionPhase connectionPhase_ = ConnectionPhase::kIdle; TerminalConfig config_; QWidget* returnCover_ = nullptr; bool kioskInputGuard_ = true; bool keyboardGrabActive_ = false; bool keyboardGrabRetryPending_ = false; #ifdef Q_OS_UNIX void* grabDisplay_ = nullptr; #endif }; } // namespace vdi #endif // KIOSK_SHELL_MAIN_WINDOW_H