如何在awesome-wm中剪切`:layout`方法绘制的区域?

时间:2019-05-07 16:02:21

标签: awesome-wm

这是How to make mouse events propagate to widgets in `scroll` containers?

的后续活动

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 :(得分:0)

未经测试,但我想:

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

这将使用描述滚动小部件大小的矩形并将所有子代剪切到该矩形,这意味着它们不能在滚动小部件外部绘制。

请注意,这仅防止绘制子窗口小部件。它不会使awesomeWM“忘记它们”。我的意思是:如果可见,您仍然可以单击小部件的位置。单击仍将由窗口小部件处理。仅阻止实际绘制子窗口小部件。

以上就是为什么我在您的原始问题中问您是否只想滚动一个小部件,而不滚动任何小部件。因为如果滚动窗口小部件覆盖了整个wibox,那么整个问题就消失了。

据我所知/所见,没有办法阻止未绘制的窗口小部件获得按钮点击。