Around 15 o'clock on Nov 6, Owen Taylor wrote:
> Last time I talked to Keith about this, he had the idea that perhaps
> when one client configures the window of another client, the priority
> of the second client should be increased.
I've got that patch in my X server right now, and frankly it doesn't help
as much as I'd hoped. I've attached a diff if you'd like to give it a
whirl. If it is useful, I can just stick it into CVS; it's cheap enough.
As you can see, it takes effect when an application configures or maps
another applications window; tracing your window manager will tell you if
this is sufficient, or if additional requests need to be so instrumented.
-keith
Index: dispatch.c
===================================================================
RCS file: /home/x-cvs/xc/programs/Xserver/dix/dispatch.c,v
retrieving revision 3.27
diff -u -r3.27 dispatch.c
--- dispatch.c 19 Feb 2002 11:09:21 -0000 3.27
+++ dispatch.c 26 Jun 2002 17:31:35 -0000
@@ -344,6 +344,45 @@
}
return best;
}
+
+/*
+ * When a window manager manipulates a client window,
+ * swap scheduling priority between the two so that the
+ * client runs next.
+ */
+void
+SmartScheduleYield (ClientPtr current_client, XID next_rid)
+{
+ int next_index = CLIENT_ID (next_rid);
+ ClientPtr next_client;
+
+ if (next_index && (next_client = clients[next_index]) &&
+ next_client != current_client)
+ {
+ if (current_client->smart_priority > 0)
+ {
+ long bonus = current_client->smart_priority;
+#if 0
+ ErrorF ("0x%x/%d yielding to 0x%x/%d\n",
+ current_client->clientAsMask,
+ current_client->smart_priority,
+ next_client->clientAsMask,
+ next_client->smart_priority);
+#endif
+ current_client->smart_priority = 0;
+ next_client->smart_priority += bonus;
+ if (next_client->smart_priority > SMART_MAX_PRIORITY)
+ next_client->smart_priority = SMART_MAX_PRIORITY;
+ }
+ }
+
+}
+#define CHECK_YIELDTO(c,id) (((c)->clientAsMask != ((id) & ~RESOURCE_ID_MASK))?\
+ SmartScheduleYield((c),(id)) : (void) 0)
+#endif
+
+#ifndef CHECK_YIELDTO
+#define CHECK_YIELDTO(c,id)
#endif
#define MAJOROP ((xReq *)client->requestBuffer)->reqType
@@ -686,6 +725,7 @@
if (!pWin)
return(BadWindow);
MapWindow(pWin, client);
+ CHECK_YIELDTO(client,stuff->id);
/* update cache to say it is mapped */
return(client->noClientException);
}
@@ -759,6 +799,7 @@
return BadLength;
result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
client);
+ CHECK_YIELDTO(client,stuff->window);
if (client->noClientException != Success)
return(client->noClientException);
else