wojtryb / Shortcut-Composer

Krita plugin for creating complex keyboard shortcuts

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Key release does not trigger an event on non-latin keyboard layouts

JoerdanNewue opened this issue · comments

General info

  • Plugin version: ... [v1.1.1]+ Krita 5.1.5
  • Operating System: ... [Windows 10, 22h2]

Bug description
i assigned mouse trackers and pie menues on single keyboard buttons (w, f, 1, 2, 3, x). when i press it i get pie menue interface, than i chose instrument i needed -- but instead chosing and colosing it this menue dont close. i release button and nothing happen, when i click i get opportunity change instrument order, i thought it tablet bug- i disconnected it and tryied with mouse+keyboard- again BUT i dont know how trigger this bug, some times all work ok but after something all what worked before break, reload shortcut composer doesnt help, relaunching krita doesnt help. only system restart helps. i dont know how git hub works and how you can ask me additional question if you missunderstood me, i ll try check this page more often

Ideally:

  • check if the bug also occurs on the development branch (on github overview page, switch from 'main' to 'development', then download and install the plugin)
  • try to break down when the bug happens (always/occasionally), and what is needed for it to happen

When the bug is fixed, close the issue. After not getting a response from you for a week, I will close it myself.
qwer

Hi, and thank you for reporting.

Note that keys like 1,2,3... are reserved to krita canvas inputs, and using it as shortcuts may result in conflicts. You can reassign them to other keys, or go to Settings > Configure Krita > Canvas Inputs and remove the bindings for 1,2,3...

Try this out and check if your problem presists.

no the problem isnt in keys i choosed- i disabled default functions on these buttons

I'm afraid I may not be able to help you much.

If the feature works to some point, then suddenly breaks, and the only possibility to fix is the system restart, then I believe the issue lies somewhere in your system. Maybe it's some specific software or driver you use that breaks krita recognising the key release. So far the plugin was used by several Windows users and none reported a similar issue.

I can keep the issue open for now - in case it really is a general problem, and other people will find it - but I'm afraid this problem is specific to your setup, and I won't be able to help you as I'm not so good with Windows.

I think I have not understood you well.

The screenshot you provided has a pie menu in edit mode. You activate it by dragging any of the labels and close it with the tick button in the middle. To select the value you are not supposed to click the label (which activates the edit mode) but to hover over the label and release the keyboard button.

This behaviour will be changed a bit in next release (entering edit mode will have a separate button) to protect from accidental activation.

Read more in documentation: https://github.com/wojtryb/Shortcut-Composer#pie-menus

The issue remains, with this video showing what happens: https://www.youtube.com/watch?v=UmkFysKtBrM
If anyone can reproduce this issue, please comment below - I can't reproduce it on win10 and krita 5.1.5.

I'm reopeing the issue for now in case someone can confirm it.
After some time I'll probably have to assume the issue is specific to user's setup and I'll close this issue once again.

