GNU General Public License v3.0

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

深度分析 Gnome Shell Extension - Another Window Session Manager

项目背景与痛点

在现代桌面环境中,桌面窗口管理是用户日常操作中一个至关重要的功能。Gnome Shell 提供了大量的插件和支持来改善用户体验,然而,问题在于,如何在关闭所有窗口时优雅地保存它们的会话,以便在下次启动时能够快速恢复工作环境?这对于高效工作至关重要。另外,不同的桌面环境和显示服务器(如 X11 和 Wayland)带来的交互差异,使得这一需求变得更具挑战性。

核心技术揭秘

技术栈与架构

gnome-shell-extension-another-window-session-manager 是一个插件,致力于解决上述问题。该项目采用 JavaScript 语言开发,利用 Gnome Shell 的 API 和其扩展机制来集成。插件的操作链路主要包括窗口事件监听、会话数据持久化以及会话恢复的功能。

关键数据流

以下是内核逻辑简化后的数据流图:

graph TD A[用户关闭窗口] --> B{"会话状态监听"} B -->|"确定会话保存"| C[持久化会话数据] C --> D[保存成功] B -->|"会话无改变"| E[返回] F[用户重启 Gnome Shell] --> G{"会话数据检查"} G -->|"会话存在"| H[恢复会话] G -->|"会话丢失"| I[初始化]

数据持久化

数据持久化是一个关键的技术点。该插件实现了一套机制来记录各窗口的状态(位置、尺寸、可见性等),并将其存储在 Gnome Shell 的本地存储中。数据结构的合理设计可以确保会话数据能被高效地写入和读取。

功能亮点与差异

相比同类插件,Another Window Session Manager 的独特之处在于其对 X11 和 Wayland 双平台的良好支持。对于 Wayland,由于没有像 X11 那样的广泛兼容性,开发成本和实现难度都更高。这不仅仅意味着功能的实现,也包括了对每一个使用场景的细致测试和性能优化。

应用场景与落地建议

在生产环境使用时,需要注意的是系统的资源消耗问题,以及扩展的更新与兼容性。对于大型的工作环境,会话保存的频率、数据的体积都可能成为影响性能的因素。在高负载环境下,适当配置会话保存策略能够帮助减少资源占用。

该插件特别适合开发人员、设计师等需要频繁切换大量窗口和应用程序的用户,它能够大幅提升他们的工作效率,并帮助减少工作环境的不一致性带来的困扰。

综合评价

  • 优点:功能强大且稳定,对 X11 和 Wayland 良好的兼容性,完善的数据持久化服务。
  • 缺点:对资源使用量较大,尤其是在保存大量会话时可能会对系统性能有一定影响。此外,开发成本和后续维护是一项长期且持续的挑战。

总体来说,gnome-shell-extension-another-window-session-manager 为 Gnome Shell 用户提供了强大的会话管理功能,若能优化其性能消耗,无疑将更加完善。

关于

GitHub 原始描述(英文)

A Gnome shell extension to close open windows gracefully and save them as a session. The previous session can be restored at startup. Most importantly, it supports both X11 and Wayland!

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

语言占比

CSS
JavaScript
Shell

Release

README

gnome-shell-extension-another-window-session-manager

Close open windows gracefully and save them as a session. And you can restore them when necessary manually or automatically at startup.

Most importantly, it supports both X11 and Wayland!

This extension is based on several Gnome technologies and APIs including Meta, Shell and St(Shell Toolkit).

Get it on GNOME Extensions

Screenshot

Overview

image

Close open windows

Click item to close open windows:

image

After confirm to close:

image

Save open windows

Click item to save open windows as a session:

image

After confirm to save:

image

Activate the current session to be restored at startup

image

Preferences

Restore sessions

image

Close windows

image

Main features

  1. Restore the previous session at startup. disabled by default, to enable it please activate Restore previous apps and windows at startup under Restore sessions. (See also: Restore previous apps and windows at startup).
  2. Save running apps and windows automatically when necessary, this will be used to restore the previous session at startup.
  3. Close running apps and windows automatically before Log Out, Restart, Power Off. disabled by default, to enable it please activate Auto close session under Close windows. (See also: Auto close session).
  4. Close running windows gracefully
  5. Close apps with multiple windows gracefully via ydotool so you don’t lose sessions of this app (See also: How to make Close by rules work)
  6. Save running apps and windows manually
  7. Restore a selected session at startup (See also: #9). disabled by default.
  8. Restore a saved session manually
  9. Restore window state, including Always on Top, Always on Visible Workspace and maximization
  10. Restore window workspace, size and position
  11. Restore 2 column window tiling
  12. Stash all supported window states so that those states will be restored after gnome shell restarts via Alt+F2 -> r or killall -3 gnome-shell.
  13. Move windows to their own workspace according to a saved session
  14. Support multi-monitor
  15. Remove saved session to trash
  16. Search saved session by the session name fuzzily
  17. …

Close windows

Auto close session

Enable this feature through Auto close session under Close windows:

image

After you click the Log Out/Restart/Power Off button:

image

If the second button on the above dialog has via AWSM, it means this feature is enabled.

After you click Log Out(via AWSM), all apps and windows will be closed automatically by AWSM. But some apps might be still opening, you have to close them yourself; then if there are no running apps, this extension logs out the current user immediately.

image

You can move it around in case it covers other windows.

Please note that currently if this option is enabled, it modifies the Gnome Shell endSessionDialog globally, which means running gnome-session-quit --logout will also popup the new modified dialog.

How to make Close by rules work

To make this feature work, you need to install ydotool:

# 1. Install `ydotool` using the package manager and make sure the version is greater than v1.0.0
sudo dnf install ydotool
#Or install it from the source code: https://github.com/ReimuNotMoe/ydotool

#Check the permission of `/dev/uinput`, if it's `crw-rw----+`, you can skip step 2
# 2. Get permission to access to `/dev/uinput` as the normal user
sudo touch /etc/udev/rules.d/60-awsm-ydotool-uinput.rules
# Here we use `tee`, not redirect(>), to avoid `warning: An error occurred while redirecting file '/etc/udev/rules.d/60-awsm-ydotool-uinput.rules' open: Permission denied`
# See: https://www.shellhacks.com/sudo-echo-to-file-permission-denied/
echo '# See:
  # https://github.com/ValveSoftware/steam-devices/blob/master/60-steam-input.rules 
  # https://github.com/ReimuNotMoe/ydotool/issues/25

  # ydotool udev write access
  KERNEL=="uinput", SUBSYSTEM=="misc", TAG+="uaccess", OPTIONS+="static_node=uinput"' | sudo tee --append /etc/udev/rules.d/60-awsm-ydotool-uinput.rules

cat /etc/udev/rules.d/60-awsm-ydotool-uinput.rules
#Remove executable permission (a.k.a. x)
sudo chmod 644 /etc/udev/rules.d/60-awsm-ydotool-uinput.rules

# 3. Copy ydotool.service to /usr/lib/systemd/user, so `systemctl --user enable ydotool.service` can work
sudo cp /usr/lib/systemd/system/ydotool.service /usr/lib/systemd/user
# 4. Start ydotool.service at startup automatically for the current normal user
systemctl --user enable ydotool.service
# 5. Note that you may have to restart the system if the following commands are not working
# 6. Start the ydotoold service for the current normal user
systemctl --user start ydotool.service
# 7. Check if ydotoold service is working. The word `hello` should print on the terminal, if not you might need to reboot the system or try to relogin your account. 
ydotool type 'hello'

## misc. ##

# Check if the ydotoold service is running, if not you may have to restart the system or start ydotool.service
systemctl --user status ydotool.service

Note that it’s no necessary to run systemctl --user enable ydotool.service, because this extension starts ydotool.service every time while you use it to close windows.

Feel free to fill an issue if ydotool does not work under normal user, you may also want to do that in its git issue area

Restore sessions

Restore previous apps and windows at startup

image

Activate Restore previous apps and windows at startup to enable this feature. This option and Restore selected session at startup are exclusive. And this option works for shutting down the system normally (via Log Out/Restart/Power Off buttons) and other ways (like pressing the physical power-off button).

Then while startup, AWSM will launch and restore apps and states from the previous saved session configs.

The session configs are saved in the path ~/.config/another-window-session-manager/sessions/currentSession.

You can use the below command to test it.

gdbus call --session --dest org.gnome.Shell.Extensions.awsm --object-path /org/gnome/Shell/Extensions/awsm --method org.gnome.Shell.Extensions.awsm.Autostart.RestorePreviousSession "{'removeAfterRestore': <false>}"

How to Restore a session at startup?

To make it work, you must enable it through Restore sessions -> Restore at startup in the Preferences AND active a session by clicking in the popup menu.

While you enable it through Restore sessions -> Restore at startup, it creates a _gnome-shell-extension-another-window-session-manager.desktop under the folder ~/.config/autostart/.

Test the settings in command line via:

gdbus call --session --dest org.gnome.Shell.Extensions.awsm --object-path /org/gnome/Shell/Extensions/awsm --method org.gnome.Shell.Extensions.awsm.Autostart.RestoreSession

Please do not modify _gnome-shell-extension-another-window-session-manager.desktop, all changes by yourself could be overidden or deleted.

Panel menu items

Icons description

Icon Description
Save open windows as a session, which name is the item’s name
Restore the saved session using the item’s name
Move the open windows using the item’s name
Close the current open windows
Activate the current session to be restored at startup
Inactivate the current session to be restored at startup
Indicate the autorestore button

Dependencies

  • procps-ng

Use ps and pwdx to get some information from a process, install it via dnf install procps-ng if you don’t have.

  • glib2

Use gdbus to call the remote method, which is provided by this exension, to implement the restore at start feature. gdbus is part of glib2.

  • ydotool

Send keys to close the application gracefully with multiple windows.

  • libgtop2

As of version 34, AWSM also uses libgtop2 to query process information, just like ps. The cost of calling ps is very high, so I’m planing to remove this entirely.

To install it:

  • Fedora and derivatives: dnf install libgtop2

  • Debian, Ubuntu, Pop!_OS, and derivatives: apt install gir1.2-gtop-2.0 libgtop2-dev

  • Arch and derivatives: pacman -S libgtop

Known issues

  1. On both X11 and Wayland, if click restore button () continually during the process of restoring, the window size and position may can’t be restored, and it may restore many instances of an application. As a workaround, click the restore button () only once until all apps are restored.

Support applications launched via a command line or applications that don’t have a proper .desktop file

If the .desktop is missing from a session file, restoring an application relies on the command line completely.

In this case this extension will generate a .desktop in the journalctl when you click the save button (). Search Generated a .desktop file in journalctl /usr/bin/gnome-shell -r to find it: journalctl /usr/bin/gnome-shell -b -o cat --no-pager | grep 'Generated a .desktop file'. To make it work, You need to copy it to ~/.local/share/applications, and relaunch the app and save the session again. This extension should be able to restore the workspace, state, size and position of this application.

The generated .desktop might not work sometimes, it’s better to check whether the value of Exec is correct or not. If you restore an app using a bad .desktop, this extension will give you a notification and log error level logs in the journalctl.

I tested on Anki, VirtualBox machine and two .AppImage apps, they all have no .desktop and are launched in the terminal. By using the generated .desktop, Anki, VirtualBox machine works. One .AppImage app works. Another .AppImage app is Wire_x86_64.AppImage and doesn’t work, because the command line returned is something like /tmp/.mount_Wire-3xxxxx/wire-desktop, you can use it to launch Wire but files in the /tmp will be deleted during the OS shutdown and start.

It’s impossible / hard to query the command line from a process, the pid of a window might not be right too and I don’t find a standard way for this.

How can I know whether a .desktop of an application is proper or not?

One of the following should be enough to prove the .desktop is not proper:

  1. Right click on the icon in the panel or dash, if there is no Add to Favorites in the menu
  2. This extension can launch an application, but can’t move the window to its workspace. (But it might suggest there is a bug in this extension, LOL :))

