侏儒壳 ≤ 42 (22.04)

侏儒壳 ≤ 42 (22.04)

我可以通过各种方式更改我当前的工作区,例如通过单击某些切换器小部件、使用某些组合键或使用终端中的命令。

有没有办法检测工作区是否已经改变,并在那一刻启动 bash 脚本?

(例如,我认为 d-bus 上有一个可监控的信号,类似这样的东西。)

答案1

有一个更节能的 gnome-shell 扩展解决方案。它实际上会“在那一刻启动一个 bash 脚本”,而你无需事先启动任何东西。以下是安装过程:

  1. 创建要运行的脚本~/script.sh
  2. 确保它是可执行的
  3. 将正确的版本粘贴到~/.local/share/gnome-shell/extensions/[email protected]/metadata.json
  4. 将正确的版本粘贴到~/.local/share/gnome-shell/extensions/[email protected]/extension.js
  5. 重新登录
  6. 跑步gnome-extensions enable [email protected]

我使用script.sh刚刚创建文件的 进行了测试。我测试了Ctrl++ /并确认脚本在那时运行,而不是在登录等其他时间运行。gnome-shell 不会将信号暴露给 DBus,并且AltDBus方法被锁定。但是,gnome-shell 扩展可以监听 gobject 信号org.gnome.Shell.EvalWorkspaceManager::active-workspace-changed

侏儒壳 ≤ 42 (22.04)

metadata.json

{
    "uuid": "[email protected]",
    "name": "Workspace change detect script launcher",
    "description": "Detect that the workspace has been changed, to launch a bash script at that moment",
    "shell-version": [ "42" ],
    "url": "https://askubuntu.com/q/1502368/1004020"
}

extension.js

const {GLib} = imports.gi;
let handlerId;

function enable() {
    handlerId  = global.workspaceManager.connect('active-workspace-changed', () => {
        // Put the script to launch at ~/script.sh , or change the string on the next line:
        GLib.spawn_command_line_async('./script.sh');
    });
}

function disable() {
    global.workspaceManager.disconnect(handlerId);
}

侏儒壳 ≥ 45 (23.10)

metadata.json

{
    "uuid": "[email protected]",
    "name": "Workspace change detect script launcher",
    "description": "Detect that the workspace has been changed, to launch a bash script at that moment",
    "shell-version": [ "45" ],
    "url": "https://askubuntu.com/q/1502368/1004020"
}

extension.js

import GLib from 'gi://GLib';
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';

export default class WorkspaceChangeDetectExtension extends Extension {
    enable() {
        global.workspaceManager.connectObject('active-workspace-changed', () => {
            // Put the script to launch at ~/script.sh , or change the string on the next line:
            GLib.spawn_command_line_async('./script.sh');
        }, this);
    }

    disable() {
        global.workspaceManager.disconnectObject(this);
    }
}

答案2

我确实研究过 D-Bus 和其他想到的 Gnome DE 特定方法,但找不到比下面描述的更可靠、可持续和便携的解决方案……

您可以使用xdotool(这似乎也适用于 Wayland)在 shell 循环中如下:

#!/bin/sh

while sleep 0.2
  do
  v="$(xdotool get_desktop)"
  if [ -z "$ws" ]
    then
    ws="$v"
    elif [ "$ws" -ne "$v" ]
      then
        ws="$v"
        echo "changed to $ws"
        # Your command here
    fi
  done

...该工具仍可在 Wayland 上使用,因为它读取_NET_CURRENT_DESKTOP的财产EWMH扩展窗口管理器提示其中许多窗口管理器/系统仍然支持并制定标准。

不用说,还有其他工具支持读取该属性以及内置的持续监视功能(如果你不喜欢不断循环sleep通话) 喜欢xprop你也可以像这样使用它:

#!/bin/bash

xprop -root -spy _NET_CURRENT_DESKTOP |
while IFS=" " read -r p s n
  do
  if ! [[ "$ws" =~ ^[0-9]+$ ]]
    then
    ws="$n"
    elif [ "$n" -ne "$ws" ]
      then
        ws="$n"
        echo "changed to $ws"
        # Your command here
    fi
  done

... 甚至xev像这样:

#!/bin/sh

xev -root -event property |
grep --line-buffered -o '_NET_CURRENT_DESKTOP' |
while read -r p
  do
    echo "Workspace changed."
    # Your command here
    done

...当然,如果您愿意,您也可以选择实现自己的应用程序,_NET_CURRENT_DESKTOP用任何语言 C、Python...等读取属性,而不一定使用这些工具的 shell 脚本。

注意:

  • 上面第一个循环xdotool和最后一个循环xev不是 Bash 特有的,sh例如可以与其他 POSIX shell 一起运行。

  • 在 Wayland 上使用时xprop,据报告@Daniel T(谢谢丹尼尔),那么在开始捕捉它之前必须至少切换工作区一次xprop,因此您在工作区之间的第一次切换将超出脚本的范围......所以,如果这很关键,请使用xdotool

注意并且(不言而喻)这些循环需要在用户图形会话运行时运行,即在登录后和注销前...因此,最好的实现方式如下启动应用程序Command:无论它们是包含在脚本文件中还是甚至作为单个 shell 命令字符串布局在字段中,如下所示:

 sh -c 'while sleep 0.2; do if [ -z "$ws" ]; then ws="$(xdotool get_desktop)"; elif [ "$ws" -ne "$(xdotool get_desktop)" ]; then ws="$(xdotool get_desktop)"; echo "changed to $ws"; fi done'

...或者像这样:

bash -c 'xprop -root -spy _NET_CURRENT_DESKTOP | while IFS=" " read -r p s n; do if ! [[ "$ws" =~ ^[0-9]+$ ]]; then ws="$n"; elif [ "$n" -ne "$ws" ]; then ws="$n"; echo "changet to $ws"; fi done'

...或者像这样:

sh -c 'xev -root -event property | grep --line-buffered -o '_NET_CURRENT_DESKTOP' | while read -r p; do  echo "Workspace changed."; done'

... 这些命令字符串中的自定义命令应该代替该echo "..."部分。

相关内容