gnustep-dev
[Top][All Lists]
Advanced

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

Re: Window managers


From: Christopher Armstrong
Subject: Re: Window managers
Date: Sat, 31 Mar 2007 09:51:00 +1000
User-agent: Thunderbird 1.5.0.10 (Windows/20070221)

Hi
I have added Yen-Ju Chen's contributions to the wiki. Thank you very much for
helping out. If anyone has stuff to add, speak up! Please read and
contribute to the wiki page at
http://wiki.gnustep.org/index.php/Window_manager .
I was just reading Yen-Ju Chen's contribution and the bit about "windows turning black" caught my eye. This problem exists on Microsoft Windows as well when you activate native window borders. I found a partial solution for this problem on Windows.

Another problem with window drawing is that non-retained (i.e. unbuffered) windows on Microsoft Windows do not seem to update properly. For example, when you drag items from the toolbox in Gorm.app to a non-retained window, it doesn't show up. By dragging the window off the screen and back on, a repaint is forced and then it shows up again. I can't seem to remember if this problem exists on X11.

I have been sitting on some code to fix black windows on Windows (please note the capitalisation carefully) and a fix for a problem where mouse up events don't get sent when the mouse is released outside of a GNUstep window. A patch is attached; please test with GNUstep window decorations turned OFF. There is also a (partial, "seems to work") fix for incorrect backbuffer blitting after a resize.

Regards
Chris

P.S: [Forwarding this to gnustep-dev]
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 24952)
+++ ChangeLog   (working copy)
@@ -1,3 +1,16 @@
+2007-03-31 Christopher Armstrong <address@hidden>
+
+       * Source/win32/WIN32Server.m: Backend capture mouse when it
+       is clicked down, and releases the mouse capture when the mouse button
+       is released.
+       * Source/win32/w32_movesize.m: WM_SIZING sends
+       GSAppKitWindowResized events to the frontend so that frame rect is
+       updated during the resize.
+       * Headers/win32/WIN32Server.h
+       * Source/win32/w32_windowdisplay.m: Added a flag to the WIN_INTERN
+       structure so that we can tell when the backing store contains no
+       useful data and a repaint should occur.
+
 2007-03-30 Fred Kiefer <address@hidden>
 
        * header/xlib/XGGeometry.h: Replace calls to the now deprecated
Index: Source/win32/w32_windowdisplay.m
===================================================================
--- Source/win32/w32_windowdisplay.m    (revision 24952)
+++ Source/win32/w32_windowdisplay.m    (working copy)
@@ -35,6 +35,18 @@
 {
   WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)hwnd, GWL_USERDATA);
 
+  if (!win->useHDC || win->backingStoreEmpty) 
+    {
+      NSWindow *window = GSWindowWithNumber((int)hwnd);
+      NSRect r = MSWindowRectToGS(svr, (HWND)hwnd, rect);
+      
+      /* Repaint the window's client area. */
+
+      [[[window contentView] superview] setNeedsDisplayInRect: r];
+      [[[window contentView] superview] displayIfNeeded];
+      win->backingStoreEmpty = NO;
+
+    }
   if (win->useHDC)
     {
       HDC hdc = GetDC((HWND)hwnd);
@@ -49,18 +61,6 @@
       }
       ReleaseDC((HWND)hwnd, hdc);
     }
-  else 
-    {
-      NSWindow *window = GSWindowWithNumber((int)hwnd);
-      NSRect r = MSWindowRectToGS(svr, (HWND)hwnd, rect);
-      
-      /*
-       NSLog(@"Invalidated window %d %@ (%d, %d, %d, %d)", hwnd, 
-       NSStringFromRect(r), rect.left, rect.top, rect.right, rect.bottom);
-      */
-      // Repaint the window's client area. 
-      [[[window contentView] superview] setNeedsDisplayInRect: r];
-    }
 }
 
 @implementation WIN32Server (w32_windowdisplay)
@@ -206,6 +206,7 @@
   RECT rect;
    //LPPAINTSTRUCT lpPaint;
    //HDC theHdc;
+  PAINTSTRUCT pPaint;
 
    /*BOOL InvalidateRect(
    HWND hWnd,           // handle to window
@@ -216,14 +217,14 @@
    //theHdc=BeginPaint(hwnd, lpPaint);
    //if (flags.HOLD_PAINT_FOR_SIZING==FALSE)
    // {
-  if (GetUpdateRect(hwnd, &rect, NO))
+  if (GetUpdateRect(hwnd, &rect, TRUE))
     {
-      //InvalidateRect(hwnd, rect, YES);
-          
+      BeginPaint(hwnd, &pPaint);          
+      
+      // Perform drawing (or blitting if buffered) in response to WM_PAINT
       invalidateWindow(self, hwnd, rect);
-      // validate the whole window, for in some cases an infinite series
-      // of WM_PAINT is triggered
-      ValidateRect(hwnd, NULL);
+
+      EndPaint(hwnd, &pPaint);
     }
    // } 
   flags._eventHandled=YES;
@@ -281,6 +282,7 @@
       win->hdc = hdc2;
       
       ReleaseDC((HWND)hwnd, hdc);
+      win->backingStoreEmpty = YES;
     }
 }
 
Index: Source/win32/WIN32Server.m
===================================================================
--- Source/win32/WIN32Server.m  (revision 24952)
+++ Source/win32/WIN32Server.m  (working copy)
@@ -418,8 +419,9 @@
 
 /*  stubs for window server events note other stubs should be 
     declared for mouse and keyboards
-    these should be implmented in a subclass or a catagory
+    these should be implemented in a subclass or a catagory
 */
+
 - (LRESULT) decodeWM_ACTIVEParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd
 {
   [self subclassResponsibility: _cmd];
@@ -1084,6 +1086,11 @@
 
       ReleaseDC((HWND)winNum, hdc);
     }
+  else
+    {
+      win->useHDC = NO;
+      win->hdc = NULL;
+    }
 }
 
 - (void) titlewindow: (NSString*)window_title : (int) winNum
@@ -1706,14 +1713,15 @@
   short deltaY = 0;
   static int clickCount = 1;
   static LONG lastTime = 0;
-
   gcontext = GSCurrentContext();
   eventLocation = MSWindowPointToGS(svr, hwnd,  GET_X_LPARAM(lParam), 
-                                   GET_Y_LPARAM(lParam));
+           GET_Y_LPARAM(lParam));
   ltime = GetMessageTime();
   time = ltime / 1000;
   tick = GetTickCount();
   eventFlags = 0;
+
+  
   if (wParam & MK_CONTROL)
     {
       eventFlags |= NSControlKeyMask;
@@ -1765,7 +1773,30 @@
          clickCount = 1;
          lastTime = ltime;
        }
+      /* Capture the mouse so we can receive a mouse up event outside of
+         a GNUstep window. Windows does not send mouse up events otherwise.*/
+      SetCapture(hwnd);
+
+      /* Store a copy of the button that went down so that we release
+         the capture on the correct mouse up event. */
+      if (svr->flags.lastButtonDownType)
+        svr->flags.lastButtonDownType = eventType; 
     }
+  else if ((eventType == NSLeftMouseUp)
+    || (eventType == NSRightMouseUp)
+    || (eventType == NSOtherMouseUp))
+    {
+      /* Release the mouse from this thread so that other threads can capture
+         it and that it is "best practice" to do so at this time. */
+      int lbdt = svr->flags.lastButtonDownType;
+      if ((eventType==NSLeftMouseUp && lbdt==NSLeftMouseDown) ||
+          (eventType==NSRightMouseUp && lbdt==NSRightMouseDown) ||
+          (eventType==NSOtherMouseUp && lbdt==NSOtherMouseDown))
+        {
+          ReleaseCapture();
+          svr->flags.lastButtonDownType = 0;
+        }
+    }    
 
   event = [NSEvent mouseEventWithType: eventType
                             location: eventLocation
Index: Source/win32/w32_movesize.m
===================================================================
--- Source/win32/w32_movesize.m (revision 24952)
+++ Source/win32/w32_movesize.m (working copy)
@@ -302,6 +302,27 @@
    //printf("SIZING called\n");
 
    //return TRUE;
+  NSPoint eventLocation;
+  NSRect rect;
+  RECT r;
+  NSEvent *ev =nil;
+  
+  //GetWindowRect(hwnd, &r);
+  r = *((LPRECT)lParam);
+  
+  rect = MSScreenRectToGS(r, [EVENT_WINDOW(hwnd) styleMask], self);
+  ev = [NSEvent otherEventWithType: NSAppKitDefined
+      location: eventLocation
+      modifierFlags: 0
+      timestamp: 0
+      windowNumber: (int)hwnd
+      context: GSCurrentContext()
+      subtype: GSAppKitWindowResized
+      data1: rect.size.width
+      data2: rect.size.height];
+  NSLog(@"Window SIZING, called with GSAppKitWindowResized and {%d,%d,%d,%d}",
+      r.left, r.top, r.right, r.bottom);
+  [self resizeBackingStoreFor:hwnd];
 }
 
 - (LRESULT) decodeWM_MOVINGParams:(HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam
Index: Headers/win32/WIN32Server.h
===================================================================
--- Headers/win32/WIN32Server.h (revision 24952)
+++ Headers/win32/WIN32Server.h (working copy)
@@ -91,6 +91,7 @@
     BOOL _hasGSClassName;           // does the event window have a GSclassName
     int lastEventType;     
     int hold;
+    int lastButtonDownType;         // the button type of the last mouse down. 
   } serverFlags;
 
 @interface WIN32Server : GSDisplayServer
@@ -171,6 +172,7 @@
 
 typedef struct _win_intern {
   BOOL useHDC;
+  BOOL backingStoreEmpty;
   HDC hdc; 
   HGDIOBJ old;
   MINMAXINFO minmax;

reply via email to

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