GNOME Bugzilla – Bug 100343
Modal dialogs can be lowered, preventing application input.
Last modified: 2009-08-15 18:40:50 UTC
Package: metacity Product: metacity Synopsis: Modal dialogs can be lowered, preventing application input. Severity: grave Priority: Urgent Bugzilla-Product: metacity BugBuddy-GnomeVersion: 2.0 It is possible to raise an application window above one of it's modal dialogs. In this state it is not possible to enter anything in the modal dialog or in the application window which is on top. Here is an example: 1) Open a nautilus folder which is set to automatic layout (the default for unvisited folders). 2) Drag an icon within this folder. 3) You will see a "Switch to Manual layout?" dialog 4) Now click anywhere else in the nautilus window. Nautilus will raise above the modal dialog. 5) From the users point of view, Nautilus is now frozen. There is a hidden modal dialog which cannot accept input and the top window cannot accept input because of the modal dialog. Modal dialogs should always raise above all other windows of an application. Bugtraq+: 4788296 ------- Bug moved to this database by unknown@bugzilla.gnome.org 2002-12-04 11:52 ------- Reassigning to the default owner of the component, hp@redhat.com.
This happens even with 'File types & application' under desktop preferences. Clicking on edit opens a new window which is modal. And if by mistake main window comes on top, then it wouldn't let you key-in anything and user wouldn't know whats going wrong.
The Nautilus dialog is set transient for the bonobo component (the icon view) instead of transient for the toplevel Nautilus window.
Havoc: also eel_show_yes_no_dialog() does not set the dialog to be Modal. I guess we should pass NULL instead of the parent so that the dialog would be always on top irrespective of the number of nautilus windows opened. But the other question of "file types" what do you think ?
The file types dialog has been reported against metacity several times and moved to control-center several times. Someone needs to fix the file types capplet to set the transient parent. Setting a NULL parent is the wrong fix for the Nautilus dialog; it should set the toplevel nautilus window as the parent. Modality is already getting set somewhere (or the dialog would not be modal), probably it's set by gtk_dialog_run().
Havoc: Yeah, a gtk_dialog_run is done. :) If I have 2 nautilus windows A and B. I get the dialog for A and set the parent as A (the toplevel window). Now when I click on B, the dialog is hidden since B is not the parent.But still I can't use B. So, I suggested passing NULL. Am I missing something here ?
Ah, I see your point about NULL. You know, I think it would be better to fix that in metacity by keeping _modal_ dialogs above all windows in the MetaGroup. Because we still want to know the correct parent of the dialog (for purposes of window placement for example). So in metacity we could assume that modal dialogs block input to everything in the MetaGroup and keep the dialog on top. Should be a trivial change to stack.c. Should I make that change? I didn't mention before, my theory on this bug is that someone assumed gtk_widget_get_toplevel() always returned a toplevel window, which it doesn't - it can return a GtkPlug for example... Perhaps bonobo has some way to get the real toplevel.
Created attachment 12756 [details] [review] Metacity part of fix
havoc: Guess the patch fixes the metacity part. Please let me know if it is fine. While fixing this I came across two interesting problems... a) although gtk_dialog_run() calls gtk_window_set_modal(), the NET_WM_STATE is not set to NET_WM_STATE_MODAL. That's probably because in gtk_dialog_run(), a gtk_widget_show() is being done before gtk_window_set_modal(). Thanks to Bastien for pointing this out. Anyway I will test it out and raise a seperate bug in gtk+. b)currently the call eel_show_yes_no_dialog() being used to show the nautilus dialog has no way setting the GtkDialogFlags. Hence to make this dialog modal, we may have to either change the eel API (not sure if the maintainers would agree upon now) or subsitute the gtk code directly.
Okay, I created a bug in gtk+ and attached the patch. http://bugzilla.gnome.org/show_bug.cgi?id=100416 dave,alex But for the other problem about eel, shall I go ahead to replace the call with gtk code itself ?
re: the patch, I would say the modal window should be constrained above other modal windows only if the first modal window is explicitly transient for the second one. i.e. for a modal window, we have two constraints: - above each non-transient-type window in the group (this does not include other modal windows) - above the explicit transient parent of the modal window
Havoc: i am bit confused :) > re: the patch, I would say the modal window should be constrained > above other modal windows only if the first modal window is > explicitly transient for the second one If modal window A is the transient parent of modal window B then B should always remain on top of A. right ? If that's the case the check is missing in the patch. >i.e. for a modal window, we have two constraints: > - above each non-transient-type window in the group patch takes care of it atm. > (this does not include other modal windows) I guess this is reference to your first comment. > - above the explicit transient parent of the modal window This will always be the case with the patch since we will keep the modal window always on top of the group irrespective of whether the parent is set or not. The issue that remains would of handling 2 model windows having parent-child relationship. Please let me know. Thanks.
> If modal window A is the transient parent of modal window B then > B should always remain on top of A. right ? Yes. This is the constraint "B above A" Then there should also be a constrain "B above all non-transient windows in the group" where all modal windows are considered transient.
Created attachment 12791 [details] [review] Partial metacity fix.
Havoc: I fixed the modal windows(parent-child) one. > Then there should also be a constrain "B above all non-transient > windows in the group" where all modal windows are considered > transient. B would always be above non-tranisent windows(other than modal windows). But I was not able to get a condition satisfying for B to above all the other modal windows (which have not set their parent) ie. A above B above C being modal dialogs but none have their parent set. On clicking A, C and B would go under A. Could you please have a quick look at this. Thanks.
Havoc/ Owen: Refering to this thread http://mail.gnome.org/archives/wm-spec-list/2002-December/msg00018.html If a modal dialog has its transient parent set and gtk_dialog_run() is done, the user cannot interact with any other window in the group, but has a possibility of the modal window getting lost under another which is not its parent. Now, when and how should one use a gtk_dialog_run() then... a) If the dialog HAS to be dismissed before interacting with any other window in the group. With current suggestions in EWMH, to acomplish this, don't set the tranisent parent, so that its always on the top of the group. Have I got this right ? Please let know.
sorry, its not gtk_dialog_run(), its the gtk_window_set_modal() that blocks the rest of the windows :/ I guess we still have the problem of the modal window going behind a non-parent window, when its transient parent is set.
Arvind - that's something metacity has enough information to figure out. i.e. if A is modal, and transient for B, which is transient for C, and C is a toplevel with no transient parent, we could keep C above the group, perhaps.
Havoc: Currently with existing code, I guess if A is modal, and transient for B, which is transient for C, A will remain on top irrespective of whether it is a modal or not. The problem I saw was with 2 nautilus windows (toplevel) A and B. A has a modal dialog A1 with the transient parent set to A. Click on B and A1 would be lost behind B. And we can't interact with B as well since A1 is modal and has to be dismissed first. Probably I am dragging this whole issue :/ But I feel that any Modal window should be above all the windows in the group since interaction with the rest is not possible without dismissing the modal window. Please let me know.
In your example, A (which is equivalent to my C) should be kept above the whole group, thus keeping it above B.
Created attachment 14201 [details] [review] Another attempt :)
Created attachment 14202 [details] [review] Nautilus part of the fix
Test Case 1 : 1) Have 2 nautilus windows open 2) Drag a file in one of the windows. It throws up a dialog which is MODAL. 3) Click on the other nautilus window. The dialog is still on top of the nautilus window group. Test Case 2 : 1) Have 2 nautilus windows open 2) Open Preferences dialog. It is a dialog without a transient parent. 3) Drag a file in one of the windows. It throws up a dialog which is MODAL. 4) Click on the other nautilus window or the preferences dialog. The MODAL dialog is still on top of the nautilus window group.
Havoc: If you feel the approach of the metacity patch is in the right direction, then I would like to do this change to the current patch I put up. in #define WINDOW_TRANSIENT_FOR_WHOLE_GROUP(w) + (w->type == META_WINDOW_MODAL_DIALOG && \ + meta_window_is_modal_with_no_grandparent (w))) instead of just + meta_window_is_modal_with_no_grandparent (w) Since we are interested in MODAL dialogs only. Please let me know.
Nautilus patch has been checked in to CVS. Approved by Campd.
Havoc: ping :)
Moved it to Metacity for getting in to hp's radar.
Havoc, could you have a look at Arvind's patches?
The patch isn't fully general; it just goes up a single level. You have to handle the case where A is modal, A is transient for B is transient for C is transient for D is transient for E, then we must keep A->B->C->D->E all in order, and all above any other windows in the group. In other words, if a transient descendant of a window (child or grandchild or great-grandchild) is modal, then we need to add_constraint() where the window with the modal descendant is kept above the group. In this case, each of A through E have a constraint that they are above the other windows in the group. Or will this not work for some reason?
Seems to be closely related to bug 96140. That bug has a link to this one, but I didn't see a comment in here about that bug so I thought I'd add one. :)
See also: http://bugzilla.ximian.com/show_bug.cgi?id=39059 I run into this in a couple ways-- I get a spurious xkb error every time I log in, which, if I don't dismiss it soon enough, is then hidden behind the GNOME splash screen, which won't go away until I dismiss the xkb error dialog... Or, say, today I sent a message and quit Evolution. However the message had not been sent and it asked if I really wanted to quit, opening a modal dialog. Then the send process got going and opened another dialog in front of the earlier modal dialog asking if I wanted to accept the SMTP server's SSL certificate... anyway, it appears in a few odd cases-- may be that the error is on the part of the apps, but we need to make it easy to avoid this kind of behavior!
Does this bug still exist? Or did Rob's fix for bug 96140 fix this too?
Arvind, Havoc? Should this be closed now?
yes, i checked out with metacity-window-demo and tweaked to it do the test case Havoc was referring to > A is modal, A is transient for B is transient for C is transient for D > is transient for E, then we must keep A->B->C->D->E all in order, > and all above any other windows in the group. This worked. So marking the bug fixed.