3

我从不喜欢 Awesome 中的默认窗口切换可能性,所以我想我会实现考虑历史的 Alt-Tab 行为(并做花哨的不透明效果)。

当按下 Alt-Tab 时,整个历史记录被记录在一个表格中,并且附加到该历史记录的是最小化的窗口(在同一个标​​签内)。生成此表时,我实例化一个捕获 Tab 按下事件(以切换到表中的下一个客户端)和 Alt 释放事件(完全中止)的 keygrabber。

一个标志跟踪用户是否在 Alt-tabbing 的过程中,以防止表被一遍又一遍地生成。

代码(很多,你可能不需要看,但我的经验告诉我,当我不发布所有代码时,人们最终会要求它):

altTabbing = false
altTabIndex = 1
altTabHistory = {}
clientOpacities = {}

function altTabSetOpacities(restore)
   for i,c in pairs(altTabHistory) do
      if not restore and i ~= altTabIndex then
         c.opacity = 0.5
      else
         c.opacity = clientOpacities[i]
      end
   end
end

function myAltTab()
   -- First check if the user is already alttabbing, in which case the history
   -- should NOT be updated. If the user has just pressed alt-tab, generate a new 
   -- history-table

   if not altTabbing then -- generate history-table

      -- Clear Tables
      for i in pairs(altTabHistory) do altTabHistory[i] = nil end
      for i in pairs(clientOpacities) do clientOpacities[i] = nil end

      -- Get focus history for current tag
      local s = mouse.screen;
      local idx = 0
      local c = awful.client.focus.history.get(s, idx)

      while c do
         table.insert(altTabHistory, c)
         table.insert(clientOpacities, c.opacity)

         idx = idx + 1
         c = awful.client.focus.history.get(s, idx)
      end

      -- Minimized clients will not appear in the focus history
      -- Find them by cycling through all clients, and adding them to the list
      -- if not already there.
      -- This will preserve the history AND enable you to focus on minimized clients

      local t = awful.tag.selected(s)
      local all = client.get(s)

      for i = 1, #all do
         local c = all[i]
         local ctags = c:tags();

         -- check if the client is on the current tag
         local isCurrentTag = false
         for j = 1, #ctags do
            if t == ctags[j] then
               isCurrentTag = true
               break
            end
         end

         if isCurrentTag then
            -- check if client is already in the history
            -- if not, add it
            local addToHistory = true
            for k = 1, #altTabHistory do
               if altTabHistory[k] == c then
                  addToHistory = false
                  break
               end
            end

            if addToHistory then
               table.insert(altTabHistory, c)
               table.insert(clientOpacities, c.opacity)
            end
         end
      end

      -- reset current index and flag
      altTabIndex = 1
      altTabbing = true

      -- Now that we have collected all windows, we should run a keygrabber
      -- as long as the user is alt-tabbing:
      keygrabber.run(
         function (mod, key, event)  
            -- Stop alt-tabbing when the alt-key is released
            if key == "Alt_L" and event == "release" then
               altTabbing = false
               altTabSetOpacities(true)
               c = altTabHistory[altTabIndex]
               client.focus = c                  
               c:raise()   
               return false -- stop keygrabber
            end

            -- Move to next client on each Tab-press
            if key == "Tab" and event == "press" then
               myAltTab()
               return true -- keep going
            end

            return true -- keep going
         end
      )

   end -- if not altTabbing

   -- at this point, the user is alt-tabbing, so we should raise
   -- the next client in the history-table
   if #altTabHistory < 2 then return end

   -- Switch to next client
   altTabIndex = altTabIndex + 1
   if altTabIndex > #altTabHistory then
      altTabIndex = 1 -- wrap around
   end

   -- focus on current client
   local c = altTabHistory[altTabIndex]
   c.minimized = false
   c:raise()

   -- make current client stand out
   altTabSetOpacities(false)
end

我意识到有很多代码,但主要的是keygrabber。由于仍然未知的原因,当我使用这种方法进行 Alt-Tabbing 时,Awesome 有时会崩溃。我想通过将信号连接到 Alt 和 Tab 键来替换 keygrabber,并在用户完成后立即断开它们。但是,由于某种原因,我无法做到这一点。

我像这样实例化一个新的键对象:

local altkey = awful.key({}, "Alt_L")[1]

我通过反复试验发现它awful.key()实际上返回了一个表,我可以在其中查询第一个元素keykeysym,因此[1]. 但是,当我尝试将信号连接到该对象时,LUA 解释器会抱怨并告诉我它是一个 nil 对象。所以我的问题是:我在这里做正确的事吗?是否有可能以我打算的方式更换密钥采集器?

4

1 回答 1

1

要在 Awesome 中使用 Alt_L 键,您应该参考 rc.lua 文件中的“Mod1”,为了使其更具可读性,我在配置的开头添加了以下行,以便可以使用 Alt_L。

Alt_L = "Mod1"
于 2015-07-29T20:49:56.760 回答