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

Using with Kinto v1.2-13 #36

Open
joshgoebel opened this issue Jun 15, 2022 · 18 comments
Open

Using with Kinto v1.2-13 #36

joshgoebel opened this issue Jun 15, 2022 · 18 comments
Assignees
Labels
documentation Improvements or additions to documentation help welcome Help/contrib is esp welcome

Comments

@joshgoebel
Copy link
Owner

joshgoebel commented Jun 15, 2022

Making an issue thread for discussion of early beta testers. This should be limited to getting your Kinto.sh config working with keyszer, any actual issues should be reported separately.

Please see:

@joshgoebel
Copy link
Owner Author

@rbreaves

@joshgoebel joshgoebel added documentation Improvements or additions to documentation help welcome Help/contrib is esp welcome labels Jun 15, 2022
@joshgoebel joshgoebel self-assigned this Jun 17, 2022
@RedBearAK
Copy link
Contributor

@joshgoebel

I believe I'm now using the timeouts construct correctly in the config file to set the suspend timeout, but I've looked at the README and the example config and the files in the first post here and I can't see anything yet that talks about how to set the DIAG and DEBUG keys from within the config. That was the intention with the latest iteration of the code, right?

I'm on the latest pull of main as of last night.

@joshgoebel
Copy link
Owner Author

It's in config_api even if not yet documented.

@RedBearAK
Copy link
Contributor

It's in config_api even if not yet documented.

Yes, I have seen the newer structures in config_api. And tried many different ways of attempting to use them from the config file. All have resulted in failure to set the key, or a syntax error crash.

This exact syntax was not self-explanatory (to me), but it seems to finally work:

dump_diagnostics_key(Key.F7)
emergency_eject_key(Key.F8)

@joshgoebel
Copy link
Owner Author

This exact syntax was not self-explanatory (to me), but it seems to finally work:

They are just functions, like all the other functions (keymap, K, etc)... all invoked with name() syntax.

@RedBearAK
Copy link
Contributor

I get that they are just functions, but what to put inside the (), and where quotes need to be used or not used, is often not clear to me without an example. I first assumed the function would want a string that would correspond to a key name in key.py, like "F8". Kind of like the K function just wants the name of the key, in quotes. But that didn't work, of course.

