如何避免打开第二个实例?

Jak*_*kob 5 firefox scripts lirc

我设置lirc为用遥控器控制我的电脑。为了在不同模式之间切换,我编辑了.lircrc如下:

begin vlc
    include ~/.lirc/vlc
end vlc
begin gnome
    include ~/.lirc/gnome
end gnome
begin firefox
    include ~/.lirc/firefox
end firefox
begin me-tv
    include ~/.lirc/me-tv
end me-tv

begin
    prog = irexec
    button = KEY_YELLOW
    config = if [ -n $(pgrep -f vlc) ]; then (vlc &); fi
    mode = vlc
end
begin
    prog = irexec
    button = KEY_GREEN
    mode = gnome
end
begin
    prog = irexec
    button = KEY_RED
    config = if [ -n $(pgrep -x firefox) ]; then (firefox &); fi
    mode = firefox
end
begin
    prog = irexec
    button = KEY_BLUE
    config = if [ -n $(pgrep -x me-tv) ]; then (me-tv &); fi
    mode = me-tv
end
Run Code Online (Sandbox Code Playgroud)

一切正常 - 除了切换到 Firefox:当 Firefox 正在运行并且我按下红色按钮时,它会切换模式(因为它应该) 打开 Firefox 的第二个窗口/实例(因为它不应该)

该问题仅在 Firefox 中出现。

Edit? Preferences? Tabs? Open new windows in a new tab instead已经启用:

选项卡首选项

当 Firefox 正在运行并且我firefox在终端中启动会发生什么?

  • firefox - 第二个窗口打开
  • firefox about:startpage - Firefox 中的一个新标签页会打开并带有预配置的起始页
  • (!) firefox about:blank- Firefox 中的一个新标签页打开了我的个人起始页( Speeddial )
  • firefox chrome://speeddial/content/speeddial.xul (这是快速拨号起始页的地址) - 没有任何反应

当 Firefox 未运行而我firefox在终端中启动会发生什么?

  • firefox- Firefox 按照Preferences( Show my windows and tabs from last time) 中的配置打开
  • firefox about:startpage - Firefox 将打开一个带有预配置起始页的附加新选项卡
  • (!) firefox about:blank- Firefox 打开一个额外的新空白标签
  • firefox chrome://speeddial/content/speeddial.xul - 火狐无法打开:
    *** Preventing external load of chrome: URI into browser window.
    Use -chrome <uri> instead

因此,当我修改脚本 ( config = ...) 中的命令并添加类似about:blank它的地址时,可以部分解决问题。问题仍然存在,当它已经运行时,它不会将 Firefox 置于前台。这只是有时发生。

谁能帮我编辑这个脚本来解决这个不当行为?(我修改的脚本的来源。)

gei*_*rha 4

该来源的一些 shell 代码并没有执行其声称的功能;主要是这样的类型:

if [ -n $(pgrep -f vlc) ]; then (vlc &); fi
Run Code Online (Sandbox Code Playgroud)

这在两种情况下运行vlc &。如果没有与“vlc”匹配的进程,并且恰好有一个与“vlc”匹配的进程。如果有多个进程匹配“vlc”,vlc &则不会运行。所以这些 if 块是相当无用的。只是跑步vlc &可能会更正确。

不幸的是,糟糕的 shell 建议在互联网上很常见。

根据您的问题描述,您希望的结果是,如果程序尚未运行,则运行该程序;如果正在运行,则将该窗口置于前面,并给予其焦点。为此,wmctrl可以使用。

wmctrl -a 'Mozilla Firefox'将找到一个标题中包含“Mozilla Firefox”的窗口,然后“激活”它。也就是说,移至其所在的工作区,将其置于最前面并给予其焦点。其次,如果没有窗口匹配,wmctrl 将不执行任何操作并以非零(假)退出状态退出,在这种情况下,我们可以假设程序没有运行,并启动它。

wmctrl -a 'Mozilla Firefox' || firefox &
Run Code Online (Sandbox Code Playgroud)

但它仍然不完美。除 Firefox 窗口之外的其他窗口可能会在其标题中包含该字符串,因此我们应该找到一种更可靠的方法来识别这种情况下的正确窗口。

使用 -x,wmctrl 将在窗口的 VM_CLASS 上进行操作,该窗口通常每个程序都有一个唯一的值。wmctrl -lx所有 Firefox 窗口都将具有 VM_CLASS“Navigator.Firefox” ,在 Firefox 运行时运行可以看到

$ wmctrl -lx
...
0x03ba3d43  3 gnome-terminal.Gnome-terminal  pilot Terminal
0x04c000bc  0 Navigator.Firefox     pilot Group #1 - Speed Dial - Mozilla Firefox
Run Code Online (Sandbox Code Playgroud)

这样我们就可以选择恰好具有“Navigator.Firefox”作为 VM_CLASS 的窗口

wmctrl -Fxa Navigator.Firefox || firefox &
Run Code Online (Sandbox Code Playgroud)

希望同样的情况也适用于其他程序。