Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed PR: Super + Hyper #118

Open
bjohas opened this issue Jan 7, 2021 · 21 comments
Open

Proposed PR: Super + Hyper #118

bjohas opened this issue Jan 7, 2021 · 21 comments

Comments

@bjohas
Copy link

bjohas commented Jan 7, 2021

Hi @mooz ,

xkeysnail doesn't handle Super/Hyper at the moment. Would you welcome a PR that added these two keys as modifiers?

(CC @pat-flew, #88)

@rbreaves
Copy link
Contributor

How is Super not supported I swap Ctrl & Super just fine?

@bjohas
Copy link
Author

bjohas commented Feb 2, 2021

Hi @rbreaves - could you given an example? Super/Hyper aren't listed in the key definitions for xkeysnail, so how do you use them? Apologies if I misunderstanding something! Many thanks!

@rbreaves
Copy link
Contributor

rbreaves commented Feb 2, 2021

@pat-flew
Copy link

pat-flew commented Feb 2, 2021

@bjohas - Super is defined in Keys.py, mapped to Meta as you previously noted. Treating super and meta interchangeably is probably one of several conventions arising out of the fact there are no standard super / meta keys on keyboards, and the Win key is often treated as both. I assume you're looking at the option treating them separately?

Regarding Hyper, for my own purposes, I added a hardcoded modifier that used katakana as a kludgey convenience. After mapping the same in xmodmap, I was able to refer to this 'hyper' both in xkeysnail's config.py and my WM (Gnome) shortcuts. This allows me to use caps as a new modifier. The important part is that whatever key is used is treated as a modifier; calling it 'super' (rather than katakana, in my case) is only a convenience

I noticed that there is a 'fake' hyper code defined in evdev although in this moment I'm not sure how to take advantage of it.

@bjohas
Copy link
Author

bjohas commented May 31, 2021

@pat-flew I've come round to exploring this again. I do like the Hyper modification, but I'm concerned that it's baked into the code, i.e., one would have to recompile xkeysnail over and over. Is there a way the hyper modification could be introduced into the code in a user-configurable way? Many thanks!

@097115
Copy link

097115 commented Apr 23, 2022

Okay, I'm still failing to remap LAlt <-> LSuper...

Let's say I have the following in my config:

terminals = ["gnome-terminal","xterm","kitty"]
define_keymap(lambda wm_class: wm_class.casefold() not in terminals,{
    K("LSuper-C") : K("LC-C"),
    K("LSuper-V") : K("LC-V"),
    Key.LEFT_ALT: Key.LEFT_META,
    Key.LEFT_META: Key.LEFT_ALT,
})

And while the first two mappings work just fine, the last two remaps (Left Alt to Super and vice versa) don't work at all.

@rbreaves, @pat-flew any hint may be?

@rbreaves
Copy link
Contributor

Okay, I'm still failing to remap LAlt <-> LSuper...

Let's say I have the following in my config:

terminals = ["gnome-terminal","xterm","kitty"]
define_keymap(lambda wm_class: wm_class.casefold() not in terminals,{
    K("LSuper-C") : K("LC-C"),
    K("LSuper-V") : K("LC-V"),
    Key.LEFT_ALT: Key.LEFT_META,
    Key.LEFT_META: Key.LEFT_ALT,
})

And while the first two mappings work just fine, the last two remaps (Left Alt to Super and vice versa) don't work at all.

@rbreaves, @pat-flew any hint may be?

You're mixing remapping hotkey combos and remapping just modifier keys, you can't do that like that.

Modifiers belong in a different function - conditional modmap.

# [Global modemap] Change modifier keys as in xmodmap
define_conditional_modmap(lambda wm_class: wm_class.casefold() not in terminals,{
    Key.LEFT_ALT: Key.LEFT_META,
    Key.LEFT_META: Key.LEFT_ALT,
})

@097115
Copy link

097115 commented Apr 23, 2022

@rbreaves

Thanks, Ben!

@bjohas
Copy link
Author

bjohas commented Apr 24, 2022

Hello @rbreaves and @pat-flew - I'd like to come back to this. Can you help me understand the issue of hardcoding the keys? I can see that if I change key.py, then I can introduce a mapping there. However, my keyboard doesn't have many of the keys listed in key.py, so is it not possible to introduce a dummy for Hyper? xkb also has things like ISO_SHIFT_3/5 (though key.py has an ISO, which might be ISO_SHIFT_3).

Is it that xkeysnail operates at a lower level than xkb? For example, in one of my xkb files, I have

partial alphanumeric_keys modifier_keys
xkb_symbols "caps_and_rctl_are_hyper" {
    replace key <CAPS> { [ Hyper_L, Hyper_L ] };
    replace key <RCTL> { [ Hyper_R, Hyper_R ] };
    modifier_map Mod3    { <CAPS>, <RCTL> };
};

which leads to emitting Hyper_L/Hyper_R, which I can check with xev. E.g. autokey then allows me to bind actions to this.

The example code has

# [Global modemap] Change modifier keys as in xmodmap
define_modmap({
    Key.CAPSLOCK: Key.LEFT_CTRL
})

I suppose that are all keys that are defined in key.py,

So is maybe the real issue that there's no provision for Hyper (I'm not quite sure what I mean by that 😀)?
I suppose I would want something like this:

