GNOME Bugzilla – Bug 100416
gtk_dialog_run does not update the NET_WM_STATE to NET_WM_STATE_MODAL
Last modified: 2011-02-04 16:11:52 UTC
Calling a gtk_dialog_run() does make the dialog MODAL but does not set the NET_WM_STATE hint to NET_WM_STATE_MODAL. This is due to gtk_widget_show() being called prior to gtk_window_set_modal()
Created attachment 12757 [details] [review] Patch fixes the problem. Thanks to Bastien for pointing it out.
owen: is the patch ok ? Please let me know, Thanks.
This patch doesn't fully solve the probleme; GtkWindow needs to change call gdk_window_set_modal_hint() in response to gtk_window_set_modal() gtk_window_set_transient_for() [ and to the transient parent being destroyed ] With just this patch: gtk_window_show (dialog); gtk_window_hide (dialog); gtk_dialog_run (dialog); Won't work because the window is realized before gtk_dialog_run() is called. (This patch probably makes sense as an efficiency thing, but correctness has handled inside gtkwindow.c)
Created attachment 12886 [details] [review] patch with changes suggested by owen
a) gtk_window_set_modal() needs also to unset the modal hint when setting modal to FALSE. b) gtk_window_set_modal() needs to only set the modal hint when window->transient_parent && GTK_WIDGET_REALIZED (window->transient_parent) c) you need the change I mentioned to gtk_window_realize() to change window->transient_parent to window->transient_parent && GTK_WIDGET_REALIZED (window->transient_parent)
> b) gtk_window_set_modal() needs to only set the modal hint > when window->transient_parent && GTK_WIDGET_REALIZED > (window->transient_parent) owen: can't I set modality for a dialog which has no transient parent ? I ask this because a problem in metacity bug #100343 could have an answer here.
I would say all modal dialogs should set the modal type, even if they lack a transient parent. (disclaimer, I haven't looked at any of the code or patches here.)
The WM spec says: _NET_WM_STATE_MODAL indicates that this is a modal dialog box. The WM_TRANSIENT_FOR hint MUST be set to indicate which window the dialog is a modal for, or set to the root window if the dialog is a modal for its window group. And the GDK docs and the current code in GtkWindow avoid setting _NET_WM_STATE_MODAL unless there is a transient parent. (Transient-for-the-root-window is just odd; it's a old GTK+ bug that somehow found it's way into the standard...)
While the WM spec literally says you must set the transient for hint, I think the spirit of it is: The reason to do "transient for root" was to indicate DIALOG semantic type, while not actually setting a real transient parent. Thus I think setting the DIALOG type, but no transient parent, should be treated the same as setting transient for root. Both of those mean "transient for the entire group" and metacity will keep such windows above the whole group, for example (though the info conveyed to the WM is semantic, some WMs may not keep above). If we're going to interpret the WM spec literally, I think we should set all dialogs transient for the root window if they aren't transient for something else, because our modal dialogs *are* transient for the entire group. The spec could use some clarification here of course. mathias, what is your take on this?
Reading up what the ICCCM says about WM_TRANSIENT_FOR: The implication is that this window is a pop-up on behalf of the named window, and window managers may decide not to decorate transient windows or may treat them differently in other ways. In particular, window managers should present newly mapped WM_TRANSIENT_FOR windows without requiring any user interaction, even if mapping top-level windows normally does require interaction. Dialogue boxes, for example, are an example of windows that should have WM_TRANSIENT_FOR set. I think most of these uses are covered better by the EWMH semantic types by now. One thing where WM_TRANSIENT_FOR is still needed is placement relative to the transient parent, the other is modality wrt to a dedicated parent, not the whole group. I think we should try to clarify this in the EWMH and rewrite the explanation of _NET_WM_STATE_MODAL along the lines of If the WM_TRANSIENT_FOR hint is set to another toplevel window, the dialog is modal for that window; if WM_TRANSIENT_FOR is not set or set to the root window the dialog is modal for its window group.
Assuming that someone is going to push the necessary EMWH changes, I think we can ahead and ignore the modal => transient-for part of the spec for now. It certainly makes sense to me that no transient for would be treated the same as being transient for the root window for the purposes of the MODAL hint.
Created attachment 13012 [details] [review] Patch as applied
Sun Dec 15 18:47:30 2002 Owen Taylor <otaylor@redhat.com> Some fixes for modal hint setting based on a patch from Arvind Samptur (#100416) * gtk/gtkdialog.c (gtk_dialog_run): Call gtk_window_set_modal before showing the window for efficiency. * gtk/gtkwindow.c (gtk_window_realize): Ignore the EWMH constraint that the transient-for hint must always be set on windows with the modal hint and just always set the modal hint. * gtk/gtkwindow.c (gtk_window_set_modal): Update the modal hint on the GdkWindow when the window is realized.