When OWB is running on a public screen, and then closes, it appears that it never calls CloseScreen(), and instead relies upon the "Open/close automatically" feature of Sys:Prefs/Screens...
... But this feature does not appear to work when a "foriegn" window (like a Ringhio notification) is temporarily present on that public screen. You would expect the public screen to automatically close when this foreign window closes, but this does not appear to be the case.
EDIT: Please note that this bug report is not quite correct, and I have revised it in Post #22
EDIT 2: It appears that both bugs have already been fixed, and so should be available in the next OS4 update!
Edited by ChrisH on 2011/6/16 19:26:19 Edited by ChrisH on 2011/6/18 12:32:39 Edited by ChrisH on 2011/6/18 12:33:14
I think that's actually a Ringhio bug. The last window on a public screen is responsible for closing it. On public screens an application should be attempting a CloseScreen() when it has finished on that screen.
AFAIK, anyway. You can't expect the application that opens a public screen to hang around in memory waiting to close it, if other apps are squatting.
(btw, I have downloaded and installed your litle patch)
Easy workaround is close that Ringhio window before closing your app.
Except that it is easy to forget (or not even notice the Ringhio notification).... not to mention this shouldn't be an issue in the first place for something as important to the Amiga as Screens.
@Chris So what does "Open/close automatically" do then? I thought it was a new feature for OS4.1, which automatically opened (and closed) public screens when you referred to them by name instead of using OpenScreen/CloseScreen (although I don't actually know how you would do that).
Quote:
btw, I have downloaded and installed your litle patch)
Please make sure to download version "r2", as this fixes problems with MPlayer amoung other things.
@ChrisH No public screen will close if there is a window open on it. It's a safety measure not a bug. What do you think would happen if a program rendered to a window on a screen that has closed? The screen closing is automatic in the sense that the last visitor window on a public screen doesn't need to explicitly close a screen when the window closes.
No public screen will close if there is a window open on it.
Of course not! That is not what I am claiming. Please re-read what I wrote. If it is still not clear, then I will explain again....
Quote:
The screen closing is automatic in the sense that the last visitor window on a public screen doesn't need to explicitly close a screen when the window closes.
The screen closing is automatic in the sense that the last visitor window on a public screen doesn't need to explicitly close a screen when the window closes.
This is NOT happening, hence my bug report.
Regardless of whether this is set or not, visitor windows should still be trying to close the public screen... I think. Otherwise you get the situation where the application that opened the screen initially has to stay in memory and loop trying to close it.
FUNCTION Prevents a public screen (or the Workbench) from closing while you examine it in preparation of opening a visitor window.
The sequence you use to open a visitor window that needs to examine fields in the screen it is about to open on is: LockPubScreen() ... examine fields ... OpenWindow() on public screen UnlockPubScreen() ... use your window ... CloseWindow()
NOTE You needn't hold the "pubscreen lock" for the duration that your window is opened. LockPubScreen() basically has the same effect as an open visitor window: it prevents the screen from being closed.
If you pass the string "Workbench" or you pass NULL and there is no default public screen, the Workbench screen will be automatically opened if it is not already present.
INPUTS name - name string for public screen or NULL for default public screen. The string "Workbench" indicates the Workbench screen.
RESULT screen - Returns pointer to a screen if successful or NULL. The call can fail for reasons including that the named public screen doesn't exist or is in private state.
Quote:
NAME CloseWindow -- Close an Intuition window.
SYNOPSIS CloseWindow( Window )
VOID CloseWindow( struct Window * );
FUNCTION Closes an Intuition window. Unlinks it from the system, deallocates its memory, and makes it disappear.
...
New for V36: If your window is a "Visitor Window" (see OpenWindow) CloseWindow will decrement the "visitor count" in the public screen on which the window was open. When the last visitor window is closed, a signal will be sent to the public screen task, if this was pre-arranged (see OpenScreen).
Quote:
NAME OpenWindow -- Open an Intuition window.
SYNOPSIS Window = OpenWindow( NewWindow )
struct Window *OpenWindow( struct NewWindow * );
FUNCTION
...
WA_PubScreenName - This tag item declares that you want your window to open as a visitor window on the public screen whose name is pointed to by (STRPTR) ti_Data.
WA_PubScreen - Open as a visitor window on the public screen whose address if provided as (struct Screen *) ti_Data. To ensure that this screen remains open long enough, you must either: 1) Be the screen's owner 2) have another window already open on the screen 3) use LockPubScreen() Using exec.library/Forbid() is not sufficient.
You can provide ti_Data to be NULL (zero), without any of the above precautions, to specify the default public screen.
WA_PubScreenFallBack - This Boolean attribute specifies that a visitor window should "fall back" to opening on the default public screen if the explicitly specify public screen is not available.
...
NOTES Regarding Public Screens, you can specify a window to be a "visitor window" on a public screen in one of several ways. In each case, you must be sure not to specify a NewWindow type of CUSTOMSCREEN. You should use the value PUBLICSCREEN.
There are actually several ways you can specify which screen you want a visitor window to be opened on:
1) Specify the name of the public screen WA_PubScreenName, or a NULL pointer, in ti_Data. The name might have been provided by the user. A NULL pointer means to use the default public screen.
If the named screen cannot be found, the default public screen will be used if the Boolean attribute WA_PubScreenFallBack is TRUE.
2) Specify a pointer to a public screen using the WA_PubScreen tag item. The WA_PubScreenFallBack attribute has no effect. You can specify the default public screen by providing a NULL pointer.
You can also specify the pointer by setting NewWindow.Type to PUBLICSCREEN, and specifying the public screen pointer in NewWindow.Screen. The WA_PubScreen tag item has precedent over this technique.
Unless NULL, the screen pointer provided MUST be a valid public screen. You may ensure this several ways:
- Be the owner of the screen. - Have a window already open on the screen. - Use LockPubScreen() to prevent the screen from closing. - specifying the WFLG_VISITOR bit in NewWindow.Flags is not supported.
It is anticipated that the last will be the most common method of opening public screens because you often want to examine properties of the screen your window will be using in order to compensate for differences in dimension, depth, and font.
The standard sequence for this method is as follows: LockPubScreen() - obtain a pointer and a promise layout window - adapt your window to the screen you will use OpenWindow() - using the pointer you specify UnlockPubScreen() - once your window is open, you can let go of the lock on the public screen ... normal window even processing ... CloseWindow().
The following two tag items specify the task and signal to be issued to notify when the last "visitor" window closes on a public screen. This support is to assist envisioned public screen manager programs.
SA_PubTask: Task to be signalled. If absent (and SA_PubSig is valid), use the task which called OpenScreen() or OpenScreenTagList()).
SA_PubSig: Data is a UBYTE signal number (not flag) used to notify a task when the last visitor window closes on a public screen.[b]
...
[b]A_ErrorCode: ti_Data points to a ULONG in which Intuition will stick an extended error code if OpenScreen[TagList]() fails. Values are of this include 0, for success, and: OSERR_NOMONITOR - monitor for display mode not available. OSERR_NOCHIPS - you need newer custom chips for display mode. OSERR_NOMEM - couldn't get normal memory OSERR_NOCHIPMEM - couldn't get chip memory OSERR_PUBNOTUNIQUE - public screen name already used
This all seems to indicate that "visitor windows" should NOT try opening or closing the screen. There does not appear to be any counter operating in the fashion you suggest.
It also provides a way that "Open/close automatically" COULD work: If public screen FooBar has that feature enabled, then when a program calls LockPubScreen("FooBar"), or if it opens a window with WA_PubScreenName="FooBar", then AmigaOS can automatically open that screen for the program.
This also means that AmigaOS must automatically close the screen when the last visitor window is CloseWindow()ed... except it doesn't in my tests.
Edited by ChrisH on 2011/6/16 13:21:55 Edited by ChrisH on 2011/6/16 13:49:02
A screen, public or not, belongs to the application which opened it by a call to OpenScreen or OpenScreenTags. Only this application is allowed to close the screen by a call to CloseScreen. Visitor windows must not call CloseScreen on public screens.
If OS4 has a mechanism to open public screens automatically by a call to LockPubScreen, this mechanism is also responsible to close the screen. If it does not work, it is a bug. Usually LockPubScreen should not open a screen, but fail if the named screen does not exist or is not public.
A program which opened a screen and made it public must be aware that visitor windows can exist and that CloseScreen can fail. In this case it has to wait until all visitor windows are gone before it closes the screen. It must not quit before the screen is closed.
A program which opened a screen and made it public must be aware that visitor windows can exist and that CloseScreen can fail. In this case it has to wait until all visitor windows are gone before it closes the screen. It must not quit before the screen is closed.
That's true for programs that open their own screens and has been the case since public screens were introduced to the O.S. However, the OS4 Screens preferences program enables system created screens that are opened automatically whenever a program attempts to open on a screen with that name. Even programs that don't normally open their own public screens can be opened on a public screen that does not yet exist if the screen is defined in the Screens preferences and set to open/close automatically. For example, I have created a screen in Screens preferences called "Internet" with the auto open/close setting selected. I have a TOOLTYPE "PUBSCREEN=Internet" set in all my Internet apps. Whenever I start one of my Internet apps, OS4 will automatically open the screen "Internet" if it is not already open. My other Internet programs will also open on the same screen once it is opened and the screen will closed automatically when the last window is closed. OS4 OWB doesn't open it's own screen. It will open on a public screen specified with the PUBSCREEN Tooltype. The whole public screen mechanism and "Screens" created public screens work fine on my system. I don't like Ringhio and don't use it. It opens small notification messages that don't look or act like standard Amiga Windows. They are just small colored blocks with text that appear on the screen background. I think the Ringio notifications look like they belong in some other OS. There are clearly defined mechanisms for visitor windows and requesters on public screens but Ringhio messages don't act like normal windows or requesters and don't appear to be well integrated into Intuition. The problem is with Ringhio and not Intuition or Screens preferences and I think that patching CloseScreen() is a misguided attempt to compensate for a Ringhio problem. Without Ringhio, my public screens (whether program created or Screen prefs created) all work as they should. I think Ringhio should use system compliant requesters instead of the current method.
xenic wrote: The problem is with Ringhio and not Intuition or Screens preferences and I think that patching CloseScreen() is a misguided attempt to compensate for a Ringhio problem. Without Ringhio, my public screens (whether program created or Screen prefs created) all work as they should. I think Ringhio should use system compliant requesters instead of the current method.
I agree with you patching CloseScreen() so that it never fails might not be a good idea because this means that some programs that rely on the fact that CloseScreen() returns immediately might get stuck for ever without being prepared of this... *If* it's a bug in Ringhio let's fix Ringhio not Intuition.
However, the OS4 Screens preferences program enables system created screens that are opened automatically whenever a program attempts to open on a screen with that name.
As I said, if there is such a mechanism, then this mechanism is responsible for closing the screen, just like any other application.
And it must be possible for that mechanisam and any other application to rely on the notification system (SA_PubSig, SA_PubTask) in order to know when the last visitor window disappears.
If Ringhio destroys the notification because it does not use the normal LockPubScreen/UnlockPubScreen and/or OpenWindow/CloseWindow functions, then it is just bad software and should be fixed.
I cannot replicate the problem using AOS4.1 beta (upd2 + daily updates) OWB (3.32) correctly close the screen when the last Ringhio notification fades away, so the bug seems to be fixed.
I agree with you patching CloseScreen() so that it never fails might not be a good idea because this means that some programs that rely on the fact that CloseScreen() returns immediately might get stuck for ever without being prepared of this...
Yes, I can imagine all sorts of potential problems. I wonder what happens if a visitor window attempts to open on the screen while the owning program is stuck in patched CloseScreen()? Some screens are opened with a request for signaling when the last window is closed and will never even call CloseScreen() until the signal is received. Patching CloseScreen() would have no effect anyway. It would be nice if someone involved in OS4 development would comment on the wisdom of patching CloseScreen() in this way.
I cannot replicate the problem using AOS4.1 beta (upd2 + daily updates) OWB (3.32) correctly close the screen when the last Ringhio notification fades away, so the bug seems to be fixed.
In that case, I think Chris should remove the patch from OS4Depot before it causes any unforseen problems. I have to wonder how MUI will react if it gets stuck in CloseScreen() of an MUI defined screen.
As thomas said, theres simply no need for a CloseScreen() patch. Just follow the development guidelines, and do some wait if CloseScreen() fails. If theres a broken program still holding a Lock on your public screen, there is actually nothing you (or the OS) can do against this, beside freeing as many resources as possible and place yourself into a Wait() loop.
Some time in the future there may be some other solution for closing public screens, involving messaging perhaps, which would help with crashed programs holding a Lock on a public screen. As soon as Exec/Dos killed the broken program (and freed its resources/locks), Intuition could send a Signal/Message to the process that opened the public screen, telling that its safe now to attempt another CloseScreen(). Something along this line...
@all Since people are blaming Ringhio, and/or the programs, I will explain more why I think this is an *OS4* bug:
If I get MUI to open a screen for SimpleMail, then tell CygnusEd to open it's window on that public screen, then close SimpleMail, then close CygnusEd... then the public screen will remain open forever (and in fact if I run SimpleMail again then it will be unable to use that public screen, and will use Workbench instead, since I suspect MUI tries to create a new public screen of the same name and fails because one already exists).
@whose Quote:
As thomas said, theres simply no need for a CloseScreen() patch. Just follow the development guidelines
That is all very well... unless OS4 itself is buggy. My BetterCloseScreen patch solves the problem for MUI apps, but not for OWB since it (unsurprisingly) never seems to call CloseScreen in the first place.
@all I do NOT wish to debate the pros & cons of my CloseScreen patch in this thread, and kindly ask you to refrain from doing so. This thread is about an OS4 bug. You can create a new thread if you wish to discuss my patch... however I would prefer if you would wait for the "r2" release to be verified for public download, since this fixes a major bug.