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

Shortcut Creation (xkeysnail) #115

Open
rbreaves opened this issue Apr 15, 2020 · 24 comments
Open

Shortcut Creation (xkeysnail) #115

rbreaves opened this issue Apr 15, 2020 · 24 comments
Assignees
Labels
first-timers-only For people who want to contribute.

Comments

@rbreaves
Copy link
Owner

rbreaves commented Apr 15, 2020

So you want to contribute? That's great!

Kinto now officially uses xkeysnail as its preferred method of key remapping.

Clone master or fork master

git clone https://github.com/rbreaves/kinto.git

GUI Keys

Value Description Mac/Kinto Equivalent
C,Ctrl Control Cmd
M,Alt Alt/Option Alt/Option
Super Win/Super Ctrl

Terminal Keys

Value Description Mac/Kinto Equivalent
RC,RCtrl Right Control on Left & Right Alt/Cmd key Cmd
M,Alt Alt/Option Alt/Option
Ctrl Ctrl Ctrl

You can define new keymaps for your specific app via this method. You also do not have to cancel out the original keybinding if you do not need or want to, but you can do so with "pass_through_key".

Defining Keymaps Per App

# Keybindings for Sublime Text
define_keymap(re.compile("Sublime_text"),{
    K("C-h"): pass_through_key,          # cancel replace
    K("Ctrl-Alt-f"): K("Ctrl-h"),        # replace
    K("C-M-v"): [K("C-k"), K("C-v")],    # paste_from_history
}

In the above example I am also showing that you can define a single shortcut to enact multiple shortcut keys if needed by defining an array of shortcuts to trigger.

You can also make your changes in the ~/.config/kinto/kinto.py location and then restart Kinto. The system also has Edit Config built in now.

More information can be seen on the readme page of xkeysnail.

Note on submitting keymaps for consideration

If it is a basic system level keymap then please consult ticket #44 and the excel doc to ensure that you are aware of all of the possibly differing hotkeys between DE's before submission and try to account for them in the setup.py and kinto.py file.

If it is more DE, application or language specific and then considering commenting it out in the kinto.py config file. This will allow me, or you, to create it as an installable option in xkeysnail_service.sh.

An example

# K('Shift-KEY_3'):K('KEY_EURO'), # UK KBD

XKB Shortcut Creation

The older xkb shortcut method info can be read about in ticket #125.

@rbreaves rbreaves added the first-timers-only For people who want to contribute. label Apr 15, 2020
@rbreaves rbreaves self-assigned this Apr 15, 2020
@rbreaves
Copy link
Owner Author

rbreaves commented Apr 24, 2020

Why did Kinto change from xkb and kintox11?
Just to make a note of it here as well, the reasons for this are the following.

  • udev implementation via xkeysnail simplifies adding shortcuts
  • udev is more stable than xkb. Some xkb configs can cause segfaults/reboots.
  • udev works with more applications than xkb.
  • udev has re-use under wayland, although the xkeysnail app that maps udev needs x11.
  • udev with xkeysnail allows for better Alt-Tab/Ctrl-Tab functionality under KDE than xkb

Generally Kinto with xkb is very stable and has high compatibility with most apps, but there are exceptions. If your distro or configuration is an exception it could lead to a reboot and systemd should disable the problematic service for you to troubleshoot and/or report the issue.

Regardless this is why Kinto is moving to udev and xkeysnail. Also xkeysnail greatly simplifies the process of adding new shortcut keys to specific apps. Users will no longer need to gain an understanding of xkb or its intricacies which are looked at from the perspective of the keyboard instead of the user. Xkeysnail is much more focused on the user experience, the app and the shortcut keys than forcing you to think about all of the possible permutations of a single key and all of its modifier levels up front.

@rbreaves rbreaves pinned this issue Apr 28, 2020
@rbreaves rbreaves changed the title Add Application Shortcuts using xkeysnail Shortcut Creation (xkeysnail/udev) Apr 28, 2020
@rbreaves rbreaves changed the title Shortcut Creation (xkeysnail/udev) Shortcut Creation (xkeysnail) Apr 28, 2020
@one-summers-day
Copy link

Hi! I'm a uni student who just began teaching himself python - do you still need help with this? If not, do you have some other issues that I may be able to assist with? Very green, but very motivated =)

@rbreaves
Copy link
Owner Author

rbreaves commented May 22, 2020

Well one thing I need to look at fixing is reworking the last 2 commits on my xkeysnail fork & resubmitting to the main project.

It’s all python. mooz/xkeysnail#74

Another feature that would be highly valuable would be to integrate an inotify library that checks the config file for changes & reloads the file without restarting the entire xkeysnail python app. No idea how involved that’ll end up being.

And besides the PPA thing here, just about anything on this page. Additionally if xkeysnail could be updated for wayland support by using APIs for specific DEs to grab wm_class IDs then that also would helpful to those moving on from x11.

#32

A fork for a KDE plasmoid & a gist, about gnome3, I have has some very early work done to support wayland.

@rbreaves
Copy link
Owner Author

rbreaves commented May 22, 2020

Also adding more cross-platform text editors or IDE shortcuts to ./xkeysnail-config/kinto.py could help people.

Also was thinking an app that contains original shortcuts for Linux & Mac apps & categorizes the app types while matching similar functionality could be very helpful too if it could write translations in xkeysnail.

What I mean is if someone has a preference to use Photoshop hotkeys in Gimp then being able to set 2 drop downs & adding that quickly to the config would be amazing..

That’d be some tedious work though, creating the database of hotkeys & recognizing similar functionality & creating universal names.

Despite the tedium people could get up & running quickly with their preferred shortcuts.

Also a python app that could display a “cheatsheet” of the custom keymaps for the currently focused app would be amazing too. Let it convert the config & comments to something pretty like this & just for the app you’re in https://mediaatelier.com/CheatSheet/

@vendz
Copy link

vendz commented Jun 1, 2021

Hey, I am a student and a self-taught Python programmer. I am looking for projects to contribute to, can you find me any issues to which I can contribute to?

@rbreaves
Copy link
Owner Author

rbreaves commented Jun 1, 2021

I do need to update my current release with the install of the old 1.0.7-3 release, but in an inactive state. It needs to be there for virtual sessions, such as xrdp and vnc. That may be a bit much though.

The easiest things to contribute would be shortcut keys.

The greatest impact though would be to work out how to reliably interact with Wayland through the major DE's out there - contributing to this ticket would be huge imo. Not just for this project by anything that branches off of xkeysnail.

mooz/xkeysnail#108

@vas0k
Copy link

vas0k commented Sep 26, 2021

Hey everyone, I'm new to open source development and eager to help out with any issues you're facing!

Thanks.

@tnyeanderson
Copy link

tnyeanderson commented Dec 7, 2021

So I see that changes can be made here: ~/.config/kinto/kinto.py

Perhaps I'm missing something, but isn't this essentially the "base" shortcuts file on install? How does this file get updated for newly added shortcuts from upstream without overwriting user changes?

I would like to be able to do something like this:

.config
└── kinto
    ├── kinto.py
    └── shortcuts.d
        ├── 00-dolphin.py
        ├── 10-konsole.py
        ├── 20-gimp.py
        └── 99-dolphin-testing.py

Where the kinto.py file contains the default kinto shortcuts (and can therefore be easily updated from upstream), and shortcuts.d loads subsequent user-defined shortcuts in alphabetical order, overwriting previous ones as needed. So for example, I might have my known-good extra shortcuts that I like for dolphin in 00-dolphin.py, but I might also try some new ones in 99-dolphin-testing.py without having to worry about the difficulty of reverting the changes later (just delete the file).

My reasoning for this is 1) to encapsulate different parts of the configuration into easily findable and digestible chunks and 2) to make it really easy to provide my custom shortcuts to other systems later on, while 3) maintaining any changes from upstream during a new install or upgrade. A great side effect of this is it makes it really easy for the community to share their shortcuts for certain applications as needed.... just give me your file and I'll put it in my shortcuts.d.... done!

