Non-modal modal file dialog

Has anyone else noticed that occasionally an OpenFileDialog.ShowModal results in the focus and keyboard activity remaining on the window in the background? I’ve not bee able to track it down or reproduce it but it certainly seems to happen from time to time.

Xojo 2023r1.1, macOS 13.4

3 Likes

I have a similar issue with 2021r2.1 under the following circumstances:

  • Windows target.
  • In the MouseDown (or MouseUp) event of a Canvas on Window1, instantiate a Window2 and call a method on it that invokes Self.Showmodal.

No amount of ClearFocus/SetFocus seems to be able to set the focus to a TextField on WIndow2. User has to click on the TextField before text can be entered.

It does work with MacOS target.

1 Like

By the time that occurs, how would window2 know what parent it is modal to?
I’m curious why you don’t use

dim w as new window2
w.showmodal

in Window1

or, maybe add a constructor to Window2 where it takes the parent window as a parameter
(…im not sure what order would be best here)


Constructor (optional myParent as Window)
super.constructor
textfield1.setfocus // if not the default control ?
self.showmodalwithin myParent

Window2 doesn’t need to know what its “parent” is - it returns a string.

There are certainly multiple ways to do this, but in my case Window2 has ImplicitInstance set to true, and all I have to do in Window1 is

Answer = Window2.GetAnswer

But I think that’s probably irrelevant to the focus issue, especially as it works under MacOS but not under Windows.

1 Like

Maybe I misunderstand modal, then… I’ll not rule that out.

To me, one window is modal to a parent window, which it (should) effectively disable until the modal window is closed.
It’s not just a ‘show this window until it is closed’ thing, is it?

Yes, it is. It’s an age-old technique for getting a string from user input.

The GetAnswer method of Window2 is basically

me.ShowModal
Return TheAnswer // TheAnswer is a property of Window2

Window2 has an “OK” button and a Cancel button. The OK button’s Action handler is

TheAnswer = TextField1.Text
self.Close

and the Cancel button’s handler is

self.close

The calling code recognizes cancellation if the returned string is “”.

Note one shouldn’t implement GetAnswer as

me.showModal
Return TextField1.Text

because it’s very likely the TextField will be nil at that point.

As interesting as this is it’s not really my issue. For me simple code like this:

Var oFileOpen As New OpenFileDialog
// configure
Return oFileOpen.ShowModal

Has been providing a window that is allowing character entry and keyboard events on a window in the background.

What happens if you have a Module method as Follows:

Function GetAnswer( oWindow as DesktopWindow ) as String
   Return oWindow.ShowModal.GetAnswer
End Function

// Calling it as:
Answer = GetAnswer( Window2 )

Does that solve your issue?

Oh. You said

Which is what I see as well, albeit with my own modal dialog window rather than your OpenFileDialog. But if you think my case is irrelevant to yours, feel free to ignore. Just thought it might help.

No.

1 Like

The title says “non modal modal file dialog”.

Also, I’m not calling it from within the window that is being opened in a modal way, which could be part of your issue.

If I’m reading your issue correctly you are not getting the focus in the place you want on Window2?

I’m getting the focus on the window in the background, not the wrong place within the freshly opened window.

You’re correct, our issues are unrelated. Thanks for inspiring me to look a little more closely, though - it turns out that a call to RemoteControlMBS.WinBringWindowToTop was preventing the TextField from getting the focus as expected :woman_shrugging:

Sorry if I wasted anyone’s time.

1 Like

Hardly a waste of time if it helped one of us solve a problem :slight_smile:

1 Like

I bet you handle the case where the user empties the text field :wink:

Input validation can of course be performed by the calling code as necessary, and I’ve never encountered a case where I needed to differentiate between the user clicking OK with the text field empty or clicking Cancel or entering text then clearing the text and then clicking OK. In the majority of cases I use my GetTextWindow for password input, so if the user clears the text field it’s simply an invalid password and the window does the “shake” thing.

Is that needed because showing the window in this way doesn’t always show it in front of the calling window?

It is not needed - apparently at some point in the past I thought it was, maybe trying to open it from another modal window and they ended up fighting for frontmost. When I abandoned that, I neglected to remove the MBS call, which I assumed was benign.