LINUX.ORG.RU

awesome + navigation

 


0

1

Да, я в курсе про Win+j/k, про Win+tab, но хотелось бы еще чего-то стиле табов в браузере, типо Win+Shif+N, где N e { 1,2,3,4,5,6,7,8,9,0 }. Т.е. имея что-то такое вверху awesome что-нибудь вроде:

https://raw.githubusercontent.com/xor512/trashbin/master/awesome_taskbar.png

т.е.:

terminal1 | evince | terminal2 | firefox

Нажав что-то вроде Win+Shift+1 «прыгнуть» в terminal1, а что-то вроде Win+Shift+4 в firefox. Таких shortcut’ов вроде нет. Может их довольно просто добавить?

Т.е. я хочу (и это я имею by default) переключаться между workspace’ами по Win+N, но еще (и этого я не имею) переключаться между программами внутри workspace’ов.

PS Да, я понимаю, что документация awful.* есть и в принципе сделать это не сложно: создать самому callback’и на эти комбинации, взять stack окон и прыгать), но мне кажется там будет трабла, что позиция в таскбаре (надеюсь я правильно называю это что-то вверху экрана) не обязательно будет соответствовать позиции в stack’е из-за tile’вости или я придумываю себе проблемы?

Ну и вообще вдруг кому-то не лень подсказать как это сделать минимальными усилиями (а может оно уже существует)?

★★

Последнее исправление: dissident (всего исправлений: 3)

Нажав что-то вроде Win+1 или Win+Shift+1 и т.п. «прыгнуть» в terminal1, а что-то вроде Win+4 в firefox. Таких shortcut’ов вроде нет.

Ну так можно насоздавать "рабочих столов" (воркспейсов, тегов или как они там в осоме называются), привязать каждое приложение к своему столу и переключаться между ними так.

micronekodesu ★★★
()
Ответ на: комментарий от micronekodesu

Если присмотреться к https://raw.githubusercontent.com/xor512/trashbin/master/awesome_taskbar.png, то видно, что я так не люблю. Я люблю, чтобы каждый workspace имел свой layout. У меня железо г-но + 1 монитор, поэтому их мало, смысл это больше имеет, когда 2 монитора и железо ок.

Тогда каждый workspace = свой layout + свое предназначение. Т.е. точно так же я мог бы их назвать (не сравнивай со скриншотом, придумал порядок только что):

main | main2 | music | communications

и т.п.

При этом, например, у меня правила, что pavucontrol + deadbeef идут всегда в tag music (в скриншоте в таг tile2), выглядя так, что слева deadbeef, справа pavucontrol.

Для двух мониторов я бы еще завел workspace для всяких skype, slack, thunderbird, other_shit.

И т.д.

Т.е. для меня предложенный подход ломает всю «прэлесть» использования awesome (повторю: для меня).

dissident ★★
() автор топика
Ответ на: комментарий от dissident

Чет я не понял чем "каждый workspace = свой layout + свое предназначение" отличается от того что я предложил.

У меня железо г-но + 1 монитор, поэтому их мало, смысл это больше имеет, когда 2 монитора и железо ок.

Я осомом пользовался лет так пять назад на нетбуке на атоме с 10" экраном. И этих рабочих столов у меня было десять. У тебя все гораздо хуже с железом, или за это время осом так разжирел и каждый воркспейс это отдельный инстанс с KDE? Или ты просто смотришь на то сколько приложение в воркспейсе жрет?

micronekodesu ★★★
()
Ответ на: комментарий от micronekodesu

Чет я не понял чем «каждый workspace = свой layout + свое предназначение» отличается от того что я предложил.

Ты сказал

привязать каждое приложение к своему столу и переключаться между ними так.

А у меня workspace для музыки. И к музыке относятся deadbeef + pavucontrol, а это два приложения. Так же если workspace для коммуникации, то там туева хуча всякого г-на. Т.е. один workspace = 1 приложение ломает мне «прэлесть» и «awesome» и станотся «awful» (прямо как в его документации).

Я бы хотел одновременно:

  • оставить идею: один workspace = или одно предназначение или какой-то конкретный layout или и то и другое вместе, но при этом в workspace могут быть много программ, что вписывается в понятие «предназначение» - у многих программ схожее предназначение
  • иметь возможность не только «прыгать» между workspace’ами, но и «внутри» workspace’ов между программами схожего предназначения, например, подобным образом, т.е. если Win+N переключает workspace, то пусть Win+Shift+N переключает программу внутри workspace

Я осомом пользовался лет так пять назад на нетбуке на атоме с 10" экраном. И этих рабочих столов у меня было десять.

У меня на двух мониторах было тоже около десяти, примерно поровну по ок. 5 на каждый монитор.

У тебя все гораздо хуже с железом, или за это время осом так разжирел и каждый воркспейс это отдельный инстанс с KDE? Или ты просто смотришь на то сколько приложение в воркспейсе жрет?

Гораздо хуже. Моему железу более 10 лет. И я задолбался объяснять, почему так вышло (и так понятно).

А awesome как летал, так и летает. Причем летает он настолько, что вот у меня полгода назад был thinkpad за 1000 баксов, так он там (сам по себе я имею ввиду) летал так же шустро как на нынешнем г-не.

Просто на нынешнем г-не мне столько workspace’ов не надо, потому что одновременно skype + chromium + thunderbird + firefox и уже тошнить мое г-но начинает.

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 1)

Смотреть в сторону awful.client. Более подробно могу попробовать нарекомендовать часов через шестнадцать-восемнадцать, но обязательно забуду, так что не стесняйся меня кастануть.

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

но обязательно забуду, так что не стесняйся меня кастануть.

Обязательно. Я тут понял, что мне этого не хватало все те годы, что я пользуюсь awesome’ом, везде его ставлю, где могу и повторяю: «awesome!». Свихнулся в-общем. Но вот этого не хватало. Win+j/k не очень удобны, да и то мне пришлось дефолтные поменять чтобы переключались иначе https://github.com/awesomeWM/awesome/issues/2462#issuecomment-436862333, т.е. не согласно stack’у, а согласно положению в taskbar.

Т.е. кажется я уже понял как это сделать. Точно тем же:

    awful.key({ modkey, Shift        }, "1",
        function ()
            -- Something like  
            -- awful.client.focus.byidx(1)
            -- but AFAIR this switches to the window to the right
            -- what I want is to switch to 1 window in the
            -- taskbar (no matter what stack looks like)
        end,
        {description = "focus to window 1 in taskbar", group = "client"}
    ),

и т.д.

Сегодня поздно, завтра суббота - нельзя работать ведь жидам (везде жиды (с)), а в воскресенье сделаю, разве что ты опередишь.

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 4)
Ответ на: комментарий от dissident

Только вот именно, что awful.client.focus.byidx использует relative index, т.е. byidx(3) значит «3 окна направо», а byidx(-3) значит «3 окна налево», а мне нужен «index in the taskbar», т.е. awful.client.focus.smth(3), что значит «3-ее окно в taskbar». Или использовать iterate, чтобы получить первый а потом от него прыгнуть byidx’ом вправо N раз?

да и еще проблема… Win-Shift-N перемещает окно в N-тый workspace, Win-Ctrl-N тоже делает что-то непонятное, Win-Alt-N делает что-то вообще непонятное в mc и даже в терминале, так что даже хез, что тут использовать…

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 5)
Ответ на: комментарий от dissident

В общем должно работать как-то так:

--- {{{ From https://www.reddit.com/r/awesomewm/comments/gd4qxl/get_index_of_client_in_tasklist/ with some modifications
local function fixed_idxing_filter(c, screen)
	if not c then
		return false
	end
	if not (c.skip_taskbar or c.hidden or c.type == "splash" or c.type == "dock" or c.type == "desktop") and awful.widget.tasklist.filter.currenttags(
		c,
		screen
	) then
		return true
	end
	return false
end

local function client_by_taskbar_idx(screen, i)
	local list = capi.client.get()

	local idx = 0
	for _, c in ipairs(list) do
		if util.fixed_idxing_filter(c, screen) then
			idx = idx + 1
			if (idx == i) then
				return c
			end
		end
	end

	return nil
end

function client_taskbar_idx(client)
	local screen = client.screen
	local list = client.get()

	local idx = 0
	for _, c in ipairs(list) do
		if util.fixed_idxing_filter(c, screen) then
			idx = idx + 1
			if (c == client) then
				return idx
			end
		end
	end
	return 1
end
--- }}}

local function client_focus_by_taskbar_idx(taskbar_idx)
    local focused_client = awful_client.next(0)
    local current_focused_client_idx = client_taskbar_idx(focused_client)
    awful.client.focus.byidx(relative_idx)
end



globalkeys = gears.table.join(

-- skip

    awful.key({ modkey,           }, "F2",
        function ()
            client_focus_by_taskbar_idx(2)
        end,
        {description = "focus client 1 in taskbar", grpup = "client"}
    ),
    awful.key({ modkey,           }, "F2",
        function ()
            client_focus_by_taskbar_idx(2)
        end,
        {description = "next window to the left by index", group = "client"}
    ),

-- skip

Только не работает. ;)

    local focused_client = awful_client.next(0)

Вот это какую-то ерунд возвращает. Так и не понял, как добраться до currently focused client. Вроде бы так:

client.focus
    The focused client or nil (in case there is none).

        focus client

(c) https://awesomewm.org/doc/api/classes/client.html

Но что-то тоже не очень. Awesome wm. Awful API. ;)

2mord0d: поправь меня plz, если я слишком много наговнокодил (ну т.е. IMO это будет работать в конце концов, ну т.е. надо бы еще проверок добавить что когда нажимаешь Win+F4, а окон всего 3, то ничего не происходит), но может это можно много проще сделать?

dissident ★★
() автор топика
Ответ на: комментарий от dissident

PS Забыл:

    local relative_idx = taskbar_idx - current_focused_client_idx

Ну т.е. весь смысл в:

local function client_focus_by_taskbar_idx(taskbar_idx)
    -- TODO: check that taskbar_idx is > 1 and <= this_tag_clients_size, if not - return
    local focused_client = awful_client.next(0) -- does not work
    if focused_client ~= nil then
        local focused_client_taskbar_idx = client_taskbar_idx(focused_client)
        local relative_idx = taskbar_idx - focused_client_taskbar_idx
        awful.client.focus.byidx(relative_idx)
    end
end

Остальное - всякий util. Вот только не могу достать никаких currently focused client if any.

@mord0d: тест фичи (как правильно писать 2user (комментарий))

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 8)
Ответ на: комментарий от dissident

util.fixed_idxing_filter

У тебя не util.fixed_idxing_filter, а просто fixed_idxing_filter, как и прочие util.* в коде выше.

local focused_client = awful_client.next(0)
Вот это какую-то ерунд возвращает.

Потому что это относительное смещение. То есть он смещает на i клиентов. Естественно 0 у тебя никуда не ведёт. Вторым аргументом awful.client.next() жрёт клиент, относительно которого смещать (по умолчанию — текущий клиент в фокусе).

Так и не понял, как добраться до currently focused client.

В функции fixed_idxing_filter() можешь использовать c.focused, в client_taskbar_idx()client, обе эти переменные содержат объект клиента, передаваемого им.

А если тебе нужно получить клиент в фокусе из всех, то нужно проходиться по всем клиентам:

local function get_focused_client()
  for _, c in ipairs(awful.client.get()) do
    if c and c.focused then
      return c
    end
  end
  return nil
end

Но это некоторый оверхед.

---

Может ещё что добавлю, когда окончательно проснусь.

---

суббота - нельзя работать

