是否有类似于"awful.client.focus.global_byidx()"的功能?

我有两个显示器,我想使用快捷方式更改聚焦的客户端。现在我有awful.client.focus.byidx(1),但它仅更改一个显示器上的客户端。我知道有awful.client.focus.global_bydirection("right")可以在多个屏幕上工作,但它只朝一个方向移动并在到达最后一个客户端时停止工作。我喜欢awful.client.focus.byidx(1)的行为,它可以循环遍历所有客户端,因此从最后一个客户端转到第一个客户端。

我想使用混合模式:在所有显示器/屏幕上像awful.client.focus.global_bydirection("right")一样遍历客户端,但像awful.client.focus.byidx(1)一样。是否有一个函数能够具有这种行为,以便我可以使用它?如果没有,您知道我如何实现这个目标吗?

点赞
用户436275
用户436275

首先,让我们看看如何实现awful.client.focus.byidx

该函数本身调用awful.client.next,然后对返回的客户端进行聚焦,如果有任何客户端,则进行聚焦:

https://github.com/awesomeWM/awesome/blob/9781f14b105ee700c5bca339bf49bb52d2cca4b5/lib/awful/client/focus.lua#L65-L71

awful.client.next在此处实现:https://github.com/awesomeWM/awesome/blob/9781f14b105ee700c5bca339bf49bb52d2cca4b5/lib/awful/client.lua#L262-L284

它执行以下操作:

  • 第263行:获取当前聚焦的客户端
  • 第267行:获取当前可见客户端屏幕上的所有可见客户端
  • 第270-274行:从列表中过滤出无法聚焦的客户端
  • 第277-278行:在结果列表中找到聚焦的客户端
  • 第280行:获取所需偏移量处的客户端并返回它

因此,您的请求听起来好像只需要更改一个步骤:获取所有可见客户端的列表,而不仅仅是当前聚焦屏幕上的客户端。要获取该列表,您需要使用nil调用awful.client.visible而不是特定屏幕。

未经测试的代码:

function next_global(i, sel, stacked)
  sel = sel or client.focus
  if not sel then return end
  local cls = awful.client.visible(nil, stacked)
  local fcls = {}
  for _, c in ipairs(cls) do
    if awful.client.focus.filter(c) or c == sel then
      table.insert(fcls, c)
    end
  end
  cls = fcls
  for idx, c in ipairs(cls) do
    if c == sel then
      return cls[gears.math.cycle(#cls, idx + i)]
    end
  end
end
function focus_byidx_global(i, c)
  local target = next_global(i, c)
  if target then
    target:emit_signal("request::activate", "client.focus.byidx", {raise=true})
  end
end

我不知道您使用的是哪个AwesomeWM版本。如果不确定,请查看/usr/share/awesome/lib/中安装的文件并从那里复制代码,然后进行更改。

(更糟糕的解决方案可能是像以下一样,尽管它需要更少的代码;我将其留给读者自行解决,但请注意,如果发生Lua错误并且猴子补丁变得永久,这会“破坏”一些东西)

function focus_byidx_global(i, c)
  local old = awful.client.visible
  awful.client.visible = function(_, s) return old(nil, s) end
  awful.client.focus.byidx(i, c)
  awful.client.visible = old
end
2020-05-07 13:21:03