Results 1 to 7 of 7
i'm writing a program that does a couple nested XQueryTree's to find window IDs based on window names.
at initialization it works just fine getting the ID's of 3 windows.
...
- 04-30-2008 #1Just Joined!
- Join Date
- Apr 2008
- Posts
- 4
XLib - XQueryTree fails -- help
i'm writing a program that does a couple nested XQueryTree's to find window IDs based on window names.
at initialization it works just fine getting the ID's of 3 windows.
the problem comes later on in execution where an event triggers another query using the same C function as used before... however this time if fails by having XQueryTree returning a 0. i'm sending the same Display Pointer and Root Window ID...
is there any way to determine why XQueryTree is returning 0? or any ideas why it might be failing?
thanks a bunch in advance.
- 04-30-2008 #2
According to the O'Reilly XLib Reference Manual, the only possible error is BadWindow.
Could you possibly log somewhere the actual values of the first two parameters to XQueryTree just before you call it, both at the beginning (where it works) and later (where it fails), just to make sure they haven't changed? That's what I would do next, anyway.--
Bill
Old age and treachery will overcome youth and skill.
- 04-30-2008 #3Just Joined!
- Join Date
- Apr 2008
- Posts
- 4
the values of the first two arguments (Display Pointer and Root Window) are EXACTLY the same when it works and when it doesn't...
here's what i have that breaks....
Code:Window find_window_id(char *app_name, int repeat) { Window root_return, parent_return, *children_return, *chld_tmp, ret_val; int nchildren_return, tmp, i, j; int found = 0; char *win_name; do { if (XQueryTree(dpy, X_Root_Window, &root_return, &parent_return, &children_return, &nchildren_return)) { for (i=0; i < nchildren_return; i++) { XQueryTree(dpy, children_return[i], &root_return, &parent_return, &chld_tmp, &tmp); for (j=0; j < tmp; j++) { if (XFetchName(dpy, chld_tmp[j], &win_name)) { if (strcmp (app_name, win_name) == 0) { found = 1; break; } } } if (found == 1) break; } } else printf("didnt work\n"); } while ((repeat == 1) && (found != 1)); if (found == 1) { ret_val = chld_tmp[j]; XFree(children_return); XFree(chld_tmp); return ret_val; } else { XFree(children_return); XFree(chld_tmp); return 0; } }
i got a workaround that works... doing this...
the work around makes no sense to me whatsoever since the values are the same... and the nested XQueryTree continues then to work fine using the global 'dpy' and 'X_Root_Window'Code:Window find_window_id(char *app_name, int repeat) { Window root_return, parent_return, *children_return, *chld_tmp, ret_val; int nchildren_return, tmp, i, j; int found = 0; char *win_name; Display *tmp_dpy; tmp_dpy = XOpenDisplay ("192.168.1.99:0.0"); do { if (XQueryTree(tmp_dpy, XDefaultRootWindow(tmp_dpy), &root_return, &parent_return, &children_return, &nchildren_return)) { for (i=0; i < nchildren_return; i++) { XQueryTree(dpy, children_return[i], &root_return, &parent_return, &chld_tmp, &tmp); for (j=0; j < tmp; j++) { if (XFetchName(dpy, chld_tmp[j], &win_name)) { if (strcmp (app_name, win_name) == 0) { found = 1; break; } } } if (found == 1) break; } } else printf("didnt work\n"); } while ((repeat == 1) && (found != 1)); if (found == 1) { ret_val = chld_tmp[j]; XFree(children_return); XFree(chld_tmp); XCloseDisplay(tmp_dpy); return ret_val; } else { XFree(children_return); XFree(chld_tmp); XCloseDisplay(tmp_dpy); return 0; } }
any ideas?
- 04-30-2008 #4
I would say that someone is stomping on something that shouldn't be stomped on somewhere. I know that's a notoriously difficult thing to find, but I think that's what's going on. It could be that the window ID hasn't changed, but that stuff in your heap has been trashed.
At any rate, three questions.
First, in the first chunk of code, does it fail on the outer XQueryTree(), or the inner XQueryTree()?
Second, when you say this:
do you know this from inspection of the code, or have you actually inserted printf() statements just before each XQueryTree call to make sure?the values of the first two arguments (Display Pointer and Root Window) are EXACTLY the same when it works and when it doesn't
Third, what happens when you try this instead? This is exactly like your first code (the code that misbehaves) except for the first call to XQueryTree().
Code:Window find_window_id(char *app_name, int repeat) { Window root_return, parent_return, *children_return, *chld_tmp, ret_val; int nchildren_return, tmp, i, j; int found = 0; char *win_name; do { if (XQueryTree(dpy, XDefaultRootWindow(dpy), &root_return, &parent_return, &children_return, &nchildren_return)) { for (i=0; i < nchildren_return; i++) { XQueryTree(dpy, children_return[i], &root_return, &parent_return, &chld_ tmp, &tmp); for (j=0; j < tmp; j++) { if (XFetchName(dpy, chld_tmp[j], &win_name)) { if (strcmp (app_name, win_name) == 0) { found = 1; break; } } } if (found == 1) break; } } else printf("didnt work\n"); } while ((repeat == 1) && (found != 1)); if (found == 1) { ret_val = chld_tmp[j]; XFree(children_return); XFree(chld_tmp); return ret_val; } else { XFree(children_return); XFree(chld_tmp); return 0; } }--
Bill
Old age and treachery will overcome youth and skill.
- 05-01-2008 #5Just Joined!
- Join Date
- Apr 2008
- Posts
- 4
if fails on the outer... inner works fine every time.
i used printf's and compared when it worked to when it didn't and they were the same.do you know this from inspection of the code, or have you actually inserted printf() statements just before each XQueryTree call to make sure?
it still fails using dpy and xdefaultrootwindow(dpy)Third, what happens when you try this instead? This is exactly like your first code (the code that misbehaves) except for the first call to XQueryTree().
so here's the weird thing...
this doesn't work
but this does...Code:XQueryTree(dpy, X_Root_Window, ...
same root window id but new display pointer. the inner query always works fine with the global display pointer. bizarre.Code:XQueryTree(tmp_dpy, X_Root_Window, ...
some code in the same file will still do XQueryPointer's no problem using the same global display pointer.
i'm at a loss... but at least i have a lousy work-around.
any other insight?
- 05-01-2008 #6Just Joined!
- Join Date
- Apr 2008
- Posts
- 4
one other thing. these routines are being called externally by another program... dont know if that makes a difference.
- 05-01-2008 #7We've eliminated all the painless explanations, so the only one left is the painful one.any other insight?
Something somewhere in the application is stomping on something in your heap (or, less likely, the stack) that it shouldn't be stomping on. The offending code might even have nothing to do with X Window processing.
So here's what you should probably do, painful as it is!
Write a bare-bones X application which throws up a window with an arbitrary name and waits for keystroke input in the window. (This will, among other good effects, make sure that all the data gets flushed to the X server.) Then, in reaction to the keystroke event, call this function.
Then wait for the event you talked about in your original post (it might be another keystroke; it doesn't matter), and call this function again.
I'll bet the function works perfectly both times.
If that's the case, it's almost certainly going to be a memory-stomping bug elsewhere in the application. If that's the case, the yellow brick road you are walking will be a long, hard yellow brick road.--
Bill
Old age and treachery will overcome youth and skill.


Reply With Quote
