ratpoison-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RP] bug?


From: Joshua Neuheisel
Subject: Re: [RP] bug?
Date: Tue Apr 29 05:36:08 2003

From: "twb" <address@hidden>
> Spotted a possible bug.
>
> When you open  gnucash for the first time, it  opens TWO transients (a
> `TipOTD'  and  a  druid).  Both  of  them  appear,  and neither  do
> the take-up-whole-screen   thing.   After   about  5   seconds,
> ratpoison segfaults.  This happened reproducibly even with no other X
> clients.

This particular bug is fixed in CVS (and also in beta4 I think).  It's the
same one that was causing ImageMagick to bring down RP.  When I was checking
this out, though, I ran into another unrelated bug.  When you start gnucash,
it brings up the 'Tip O'the Day' and the little druid box.  If you click
'Cancel' on the druid box, and then OK on the resulting box, you will be
left with the main window and the (obscured) TOTD.  Without closing the
TOTD, close the main window.  Now the frame will be left with no window and
no focus!  This is particularily bad when running RP with only one frame: in
fact, in this case the only way I can see to proceed is to kill X and start
over again.

I've seen this bug before so I decided to do a little detective work.  I've
figured out what the problem is, but bear with me because this may take a
minute to explain in detail...

The main window is being destroyed first (RP receives an UnmapNotify and
then a DestroyWindow).  The UnmapNotify tells RP to map an obscured window
(via cleanup_frame) which maximized the TOTD window.  Great: this is exactly
as it should be.  Now RP receives a DestroyWindow for the TOTD window, but
no UnmapNotify since we just mapped the TOTD window and RP received the
DestroyWindow event first.  Now there's a problem: cleanup_frame will not be
called before the TOTD window is removed.  We're left with a frame that
hasn't been 'cleaned-up'.

Here's a simple GTK2 program people may find easier to use when testing this
out:

#include <gtk/gtk.h>
gint
delete_event (GtkWidget * widget, GdkEvent * event, gpointer data)
{
  gtk_main_quit ();
  return FALSE;
}
int
main (int argc, char *argv[])
{
  GtkWidget *window, *dialog;
  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  dialog = gtk_dialog_new ();
  gtk_window_set_title (GTK_WINDOW (window), "Main Window");
  gtk_window_set_title (GTK_WINDOW (dialog), "Dialog Box");

  g_signal_connect (G_OBJECT (window), "delete_event",
                    G_CALLBACK (delete_event), NULL);
  gtk_widget_show (window);
  gtk_widget_show (dialog);

  gtk_main ();
  return 0;
}

This program opens a main window and then a dialog box.  Run this and use
the window list to bring the main window to the top.  Now kill the main
window with 'C-t K' (not 'C-t k', since we need to make sure the main window
gets killed first).  The same ghost-frame effect will be apparent.

So now that I've described the problem, how do we fix it?  Well, here's a
proposed patch:

Index: src/events.c
===================================================================
RCS file: /cvsroot/ratpoison/ratpoison/src/events.c,v
retrieving revision 1.92
diff -u -r1.92 events.c
--- src/events.c 10 Apr 2003 19:29:04 -0000 1.92
+++ src/events.c 29 Apr 2003 12:25:53 -0000
@@ -176,6 +176,9 @@
   win = find_window (ev->window);
   if (win == NULL) return;

+  /* Make sure the window is unmapped */
+  unmap_notify ((XEvent *) ev);
+
   ignore_badwindow++;
   unmanage (win);
   ignore_badwindow--;

This patch is very simple: every time destroy_window gets called (e.g., in
response to a DestroyNotify), we fake as if we had just received an
UnmapNotify by calling unmap_notify.  If the window was already unmapped, no
harm done.  If not, we take care of it.

To quote REM: "I've said too much; I haven't said enough"...

Joshua



reply via email to

[Prev in Thread] Current Thread [Next in Thread]