会话管理
一个会话是指一组正在运行的应用程序,每个应用程序都有特定的状态。会话由一个名为会话管理器的服务控制。参与会话的应用程序称为会话客户端。
会话管理器代表用户向其客户端发出命令。这些命令可能会导致客户端提交未保存的更改(例如保存打开的文件),为将来的会话保存其状态,或正常终止。这个操作集称为会话管理。
通常情况下,会话包括用户在桌面上同时运行的所有应用程序。然而在 Unix/X11 上,会话可能包括在不同计算机上运行的应用程序,并且可能跨多个显示器。
关闭会话
会话通常由会话管理器关闭,通常是在用户想要注销时执行的。系统也可能在紧急情况下执行自动关闭,例如当电源即将丢失时。显然,这些关闭类型之间存在显著差异。在第一种情况下,用户可能希望与应用程序进行交互,具体指定哪些文件应该保存,哪些应该丢弃。在后一种情况下,没有时间进行交互,甚至可能没有用户坐在机器前。
不同平台上的协议和支持
在 macOS 和 Windows 2000 之前的 Microsoft Windows 版本中,还没有类似完整的会话管理功能,即没有恢复以前会话的功能。(Windows 2000 和 XP 提供了“休眠”功能,即将整个内存保存到磁盘并在机器重新启动时恢复。)它们支持正常的注销,应用程序有机会在获得用户确认后取消该过程。这对应于 QGuiApplication::commitDataRequest() 信号的功能。
X11 自 X11R6 以来一直支持完整的会话管理。
使用 Qt 实现会话管理
首先,通过连接一个槽到 QGuiApplication::commitDataRequest() 信号,使您的应用程序能够参与正常的注销过程。如果您只针对 Microsoft Windows 平台,这是您唯一需要提供的功能。理想情况下,您的应用程序应该提供一个类似于以下的关闭对话框:
有关此对话框的示例代码,请参见 QSessionManager::allowsInteraction() 文档。
对于完整的会话管理(目前仅在 X11R6 上支持),您还必须处理保存应用程序的状态,并可能在会话的下一个生命周期中恢复状态。这通过实现一个槽来完成,该槽连接到 QGuiApplication::saveStateRequest() 信号。您在此函数中保存的所有状态数据都应标记为会话标识符 QGuiApplication::sessionId()。此应用程序特定的标识符在全局范围内是唯一的,因此不会发生冲突。(有关保存/恢复特定 Qt 应用程序状态的信息,请参见 QSessionManager。)
恢复通常在应用程序的 main() 函数中进行。检查 QGuiApplication::isSessionRestored() 是否为 true。如果是这样,再次使用会话标识符 QGuiApplication::sessionId() 来访问您的状态数据并恢复应用程序的状态。
重要提示: 为了允许窗口管理器恢复窗口属性,如堆叠顺序或几何信息,必须使用唯一的应用程序范围的对象名称(参见 QObject::setObjectName())。恢复应用程序时,必须确保所有恢复的顶级窗口都具有与之前相同的唯一名称。
测试和调试会话管理
由于操作系统本身缺乏此功能,macOS 和 Windows 上的会话管理支持相当有限。只需关闭会话并验证您的应用程序是否按预期行为。可能在启动应用程序之前,启动另一个应用程序(通常是集成开发环境),该应用程序会在之后收到关闭消息,从而允许您取消关闭。否则,您在每次测试运行后都必须重新登录,这不是问题,但非常耗时。
在 Unix 上,您可以使用支持标准 X11R6 会话管理的桌面环境,或者推荐的方法是使用 X Consortium 提供的会话管理器参考实现。此示例管理器称为 xsm
,是标准 X11R6 安装的一部分。正如 X11 一贯的做法,提供了一个有用且信息丰富的手册页。使用 xsm
很简单(尽管基于 Athena 的用户界面有些笨拙)。这里有一个简单的方法:
-
运行 X11R6。
-
在您的主目录中创建一个点文件
.xsmstartup
,其中包含单行xterm
。这告诉xsm
默认/安全会话只是一个 xterm,没有其他东西。否则xsm
会尝试调用很多客户端,包括窗口管理器twm
,这并不太有帮助。 -
现在从另一个终端窗口启动
xsm
。会出现一个会话管理器窗口和 xterm。这个 xterm 有一个很好的属性,它将自己与您当前运行的所有其他 shell 区分开来:在其 shell 中,SESSION_MANAGER
环境变量指向您刚刚启动的会话管理器。 -
从新的 xterm 窗口启动您的应用程序。它会自动连接到会话管理器。您可以通过 ClientList 按钮检查连接是否成功。
注意: 启动或结束会话管理的客户端时,不要保持 ClientList 打开!否则 xsm
可能会崩溃。
-
使用会话管理器的 Checkpoint 和 Shutdown 按钮进行不同设置,查看应用程序的行为。保存类型 local 意味着客户端应该保存其状态。它对应于 QGuiApplication::saveStateRequest() 信号。global 保存类型要求应用程序在永久、全局可访问的存储中保存其未保存的更改。它调用 QGuiApplication::commitDataRequest()。
-
每当出现崩溃时,归咎于
xsm
而不是 Qt。xsm
远未成为用户桌面上的可用会话管理器。然而,它足够稳定和有用,能够作为测试环境。