【问题标题】:awesome-wm wibox not reacting to mouse signals when input_passthrough is true当 input_passthrough 为真时,awesome-wm wibox 对鼠标信号没有反应
【发布时间】:2019-07-13 05:06:36
【问题描述】:

基本上,我想要做的是有一个侧边栏,当我将鼠标移动到屏幕的左边缘时它会显示出来,当我将鼠标移得太远时侧边栏会消失侧边栏。

所以我做了三个小部件:

  • 侧面宽度为 1 像素,并且在检测到鼠标进入时显示侧边栏

  • 实际的侧边栏

  • 还有一个比侧边栏更宽的小部件,完全透明,将input_passthrough 设置为true,它的唯一目的是寻找“mouse::leave”信号以及鼠标何时离开,它会让自己和侧边栏消失。

我已经完成了大部分工作,但有一个我无法解决的特殊错误:

wibox 函数将字段表作为参数。如果您查看我提供的代码,您会注意到sidebar_visible_limitinput_passthrough 字段没有放在表的主体中,而是在创建小部件之后提供的。

这样做的问题是当鼠标离开时它根本不会关闭侧边栏或自身。它没有检测到鼠标离开。

但是如果将input_passthrough = true 放在提供给wibox 函数的表中,如下所示:

    bar.sidebar_visible_limit = wibox({ 
    x = 0, 
    y = 0, 
    ontop = false, 
    visible = false,
    width = bar.sidebar.width + dpi(100),
    height = bar.sidebar.height,
    bg = '#000000',
    opacity = 0.3, -- when it's all done this will be '0'
    input_passthrough = true
    })

然后一切正常,除了现在它不允许输入通过。

我非常感谢您解释为什么会发生这种情况。

这是代码:

awful = require("awful")
local wibox = require("wibox")
local naughty = require("naughty")
local gears = require("gears")
local beautiful = require("beautiful")
xresources = require("beautiful.xresources")
dpi = xresources.apply_dpi

bar = {}

-- make the sidebar
bar.sidebar = wibox({ 
    x = 0, 
    y = 0,  
    ontop = false, 
    visible = false,
    width = beautiful.sidebar_width or dpi(450),
    bg = beautiful.sidebar_bg or "#2f2e3a",
    type = "dock",
    height = beautiful.sidebar_height or awful.screen.focused().geometry.height,
})

-- Hide sidebar when mouse leaves too much from the sidebar
-- It's incorporated along in the same table with the sidebar so the users
-- can implement these however they want, e.g. in the 'keys.lua' module

bar.sidebar_visible_limit = wibox({ 
    x = 0, 
    y = 0, 
    ontop = false, 
    visible = false,
    width = bar.sidebar.width + dpi(100),
    height = bar.sidebar.height,
    bg = '#000000',
    opacity = 0.3, --when it's all done this will be '0'
    })
bar.sidebar_visible_limit.input_passthrough = true

-- Show sidebar when mouse touches edge
local sidebar_displayer = wibox({ 
    x = 0,
    y = 0, 
    height = bar.sidebar.height,
    ontop = true,
    width = 1,
    visible = true, 
    opacity = 0,
    input_passthrough = true
})

function toggle_bar()

    -- they have to be in this order, so the sidebar will show first,
    -- and then the wibox that will close the sidebar when the mouse leaves
    -- second. If you do it the other way around, then if you go with the
    -- mouse on the sidebar-closing wibox , then if you try to go back 
    -- to the sidebar, it will close it because it's 'left' the widget.
    -- That's why you have the sidebar-closing wibox on top and allow
    -- input_passthrough for the sidebar-closing wibox

    bar.sidebar.visible = not bar.sidebar.visible
    bar.sidebar.ontop = not bar.sidebar.ontop

    bar.sidebar_visible_limit.visible = not bar.sidebar_visible_limit.visible
    bar.sidebar_visible_limit.ontop = not bar.sidebar_visible_limit.ontop

end

bar.sidebar_visible_limit:connect_signal( "mouse::leave", toggle_bar )
sidebar_displayer:connect_signal( "mouse::enter", toggle_bar )

【问题讨论】:

    标签: awesome-wm


    【解决方案1】:

    您可以使用mousegrabber 来检测鼠标的位置:

    bar.sidebar.ontop = true
    
    function show_sidebar()
        bar.sidebar.visible = true
        mousegrabber.run(function(mouse)
            if mouse.x > bar.sidebar.width + dpi(100) then
                hide_sidebar()
                return false
            end
            return true
        end)
    end
    
    function hide_sidebar()
        bar.sidebar.visible = false
    end
    

    或者,您也可以使用相同的mousegrabber 来决定何时显示侧边栏:

    bar.sidebar.ontop = true
    
    function show_sidebar()
        bar.sidebar.visible = true
    end
    
    function hide_sidebar()
        bar.sidebar.visible = false
    end
    
    mousegrabber.run(function(mouse)
        if bar.sidebar.visible then
            if mouse.x > bar.sidebar.width + dpi(100) then
                hide_sidebar()
            end
        else
            if mouse.x == 1 then
                show_sidebar()
            end
        end
        return true
    end)
    

    我认为这比在整个屏幕上创建一个不可见的 wibox 更好。

    【讨论】:

      【解决方案2】:

      我将非常感谢您解释为什么会发生这种情况。

      我认为 X11 服务器报告鼠标进入/退出相对于窗口的输入区域。使用input_passthrough,输入区域变为空。这意味着 X11 服务器现在将报告鼠标指针位于 wibox 下方的窗口内,而不是 wibox 本身内。

      但是如果将 input_passthrough = true 放在提供给 wibox 函数的表中,那么一切正常,除了现在它不允许输入通过。

      换句话说:在这种情况下,input_passthrough 属性未设置。似乎您找到了无法以这种方式设置的属性之一。 ;-)


      因为我猜你也想知道如何做你想做的事情:如果你正在运行一个合成管理器(xcompmgrcompton,...),你可以用完全透明的背景。这样,X11 服务器将“认为”窗口存在并报告与它相关的输入事件,但 wibox 实际上不会在屏幕上可见。

      (如果您没有合成管理器:制作一个以适当偏移量显示壁纸的小部件。可以通过阅读/usr/share/awesome/lib/wibox/drawable.lua(以@987654326 开头的部分)找到有关如何执行此操作的提示@ 并且与墙纸有关。如有必要,请随时询问更多详细信息。)

      【讨论】:

      • 啊,我明白了,所以当您将input_passthrough 设置为true 时,wibox 至少无法捕捉到某些鼠标信号,例如mouse::leave。我最终做出了妥协,并决定让侧边栏在鼠标离开时消失。不过谢谢你的帮助!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-25
      相关资源
      最近更新 更多