【问题标题】:How to clip areas drawn by `:layout` methods in awesome-wm?如何在 awesome-wm 中剪切由`:layout` 方法绘制的区域?
【发布时间】:2019-09-25 08:18:17
【问题描述】:

这是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

使用默认的滚动小部件,我的小部件看起来像这样,但我点击的没有任何效果:

但是通过我上面所做的更改,带有行的小部件确实滚动了,我可以很好地点击每个孩子并让它做出反应,只是它在其边界之外绘制 所有内容 ,我也可以点击边界之外的东西:

所以我的问题是:我将如何限制 :layout 方法显示的内容,让它以默认 scroll 布局的方式工作,但仍然能够与孩子互动?

【问题讨论】:

    标签: awesome-wm


    【解决方案1】:

    未经测试,但我猜:

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

    这将获取描述滚动小部件大小的矩形并将所有子元素剪辑到它,这意味着它们不能在滚动小部件之外绘制。

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

    以上就是为什么我在您最初的问题中询问您是否只希望滚动这个小部件,而旁边没有任何东西。因为如果滚动小部件覆盖了整个 wibox,那么这类问题就会消失。

    不,据我所知/看到,没有办法阻止未绘制的小部件接收按钮点击。

    【讨论】:

    • 是的,这正是我昨晚所做的,我可怕地尝试剪掉孩子们以及你可以与他们互动的部分。但就像你回应的那样,我只剪掉了画的东西,而不是你可以与孩子们互动的部分,如果他们是在那个偏移量处绘制的。真的没有别的办法了吗? (由于空间不足,我将在下一条评论中继续)
    • 我记得有些东西(比如客户端)有一个shape_input 属性或类似的东西。 wibox 也是如此。我查看了源代码,发现两者都做了这样的事情:local img = cairo.ImageSurface(cairo.Format.A1, geo.width, geo.height); local cr = cairo.Context(img) 然后是其他一些 cairo 魔法,然后对于我尝试过的所有事情,你可以做一些事情,比如在某物上设置圆角,然后不能与该小部件交互,否则将绘制角的部分。在这种情况下我也不能这样做吗?
    • 嗯...您的:layout 方法的结果变成了一棵树。这棵树描述了哪个小部件有哪些其他作为子级以及它们的大小。当某些输入事件发生时,此树用于确定哪个小部件在哪里被击中。这棵树也用于绘制小部件。我们可以影响绘图(就像这里所做的那样),但是输入事件直接使用树(具体来说:button_signalswibox.drawable.find_widgets 中的wibox.drawable 用于输入事件)。因此,形状可用于完全“删除”wibox 的一部分,但不能用于单个小部件。对不起。
    • 或者,你可以做一些类似于 awesome 中的滚动小部件当前所做的事情:在不使用 :layout 的情况下绘制孩子,这样 awesome 的其余部分不知道它们并且不能转发输入事件.接下来(这是当前代码不做的事情),我们可以自己将输入事件转发给子小部件,而无需使用 AwesomeWM 中已经存在的代码。但是,对于当前的滚动小部件(对于 $REASONS)来说,这实际上是不可能的,因此很复杂......
    • 啊我明白了,所以您只需使用:draw 方法而不是:layout 方法绘制小部件,然后您会单独处理事件处理?那是对的吗?如果是这样,那真的可以让我完成我正在寻找的东西吗?如果这是真的,你能粗略地指导我做我必须做的事情并学会做这项工作吗?即使是提示,我也会非常感激,因为我真的不知道下一步该做什么来完成这项工作。
    猜你喜欢
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    相关资源
    最近更新 更多