LightDM Greeter的启动流程与分析

编程入门 行业动态 更新时间:2024-10-24 22:25:10

LightDM Greeter的启动<a href=https://www.elefans.com/category/jswz/34/1770115.html style=流程与分析"/>

LightDM Greeter的启动流程与分析

重要的概念

LightDM Greeter是什么?它是一个登录管理器,用于在Ubuntu或其他基于Linux的操作系统中管理用户登录。它提供了一个图形化用户界面,用户可以在其中输入他们的用户名和密码以及选择登录的桌面环境。LightDM Greeter还提供了可定制的选项,如自定义主题和背景图像。它是一个轻量级的登录管理器,可以与各种桌面环境和窗口管理器一起使用。

如果把系统比作一栋建筑,Greeter就像是那个门卫——它还不算是警卫。通过LightDM的配置把它屏蔽,用户可以长驱直入。下文以Linux Deepin系统开发的lightdm-deepin-greeter为样本。其它系统大同小异。LightDM视角下Greeter流程如下图所示:

配置部分

lightdm配置

LightDM支持以下位置的配置文件:

/usr/share/lightdm/lightdm.conf.d/*.conf
/etc/lightdm/lightdm.conf.d/*.conf
/etc/lightdm/lightdm.conf

当多个配置文件存在相同配置时以最后的配置文件的配置为依据,读取顺序从上到下。dde-session-shell直接修改最后一个配置文件/etc/lightdm/lightdm.conf,把greeter-session设置为lightdm-deepin-greeter

Desktop文件

代码里面的files文件夹下的lightdm-deepin-greeter.desktop文件就是按照LightDM的要求写的配置文件,内容如下:

[Desktop Entry]
Name=Deepin Lightdm Greeter
Comment=Deepin Lightdm Greeter
Exec=/usr/bin/deepin-greeter
Type=Application
X-Ubuntu-Gettext-Domain=deepin-lightdm-greeter

CMakeLists.txt第396行代码是关于这个文件的安装规则代码,它指定安装包把这个Desktop文件复制到/usr/share/xgreeters/下面。
Desktop文件其中的Exec指定启动/usr/bin/deepin-greeter这个文件。

Shell部分

deepin-greeter

deepin-greeter是一个shell文件,代码位于files文件夹下,代码如下:

for i in /etc/deepin/greeters.d/*; do$i
done

CMakeLists.txt第387行代码是关于这个文件的安装规则代码,它指定安装包把这个shell文件复制到/usr/bin/下面。
它的作用是遍历/etc/deepin/greeters.d/下面的所有可执行文件,把它们依次轮流启动执行。

深度shell

这部分shell代码不在dde-session-shell工程代码里面。其中存在2个关键的shell,第一个是00-xrandr。文件名为什么要加00-呢?因为这个shell是用来获取显示设备最大支持的分辨率并改变分辨率。按照deepin-greeter这个shell的依次循环执行做法,为了保证先设置分辨率后启动界面应用,所以加了这个前缀。它的代码如下:

#!/bin/bash
#
# xrandr 输出的主屏幕有可能是断开的
# $ xrandr|egrep -o '^.* (connected|primary)'
# DVI-I-0 disconnected primary
# DVI-I-1 connected
# VGA-1-1 connectedxinfo(){local IFS=$'\n'XINFO=($(xrandr|egrep -o '^.* connected( primary)?'))
}# 仅当连接两个屏幕时进行如下操作
if xinfo && ((${#XINFO[@]} == 2)); then# 假设第一行为主屏primary=(${XINFO[0]})second=(${XINFO[1]})# 如果第二行输出含有 primary, 则交换if ((${#second[@]} == 3)); thenprimary=(${XINFO[1]})second=(${XINFO[0]})fixrandr --output ${second[0]} --right-of ${primary[0]} --auto
fi

第二个是lightdm-deepin-greeter。注意这还是个shell,不是Qt编译的二进制可执行文件。它的代码是:

#!/bin/bash
display_daemon="/usr/lib/deepin-daemon/greeter-display-daemon"
if [ -x $display_daemon ]; then$display_daemon &
fi
/usr/bin/lightdm-deepin-greeter

为了计时,编者把代码改成了:

#!/bin/bash
display_daemon="/usr/lib/deepin-daemon/greeter-display-daemon"
if [ -x $display_daemon ]; thenecho $(date +"%Y-%m-%d %H:%M:%S") $display_daemon  >> /home/log/greeter-elapse.log$display_daemon &
fi
echo $(date +"%Y-%m-%d %H:%M:%S") /usr/bin/lightdm-deepin-greeter started >> /home/log/greeter-elapse.log
/usr/bin/lightdm-deepin-greeter
echo $(date +"%Y-%m-%d %H:%M:%S") /usr/bin/lightdm-deepin-greeter ended >> /home/log/greeter-elapse.log

增加到代码都是把时刻打印到/home/log/greeter-elapse.log。需要注意是的这些shell的启动身份是lightdm这个用户。这个用户权限很低,/home/log/ 的权限须为755greeter-elapse.log的权限须为777

可执行文件部分

/usr/bin/lightdm-deepin-greeter是最终的可执行文件,它才是dde-session-shell的编译结果。CMakeLists.txt第386行代码指定安装包把lightdm-deepin-greeter复制到/usr/bin

主程序入口

main函数位于lightdm-deepin-greeter.cpp第181行。开始启动时调用DTK加载主题,设置Qt主程序相关信息,设置Qt的调色板等等。最重要的是判断当系统环境是不是X11,如果是则加载XCB插件。

SessionBaseModelGreeterWorkek类型虽然不是单例模式的实现,但是单例模式的用法,它在界面类型中层层传递,确认只有这些类型的单个对象。GreeterWorkek实现了登录逻辑。

多屏的信号监听由MultiScreenManager提供支持。每个屏幕信号都触发一次std::function<QWidget *(QScreen *)> 类型的回调。

LoginWindow类型

这个类型是主窗口,继承自FullscreenBackground类型。FullscreenBackground的作用是全屏遮挡,但它作用一个通用类型不提供界面的实现细节,也不实现对鼠标和键盘信号的抓取并屏蔽功能。它特别提供了一个调试功能,debug模式编译的程序可按Esc键退出。

绘制的背景图片之前要获取用户设置的背景图片。曾经的做法是从com.deepin.daemon.Accounts服务获取用户的背景图片的路径,然后调用com.deepin.daemon.ImageEffect生成虚化的背景图片,用虚化的背景图片填充效果。这样的做法存在一个巨大的敝端:无论用户是否修改过背景图片,它在每次登录操作都要生成一次。对于龙芯这样的没有真实GPU只能模拟图形处理的硬件平台造成不必要的启动缓慢问题。后来引入共享内存技术,通过保存用户修改背景图片设置时的保存的缓存图片,一定程序上提高了greeter启动速度,特别对于开机后的注销、锁屏操作,速度提升效果更加明显。

LoginContent类型

LoginContent类型继承自LockContent类型。这里是greeter和锁屏程序的逻辑存在共用的地方。框架上的整体布局由它管理和设置,它管理的LogoWidget对象实现了左下角UOS的标志,MediaWidget对象实现了锁屏播放音乐,UserLoginInfo对象实现中间的登录界面,ControlWidget实现了切换用户、关机、重启等界面。

关于服务器版本

服务器版本不显示用户列表,不过它并非通过LightDM的配置实现,而是自己写了一个配置文件,代码位于files文件夹下的dde-session-ui.conf.in,代码是:

[Power]
sleep=$$ENABLE_SLEEP
hibernate=$$ENABLE_HIBERNATE[OS]
isDeepin=$$IS_DEEPIN[General]
loginPromptAvatar=$$LOGIN_PROMPT_AVATAR
loginPromptInput=$$LOGIN_PROMPT_INPUT
lockNoPassword=false[Lock]
#[always | ondemand | disabled]
showSwitchUserButton=$$SHOW_SWITCH_USER_BUTTON

其中$ENABLE_SLEEP$$LOGIN_PROMPT_INPUT$$IS_DEEPIN$$LOGIN_PROMPT_INPUT$$SHOW_SWITCH_USER_BUTTON是CMake传递过来的变量。showSwitchUserButton指明是否显示切换用户按钮,sleep指明是否显示休眠按钮,hibernate指明是否显示待机按钮,isDeepin指示是否深度系统,loginPromptAvatar指示是否显示用户头像。

dde-session-ui.conf.inCMakeLists.txt指定安装到/usr/share/dde-session-ui/dde-session-ui.conf

作者:岬淢箫声
日期:2020年12月16日
版本:1.0
博客:
创作不易,请大家多多支持关注、转发。转发请注明来源。

更多推荐

LightDM Greeter的启动流程与分析

本文发布于:2023-12-06 03:51:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1666354.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:流程   LightDM   Greeter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!