TextInputCanvas does not propagate the KeyDown event

When a canvas has the keyboard focus, typing a character causes canvas.KeyDown to fire AND window.KeyDown

When a TextInputCanvas has the keyboard focus, typing a character causes only TextInputCanvas.KeyDown to fire but NOT window.KeyDown.

I need TextInputCanvas to behave the same as Canvas in this respect.

How can this be achieved?

I uploaded a demo of the issue here:
http://aspexsoftware.cachefly.net/temp/keydown_test.zip

From my experience you don’t want the TextInputCanvas to handle KeyDown events at all. In Formatted Text Control we don’t even implement the KeyDown event.

Understood. It is likely I also don’t need to handle TextInputCanvas.KeyDown.

But the problem is that TextInputCanvas having keyboard focus blocks Window.KeyDown from firing.

When I convert a canvas subclass into a TextInputCanvas subclass in order to take advantage of the Cocoa IME support, it prevents existing code in Window.KeyDown from running.

I need TextInputCanvas to allow KeyDown events to propagate to Window.KeyDown, in the same way that Canvas does this.

Any ideas?

I’d rethink that design as doing something in Windows.Keydown on EVERY keystroke can make your app slow
This is one of the things that was occurring in the IDE that I’ve gotten rid of over time

[quote=363268:@Thomas Sanham]Understood. It is likely I also don’t need to handle TextInputCanvas.KeyDown.

But the problem is that TextInputCanvas having keyboard focus blocks Window.KeyDown from firing.

When I convert a canvas subclass into a TextInputCanvas subclass in order to take advantage of the Cocoa IME support, it prevents existing code in Window.KeyDown from running.

I need TextInputCanvas to allow KeyDown events to propagate to Window.KeyDown, in the same way that Canvas does this.

Any ideas?[/quote]
Since that’s a plugin there’s not much you can do in Xojo code. But, you can talk to @Christian Schmitz from MBS to come up with a version that doesn’t fire the keydown event at all.

Thank you for the responses.

I have now found that InterpretKeyEvent in the TextInputCanvas plugin is returning true in this circumstance. Changing the code to return false from this method does cause the keypress to be propagated to the window.

You might not need to alter the sources at all
Implement the “key falls through” event on the existing text input canvas
Then you can selectively propagate keys

[quote=363447:@Norman Palardy]You might not need to alter the sources at all
Implement the “key falls through” event on the existing text input canvas
Then you can selectively propagate keys[/quote]

The Key Falls Through event doesn’t work. If you look at the plugin source it isn’t hooked up to anything.
I had a similar requirement (see https://forum.xojo.com/44549-textinputcanvas-how-to-receive-other-key-events/p1#p361933)
and ended up using the MBS NSEventMBS class to capture the key presses before they were passed to the TextInputCanvas.

Thanks again for responses.

I’d like to describe a related issue which I am hitting a brick wall on at the moment:

The canvas I am constructing is a ‘draw area’, which may contain any number of vector objects, some of which may be editable text shapes, and some of which may be other vector shapes (eg. square, circle, etc).

I need the IME candidate window to appear as necessary, but ONLY if an editable text shape is selected.

If some other shape is selected, I need the IME candidate window to never appear. But I still need to respond to keypresses in ‘KeyDown’ or equivalent, to implement features such as ‘press delete to delete shape’.

Unfortunately, I don’t seem to be able to programmatically tell the IME candidate window not to show upon a keypress, but still keep keyboard focus on the ‘draw area’ control. I am experiencing this issue when running the application on Win 10.

Does anyone know a way?

It might be easier to use the TextInputCanvas only when you want to edit text.

Use a standard canvas for your draw area and have a non-visible TextInputCanvas subclass which you position and make visible at the time of text editing. Once text editing has finished you simply make the TextInputCanvas subclass invisible again. You will probably have to pass data / state between the two classes and possibly copy some of your draw area into the TextInputCanvas so that visually, nothing looks different. This is the approach we used in Carbon builds when we interacted with the Text Services Manager and still use in Cocoa with the TextInputCanvas.

Alternatively, if you have the MBS plugins you can possibly use NSEventMBS to capture the keypresses before they reach the TextInputCanvas and do whatever you want with them.

This issue doesn’t ever appear to have been reported in feedback

Just logged it: 50752

From the textinputcanvas, if it’s required… one way to do this is to set up a hook on the application window handle with SetWindowHookEx and push the WM_KEYDOWN message when textinputcanvas.keydown is invoked. There’s equivalents for Mac which I believe the MBS plugins already have implemented in them. Or you can visit the git mirrored at

http://git./XojoDevelopersSpot/TextInputCanvas

And add the hook in, recompile the plug-in and replace your current version :slight_smile:

We already had a custom wndproc to handle windows IMM events so we just enhanced it to capture keydown events. On macOS we ended up using NSEventMBS.

Perfect! Glad everything is working with the workaround :slight_smile: