awesome
awesome copied to clipboard
Key release signals not emitted for modifier keys
Signals for the modifier keys (Alt_L, Ctrl_L, Super_L, etc.) are emitted only on key press events, not on key release events.
I added
awful.key({ modkey }, "Alt_R", nil)
to globalkeys
, then added the lines
for i,v in pairs(globalkeys) do
if v.key == "Alt_R" then
v:connect_signal("press", function(...)
print("press signal received")
end)
v:connect_signal("release", function(...)
print("release signal received")
end)
end
end
Running awesome inside Xephyr, I see the press signals but not the releases.
Other keys such as alphanumerics work as expected.
Running awesome inside Zephyr, I see the press signals but not the releases.
It is not specific to Xephyr, is it?
No, I can run xev
within Xephyr and see all the correct key presses.
I've meant if it also happens when running awesome directly. And I assume that you mean Xephyr instead of "Zephyr"?
I just tested and it happens when running awesome directly as well.
You're right about Xephyr, I fixed it.
Can confirm. I'm running awesome directly, key release events don't get called. This is the key binding I'm creating in rc.lua
inside globalkeys
:
awful.key({ "Shift" }, "Control_L",
function() naughty.notify{ title="ctrl+shift down" } end,
function() naughty.notify{ title="ctrl+shift up"} end
)
Like @keidax, I see the notification for "ctrl+shift down", but not up, regardless of the order of releasing the keys.
same thing for mouse buttons.
tested with:
awful.button({ modkey }, 1 , print("press") , print("release"))
See also this report in the old bugtracker, which has some additional information from when I've tried to debug this: https://awesome.naquadah.org/bugs/index.php?do=details&task_id=1129
The problem appears to be that for the "release" event the released modifier is probably in ev->state
, but not in k->modifiers
.
https://github.com/awesomeWM/awesome/blob/68b0fa243ff828abd0a766a18c87755730676f9d/event.c#L87-L95
Add the following to your globalkeys and then think about the results:
awful.key({ }, "Alt_L", function() print("alt pressed") end, function() print("does not happen") end),
awful.key({ "Mod1" }, "Alt_L", function() print("does not happen") end, function() print("alt released") end),
Result:
alt pressed
alt released
(Spoiler: The above asks for "Alt_L" without any modifiers and then for "Alt_L" together with modifier 1 and pressing Alt_L activates modifier 1. So the problem is that Alt_L itself is a modifier and thus the release event no longer matches the keybinding asking for no modifiers at all. No idea how to sanely fix this, but I guess we'd have to ask libxkbcommon "Alt_L was released, which modifier does this deactivate which I should thus ignore?".)
(However, it's not really that easy, because, for example, there is a left and a right shift key. When you press both, the press and release for the second one should have the Shift modifier activated and only the very first press and the very last one should ignore the modifier. And handling this correctly becomes tricky.)
Oh and the issue about mouse buttons is unrelated to this one. So this has nothing to do with FS#1129.
Sorry for only noticing this now. At least you know have a work-around for this.
I guess we'd have to ask libxkbcommon "Alt_L was released, which modifier does this deactivate which I should thus ignore?"
That does not seem to be too simple. I have found XGetModifierMapping
which could be used to get the modifier that a key belongs to. It is used by xmodmap
(from x11-xserver-utils
).
We have xutil_key_mask_fromstr
already, and could add xutil_mod_mask_fromkey
in the same vain.
My first attempt has been the following, but it will match too many (if there is the same hotkey with multiple modifier combinations):
&& (k->modifiers == XCB_BUTTON_MASK_ANY
|| (XCB_EVENT_RESPONSE_TYPE(ev) == XCB_KEY_PRESS
&& k->modifiers == ev->state)
|| (XCB_EVENT_RESPONSE_TYPE(ev) == XCB_KEY_RELEASE
&& (ev->state & k->modifiers) == globalconf.modifier_mask)));
I wonder if the same method from event_handle_button
could be applied here
(https://github.com/awesomeWM/awesome/blob/68b0fa243ff828abd0a766a18c87755730676f9d/event.c#L201-212)?
/* ev->state contains the state before the event. Compute the state
* after the event for the mousegrabber.
*/
uint16_t state = ev->state, change = 1 << (ev->detail - 1 + 8);
if (XCB_EVENT_RESPONSE_TYPE(ev) == XCB_BUTTON_PRESS)
state |= change;
else
state &= ~change;
if(event_handle_mousegrabber(ev->root_x, ev->root_y, state))
return;
Another idea might be to handle it via XCB_XKB_STATE_NOTIFY
in event_handle_xkb_notify
and keep track of the modifier mask in globalconf
somehow?!
Is the discussion around this issue still alive? Stumbled across this, while trying to get the release event for Super_L.
Also is there with the current open issue any known workaround to get a function triggered on the release of a modifier key (especially one that is also used in several other keybindings)? I tried registering a keyhandler
in the pressed callback, but as long as this is running no other registered shortcut for this modifier key works. Is there a possibility to pass a key event from my keyhandler to the "global" one of awesome, so that I could use this as a workaround? Using awful.key.execute
from within the keygrabber (or this special key combinations with Super in it) doesn't seem to execute any of the other registered listeners.
Okay I found a workaround for my case (and perhaps it helps someone else too):
awful.key({}, 'Super_L', function()
-- press event will be called
end)
awful.key({'Mod4'}, 'Super_L', function() end, function()
-- release event will be triggered with the key itself as a modifier
end)
And I stand corrected again. The above basically works and other global hotkeys containing Super_L will still be triggered, but key bindings on clients containing that meta key won't be triggered at all anymore (which might be some kind of new bug?)
Is there any news? I've faced the same issue on awesome v4.3 and Shift+Control_L/Control+Shift_L hotkeys.
Since I am running into that right now again, can also confirm this is still an issue on v4.3 and also want to elaborate my comment from 3 years ago.
It seems as soon as you have a root key listener on a meta key: (awful.key({}, 'Super_L', function() ... end)
) at that point no further keys registered directly on clients (e.g. via awful rules) will be called anymore (the workaround function above is irrelevant for that behavior). At the same time all other root
key bindings that contain Mod4
as a modifier will still work perfectly.
This behavior is slightly annoying, since it prevents to build any global shortcut on the primary modifier key alone e.g. I wanted to trigger something when double clicking the Super key, but that breaks all client key bindings.
I am curious if anyone has found a recent workaround for that?
I've just run into this same issue. I've come from i3 where I had the toolbar hide until I was holding the modkey (Super_L) as I like a clean minimal display. I had hoped that a WM with a full language based config would give me complete control. I guess I should have known better, lol.
@RJSzynal you mean solution provided 5 years ago stopped working? https://github.com/awesomeWM/awesome/issues/169#issuecomment-129749339 https://github.com/awesomeWM/awesome/issues/169#issuecomment-294317264
@actionless It sounds like that solution never worked in the first place. https://github.com/awesomeWM/awesome/issues/169#issuecomment-294752983 https://github.com/awesomeWM/awesome/issues/169#issuecomment-622482864
It seems as soon as you have a root key listener on a meta key: (awful.key({}, 'Super_L', function() ... end)) at that point no further keys registered directly on clients (e.g. via awful rules) will be called anymore (the workaround function above is irrelevant for that behavior)
then it's a different issue from the OP
To clarify, I'm saying the solution to the original issue, provided before, creates this second issue and is therefore not viable. So the original issue stands unresolved.
the OP is about binding release
handlers, your issue is about inability to bind press
event handler if modifier is already engaged
My problem is that it does not register release event handlers! Literally the same as the first line of the first post.
Signals for the modifier keys (Alt_L, Ctrl_L, Super_L, etc.) are emitted only on key press events, not on key release events.
I tried the "solution" you referenced but it only creates a second issue whereby the press
event is not handled for clients and is therefore not a solution
This leaves my issue back to being the same as the OP.
Hi I'm facing the same issue, but as tried follow the example @psychon in https://github.com/awesomeWM/awesome/issues/169#issuecomment-129749339 and I came to this piece of code:
local awful = require("awful")
local gears = require("gears")
local debug = gears.debug.dump_return
local function notify(options)
require("naughty").notify(options)
end
local function dump(variable)
return gears.debug.dump_return(variable)
end
local key_press = {
last_press = nil,
current_press = os.time()
}
local globalkeys = gears.table.join(
awful.key({ }, "Super_R",function()
local now=os.time()
local last_press=key_press.last_press
notify({
title="last_press " .. last_press,
text="current " .. now,
timeout=5
})
--- here I define a timeout between super key and others bindings
-- to act like windows
if now - last_press > 2 and last_press ~= nil then
notify({title="Super_R Finished"})
end
end),
awful.key({ "Mod4" }, "Super_R", _ , function()
notify({title="Super_R released"});
end),
awful.key({ "Mod4" }, "p", function()
notify({title="Super_R + p pressed"})
end)
)
-- I save the last timestamp the key was pressed
key.connect_signal("press",function()
local now = os.time()
local last_press
local msg
if key_press.last_press == nil then
last_press=now
key_press.last_press = last_press
else
last_press=key_press.last_press
key_press.last_press = now
end
notify({
title="last_press " .. last_press,
text="current " .. now,
timeout=5
})
end)
root.keys(globalkeys)
this way I can use my
Sorry for the english. :(
Edit:
Hi I made another tests and using the method suggested by @psychon some keybinds stopping working like modkey + o.
I am running into a similar issue but mine is having an effect on the XF86AudioRaiseVolume and XF86AudioLowerVolume key events. I run xev and it is picking up the key strokes. xmodmap shows all of the XF86Audio* keys, too. The setup I've been using is:
awful.key({}, "XF86AudioRaiseVolume", get_current_volume(volumesliderwidget), {description="Raise volume", group="control"})
Putting a naughty.notify() function call in the callback doesn't even run so the event isn't being registered. Am I missing something? I am running:
awesome v4.3 (Too long) • Compiled against Lua 5.3.3 (running with Lua 5.3) • D-Bus support: ✔ • execinfo support: ✔ • xcb-randr version: 1.6 • LGI version: 0.9.2
@willholl4nd This is unrelated to the issue you posted in.
XF86*
keys are not modifier keys, and in the snippet you posted, you're not using the key release event.
Either way, it looks like you're not actually providing a callback function, unless get_current_volume
returns a function.
These two snippets are equivalent:
awful.key({}, "XF86AudioRaiseVolume", naughty.notify({ text = "XF86AudioRaiseVolume" }))
naughty.notify({ text = "XF86AudioRaiseVolume" })
awful.key({}, "XF86AudioRaiseVolume", nil)
The notification is created only one time, when the key definition is created. You need to provide a function that may be called at a later time (when the key is pressed).
awful.key({}, "XF86AudioRaiseVolume", function()
naughty.notify({ text = "XF86AudioRaiseVolume" })
end)
And I stand corrected again. The above basically works and other global hotkeys containing Super_L will still be triggered, but key bindings on clients containing that meta key won't be triggered at all anymore (which might be some kind of new bug?)
I ran into this today, too. Seem to still be a bug. Is there anything we can do about it?
https://github.com/awesomeWM/awesome/issues/169#issuecomment-294317264
This does not work for me, but if you replace Mod4
with Any
, it does seem to work for me
awful.key({ 'Any' }, 'Super_L', nil, function()
-- release event will be triggered
end)