[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-optimize
Subject:    Block reading of X properties
From:       Lubos Lunak <l.lunak () suse ! cz>
Date:       2006-08-25 14:29:07
Message-ID: 200608251629.07504.l.lunak () suse ! cz
[Download RAW message or body]

Hello,

 I'm considering adding this optimization to kdelibs but first I'd need more 
testing for it, as it uses some kind of internal code of Xlib and I have no 
idea how it compiles/works on other platforms. Are there still people using 
KDE with some other X than X.org/XFree86? Could you please try if kdelibs 
with this patch compiles and works?

 As for technical details, each XGetWindowProperty() call for reading one X 
property means one X server roundtrip, i.e. sending request to X server and 
waiting for an answer (and the context switches and possibly transferring 
over network and so on). The patch allows grouping of such requests resulting 
in only one roundtrip for the whole group. It doesn't actually save as much 
as I originally expected, but I guess it could be still worth adding it, at 
least for people running remote X (well, since I've already written it 
anyway).

 Thanks

-- 
Lubos Lunak
KDE developer
--------------------------------------------------------------
SUSE LINUX, s.r.o.   e-mail: l.lunak@suse.cz , l.lunak@kde.org
Lihovarska 1060/12   tel: +420 284 028 972
190 00 Prague 9      fax: +420 284 028 951
Czech Republic       http//www.suse.cz

["kdecore.patch" (text/x-diff)]

--- kdecore/kasyncprop.h.sav	2006-08-16 11:52:32.000000000 +0200
+++ kdecore/kasyncprop.h	2006-08-16 13:29:56.000000000 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 1986, 1998  The Open Group
+ * Copyright (C) 2002 Havoc Pennington
+ * Copyright (C) 2006 Lubos Lunak
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation.
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of The Open Group shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from The Open Group.
+ */
+
+#include <X11/Xlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void KXAskWindowProperty( Display *dpy, Window w, Atom property, long offset,
+    long length, Bool del, Atom req_type );
+
+int KXReceiveWindowProperty( Display *dpy, Window w, Atom property, long offset,
+    long length, Bool del, Atom req_type, Atom *actual_type, int *actual_format,
+    unsigned long *nitems, unsigned long *bytesafter, unsigned char **prop );
+
+void KXPropertyCleanup( Display* dpy );
+
+#ifdef __cplusplus
+}
+#endif
--- kdecore/Makefile.am.sav	2006-07-12 17:54:24.000000000 +0200
+++ kdecore/Makefile.am	2006-08-16 11:52:41.000000000 +0200
@@ -59,7 +59,7 @@ include_HEADERS = kconfig.h kconfigskele
 	kcalendarsystem.h kcalendarsystemfactory.h kmacroexpander.h \
 	kmanagerselection.h kmountpoint.h kuser.h klockfile.h \
 	kidna.h ktempdir.h kshell.h fixx11h.h kxerrorhandler.h kdelibs_export.h \
-	kdemacros.h kde_file.h ktimezones.h
+	kdemacros.h kde_file.h ktimezones.h kasyncprop.h
 
 libkdefakes_la_SOURCES = fakes.c vsnprintf.c
 libkdefakes_la_LDFLAGS = -version-info 6:0:2
@@ -113,7 +113,7 @@ libkdecore_la_SOURCES = libintl.cpp kapp
 	ktempdir.cpp kshell.cpp kmountpoint.cpp kcalendarsystemjalali.cpp \
 	kprotocolinfo_kdecore.cpp kprotocolinfofactory.cpp kxerrorhandler.cpp \
 	kuser.cpp kconfigskeleton.cpp kconfigdialogmanager.cpp klockfile.cpp \
-	kqiodevicegzip_p.cpp ktimezones.cpp
+	kqiodevicegzip_p.cpp ktimezones.cpp kasyncprop.c
 
 libkdecore_la_LDFLAGS = $(QT_LDFLAGS) $(KDE_RPATH) $(KDE_MT_LDFLAGS) $(X_LDFLAGS) \
$(USER_LDFLAGS) -version-info 6:0:2 -no-undefined  libkdecore_la_LIBADD = \
malloc/libklmalloc.la network/libkdecorenetwork.la $(SVGICON_LIB) ../dcop/libDCOP.la \
../libltdl/libltdlc.la $(LIB_XEXT) $(LIBRESOLV) $(LIBUTIL) $(LIBART_LIBS) $(LIB_IDN) \
                ../kdefx/libkdefx.la
--- kdecore/netwm.cpp.sav	2006-07-31 16:39:20.000000000 +0200
+++ kdecore/netwm.cpp	2006-08-16 15:14:30.000000000 +0200
@@ -39,6 +39,8 @@
 
 #include "netwm_p.h"
 
+#include <kasyncprop.h>
+
 // UTF-8 string
 static Atom UTF8_STRING = 0;
 
@@ -430,7 +432,8 @@ static void create_atoms(Display *d) {
 }
 
 
