Как обрезать области, нарисованные методами `: layout` в awesome-wm? - PullRequest
0 голосов
/ 07 мая 2019

Это продолжение до Как заставить события мыши распространяться на виджеты в контейнерах `scroll`?

TL;DR:

Метод :layout, который я реализовал, заставляет виджет рисовать поверх всех других виджетов (см. Рисунки ниже).Как я могу ограничить, где метод :layout будет рисовать мои виджеты и где он позволит мне взаимодействовать с детьми?

Более длинная версия:

Так что я закончил патчем scrollконтейнер и то, что я в основном сделал, это то, что я реализовал метод :layout, основанный на вычислениях смещения, которые уже были сделаны в исходном коде контейнера scroll.

Это в основном то, что я сделал (я будутолько поместите соответствующие части здесь):


-- this function emits signals `self._private.fps` times a second
local _need_scroll_redraw = function(self)
    if not self._private.paused and not self._private.scroll_timer then
        self._private.scroll_timer = timer.start_new(1 / self._private.fps, function()
            self._private.scroll_timer = nil
            self:emit_signal("widget::redraw_needed")
            self:emit_signal("widget::layout_changed") -- this is the only 
                                                       -- line that I added 
                                                       -- to this function
        end)
    end
end

local function calculate_info(self, context, width, height)
    -- this is a longer function, but in summary here we calculate the
    -- ideal size that the child would like to be, we see if the child
    -- is bigger than the space we have for drawing, and if it is, 
    -- we calculate offsets (and we call `_need_scroll_redraw` here) 
    -- so we later know where and how often to `:draw` and `:fit` it
end

function scroll:fit(context, width, height)
    local info = calculate_info(self, context, width, height)
    return info.fit_width, info.fit_height
end

function scroll:layout(context, width, height)
    local result = {}
    local i = calculate_info(self, context, width, height)

    table.insert(result, base.place_widget_at(
        self._private.widget, i.first_x, i.first_y, i.surface_width, i.surface_height 
    ))

    return result
end

-- Also, there was a `:draw` method, but I took it out entirely since
-- if I add the `:layout` method, things get drawn just fine
-- P.S: I also tried to implement what was in the `:draw` method, inside
-- the `:layout` method, so that it'll clip properly. I also tried that idea
-- with the `:before_draw_children` and `:after_draw_children` methods
-- but since I don't know how to use cairo, god knows what I wrote there,
-- but it didn't work

С виджетом прокрутки по умолчанию мой виджет выглядит так, но ничего, на что я нажимаю, не работает: like this

Но с изменениями, которые я сделал выше, виджет со строками прокручивается, и я могу просто щелкнуть по каждому дочернему элементу и заставить его реагировать, просто он рисует все вне его границ, и ятакже можно щелкнуть мышью по элементам, находящимся за пределами границ:

not like this

Поэтому мой вопрос: как мне ограничить то, что отображает метод :layout, чтобы это жИли как работает макет по умолчанию scroll, но все еще можно взаимодействовать с детьми?

1 Ответ

0 голосов
/ 08 мая 2019

Не проверено, но я думаю:

function scroll:before_draw_children(context, cr, width, height)
    cr:rectangle(0, 0, width, height)
    cr:clip()
end

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

Обратите внимание, что это только предотвращает рисование дочерних виджетов. Это не заставляет удивительные WM "забывать о них". Я имею в виду следующее: вы все равно можете нажать на то место, где был бы виджет, если бы он был виден. Клик по-прежнему будет обрабатываться виджетом. Только фактическое рисование дочернего виджета не допускается.

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

И нет, насколько я знаю / вижу, нет способа помешать неотрисованным виджетам получать нажатия кнопок.

...