• 6 Posts
  • 117 Comments
Joined 2 years ago
cake
Cake day: July 2nd, 2023

help-circle

  • Do you follow the reasoning for why they set it up this way? The comments in this function from _xorg in keyboard make it seem like it expects K1 K2 K3 K4.

    #: Finds a keycode and index by looking at already used keycodes
            def reuse():
                for _, (keycode, _, _) in self._borrows.items():
                    keycodes = mapping[kc2i(keycode)]
    
                    # Only the first four items are addressable by X
                    for index in range(4):
                        if not keycodes[index]:
                            return keycode, index
    

    I assume that second comment is the reason the person who wrote your function likes the number 4.

    Which way is right/wrong here? It would seem at least part of the issue to me is that they don’t make the list be K1 K2 K1 K2 as they say, since the function I quoted above often receives a list formatted like K1 K2 K1 NoSymbol.

    Also, if I modify the function you quoted from to remove the duplications, I’m still finding that the first element is always duplicated to the third element anyways - it must be happening elsewhere as well. Actually, even if I modify the entire function to just be something nonsensical and predictable like this:

    def keysym_normalize(keysym):
        # Remove trailing NoSymbol
        stripped = list(reversed(list(
            itertools.dropwhile(
                lambda n: n == Xlib.XK.NoSymbol,
                reversed(keysym)))))
        if not stripped:
            return
        else:
            return (keysym_group(stripped[0], stripped[0]), keysym_group(stripped[0], stripped[0]))
    

    then the behavior of the output doesn’t change at all from how it behaves when this function is how it normally is… It still messes up every third special character, duplicating the previously encountered special character

    Later edit: After further investigation, the duplication of the first entry to the third entry seems to happen in the Xlib library, installed with pynput, in the display.py file, in the change_keyboard_mapping function, which only has a single line. Inspecting the output of the get_keyboard_mapping() function both before and after the change_keyboard_mapping function does its thing shows that it jumps right from [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] to [keysym, 0, keysym, 0, 0, 0, 0, 0, 0, 0]. It’s still unclear to me if this is truly intended or a bug.


  • Gonna make some notes since I made some progress tonight (so far).

    Within pynput’s keyboard’s _xorg.py file, in the Controller class, self._keyboard_mapping maps from each key’s unique keysym value, which is an integer, to a 2-tuple of integers. The actual keysym for each key in the mapping appears to be correct, but occasionally the 2-tuple duplicates that of another entry in self._keyboard_mapping - and these duplicates correspond precisely to the errors I see in pynput’s outputs.

    For example, ‘𝕥’ has keysym = 16897381 and ‘𝕖’ has keysym = 16897366, but both 16897381 and 16897366 map, in self._keyboard_mapping, to the 2-tuple (8, 1) - and ‘𝕖’ is indeed printed as ‘𝕥’ by pynput. (𝕥’s keysym appears first in self._keyboard_mapping). (The 2-tuple keysyms map to are not unique or consistent, they vary based on the order they were encountered and reset when X resets)

    Through testing, I found that this type of error happens precisely every third time a new keysym is added to self._keyboard_mapping, and that every third such mapping always duplicates the 2-tuple of the previous successful mapping.

    From that register function I mentioned, the correct 2-tuple should be, I believe, (keycode, index). This is not happening correctly every 3rd registration, but I’m not yet sure why.

    However, I did find a bit more than that: register() gets its keycode and index from one of the three functions above it, reuse() borrow() or overwrite(). The problematic keys always get their keycode and index from reuse - and reuse finds the first unused index 0-3 for a given keycode, then returns that. What I found here is that, for the array keycodes, the first element is always duplicated to the third position as well, so indexes 0 and 2 are identical. As an example, here are two values of keycodes from my testing:

    keycodes = array('I', [16897386, 0, 16897386, 0, 0, 0, 0, 0, 0, 0])
    keycodes = array('I', [16897384, 16897385, 16897384, 0, 0, 0, 0, 0, 0, 0])
    

    With this in mind, I was actually able to fix the bug by changing the line for index in range(4): in reuse() to for index in range(2):. With that change my script no longer produces any incorrect characters.

    However, based on the comments in the function, I believe range(4) is the intended behavior and I’m just avoiding the problem instead of fixing it. I have a rather shallow understanding of what these functions or values are trying to accomplish. I don’t know why the first element of the array is duplicated to the third element. There’s also a different issue I noticed where even when this function returns an index of 3, that index of 3 is never used in self._keyboard_mapping - it uses 1 instead. I’m thinking these may be two separate bugs. Either way, these two behaviors combined explain why it’s every third time a new keysym is added to self._keyboard_mapping that the issue happens: While they in theory support an index of 0 1 2 or 3 for each keycode, in practice only indices 0 1 and 3 work since 2 always copies 0 - and whenever 3 is picked it’s improperly saved as 1 somewhere.

    I may keep investigating the issues in search of a true fix instead of a cover-my-eyes fix.


  • I agree and appreciate it. I’ve been trying to figure it out myself but feel a bit out of my element.

    What I’ve found is that in pynput’s keyboard’s _xorg.py file, the Controller class’s self._keyboard_mapping seems to map some different keycodes to the same value, and that seems to correlate exactly with the errors I’m seeing. I haven’t figured out why yet. I got to thinking it had something to do with the register function in the _resolve_borrowing function but I forget why and I’m too tired to continue for now. I’ll continue tomorrow though.








  • What an insightful post 🙂

    The only one of these I’ve updated since the original is the one for Ars Technica, which is now this:

    arstechnica.com##:not(:not(head>title:has-text(/Serving the Technologist/))) article:has-text(/Trump|Elon|Musk|nazi|doge|maga/i)

    The reason being that ‘Ars Technica’ now appears in the title of articles, while it didn’t originally, which caused the original filter to block out entire articles. ‘Serving the Technologist’ only appears on the homepage so this updated filter will still filter the homepage but display the contents of articles that contain blacklisted words.



  • zkfcfbzr@lemmy.world
    cake
    toLinux@lemmy.mlFirefox 135.0 released
    link
    fedilink
    English
    arrow-up
    99
    ·
    5 months ago

    Firefox now includes safeguards to prevent sites from abusing the history API by generating excessive history entries, which can make navigating with the back and forward buttons difficult by cluttering the history. This intervention ensures that such entries, unless interacted with by the user, are skipped when using the back and forward buttons.

    Nice



  • Hello again 🙂 I have a good feeling about this one.

    infosec.pub##:not(head>title:has-text(/leopard/i)) article.row:has-text(/Trump|Elon|Musk|nazi/i):not(:has-text(/leopard/i))
    

    It’s doing basically the same thing as the last one but now instead of targeting an <a> tag with the community-link attribute, which was basically just the first way I was able to find of identifying a community last time, it targets the title of the page itself, which seems like it should be a lot more reliable. This does mean using the literal leopardsatemyface-type filter won’t work since the title of the page is the community’s user-friendly name: “Leopards Ate My Face” in this case.

    So as before it should block any posts which contain words from the blacklist, unless they also contain words from the whitelist - and now if the title of the page has any words from the whitelist (indicating we’re on an allowed community page), it will block nothing at all. The blacklist and whitelist will apply to the post title, community name, and even the submitter’s name - anything you can read and even some things you can’t read.


  • I think I may see why. I didn’t actually bother to check the main feed before, but it seems like it does have the a.community-link tag the new filter targets in every post - so if a post from leopardsatemyface ever shows up in the main feed, then the filter will think it’s on that community page and fail to block any posts. But the filter should work fine so long as no posts from that community are currently on the main feed. This should be the case regardless of which regex is used - if it wasn’t just a coincidence earlier I’ll have to test around to figure out what happened with that.

    It’s a process making a good filter, I guess - I may look into a more reliable and narrower way to achieve the desired effect later on



  • Hey! I’m pretty sure this one will work:

    infosec.pub##:not(a.community-link:matches-attr(title=/.*?leopard.*?/i)) article.row:has-text(/Trump|Elon|Musk|nazi/i):not(:has-text(/leopard/i))
    

    Where now we have three filters. If the community name matches the first regex, then nothing at all will be filtered out - and then the other two work the same as before. So any post that matches the blacklist regex will be filtered out unless it also matches the whitelist regex.

    I chose to make the first regex /.*?leopard.*?/i because my thinking is you may want to just copy/paste the other whitelist filter there for simplicity, but it might make more sense to do it like the others, like /leopardsatemyface|second community|third community|etc/i. The “title” of a community for the purpose of this filter should be whatever appears after /c/ in the URL, not counting the @lemmy.world (or whatever instance) part.



  • I’m not sure I follow - the filter seems to work as-is to me. It allows posts on both the front page and the !leopardsatemyface@lemmy.world to bypass the filter for me.

    To be clear, it’s not only applying to the title row - the article tag it targets contains the entire post as it appears in the post feed, including the title, community name, the person who submitted it, the timestamp, etc. So if anything there contains a filtered or whitelisted word it should trigger the filter.

    I wouldn’t have necessarily expected the whitelist filter to work directly on the leopards community page, since posts on community feeds don’t include the community name, but it works anyways because, it seems, there’s a hidden mod option in the HTML with the community name in it: <div class="modal-body text-center align-middle text-body">Are you sure you want to transfer leopardsatemyface@lemmy.world to TheBat@lemmy.world?</div>



  • At one point I had the very similar filter lemmy.world##.post-listing:has-text(/trump/i), but I wasn’t happy with it because it would also remove post content on actual post pages, not just the post feed. That was the whole reason I swapped to the article.row solution instead - posts in the feed have the row class while posts on their own page don’t. But it looks like you found an alternate solution to achieve essentially the same thing. Neat!

    I have no real interest in filtering out comments, but it’s nice to have that option there for people who do.