Missing keyboard focus for TextCtrl under OS X

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
tobybear
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Sep 03, 2020 1:01 pm

Missing keyboard focus for TextCtrl under OS X

Post by tobybear »

Here is a rather special use case, maybe some of you know where to look.
I have a simple modal dialog with a text control that is being displayed on a button press in a plugin which is running inside Adobe After Effects.
All works fine except that some keys are intercepted by the host and are not delivered to the text control at all.
The weird thing is that this only happens when the flag wxTE_MULTILINE is set on the control.
If it is not set, all keys end up properly at my modal dialog while it is open.
I assumed since it is a modal dialog, it would always receive keypresses. The dialog itself is on top of all other windows and is modal, i.e. I can't click the app in the background once it is shown. On Windows systems, the problem does not occur, all is fine there.

I don't do anything fancy when creating the control, there are no connect() or event handlers, just this:
tc = new wxTextCtrl(this, ID_TEXT, wxT("TEXT"), wxPoint(-1, -1), wxSize(-1, -1), wxTE_MULTILINE | wxTE_DONTWRAP);
I have also read the WxMac specific topics and implemented TransformProcessType(&PSN, kProcessTransformToForegroundApplication);
Plugins are bundles per se, so that is also out of the question.

It is unclear to me why setting the mulitline flag changes something in the key event handling procedure.
In the wxWidgets sources I stumbled upon something in textdlgg.cpp:
// Do not pass style to GetParentForModalDialog() as wxDIALOG_NO_PARENT
// has the same numeric value as wxTE_MULTILINE and so attempting to create
// a dialog for editing multiline text would also prevent it from having a
// parent which is undesirable. As it is, we can't create a text entry
// dialog without a parent which is not ideal neither but is a much less
// important problem.
Could this be related to my problem?

System info:
wxWidgets: 3.1.4 (also tried with 3.1.3) -> target is Cocoa
MacOS X 10.11
Adobe After Effects CC 2020
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7478
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Missing keyboard focus for TextCtrl under OS X

Post by ONEEYEMAN »

Hi,
When you say "intercepted by the host" - do you mean those keys are received by the dialog or by the Adobe?
What do you do when this happens - i.e. is there a pattern of such behavior or it happens at any given moment with the random key?
What is your keyboard layout?

Thank you.
tobybear
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Sep 03, 2020 1:01 pm

Re: Missing keyboard focus for TextCtrl under OS X

Post by tobybear »

The behaviour is predictable/not random:
The main window of the Adobe application (unrelated to my piece of software or wxWidgets) will react to specific key presses by activating the actions associated with it. For example pressing the "u" key will open up the transformations menu, pressing the "," and "." keys will scroll throught the timeline, etc. Now when I open my modal wxWidgets dialog with the text control set to multiline, the key presses will still go to Adobe and be interpreted in the main window (even though it is inactive behind the modal dialog), and only keys that are not handled by Adobe are passed on to the wxWidgets dialog.
Which does for example mean that I can type in all the regular letters in my text control, except for "u", which when pressed triggers an action in the Adobe window instead. I do not receive any event in the wxWidgets dialog when the key "u" is pressed, even though my dialog has focus.
Removing the multiline flag from the text control and changing nothing else makes it all work fine, with all key presses being sent exclusively to the wxWidgets modal dialog.
I tested with US and German keyboard layouts, but I have reports from users all over the world experiencing the same issue.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7478
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Missing keyboard focus for TextCtrl under OS X

Post by ONEEYEMAN »

Hi,
This is weird.
Do you see the caret inside the text control?
Maybe you should call

Code: Select all

textCtrl->SetFocus();
?

Thank you.
tobybear
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Sep 03, 2020 1:01 pm

Re: Missing keyboard focus for TextCtrl under OS X

Post by tobybear »

Yes, the caret is visible in the control, and as I said, all other keys pass through fine.
I have also tried calling textCtrl->SetFocus() but it made no difference.

But now I have added two text controls on the same dialog, one with multiline enabled, one without it.
And funnily, the multiline one does not get the "u" key, but the one without it does (all within the same dialog).
I am currently doing some research in the wxWidgets sources (src/osx/cocoa/textctrl.mm) to see how the controls are actually set up.
And there is quite a difference in that they are different controls, depending on the multiline flag (if set, it is a wxNSTextScrollView, else a simple NSTextField). So I guess I will play around with the various MacOS specific options and parameters in these classes and try to find out the difference.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7478
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Missing keyboard focus for TextCtrl under OS X

Post by ONEEYEMAN »

Hi,
Do you handle any {key} events in the dialog?
Are you calling event.Skip() everywhere it is required?

Thank you.
tobybear
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Sep 03, 2020 1:01 pm

Re: Missing keyboard focus for TextCtrl under OS X

Post by tobybear »

No event handling in the dialog
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7478
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Missing keyboard focus for TextCtrl under OS X

Post by ONEEYEMAN »

Hi,
So you put just a wxDialog and no events in it? Just "OnOK()/OnCancel()"?
I presume you are testing with the debug version of the library and your application?
Did you build wxWidgets from the Terminal? With what configure options?
Is there any messages shown either on the console or the screen - assert or otherwise?

Thank you.
tobybear
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Sep 03, 2020 1:01 pm

Re: Missing keyboard focus for TextCtrl under OS X

Post by tobybear »

I have built the 3.1.3 and 3.1.4 using these commands:

Code: Select all

./configure --disable-shared
make
I tried to remove as much as possible from the dialog to keep possible intereference low. So yeah, basically nothing but a dialog class derived directly from wxDialog. Here is the minimal example I am currently testing it with:

Code: Select all

class TextDialog : public wxDialog {
public:
  TextDialog(const wxString& title, wxWindow* parent) : 
    wxDialog(parent, ID_DLG, title, wxDefaultPosition, wxSize(800, 500), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxSTAY_ON_TOP) {
      wxBoxSizer* box = new wxBoxSizer(wxHORIZONTAL);
      
      // this one works
      wxTextCtrl* tc = new wxTextCtrl(this, ID_TEXT, wxT("TEXT"), wxPoint(-1, -1), wxSize(-1, -1), wxTE_DONTWRAP);
      box->Add(tc, 1, wxEXPAND);
      
      // this one doesn't work
      wxTextCtrl* tc2 = new wxTextCtrl(this, ID_TEXT2, wxT("TEXT2"), wxPoint(-1, -1), wxSize(-1, -1), wxTE_MULTILINE | wxTE_DONTWRAP);
      box->Add(tc2, 1, wxEXPAND);
      
      SetSizer(box);
  }
};

// called in app like this:
	...
	TextDialog* dlg = new TextDialog(wxT("Test"), NULL);
	dlg->ShowModal();
	dlg->Destroy();
No failure/error messages to be seen while running.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7478
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Missing keyboard focus for TextCtrl under OS X

Post by ONEEYEMAN »

Hi,
Can you try with the:

Code: Select all

../configure --enable-debug
make
It will make a default debug build.

Maybe there is something happening when you type the key and debug build will help investigate it...

Thank you.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Missing keyboard focus for TextCtrl under OS X

Post by doublemax »

This is probably an issue specifically related to Adobe plugin development. My guess would be that the whole wxWidgets part needs to run in its own thread so that the event loop of the main application and wxWidgets' event loop don't conflict. The "dll" sample that comes with wxWidgets shows how to do it, but it's Windows specific.

I found this article that describes a workaround for text entry, i don't know if this is suitable for you:
https://community.adobe.com/t5/after-ef ... 196?page=1
Use the source, Luke!
tobybear
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Sep 03, 2020 1:01 pm

Re: Missing keyboard focus for TextCtrl under OS X

Post by tobybear »

doublemax wrote: Thu Sep 03, 2020 10:19 pm This is probably an issue specifically related to Adobe plugin development. My guess would be that the whole wxWidgets part needs to run in its own thread so that the event loop of the main application and wxWidgets' event loop don't conflict. The "dll" sample that comes with wxWidgets shows how to do it, but it's Windows specific.

I found this article that describes a workaround for text entry, i don't know if this is suitable for you:
https://community.adobe.com/t5/after-ef ... 196?page=1
Thanks. Yes, I know that article you linked to quite well, as it is me giving the correct answer there with the list of all possible solutions and workarounds.😁
I have been experimenting with this for quite some time and have always had good results with wxwidgets (since version 3.0+ at least) for text entry in Adobe products, since opening a modal dialog always seemed to create an own run loop independent of the main app. I tried various suggested workarounds from the wxwidgets community in the past, but with wxwidgets 3.0, it just worked out of the box. So it is not a problem of it not working generally.
I suspect the culprit being in the Objective-C code that wxwidgets uses to specifically create multiline text controls. I can have a dialog with lots of different type of controls, and they all receive key events correctly/exclusively when focused, except for the multiline control - all within the same dialog instance.
Or maybe it us a bug/feature in MacOS itself, wouldn't be the first quirk I encounter there.

I will try with a debug build and play with the .mm code to see if I can narrow it down.
tobybear
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Sep 03, 2020 1:01 pm

Re: Missing keyboard focus for TextCtrl under OS X

Post by tobybear »

Ok, so the debug build didn't yield any new information/errors.

For now, I implemented a wacky hack/workaround at the moment which kind of seems to work:
I now use the text control without multiline flag (so it gets based on NSTextField not NSTextView), which works fine concerning key input, but does not work with the enter key to create a new line.
In the source for the wxTextEntryFormatter in textctrl.mm, I therefore removed the line that replaces \n with a space.
Then in my actual dialog code, I set the wxTE_PROCESS_ENTER and connect the wxEVT_KEY_DOWN to a handler that when the enter key (code 13) is pressed, I manually insert a \n character at the current position of the cursor. Bam! - multiline text even in a NSTextField control!

This seems to work surprisingly good so far, but there might be other issues down the line, so I will do some more testing. And of course it is only an intermediate patch directly in the wxWidgets sources, so not future-proof.

The wxWidgets event handling seems to be quite special for NSTextView (or rather the surrounding wxNSTextView/wxNSTextViewControl), and notably different than for the single line wxNSTextFieldControl based on NSTextField, so I still there is some flag or command missing to make multiline work there as well, but at the moment I don't have the time to dig deeper.
tobybear
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Sep 03, 2020 1:01 pm

Re: Missing keyboard focus for TextCtrl under OS X

Post by tobybear »

Ok, so it is 2 years later and the issue still persists.
If a wxTextCtrl is created on MacOS with the wxTE_MULTILINE flag set, it gets based on a native MacOS "NSTextView", and if not a "NSTextField". However, "NSTextView" does not receive proper keyboard input when run as a plugin for example, making it rather useless the way it is implemented in wxWidgets.
My only solution (still) is to manually patch the wxWidgets sources to always create a "NSTextField" internally and then inject carriage returns manually by trapping the return key, but this is of course not a general solution.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Missing keyboard focus for TextCtrl under OS X

Post by doublemax »

I suggest to discuss this on the wx-users group https://groups.google.com/g/wx-users , or to open an issue at https://github.com/wxWidgets/wxWidgets/issues
Use the source, Luke!
Post Reply