是否可以从 Gnome Shell 启动器执行子命令?

是否可以从 Gnome Shell 启动器执行子命令?

我设置了一个别名来启动我的文本编辑器,使其保持在我正在 Gnome Shell 中使用的特定桌面本地:

alias geany="geany --socket-file=/tmp/geany-sock-$(xprop -root _NET_CURRENT_DESKTOP | awk '{print $3}') ${1+"$@"}"

我想用实际的 Gnome Shell 启动器来模拟这一点。就目前而言,我将启动器命令设置为:

geany --socket-file=/tmp/geany-sock-$(xprop -root _NET_CURRENT_DESKTOP | awk '{print $3}') %F

如果 Geany 会话已经打开,它将指向当前窗口中打开的 Geany 会话,但不会启动新会话。我会得到一个旋转器,然后它就会退出而不是启动应用程序。有什么办法可以做到这一点吗?

答案1

.desktop文件中的 Shell 参数和变量扩展为既不支持也不记录。通常的解决方法是(如 Avlmd 所说)创建一个 shell 脚本并将文件指向.desktop该可执行文件。

当从仪表板启动应用程序时,gnome-shell默认为激活如果另一个实例已在运行,则停止应用程序而不是启动它(只要您不使用Ctrl+click来实际启动新实例)。行为可以通过 shell 扩展来改变,因此在您的特定情况下,覆盖
gnome-shell的扩展 应该执行您想要的操作:onActivate/usr/share/gnome-shell/js/ui/appDisplay.js

  • 创建扩展文件夹:

mkdir -p ~/.local/share/gnome-shell/extensions/[email protected]

  • 在里面添加这两个文件:

metadata.json:

{
    "shell-version": ["3.6.3.1"], 
    "uuid": "[email protected]", 
    "name": "Geany Launcher", 
    "description": "Fire up new window if no instance on current workspace"
}

extension.js:

const Clutter = imports.gi.Clutter;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const AppDisplay = imports.ui.appDisplay;

var _onActivateOriginal = null;

function  _onActivate(event) {
        this.emit('launching');
        let modifiers = event.get_state();
        let cTRL = Clutter.ModifierType.CONTROL_MASK;
        let rUN = Shell.AppState.RUNNING;
        let crtW = global.screen.get_active_workspace();
        if (this._onActivateOverride) {
            this._onActivateOverride(event);
        } else {
            if (this.app.get_id() == "geany.desktop") {
                if (this.app.state == rUN && ((modifiers & cTRL) || !this.app.is_on_workspace(crtW))) {
                    this.app.open_new_window(-1);
                } else {
                    this.app.activate();
                    } 
            } else {
                if (modifiers & cTRL && this.app.state == rUN) {
                    this.app.open_new_window(-1);
                } else {
                    this.app.activate();
                    }
                }
            }
        Main.overview.hide();
}

function init() {
  _onActivateOriginal = AppDisplay.AppWellIcon.prototype._onActivate;
}

function enable() {
  AppDisplay.AppWellIcon.prototype._onActivate = _onActivate;
}

function disable() {
  AppDisplay.AppWellIcon.prototype._onActivate = _onActivateOriginal;
}
  • Alt使用+ F2r、重新启动 shell Enter。然后启用扩展gnome-tweak-tool(您可能需要再次重新启动 shell 才能启用扩展)。

这适用于gnome-shell-3.6.3.1,如果您有另一个版本,请编辑metadata.json并更改此行以反映您的 shell 版本(不保证它适用于较旧的 shell 版本(如 3.4.x)或未来版本(如 3.8.x):

"shell-version": ["3.6.3.1"],

请注意,该扩展仅覆盖 shell 行为,如果您(双击)中的文件打开Nautilus它们,Geany它仍然会激活另一个桌面上的主窗口,因此您还必须诉诸 shell 脚本技巧来获得一致的行为:仅当当前桌面上没有实例时才显示一个新窗口,否则激活现有窗口。我没有xprop安装,但这适用于我的系统:

  • 在我的 $PATH 中的某个位置创建一个新的可执行文件(如/usr/local/bin/djinni):
#!/bin/sh

geany --socket-file /tmp/geany-sock-$(xdotool get_desktop) ${1+"$@"}
  • 将启动器 ( /usr/share/applications/geany.desktop) 指向新创建的脚本:

    Exec=djinni %F

答案2

一种可能的解决方法是将命令保存到 ~/bin/geany:

mkdir -p ~/bin
cat > ~/bin/geany
/usr/bin/geany --socket-file=/tmp/geany-sock-$(xprop -root _NET_CURRENT_DESKTOP | awk '{print $3}') $1
^d
chmod 755 ~/bin/geany

可执行文件并制作 .desktop 启动器,如下所示:/home/$USER/bin/geany %F.

相关内容