-static void readIcon(Display* display, Window window, Atom property, \
NETRArray<NETIcon>& icons, int& icon_count) { +static void readIcon(Display* display, \
Window window, Atom property, +    NETRArray<NETIcon>& icons, int& icon_count, bool \
has_prefetch) {  
 #ifdef    NETWMDEBUG
     fprintf(stderr, "NET: readIcon\n");
@@ -455,10 +458,17 @@ static void readIcon(Display* display, W
 
     // read data
     do {
-	if (XGetWindowProperty(display, window, property, offset,
+        int status;
+        if( has_prefetch )
+	    status = KXReceiveWindowProperty(display, window, property, offset,
 			       MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
-			       &format_ret, &nitems_ret, &after_ret, &data_ret)
-	    == Success) {
+			       &format_ret, &nitems_ret, &after_ret, &data_ret);
+        else
+	    status = XGetWindowProperty(display, window, property, offset,
+			       MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
+			       &format_ret, &nitems_ret, &after_ret, &data_ret);
+        has_prefetch = false;
+	if( status == Success) {
             if (!bufsize)
             {
                if (nitems_ret < 3 || type_ret != XA_CARDINAL ||
@@ -2104,11 +2114,64 @@ void NETRootInfo::update( const unsigned
     const unsigned long& dirty = props[ PROTOCOLS ];
     const unsigned long& dirty2 = props[ PROTOCOLS2 ];
 
+// Property prefetching part. Duplicate calls to KXReceiveWindowProperty()
+// as KXAskWindowProperty() calls here, without the out arguments.
+    if (dirty & Supported )
+        KXAskWindowProperty(p->display, p->root, net_supported,
+                               0l, MAX_PROP_SIZE, False, XA_ATOM);
+    if (dirty & ClientList)
+	KXAskWindowProperty(p->display, p->root, net_client_list,
+			       0l, MAX_PROP_SIZE, False, XA_WINDOW);
+    if (dirty & KDESystemTrayWindows)
+	KXAskWindowProperty(p->display, p->root, kde_net_system_tray_windows,
+			       0l, MAX_PROP_SIZE, False, XA_WINDOW);
+    if (dirty & ClientListStacking)
+	KXAskWindowProperty(p->display, p->root, net_client_list_stacking,
+			       0, MAX_PROP_SIZE, False, XA_WINDOW);
+    if (dirty & NumberOfDesktops)
+	KXAskWindowProperty(p->display, p->root, net_number_of_desktops,
+			       0l, 1l, False, XA_CARDINAL);
+    if (dirty & DesktopGeometry)
+	KXAskWindowProperty(p->display, p->root, net_desktop_geometry,
+			       0l, 2l, False, XA_CARDINAL);
+    if (dirty & DesktopViewport)
+	KXAskWindowProperty(p->display, p->root, net_desktop_viewport,
+			       0l, 2l, False, XA_CARDINAL);
+    if (dirty & CurrentDesktop)
+	KXAskWindowProperty(p->display, p->root, net_current_desktop,
+			       0l, 1l, False, XA_CARDINAL);
+    if (dirty & DesktopNames)
+	KXAskWindowProperty(p->display, p->root, net_desktop_names,
+			       0l, MAX_PROP_SIZE, False, UTF8_STRING);
+    if (dirty & ActiveWindow)
+	KXAskWindowProperty(p->display, p->root, net_active_window, 0l, 1l,
+			       False, XA_WINDOW);
+    if (dirty & WorkArea)
+	KXAskWindowProperty(p->display, p->root, net_workarea, 0l,
+			       MAX_PROP_SIZE, False, XA_CARDINAL);
+    if (dirty & SupportingWMCheck) {
+	KXAskWindowProperty(p->display, p->root, net_supporting_wm_check,
+			       0l, 1l, False, XA_WINDOW);
+        // always prefetch the second property too, it will be made sure the reply
+        // is always read and freed
+	KXAskWindowProperty(p->display, p->supportwindow,
+				       net_wm_name, 0l, MAX_PROP_SIZE, False,
+				       UTF8_STRING);
+    }
+    if (dirty & VirtualRoots)
+	KXAskWindowProperty(p->display, p->root, net_virtual_roots,
+			       0, MAX_PROP_SIZE, False, XA_WINDOW);
+    if (dirty2 & WM2ShowingDesktop)
+	KXAskWindowProperty(p->display, p->root, net_showing_desktop,
+			       0, MAX_PROP_SIZE, False, XA_CARDINAL);
+
+// The fetching part - when you update KXReceiveWindowProperty() calls here,
+// update also the XAskWindowProperty() calls.
     if (dirty & Supported ) {
         // only in Client mode
         for( int i = 0; i < PROPERTIES_SIZE; ++i )
             p->properties[ i ] = 0;
-        if( XGetWindowProperty(p->display, p->root, net_supported,
+        if( KXReceiveWindowProperty(p->display, p->root, net_supported,
                                0l, MAX_PROP_SIZE, False, XA_ATOM, &type_ret,
                                &format_ret, &nitems_ret, &unused, &data_ret)
             == Success ) {
@@ -2126,7 +2189,7 @@ void NETRootInfo::update( const unsigned
 
     if (dirty & ClientList) {
         bool read_ok = false;
-	if (XGetWindowProperty(p->display, p->root, net_client_list,
+	if (KXReceiveWindowProperty(p->display, p->root, net_client_list,
 			       0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2197,7 +2260,7 @@ void NETRootInfo::update( const unsigned
 
     if (dirty & KDESystemTrayWindows) {
         bool read_ok = false;
-	if (XGetWindowProperty(p->display, p->root, kde_net_system_tray_windows,
+	if (KXReceiveWindowProperty(p->display, p->root, kde_net_system_tray_windows,
 			       0l, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2262,7 +2325,7 @@ void NETRootInfo::update( const unsigned
         p->stacking_count = 0;
         delete[] p->stacking;
         p->stacking = NULL;
-	if (XGetWindowProperty(p->display, p->root, net_client_list_stacking,
+	if (KXReceiveWindowProperty(p->display, p->root, net_client_list_stacking,
 			       0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2286,7 +2349,7 @@ void NETRootInfo::update( const unsigned
     if (dirty & NumberOfDesktops) {
 	p->number_of_desktops = 0;
 
-	if (XGetWindowProperty(p->display, p->root, net_number_of_desktops,
+	if (KXReceiveWindowProperty(p->display, p->root, net_number_of_desktops,
 			       0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2305,7 +2368,7 @@ void NETRootInfo::update( const unsigned
 
     if (dirty & DesktopGeometry) {
         p->geometry = p->rootSize;
-	if (XGetWindowProperty(p->display, p->root, net_desktop_geometry,
+	if (KXReceiveWindowProperty(p->display, p->root, net_desktop_geometry,
 			       0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2328,7 +2391,7 @@ void NETRootInfo::update( const unsigned
     if (dirty & DesktopViewport) {
 	for (int i = 0; i < p->viewport.size(); i++)
 	    p->viewport[i].x = p->viewport[i].y = 0;
-	if (XGetWindowProperty(p->display, p->root, net_desktop_viewport,
+	if (KXReceiveWindowProperty(p->display, p->root, net_desktop_viewport,
 			       0l, 2l, False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2362,7 +2425,7 @@ void NETRootInfo::update( const unsigned
 
     if (dirty & CurrentDesktop) {
 	p->current_desktop = 0;
-	if (XGetWindowProperty(p->display, p->root, net_current_desktop,
+	if (KXReceiveWindowProperty(p->display, p->root, net_current_desktop,
 			       0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2383,7 +2446,7 @@ void NETRootInfo::update( const unsigned
         for( int i = 0; i < p->desktop_names.size(); ++i )
             delete[] p->desktop_names[ i ];
         p->desktop_names.reset();
-	if (XGetWindowProperty(p->display, p->root, net_desktop_names,
+	if (KXReceiveWindowProperty(p->display, p->root, net_desktop_names,
 			       0l, MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2411,7 +2474,7 @@ void NETRootInfo::update( const unsigned
 
     if (dirty & ActiveWindow) {
         p->active = None;
-	if (XGetWindowProperty(p->display, p->root, net_active_window, 0l, 1l,
+	if (KXReceiveWindowProperty(p->display, p->root, net_active_window, 0l, 1l,
 			       False, XA_WINDOW, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2430,8 +2493,8 @@ void NETRootInfo::update( const unsigned
 
     if (dirty & WorkArea) {
         p->workarea.reset();
-	if (XGetWindowProperty(p->display, p->root, net_workarea, 0l,
-			       (p->number_of_desktops * 4), False, XA_CARDINAL,
+	if (KXReceiveWindowProperty(p->display, p->root, net_workarea, 0l,
+			       MAX_PROP_SIZE, False, XA_CARDINAL,
 			       &type_ret, &format_ret, &nitems_ret, &unused,
 			       &data_ret)
 	    == Success) {
@@ -2461,7 +2524,8 @@ void NETRootInfo::update( const unsigned
         p->supportwindow = None;
         delete[] p->name;
         p->name = NULL;
-	if (XGetWindowProperty(p->display, p->root, net_supporting_wm_check,
+        bool was_2nd_read = false;
+	if (KXReceiveWindowProperty(p->display, p->root, net_supporting_wm_check,
 			       0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2469,7 +2533,8 @@ void NETRootInfo::update( const unsigned
 		p->supportwindow = *((Window *) data_ret);
 
 		unsigned char *name_ret;
-		if (XGetWindowProperty(p->display, p->supportwindow,
+                was_2nd_read = true;
+		if (KXReceiveWindowProperty(p->display, p->supportwindow,
 				       net_wm_name, 0l, MAX_PROP_SIZE, False,
 				       UTF8_STRING, &type_ret, &format_ret,
 				       &nitems_ret, &unused, &name_ret)
@@ -2490,13 +2555,22 @@ void NETRootInfo::update( const unsigned
 	    if ( data_ret )
 		XFree(data_ret);
 	}
+	if( !was_2nd_read ) { // read the second property if not needed, just in order to \
free the reply +	    unsigned char *name_ret;
+            if( KXReceiveWindowProperty(p->display, p->supportwindow,
+				       net_wm_name, 0l, MAX_PROP_SIZE, False,
+				       UTF8_STRING, &type_ret, &format_ret,
+				       &nitems_ret, &unused, &name_ret) == Success
+                    && name_ret )
+                XFree( name_ret );
+        }
     }
 
     if (dirty & VirtualRoots) {
         p->virtual_roots_count = 0;
         delete[] p->virtual_roots;
         p->virtual_roots = NULL;
-	if (XGetWindowProperty(p->display, p->root, net_virtual_roots,
+	if (KXReceiveWindowProperty(p->display, p->root, net_virtual_roots,
 			       0, MAX_PROP_SIZE, False, XA_WINDOW, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -2518,7 +2592,7 @@ void NETRootInfo::update( const unsigned
 
     if (dirty2 & WM2ShowingDesktop) {
         p->showing_desktop = false;
-	if (XGetWindowProperty(p->display, p->root, net_showing_desktop,
+	if (KXReceiveWindowProperty(p->display, p->root, net_showing_desktop,
 			       0, MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -3748,9 +3822,88 @@ void NETWinInfo::update(const unsigned l
     if( dirty_props[ PROTOCOLS ] & XAWMState )
         props[ PROTOCOLS ] |= XAWMState;
 
+// Property prefetching part. Duplicate calls to KXReceiveWindowProperty()
+// as KXAskWindowProperty() calls here, without the out arguments.
+    if (dirty & XAWMState)
+	KXAskWindowProperty(p->display, p->window, xa_wm_state, 0l, 1l,
+			       False, xa_wm_state);
+    if (dirty & WMState)
+	KXAskWindowProperty(p->display, p->window, net_wm_state, 0l, 2048l,
+			       False, XA_ATOM);
+    if (dirty & WMDesktop)
+	KXAskWindowProperty(p->display, p->window, net_wm_desktop, 0l, 1l,
+			       False, XA_CARDINAL);
+    if (dirty & WMName)
+	KXAskWindowProperty(p->display, p->window, net_wm_name, 0l,
+			       MAX_PROP_SIZE, False, UTF8_STRING);
+    if (dirty & WMVisibleName)
+	KXAskWindowProperty(p->display, p->window, net_wm_visible_name, 0l,
+			       MAX_PROP_SIZE, False, UTF8_STRING);
+    if (dirty & WMIconName)
+	KXAskWindowProperty(p->display, p->window, net_wm_icon_name, 0l,
+			       MAX_PROP_SIZE, False, UTF8_STRING);
+    if (dirty & WMVisibleIconName)
+	KXAskWindowProperty(p->display, p->window, net_wm_visible_icon_name, 0l,
+			       MAX_PROP_SIZE, False, UTF8_STRING);
+    if (dirty & WMWindowType)
+	KXAskWindowProperty(p->display, p->window, net_wm_window_type, 0l, 2048l,
+			       False, XA_ATOM);
+    if (dirty & WMStrut)
+	KXAskWindowProperty(p->display, p->window, net_wm_strut, 0l, 4l,
+			       False, XA_CARDINAL);
+    if (dirty2 & WM2ExtendedStrut)
+	KXAskWindowProperty(p->display, p->window, net_wm_extended_strut, 0l, 12l,
+			       False, XA_CARDINAL);
+    if (dirty & WMIconGeometry)
+	KXAskWindowProperty(p->display, p->window, net_wm_icon_geometry, 0l, 4l,
+			       False, XA_CARDINAL);
+    if (dirty & WMIcon)
+	KXAskWindowProperty(p->display, p->window, net_wm_icon, 0l,
+			       MAX_PROP_SIZE, False, XA_CARDINAL);
+    if (dirty & WMKDESystemTrayWinFor)
+	KXAskWindowProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
+			       0l, 1l, False, XA_WINDOW);
+    if (dirty & WMFrameExtents) {
+	KXAskWindowProperty(p->display, p->window, net_frame_extents,
+			       0l, 4l, False, XA_CARDINAL);
+	KXAskWindowProperty(p->display, p->window, kde_net_wm_frame_strut,
+			       0l, 4l, False, XA_CARDINAL);
+    }
+    if (dirty & WMPid)
+	KXAskWindowProperty(p->display, p->window, net_wm_pid, 0l, 1l,
+			       False, XA_CARDINAL);
+    if (dirty2 & WM2StartupId)
+	KXAskWindowProperty(p->display, p->window, net_startup_id, 0l,
+			       MAX_PROP_SIZE, False, UTF8_STRING);
+    if( dirty2 & WM2AllowedActions )
+	KXAskWindowProperty(p->display, p->window, net_wm_allowed_actions, 0l, 2048l,
+			       False, XA_ATOM);
+    if (dirty2 & WM2UserTime)
+	KXAskWindowProperty(p->display, p->window, net_wm_user_time, 0l, 1l,
+			       False, XA_CARDINAL);
+#if 0
+    if (dirty2 & WM2TransientFor)
+todo
+        XGetTransientForHint(p->display, p->window, &p->transient_for);
+    if (dirty2 & WM2GroupLeader)
+todo
+        XWMHints *hints = XGetWMHints(p->display, p->window);
+    if( dirty2 & WM2WindowClass )
+todo
+        if( XGetClassHint( p->display, p->window, &hint ))
+#endif
+    if( dirty2 & WM2WindowRole )
+	KXAskWindowProperty(p->display, p->window, wm_window_role, 0l,
+			       MAX_PROP_SIZE, False, XA_STRING);
+    if( dirty2 & WM2ClientMachine )
+	KXAskWindowProperty(p->display, p->window, XA_WM_CLIENT_MACHINE, 0l,
+			       MAX_PROP_SIZE, False, XA_STRING);
+
+// The fetching part - when you update KXReceiveWindowProperty() calls here,
+// update also the XAskWindowProperty() calls.
     if (dirty & XAWMState) {
         p->mapping_state = Withdrawn;
-	if (XGetWindowProperty(p->display, p->window, xa_wm_state, 0l, 1l,
+	if (KXReceiveWindowProperty(p->display, p->window, xa_wm_state, 0l, 1l,
 			       False, xa_wm_state, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -3780,7 +3933,7 @@ void NETWinInfo::update(const unsigned l
 
     if (dirty & WMState) {
 	p->state = 0;
-	if (XGetWindowProperty(p->display, p->window, net_wm_state, 0l, 2048l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_state, 0l, 2048l,
 			       False, XA_ATOM, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -3839,7 +3992,7 @@ void NETWinInfo::update(const unsigned l
 
     if (dirty & WMDesktop) {
 	p->desktop = 0;
-	if (XGetWindowProperty(p->display, p->window, net_wm_desktop, 0l, 1l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_desktop, 0l, 1l,
 			       False, XA_CARDINAL, &type_ret,
 			       &format_ret, &nitems_ret,
 			       &unused, &data_ret)
@@ -3861,7 +4014,7 @@ void NETWinInfo::update(const unsigned l
     if (dirty & WMName) {
         delete[] p->name;
         p->name = NULL;
-	if (XGetWindowProperty(p->display, p->window, net_wm_name, 0l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_name, 0l,
 			       MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -3877,7 +4030,7 @@ void NETWinInfo::update(const unsigned l
     if (dirty & WMVisibleName) {
         delete[] p->visible_name;
         p->visible_name = NULL;
-	if (XGetWindowProperty(p->display, p->window, net_wm_visible_name, 0l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_visible_name, 0l,
 			       MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -3893,7 +4046,7 @@ void NETWinInfo::update(const unsigned l
     if (dirty & WMIconName) {
         delete[] p->icon_name;
         p->icon_name = NULL;
-	if (XGetWindowProperty(p->display, p->window, net_wm_icon_name, 0l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_icon_name, 0l,
 			       MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -3910,7 +4063,7 @@ void NETWinInfo::update(const unsigned l
     {
         delete[] p->visible_icon_name;
         p->visible_icon_name = NULL;
-	if (XGetWindowProperty(p->display, p->window, net_wm_visible_icon_name, 0l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_visible_icon_name, 0l,
 			       MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -3927,7 +4080,7 @@ void NETWinInfo::update(const unsigned l
 	p->types.reset();
 	p->types[ 0 ] = Unknown;
         p->has_net_support = false;
-	if (XGetWindowProperty(p->display, p->window, net_wm_window_type, 0l, 2048l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_window_type, 0l, 2048l,
 			       False, XA_ATOM, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -3987,7 +4140,7 @@ void NETWinInfo::update(const unsigned l
 
     if (dirty & WMStrut) {
         p->strut = NETStrut();
-	if (XGetWindowProperty(p->display, p->window, net_wm_strut, 0l, 4l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_strut, 0l, 4l,
 			       False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -4006,7 +4159,7 @@ void NETWinInfo::update(const unsigned l
 
     if (dirty2 & WM2ExtendedStrut) {
         p->extended_strut = NETExtendedStrut();
-	if (XGetWindowProperty(p->display, p->window, net_wm_extended_strut, 0l, 12l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_extended_strut, 0l, 12l,
 			       False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -4033,7 +4186,7 @@ void NETWinInfo::update(const unsigned l
 
     if (dirty & WMIconGeometry) {
         p->icon_geom = NETRect();
-	if (XGetWindowProperty(p->display, p->window, net_wm_icon_geometry, 0l, 4l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_icon_geometry, 0l, 4l,
 			       False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -4051,12 +4204,12 @@ void NETWinInfo::update(const unsigned l
     }
 
     if (dirty & WMIcon) {
-	readIcon(p->display,p->window,net_wm_icon,p->icons,p->icon_count);
+	readIcon(p->display,p->window,net_wm_icon,p->icons,p->icon_count, true);
     }
 
     if (dirty & WMKDESystemTrayWinFor) {
 	p->kde_system_tray_win_for = 0;
-	if (XGetWindowProperty(p->display, p->window, kde_net_wm_system_tray_window_for,
+	if (KXReceiveWindowProperty(p->display, p->window, \
kde_net_wm_system_tray_window_for,  0l, 1l, False, XA_WINDOW, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -4074,7 +4227,7 @@ void NETWinInfo::update(const unsigned l
     if (dirty & WMFrameExtents) {
         p->frame_strut = NETStrut();
         bool ok = false;
-	if (XGetWindowProperty(p->display, p->window, net_frame_extents,
+	if (KXReceiveWindowProperty(p->display, p->window, net_frame_extents,
 			       0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret) == Success) {
 	    if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
@@ -4089,10 +4242,12 @@ void NETWinInfo::update(const unsigned l
 	    if ( data_ret )
 		XFree(data_ret);
         }
-	if (!ok && XGetWindowProperty(p->display, p->window, kde_net_wm_frame_strut,
+        // the !ok check is intentionally done only later, so that \
KXReceiveWindowProperty() +        // always reads the received reply
+	if (KXReceiveWindowProperty(p->display, p->window, kde_net_wm_frame_strut,
 			       0l, 4l, False, XA_CARDINAL, &type_ret, &format_ret,
-			       &nitems_ret, &unused, &data_ret) == Success) {
-	    if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
+			       &nitems_ret, &unused, &data_ret) == Success ) {
+	    if (!ok && type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 4) {
                 ok = true;
 		long *d = (long *) data_ret;
 
@@ -4108,7 +4263,7 @@ void NETWinInfo::update(const unsigned l
 
     if (dirty & WMPid) {
 	p->pid = 0;
-	if (XGetWindowProperty(p->display, p->window, net_wm_pid, 0l, 1l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_pid, 0l, 1l,
 			       False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret) == Success) {
 	    if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1) {
@@ -4123,7 +4278,7 @@ void NETWinInfo::update(const unsigned l
     {
         delete[] p->startup_id;
         p->startup_id = NULL;
-	if (XGetWindowProperty(p->display, p->window, net_startup_id, 0l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_startup_id, 0l,
 			       MAX_PROP_SIZE, False, UTF8_STRING, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -4138,7 +4293,7 @@ void NETWinInfo::update(const unsigned l
 
     if( dirty2 & WM2AllowedActions ) {
         p->allowed_actions = 0;
-	if (XGetWindowProperty(p->display, p->window, net_wm_allowed_actions, 0l, 2048l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_allowed_actions, 0l, \
2048l,  False, XA_ATOM, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -4189,7 +4344,7 @@ void NETWinInfo::update(const unsigned l
 
     if (dirty2 & WM2UserTime) {
 	p->user_time = -1U;
-	if (XGetWindowProperty(p->display, p->window, net_wm_user_time, 0l, 1l,
+	if (KXReceiveWindowProperty(p->display, p->window, net_wm_user_time, 0l, 1l,
 			       False, XA_CARDINAL, &type_ret, &format_ret,
 			       &nitems_ret, &unused, &data_ret) == Success) {
             // don't do nitems_ret check - Qt does PropModeAppend to avoid API call \
for it @@ -4234,7 +4389,7 @@ void NETWinInfo::update(const unsigned l
     if( dirty2 & WM2WindowRole ) {
         delete[] p->role;
         p->role = NULL;
-	if (XGetWindowProperty(p->display, p->window, wm_window_role, 0l,
+	if (KXReceiveWindowProperty(p->display, p->window, wm_window_role, 0l,
 			       MAX_PROP_SIZE, False, XA_STRING, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
@@ -4249,7 +4404,7 @@ void NETWinInfo::update(const unsigned l
     if( dirty2 & WM2ClientMachine ) {
         delete[] p->client_machine;
         p->client_machine = NULL;
-	if (XGetWindowProperty(p->display, p->window, XA_WM_CLIENT_MACHINE, 0l,
+	if (KXReceiveWindowProperty(p->display, p->window, XA_WM_CLIENT_MACHINE, 0l,
 			       MAX_PROP_SIZE, False, XA_STRING, &type_ret,
 			       &format_ret, &nitems_ret, &unused, &data_ret)
 	    == Success) {
--- kdecore/kapplication.cpp.sav	2006-07-12 18:46:20.000000000 +0200
+++ kdecore/kapplication.cpp	2006-08-16 14:23:51.000000000 +0200
@@ -77,6 +77,7 @@
 
 #if defined Q_WS_X11
 #include <kstartupinfo.h>
+#include <kasyncprop.h>
 #endif
 
 #include <dcopclient.h>
@@ -1663,6 +1664,11 @@ KApplication::~KApplication()
 #else
   // FIXME(E): Implement for Qt Embedded
 #endif
+
+#ifdef Q_WS_X11
+  if (Tty != kapp->type())
+    KXPropertyCleanup( qt_xdisplay());
+#endif
 }
 
 
--- kdecore/configure.in.in.sav	2005-11-30 16:54:00.000000000 +0100
+++ kdecore/configure.in.in	2006-08-16 12:28:39.000000000 +0200
@@ -231,3 +231,5 @@ AC_TRY_LINK(dnl
       ],
       AC_MSG_RESULT(no)
 )
+
+KDE_CHECK_HEADER(X11/Xlib.h, [AC_DEFINE(HAVE_X11_XLIB_H,1,[Define to 1 if you have \
                the <X11/Xlib.h> header file.])])
--- kdecore/kasyncprop.c.sav	2006-08-16 11:47:21.000000000 +0200
+++ kdecore/kasyncprop.c	2006-08-16 15:49:59.000000000 +0200
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 1986, 1998  The Open Group
+ * Copyright (C) 2002 Havoc Pennington
+ * Copyright (C) 2006 Lubos Lunak
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation.
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of The Open Group shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from The Open Group.
+ */
+
+#include "kasyncprop.h"
+
+#include "kdelibs_export.h"
+
+#include <config.h>
+#ifdef HAVE_X11_XLIB_H
+
+/* This code is a replacement for XGetWindowProperty() that allows batching
+   of the requests - normally every single XGetWindowProperty() means one
+   Xserver roundtrip. For several XGetWindowProperty() calls it's better
+   to replace them by a series of XAskWindowProperty() calls that will
+   request the properties and then a series of matching XReceiveWindowProperty()
+   calls to actually retrieve the properties. Such a batch of requests
+   causes only one Xserver roundtrip.
+*/
+
+
+/*#define NEED_REPLIES*/
+#include <X11/Xlibint.h>
+
+#include <stdio.h>
+
+typedef struct _XPropertyData {
+    struct _XPropertyData* next;
+    Window window;
+    Atom property;
+    Bool delete;
+    Atom req_type;
+    Atom actual_type;
+    int actual_format;
+    long offset;
+    long length;
+    unsigned long nitems;
+    unsigned long bytesafter;
+    char* prop;
+    int status;
+    unsigned long sequence;
+} _XPropertyData;
+
+static _XPropertyData* data_pending;
+static _XPropertyData** data_pending_last;
+static _XPropertyData* data_done;
+static _XPropertyData** data_done_last;
+static _XAsyncHandler async;
+static unsigned long last_reply;
+
+#define LIST_REMOVE_ITEM( item, pos, last ) \
+    *pos = item->next; \
+    if( last == &item->next ) \
+        last = pos;
+
+#define LIST_APPEND_ITEM( item, last ) \
+    *last = item; \
+    item->next = NULL; \
+    last = &(item->next);
+
+static _XPropertyData* _XPropertyRemovePending( unsigned long sequenceNumber )
+{
+#if 1
+/* Replies come in the same order like requests were sent, so just pick the first \
one. */ +    if( data_pending == NULL )
+        return NULL;
+    if( data_pending->sequence == sequenceNumber )
+        {
+        _XPropertyData* item = data_pending;
+        _XPropertyData** pos = &data_pending;
+        LIST_REMOVE_ITEM( item, pos, data_pending_last )
+        LIST_APPEND_ITEM( item, data_done_last )
+        return item;
+        }
+    return NULL;
+#else
+    _XPropertyData** pos = &data_pending;
+    while( *pos != NULL )
+        {
+        if( (*pos)->sequence == sequenceNumber )
+            {
+            _XPropertyData* item = *pos;
+            LIST_REMOVE_ITEM( item, pos, data_pending_last )
+            LIST_APPEND_ITEM( item, data_done_last )
+            return item;
+            }
+        pos = &((*pos)->next);
+        }
+    return NULL;
+#endif
+}
+
+static Bool _XPropertyHandler( Display* dpy, xReply* rep, char* buf, int len, \
XPointer data ) +{
+    xGetPropertyReply replbuf;
+    register xGetPropertyReply *repl;
+    _XPropertyData* item;
+    
+    (void)data;
+    (void)dpy;
+
+    /* rep->generic.sequenceNumber contains only lowest 16bits of the sequence,
+       use dpy->last_request_read */
+    item = _XPropertyRemovePending( dpy->last_request_read );
+    if( item == NULL ) /* not a reply to our request */
+        return False;
+
+/*
+ TODO: remove old replies that haven't been read using XReceiveWindowProperty()
+ for some reason? Sequence numbers wrap around and there's a tiny chance old
+ values could be reused. Additionally keeping old values wastes memory (although
+ failing to use matching XReceiveWindowProperty() is considered to be an error).
+*/
+    if (rep->generic.type == X_Error) {
+/* Metacity here discards the error, arguing that async API should not require
+   synchronous trapping of errors, but I disagree. This API is meant for
+   reading data in bursts, so it kind of is synchronous anyway. */
+        item->status = rep->error.errorCode;
+        return False;
+    }
+    repl = (xGetPropertyReply *)
+	_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
+			(SIZEOF(xGetPropertyReply) - SIZEOF(xReply)) >> 2,
+			False);
+    item->prop = NULL;
+    if (repl->propertyType != None) {
+	long nbytes, netbytes;
+	switch (repl->format) {
+      /* 
+       * One extra byte is malloced than is needed to contain the property
+       * data, but this last byte is null terminated and convenient for 
+       * returning string properties, so the client doesn't then have to 
+       * recopy the string to make it null terminated. 
+       */
+	  case 8:
+	    nbytes = netbytes = repl->nItems;
+            netbytes = ( netbytes + 3 ) & ~3; /* align to 4 */
+	    if (nbytes + 1 > 0 &&
+		(item->prop = Xmalloc ((unsigned)nbytes + 1))) {
+                _XGetAsyncData(dpy, item->prop, buf, len,
+		   SIZEOF(xGetPropertyReply), nbytes,
+		   netbytes);
+            }
+	    break;
+
+	  case 16:
+	    nbytes = repl->nItems * sizeof (short);
+	    netbytes = repl->nItems << 1;
+            netbytes = ( netbytes + 3 ) & ~3; /* align to 4 */
+	    if (nbytes + 1 > 0 &&
+		(item->prop = Xmalloc ((unsigned)nbytes + 1))) {
+                _XGetAsyncData(dpy, item->prop, buf, len,
+		   SIZEOF(xGetPropertyReply), nbytes,
+		   netbytes);
+            }
+	    break;
+
+	  case 32:
+	    nbytes = repl->nItems * sizeof (long);
+	    netbytes = repl->nItems << 2;
+	    if (nbytes + 1 > 0 &&
+		(item->prop = Xmalloc ((unsigned)nbytes + 1))) {
+                if( sizeof( long ) == 4 ) {
+                    _XGetAsyncData(dpy, item->prop, buf, len,
+		       SIZEOF(xGetPropertyReply), nbytes,
+		       netbytes);
+                } else {  /* format 32 is long even on 64bit platforms */
+                    _XGetAsyncData(dpy, item->prop, buf, len,
+		       SIZEOF(xGetPropertyReply), netbytes,
+		       netbytes);
+                    long* dst = (( long* ) item->prop ) + repl->nItems - 1;
+                    CARD32* src = (( CARD32* ) item->prop ) + repl->nItems - 1;
+                    int i;
+                    for( i = repl->nItems;
+                         i > 0;
+                         --i )
+                        *dst-- = *src--;
+                }
+            }
+	    break;
+
+	  default:
+	    /*
+	     * This part of the code should never be reached.  If it is,
+	     * the server sent back a property with an invalid format.
+	     * This is a BadImplementation error. 
+	     */
+            item->status = BadImplementation;
+	    nbytes = netbytes = 0L;
+	    break;
+	}
+	if (! item->prop) {
+            _XGetAsyncData(dpy, NULL, buf, len,
+		   SIZEOF(xGetPropertyReply), 0,
+		   netbytes);
+
+            item->status = BadAlloc;	/* not Success */
+            return True;
+	}
+	(item->prop)[nbytes] = '\0';
+    }
+    item->actual_type = repl->propertyType;
+    item->actual_format = repl->format;
+    item->nitems = repl->nItems;
+    item->bytesafter = repl->bytesAfter;
+    return True;
+}
+
+static int init = 0;
+
+static void XPropertyInit( Display* dpy )
+{
+    LockDisplay(dpy);
+    if( init )
+        {
+        UnlockDisplay(dpy);
+        return;
+        }
+    init = 1;
+/*    fprintf(stderr,"Init: %ld\n", dpy->request ); */
+    data_pending = NULL;
+    data_pending_last = &data_pending;
+    data_done = NULL;
+    data_done_last = &data_done;
+    last_reply = dpy->last_request_read;
+    async.next = dpy->async_handlers;
+    async.handler = _XPropertyHandler;
+    async.data = NULL;
+    dpy->async_handlers = &async;
+    UnlockDisplay(dpy);
+}
+
+static int _XPropertyGetReply( Window w, Atom property, long offset, long length, \
Bool delete,  +    Atom req_type, Atom* actual_type, int* actual_format, unsigned \
long* nitems, +    unsigned long* bytesafter, unsigned char** prop, int* status )
+{
+    _XPropertyData** pos;
+    for( pos = &data_done;
+         *pos != NULL;
+         pos = &((*pos)->next))
+        {
+        _XPropertyData* item = *pos;
+        if( item->window != w )
+            continue;
+        if( item->property != property )
+            continue;
+        if( item->delete != delete
+            || item->req_type != req_type
+            || item->offset != offset
+            || item->length != length )
+            continue;
+        /* found */
+        *actual_type = item->actual_type;
+        *actual_format = item->actual_format;
+        *nitems = item->nitems;
+        *bytesafter = item->bytesafter;
+        *prop = ( unsigned char* )item->prop;
+        *status = item->status;
+        LIST_REMOVE_ITEM( item, pos, data_done_last )
+        XFree( item );
+        return True;
+        }
+    return False;
+}
+
+
+KDECORE_EXPORT void KXAskWindowProperty( Display* dpy, Window w, Atom property, long \
offset, +    long length, Bool delete, Atom req_type )
+{
+    register xGetPropertyReq *req;
+    _XPropertyData* item;
+
+    XPropertyInit( dpy );
+
+    LockDisplay(dpy);
+
+    GetReq (GetProperty, req);
+    req->window = w;
+    req->property = property;
+    req->type = req_type;
+    req->delete = delete;
+    req->longOffset = offset;
+    req->longLength = length;
+    item = Xmalloc( sizeof( _XPropertyData ));
+    item->window = w;
+    item->property = property;
+    item->delete = delete;
+    item->req_type = req_type;
+    item->actual_type = None;
+    item->actual_format = 0;
+    item->offset = offset;
+    item->length = length;
+    item->nitems = 0;
+    item->bytesafter = 0;
+    item->prop = NULL;
+    item->status = Success;
+    item->sequence = dpy->request;
+    LIST_APPEND_ITEM( item, data_pending_last )
+/*    fprintf( stderr, "Ask: 0x%ld 0x%ld %ld\n", w, property, dpy->request );*/
+    UnlockDisplay(dpy);
+    SyncHandle();
+}
+
+KDECORE_EXPORT int KXReceiveWindowProperty( Display* dpy, Window w, Atom property, \
long offset, +    long length, Bool delete, Atom req_type, Atom* actual_type, int* \
actual_format, +    unsigned long* nitems, unsigned long* bytesafter, unsigned char** \
prop ) +{
+    int ret;    
+
+    XPropertyInit( dpy );
+
+/*    fprintf( stderr, "Receive: 0x%ld 0x%ld\n", w, property ); */
+
+    LockDisplay(dpy);
+
+    if( _XPropertyGetReply( w, property, offset, length, delete, req_type,
+        actual_type, actual_format, nitems, bytesafter, prop, &ret ))
+        {
+/*        fprintf( stderr, "Receive1\n" ); */
+        UnlockDisplay(dpy);
+        return ret;
+        }
+
+    /*
+     * XSync (dpy, 0)
+     */
+    {
+	xGetInputFocusReply rep;
+	register xReq *req;
+
+	GetEmptyReq(GetInputFocus, req);
+	(void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
+    }
+
+    /* check again, after sync */
+    if( _XPropertyGetReply( w, property, offset, length, delete, req_type,
+        actual_type, actual_format, nitems, bytesafter, prop, &ret ))
+        {
+/*        fprintf( stderr, "Receive2\n" ); */
+        UnlockDisplay(dpy);
+        SyncHandle();
+        return ret;
+        }
+/*    fprintf( stderr, "Receive3\n" ); */
+    UnlockDisplay(dpy);
+    SyncHandle();
+    return BadValue; /* this should not(?) happen */
+}
+
+KDECORE_EXPORT void KXPropertyCleanup( Display* dpy )
+{
+    _XPropertyData* pos;
+    _XPropertyData* pos2;
+    XSync( dpy, False );
+    LockDisplay(dpy);
+    if( init )
+        {
+        int pending = 0;
+        int done = 0;
+        DeqAsyncHandler(dpy, &async);
+        pos = data_pending;
+        while( pos != NULL )
+            {
+            pos2 = pos->next;
+            XFree( pos );
+            pos = pos2;
+            ++pending;
+            }
+        pos = data_done;
+        while( pos != NULL )
+            {
+            pos2 = pos->next;
+            XFree( pos );
+            pos = pos2;
+            ++done;
+            }
+#ifndef NDEBUG
+        if( pending > 0 || done > 0 )
+            fprintf(stderr,"XAskWindowProperty cleanup: %d pending requests, %d \
pending replies\n", pending, done ); +#endif
+        init = 0;
+        }
+    UnlockDisplay(dpy);
+}
+#endif



_______________________________________________
Kde-optimize mailing list
Kde-optimize@kde.org
https://mail.kde.org/mailman/listinfo/kde-optimize


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic