After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 371036 - Win32: Raise modal children dialogs when clicking parent in window list
Win32: Raise modal children dialogs when clicking parent in window list
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: Other
2.10.x
Other Windows
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks: 395327
 
 
Reported: 2006-11-05 14:16 UTC by Andreas Köhler
Modified: 2007-10-18 00:34 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
raise modals, smaller example (625 bytes, text/plain)
2006-11-05 15:42 UTC, Andreas Köhler
  Details
Charles Reilly's patch (11.94 KB, patch)
2006-11-05 20:34 UTC, Tor Lillqvist
none Details | Review

Description Andreas Köhler 2006-11-05 14:16:12 UTC
Steps to reproduce:
* execute gtk-demo.exe
* choose Dialog and Message Boxes
* click Message Dialog
* raise some other windows by alt-tab or the window list
* raise the parent window (Dialogs)

This window ist not responsive, because there is still a modal dialog you cannot see unless you minimize/move_out_of_the_way all windows that got stacked above it. But the user will not expect that and assume the application crashed somehow.
Comment 1 Andreas Köhler 2006-11-05 15:42:52 UTC
Created attachment 76029 [details]
raise modals, smaller example

Here is a smaller example code.
Comment 2 Tor Lillqvist 2006-11-05 15:58:46 UTC
Thanks for the excellent small test program. The problem is fixed by a patch that has been circulating (slowly) between me and some gnumeric people for quite some time without any clear consensus (I think) whether it's good enough or entirely correct. I don't think the patch introduces any new problems, though, and your example shows how easy it is to get the problem, so I think I will commit the patch.
Comment 3 Tor Lillqvist 2006-11-05 16:12:36 UTC
Sorry, I meant Inkscape, not gnumeric. I'll include here a couple of mail messages exchanged with Inkscape people to show the kind of complexities involved:

Message 1:
  In summary, our use of transients breaks into two parts, the trivial
  part and the hacky part:

  The trivial part: each dialog window is attached to the main editing
  window by gtk_window_set_transient_for. Both belong to the same
  application, of course.

  The hackish part: Inkscape may have _several_ editing windows, if
  you load several documents. All they are still the same application,
  and the floating dialogs are _shared_ between them and are switching
  to display the information pertaining to the document window which
  currently has focus.

  With regard to transient behavior, of course the ideal approach
  would be something like "make this dialog window transient to this
  GROUP of windows, so that no matter which one has focus, the dialog
  will be on top of it". But there's no such API as far as I know. So
  we achieve the same by a hack: whenever a document window gets
  focus, it sends a signal to all active dialogs, and these dialogs
  "re-transientize" themselves, i.e. use gtk_window_set_transient_for
  to attach to the document window which is currently on top. If
  anyone has a better idea of how to achieve the same effect, we'd
  like to hear.

  Additional bits:

  - Each dialog also is hidden from the task bar by default, using
  gtk_window_set_skip_taskbar_hint.

  - On some window managers, re-transientizing a dialog does not pull it
  on top unless you click on the document window to which this dialog is
  transientized. To work around this we have the "aggressive" mode
  where, after each gtk_window_set_transient_for, a gtk_window_present
  call is used on the dialog.

  - Each dialog stores the pointer to the editing window to which it is
  currently transient and uses it to pass focus to that window, e.g.
  when you press Esc or in some other situations.

Message 2, by he author of the patch I talk about in comment #2:

  I've just had a go with Inkscape on Linux (Ubuntu) and it also seems to
  have problems with transient windows. For example:

  Create two new documents each containing a simple shape.
  Right-click on a shape and select "Fill and Stroke". Minimize the
  active document window. The "Fill and Stroke" window is also
  minimized.

  Restore the document. Note that "Fill and Stroke" doesn't return.
  Right-click on a shape and select "Fill and Stroke".  It still
  doesn't return. Select the menu command "View|Show/Hide dialogs".
  It still doesn't return. Open another dialog (e.g. "Swatches") and
  "Fill and Stroke" reappears. (But it wouldn't have without the
  preceding step.)

  It's also very unfriendly if you have two inkscape documents open in
  different workspaces.

  The Windows patch was fairly complicated to avoid the problems on
  minimization, but it looks like I was putting the fix in the wrong place. 
  I think it would be sensible to fix Inkscape's problems before trying to
  take the win32 patch any further.

Message 3:

  As you might guess, all this weirdness is NOT coded into Inkscape in
  any shape or form. It's just the reality of how window managers
  support transient windows. I agree it's a mess, but it's not
  Inkscape's mess. Inkscape just tries to adapt and work around this
  mess as best it can.

  Needless to say, this very much depends on your window manager. For
  example, on my KDE 3.3 the sequence differs from yours in this item:

  > Right-click on a shape and select "Fill and Stroke".  It still doesn't
  > return.

  For me, it does.

  I have explained exactly how Inkscape uses transiency (see my last
  mail). If you spot something wrong with it, please share your
  suggestions.

  Please also understand that I'm not a specialist in window interface
  at all, and never claimed to be one. It's not an area that interests
  me as such. I was forced to code this hack simply because without
  it, Inkscape was unusable. With it, it's far from ideal but at least
  tolerable. If you can help me make it work better or reimplement it
  in a more correct way, your help will be GREATLY appreciated.

  Briefly, the ideal behavior of Inkscape dialogs is this: they always
  stay on top of the topmost (active) document window; they minimize
  and restore together with the LAST document window; and they are
  hidden from the taskbar. That's all I'm asking for. The current
  Linux implementation does not fully conform to this, but this is the
  best I could do with the current window managers.

  If you can help me fix the Linux side of things (there may be some
  things I overlooked, of course), I will be very grateful. If you can
  make the Windows port work the same or even better than the Linux
  (i.e. closer to the above ideal), it would be simply great and much
  much appreciated. Just don't look at the actual Linux behavior as a
  reference, because it is not.

  I look forward to hearing your thoughts on this. Please do help me
  out. I've been fighting with this stuff basically alone for 3 years.
Comment 4 Andreas Köhler 2006-11-05 18:26:08 UTC
May you attach the patch you have?

OT: The docs for gtk_window_set_transient_for miss a word, exactly in the sentence describing the behavior on Windows. May you fix that too or should I file a new bug?
Comment 5 Tor Lillqvist 2006-11-05 20:33:52 UTC
Hmm, I wonder what the documentation is supposed to say. Most probably just that the function (or the underlying GDK functionality) will only do its best to try doing what the window manager would/should do on X11.

Attaching the patch, originally by Charles Reilly. It most probably needs more thorough testing, for instance for what happens in the case of chained transient-for. Also, I guess the code (regardless whether the patch is applied or not) should start checking, and explicitly disregard, attempts to se transient-for-ness across process boundaries, as that can cause hangs.
Comment 6 Tor Lillqvist 2006-11-05 20:34:52 UTC
Created attachment 76051 [details] [review]
Charles Reilly's patch
Comment 7 Michail Crayson 2007-02-08 23:15:07 UTC
I have this problem with GtkMessageDialog, and a workaround which seems to work for me is to simply run this after creating the dialog with gtk_message_dialog_new():

gtk_window_set_skip_taskbar_hint( GTK_WINDOW( dialog ), FALSE );

I have no idea why this works. And the dialog still doesn't show up in the taskbar, probably because it is transient to the parent window.

Also, with the risk of falling off topic and while confessing that I don't really understand anything of the GTK+ internals, I can't help but wonder why this hint is set in gtk_message_dialog_init() where it will affect all dialogs, even those without a parent window. If a dialog doesn't have a parent window, wouldn't you then want it to show up in the task bar?
Comment 8 Cody Russell 2007-08-29 06:45:26 UTC
I posted a patch to bug #164537 that also addresses this bug.
Comment 9 Cody Russell 2007-10-18 00:34:16 UTC
2007-10-17  Cody Russell  <cody@jhu.edu>

        * gdk/win32/gdkevents-win32.c
        * gdk/win32/gdkwindow-win32.[ch]: Force non-modal transient dialogs
        to iconify with their parents on Win32.  Maintain a list of transient
        children, and whenever a window is hidden or restored we now do the
        same thing to all connected transient windows above and below the
        current window in the chain.  See comment under WM_ACTIVATE for the
        reasons why.  (#164537, #371036, #405178)