bug-gnustep
[Top][All Lists]
Advanced

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

[patch] ConfigureNotify events


From: Alexander Malmberg
Subject: [patch] ConfigureNotify events
Date: Sun, 29 Feb 2004 22:31:09 +0100

While working on getting -gui to handle window decorations, some of my
brave testers (thanks :) noticed odd issues with events being lost and
DnD not working. After lots of investigation, this turned out to be
caused by the current handling of ConfigureNotify events in
back/Source/x11. After checking with the ICCCM (in particular, part
4.1.5), I got it to work with the attached patch. Since this is fairly
messy stuff, a second opinion would be nice. I've been using it here for
a while, so if it seems ok, I'll commit it.


Currently, the backend ignores the window position in non-synthetic
ConfigureNotify events. Most likely, this is because testing has shown
that the coordinates in such events aren't useful (the ICCCM explains
that they may be relative to some window manager decoration window).
Unfortunately, those events due correspond to real window movement, so
ignoring them causes GNUstep's notion of the window's position to go
out-of-sync with the real position. The patch makes the backend use
XTranslateCoordinates to get the real position when a non-synthetic
ConfigureNotify event is received, as suggested by the ICCCM.

Also, the current code ignores ConfigureNotify events for windows it
thinks are unmapped. I don't know why the code does this, but it causes
problems here. It might be because the window manager sends important
ConfigureNotify events before sending a MapNotify, but I see no reason
why we should ignore ConfigureNotify:s for unmapped windows. The patch
handles all ConfigureNotify events.

- Alexander Malmberg, finally finding time to commit all my local
changes
Index: Source/x11/XGServerEvent.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/back/Source/x11/XGServerEvent.m,v
retrieving revision 1.21
diff -u -r1.21 XGServerEvent.m
--- Source/x11/XGServerEvent.m  4 Feb 2004 00:59:59 -0000       1.21
+++ Source/x11/XGServerEvent.m  29 Feb 2004 20:50:16 -0000
@@ -685,34 +685,45 @@
                      xEvent.xconfigure.send_event ? 'T' : 'F');
          if (cWin == 0 || xEvent.xconfigure.window != cWin->ident)
            generic.cachedWindow = [XGServer 
_windowForXWindow:xEvent.xconfigure.window];
-         /*
-          * Ignore events for unmapped windows.
-                */
-         if (cWin != 0 && cWin->map_state == IsViewable)
+
+         if (cWin != 0)
            {
              NSRect       r, x, n, h;
              NSTimeInterval ts = (NSTimeInterval)generic.lastMotion;
 
-             /*
-              * Get OpenStep frame coordinates from X frame.
-              * If it's not from the window mmanager, ignore x and y.
-              */
              r = cWin->xframe;
+
+             x = NSMakeRect(xEvent.xconfigure.x,
+                            xEvent.xconfigure.y,
+                            xEvent.xconfigure.width,
+                            xEvent.xconfigure.height);
+
+             /*
+             According to the ICCCM, coordinates in synthetic events
+             (ie. non-zero send_event) are in root space, while coordinates
+             in real events are in the parent window's space. The parent
+             window might be some window manager window, so we can't
+             directly use those coordinates.
+
+             Thus, if the event is real, we use XTranslateCoordinates to
+             get the root space coordinates.
+             */
              if (xEvent.xconfigure.send_event == 0)
                {
-                 x = NSMakeRect(r.origin.x, r.origin.y,
-                                xEvent.xconfigure.width, 
xEvent.xconfigure.height);
-               }
-             else
-               {
-                 x = NSMakeRect(xEvent.xconfigure.x, 
-                                xEvent.xconfigure.y,
-                                xEvent.xconfigure.width, 
-                                xEvent.xconfigure.height);
-                 cWin->xframe.origin = x.origin;
+                 int root_x, root_y;
+                 Window root_child;
+                 XTranslateCoordinates(dpy, xEvent.xconfigure.window,
+                                       RootWindow(dpy, cWin->screen),
+                                       0, 0,
+                                       &root_x, &root_y,
+                                       &root_child);
+                 x.origin.x = root_x;
+                 x.origin.y = root_y;
                }
+
+             cWin->xframe = x;
              n = [self _XFrameToOSFrame: x for: cWin];
-             NSDebugLLog(@"Moving", 
+             NSDebugLLog(@"Moving",
                          @"Update win %d:\n   original:%@\n   new:%@",
                          cWin->number, NSStringFromRect(r), 
                          NSStringFromRect(x));
@@ -722,18 +733,15 @@
              h = [self _OSFrameToXHints: n for: cWin];
              cWin->siz_hints.width = h.size.width;
              cWin->siz_hints.height = h.size.height;
-             //if (xEvent.xconfigure.send_event != 0)
-             {
-               cWin->siz_hints.x = h.origin.x;
-               cWin->siz_hints.y = h.origin.y;
-             }
+             cWin->siz_hints.x = h.origin.x;
+             cWin->siz_hints.y = h.origin.y;
 
              /*
               * create GNUstep event(s)
               */
              if (!NSEqualSizes(r.size, x.size))
                {
-                 /* Resize events move the origin. There's no goo
+                 /* Resize events move the origin. There's no good
                     place to pass this info back, so we put it in
                     the event location field */
                  e = [NSEvent otherEventWithType: NSAppKitDefined

reply via email to

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