bug-gnustep
[Top][All Lists]
Advanced

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

Request for help: Dragging windows without Periodic Events


From: Michael Hanni
Subject: Request for help: Dragging windows without Periodic Events
Date: Fri, 4 Apr 2003 20:27:03 -0800 (PST)

Hi,

Alex Malmberg came up with an event loop that does not use periodic events, but
still is responsive on slow machines. With his help I've got NSMenuTitleView
using this loop, however, on my machine I can't drag the menus very long before
the menus start jumping all over the place. Dragging at a good clip causes the
menus to leap right off the screen. Somehow the mouse location information is
getting corrupted in the backend and when we use that information the menu gets
screwy.

(XGServerWindow.m placewindow: seems to be part of the problem.)

I've tried to trace this to where the actual problem begins, but I have been
unsuccessful. I attached the latest patch, which should apply cleanly to an
up-to-date CVS pull, and I'd appreciate if some of the other "menu hackers"
would take a look at this and test it on their setups.

Thanks!

Michael

=====
Index: NSMenuView.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSMenuView.m,v
retrieving revision 1.86
diff -u -r1.86 NSMenuView.m
--- NSMenuView.m        1 Apr 2003 19:52:08 -0000       1.86
+++ NSMenuView.m        2 Apr 2003 23:30:19 -0000
@@ -1390,9 +1390,9 @@
 {
   NSPoint              lastLocation;
   NSPoint              location;
-  unsigned     eventMask = NSLeftMouseUpMask | NSLeftMouseDraggedMask;
-  BOOL         done = NO;
-  NSDate               *theDistantFuture = [NSDate distantFuture];
+  unsigned     eventMask = NSLeftMouseUpMask | NSLeftMouseDraggedMask | 
+                               NSMouseMovedMask;
+  NSPoint oldOrigin, newOrigin;
 
   NSDebugLLog (@"NSMenu", @"Mouse down in title!");
 
@@ -1403,36 +1403,54 @@
         [menu setTornOff: YES];
     }
 
-  while (!done)
-    {
+  oldOrigin = [_window frame].origin;
+
+do
+{
+   /* Inner loop that gets and (quickly) handles all events that have
+    * already arrived.
+    */
+   while (theEvent && [theEvent type]!=NSLeftMouseUp)
+   {
+NSLog(@"handle");
+//      location = [_window mouseLocationOutsideOfEventStream];
+      location = [theEvent locationInWindow];
+      location = [_window convertBaseToScreen: location];
+      /* Note the event here. Don't do any expensive handling. */
       theEvent = [NSApp nextEventMatchingMask: eventMask
-        untilDate: theDistantFuture
-        inMode: NSEventTrackingRunLoopMode
-        dequeue: YES];
-
-      switch ([theEvent type])
-        {
-        case NSRightMouseUp:
-        case NSLeftMouseUp: 
-          done = YES; 
-          break;
-        case NSRightMouseDragged:
-        case NSLeftMouseDragged:   
-          location = [_window mouseLocationOutsideOfEventStream];
-          if (NSEqualPoints(location, lastLocation) == NO)
-            {
-              NSPoint origin = [_window frame].origin;
-
-              origin.x += (location.x - lastLocation.x);
-              origin.y += (location.y - lastLocation.y);
-              [menu nestedSetFrameOrigin: origin];
-            }
-          break;
-
-        default: 
-          break;
-        }
-    }
+         untilDate: [NSDate distantPast] /* Only get events that have already 
a$ */
+         inMode: NSEventTrackingRunLoopMode
+         dequeue: YES];
+   } 
+        
+   if ([theEvent type]==NSLeftMouseUp)
+      break;
+
+   /*
+   location is position of the cursor in screen coordinate system.
+   lastLocation is the position of the cursor in the window. Thus, we want
+   the origin to satisfy origin+lastLocation=location:
+   */
+   newOrigin.x = location.x-lastLocation.x;
+   newOrigin.y = location.y-lastLocation.y;
+
+   /* No more events right now. Do expensive handling, like drawing, here. */
+   if (NSEqualPoints(oldOrigin, newOrigin) == NO)
+     {
+       oldOrigin = newOrigin;
+NSLog(@"move to (%g %g)",newOrigin.x,newOrigin.y);
+       [menu nestedSetFrameOrigin: newOrigin];
+     }
+
+NSLog(@"block");
+   /* Get the next event, blocking if necessary. */
+   theEvent = [NSApp nextEventMatchingMask: eventMask
+      untilDate: nil /* No limit, block until we get an event. */
+      inMode: NSEventTrackingRunLoopMode
+      dequeue: YES];
+ 
+} while ([theEvent type] != NSLeftMouseUp);
+
 }
 
 - (void) createButton

reply via email to

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