gnustep-dev
[Top][All Lists]
Advanced

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

Re: Window managers


From: Fred Kiefer
Subject: Re: Window managers
Date: Mon, 09 Apr 2007 14:01:13 +0200
User-agent: Thunderbird 1.5.0.10 (X11/20060911)

Hi Christopher,

I am not sure if capturing the mouse is a great idea. I understand that
we have the problem with Windows of not getting a mouse up event when
the mouse leaves the current window. But this should be handled on
another level. In most cases we are not interested in a mouse up, so why
always capture it? This could disturb the interaction with other
applications.

As for the change in windowbacking:, I could prove to you that it is not
needed. But if you feel more comfortable with explicit code, it is fine
for me.

I feel a bit uncomfortable with the change to invalidateWindow(). This
looks like a potential recursion problem. The back end here asks the
front end to do some drawing and this of course will ask the back end to
do it. I think it wont loop, but still it looks a bit dangerous. Perhaps
some simplification and documentation of the code would help here.
It looks like invalidateWindow is now only used in
decodeWM_PAINTParams:::. So why not move the code to here?

Cheers,
Fred

Christopher Armstrong wrote:
> 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;
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Discuss-gnustep mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/discuss-gnustep





reply via email to

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