I could be way off base on this as I have no idea how xkeysnail works or how kinto works behind the scenes, so let me know if this is off the deep end. Otherwise, what would need to be done to make this (or something like it) possible? Of course a new issue would be opened if work needs to be done, but I figured this was the most discoverable place for a question like this.

Thanks for all the hard work on kinto! I'm excited to start using it in lieu of my mess of custom shortcuts when I move to OpenSUSE :)

@rbreaves
Copy link
Owner Author

rbreaves commented Dec 8, 2021

@tnyeanderson this was discussed to some length in a PR already. I’ve not yet been able to take the time to implement it - the concept was somewhat similar although I like the way you laid the files out more.

I was also planning to make a yaml based config instead to further abstract unnecessary syntax away from the user. Both these concepts, yours & that in an outstanding PR need pursuing.

@tnyeanderson
Copy link

I do love YAML! Is this PR #455 ?

@rbreaves
Copy link
Owner Author

rbreaves commented Dec 8, 2021

@tnyeanderson that would be the one, changes to the installer were discussed there previously as was changes to the actual shortcut config files too.

It also drove some of the design for sorun.me as I used yaml config files for it. But yea this project does need some rewriting to make it more maintainable & easier for people to maintain their custom changes.

I make custom changes too for vscode, but vscode is a little complicated since I install sublime text keymaps & a custom keybinding file (inside of vscode itself which I typically don't ever do, I want all remaps outside of the base program, but VSCode is an electron app and it has certain limitations).

@tnyeanderson
Copy link

tnyeanderson commented Dec 8, 2021

EDIT: Added raw directive to yaml spec

So it seems to me that the flow might be something like this (all files are relative to .config/kinto and subject to discussion/change):

  1. xkeysnail watches a "final config" file (kinto.py) for changes and applies them as needed (this remains the same and allows backwards compatibility)
  2. Kinto places and updates the base configuration file (base.py or base.yaml)
  3. On application start, kinto.py is generated based on base.{py,yaml} and shortcuts.d/*.yaml
  4. A utility like watchman is used to watch shortcuts.d for changes. On change, regenerate kinto.py as above
  5. xkeysnail recognizes and applies the changes to kinto.py

Each yaml config file might look something like this (my blindspot is here as I'm not familiar with xkeysnail):

name: My application
description: Gives me special shortcuts
keymaps:
  - name: Firefox and Chrome
    conditional:
      regex: "Firefox|Google-chrome"
      #case_sensitive: false
    maps:
      - from: "C-M-j"
        to: "C-TAB"
      - from: "C-M-k"
        to: "C-Shift-TAB"
  - raw: |
      define_keymap(re.compile("Zeal"), {
          # Ctrl+s to focus search area
          K("C-s"): K("C-k"),
      }, "Zeal")
  - name: Emacs-like keys
    conditional:
      wm_class:
        #in:
        not:
          - Emacs
          - URxvt
    maps:
      - description: C-x YYY
        from: "C-x"
        maps:
          - description: C-x C-f (open)
            from: "C-f"
            to: "C-o"
          - description: C-x C-s (save)
            from: "C-s"
            to: "C-s"

Which would generate:

define_keymap(re.compile("Firefox|Google-chrome"), {
    K("C-M-j"): K("C-TAB"),
    K("C-M-k"): K("C-Shift-TAB"),
}, "Firefox and Chrome")

define_keymap(re.compile("Zeal"), {
    # Ctrl+s to focus search area
    K("C-s"): K("C-k"),
}, "Zeal")

define_keymap(lambda wm_class: wm_class not in ("Emacs", "URxvt"), {
    # C-x YYY
    K("C-x"): {
        # C-x C-f (open)
        K("C-f"): K("C-o"),
        # C-x C-s (save)
        K("C-s"): K("C-s"),
    },
}, "Emacs-like keys")

Examples taken from: https://github.com/mooz/xkeysnail#example-configpy

Cases not handled (nicely) by this yaml yet (could be more, possibly many more... this was very quickly put together):

  • K("C-g"): [K("esc"), set_mark(False)] (using set_mark)
  • K("C-q"): escape_next_key (using variables like escape_next_key or pass_through_key)

NOTE: With the raw directive shown above... anything is possible :)

Things to consider:

  • Sanitization when translating from yaml to python
  • Get yaml configs implemented upstream in xkeysnail to benefit the rest of the community
  • Does xkeysnail automatically overwrite shortcuts? For instance if I set a shortcut and then immediately (or much later) set the same shortcut key, does it get overwritten to only the new shortcut? If so, PERFECT. If not, oof.... we would have to implement some serious logic.

Finally, while there was discussion in that PR, I think this should be its own issue/PR to be more discoverable and trackable. We should link to it from here for the same reasons :)

Thanks again for the hard work!

@rbreaves
Copy link
Owner Author

rbreaves commented Dec 8, 2021

Thanks that is pretty much exactly the vision. The emacs formatting looks weird as I don't know if I do any of that by default, but that is probably how that'll look too. I probably will not be able to get to this till some time in early 2022 is my guess with the holidays being what they are.

Logic for finding any potential conflicts will need to be added - and ultimately if the user adds something in .d then I will have it override the default. May provide a warning that conflicts existed and the affected default keybindings may not be accessible.

@tnyeanderson
Copy link

If you need any help with it, let me know and I'm happy to give it a shot.

@tnyeanderson
Copy link

tnyeanderson commented Dec 9, 2021

Well I got bored, sleepless, and curious (a winning combination) and made a parser that matches the spec above. It includes support for multidoc yaml and all syntax (including commented) in the above yaml, and outputs the above .py.

I know you won't have time to get to this until next year (and that's okay!) but I do hope this helps take some work off of your hands.

https://gist.github.com/tnyeanderson/23057d8286be5a90ce25923f41352dc8

Still to do:

  • Thoroughly test (write tests if possible!)
  • Recognize duplicates/overrides
  • Include base.{py,yaml} in resulting output
  • Unsupported cases from above?
  • Profit? :)

Please feel free to use this however you wish, if you wish

@Tu-Code
Copy link

Tu-Code commented May 11, 2022

Is this issue still active?

@rbreaves
Copy link
Owner Author

rbreaves commented May 12, 2022

This is intended to be an on going thread so yes, it will always be open and active. I have not had much time to do many of the rewrites I would like to do though, busy w/ life and work.

I mostly just merge quick and easy shortcuts people contribute as PRs and maintain keeping Kinto working on various distros or with DEs. Small rewrites and wayland support does need to be worked on as well as multi-user and normal user mode elevation support needs to be added as well, but those aren't things I have had the time to work on lately.

Wayland support I think is held up by an xdg desktop accessibility portal feature that is being debated or mulled over atm to bring visibility to the wm_class names of the actively focused app. There's also just a lot of devs that aren't really community that well imo as I am noticing this type of thing gets mentioned in various places but I think we have devs unaware of what others are doing or talking about because you have your github devs, gitlab, personal blogs, launchpad and mailing lists... to really see movement here I think it will take someone going back and forth btwn the right people in each of their preferred environments for collaboration lol.

@rbreaves
Copy link
Owner Author

I do need to get around to implement what tnyanderson and I were discussing as well as redbearak and one other guy who I am blank on their name atm.

@DanielPickens
Copy link

DanielPickens commented Jun 5, 2022

@rbreaves I'd like to contribute to this by: udev implementation via xkeysnail using the devised approach by @tnyeanderson , can build off the gist by adding logic to accommodate recognized duplicates/overrides within kinto.py, and would be able to write thorough unit tests for the parser.
Would I be able to contribute to this issue?

@rbreaves
Copy link
Owner Author

rbreaves commented Jul 2, 2022

@DanielPickens Oh I'd love to see some solid examples of setting up unit tests to ensure changes with xkeysnail are functioning as expected. I figure though it will require a fairly complicated CI/Pipeline though spinning up an entire distro (maybe something that can be cached though). Also I do plan to switch over to @joshgoebel fork.

@joshgoebel
Copy link
Contributor

see some solid examples of setting up unit tests to ensure changes with xkeysnail are functioning as expected.

Keyszer has a growing number of unit tests already to prevent any accidental regressions in behavior... you can test most things that matter at just the transform layer - you don't need a whole physical Linux box...

@rbreaves
Copy link
Owner Author

rbreaves commented Jul 2, 2022

Oh yea, I forgot you said that you would have that in yours lol. I am just now trying to get caught up on notifications.. and I guess it is getting late. I will finish going through this tomorrow 😅. Thanks for all the work you've been putting into your fork @joshgoebel ! I will be trying to get Kinto moved over to it soon.

I have been busy with work, but also I have re-structured my primary computer's OS's to actually be macOS once again since I resolved the biggest remote desktop issue I had with Linux when I patched x11vnc lol. That one issue actually had me using only Linux and Windows for well over a year, as I couldn't properly remote into a Linux VM very well at all. (NoMachine was just way too heavy & was causing my CPUs to make noise and heat up.)

@rbreaves
Copy link
Owner Author

rbreaves commented Jul 2, 2022

you can test most things that matter at just the transform layer - you don't need a whole physical Linux box

Well I was also thinking in terms of ensuring that specific remaps in particular apps might be good to test against continuously as new key mapping additions can always have a potential to step on another was all I was thinking. But that's probably more difficult to automate and test than a simpler unit test I guess.

@joshgoebel
Copy link
Contributor

as new key mapping additions can always have a potential to step on another

I'd need a specific example, but if it's something that could be detected at config time then I'd be open to a feature that just auto-detected such problems and disallowed them. It sounds like a config testing issue now, not a service testing issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
first-timers-only For people who want to contribute.
Projects
None yet
Development

No branches or pull requests

8 participants