[Top][All Lists]
[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
- Re: Window managers,
Fred Kiefer <=