# [Global modemap] Change modifier keys as in xmodmap
define_modmap({
    Key.CAPSLOCK: Key.LEFT_HYPER
})

@bjohas
Copy link
Author

bjohas commented Apr 24, 2022

To add to this. So seems that xkeysnail processes raw key presses, i.e., before the xkb keyboard map is applied. That's different from autokey, which applies to key presses after the xkb keyboard map has been applied. It's not clear to me what is a better option. I suppose it means with xkeysnail you cannot easily combine, e.g., gnome keyboard changes and xkeysnail?

Anyway - looking at xkb, the key number for Hyper is not consistent:

evdev:298:	<HYPR> =   207;
xfree86:363:    <HYPR> =   128; // <U80>

I've added Hyper here: https://github.com/bjohas/xkeysnail/blob/master/xkeysnail/key.py, line 271, to 249/250 (left/right hyper). I then do a config like this:

import re
from xkeysnail.transform import *

# define timeout for multipurpose_modmap
define_timeout(1)

# [Conditional modmap] Change modifier keys in certain applications
define_conditional_modmap(re.compile(r'konsole'), {
    Key.CAPSLOCK: Key.LEFT_CTRL,
    Key.LEFT_ALT: Key.LEFT_HYPER,
    Key.LEFT_CTRL: Key.LEFT_META,
    Key.LEFT_META: Key.LEFT_ALT
})

I can run xkeysnail like that without errors, and [as per output on screen] it dutifully emits Hyper combinations. However, when I go into the Konsole prefs, combinations with Hyper are not recognised. Any idea why?

@rbreaves
Copy link
Contributor

I don't really have an issue with you wanting to hardcode anything & adding in Hyper. I just have no real use for an additional Hyper key I don't guess, so Meta being the Super/Win key for me fully satisfies what I personally need or want. I have no real idea what I would use Hyper for.

I only commented on this thread again because there was a misunderstanding on where to remap some modifiers by another user.

@bjohas
Copy link
Author

bjohas commented Apr 25, 2022

Hi @rbreaves - thank you. Would you want to integrate Hyper into your fork? I guess not, but just double-checking. I'd obv love to have it and would be happy to put out a bounty for it or contract you.

I do use Hyper for my OS X-type layout, which is a different approach to using LCTRL and RCTRL (as kinto does). Hyper means that there's a spare mod key (obviously), which means that all Desktop apps have ctrl/alt/super as expected, while Hyper plays the OS X-CTRL role (on the Desktop, i.e. beginning / end of line). Similarly, Ubuntu-ctrl and alt/super work in Terminal, with Hyper (swapped with ctrl) will mean everything works in Terminal. It's just a different strategy from Kinto LCTRL/RCTRL. But that's why I'd like it. :)

