Re: [racket-users] GUI problem -- main window loosing focus when two dialog boxes are opened

2018-05-08 Thread Alex Harsanyi


On Wednesday, May 9, 2018 at 7:25:34 AM UTC+8, gneuner2 wrote:
>
>  
>
Ignoring Racket's extraneous added panels, a better organization would be:
>
> Window 00010010 "" #32769 (Desktop)
> :
> Window 0017076E "Hello World" PLTFrame
> Window 000F03D2 "Dialog 1" #32770 (Dialog)
> Window 00320BCC "Dialog 2" #32770 (Dialog)
> Window 003A052E "Close Dialog 2" PLTBUTTON
> Window 0057098A "Open Dialog 2..." PLTBUTTON
> Window 001807D4 "Close Dialog 1" PLTBUTTON
> Window 003704DA "Open Dialog 1..." PLTBUTTON
> :
>
> but it would work even if the dialogs were just siblings under the top 
> level frame [assuming their creation Z-order was correct]. 
>

I think the current window hierarchy is correct: I compared a similar setup 
in Visual Studio, where I opened two nested dialog boxes and inspected them 
with Spy++.  The dialog boxes are toplevel windows, same as for the Racket 
sample application I had.  The "OwnerWindow"of the dialogs is setup to 
point to the owner of the dialog boxes(i.e. the owner of Dialog 2 is Dialog 
1 and the owner of Dialog 1 is the main frame).  

As far as I can tell the window hierarchy for the main frame + two dialog 
boxes is the same in Racket as it is for Visual Studio...

Best Regards,
Alex.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] GUI problem -- main window loosing focus when two dialog boxes are opened

2018-05-08 Thread George Neuner

Hi Alex,

fwiw:  I tried with 32-bit 6.11 on Win7 and it messes up also.


On 5/8/2018 6:24 AM, Alex Harsanyi wrote:
I had a look at the application windows using Spy++ and all three 
windows (the main frame and the two dialog ones) are toplevel windows, 
as expected; however they are linked together as 
GetNextWindow/GetPreviousWindow correctly. Unfortunately, I am not 
very familiar with Windows GDI programming, but I will try to trace 
the messages to the windows themselves.


I now also have taken a look with Spy.  The problem is that the windows 
should NOT all be top level.  Per the code, dialog1 should be a child of 
the frame, and dialog2 a child of dialog1.


On my system, Spy shows:

Window 00010010 "" #32769 (Desktop)
    :
    Window 00320BCC "Dialog 2" #32770 (Dialog)
        Window 001E0C6C "" PLTPanel
            Window 00DF0854 "" PLTTabPanel
                Window 003A052E "Close Dialog 2" PLTBUTTON
    Window 000F03D2 "Dialog 1" #32770 (Dialog)
        Window 00370596 "" PLTPanel
            Window 001806EE "" PLTTabPanel
                Window 0057098A "Open Dialog 2..." PLTBUTTON
                Window 001807D4 "Close Dialog 1" PLTBUTTON
    Window 0017076E "Hello World" PLTFrame
        Window 00430564 "" PLTPanel
            Window 000B03F8 "" PLTTabPanel
                Window 003704DA "Open Dialog 1..." PLTBUTTON
    :

When the dialogs are "closed", they persist as hidden / deactivated windows.


With this organization the GDI  GetNextWindow()  function can't be 
relied on to find the right focus target.   It doesn't matter that the 
windows persist when not in use.  Nor does it really matter whether they 
have a parent and child relationship or are siblings [created in the 
right order].   But for  GetNextWindow()  to work properly, it *does* 
matter that they are top level and that there is no "root" application 
window that is the parent of all the others.



See: 
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633509(v=vs.85).aspx

The important part is right at the beginning:

   /If the specified window is a topmost window, the function searches
   for a topmost window. If the specified window is a top-level window,
   the function searches for a top-level window. If the specified
   window is a child window, the function searches for a child window./

The problem is: every application has at least one top level window.  If 
the Z-order gets disturbed - say by another application activating 
momentarily - or if  GetNextWindow()  searches in the wrong 
direction[*],  then a window belonging to another application may be found.
[*] searching next vs previous doesn't matter with only 2 choices, but 
it does matter with more and when extraneous choices are intermixed.


Also, the "topmost" part is a bit misleading:  WS_EX_TOPMOST is a window 
style intended for things that should *always* stay on top [of other 
same application windows] when visible.   It isn't used very often as 
there are other ways of keeping things visible: e.g., by using panels.  
And modal dialogs stay on top because their handler code won't permit 
switching to another [same application] window until the dialog is 
hidden / closed.




Ignoring Racket's extraneous added panels, a better organization would be:

Window 00010010 "" #32769 (Desktop)
    :
    Window 0017076E "Hello World" PLTFrame
    Window 000F03D2 "Dialog 1" #32770 (Dialog)
    Window 00320BCC "Dialog 2" #32770 (Dialog)
    Window 003A052E "Close Dialog 2" PLTBUTTON
    Window 0057098A "Open Dialog 2..." PLTBUTTON
    Window 001807D4 "Close Dialog 1" PLTBUTTON
    Window 003704DA "Open Dialog 1..." PLTBUTTON
    :

but it would work even if the dialogs were just siblings under the top 
level frame [assuming their creation Z-order was correct].




I'm not sure how to verify it at the moment, but my suspicion is that - 
on Windows at least - Racket somehow is searching wrongly with 
GetNextWindow().  That might be a simple fix.


Apart from that I don't see an easy work-around.  Maybe creating custom 
window class(es) that focus the parent explicitly when a window object 
is hidden or destroyed.   But right now I don't see a way to make it 
work using the stock gui objects .


It would best if the GDI object hierarchy accurately reflected the 
Racket object hierarchy, but that's probably a whole lot of work.


Sigh!,
George

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] GUI problem -- main window loosing focus when two dialog boxes are opened

2018-05-08 Thread James Platt
No problem on macOS 10.11.6 "El Capitan", Racket 6.10, or on macOS 10.13.4 
"High Sierra", Racket 6.12.


On May 7, 2018, at 8:46 PM, Alex Harsanyi wrote:

> I have a problem with the Racket GUI where the main application window looses
> focus if two dialog boxes are opened than closed.  The problem occurs when the
> main window opens the first dialog box and the first dialog box opens the
> second one on top of it.  Once both dialog boxes are closed, the main window
> looses focus and goes to the bottom of the window stack (i.e. behind other
> windows).  This does not seem to happen if only one dialog box is opened than
> closed -- in that case the main window will have the focus.
> 
> Could someone confirm if this behaviour is seen on other platforms (I use
> Windows), and perhaps offer a workaround?
> 
> I attached a sample application that illustrates the problem below and you can
> also find the code here:
> https://gist.github.com/alex-hhh/20b3f1000813677330bbd2b85c57d319
> 
> Too see the problem, this code needs to be compiled into a stand-alone
> executable (using the Racket/Create Executable... from DrRacket).
> 
> #lang racket
> (require racket/gui)
> 
> (define toplevel (new frame%
>   [label "Hello World"]
>   [width 800]
>   [height 600]))
> (define dialog-1 (new dialog%
>   [parent toplevel]
>   [label "Dialog 1"]
>   [width 400]
>   [height 300]))
> (define dialog-2 (new dialog%
>   [parent dialog-1]
>   [label "Dialog 2"]
>   [width 200]
>   [height 150]))
> 
> (define (on-open-dialog1 button event)
>   (send dialog-1 show #t))
> 
> (define (on-close-dialog1 button event)
>   (send dialog-1 show #f))
> 
> (define (on-open-dialog2 button event)
>   (send dialog-2 show #t))
> 
> (define (on-close-dialog2 button event)
>   (send dialog-2 show #f))
> 
> (define b1 (new button%
> [parent toplevel]
> [label "Open Dialog 1..."]
> [callback on-open-dialog1]))
> (define b2 (new button%
> [parent dialog-1]
> [label "Open Dialog 2..."]
> [callback on-open-dialog2]))
> (define b3 (new button%
> [parent dialog-1]
> [label "Close Dialog 1"]
> [callback on-close-dialog1]))
> (define b4 (new button%
> [parent dialog-2]
> [label "Close Dialog 2"]
> [callback on-close-dialog2]))
> 
> (send toplevel show #t)
> 
> Thanks,
> Alex.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] GUI problem -- main window loosing focus when two dialog boxes are opened

2018-05-08 Thread George Neuner

Hi Alex,

On 5/8/2018 6:24 AM, Alex Harsanyi wrote:


On Tuesday, May 8, 2018 at 2:08:02 PM UTC+8, gneuner2 wrote:


So I guess the 1st question to answer is: does the GDI object have
the
correct parent HWND?  [The Racket dialog% object has a parent, but
does
the underlying display object?]   If it does, there's something weird
going on in finding the right window to switch to.


I had a look at the application windows using Spy++ and all three 
windows (the main frame and the two dialog ones) are toplevel windows, 
as expected; however they are linked together as 
GetNextWindow/GetPreviousWindow correctly. Unfortunately, I am not 
very familiar with Windows GDI programming, but I will try to trace 
the messages to the windows themselves.


I'm not sure why exactly Racket creates "top level" windows everywhere 
[other than for the annoying issue that style WS_CHILD prevents a window 
from having a menu bar].  Maybe it's just terminology - i.e. it's not a 
WS_CHILD, so what do we call it?



Also, if I only open the first dialog, than close it, the main frame 
does not go to the bottom of the window stack...


Yes. I saw that.  It makes me wonder about how (or even if) Racket is 
using GetNextWindow.  Since the Racket objects form their own hierarchy, 
Racket could be walking *that* structure to find the window rather than 
letting GDI handle it.




Thanks for looking into this.


"Looking into" is perhaps too strong to describe what I did, but you're 
welcome. 




Alex.


George

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] GUI problem -- main window loosing focus when two dialog boxes are opened

2018-05-08 Thread Alex Harsanyi


On Tuesday, May 8, 2018 at 2:08:02 PM UTC+8, gneuner2 wrote:
>
> Hi Alex, 
>
>
> So I guess the 1st question to answer is: does the GDI object have the 
> correct parent HWND?  [The Racket dialog% object has a parent, but does 
> the underlying display object?]   If it does, there's something weird 
> going on in finding the right window to switch to. 
>

I had a look at the application windows using Spy++ and all three windows 
(the main frame and the two dialog ones) are toplevel windows, as expected; 
however they are linked together as GetNextWindow/GetPreviousWindow 
correctly.  Unfortunately, I am not very familiar with Windows GDI 
programming, but I will try to trace the messages to the windows themselves.

Also, if I only open the first dialog, than close it, the main frame does 
not go to the bottom of the window stack...

Thanks for looking into this.
Alex.

>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] GUI problem -- main window loosing focus when two dialog boxes are opened

2018-05-07 Thread George Neuner

Hi Alex,

On 5/7/2018 8:46 PM, Alex Harsanyi wrote:
I have a problem with the Racket GUI where the main application window 
looses
focus if two dialog boxes are opened than closed.  The problem occurs 
when the

main window opens the first dialog box and the first dialog box opens the
second one on top of it.  Once both dialog boxes are closed, the main 
window

looses focus and goes to the bottom of the window stack (i.e. behind other
windows).  This does not seem to happen if only one dialog box is 
opened than

closed -- in that case the main window will have the focus.

Could someone confirm if this behaviour is seen on other platforms (I use
Windows), and perhaps offer a workaround?


Using 6.11 (64-bit), it works fine on CentOS 6.9 with Gnome2 if that 
matters.   Fails as advertised on Win7.




... find the code here:
https://gist.github.com/alex-hhh/20b3f1000813677330bbd2b85c57d319

Too see the problem, this code needs to be compiled into a stand-alone
executable (using the Racket/Create Executable... from DrRacket).


Works the same running from DrRacket or as a separate executable.


I don't know what's happening in Racket, but I have seen some odd focus 
behavior in Windows when windows are improperly created (or improperly 
linked).



An application's windows normally form a tree by parent-child relation, 
rooted at a single top level frame.  But it is not an error to create a 
window that has no parent ... that is, in fact, how you get a top level 
frame.


The issue is that Windows doesn't maintain window Z-order per 
application ... all the windows on the desk, visible or not, are 
intermingled together on a single Z stack.  When the top window closes 
or becomes invisible, GetNextWindow() is called to find the next lower 
window to focus.  If the current window has no parent, GetNextWindow() 
searches only among (other) top level windows ... and then when the 
switch is made to whatever window it finds, you can end up in another 
application or back on the desktop itself.  So you need to make sure all 
your application's windows have appropriate parent-child relationships, 
or else changing focus can F_ up.


So I guess the 1st question to answer is: does the GDI object have the 
correct parent HWND?  [The Racket dialog% object has a parent, but does 
the underlying display object?]   If it does, there's something weird 
going on in finding the right window to switch to.



Sorry I can't be more help.  I have done quite a bit of Windows GUI 
programming, but unfortunately not very much using Racket.  I don't know 
how much it abstracts away from the GDI.


George

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.