Мне никогда не нравились возможности переключения окон по умолчанию в Awesome, поэтому я решил реализовать поведение Alt-Tab, которое учитывает историю (и создает необычные эффекты непрозрачности).
При нажатии Alt-Tab вся история записывается в таблицу, и к этой истории добавляются свернутые окна (в том же теге). Когда эта таблица создается, я создаю экземпляр keygrabber, который фиксирует события нажатия Tab (для переключения на следующего клиента в таблице) и события Alt-release (для полного прерывания).
Флаг отслеживает, находится ли пользователь в процессе 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
Я понимаю, что кода много, но главное - это клавиатурный захват. По еще неизвестным причинам Awesome иногда дает сбой, когда я использую этот подход при нажатой клавише Alt. Я хочу заменить клавиатурный захват, подключив сигналы к клавишам Alt и Tab и отключив их, как только пользователь закончит. Однако по какой-то причине я не могу этого сделать.
Я создаю новый ключевой объект следующим образом:
local altkey = awful.key({}, "Alt_L")[1]
Методом проб и ошибок я обнаружил, что awful.key()
фактически возвращает таблицу, из которой я могу запросить первый элемент для key
, keysym
и т. Д., Следовательно, [1]
. Однако, когда я пытаюсь подключить сигнал к этому объекту, интерпретатор LUA жалуется и сообщает мне, что это нулевой объект. Итак, мой вопрос: правильно ли я поступаю здесь? Можно ли вообще заменить кейграббер так, как я собираюсь?
[1]
я не смог бы запросить у объекта какие-либо его свойства, поэтому я поместил его туда. Lua пожаловался при попытке подключить сигнал. Оказалось, что во время обновления до 3.5.5, 3.4 не была заменена должным образом, поэтомуconnect_signal
был недоступен. Я исправил это, но теперь многие другие сломались. Придется поработать еще немного. Тем не менее, любопытно, можно ли заменить кейграббер! - person JorenHeit   schedule 16.07.2014connect_signal
на ключе (без добавления[1]
):attempt to call method 'connect_signal' (a nil value)
(также в 3.5.5). Это сообщение исчезает при подходе[1]
, но я еще не видел, чтобы выполнялась подключенная функция. - person JorenHeit   schedule 16.07.2014