当 input_passthrough 为真时,awesome-wm wibox 不会对鼠标信号做出反应
awesome-wm wibox not reacting to mouse signals when input_passthrough is true
基本上,我想要做的是有一个侧边栏,当我将鼠标移到屏幕的左边缘时它会显示,当我将鼠标移得太远时它会消失来自侧边栏。
所以我制作了三个小部件:
边上一个像素宽,当它检测到鼠标进入时,显示边栏
实际侧边栏
和一个比侧边栏宽的小部件,完全透明,input_passthrough
设置为 true
,其唯一目的是寻找 "mouse::leave" 信号,当鼠标离开时,它会让自己和侧边栏消失。
我已经完成了大部分工作,但有一个我无法解决的特殊错误:
wibox
函数将 table 个字段作为参数。如果您查看我提供的代码,您会注意到 sidebar_visible_limit
的 input_passthrough
字段并未放入 table 的正文中,而是在之后提供,就在创建小部件。
问题是它不会在鼠标离开时关闭侧边栏或自身。它没有检测到鼠标离开。
但是如果把 input_passthrough = true
放在提供给 wibox 函数的 table 中,像这样:
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 )
I would greatly appreciate an explanation as to why this happens.
我认为 X11 服务器报告鼠标 enter/exit 相对于 window 的输入区域。使用 input_passthrough
,输入区域变为空。这意味着 X11 服务器现在将报告鼠标指针位于您的 wibox 下方的 window 内,而不是 wibox 本身内。
BUT if put the input_passthrough = true in the table provided to the wibox function then everything works fine, EXCEPT that now it doesn't allow input to pass through.
换句话说:在这种情况下,input_passthrough
属性 未设置。似乎您发现了无法以这种方式设置的属性之一。 ;-)
因为我猜你也想知道如何做你想做的事情:如果你是 运行 合成经理(xcompmgr
、compton
、. ..),你可以制作一个背景完全透明的wibox。这样,X11 服务器将 "think" window 在那里并报告与其相关的输入事件,但 wibox 实际上不会在屏幕上可见。
(如果您没有合成管理器:制作一个显示具有适当偏移量的墙纸的小部件。可以通过阅读 /usr/share/awesome/lib/wibox/drawable.lua
找到有关如何执行此操作的提示,以 if not capi.awesome.composite_manager_running then
开头,这对墙纸有所帮助。如有必要,请随时询问更多详细信息。)
您可以使用 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 更好。
基本上,我想要做的是有一个侧边栏,当我将鼠标移到屏幕的左边缘时它会显示,当我将鼠标移得太远时它会消失来自侧边栏。
所以我制作了三个小部件:
边上一个像素宽,当它检测到鼠标进入时,显示边栏
实际侧边栏
和一个比侧边栏宽的小部件,完全透明,
input_passthrough
设置为true
,其唯一目的是寻找 "mouse::leave" 信号,当鼠标离开时,它会让自己和侧边栏消失。
我已经完成了大部分工作,但有一个我无法解决的特殊错误:
wibox
函数将 table 个字段作为参数。如果您查看我提供的代码,您会注意到 sidebar_visible_limit
的 input_passthrough
字段并未放入 table 的正文中,而是在之后提供,就在创建小部件。
问题是它不会在鼠标离开时关闭侧边栏或自身。它没有检测到鼠标离开。
但是如果把 input_passthrough = true
放在提供给 wibox 函数的 table 中,像这样:
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 )
I would greatly appreciate an explanation as to why this happens.
我认为 X11 服务器报告鼠标 enter/exit 相对于 window 的输入区域。使用 input_passthrough
,输入区域变为空。这意味着 X11 服务器现在将报告鼠标指针位于您的 wibox 下方的 window 内,而不是 wibox 本身内。
BUT if put the input_passthrough = true in the table provided to the wibox function then everything works fine, EXCEPT that now it doesn't allow input to pass through.
换句话说:在这种情况下,input_passthrough
属性 未设置。似乎您发现了无法以这种方式设置的属性之一。 ;-)
因为我猜你也想知道如何做你想做的事情:如果你是 运行 合成经理(xcompmgr
、compton
、. ..),你可以制作一个背景完全透明的wibox。这样,X11 服务器将 "think" window 在那里并报告与其相关的输入事件,但 wibox 实际上不会在屏幕上可见。
(如果您没有合成管理器:制作一个显示具有适当偏移量的墙纸的小部件。可以通过阅读 /usr/share/awesome/lib/wibox/drawable.lua
找到有关如何执行此操作的提示,以 if not capi.awesome.composite_manager_running then
开头,这对墙纸有所帮助。如有必要,请随时询问更多详细信息。)
您可以使用 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 更好。