Шаббат, да. Но на котов это вроде как не распространяется.

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

@mord0d:

Потому что это относительное смещение. То есть он смещает на i клиентов. Естественно 0 у тебя никуда не ведёт. Вторым аргументом awful.client.next() жрёт клиент, относительно которого смещать (по умолчанию — текущий клиент в фокусе).

А вот оказывается awful.client.next(0) как раз и возвращает текущего сфокусированного. Другие способы у меня не заработали (может не умею готовить их).

А если тебе нужно получить клиент в фокусе из всех, то нужно проходиться по всем клиентам:

Ну вот оказывается не нужно.

Может ещё что добавлю, когда окончательно проснусь.

Только добавь plz к тому, что ниже, бо оно работает. Вобщем я кончил.

Мне только не нравится функция selected_tag_number_of_clients, наверняка это можно сделать короче и без copy paste из функции client_taskbar_idx, но как я так и не понял.

Да и awful.widget.tasklist.filter.currenttags(c, screen) в принципе лишнее, так как все это фильтруется и так при вызове awful.client.iterate, но это как раз неплохо, больше проверок - лучше.

Конечно если бы это было на работе или там в какой-то проект я бы такого не закомитил (из-за selected_tag_number_of_clients), а так - работает и ладно. Но любые упрощения mile widzane!

-- {{{ Mine

    -- {{{ From https://www.reddit.com/r/awesomewm/comments/gd4qxl/get_index_of_client_in_tasklist/ with some modifications
    local function fixed_indexing_filter(c, screen)
        if not c then
            return false
        end
        if not (c.skip_taskbar or c.hidden or c.type == "splash" or c.type == "dock" or c.type == "desktop") and 
            (screen == nil or awful.widget.tasklist.filter.currenttags(c, screen)
        ) then
            return true
        end
        return false
    end

    -- Returns client index in the taskbar (first on the left will have index = 1)
    local function client_taskbar_idx(client)
        local focused_screen = awful.screen.focused()
        local selected_tag = focused_screen.selected_tag
        local selected_tag_filter = function (c) return c.first_tag == selected_tag end
        local first_client_taskbar_idx = 1
        local client_screen = client.screen

        local client_taskbar_idx = 0
        for c in awful.client.iterate(selected_tag_filter, first_client_taskbar_idx, focused_screen) do
            if fixed_indexing_filter(c, client_screen) then
                client_taskbar_idx = client_taskbar_idx + 1
                if (c == client) then
                    return client_taskbar_idx
                end
            end
        end

        return nil
    end
    -- }}}
    
    -- Returns total number of clients in the currently selected tag
    local function selected_tag_number_of_clients()
        local focused_screen = awful.screen.focused()
        local selected_tag = focused_screen.selected_tag
        local selected_tag_filter = function (c) return c.first_tag == selected_tag end
        local first_client_taskbar_idx = 1

        local number_of_clients = 0
        for c in awful.client.iterate(selected_tag_filter, first_client_taskbar_idx, focused_screen) do
            if fixed_indexing_filter(c) then
                 number_of_clients = number_of_clients + 1
            end
        end
        return number_of_clients
    end

    -- Switches focus to the client of index in the taskbar = taskbar_idx:
    --    * client with 1st taskbar item will have index 1
    --    * client with 2nd taskbar item will have index 2
    --    * etc
    local function client_focus_by_taskbar_idx(taskbar_idx)
        -- User wants to focus a non-existing client, e.g. there are only 2 opened in
        -- focused screen selected tag cllients and user wants to focus 3rd one, as there is
        -- no 3rd one just do nothing
        if taskbar_idx < 1 or taskbar_idx > selected_tag_number_of_clients() then
            return
        end
     
        local focused_client = awful.client.next(0) -- does not work

        if focused_client ~= nil then
            local focused_client_taskbar_idx = client_taskbar_idx(focused_client)
            if focused_client_taskbar_idx ~= nil then
                local relative_idx = taskbar_idx - focused_client_taskbar_idx
                awful.client.focus.byidx(relative_idx)
            end
        end
    end
    --- }}}

-- }}}

