From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26651 invoked by alias); 20 Aug 2011 22:41:36 -0000 Received: (qmail 26638 invoked by uid 22791); 20 Aug 2011 22:41:32 -0000 X-SWARE-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mailout-de.gmx.net (HELO mailout-de.gmx.net) (213.165.64.22) by sourceware.org (qpsmtpd/0.43rc1) with SMTP; Sat, 20 Aug 2011 22:41:18 +0000 Received: (qmail invoked by alias); 20 Aug 2011 22:41:15 -0000 Received: from p5B08E997.dip0.t-ipconnect.de (EHLO [192.168.178.47]) [91.8.233.151] by mail.gmx.net (mp064) with SMTP; 21 Aug 2011 00:41:15 +0200 Message-ID: <4E50380A.6070101@gmx.de> Date: Sat, 20 Aug 2011 22:41:00 -0000 From: Oliver Schmidt User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20110812 Thunderbird/6.0 MIME-Version: 1.0 To: cygwin-xfree@cygwin.com Subject: redraw windows while resizing/moving windows in multiwindow mode Content-Type: multipart/mixed; boundary="------------000706060001040702000305" X-IsSubscribed: yes Mailing-List: contact cygwin-xfree-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-xfree-owner@cygwin.com Reply-To: cygwin-xfree@cygwin.com Mail-Followup-To: cygwin-xfree@cygwin.com X-SW-Source: 2011-08/txt/msg00049.txt.bz2 --------------000706060001040702000305 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1493 Hi, the following patch is a quick & dirty hack to enable redrawing of windows while the user moves or resizes the window. This patch should be seen as experimental proof that this can be done with only small changes in the source code. The main problem with window resizing/moving under Windows is, that in the function invocation stack dix/Dispatch -> os/WaitForSomething -> WakeupHandler -> hw/xwin/winWakeupHandler -> Windows/DispatchMessage -> hw/xwin/winTopLevelWindowProc the Windows function DispatchMessage does not return while the user resizes/moves a window. This function only returns after the user releases the mouse button. However the dix/Dispatch functions must be run to allow the clients to process the queued redraw/resizing events. The enclosed hack simply moves the invocation of DispatchMessage in winWakeupHandler outside WaitForSomething into Dispatch and breaks up the Dispatch function into a loop and inner dispatch handling that can be called from the winTopLevelWindowProc while WM_SIZE/WM_MOVE events are processed. This could further be improved by setting a windows timer while resizing moving to process clients messages even if the mouse is not moved while resizing (and therefore WM_SIZE/WM_MOVE events are not send). What do you think about this idea? One problem here is, that the dix package is also affected. Of course some work must be done to cleanly integrate this into the existing dix/hw architecture. Best regards, Oliver --------------000706060001040702000305 Content-Type: text/plain; name="patch05.txt" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="patch05.txt" Content-length: 4475 diff --git a/cygwin/dix/dispatch.c b/cygwin/dix/dispatch.c index 44f8087..18e9697 100644 --- a/cygwin/dix/dispatch.c +++ b/cygwin/dix/dispatch.c @@ -343,33 +343,27 @@ DisableLimitedSchedulingLatency(void) #define MAJOROP ((xReq *)client->requestBuffer)->reqType -void -Dispatch(void) -{ - int *clientReady; /* array of request ready clients */ - int result; - ClientPtr client; - int nready; - HWEventQueuePtr* icheck = checkForInput; - long start_tick; +static int *clientReady; /* array of request ready clients */ +static int result; +static ClientPtr client; +static int nready; +static HWEventQueuePtr* icheck = checkForInput; +static long start_tick; - nextFreeClientID = 1; - nClients = 0; - - clientReady = malloc(sizeof(int) * MaxClients); - if (!clientReady) - return; - - SmartScheduleSlice = SmartScheduleInterval; - while (!dispatchException) - { +int DispatchOneStep(Bool handleWindowMessage) +{ + int rslt = 0; + if (*icheck[0] != *icheck[1]) { ProcessInputEvents(); FlushIfCriticalOutputPending(); } - nready = WaitForSomething(clientReady); + rslt = nready; + + if (handleWindowMessage) + handleNextWindowMessage(); if (nready && !SmartScheduleDisable) { @@ -460,6 +454,24 @@ Dispatch(void) client->smart_stop_tick = SmartScheduleTime; } dispatchException &= ~DE_PRIORITYCHANGE; + + return rslt; +} + +void +Dispatch(void) +{ + nextFreeClientID = 1; + nClients = 0; + + clientReady = malloc(sizeof(int) * MaxClients); + if (!clientReady) + return; + + SmartScheduleSlice = SmartScheduleInterval; + while (!dispatchException) + { + DispatchOneStep(TRUE); } if (ddxHooks.ddxBeforeReset) diff --git a/cygwin/hw/xwin/winmultiwindowwndproc.c b/cygwin/hw/xwin/winmultiwindowwndproc.c index bd84c05..265fdcc 100644 --- a/cygwin/hw/xwin/winmultiwindowwndproc.c +++ b/cygwin/hw/xwin/winmultiwindowwndproc.c @@ -321,6 +321,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message, static Bool s_fTracking = FALSE; Bool needRestack = FALSE; LRESULT ret; + static Bool hasEnteredSizeMove = FALSE; #if CYGDEBUG winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam); @@ -871,7 +872,15 @@ winTopLevelWindowProc (HWND hwnd, UINT message, case WM_MOVE: /* Adjust the X Window to the moved Windows window */ - winAdjustXWindow (pWin, hwnd); + if (!hasEnteredSizeMove) + { + winAdjustXWindow (pWin, hwnd); + } + else + { + winAdjustXWindow (pWin, hwnd); + while (DispatchOneStep(FALSE) > 0) {} + } return 0; case WM_SHOWWINDOW: @@ -1012,6 +1021,16 @@ winTopLevelWindowProc (HWND hwnd, UINT message, */ break; + case WM_ENTERSIZEMOVE: + hasEnteredSizeMove = TRUE; + return 0; + + case WM_EXITSIZEMOVE: + /* Adjust the X Window to the moved Windows window */ + hasEnteredSizeMove = FALSE; + winAdjustXWindow (pWin, hwnd); + return 0; + case WM_SIZE: /* see dix/window.c */ #if CYGWINDOWING_DEBUG @@ -1036,9 +1055,17 @@ winTopLevelWindowProc (HWND hwnd, UINT message, (int)(GetTickCount ())); } #endif - /* Adjust the X Window to the moved Windows window */ - winAdjustXWindow (pWin, hwnd); - if (wParam == SIZE_MINIMIZED) winReorderWindowsMultiWindow(); + if (!hasEnteredSizeMove) + { + /* Adjust the X Window to the moved Windows window */ + winAdjustXWindow (pWin, hwnd); + if (wParam == SIZE_MINIMIZED) winReorderWindowsMultiWindow(); + } + else + { + winAdjustXWindow (pWin, hwnd); + while (DispatchOneStep(FALSE) > 0) {} + } return 0; /* end of WM_SIZE handler */ case WM_STYLECHANGING: diff --git a/cygwin/hw/xwin/winwakeup.c b/cygwin/hw/xwin/winwakeup.c index 031a510..6eab76a 100644 --- a/cygwin/hw/xwin/winwakeup.c +++ b/cygwin/hw/xwin/winwakeup.c @@ -43,6 +43,14 @@ winWakeupHandler (int nScreen, unsigned long ulResult, pointer pReadmask) { + /* was: handleNextWindowMessage, but + this will block in WaitForSomething when + moving resizing windows in multiwindow + mode. */ +} + +void handleNextWindowMessage(void) +{ MSG msg; /* Process one message from our queue */ --------------000706060001040702000305 Content-Type: text/plain; charset=us-ascii Content-length: 223 -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/ --------------000706060001040702000305--