So Key with the capital letter (this is an aspect of Python that I don't really appreciate) is a class imported from models/key.py, and using Key.F8 does what, sets the actual key code to the value of the corresponding member object of the Key class?

Is that even close to correct?

@joshgoebel
Copy link
Owner Author

joshgoebel commented Jun 20, 2022

but what to put inside the (), and where quotes need to be used or not used, is often not clear to me without an example.

Yes, I see the confusion - we need docs, but the functions inside API do show the input type expected (via isinstance):

def dump_diagnostics_key(key):
    global DUMP_DIAGNOSTICS_KEY
    if isinstance(key, Key):
        DUMP_DIAGNOSTICS_KEY = key

Any other types are silently ignored. (should probably raise an error instead)

Kind of like the K function just wants the name of the key, in quotes.

Well, not really the name of a key (and K is a poor choice IMHO), but an entire combo specification... it just so happens that a combo can be a single key... the right side of a combo can be specified with only a Key instance (if only a key is needed).

this is an aspect of Python that I don't really appreciate

It's not just Python, uppercase classes are common in MANY languages.

and using Key.F8 does what, sets the actual key code to the value of the corresponding member object of the Key class?

Well it doesn't "set" anything really, but as an expression it evaluates to that, yes. Though I'm not fully sure "member object" is the right wording, but I think you have the overall idea.

@RedBearAK
Copy link
Contributor

RedBearAK commented Jun 20, 2022

I see. Now things like:

keymap(
   "Ctrl-Alt-a": Key.LEFT_META
)

Make a bit more sense to me.

It's not just Python, uppercase classes are common in MANY languages.

Do most languages let you use "key", "Key", "kEy", "keY", "KEy", "KeY", and "kEY", all for different purposes, with the only difference being the capitalization? The capitalization of the class name specifically was not really my issue. That's fine, even helpful, if it's a generally understood styling standard.

and K is a poor choice IMHO

You know, I have wondered in the past whether the K() could actually be gotten rid of, in terms of the user not having to use it to surround every shortcut in the config file.

Instead of (completely random shortcuts example):

K("Shift-X"): [ K("Shift-Alt-Y"), K("RC-a") ],

Shouldn't it be possible to just do:

"Shift-X": [ "Shift-Alt-Y", "RC-a" ], 

@joshgoebel
Copy link
Owner Author

Do most languages let you use "key", "Key", "kEy", "keY", "KEy", "KeY", and "kEY", all for different purposes,

Many language are case-sensitive like this, yes. The difference between KEY, Key and key (which can tell you a lot) wouldn't mean much if someone could sloppily just type whichever and it always worked.

I have wondered in the past whether the K() could actually be gotten rid of,

Technically it could, but I'm not sure its a good idea because then you lose the ability to let a string be a string in the future... like right now one might possibly write:

K("Alt-S"): ["save:", Key.Enter]

And we could treat "save:" differently just beacuse it's a string - meaning we know for sure it's NOT a combo...

@joshgoebel
Copy link
Owner Author

BUT if you learned Python it would be pretty trivial to write your own keymap, modmap proxy functions that took in strings and spit out K() wrapped objects... only a few lines of code likely...

@RedBearAK
Copy link
Contributor

wouldn't mean much if someone could sloppily just type whichever and it always worked

No, that would be bad. I'm perfectly fine with being required to call a function or variable with exact case. I just don't like how case sensitivity without enforcing case INsensitive uniqueness lets the programmer use the, quote, "same" word (or what we would normally consider the same word in everyday life) for completely different purposes. Shell scripts don't allow that, if I remember right. But you still have to call the variable with the right case. I have no issue with that at all. I just think it's much more clear if the language makes you use a slightly different name for every object, rather than letting you rely only on case. Heaven forbid things get named a bit more verbosely like "KeyClass" instead of just "Key" with a capital letter.

only a few lines of code likely.

If by "a few" you mean around a dozen lines, that seems possible.

I am working on a UC() function to at least handle 4-character Unicode strings. Printing a string that looks like what I want is fairly easy, but of course that's just a string in the log. Creating a list turned out to be not too difficult. I eventually wound up with expected printed output at various stages. But I'm very hung up on exactly how to get the created list back into the spot (and in the proper form vis-a-vis things like commas being correct) where it will then get evaluated as if it had just been a macro of K() objects in the first place. Returning something static like a value or string is much easier to comprehend than this kind of recursive evaluation of constructed functions coming back from other functions.

Still working my way through video tutorials like the one you linked to (which I actually found independently, and it's not a bad starter). But at the moment I'm still very much not getting how to do what you're describing. Or at least, all the variations I've tried so far have not worked.

And we could treat "save:" differently just beacuse it's a string - meaning we know for sure it's NOT a combo...

Hmm. I don't immediately see the benefit. For the use case of a keymapper like this it feels like the more appropriate thing would be to get rid of K() and just make the user use an S() to wrap strings. After all, you would only have to do S() once for a string of any length, where you need to use K() for each individual letter (or combo). But it was just an idle thought anyway.

@joshgoebel
Copy link
Owner Author

joshgoebel commented Jun 20, 2022

Heaven forbid things get named a bit more verbosely like "KeyClass" instead of just "Key" with a capital letter.

Key is a class and key is likely an instance of said class. This is fairly common and not that problematic once you get used to it. KeyClass would just be repetitive and verbose as would key_instance or a_key.

Of course good syntax highlighting helps a lot with this as well.

For the use case of a keymapper like this it feels like the more appropriate thing would be to get rid of K() and just make the user use an S() to wrap strings.

I don't necessarily disagree, but I was pointing out the downside... I very much like using "implicit" classes when one can to simplify APIs, and giving up string for ALL potential future uses is a pretty big loss. Just because you can't think of a use other than S today doesn't mean there won't be one tomorrow.

Or at least, all the variations I've tried so far have not worked.

Seeing some specific code might help.

But I'm very hung up on exactly how to get the created list back into the spot (and in the proper form vis-a-vis things like commas being correct) where it will then get evaluated as if it had just been a macro of K() objects in the first place.

You don't need to worry about the textual form, you need to worry about the object form... you aren't trying to make a string (or that's the hard way IMHO)... you're literally trying to make a chain of objects... for example a very naive and overly simplistic S:

def S(s):
   keys = []
   for letter in s.upper():
      keys.append(Key[letter])
   return keys
>>> print(S("test"))
[<Key.T: 20>, <Key.E: 18>, <Key.S: 31>, <Key.T: 20>]

Boom, turning a string into keys... Now you should still be able to print things to check them (as I just did above), we have nice printed representation for most objects so you can see what they are... but what you want here in the end is an array of keys/combos...

@RedBearAK
Copy link
Contributor

Quick question. I have a line that prints the incoming string right at the top of the UC() function. It appears to print out the string once for each instance of a shortcut line that calls the function. So if I do the same thing I did on Windows and implement all 137 characters on the Apple keyboard, that means that function would get evaluated 137 times, each time the config file is loaded? And that’s what is also happening with all the K() functions and the functions they are inside of?

@joshgoebel
Copy link
Owner Author

Yes.

@Merkie
Copy link

Merkie commented Mar 4, 2024

Hey I've been attempting to use this project with Kinto and every time I try to install it I end up having to reset my Kinto config so I'm coming here for help. I am using Kubuntu LTS.

The first issue I run into is whenever I remove the imports from my kinto.py file, it lights up my editor due to all the functions not being defined. Is this normal? My editor tells me to import the functions from Keyszer but the docs say no import statements are needed.

This also happens when I remove the re module as some of the items in the config require Regex in their names, but the docs say to just remove it... I don't understand how that's supposed to happen.

Another issue I have is I'm failing to understand how everything is going to work together. Will Keyszer be replacing XKeysnail entirely? Or will Kinto, Keyszer, and XKeysnail all be running together at the same time?

If anyone just has a config or clear instructions for this that would be really appreciated. I thought this would be a quick and easy fix like it was described on the Kinto issues page but I've sunk about 2 afternoons into this just to get modifier selections working 😭

@RedBearAK
Copy link
Contributor

@Merkie

Will Keyszer be replacing XKeysnail entirely? Or will Kinto, Keyszer, and XKeysnail all be running together at the same time?

Technically keyszer is a drop-in replacement for xkeysnail. They both need to exclusively "grab" keyboard devices and the /dev/uinput device in order to do what they do with keyboard input, so they literally can't operate at the same time, and you wouldn't want them to.

If what you want is a Mac-like config like Kinto, but using keyszer to get the benefit of all the new features and bug fixes that happened after it was forked from xkeysnail, you should check out my project, Toshy:

https://github.com/RedBearAK/toshy

(shorter redirect URL: https://toshy.app)

This project has a config that is based on Kinto's config, but has gone a bit beyond it in features (like automatically adapting itself to different desktop environments and keyboard types). I'm also using a customized branch of keyszer that has Wayland support for a few different desktop environments (Cinnamon, Hyprland, GNOME, KDE Plasma, and Sway, so far). Toshy is tested to work on many popular distro types, including most of the Ubuntu variants like Kubuntu LTS.

If you look at the default Toshy config file you'll see there are quite a few imports to get VSCode to calm down and highlight everything properly. Imports are technically not necessary because of the way the keymapper executes the config file. But as you've seen it makes it very difficult to work on the config in an editor like VSCode if you don't do the imports. And it's not harmful to do the imports. They are just kind of redundant outside the context of VSCode or some similar editor.

The main keyszer dev apparently uses an IDE or code editor setup where this doesn't really cause them a problem.

@joshgoebel
Copy link
Owner Author

The main keyszer dev apparently uses an IDE or code editor setup where this doesn't really cause them a problem.

Or I just turn off the linter. :-)

My editor tells me to import the functions from Keyszer but the docs say no import statements are needed.

The config file is loaded and run dynamically by Keyszer - so it auto-adds some imports and other needed housekeeping before the Python is ever executed. We honestly should probably just rename it and stop telling everyone it's Python - then the editor would shut up and stop trying to figure it out.

@RedBearAK
Copy link
Contributor

We honestly should probably just rename it and stop telling everyone it's Python - then the editor would shut up and stop trying to figure it out.

I would find that extremely unhelpful. I've done a lot of custom work in the config file and having the editor being completely incapable of helping me out with syntax highlighting and proper references would make it pretty unpleasant to work with the config.

With the imports that I do, everything works just fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation help welcome Help/contrib is esp welcome
Projects
None yet
Development

No branches or pull requests

3 participants