-- {{{ Key bindings
globalkeys = gears.table.join(

--- skip ---

    -- {{{ Mine: added/changes navigation for clients

--- skip ---

        -- {{{ added (browser-tab-like switching of clients):
        --     moving between windows with Mod4-Fn (as between tags with Mod4-n)
        awful.key({ modkey,           }, "F1",
            function () client_focus_by_taskbar_idx(1) end,
            {description = "focus client 1 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F2",
            function () client_focus_by_taskbar_idx(2) end,
            {description = "focus client 2 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F3",
            function () client_focus_by_taskbar_idx(3) end,
            {description = "focus client 3 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F4",
            function () client_focus_by_taskbar_idx(4) end,
            {description = "focus client 4 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F5",
            function () client_focus_by_taskbar_idx(5) end,
            {description = "focus client 5 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F6",
            function () client_focus_by_taskbar_idx(6) end,
            {description = "focus client 6 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F7",
            function () client_focus_by_taskbar_idx(7) end,
            {description = "focus client 7 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F8",
            function () client_focus_by_taskbar_idx(8) end,
            {description = "focus client 8 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F9",
            function () client_focus_by_taskbar_idx(9) end,
            {description = "focus client 9 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F10",
            function () client_focus_by_taskbar_idx(10) end,
            {description = "focus client 10 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F11",
            function () client_focus_by_taskbar_idx(11) end,
            {description = "focus client 11 in taskbar", group = "client"}
        ),
        awful.key({ modkey,           }, "F12",
            function () client_focus_by_taskbar_idx(12) end,
            {description = "focus client 12 in taskbar", group = "client"}
        ),
        -- }}}

    -- }}}
dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 2)

Если надумаешь перелезть на xmonad - напиши в личку, поделюсь конфигом, там всё есть что ты хочешь.

anonymous
()
Ответ на: комментарий от dissident

А вот оказывается awful.client.next(0) как раз и возвращает текущего сфокусированного.

Так и должно быть.

Мне только не нравится функция selected_tag_number_of_clients

Есть же awful.screen.selected_tags().

Да и awful.widget.tasklist.filter.currenttags(c, screen) в принципе лишнее, так как все это фильтруется и так при вызове awful.client.iterate, но это как раз неплохо, больше проверок - лучше.

Lua однопоточный, потому на каждую лишнюю проверку у тебя тратится время, интерфейс будет лагать.

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

А вот оказывается awful.client.next(0) как раз и возвращает текущего сфокусированного.

Так и должно быть.

Т.е. твое:

local function get_focused_client()
  for _, c in ipairs(awful.client.get()) do
    if c and c.focused then
      return c
    end
  end
  return nil
end

Можно заменить на:

local function get_focused_client()
    return awful.client.next(0)
end

Разве что я чего-то не понял?

PS И awful.client.get() что-то у меня не работал. Или что-то другое не работало. Сменил на awful.client.iterate - заработало.

Есть же awful.screen.selected_tags().

Мне нужно знать кол-во clients (программ) в selected_tag, а не кол-во selected_tags(), чтобы сделать вот этот sanity check:

    -- Switches focus to the client of index in the taskbar = taskbar_idx:
    --    * client with 1st taskbar item will have index 1
    --    * client with 2nd taskbar item will have index 2
    --    * etc
    local function client_focus_by_taskbar_idx(taskbar_idx)
        -- User wants to focus a non-existing client, e.g. there are only 2 opened in
        -- focused screen selected tag clients and user wants to focus 3rd one, as there is
        -- no 3rd one just do nothing
        if taskbar_idx < 1 or taskbar_idx > selected_tag_number_of_clients() then
            return
        end

Можно было бы конечно выделить общую часть client_taskbar_idx() и selected_tag_number_of_clients() или, как сейчас модно говорить, рефакторизировать, но меня не покидает ощущение, что это можно сделать проще. Да и этот код IMHO не измениться никогда. Разве что кто-то (ты, например) расскажет как проще вернуть количество клиентов в выбранном tag, чем посчитать итерируя.

Lua однопоточный, потому на каждую лишнюю проверку у тебя тратится время, интерфейс будет лагать.

Да ладно.

  1. Не лагает даже на моем г-не. Переключаются окошки так же шустро, как и Mod4-j/k (которые я тоже, кстати, поменял, чтобы было так, что Mod4-j переключает в окно левее в таскбаре, а Mod4-k правее, а не как оригинально стэкозависимо). Но это я уже говорил. Короче кому как удобнее. Мои настройки более «аля xfce чем аля i3»:
        -- {{{ changed (was according to stack, now according to taskbar position):
        --     moving between windows left/right (as in tasklist)
        awful.key({ modkey,           }, "j",
            function () awful.client.focus.byidx(-1) end,
            {description = "next window to the left by index", group = "client"}
        ),
        awful.key({ modkey,           }, "k",
            function () awful.client.focus.byidx(1) end,
            {description = "next window to the right by index", group = "client"}
        ), -- }}}
  1. Сколько там этих проверок? Ну пусть у меня 20 окон открыто выбранном таге. Я тыкаю Mod4-Fn. Ну 20 лишних проверок на этот тык. Фигня
dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 4)
Ответ на: комментарий от anonymous

Если надумаешь перелезть на xmonad - напиши в личку, поделюсь конфигом, там всё есть что ты хочешь.

А где у тебя личка, если ты не залогинился? А так, мне awesome нравится тем, что может изображать нормальное такое XFCE/LXDE/Gnome2/Mate/whatever, а может tiling WM. Ну и как видно по моим изменениям Mod4-j/k мессагой выше, мне проще управлять думая а taskbar’е, нежели о stack’е. Что не значит, что tile я не использую. Но именно то, что можно и так и этак мне нравится. И то, что каждому tag (workspace) можно приписать конкретный layout и каждому client (программе), на каком tag’е она будет открываться тоже нравится. Не уверен, есть ли все это в xmonad. Что посмотреть? Этого хватит? https://www.youtube.com/watch?v=3noK4GTmyMw

dissident ★★
() автор топика
Ответ на: комментарий от dissident

Т.е. твое:

Можно заменить на:

Да. Можно даже не городить функцию а юзать напрямую.

И awful.client.get() что-то у меня не работал. Или что-то другое не работало. Сменил на awful.client.iterate - заработало.

У них немного разные юзкейсы. Ну и в твоей версии awesome оно может отличаться, я на master сижу.

Мне нужно знать кол-во clients (программ) в selected_tag, а не кол-во selected_tags()

Да, протупил. Я ещё не успел выпить достаточно кофе чтобы проснуться. ☺

Разве что кто-то (ты, например) расскажет как проще вернуть количество клиентов в выбранном tag, чем посчитать итерируя.

Можно в функции (сигнале) manage/unmanage обновлять глобальную переменную с количеством клиентов:

-- не local!
clients_num = 0

client.connect_signal("manage", function(c)
  -- ...
  if c then
    clients_num = clients_num + 1
  end
end

client.connect_signal("unmanage", function(c)
  -- ...
  if c then
    clients_num = clients_num - 1
  end
end

Но переменная clients_num должна быть глобальной или как-либо иначе быть доступной для всех функций. Это немного костыль, но с ним у тебя будет минимальный оверхед.

mord0d ★★★★★
()
Ответ на: комментарий от dissident

ты можешь получить список окон с лэйаута, можно получить список и вообще всех окон. привязка, группировка - что за детский сад - это xmonad, там всё есть :) вот твой фокус на лэйауте. биндишь на нужный кей и всё

https://pastebin.com/cyQ02VU5

anonymous
()
Ответ на: комментарий от anonymous

у меня это работает только на текующем лэйауте, если надо с любого туда прыгать - возьми W.allWindows

anonymous
()
Ответ на: комментарий от mord0d

Но переменная clients_num должна быть глобальной или как-либо иначе быть доступной для всех функций. Это немного костыль, но с ним у тебя будет минимальный оверхед.

Тогда уже проще как есть - перечислением. В принципе Lua - простой язык, awful - простое и ужасное API, awesome - простой Wm, чего еще ожидать, надо было просто в стиле Uncle Bob’а (кстати посмотрите вот это интервью, из него сразу понятно, что Uncle Bob вообще не имеет представления о чем говорит, хоть Coplien над ним и откровенно издевается, он даже этого не вдупляет) https://www.youtube.com/watch?v=KtHQGs3zFAM. В общем надо было общую часть вынести, ну да х. с ней (другими словами для таких маленьких функций и личного конфига copy paste - не самое страшное).

PS Кстати вот более прямым текстом об этом вашем рефакторинге нашел: https://www.youtube.com/watch?v=mb9VPWbrqmE

dissident ★★
() автор топика
Ответ на: комментарий от anonymous

ты можешь получить список окон с лэйаута, можно получить список и вообще всех окон. привязка, группировка - что за детский сад - это xmonad, там всё есть :) вот твой фокус на лэйауте. биндишь на нужный кей и всё

https://pastebin.com/cyQ02VU5

Вполне возможно. Я более-менее одупляю (ну не считая там какой-нибудь scala) только ocaml. Но даже по названиям не понимаю, как это делает то, что я наговнокодил. Мне надо было по Shift-Fn переключиться на окно, репрезентованное n-тым прямоугольником на taskbar’е. Тут же есть focusByClass принимающая (или как там правильно в функциональных языках currying - whatever) n. Т.е. я так понимаю мне надо повесить на Shift-F1 focusByClass 1, на Shift-F2 focusByClass 2 и т.д.? Затем есть какое-то w.index и кажется это на самом деле в него должны мапиться n-ы из Shift-Fn-ов, но зачем тогда вовсе n? Да и где в findByQuery вообще что-то о workspace’ах? О screen’ах? Ну т.е., я не вижу как findByQuery ограничивает мои Shift-Fn до переключения между «закладками» (читай программами (в awesome called client)) только внутри выбранного workspace’а (в awesome called tag) только на в данный момент «фокуснутый» монитор (в awesome called screen). В этом и был весь смысл. В awesome полно shortcut’ов, чтобы переключаться между скринами, между тагами, а вот между клиентами в данный момент выбранного тага в данный момент «фокусного» скрина - не было, я добавил по аналогии. IMHO findByQuery просто проходится по всем программам, пофигу на workspace’ы, monitor’ы. Ну, и да, я понимаю, что этот код суперкороче, даже останется суперкороче, если сделать его 100% идентичным по назначению, но не уверен, что его быстрее/легче написать. Понять, конечно, да, если одупляешь haskell. Кстати, ты обрати внимание, что в моей пасте то на самом деле больше всего места занимают маппинги (вот эти awful.key), а если из selected_tag_number_of_clients() и client_taskbar_idx() общую часть вынести в отдельную функцию, то будет не сильно длиннее. Anyway, я смотрю https://www.youtube.com/watch?v=3noK4GTmyMw, может стану одуплять лучше.

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 1)
Ответ на: комментарий от dissident

Я плохо воспринимаю видео, текст проще заходит, потому по ссылкам не пойду. ☺

Тогда уже проще как есть - перечислением.

Плохо то, что этот перебор будет происходить каждый раз, когда нужно переключиться на другой клиент. С глобальной переменной и триггером при добавлении/удалении клиента это будет происходить только по необходимости, что снижает нагрузку, а вместе с ней и лаг.

В принципе Lua - простой язык

Да, он простой.

awful - простое и ужасное API

Не везде оно удобное, зато почти универсальное.

awesome - простой Wm

А тут нет. ☺ Он уже не простой WM, с четвёртой версии (на самом деле немного раньше) это уже фреймворк.

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Я плохо воспринимаю видео, текст проще заходит, потому по ссылкам не пойду. ☺

По второй хотя бы сходи, она короткая и там черным по белому.

В первой действительно длинноватое интервью, в котором Коплиен откровенно стебется над Бобом, а тот вообще не вдупляет че делать и че происходит и почему он пришел на интервью, а сидит с х..м в ж..е и как ему теперь себя вести. В-общем-то достаточно посмотреть вторую ссылку, чтобы понять какие рожи он в том интервью корчит и какой маразм пытается втирать.

А тут нет. ☺ Он уже не простой WM, с четвёртой версии (на самом деле немного раньше) это уже фреймворк.

А ну да. Конструктор. Ну я его аж так как ты (глядя на пару твоих постов) не перепиливал.

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 1)
Ответ на: комментарий от mord0d

Плохо то, что этот перебор будет происходить каждый раз, когда нужно переключиться на другой клиент. С глобальной переменной и триггером при добавлении/удалении клиента это будет происходить только по необходимости, что снижает нагрузку, а вместе с ней и лаг.

Да сколько там окон, чтобы прямо лаг заметен был. Неужели луа настолько тормозной? У меня для dwm есть патч как раз для сабжевой фичи. Все летает, и кода там кстати меньше, чем в ваших скриптах.

bread
()
Ответ на: комментарий от dissident

По второй хотя бы сходи, она короткая и там черным по белому.

Тупняк какой-то. o_O

Ну я его аж так как ты (глядя на пару твоих постов) не перепиливал.

Я его очень давно использую, даже Worron начал позже меня и сделал кучу интересного. Со временем втянешься, своего напилишь. ☺

mord0d ★★★★★
()
Ответ на: комментарий от bread

Да сколько там окон, чтобы прямо лаг заметен был.

Зависит ещё от самой операции в итераторе.

Неужели луа настолько тормозной?

Он достаточно быстрый, но однопоточный.

mord0d ★★★★★
()
Ответ на: комментарий от bread

и кода там кстати меньше

Перестаньте наконец сравнивать то, что я методом тыка и Копи и Паста на коленке за утро наговнял с патчами, над которыми люди трудяться, чтобы поделиться ими с миром. Я свое сюда вклеил только, чтобы отметить проблему как решенную и показать, как это можно сделать. Там вообще большую часть занимают сами определения binding’ов (awful.key). Да, это можно «рефакторизировать» в цикл от 1 до 12ти, но зачем? Еще там две функции делают одно и тоже - итерируют по программах, открытых в выбранном воркспейсе на мониторе у которого фокус - одна, чтобы посчитать их количество, другая, чтобы найти номер в данный момент фокусной программы. Да же это тоже можно «рефакторизировать», создав дополнительную утилитную функцию, но зачем?

У меня список дел разбросан по всей комнате на 100500 бумажках. Просто я решил, что в субботу, я, как истинный еврей, буду не работать а маяться х-ней. А с х-ни еще и польза. Теперь, где бы я не нашел работу про линукс - я в полчаса накачу туда awesome, возьму из backup’а свой конфиг и мне будет еще удобнее, чем сейчас. А не привыкай вечно к этим плазмам, гномам, которые уже не гномы и т.п. IMHO стандартной убунту пользоваться невозможно. Уже Windows 98 удобнее была. XFCE/LXDE/….. - ОК, но хочется:

  • чтобы можно было и tiling
  • чтобы можно было сделать так, как тебе хочется
  • чтобы оно летало

И сам осом летает. Не знаю насчет однопоточности, видимо грамотно написан (нет долгих операций). Мои два прохода по списку окон (только в выбранном воркспейсе) при нажатии Shift-Fn вообще не влияют на железе родом из 2008 г.р. Более того, я повторюсь, но ок. полгода назад у меня был thinkpad за ок. 1000$ и сам по себе awesome там летал. Так вот на г-не 2008 г.р. летает так же. Кроме того, его можно перегружать, а все останется на своих местах. Его можно бесконечно кастомизировать под себя, а можно оставить часть как есть.

Вот я смотрю https://www.youtube.com/watch?v=3noK4GTmyMw, половину посмотрел и меня не убедило. Я вот хочу иметь пару workspace’ов с float layout’ом (как винда). Может он еще до этого не дошел? Ну и c awesome ставить ничего почти не надо, какие-нибудь там виджеты + накатил свой конфиг. А не там nitrogen, compton, xmobar, ХЕЗ что еще.

И конфиг пишется не для того, чтобы его кто-то читал, а чтобы он конфигурировал. И на Lua писать легче. Да, читать хуже, чем Haskell. Но писать лучше.

PS Я пробовал i3 еще и он слишком ограничен. Здесь я могу как хочу. Захочу вообще в Windows XP превращу. А потом еще покручу и сделаю кнопку, которая часть воркспейсов делает Windows XP, а часть i3. А то i3 - это как девушка, которая дает только в попу. Круто, но почему только?

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 1)
Ответ на: комментарий от mord0d

Тупняк какой-то. o_O

Тупняк - это Uncle Bob. А он ведь король рефакторинга. Ну там следом за Фаулером. Рефакторинг конфига блин. Меньше кода. Я хотел, чтобы WM был как браузер с закладками, за утро сделал. Без всякого рефакторинга. Методом тыка и гугла. Без TDD, SAFe-а, AGILE-a, eXtreme-а, SCRUM-a и прочего SCUM-а.

dissident ★★
() автор топика
Ответ на: комментарий от mord0d

Ну вот я упростил немного и убрал лишнюю проверку (screen == nil or awful.widget.tasklist.filter.currenttags(c, screen) - особо читаемей не стало:

-- {{{ Mine

    -- {{{ From https://www.reddit.com/r/awesomewm/comments/gd4qxl/get_index_of_client_in_tasklist/ with some modifications
    local function fixed_indexing_filter(c)
        if not c then
            return false
        end
        if not (c.skip_taskbar or c.hidden or c.type == "splash" or c.type == "dock" or c.type == "desktop") then
            return true
        end
        return false
    end

    function focused_screen_current_tag_client_iterator()
        local focused_screen = awful.screen.focused()
        local selected_tag_filter = function (c) return c.first_tag == focused_screen.selected_tag end
        local first_client_taskbar_idx = 1
        return awful.client.iterate(selected_tag_filter, first_client_taskbar_idx, focused_screen)
    end

    -- Returns client index in the taskbar (first on the left will have index = 1)
    local function client_taskbar_idx(client)
        local client_taskbar_idx = 0
        for c in focused_screen_current_tag_client_iterator() do
            if fixed_indexing_filter(c) then
                client_taskbar_idx = client_taskbar_idx + 1
                if (c == client) then
                    return client_taskbar_idx
                end
            end
        end

        return nil
    end
    -- }}}
    
    -- Returns total number of clients in the currently selected tag
    local function selected_tag_number_of_clients()
        local number_of_clients = 0
        for c in focused_screen_current_tag_client_iterator() do
            if fixed_indexing_filter(c) then
                 number_of_clients = number_of_clients + 1
            end
        end
        return number_of_clients
    end

    -- Switches focus to the client of index in the taskbar = taskbar_idx:
    --    * client with 1st taskbar item will have index 1
    --    * client with 2nd taskbar item will have index 2
    --    * etc
    local function client_focus_by_taskbar_idx(taskbar_idx)
        -- User wants to focus a non-existing client, e.g. there are only 2 opened in
        -- focused screen selected tag clients and user wants to focus 3rd one, as there is
        -- no 3rd one just do nothing
        if taskbar_idx < 1 or taskbar_idx > selected_tag_number_of_clients() then
            return
        end
     
        local focused_client = awful.client.next(0)
        if focused_client ~= nil then
            local focused_client_taskbar_idx = client_taskbar_idx(focused_client)
            if focused_client_taskbar_idx ~= nil then
                local relative_idx = taskbar_idx - focused_client_taskbar_idx
                awful.client.focus.byidx(relative_idx)
            end
        end
    end
    -- }}}

-- }}}

(awful.key - байндинги уже не всобачиваю, там тоже самое).

Ай Lua как Lua. Вон WoW весь на ней построен. Эта match3 игра где надо апгрейды в виде выигрыша делать дому там, саду, русская, на мобилко, суперпопулярная, в Lua. И ниче, нормально.

Кому-то надо Haskell.

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 2)
Ответ на: комментарий от dissident

Извини, не стал читать всю портянку. Я о том, что там реально функция в десять строк на си. А эти луа-обвязки только все усложняют. Правда, в случае dwm еще нужно сам таскбар доделать, так что побольше кода конечно.

bread
()
Последнее исправление: bread (всего исправлений: 1)
Ответ на: комментарий от bread

Извини, не стал читать всю портянку. Я о том, что там реально функция в десять строк на си. А эти луа-обвязки только все усложняют. Правда, в случае dwm еще нужно сам таскбар доделать, так что побольше кода конечно.

Ну, а я посмотрел distrotube «Getting starting with xmonad» и особенно его конфиг в конце. Спасибо, у меня нет всей жизни.

В простыне я указал, что то, что ты показал делало не совсем то, если бы я на Lua написал тоже самое вышло бы примерно похожее количество строк.

А вообще, код на Haskell красив и настолько сложен, что его не напишешь на коленке. Это что, плюс для конфига WM?

Lua зато минимальна как топор. Как Lisp.

А еще плюс awesome, что он искаропки работает. Правда в 50% случаев как УГ. И эти случаи можно постепенно изменять, учась. Научившись можно в нем сделать все, что угодно.

xmonad надо уметь изначально и доставить к нему 100500 хуков, импортов и программ, после чего он будет на 90% УГ и весь процесс займет гораздо дольше. Я не спорю, это круто, но для каждого.

Я лучше https://www.youtube.com/watch?v=FGTcj6kSzGA послушаю, например, через час лягу и послушаю, фичу я на коленке сделал -> у меня есть время послушать про искусство войны. С xmonad у меня бы его не было. Хотя да, развивает мозг. Ну короче. Все ж понятно же. Каждому свое. Кому пирацетам, а кому агматин. Кому водку, кому кокаин. Кому раст, а кому Go. Кому Lua, а кому Haskell. Круто было бы уметь Haskell. Но я про монады раз пять уже все понял и каждый раз забываю, что понял. Дебил.

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 1)
Ответ на: комментарий от mord0d

PS @mord0d: Кстати, ты не в курсе, что это, за taglist_buttons, tasklist_buttons:

local taglist_buttons = gears.table.join(
                    awful.button({ }, 1, function(t) t:view_only() end),
                    awful.button({ modkey }, 1, function(t)
                                              if client.focus then
                                                  client.focus:move_to_tag(t)
                                              end
                                          end),
                    awful.button({ }, 3, awful.tag.viewtoggle),
                    awful.button({ modkey }, 3, function(t)
                                              if client.focus then
                                                  client.focus:toggle_tag(t)
                                              end
                                          end),
                    awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
                    awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
                )

local tasklist_buttons = gears.table.join(
                     awful.button({ }, 1, function (c)
                                              if c == client.focus then
                                                  c.minimized = true
                                              else
                                                  c:emit_signal(
                                                      "request::activate",
                                                      "tasklist",
                                                      {raise = true}
                                                  )
                                              end
                                          end),
                     awful.button({ }, 3, client_menu_toggle_fn()),
                     awful.button({ }, 4, function ()
                                              awful.client.focus.byidx(1)
                                          end),
                     awful.button({ }, 5, function ()
                                              awful.client.focus.byidx(-1)
                                          end))

И нигде ни в taglist ни в tasklist таких кнопок не заметил.

dissident ★★
() автор топика
Ответ на: комментарий от dissident

Ну вот я упростил немного и убрал лишнюю проверку (screen == nil or awful.widget.tasklist.filter.currenttags(c, screen) - особо читаемей не стало:

Нормальный у тебя код, не понимаю что ты напрягаешься в читабельность.

mord0d ★★★★★
()
Ответ на: комментарий от dissident

Кстати, ты не в курсе, что это, за taglist_buttons, tasklist_buttons:

Не помню уже. Но раз они локальные, то стоит искать в том же файле.

И нигде ни в taglist ни в tasklist таких кнопок не заметил.

Они же локальные, их нигде больше не видно.

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Они потом используются:

awful.screen.connect_for_each_screen(function(s)
    -- Wallpaper
    set_wallpaper(s)

--- skip ---

    -- Create a taglist widget
    s.mytaglist = awful.widget.taglist {
        screen  = s,
        filter  = awful.widget.taglist.filter.all,
        buttons = taglist_buttons -- вот тут
    }

    -- Create a tasklist widget
    s.mytasklist = awful.widget.tasklist {
        screen  = s,
        filter  = awful.widget.tasklist.filter.currenttags,
        buttons = tasklist_buttons --- и тут
    }

--- skip ---

Ну т.е. я так понимаю что taglist | tasklist - это где-то здесь:

только вот где там эти все кнопки…

dissident ★★
() автор топика
Ответ на: комментарий от dissident

только вот где там эти все кнопки…

Не путай keys и buttons. ☺

keys — про клавиатуру, buttons — про мышь.

  • 1 — Левая кнопка мыши;
  • 2 — Средняя кнопка мыши;
  • 3 — Правая кнопка мыши;
  • 4 — Скролл вверх;
  • 5 — Скролл вниз.
mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Я обнаружил блягодаря этому, что:

  1. awful.client.next(0) можно с успехом заменить на client.focus
  2. Мой код не работает для минимизированных клиентов, так как я ищу сфокусированного, чтобы его позицию использовать для обсчета куда прыгать, пришлось сделать так, что если сфокусированного клиента нет - то берем focused_client_taskbar_idx = 1, а не ничего не делаем. Кроме того перед тем как его фокусить, такому клиенту надо сделать:
        client_to_focus:emit_signal(
            "request::activate",
            "tasklist",
            {raise = true}
        )
  1. Удалось реализовать функционал minimize/maximize all windows: https://pastebin.pl/view/8b1bce5b

Спасибо еще раз! Надеюсь окончательный пример Shift-Fn тут: https://pastebin.pl/view/22a7b612

Надоело уже сюда простыню эту постить. Надеюсь это уже последний баг, ну или последний из тех, что мешают жить.

dissident ★★
() автор топика
Последнее исправление: dissident (всего исправлений: 1)
Ответ на: комментарий от dissident

awful.client.next(0) можно с успехом заменить на client.focus

К сожалению не везде.

Мой код не работает для минимизированных клиентов

Тут ничего дельного не подскажу, с минимизированными клиентами не могут справиться даже разработчики (поэтому unminimize работает на рандомный клиент). ☺

Удалось реализовать функционал minimize/maximize all windows

А не проще деактивировать все теги? (Правой кнопкой мыши по тегу, если ты ничего не менял. Также можно активировать несклько, если нужно.)

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Мой код не работает для минимизированных клиентов

Тут ничего дельного не подскажу, с минимизированными клиентами не могут справиться даже разработчики (поэтому unminimize работает на рандомный клиент). ☺

Ну теперь уже работает:

  1. Если все минимизированы и ни один не в фокусе - считает, что в фокусе первый, что логично, тогда Sift-Fn все равно работает
  2. На всякий случай unminimize’ирует Shift-Fn-тое окно перед его фокусировкой

А не проще деактивировать все теги? (Правой кнопкой мыши по тегу, если ты ничего не менял. Также можно активировать несклько, если нужно.) ☺

Ну с клавиатуры привычней. Это ж аналог Mod4-L (L кажется) в винде такой. А вообще да, так тоже можно.

dissident ★★
() автор топика
Ответ на: комментарий от mord0d

Ну с клавиатуры привычней.

А с клавиатуры по умолчанию это Super + Control + {номер тега}.

Ну вот, а я баран, не знал. Спасибо!

dissident ★★
() автор топика
Ответ на: комментарий от dissident
   Ну с клавиатуры привычней.

А с клавиатуры по умолчанию это Super + Control + {номер тега}.

Ну вот, а я баран, не знал. Спасибо!

Некоторая разница все же есть. Мое: https://pastebin.pl/view/8b1bce5b минимизирует все окна, если какое-то из них не минимизировано и максимизирует, если все минимизированы, при этом выбранный таг остается на месте и можно, например, тыкнуть RMB по wallpaper’у и выбрать edit config -> редактор откроется в том же таге, единственный не минимизированный, но все прочее все так же будет продолжать висеть в таскбаре.

Твое: Super + Control + {номер тега} прячет все клиенты с тэга, дополнительно «отвыбирая его», т.е. если это нажать то:

  • В taskbar ничего не будет
  • Повторить эксперимент с edit config -> в taglist таги станут красными, «приглашая» выбрать, в котором таге открыть редактор
  • Выбранного тага после этой операции больше нету

Т.е. и то и то ведет к тому, что wallpaper виден, но немного по-разному работает.

dissident ★★
() автор топика
Ответ на: комментарий от dissident

Т.е. и то и то ведет к тому, что wallpaper виден, но немного по-разному работает.

Это да, но твой вариант при разворачивании развернёт и те клиенты, которые были свёрнуты до «сворачивания всех окон» (то есть вернуть как было возможности нет). Но иметь дополнительный вариант работы с клиентами лишним не будет.

Я не особо понимаю твой юзкейс, так как за последние лет шесть всего пару раз свернул mpv, а мышь с рабочего стола отключил ещё раньше.

можно, например, тыкнуть RMB по wallpaper’у

Super + W открывает меню, если ты это не менял. ☺

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Это да, но твой вариант при разворачивании развернёт и те клиенты, которые были свёрнуты до «сворачивания всех окон» (то есть вернуть как было возможности нет). Но иметь дополнительный вариант работы с клиентами лишним не будет.

Ну да, «вернуть как было возможности нет». Скорее свернет все, если хоть один развернут. И развернет все обратно только если все свернуты. Это не тоже самое, что Win-L в виндоус. Но мне было лень создать и поддерживать таблицу флагов для каждого тэга - что там свернуто, а что развернуто.

Я не особо понимаю твой юзкейс, так как за последние лет шесть всего пару раз свернул mpv, а мышь с рабочего стола отключил ещё раньше.

У меня это давно зачем-то висело с TODO припиской и какими-то пробами, твой ответ про taglist_buttons/tasklist_buttons позволил мне посмотреть как они сделаны и что делают и сделать то, что было записано в TODO. Теперь, особенно после напоминания:

Super + W открывает меню, если ты это не менял. ☺

я не припоминаю зачем мне это было надо. Может, чтобы быстро убрать порнуху, когда кто-то подходит или что-то в этом стиле.

dissident ★★
() автор топика
Ответ на: комментарий от dissident

Но мне было лень создать и поддерживать таблицу флагов для каждого тэга - что там свернуто, а что развернуто.

Да, это очень комплексная штука получится. Там очень многое надо учесть.

Может, чтобы быстро убрать порнуху, когда кто-то подходит или что-то в этом стиле.

Поэтому я и порекомендовал Super + Control + {номер тега}. ☺

Я вообще не люблю когда кто-то смотрит что я делаю, даже если я пишу опенсорц.

mord0d ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.