X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2FXAtom.cc;h=bfd58483e7bb6f1b41995408ec18d8df15e2623e;hb=87e63d53af67d5ea98f55a27007663d4c9c8fc6c;hp=15bbc262e55defaa3b40ee6b8cfd338b0d04d881;hpb=cc5bde6d00892cf27fcb6e4e0b4974bcecca265f;p=chaz%2Fopenbox diff --git a/src/XAtom.cc b/src/XAtom.cc index 15bbc262..bfd58483 100644 --- a/src/XAtom.cc +++ b/src/XAtom.cc @@ -77,6 +77,9 @@ XAtom::XAtom(Display *d) { create("_BLACKBOX_CHANGE_WINDOW_FOCUS"); _atoms[blackbox_cycle_window_focus] = create("_BLACKBOX_CYCLE_WINDOW_FOCUS"); + _atoms[openbox_show_root_menu] = create("_OPENBOX_SHOW_ROOT_MENU"); + _atoms[openbox_show_workspace_menu] = create("_OPENBOX_SHOW_WORKSPACE_MENU"); + _atoms[net_supported] = create("_NET_SUPPORTED"); _atoms[net_client_list] = create("_NET_CLIENT_LIST"); _atoms[net_client_list_stacking] = create("_NET_CLIENT_LIST_STACKING"); @@ -356,47 +359,52 @@ bool XAtom::getValue(Window win, Atom atom, Atom type, assert(win != None); assert(atom != None); assert(type != None); assert(size == 8 || size == 16 || size == 32); assert(nelements > 0); - unsigned char *c_val = 0; // value alloc'd with c malloc + unsigned char *c_val = 0; // value alloc'd in Xlib, must be XFree()d Atom ret_type; int ret_size; unsigned long ret_bytes; int result; - const unsigned long maxread = nelements; + unsigned long maxread = nelements; + bool ret = False; + // try get the first element result = XGetWindowProperty(_display, win, atom, 0l, 1l, False, AnyPropertyType, &ret_type, &ret_size, &nelements, &ret_bytes, &c_val); - if (result != Success || ret_type != type || ret_size != size || - nelements < 1) { - // an error occured, the property does not exist on the window, or is empty, - // or the wrong data is in property for the request - if (c_val) XFree(c_val); - return False; - } - // the data is correct, now, is there more elements left? - if (ret_bytes == 0 || maxread <= nelements) { - // we got the whole property's value - *value = new unsigned char[nelements * size/8 + 1]; - memcpy(*value, c_val, nelements * size/8 + 1); - XFree(c_val); - return True; + ret = (result == Success && ret_type == type && ret_size == size && + nelements > 0); + if (ret) { + if (ret_bytes == 0 || maxread <= nelements) { + // we got the whole property's value + *value = new unsigned char[nelements * size/8 + 1]; + memcpy(*value, c_val, nelements * size/8 + 1); + } else { + // get the entire property since it is larger than one long + XFree(c_val); + // the number of longs that need to be retreived to get the property's + // entire value. The last + 1 is the first long that we retrieved above. + int remain = (ret_bytes - 1)/sizeof(long) + 1 + 1; + if (remain > size/8 * (signed)maxread) // dont get more than the max + remain = size/8 * (signed)maxread; + result = XGetWindowProperty(_display, win, atom, 0l, remain, False, type, + &ret_type, &ret_size, &nelements, &ret_bytes, + &c_val); + ret = (result == Success && ret_type == type && ret_size == size && + ret_bytes == 0); + /* + If the property has changed type/size, or has grown since our first + read of it, then stop here and try again. If it shrank, then this will + still work. + */ + if (! ret) + return getValue(win, atom, type, maxread, value, size); + + *value = new unsigned char[nelements * size/8 + 1]; + memcpy(*value, c_val, nelements * size/8 + 1); + } } - // get the entire property since it is larger than one long - XFree(c_val); - // the number of longs that need to be retreived to get the property's entire - // value. The last + 1 is the first long that we retrieved above. - int remain = (ret_bytes - 1)/sizeof(long) + 1 + 1; - if (remain > size/8 * (signed)maxread) // dont get more than the max - remain = size/8 * (signed)maxread; - result = XGetWindowProperty(_display, win, atom, 0l, remain, False, type, - &ret_type, &ret_size, &nelements, &ret_bytes, - &c_val); - assert(result == Success); - assert(ret_bytes == 0); - *value = new unsigned char[nelements * size/8 + 1]; - memcpy(*value, c_val, nelements * size/8 + 1); - XFree(c_val); - return True; + if (c_val) XFree(c_val); + return ret; }