I'm on Windows, but I see reports on the internet for Ubuntu too, they are 2012-2015, but perhaps still actual.
IIRC this is a GTK issue when the keyboard layout and locale don't match.
But hotkeys work in GIMP for me, it's a GTK 2 app too.
If you are talking about pre-defined keybindings try re-binding them. The same key combination may give a different code in different keyboard layouts IIUC and the default bindings are set for US international.
I think these might be related: https://github.com/geany/geany/issues/1286 https://github.com/geany/geany/issues/998
Yes, my case is exactly like #1286, Ctrl+C doesn't work, Ctrl+V works. But everything works at the program start and stops working randomly from time to time, like in #998. In contrast to other bugs I'm on Windows XP.
I've found a way to reliably reproduce it: - Open Geany (no tabs saved, an empty document is opened) - Switch to non-latin layout - Enter random text - Shift+left+left to select some letters - Ctrl+C - Press left or right arrow to deselect - Mouse clicks: Edit - Preferences - Keybindings - Cancel - Shift+left+left+left to select another letters - Ctrl+C - Ctrl+V
"another letters" are replaced by "some letters", second Ctrl+C is ignored
Which non-latin layout are you using?
Also when you go to the keybinding dialog, choose an unbound action and click change, type `ctrl+c` and post here what appears in the change dialog window, it is usually `<primary>c` (at least here :)
It's Russian layout, but the default language in the system is set to English (so I have to switch after the program is opened). It's <Primary>Cyrillic_es for Ctrl+C and <Primary>Cyrillic_em
Closed #1368.
Reopened #1368.
Well, Geany doesn't know anything about keyboard layouts, it just gets keycodes from GTK and compares them to the value set, and as you can see GTK is delivering different keycodes for the different layouts.
So there is not really anything in Geany to "fix".
I am not sure why ctrl+v continues to work, but the mapping of `v` varies between different Russian layout mappings as I understand, so GTK may be doing something "smart" there.
Note to be totally sure somebody who has your keyboard and locales would need to build Geany from source and uncomment `keybindings.c:1358` to see the raw keycodes. The codes shown in the keybindings dialog (like `<primary>c`) are generated by GTK, so it may be doing something smart with them as well.
Looks like this is it: https://bugzilla.gnome.org/show_bug.cgi?id=768722 https://bugzilla.gnome.org/show_bug.cgi?id=775163
How can I get the latest GTK dll? The one that comes with Geany - do you download it from somewhere or compile it yourself for each release?
https://wiki.geany.org/howtos/win32/msys2
See also https://github.com/geany/geany/commit/973a721574364f10995eb94a03e501e4c60c1d...
and https://github.com/geany/geany/commit/156c64b36cb0bed389c457629d5d5aad3ee845...
In case its not obvious, the windows build process has changed a lot recently and not all documentation will have kept up.
Aha, the dll is taken from MSYS2. Got the new version from here http://repo.msys2.org/mingw/i686/mingw-w64-i686-gtk2-2.24.31-1-any.pkg.tar.x.... It didn't fix the issue. So the patch wasn't shipped with this release, I suppose. I'll wait for the next one then.
The answer is that Windows XP support is broken upstream by the very patch that fixes this issue... So it should be fixed, but I won't be able to verify this, unless they restore XP support.
So, the current GTK2 package in the MSYS2 repository includes patches from the referenced bugs that should've fixed this issue. But they did not. Their author did a great job by fixing those bugs and also devoted some time to [investigating this issue](https://bugzilla.gnome.org/show_bug.cgi?id=768722#c50) with Geany. It is clear to me now that this is not a GTK problem, but a broken Geany implementation. I'll explain.
Geany hotkeys are handled in two places:
First, they are manually handled in `on_key_press_event()`, and this is the part that is implemented wrong, it checks for layout-dependent `event->keyval`.
Then, if a hotkey is not detected there, the handling goes to GTK's menu accelerators, and this is the part, why it sometimes work, because some hotkeys are bound to menu items, and GTK implements hotkeys right, in layout-independent way, so bound hotkeys work, but with some specifics: they work only when the item that corresponds to the hotkey is not grayed out (disabled). And when you open the Edit menu, Geany decides to enable or disable the Copy Ctrl+C menu item based on the existence of any selection in the textarea. You open the Edit menu when nothing is selected - Ctrl+C stops working, you select something and open the menu - Ctrl+C works again. This explains why it reproduces "randomly". Another confirmation of this theory was to find a hotkey that is not bound to a menu item, I found "Go to matching brace" <Primary>b, and indeed, it doesn't work in an alternative layout, and if I change the hotkey to the same key in an alternative layout, it stops working in English layout.
Now, when everything is clear, I hope you'll find some time to fix this.
First, they are manually handled in on_key_press_event(), and this is the part that is implemented wrong, it checks for layout-dependent event->keyval.
But as the GTK issue also says, it can't do anything else. "I'm not sure what the right thing here is. Matching hardware codes directly is not feasible, as these seem to be hardware-dependent. GDK can do that, because GDK has access to all keyboard layouts and is able to check whether current key event matches in a different layout. Geany can't."
The lucky fact that GTK's keybindings acted as a backup was purely good fortune, and suitably confusing to the debugging. Definitely kudos to you and the GTK guys who debugged it.
Unfortunately that fallback will not work for all keys, and as the GTK folks noted, Geany can't do anything about it since it doesn't have sufficient information.
So irrespective of finding time and somebody to fix it , it doesn't seem to actually have a fix.
That was why I suggested in comment 4 you re-bind the action after switching to the alternate keyboard layout.
Note that the rebound keybindings are saved in the Geany configuration, and you can specify a configuration directory with the `-c` option. So it would be possible to have two different configurations, one for each layout. You might even be able to run them both at the same time :)
Could you please inspect how it is done in, say, GIMP, and do it in the same way?
Geany is open source software, worked on by volunteers, if somebody wishes to do it, pull requests are welcome.
A quick look at the Gimp docs suggests it delegates the entire keybinding process to GTK. It would be a significant change for Geany to do the same. Also Gimp supports only GTK2, whereas Geany supports both GTK2 and GTK3. I'm not sure if the facilities are the same in both.
It is not Windows-specific, [the same thing happens](https://bugzilla.gnome.org/show_bug.cgi?id=768722#c55) using the X11 backend. Not surprising, actually, considering it isn't a GTK bug, but now feel free to adjust the labels.
Done.
As far as my issues search goes this hasn't been reported before, so its probable that the comment in your link above is right, few people run Geany in a locale that changes the ASCII keys. In fact many people with non-english locales specifically run just Geany in an english locale because most programming languages are english based.
As far as my issues search goes this hasn't been reported before...
The two issues I linked to above seem to be having the same problem.
I see these methods to fix this bug:
- Use undocumented GtkKeyHash, this is what powers GTK accelerators internally: [header](https://github.com/GNOME/gtk/blob/master/gtk/gtkkeyhash.h), [source](https://github.com/GNOME/gtk/blob/master/gtk/gtkkeyhash.c), [example](https://github.com/GNOME/gtk/blob/ab051fd53f8176665c36620a1616014e4c9a59df/g...).
- Add missing hotkeys to the AccelGroup and drop the custom hotkey handling in on_key_press_event.
- Remake all hotkey handling using [Accelerator Maps](https://developer.gnome.org/gtk2/stable/gtk2-Accelerator-Maps.html).
- Remake all hotkey handling using [Bindings](https://developer.gnome.org/gtk2/stable/gtk2-Bindings.html).
If nothing of these is planned for the next release, I suggest to stop enabling-disabling cut/copy actions on the Edit menu opening. It can be easily done by commenting out [ui_update_menu_copy_items](https://github.com/geany/geany/blob/65988f51f0634d29d4454602f367f03f925fc6d2...) and doesn't lead to any problems, only visually the menu entries will be enabled all the time. This won't make unbound hotkeys like "Go to matching brace" <Primary>b usable in non-Latin layouts, but will at least fix the confusing Ctrl+X, Ctrl+C behavior.
Use undocumented GtkKeyHash, this is what powers GTK accelerators internally: header, source, example.
Its unlikely that making Geany depend on undocumented internals of GTK will be accepted.
Add missing hotkeys to the AccelGroup and drop the custom hotkey handling in on_key_press_event.
Remake all hotkey handling using Accelerator Maps.
These require the accelerator to have a menu item to map to, whilst I personally think thats a fine goal, at the moment its not the case in Geany, nor in plugins. Also any change would have to maintain the current plugin interface.
Also one of the contributors had a first look at accelerators and came upon the stumbling block that they only allow one closure per binding, not sure if they found any workaround to that.
Remake all hotkey handling using Bindings.
Its not clear how the keybinding UI would work with keybinding files, there does not seem to be a way to load, parse and save the files.
Any of the above appear to require significant changes to Geany and plugins and certainly will not happen quickly, or at all if there is no interest in providing the effort. Geany is volunteer developed software and nobody can be instructed/tasked/forced to do anything.
I suggest to stop enabling-disabling cut/copy actions on the Edit menu opening. It can be easily done by commenting out ui_update_menu_copy_items and doesn't lead to any problems, only visually the menu entries will be enabled all the time.
Downgrading the UI for everybody in favour of a small number of users is not an acceptable approach IMHO.
You have not yet shown why the suggested workaround (rebind the problem keys for the new keyboard layout and if you use both layouts have separate configuration directories for each (-c option)) does not work, so implementing major changes or UI downgrades for everybody is inappropriate at this point. .
Use undocumented GtkKeyHash
Its unlikely that making Geany depend on undocumented internals of GTK will be accepted.
It is almost an independent module, it doesn't seem to be interconnected with other GTK internals. If it'll ever be removed (I highly doubt it will), you can copy the latest available version and it'll continue to work locally.
Add missing hotkeys to the AccelGroup and drop the custom hotkey handling in on_key_press_event.
Remake all hotkey handling using Accelerator Maps.
These require the accelerator to have a menu item to map to
No, they do not. Here's an example from [there](https://stackoverflow.com/a/19793067), tested on a hello world application without a menu: ``` GtkAccelGroup *accel_group = gtk_accel_group_new (); gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); gtk_accel_group_connect (accel_group, GDK_KEY_Q, GDK_CONTROL_MASK, 0, g_cclosure_new_swap (G_CALLBACK (hello), window, NULL)); ```
Also one of the contributors had a first look at accelerators and came upon the stumbling block that they only allow one closure per binding, not sure if they found any workaround to that.
I don't get it, what is the problem here? Does current implementation allow to have multiple actions set for one hotkey?
Any of the above appear to require significant changes
I agree about total remakes, but the approach with accelerators doesn't require many changes in my view. As for GtkKeyHash, it can even be integrated in the current architecture, the only things to do is to add hotkeys to it at the program start and keep it synchronized whenever user changes them. Then an easy lookup in the current key press event handler.
I suggest to stop enabling-disabling cut/copy actions on the Edit menu opening ... visually the menu entries will be enabled all the time.
Downgrading the UI
Sorry, but who will really even notice that particular change?
in favour of a small number of users
Are you serious? Surely you don't want to say there isn't many people who use non-Latin alphabet. But it is less likely they're able to report bugs in English, yet you already have two other opened issues about this.
You have not yet shown why the suggested workaround (rebind the problem keys for the new keyboard layout and if you use both layouts have separate configuration directories for each (-c option)) does not work
If I understand you correctly, you suggest to create two independent configurations, and then run two program copies for working with each layout. You don't have an alternative layout yourself, do you? This "workaround" just isn't viable. Usually you switch layouts at runtime, this is a part of the working process: non-Latin documents can easily contain Latin abbreviations, programming languages are Latin, but the code can contain Unicode literals or comments in non-Latin, HTML code is especially highly mixed.
It is almost an independent module, it doesn't seem to be interconnected with other GTK internals. If it'll ever be removed (I highly doubt it will), you can copy the latest available version and it'll continue to work locally.
Nor is it likely that Geany will support a fork of an internal part of GTK.
Also one of the contributors had a first look at accelerators and came upon the stumbling block that they only allow one closure per binding, not sure if they found any workaround to that.
I don't get it, what is the problem here? Does current implementation allow to have multiple actions set for one hotkey?
I havn't discussed it with them, but my expectation is that several things (Geany and Scintilla) and an unknown number in plugins connect to the keyevent signal. So plugins can override Geany and Scintilla is a fallback for Geany. Not sure how the accelerators code fits into this.
Downgrading the UI
Sorry, but who will really even notice that particular change?
Since the keybinding activates the menu making it inactive is what stops it trying to copy when there is nothing selected. And while you may understand that, there are many inexperienced users of Geany.
I agree about total remakes, but the approach with accelerators doesn't require many changes in my view.
Pull requests are welcome, though I suggest you announce a Gtihub fork where you will be doing the work so people can watch and contribute as you go, rather than just dropping a commit bomb when you have finished.
Note, I am not a fan of the current keybinding implementation, and have ranted about it in the past, but I am even less a fan of major changes to stable codebases.
Are you serious? Surely you don't want to say there isn't many people who use non-Latin alphabet. But it is less likely they're able to report bugs in English, yet you already have two other opened issues about this.
Acknowledge the issue that its difficult for non-English users to be noticed on a purely English project, but unfortunately its also all anybody has to judge the relative usage.
You don't have an alternative layout yourself, do you?
Correct, but the problem is not just an alternative layout, but the alternative has to change the keyval for the same key. It is also why I can't do anything about testing this. That is also the case for many if not all other contributors (some do use multiple languages, but for them c is still c not for example Cyrillic_es), if it was a problem for them it would have been raised before this.
@Forkest first thing, thanks a lot for the time and effort you put into this, which lead to understanding the issue a lot better, that's awesome. Same goes to LRN.
@elextr
Also one of the contributors had a first look at accelerators and came upon the stumbling block that they only allow one closure per binding, not sure if they found any workaround to that.
Well. Actually, do we even need that? I mean, I don't see any actual use for binding more than one think to the same key from the user point of view: there is no way for the user to know when which would be activated, it solely depends on how the handler is implemented, and nothing exposes that to the user. So if it's a mere internal, we could likely just have an internal handler list we activate in order when the "single" keybinding handler is called. If we really do need this multi-handler thing in the first place.
Yes, the issue here is really not trivial, because keybinding handling in Geany has a fair share of subtleties (not to say "weirdness"), but some are important (like the VTE part). But, just as you are, I'm not very fond of Geany's keybinding handling. I'm not either fond of changing something so fundamental when it works; but apparently it's actually not working properly.
So IMO we should consider the two possible solutions: fix our code (if that's even doable), or switch to the "proper" GTK methods for handling keybindings.
Since the keybinding activates the menu making it inactive is what stops it trying to copy when there is nothing selected. And while you may understand that, there are many inexperienced users of Geany.
Not really: Geany's custom keybinding handling will not consider the menu sensitiveness, and all handlers are guarded appropriately. And well, in this case it's not guarded, but it's not useful: copy/cut just doesn't do anything when there's no selection. Currently items sensitiveness is just a display thing. Important for the UI POV, but not for the internal logic one.
So if it's a mere internal, we could likely just have an internal handler list we activate in order when the "single" keybinding handler is called.
@b4n, sure we can re-implement signals yet again :) I didn't get to ask @kugel- what his problem was, but my thought was how some things fall back to Scintilla, but those could always be "upgraded" to Geany (but only if the manual is upgraded as well :)
The problem was that GTK accelators don't allow for chaining handlers. We make little of it, but more importantly plugins can use it to enhance core binding, based on the programming language.
plugins can use it to enhance core binding, based on the programming language.
Can they? Currently I'm afraid Geany's internal ones run before, so they can't override them conditionally. And if that's it, we could keep the current API and internally chain handlers, like I said, can't we?
I'm not either fond of changing something so fundamental when it works; but apparently it's actually not working properly.
Thanks for understanding the importance of this bug.
I'd like to explain a bit more about the situation here, how it all works.
On key press we have two variables: keyval and hardware_keycode. keyval is the entered symbol, hardware_keycode is the pressed physical key, looks simple. If we were parsing input, we'd convert keyval integer to unicode character and use it, simple too. Since here we are looking for hotkeys, we should check the physical key. Ok then, let's compare hardware_keycode with... what? With GDK_KEY_A? No, it is a keyval. Do we have an equivalent keycode constant? No, we don't. At least not in GDK. If we're on Windows, we can compare with VK_A, on Mac we can compare with kVK_ANSI_A, and it will be the same key A (actually, only in QWERTY layout, but that's another story). On X11 keycodes are hardware/driver dependent, one keysym (keyval in X11 terms) may correspond to multiple keycodes. GDK doesn't abstract from us the keycodes given by the system. Although I think it would be great to have GDK Virtual Key Codes, there are none. hardware_keycode is a raw value that is different between platforms and even can change at runtime.
GDK handles this keyval-keycode matching via GdkKeyHash, it is used internally in accelerators and bindings.
Although it is undocumented, in my opinion it is the simplest way to fix the issue. Just fill the hash on start with a hotkey's keyval as a key and with a pointer to GeanyKeyBinding as a value, modify when user changes a hotkey, match the key in on_key_press by a simple lookup call.
If it'll be decided against direct GdkKeyHash use, then to reimplement it on top of the current Geany hotkey handling you'll need to add an array of hardware_keycodes to the GeanyKeyBinding struct, fill it using gdk_keymap_get_entries_for_keyval on start, free and refill it on keys-changed signal and when user changes a hotkey, then modify on_key_press handler to check hardware_keycodes instead of a keyval (use GdkKeyHash as a reference).
If somebody is ready to do some refactoring, moving all handling to accelerators or bindings is the way to go. I'd like to add that menu mnemonics take precedence over accelerators, so it won't be possible by default to override Alt+S and other menu items mnemonics, like it can be done currently, but it should be possible to override this behavior by using gtk_accel_group_activate on key press.
@Forkest thanks for the patch, see with enough challenging you can explain the issue clearly, why the suggested workaround doesn't work for your use-case, and provide a better workaround :)
Commenting do not work for me at all (v. 1.33.0-2 /Manjaro) layout: german / russian
Hotkey function do not works as well as the menu-items.
github-comments@lists.geany.org