@rbreaves
Copy link
Contributor

Maybe some time next week or so, I will be busy all this week though.

@bjohas
Copy link
Author

bjohas commented Apr 26, 2022

That would be amazing, thank you!!

@joshgoebel
Copy link

which means that all Desktop apps have ctrl/alt/super as expected, while Hyper plays the OS X-CTRL role (on the Desktop,

Help me understand here... I understand how we can add random keys on the OUTPUT... but what does your mapping look like on the input side? How does one trigger this extra Hyper key if it's not using alt, ctrl, super or meta?

@bjohas
Copy link
Author

bjohas commented May 29, 2022

Hi @joshgoebel - I use capslock, as I rarely ever need capslock. However, I think it can be any key you like (assuming you don't need that key). Is that what you meant?

@joshgoebel
Copy link

joshgoebel commented Jun 2, 2022

https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h

We're using the LInux source for key names as canonical...

evdev:298:	<HYPR> =   207;
xfree86:363:    <HYPR> =   128; // <U80>

According to Linux 207 is PLAY and 128 is STOP. And there is no hyper...

@joshgoebel
Copy link

Technically long-term one should be able to use any keys as modifiers (that's the promise of modmap) but right now that's not possible because of how we treat modifiers as "special" keys... if that ever changed I think you could just use whatever keys you wanted for "Hyper", you wouldn't need to create new non-existing keys.

@joshgoebel
Copy link

However, when I go into the Konsole prefs, combinations with Hyper are not recognised. Any idea why?

Perhaps because you've mapped it to keys that don't actually exist on any keyboards anywhere? 😺 Try using some of the high F keys instead, F23, F24 and see if you have better luck... If that works that might be a direction to go here instead.

@joshgoebel
Copy link

joshgoebel commented Jun 7, 2022

Ok, here is what I did to get it working on my fork:

In my xkeysnail/keyszer config:

# create a new modifier, and use the keyboard key F24
Modifier("L_HYPER", aliases = ["LHyper"], key = Key.F24)
LHyper = Key.F24

LHyper variable is just so I can refer to the key later in modmaps without calling it F24, though sadly this won't work in actual K() macros.

The Modifier line only works on my fork, but you could get by without it but then you might run into the fact that xkeysnail treats regular keys differently than modifiers in many ways. (combos) If all you want to do is pass it thru to the OS without binding it to hotkeys it might work just fine with 0.4.0 though.


In my Awesome config:

# update my Awesome WM to use mod3 (instead of mod4)
modkey = "Mod3"

Modkey is the variable I use in all my keybindings.


In my .Xmodmap

clear mod3
clear mod4
add mod4 = Super_L Super_R
!keycode 194 = Hyper_L Hyper_L
! this is the keycode that xev seems to think kernel 194 is
keycode 202 = Hyper_L Hyper_L
add mod3 = Hyper_L

I had to redefine mod4 because Hyper was already there for some reason. Then I add Hyper_L to mod3.

The part that confuses me most is F24 (the key I'm reusing) is 194 to the kernel BUT xmodmap seems to wayt 202 (confirmed by using xev... There seems to be this offset in what both are calling the "keycode" that I don't understand.

After loading the node Xmodmap now my Hyper key works for all my Awesome WM shortcuts.

I added a note on my wiki: https://github.com/joshgoebel/xkeysnail/wiki/Hyper

@joshgoebel
Copy link

joshgoebel commented Jun 7, 2022

I suppose perhaps now that I'm thinking about it I could have just assigned capslock to L_Hyper directly, LOL. I thikn this is slightly more flexible though because techncially now I could use it in a conditional modmap and have my cake and eat it to - caps lock is both a modifier AND a caps lock key - but I never use caps lock so I don't mind losing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants