public inbox for cygwin-xfree@sourceware.org
help / color / mirror / Atom feed
From: Oliver Schmidt <oschmidt-mailinglists@gmx.de>
To: cygwin-xfree@cygwin.com
Subject: redraw windows while  resizing/moving windows in multiwindow mode
Date: Sat, 20 Aug 2011 22:41:00 -0000	[thread overview]
Message-ID: <4E50380A.6070101@gmx.de> (raw)

[-- Attachment #1: Type: text/plain, Size: 1493 bytes --]

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

[-- Attachment #2: patch05.txt --]
[-- Type: text/plain, Size: 4475 bytes --]

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 */


[-- Attachment #3: Type: text/plain, Size: 223 bytes --]

--
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/

             reply	other threads:[~2011-08-20 22:41 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-20 22:41 Oliver Schmidt [this message]
2011-09-07 15:06 ` Jon TURNEY
2011-09-08 13:09   ` Oliver Schmidt
2011-10-13 13:09     ` Jon TURNEY

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E50380A.6070101@gmx.de \
    --to=oschmidt-mailinglists@gmx.de \
    --cc=cygwin-xfree@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).