Pasting from YT video comments:
"""
hi recently with similar name in git i asked help about strange bug so i made video of what i have: pie menues and actions (opacity and size and undo history dont stop working) video: https://www.youtube.com/watch?v=UmkFysKtBrM for some reason i accidently closed window after i closed app.. so ill add comentary with text later. i should send this into git topic but i marked it as closed

hope there is no personal info), if so please delete it

RuntimeError
Python 3.8.1: C:\Program Files\Krita (x64)\bin\krita.exe

Sat Apr 15 [11:19:26](https://www.youtube.com/watch?v=Tkf2-U0OyG4&t=11h19m26s) 2023



A problem occurred in a Python script.  Here is the sequence of

function calls leading up to the error, in the order they occurred.



 C:\Users\Joerdan Newue\AppData\Roaming\krita\pykrita\shortcut_composer\templates\mouse_tracker_utils\slider_[handler.py](https://www.youtube.com/redirect?event=comments&redir_token=QUFFLUhqa0owUkRNenUzWXNRaWhxSmhSY1MxMHJNVGRCUXxBQ3Jtc0tuUzVudXBCc004MlZ3Mnl1S1RDcnIzV3M0ZFZjQlZ4bTllVm1JT05oZERmOHp3R05aM3ZZaU82SGdOenU2WHBDWFQ0RHJHckxQWHVrSFFGUGl6YTZVbHZVb05XaENPdzl4TFZKeFQ0cnhzWTdBYzBmNA&q=http%3A%2F%2Fhandler.py%2F&stzid=UgyfWjvXkLMwzqsifYp4AaABAg.9oWc_OPd1Td9oWh4iUTF3r) in _value_setting_loop(self=<templates.mouse_tracker_utils.slider_handler.SliderHandler object>)

   96     def _value_setting_loop(self) -> None:

   97         """Set current value from `SliderValues`."""

   98         clipped_value = self._interpreter.interpret(self.read_mouse())

   99         to_set = self._to_cycle.at(clipped_value)

  100         self._slider.controller.set_value(to_set)

clipped_value undefined

self = <templates.mouse_tracker_utils.slider_handler.SliderHandler object>

self._interpreter = MouseInterpreter(mouse_origin=705, start_value=0, min=-inf, max=inf, pixels_in_unit=29)

self._interpreter.interpret = <bound method MouseInterpreter.interpret of Mous...t_value=0, min=-inf, max=inf, pixels_in_unit=29)>

self.read_mouse = <bound method SliderHandler.read_mouse of <templ...acker_utils.slider_handler.SliderHandler object>>



 C:\Users\Joerdan Newue\AppData\Roaming\krita\pykrita\shortcut_composer\templates\mouse_tracker_utils\slider_[handler.py](https://www.youtube.com/redirect?event=comments&redir_token=QUFFLUhqbXZqVm9RMGxaWjFZOWtHdGxOVXJiSlpGRy1hZ3xBQ3Jtc0tsYjJLUUtTWi1MVUpRRWlPZEZnY3NDWEphRmoyZWplV3dCa3ZtWmluVjJZZUhDU25NZGUxeWxHdHFqMzJHUHVwejFuUGtWWXhUVFJlT0J1US1NeUhycXlEVVExSlY5QzJla3otRFpscG5nMlV5Qy1Icw&q=http%3A%2F%2Fhandler.py%2F&stzid=UgyfWjvXkLMwzqsifYp4AaABAg.9oWc_OPd1Td9oWh4iUTF3r) in read_mouse(self=<templates.mouse_tracker_utils.slider_handler.SliderHandler object>)

   83     def read_mouse(self) -> MouseInput:

   84         """Fetch current mouse position."""

   85         return self._mouse_getter()

   86 

   87     def _start_after_deadzone(self) -> None:

self = <templates.mouse_tracker_utils.slider_handler.SliderHandler object>

self._mouse_getter = <function SliderHandler._pick_mouse_getter.<locals>.<lambda>>



 C:\Users\Joerdan Newue\AppData\Roaming\krita\pykrita\shortcut_composer\templates\mouse_tracker_utils\slider_[handler.py](https://www.youtube.com/redirect?event=comments&redir_token=QUFFLUhqbU9zMzhoMURndnM3UWQ2bGZwZmlBSDdYNEdxZ3xBQ3Jtc0tuRGVra0JRVGhBOV9QVkRCd192WjU5Mi1xY2tYY2IzbGliOXRFcmRKUlNzbGJremdtYUVVbVZTU2d6ZjB4cHMxT21VWmU2bUdwUko1NHNkOXVUOTU4RXEtS05qN3h6MUdyQWt5bU1QWGRKc0ZIcnVaUQ&q=http%3A%2F%2Fhandler.py%2F&stzid=UgyfWjvXkLMwzqsifYp4AaABAg.9oWc_OPd1Td9oWh4iUTF3r) in <lambda>()

  127         cursor = Krita.get_cursor()

  128         if self._is_horizontal:

  129             return lambda: MouseInput(cursor.x())

  130         return lambda: MouseInput(-cursor.y())

  131 

global MouseInput = <function NewType.<locals>.new_type>

cursor = Cursor(qwin=<PyQt5.QtWidgets.QMainWindow object at 0x00000230A4937670>)

cursor.x = <bound method Cursor.x of Cursor(qwin=<PyQt5.QtWidgets.QMainWindow object at 0x00000230A4937670>)>



 C:\Users\Joerdan Newue\AppData\Roaming\krita\pykrita\shortcut_composer\api_krita\wrappers\[cursor.py](https://www.youtube.com/redirect?event=comments&redir_token=QUFFLUhqbFZsQTVRekYxTjFnNnpUOFpWYjM4QzZBMWItUXxBQ3Jtc0trU193Q255SEJLQzhVYjJKaDliVzJPcWlHUng1ZkMyb0g1Q0hXVE1SYXZ0RzM0cWlvWUFlWGxCVjlQUmFJcWFIWU5xZURZMThpQ2p0b212eENDbF9pWUwxenpPOEZybE12MDBYSnVDYmlKN0tfQlRBZw&q=http%3A%2F%2Fcursor.py%2F&stzid=UgyfWjvXkLMwzqsifYp4AaABAg.9oWc_OPd1Td9oWh4iUTF3r) in x(self=Cursor(qwin=<PyQt5.QtWidgets.QMainWindow object at 0x00000230A4937670>))

   14     def x(self) -> int:

   15         """Return x axis of cursor in pixels in relation to screen."""

   16         return self.qwin.cursor().pos().x()

   17 

   18     def y(self) -> int:

self = Cursor(qwin=<PyQt5.QtWidgets.QMainWindow object at 0x00000230A4937670>)

self.qwin = <PyQt5.QtWidgets.QMainWindow object>

self.qwin.cursor = <built-in method cursor of QMainWindow object>

).pos undefined

RuntimeError: wrapped C/C++ object of type QMainWindow has been deleted

    _cause_ = None

    _class_ = <class 'RuntimeError'>

    _context_ = None

    _delattr_ = <method-wrapper '__delattr__' of RuntimeError object>

    _dict_ = {}

    _dir_ = <built-in method _dir_ of RuntimeError object>

    _doc_ = 'Unspecified run-time error.'

    _eq_ = <method-wrapper '__eq__' of RuntimeError object>

    _format_ = <built-in method _format_ of RuntimeError object>

    _ge_ = <method-wrapper '__ge__' of RuntimeError object>

    _getattribute_ = <method-wrapper '__getattribute__' of RuntimeError object>

    _gt_ = <method-wrapper '__gt__' of RuntimeError object>

    _hash_ = <method-wrapper '__hash__' of RuntimeError object>

    _init_ = <method-wrapper '__init__' of RuntimeError object>

    _init_subclass_ = <built-in method _init_subclass_ of type object>

    _le_ = <method-wrapper '__le__' of RuntimeError object>

    _lt_ = <method-wrapper '__lt__' of RuntimeError object>

    _ne_ = <method-wrapper '__ne__' of RuntimeError object>

    _new_ = <built-in method _new_ of type object>

    _reduce_ = <built-in method _reduce_ of RuntimeError object>

    _reduce_ex_ = <built-in method _reduce_ex_ of RuntimeError object>

    _repr_ = <method-wrapper '__repr__' of RuntimeError object>

    _setattr_ = <method-wrapper '__setattr__' of RuntimeError object>

    _setstate_ = <built-in method _setstate_ of RuntimeError object>

    _sizeof_ = <built-in method _sizeof_ of RuntimeError object>

    _str_ = <method-wrapper '__str__' of RuntimeError object>

    _subclasshook_ = <built-in method _subclasshook_ of type object>

    _suppress_context_ = False

    _traceback_ = <traceback object>

    args = ('wrapped C/C++ object of type QMainWindow has been deleted',)

    with_traceback = <built-in method with_traceback of RuntimeError object>



The above is a description of an error in a Python program.  Here is

the original traceback:



Traceback (most recent call last):

  File "C:\Users\Joerdan Newue\AppData\Roaming\krita\pykrita\shortcut_composer\templates\mouse_tracker_utils\slider_[handler.py](https://www.youtube.com/redirect?event=comments&redir_token=QUFFLUhqa01kQWM4OHZ2U0lleDRzR0tieHllaVFoR1BIZ3xBQ3Jtc0tsN2xSLU5sVmlzRzUwNVk1NWJOT04xcHhGMzJPSWQ2Yk9qMTJmZVZ1NnRIVWlVbjYyOEtZZmNBcXh6VnNMal9Ed3kzYmxDblhVOGloenR3MzZGTzZaMGk1YjYyNE52SG92Mks3ZDZLMDBsMkFPVlpIZw&q=http%3A%2F%2Fhandler.py%2F&stzid=UgyfWjvXkLMwzqsifYp4AaABAg.9oWc_OPd1Td9oWh4iUTF3r)", line 98, in _value_setting_loop

    clipped_value = self._interpreter.interpret(self.read_mouse())

  File "C:\Users\Joerdan Newue\AppData\Roaming\krita\pykrita\shortcut_composer\templates\mouse_tracker_utils\slider_[handler.py](https://www.youtube.com/redirect?event=comments&redir_token=QUFFLUhqbDRGcjJua3BIUVZTcEt3Zi1WNjhNa1VhdlpJd3xBQ3Jtc0tuLTlIV0Yxc1pSSDUzWnpaT0lCZkFPaEYwWnBWOVNfRXA4aEJJOWpvTmd3eGgtTkdzaXZvQW92YVVlV0hUTWY4cFduOWZiUGVraFpaQ1lxREdxYmtubUV6MGZ3czBSTGlGN0M1b3B5a0tNalB5WWFqNA&q=http%3A%2F%2Fhandler.py%2F&stzid=UgyfWjvXkLMwzqsifYp4AaABAg.9oWc_OPd1Td9oWh4iUTF3r)", line 85, in read_mouse

    return self._mouse_getter()

  File "C:\Users\Joerdan Newue\AppData\Roaming\krita\pykrita\shortcut_composer\templates\mouse_tracker_utils\slider_[handler.py](https://www.youtube.com/redirect?event=comments&redir_token=QUFFLUhqbXpVWTJnR0xic2xmaEJ2bjJsV0pMYlQ2WUlPZ3xBQ3Jtc0tuTTJCdVo0Rl9uSG5BWXJnY3NBd3NpdlIwNEd2d2otRlRKMUV6MU15VDRqNDkwNWRJclRKbzJvemV2blJSbmtCWUY2YzdZRzlkeU5Bd2k0b3hnYzFYa3kwbjRqV0tUVjgxd3JNT0xrbGkyOEY0M0VFRQ&q=http%3A%2F%2Fhandler.py%2F&stzid=UgyfWjvXkLMwzqsifYp4AaABAg.9oWc_OPd1Td9oWh4iUTF3r)", line 129, in <lambda>

    return lambda: MouseInput(cursor.x())

  File "C:\Users\Joerdan Newue\AppData\Roaming\krita\pykrita\shortcut_composer\api_krita\wrappers\[cursor.py](https://www.youtube.com/redirect?event=comments&redir_token=QUFFLUhqbkVOUTN3cTB3UkFOMWFZNmlhbFJNVnhlNGJLQXxBQ3Jtc0trcGJ2OE5PWFczaHRWNy1taUd2a2tqSU9CODdwbHNZeDRpdnRKbXdHSVlUSklocjNPOXJuaFBXTF9YeWZmQ0J6MkxDZmZTRjdzS0dLTTZUYm5zVnRjQWprbnR4QWlTUFFsY254endjWTVmTmxFQmJyZw&q=http%3A%2F%2Fcursor.py%2F&stzid=UgyfWjvXkLMwzqsifYp4AaABAg.9oWc_OPd1Td9oWh4iUTF3r)", line 16, in x

    return self.qwin.cursor().pos().x()

RuntimeError: wrapped C/C++ object of type QMainWindow has been deleted
commented

Manjaro linux, krita 5.15 (Flatpack), plugin [1.3.2], 2 keyboard layout English and Russian
I was able to replicate something similar. This seems to be locale issue.

The menu (Pick brushes presets (red)) opens when the button is pressed and stays when the button is released.
This only happens when I press a key that has the shortcut set to it, but in a different keyboard layout.

For example, menu (Pick brushes presets (red)) has Q as shortcut and everything works perfectly (menu opens when key is pressed, menu disappears when key is released, brush is selected), BUT if I change the keyboard layout to Russian, i.e. press the same "Q" key, but in Russian layout it's "Й", then I get behavior like on the video (the menu stays frozen , brush is not selected).

probably rebooting the system helps because it changes the layout back to English (all video layout set to Russian), and in the video menu set to numbers (1,2,3) are not called, because they do not cause this problem.

Thank you, that's important info.

I'm not proficient with Windows, I wonder if JoerdanNewue could also be using a non-english keyboard layout.

I rely on krita for detecting keyboard presses and releases, and all the pies use the same code - the problem with keyboard layout must be a bug in krita or in Qt which krita uses.

Sadly, it's not something I can workaround, but I recall some fixes being made by krita devs in this zone - you can try .appimage of krita 5.2-prealpha - maybe this issue was already fixed.

commented

JoerdanNewue also used the Russian keyboard layout (This can be seen in the windows panel above the date and time "Рус" [Русский язык = Russian language]). And in the same way: assigned keys in the English layout, called them from the Russian one.

I just tried it [1.3.2] with Krita Next [krita-5.2.0-prealpha-d49660a234-x86_64.appimage]. The result is the same.

If a key is assigned in the English layout (Q for example), then when you call it from the Russian layout (Й in place of Q), the menu is called, but you can't choose brush, the menu freezes. (in English layout everything is perfect).

If you assign a key on the Russian layout (Й for example), then when you press Q on the English layout, the menu is not called at all. (in Russian layout everything is perfect)

[Й and Q are on the same key in different layouts].

Probably people with other layouts that do not have Latin characters may have the same problem, it can be not so specific setup problem.

If I have enough time, I'll check it out the other day with a conventionally Korean layout and report back.

A working way to use the extension now is to assign the key to buttons that don't change from the layout. (Conditionally, 1,2,3, etc. [specifically these are assigned to the default by Krita in Canvas Input Settings, and must be changed from there to work]).

Thank you, I don't think more triaging is needed as now I have a good enough understanding of the issue.

Key presses and releases are detected from two sources. Presses are handled by krita shortcut system. Releases are handled by my code which asks krita about the shortcuts.

Krita somehow managed to treat those two signs as the same input - but I never tried to do it as well.

This requests some thinking-through, and I can't promise I'll fix that soon, but at least this issue is now explained.

Thank you for finding that

commented

Thank you a lot for your work.

In order to make sure that this is not just a problem with the Russian layout, I checked a couple of others layouts.

Korean, Japanese, Chinese layouts that use Latin for input do not cause the problem.
I can confirm the problem on Arabic, Greek, Georgian layouts (other non-Latin layouts).
In the German layout, the problem occurs exclusively with expanded Latin characters (like Ä, Ö, Ü).

Thank you for testing.

I have a fix already, but it's a work in progress. You can download it from this branch.

Unluckily I couldn't find an automated way to do that, so I had to define those layouts myself. I have Cyrillic and Arabic alphabets done (but Arabic doesn't work with Shift yet).

I'll try to figure it out, and prepare other layouts you mentioned before merging this bugfix.

commented

Just checked the [origin/bugfix/non-latin-layouts] branch and I can confirm that the fix works in Russian layout, with additional keys in German layout, with Arabic layout.

But I realized that there are different layouts even for Russian Cyrillic.

And there are different layouts based on Cyrillic, for example Bulgarian (very different from Russian).
image
image

And there are variations like the Kazakh layout (mostly Russian Cyrillic, but there will be problems with the numeric row because there are extended Cyrillic characters there). [and the Kazakh layout will change because in this country they are switching from extended Cyrillic to extended Latin].

Perhaps a temporary solution would be better to add a panel where users can add matches (manually / from a template by language at least standard layout). I agree that this is a bad solution, but nothing better comes to mind.

I thought it was possible to write a generator of matches, but after looking at the KBD (Linux keyboard tools) repository, I realized that the style in which the layouts are written is very different. (You can check it)

Thank you so much for your hard work. This seems to be a really difficult challenge.

Yes, basically all solutions are bad in some way:

  • hardcoded mappings will always fail at some point considering how many different layouts are there, conflicts between them, and their specific quirks
  • new input system that operates on keys instead of characters would disallow to assign non-latin characters, as it's impossible to tell from which key it came
  • writing key remappers with GUI would take weeks/months and would just be very confusing feature for users
  • not activating shortcuts when layouts do not match would probably be the best solution, but I tried to code it and failed - I'm afraid I must rely on krita with key presses
  • using any key release for ending actions would solve the problem but make it impossible to use two shortcuts (like temporaty eraser and opacity) at the same time

I guess I'll have to merge current bugfix, knowing it won't be fully enough, and there will be some keys and layouts not fully working.

If I ever release version 2.0 (which allows to remove features), I think I would disallow to use multiple shortcuts at the same time, and use any key release to end all ongoing actions.

 yes i can proof that russian keyboard layout cause some problems even in Krita without plugins. 

{example: i prefer set popup menue, RMB menue [i think you understand what im talking about] as tilda button "~" but for some reason krita cannot detect it when i use rus layout and i also need place alternative key "Ё" and only after this its work}
but

sorry for clicking wrong buttons im not familiar with git. so returning to theme. I can proof that Krita even without plugins cannot detect buttons well--- for example i love call popup menue (RMB) with tilda button, but sometimes it doesnt work because i switch layout... i set all alternative keys for this function to make it work properly- "`" +"~" + "Ё" . Plugin.. sometimes it works smoth- no bugs, but some times this (all what was described before happens) and after reading your discus i think problem really hiding in different layouts. i use windows in english so programs displayed with english text, but where its possible i change it, If you need some tests from me as user i can help you . but it seems you know how to solve problem (and its required a lot of time to research and fix this)

I have a possible fix for this issue. You can check it out by downloading the plugin from this branch: https://github.com/wojtryb/Shortcut-Composer/tree/bugfix/non-latin-layouts

It should work regardless of the layout.

The problem is that it changes how the core functionality of my plugin works - now every key release ends every action. So, using two actions at once would feel different.

I'm not sure how to handle that tbh. I can't really keep the old functionality and fully fix this bug.

This issue is now fixed in 1.4.0.

Thanks everybody for your help.