Most existing applications should have a proper .desktop. I’m just handling the special case. Someone like myself might want this feature.

Where are the saved sessions?

They are all in ~/.config/another-window-session-manager/sessions. When use an existing name to save the current open windows, the previous file will be copied to ~/.config/another-window-session-manager/sessions/backups as a new name, which is the-old-session-name**.backup-current-timestamp**.

Note that I’ve marked backups as a reserved word, so you can’t use it as a session name when saving a session. But you do have the freedom to manually create a file named backups in ~/.config/another-window-session-manager/sessions. But this extension will only backup the session file that you are clicking the save button and you will receive an error log in the journalctl and an error notification every time you save an existing session.

TODO

    • Save open windows
      • Save open windows
    • Restore saved open windows
      • Restore saved open windows
      • Move to belonging workspace automatically
      • Restore window size and position (issue 17)
      • Restore window workspace, size and position of applications launched via a command line and don’t have a recognizable .desktop file by Shell.AppSystem.get_default().get_running().
      • Support multi-monitor (issue 21)
    • Saved open windows list
      • Save open windows button
      • Restore button
      • Rename button (double click text to rename?)
      • Move button
      • Delete button
    • Move windows according to a saved session.
    • Settings
      • Debugging mode
      • whitelist using for closing application with multiple windows
    • Support restoring a saved session at startup (issue 9)
    • Support saving and closing windows when Log Out, Power off, Reboot (issue 9)
    • All TODO tags in the projects
    • Translation?
    • A client tool called awsm-client (See: issue 34)
    • Fix any typo or grammar errors.
    • Open the Preferences on the popup menu
    • Open the session file from the popup menu

评论

暂无评论