Upgrade treeland-ddm protocol and unify GreeterProxy with Wayland#810
Upgrade treeland-ddm protocol and unify GreeterProxy with Wayland#810wineee wants to merge 4 commits intolinuxdeepin:masterfrom
Conversation
In this upgrade we rewrite all treeland-ddm interactions, includes those originally in SocketServer / GreeterProxy, into wayland communication. There's only one true treeland-ddm interaction which should on behalf of the Wayland protocol.
With the upgrade we did in previous commit, communication with ddm using QLocalSocket is not needed now, and we shall reform GreeterProxy, the communication method with our display manager the DDM, to use the newly formed Wayland protocol.
Although the logind session id is exactly an integer in current systemd-logind, but this is an UB according to systemd documentation. Systemd advertise us to treat it as a string and we shall adapt it.
The compositor now provides separate user-level switches for workspace, maximize, minimize, show desktop, launchpad, layer shell, and window open/close animations. When an animation is disabled, treeland now applies the target state immediately instead of keeping the old window geometry or creating the workspace switcher black background. Log: support disabling compositor animations Influence:
|
Skipping CI for Draft Pull Request. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: wineee The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Reviewer's GuideReplaces the legacy QLocalSocket-based DDM greeter protocol with a new Treeland Wayland-based treeland-ddm v2 interface, propagates session IDs to be strings instead of ints, and adds fine‑grained configuration-driven control over window/workspace animations and state transitions across the compositor. Sequence diagram for Wayland-based DDM login via GreeterProxysequenceDiagram
actor User
participant GreeterUI
participant GreeterProxy
participant DDMInterfaceV2 as DDMInterfaceV2
participant DDM as DDM_Daemon
participant Logind as Logind_Manager
participant Helper
participant SessionManager
participant UserModel
participant SessionModel
User->>GreeterUI: Enter credentials
GreeterUI->>GreeterProxy: login(user, password, sessionIndex)
alt DDMInterfaceV2 isValid
GreeterProxy->>SessionModel: index(sessionIndex, 0)
SessionModel-->>GreeterProxy: sessionType, sessionFile
GreeterProxy->>DDMInterfaceV2: login(user, password, sessionType, sessionFile)
DDMInterfaceV2-->>DDM: treeland_ddm_v2.login
DDM-->>Logind: Create session
Logind-->>DDM: Session created(id, username)
DDM-->>DDMInterfaceV2: user_logged_in(username, session)
DDMInterfaceV2-->>GreeterProxy: userLoggedIn(username, session)
GreeterProxy->>UserModel: updateUserLoginState(username, true)
GreeterProxy->>UserModel: userLoggedIn(username, session)
UserModel-->>SessionManager: updateActiveUserSession(username, session)
SessionManager-->>Helper: activeSession changed
else DDMInterfaceV2 invalid
GreeterProxy->>GreeterProxy: localValidation(user, password)
alt localValidation success
GreeterProxy->>GreeterProxy: setLock(false)
else localValidation failed
GreeterProxy-->>GreeterUI: failedAttemptsChanged
end
end
Class diagram for new DDMInterfaceV2-based greeter/session integrationclassDiagram
class DDMInterfaceV2 {
<<QObject, WServerInterface>>
+QByteArrayView interfaceName()
+void setHandle(handle: wl_resource*)
+static QString authErrorToString(error: uint32_t)
+void login(username: QString, password: QString, sessionType: DDM_Session_Type, sessionFile: QString)
+void logout(session: QString)
+void lock(session: QString)
+void unlock(session: QString, password: QString)
+void powerOff()
+void reboot()
+void suspend()
+void hibernate()
+void hybridSleep()
+void switchToVt(vtnr: int)
+void connected()
+void disconnected()
+void capabilities(capabilities: uint32_t)
+void userLoggedIn(username: QString, session: QString)
+void authenticationFailed(error: uint32_t)
-wl_global* m_global
-wl_resource* m_handle
}
class GreeterProxy {
+GreeterProxy(parent: QObject*)
+~GreeterProxy()
+void connectDDM(interface: DDMInterfaceV2*)
+void powerOff()
+void reboot()
+void suspend()
+void hibernate()
+void hybridSleep()
+void login(user: QString, password: QString, sessionIndex: int)
+void unlock(user: QString, password: QString)
+void logout()
+void lock()
+void capabilities(capabilities: uint32_t)
+void userLoggedIn(username: QString, session: QString)
+void authenticationFailed(error: uint32_t)
+void onSessionNew(id: QString, path: QDBusObjectPath)
+void onSessionRemoved(id: QString, path: QDBusObjectPath)
+void onSessionLock()
+void onSessionUnlock()
-DDMInterfaceV2* m_ddmInterface
-LockScreen* m_lockScreen
-QString m_hostName
-bool m_canPowerOff
-bool m_canReboot
-bool m_canSuspend
-bool m_canHibernate
-bool m_canHybridSleep
-int m_failedAttempts
-bool m_showShutdownView
-bool m_showAnimation
-bool m_hasActiveSession
}
class Helper {
+static Helper* instance()
+void init(treeland: Treeland)
+UserModel* userModel() const
+SessionModel* sessionModel() const
+DDMInterfaceV2* ddmInterfaceV2() const
+SessionManager* sessionManager() const
+void showLockScreen(withAnimation: bool)
+void activateSession()
+void deactivateSession()
+void enableRender()
+void disableRender()
-DDMInterfaceV2* m_ddmInterfaceV2
-GreeterProxy* m_greeterProxy
-SessionManager* m_sessionManager
-UserModel* m_userModel
-SessionModel* m_sessionModel
}
class Session {
+~Session()
+QString id() const
+uid_t uid() const
+const QString& username() const
+WSocket* socket() const
-QString m_id
-uid_t m_uid
-QString m_username
-WSocket* m_socket
-WXWayland* m_xwayland
}
class SessionManager {
+bool activeSocketEnabled() const
+void setActiveSocketEnabled(newEnabled: bool)
+void updateActiveUserSession(username: QString, id: QString)
+void removeSession(session: shared_ptr~Session~)
+shared_ptr~Session~ sessionForId(id: QString) const
+shared_ptr~Session~ sessionForUid(uid: uid_t) const
+shared_ptr~Session~ sessionForUser(username: QString) const
+shared_ptr~Session~ sessionForXWayland(xwayland: WXWayland*) const
+shared_ptr~Session~ activeSession() const
+void sessionChanged()
-shared_ptr~Session~ ensureSession(id: QString, username: QString)
-weak_ptr~Session~ m_activeSession
-QList~shared_ptr~Session~~ m_sessions
}
class UserModel {
+QString currentUserName() const
+void setCurrentUserName(username: QString)
+void updateUserLoginState(username: QString, loggedIn: bool)
+QSharedPointer~User~ getUser(username: QString) const
+void userLoggedIn(username: QString, session: QString)
}
DDMInterfaceV2 ..|> Waylib_Server_WServerInterface
GreeterProxy --> DDMInterfaceV2 : uses
Helper --> DDMInterfaceV2 : owns
Helper --> GreeterProxy : owns
Helper --> SessionManager : owns
Helper --> UserModel : owns
SessionManager --> Session : manages
GreeterProxy --> Helper : uses
GreeterProxy --> UserModel : uses
GreeterProxy --> SessionModel : uses
GreeterProxy --> SessionManager : uses
Helper ..> WServer : attach
Class diagram for animation and window state control in SurfaceWrapper and workspaceclassDiagram
class SurfaceWrapper {
+SurfaceWrapper(qmlEngine: QmlEngine*, container: SurfaceContainer*, shellSurface: QObject*, appId: QString, parent: QQuickItem*)
+SurfaceWrapper(original: SurfaceWrapper*, parent: QQuickItem*)
+State previousSurfaceState() const
+State surfaceState() const
+void setSurfaceState(newSurfaceState: State, performAnimation: bool = true)
+bool isNormal() const
+bool isMaximized() const
+bool isMinimized() const
+void requestMinimize(onAnimation: bool = true)
+void requestCancelMinimize(onAnimation: bool = true)
+void requestMaximize(onAnimation: bool = true)
+void requestCancelMaximize(onAnimation: bool = true)
+void requestToggleMaximize(onAnimation: bool = true)
+void requestFullscreen()
+void requestCancelFullscreen()
+void geometryChange(newGeo: QRectF, oldGeo: QRectF)
+void startMinimizeAnimation(iconGeometry: QRectF, direction: uint)
+void startMaximizeAnimation(geometry: QRectF, direction: uint)
+void startShowDesktopAnimation(show: bool)
+void onMinimizeAnimationFinished()
+void onShowDesktopAnimationFinished()
+void applyStateGeometry(targetGeometry: QRectF)
-void doSetSurfaceState(newSurfaceState: State)
-void startStateChangeAnimation(newSurfaceState: State, targetGeometry: QRectF)
-void updateClipRect()
-QPointer~QAbstractAnimation~ m_geometryAnimation
-QPointer~QAbstractAnimation~ m_windowAnimation
-QPointer~QAbstractAnimation~ m_showDesktopAnimation
-State m_surfaceState
-State m_previousSurfaceState
-QRectF m_normalGeometry
-uint m_hideByshowDesk : 1
-uint m_hideByLockScreen : 1
-uint m_confirmHideByLockScreen : 1
-uint m_ignoreNormalGeometryUpdate : 1
-uint m_blur : 1
-uint m_isActivated : 1
-SurfaceRole m_surfaceRole
}
class WorkspaceAnimationController {
+void slide(fromWorkspaceIndex: uint, toWorkspaceIndex: uint)
+void bounce(currentWorkspaceIndex: uint, direction: Direction)
+void startSlideAnimation()
+void slideRunning(toWorkspaceIndex: uint)
+void slideNormal(fromWorkspaceIndex: uint, toWorkspaceIndex: uint)
-QAbstractAnimation* m_slideAnimation
-QAbstractAnimation* m_bounceAnimation
-QPointF m_animationDestination
-bool m_needBounce
}
class Workspace {
+void updateSurfacesOwnsOutput()
+void createSwitcher()
-bool m_switcherEnabled
-QObject* m_switcher
}
class Helper {
+static Helper* instance()
+Config* config() const
+QmlEngine* qmlEngine() const
}
class Config {
+bool enableMaximizeAnimation() const
+bool enableWindowOpenCloseAnimation() const
+bool enableLaunchpadAnimation() const
+bool enableLayerShellAnimation() const
+bool enableShowDesktopAnimation() const
+bool enableMinimizeAnimation() const
+bool enableWorkspaceAnimation() const
}
class QmlEngine {
+QAbstractAnimation* createNewAnimation(surface: SurfaceWrapper*, container: SurfaceContainer*, direction: uint)
+QAbstractAnimation* createLaunchpadAnimation(surface: SurfaceWrapper*, direction: uint, container: SurfaceContainer*)
+QAbstractAnimation* createLayerShellAnimation(surface: SurfaceWrapper*, container: SurfaceContainer*, direction: uint)
+QAbstractAnimation* createShowDesktopAnimation(surface: SurfaceWrapper*, container: SurfaceContainer*, show: bool)
+QQuickItem* createWorkspaceSwitcher(workspace: Workspace*)
}
SurfaceWrapper --> Helper : uses config()
SurfaceWrapper --> QmlEngine : uses animations
WorkspaceAnimationController --> Helper : uses config()
Workspace --> Helper : uses config(), qmlEngine()
Helper --> Config : owns
Helper --> QmlEngine : owns
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Summary by Sourcery
Migrate Treeland to the new treeland-ddm v2 protocol, integrating DDM over Wayland instead of a custom socket, while making session IDs string-based and adding configuration-controlled animations for window, workspace, and desktop transitions.
New Features:
Bug Fixes:
Enhancements:
Build: