Backend <-> GUI Library Interaction
Hi There are outstanding issues with the windows backend related to window management. I believe some of these can be fixed by responding to certain Win32 window messages that MSWindows posts out. I am referring to the problems with window layering/levels/ordering and related focus issues that seem to affect everything from windows going missing to modal windows playing up. There are some methods which appear in GSDisplayServer that appear to relate to these things. Without checking in detail what gnustep-gui does, could I get some clarifications on how the following methods work in response to certain inputs/outputs. - (void) orderwindow: (int) op : (int) otherWin : (int) winNum This one does appears to do window ordering (to state the bleedingly obvious). Obviously when a window is ordered it should obey the window level that is set. Take a hypothetical situation with three windows: A - window level 0 B - window level 50 C - window level 0 C is above A. B is on top of A & C (in terms of Z-order). if orderwindow was called to place A on top of B, should it order A to the top of its window level (i.e. between C and B) or should it ignore the message? Say the reverse happened (orderwindow was called asking it to order a a lower level window above a higher level window), what should occur in that case? The backend currently does what gnustep-gui tells it to do, ignoring window layering. In the AppKit, there are two notifications, NSApplicationDidBecomeActiveNotification and its counterpart NSApplicationWillBecomeActiveNotification. Are these supposed to be sent through an application when one of it's windows is made "active" (i.e. becomes key)? Or is it when an application begins responding to event messages? - (void) setinputfocus: (int) winNum In GNUstep parlance there appear to be two things: a key window (which responds to keyboard events) and a main window. Is this correct? How exactly does a main window fit into the window focus equation? Is setinputfocus: supposed to main a window "key"? If a window is not to become the key window (e.g. some floating palette windows), does gnustep-gui take messages from the backend that the window was made the key window, and respond by making another window the key window? Win32 provides some window messages such as WM_ACTIVATE (a window in an application was given/lost the keyboard focus), WM_ACTIVATEAPP (your application itself lost/gained the keyboard focus) and WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED (called for a litany of window resize/move/focus/Z-order events where the outcome can be "adjusted"). I think these could help. Does anyone have some guidance on this matter? I would like to start investigating some fixes so that perhaps I could get this working on Windows properly. Cheers Chris -- Christopher Armstrong [EMAIL PROTECTED] ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: Backend <-> GUI Library Interaction
Hi Christopher, Nice to hear from you... Christopher Armstrong wrote: There are outstanding issues with the windows backend related to window management. I believe some of these can be fixed by responding to certain Win32 window messages that MSWindows posts out. I am referring to the problems with window layering/levels/ordering and related focus issues that seem to affect everything from windows going missing to modal windows playing up. Not to mention the click twice to edit problem ;) There are some methods which appear in GSDisplayServer that appear to relate to these things. Without checking in detail what gnustep-gui does, could I get some clarifications on how the following methods work in response to certain inputs/outputs. - (void) orderwindow: (int) op : (int) otherWin : (int) winNum This one does appears to do window ordering (to state the bleedingly obvious). Obviously when a window is ordered it should obey the window level that is set. It should order self relative to otherWin according to op (NSWindowAbove, NSWindowBelow etc), staying within it's level. Take a hypothetical situation with three windows: A - window level 0 B - window level 50 C - window level 0 C is above A. B is on top of A & C (in terms of Z-order). So we have B-C-A (z-order front to back) if orderwindow was called to place A on top of B, should it order A to the top of its window level (i.e. between C and B) or should it ignore the message? I'm not sure what Cocoa does and it would be best to behave compatibly. That said, I think it should reposition itself to the top of its level so we'd get B-A-C Say the reverse happened (orderwindow was called asking it to order a a lower level window above a higher level window), what should occur in that case? The backend currently does what gnustep-gui tells it to do, ignoring window layering. That is wrong. Layering should be respected at all times. In the AppKit, there are two notifications, NSApplicationDidBecomeActiveNotification and its counterpart NSApplicationWillBecomeActiveNotification. Are these supposed to be sent through an application when one of it's windows is made "active" (i.e. becomes key)? Or is it when an application begins responding to event messages? ?? we have NSApplicationDidBecomeKeyNotification and NSApplicationDidBecomeMainNotification Do don't have NSApplicationDidBecomeActiveNotification - (void) setinputfocus: (int) winNum In GNUstep parlance there appear to be two things: a key window (which responds to keyboard events) and a main window. Is this correct? How exactly does a main window fit into the window focus equation? Is setinputfocus: supposed to main a window "key"? If a window is not to become the key window (e.g. some floating palette windows), does gnustep-gui take messages from the backend that the window was made the key window, and respond by making another window the key window? setinputfocus: sets focus to the window so it will receive key events. This is the X11 idea of focus, by the way. So on windows it makes the window active. The main window has a responder chain to processes the menu etc. So if you have a floating palette it can become 'key' but will never be 'main'. Win32 provides some window messages such as WM_ACTIVATE (a window in an application was given/lost the keyboard focus), WM_ACTIVATEAPP (your application itself lost/gained the keyboard focus) and WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED (called for a litany of window resize/move/focus/Z-order events where the outcome can be "adjusted"). I think these could help. Probably, although correcting calls to SetWindowPos() should fix the vast majority of problems. Does anyone have some guidance on this matter? I would like to start investigating some fixes so that perhaps I could get this working on Windows properly. Great. Regards, Sheldon ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: Backend <-> GUI Library Interaction
On 7 Nov 2006, at 00:55, Christopher Armstrong wrote: Hi On Mon, 6 Nov 2006 12:16:49 +, "Richard Frith-Macdonald" <[EMAIL PROTECTED]> said: Neither ... it should set it's level to be 50 and then place A immediately above B That's interesting, I thought the only way a window could change window levels was by the setwindowlevel: message. I thought the same until I checked. The documentation suggested that behavior but was not completely explicit, so I looked at the X backend code to confirm it. The other interpretation (that ordering of windows relative to each other only worked for windows in the same level) seems a bit more intuitive to me. It actually might be worth checking what MacOS-X actually does, and consider changing the GNUstep behavior if it does it the other way. In the AppKit, there are two notifications, NSApplicationDidBecomeActiveNotification and its counterpart NSApplicationWillBecomeActiveNotification. Are these supposed to be sent through an application when one of it's windows is made "active" (i.e. becomes key)? Or is it when an application begins responding to event messages? They should be set when the app becomes active/inactive ... ie at the point when it displays/hides its menus and panels. So, if an app is inactive, and you click on any of its windows making that window key, you will also be making the app active and the notification would be sent, but if the app is already active and you click on a different window, changing it to be key, then the notification is not sent. I note there appears to be no private AppKit events defined in NSEvent.h for these nor could I find any instance in gnustep-gui when these are actually sent. Are they currently being used? I would imagine that they would be used by an application when a user cycles between apps running on a system e.g. I was using the Mac's at uni the other day, and I opened up Terminal with a main window (a terminal) and a font panel. When I switched to another application, the font panel disappeared. When I switched back, the font panel reappeared. I'll have to check the behaviour of some of these apps on Linux. There is GSAppKitWindowFocusIn to tell the gui when a window is given focus. This is really a hack to cope with X ... since what the gui really wants to see is a mouse click in the window. The notifications are sent by NSApplication ... the backend doesn't need to do that ... it could call the NSApplication activateignoringOtherApps: method to activate the app, but activation is probably done implicitly (ie the backend tells the gui that a window has been given focus, and the gui noticing that it is inactive but has just had a window become key, changes to become active. When focus leaves a window without being given to another window of the app first, the backend tells the application to deactivate itsself. Should I add some events to gnustep-gui which notify the frontend of these changes, or should I just post the notifications myself from the backend? You don't need to do anything ... the NSApplication will post the notifications. Win32 provides some window messages such as WM_ACTIVATE (a window in an application was given/lost the keyboard focus), WM_ACTIVATEAPP (your application itself lost/gained the keyboard focus) and WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED (called for a litany of window resize/move/focus/Z-order events where the outcome can be "adjusted"). I think these could help. It sounds like WM_ACTIVATEAPP should trigger app activation and WM_ACTIVATE should tell the app to change the key window and the others should do window movement ... I would have thought that the win32 backend was already using these in some way ... I guess not optimally though. Actually, not really at all. They are stubbed out though for "future implementations". Only some more basic events appear to be handled. Perhaps they are not needed because other events provide the same information implicitly? For instance, WM_ACTIVATEAPP would be equivalent to a focus in event for the key wndow, However, I would have thought that WM_ACTIVATE was necessary ... unless windows always sends a mouse click event when focus goes to a window. If it always sends a mouse click then nothing else should be necessary as the receipt of the mouse click should let the gui make the window key. There was another case I also forgot to mention. I believe NSPanel can be inherited and its windows prevented from becoming "key" and becoming "main". How does gnustep-gui expect the backend to handle this? I'm presuming it just resets the keyboard input focus if a window tries to become key, or does it expect the backend to prevent this situation? IIRC is done in the gui at present ... if focus is given to something which shouldn't have it, the gui resets focus to the key window. I guess the backend could do the same thing without ever bothering the g
Re: Backend <-> GUI Library Interaction
Richard Frith-Macdonald wrote: On 7 Nov 2006, at 08:11, Christopher Armstrong wrote: Hi Richard Frith-Macdonald wrote: That's interesting, I thought the only way a window could change window levels was by the setwindowlevel: message. I thought the same until I checked. The documentation suggested that behavior but was not completely explicit, so I looked at the X backend code to confirm it. The other interpretation (that ordering of windows relative to each other only worked for windows in the same level) seems a bit more intuitive to me. It actually might be worth checking what MacOS-X actually does, and consider changing the GNUstep behavior if it does it the other way. There seems to be a little debate about this one (re: message from Sheldon Gill). I'll have to dig a bit deeper on this, but I think the MacOSX notes are ambigious too (IIRC). Well, in answering your question about the gui/backend interaction in GNUstep, Sheldon has just said how he thinks it *should* behave rather than how it *does* behave. If you want to 'fix' the windows backend to work better with the gui now, you need to implement the actual behavior rather than a potential future behavior. However, his idea of how it should behave is perfectly reasonable ... and I would probably support moving to it if (and only if) it's the way MacOS-X behaves ... once we have checked what the impact/breakage of changing behavior would be and if we got consensus/majority in favour of changing. Perhaps very few apps actually depend upon the existing behavior and changing would be pretty painless. I did a quick check against the old orderwindow operator for OpenStep (the docs for www.toodarkpark.org). Whilst not explicit, it does say that when orderwindow is called to order a window relative to another one, that this operation should be followed. Implicitly, the window level would change when it is called in this matter. It would not change when the user simply switches to it. MacOS X seems to concur in the same ambiguous fashion. A window that is ordered relative to another (via NSWindow's -orderWindow:relativeTo:), it seems to imply (it doesn't say) that the window should be moved immediately above/below this window. It also mentions the relative window number being zero, in which case it moves the window to the top/bottom of that window level. The -orderFront:/-orderBack: methods explicitly mention the window level i.e. they order to the front or back of that window level. Therefore, I think the compatible or "correct" behaviour is being observed. I'm not sure about what should happen when an application is inactive though. An interesting snippet from the NSWindow docs is that a window is brought to the top of its window level when its window level is changed using -setLevel:. And damn, I've been forwarding the messages to the wrong mailing list. Oh well, I'll CC to both now. Thanks for your help on this; with a little effort I think it may be possible to emulate this window level stuff on Windows. I just hope there isn't too many race conditions and I'm not sure what I'll do about other application's windows. Cheers Chris ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev