From 1fb198410e9d3ca660d91d1049249db0f2f47732 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 21 Dec 2009 09:51:11 -0500 Subject: A fix for delayed hiding of submenus. It fixes this: (Mikachu) dana: i think his issue was if you have a menu with two submenus s1 and s2, open the s1 submenu, then point to s2 and go into s1, then after the delay, s1 is hidden despite you being inside it still, because s2 was never unselected --- openbox/event.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openbox/event.c b/openbox/event.c index a0d26ab7..bbe7038e 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1838,8 +1838,7 @@ static gboolean event_handle_menu(XEvent *ev) break; if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window)) && - (f = find_active_menu()) && f->selected == e && - e->entry->type != OB_MENU_ENTRY_TYPE_SUBMENU) + (f = find_active_menu()) && f->selected == e) { ObMenuEntryFrame *u = menu_entry_frame_under(ev->xcrossing.x_root, ev->xcrossing.y_root); -- cgit v1.2.3 From 6d8b7bd5f7ede1803c1259f5c1b760e5dbf4dbe3 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 21 Dec 2009 09:59:28 -0500 Subject: Rename obprop to obxprop (Fixes bug #4419) Avoids collision with openbabel. --- .gitignore | 2 +- Makefile.am | 12 +- data/rc.xml | 8 +- tools/obprop/Makefile | 4 - tools/obprop/obprop.c | 320 ------------------------------------------------ tools/obxprop/Makefile | 4 + tools/obxprop/obxprop.c | 320 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 335 insertions(+), 335 deletions(-) delete mode 100644 tools/obprop/Makefile delete mode 100644 tools/obprop/obprop.c create mode 100644 tools/obxprop/Makefile create mode 100644 tools/obxprop/obxprop.c diff --git a/.gitignore b/.gitignore index e1e0e419..907abb9b 100644 --- a/.gitignore +++ b/.gitignore @@ -51,7 +51,7 @@ po/remove-potcdate.sed render/obrender-3.0.pc tools/gnome-panel-control/gnome-panel-control tools/gdm-control/gdm-control -tools/obprop/obprop +tools/obxprop/obxprop version.h .libs .deps diff --git a/Makefile.am b/Makefile.am index 4b3e0b50..60c22321 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,7 +33,7 @@ bin_PROGRAMS = \ openbox/openbox \ tools/gdm-control/gdm-control \ tools/gnome-panel-control/gnome-panel-control \ - tools/obprop/obprop + tools/obxprop/obxprop dist_secretbin_SCRIPTS = \ tools/xdg-autostart/xdg-autostart @@ -289,16 +289,16 @@ tools_gnome_panel_control_gnome_panel_control_LDADD = \ tools_gnome_panel_control_gnome_panel_control_SOURCES = \ tools/gnome-panel-control/gnome-panel-control.c -## obprop ## +## obxprop ## -tools_obprop_obprop_CPPFLAGS = \ +tools_obxprop_obxprop_CPPFLAGS = \ $(GLIB_CFLAGS) \ $(X_CFLAGS) -tools_obprop_obprop_LDADD = \ +tools_obxprop_obxprop_LDADD = \ $(GLIB_LIBS) \ $(X_LIBS) -tools_obprop_obprop_SOURCES = \ - tools/obprop/obprop.c +tools_obxprop_obxprop_SOURCES = \ + tools/obxprop/obxprop.c ## gdm-control ## diff --git a/data/rc.xml b/data/rc.xml index d7a31bda..eaf3df7f 100644 --- a/data/rc.xml +++ b/data/rc.xml @@ -646,10 +646,10 @@ # this is an example with comments through out. use these to make your # own rules, but without the comments of course. - # the name or the class can be set, or both. this is used to match # windows when they appear. role can optionally be set as well, to diff --git a/tools/obprop/Makefile b/tools/obprop/Makefile deleted file mode 100644 index cfc46539..00000000 --- a/tools/obprop/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -all clean install: - $(MAKE) -C ../.. -$(MAKEFLAGS) $@ - -.PHONY: all clean install diff --git a/tools/obprop/obprop.c b/tools/obprop/obprop.c deleted file mode 100644 index e288d7cb..00000000 --- a/tools/obprop/obprop.c +++ /dev/null @@ -1,320 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -gint fail(const gchar *s) { - if (s) - fprintf(stderr, "%s\n", s); - else - fprintf - (stderr, - "Usage: obprop [OPTIONS]\n\n" - "Options:\n" - " --help Display this help and exit\n" - " --display DISPLAY Connect to this X display\n" - " --id ID Show the properties for this window\n"); - return 1; -} - -gint parse_hex(gchar *s) { - gint result = 0; - while (*s) { - gint add; - if (*s >= '0' && *s <='9') - add = *s-'0'; - else if (*s >= 'A' && *s <='F') - add = *s-'A'; - else if (*s >= 'a' && *s <='f') - add = *s-'a'; - else - break; - - result *= 16; - result += add; - } - return result; -} - -Window find_client(Display *d, Window win) -{ - Window r, *children; - guint n, i; - Atom state = XInternAtom(d, "WM_STATE", True); - Atom ret_type; - gint ret_format, res; - gulong ret_items, ret_bytesleft, *xdata; - - XQueryTree(d, win, &r, &r, &children, &n); - for (i = 0; i < n; ++i) { - Window w = find_client(d, children[i]); - if (w) return w; - } - - // try me - res = XGetWindowProperty(d, win, state, 0, 1, - False, state, &ret_type, &ret_format, - &ret_items, &ret_bytesleft, - (unsigned char**) &xdata); - XFree(xdata); - if (res != Success || ret_type == None || ret_items < 1) - return None; - return win; // found it! -} - -static gboolean get_all(Display *d, Window win, Atom prop, - Atom *type, gint *size, - guchar **data, guint *num) -{ - gboolean ret = FALSE; - gint res; - guchar *xdata = NULL; - gulong ret_items, bytes_left; - - res = XGetWindowProperty(d, win, prop, 0l, G_MAXLONG, - FALSE, AnyPropertyType, type, size, - &ret_items, &bytes_left, &xdata); - if (res == Success) { - if (ret_items > 0) { - guint i; - - *data = g_malloc(ret_items * (*size / 8)); - for (i = 0; i < ret_items; ++i) - switch (*size) { - case 8: - (*data)[i] = xdata[i]; - break; - case 16: - ((guint16*)*data)[i] = ((gushort*)xdata)[i]; - break; - case 32: - ((guint32*)*data)[i] = ((gulong*)xdata)[i]; - break; - default: - g_assert_not_reached(); /* unhandled size */ - } - *num = ret_items; - ret = TRUE; - } - XFree(xdata); - } - return ret; -} - -gchar *append_string(gchar *before, gchar *after, gboolean quote) -{ - gchar *tmp; - const gchar *q = quote ? "\"" : ""; - if (before) - tmp = g_strdup_printf("%s, %s%s%s", before, q, after, q); - else - tmp = g_strdup_printf("%s%s%s", q, after, q); - g_free(before); - return tmp; -} - -gchar *append_int(gchar *before, guint after) -{ - gchar *tmp; - if (before) - tmp = g_strdup_printf("%s, %u", before, after); - else - tmp = g_strdup_printf("%u", after); - g_free(before); - return tmp; -} - -gchar* read_strings(gchar *val, guint n, gboolean utf8) -{ - GSList *strs = NULL, *it; - gchar *ret, *p; - guint i; - - p = val; - while (p < val + n) { - strs = g_slist_append(strs, g_strndup(p, n - (p - val))); - p += strlen(p) + 1; /* next string */ - } - - ret = NULL; - for (i = 0, it = strs; it; ++i, it = g_slist_next(it)) { - char *data; - - if (utf8) { - if (g_utf8_validate(it->data, -1, NULL)) - data = g_strdup(it->data); - else - data = g_strdup(""); - } - else - data = g_locale_to_utf8(it->data, -1, NULL, NULL, NULL); - - ret = append_string(ret, data, TRUE); - g_free(data); - } - - while (strs) { - g_free(strs->data); - strs = g_slist_delete_link(strs, strs); - } - return ret; -} - -gchar* read_atoms(Display *d, guchar *val, guint n) -{ - gchar *ret; - guint i; - - ret = NULL; - for (i = 0; i < n; ++i) - ret = append_string(ret, XGetAtomName(d, ((guint32*)val)[i]), FALSE); - return ret; -} - -gchar* read_numbers(guchar *val, guint n, guint size) -{ - gchar *ret; - guint i; - - ret = NULL; - for (i = 0; i < n; ++i) - switch (size) { - case 8: - ret = append_int(ret, ((guint8*)val)[i]); - break; - case 16: - ret = append_int(ret, ((guint16*)val)[i]); - break; - case 32: - ret = append_int(ret, ((guint32*)val)[i]); - break; - default: - g_assert_not_reached(); /* unhandled size */ - } - - return ret; -} - -gboolean read_prop(Display *d, Window w, Atom prop, const gchar **type, gchar **val) -{ - guchar *ret; - guint nret; - gint size; - Atom ret_type; - - ret = NULL; - if (get_all(d, w, prop, &ret_type, &size, &ret, &nret)) { - *type = XGetAtomName(d, ret_type); - - if (strcmp(*type, "STRING") == 0) - *val = read_strings((gchar*)ret, nret, FALSE); - else if (strcmp(*type, "UTF8_STRING") == 0) - *val = read_strings((gchar*)ret, nret, TRUE); - else if (strcmp(*type, "ATOM") == 0) { - g_assert(size == 32); - *val = read_atoms(d, ret, nret); - } - else - *val = read_numbers(ret, nret, size); - - g_free(ret); - return TRUE; - } - return FALSE; -} - -void show_properties(Display *d, Window w) -{ - Atom* props; - int i, n; - - props = XListProperties(d, w, &n); - - for (i = 0; i < n; ++i) { - const char *type; - char *name, *val; - - name = XGetAtomName(d, props[i]); - - if (read_prop(d, w, props[i], &type, &val)) { - g_print("%s(%s) = %s\n", name, type, val); - g_free(val); - } - - XFree(name); - } - - XFree(props); -} - -int main(int argc, char **argv) -{ - Display *d; - Window id, userid = None; - int i; - char *dname = NULL; - - for (i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "--help")) { - return fail(0); - } - else if (!strcmp(argv[i], "--id")) { - if (++i == argc) - return fail(0); - if (argv[i][0] == '0' && argv[i][1] == 'x') { - /* hex */ - userid = parse_hex(argv[i]+2); - } - else { - /* decimal */ - userid = atoi(argv[i]); - } - break; - } - else if (!strcmp(argv[i], "--display")) { - if (++i == argc) - return fail(0); - dname = argv[i]; - } - } - - d = XOpenDisplay(dname); - if (!d) { - return fail("Unable to find an X display. " - "Ensure you have permission to connect to the display."); - } - - if (userid == None) { - i = XGrabPointer(d, RootWindow(d, DefaultScreen(d)), - False, ButtonPressMask, - GrabModeAsync, GrabModeAsync, - None, XCreateFontCursor(d, XC_crosshair), - CurrentTime); - if (i != GrabSuccess) - return fail("Unable to grab the pointer device"); - while (1) { - XEvent ev; - - XNextEvent(d, &ev); - if (ev.type == ButtonPress) { - XUngrabPointer(d, CurrentTime); - userid = ev.xbutton.subwindow; - break; - } - } - } - - id = find_client(d, userid); - - if (id == None) - return fail("Unable to find window with the requested ID"); - - show_properties(d, id); - - XCloseDisplay(d); - - return 0; -} diff --git a/tools/obxprop/Makefile b/tools/obxprop/Makefile new file mode 100644 index 00000000..cfc46539 --- /dev/null +++ b/tools/obxprop/Makefile @@ -0,0 +1,4 @@ +all clean install: + $(MAKE) -C ../.. -$(MAKEFLAGS) $@ + +.PHONY: all clean install diff --git a/tools/obxprop/obxprop.c b/tools/obxprop/obxprop.c new file mode 100644 index 00000000..26851544 --- /dev/null +++ b/tools/obxprop/obxprop.c @@ -0,0 +1,320 @@ +#include +#include +#include +#include +#include +#include +#include + +gint fail(const gchar *s) { + if (s) + fprintf(stderr, "%s\n", s); + else + fprintf + (stderr, + "Usage: obxprop [OPTIONS]\n\n" + "Options:\n" + " --help Display this help and exit\n" + " --display DISPLAY Connect to this X display\n" + " --id ID Show the properties for this window\n"); + return 1; +} + +gint parse_hex(gchar *s) { + gint result = 0; + while (*s) { + gint add; + if (*s >= '0' && *s <='9') + add = *s-'0'; + else if (*s >= 'A' && *s <='F') + add = *s-'A'; + else if (*s >= 'a' && *s <='f') + add = *s-'a'; + else + break; + + result *= 16; + result += add; + } + return result; +} + +Window find_client(Display *d, Window win) +{ + Window r, *children; + guint n, i; + Atom state = XInternAtom(d, "WM_STATE", True); + Atom ret_type; + gint ret_format, res; + gulong ret_items, ret_bytesleft, *xdata; + + XQueryTree(d, win, &r, &r, &children, &n); + for (i = 0; i < n; ++i) { + Window w = find_client(d, children[i]); + if (w) return w; + } + + // try me + res = XGetWindowProperty(d, win, state, 0, 1, + False, state, &ret_type, &ret_format, + &ret_items, &ret_bytesleft, + (unsigned char**) &xdata); + XFree(xdata); + if (res != Success || ret_type == None || ret_items < 1) + return None; + return win; // found it! +} + +static gboolean get_all(Display *d, Window win, Atom prop, + Atom *type, gint *size, + guchar **data, guint *num) +{ + gboolean ret = FALSE; + gint res; + guchar *xdata = NULL; + gulong ret_items, bytes_left; + + res = XGetWindowProperty(d, win, prop, 0l, G_MAXLONG, + FALSE, AnyPropertyType, type, size, + &ret_items, &bytes_left, &xdata); + if (res == Success) { + if (ret_items > 0) { + guint i; + + *data = g_malloc(ret_items * (*size / 8)); + for (i = 0; i < ret_items; ++i) + switch (*size) { + case 8: + (*data)[i] = xdata[i]; + break; + case 16: + ((guint16*)*data)[i] = ((gushort*)xdata)[i]; + break; + case 32: + ((guint32*)*data)[i] = ((gulong*)xdata)[i]; + break; + default: + g_assert_not_reached(); /* unhandled size */ + } + *num = ret_items; + ret = TRUE; + } + XFree(xdata); + } + return ret; +} + +gchar *append_string(gchar *before, gchar *after, gboolean quote) +{ + gchar *tmp; + const gchar *q = quote ? "\"" : ""; + if (before) + tmp = g_strdup_printf("%s, %s%s%s", before, q, after, q); + else + tmp = g_strdup_printf("%s%s%s", q, after, q); + g_free(before); + return tmp; +} + +gchar *append_int(gchar *before, guint after) +{ + gchar *tmp; + if (before) + tmp = g_strdup_printf("%s, %u", before, after); + else + tmp = g_strdup_printf("%u", after); + g_free(before); + return tmp; +} + +gchar* read_strings(gchar *val, guint n, gboolean utf8) +{ + GSList *strs = NULL, *it; + gchar *ret, *p; + guint i; + + p = val; + while (p < val + n) { + strs = g_slist_append(strs, g_strndup(p, n - (p - val))); + p += strlen(p) + 1; /* next string */ + } + + ret = NULL; + for (i = 0, it = strs; it; ++i, it = g_slist_next(it)) { + char *data; + + if (utf8) { + if (g_utf8_validate(it->data, -1, NULL)) + data = g_strdup(it->data); + else + data = g_strdup(""); + } + else + data = g_locale_to_utf8(it->data, -1, NULL, NULL, NULL); + + ret = append_string(ret, data, TRUE); + g_free(data); + } + + while (strs) { + g_free(strs->data); + strs = g_slist_delete_link(strs, strs); + } + return ret; +} + +gchar* read_atoms(Display *d, guchar *val, guint n) +{ + gchar *ret; + guint i; + + ret = NULL; + for (i = 0; i < n; ++i) + ret = append_string(ret, XGetAtomName(d, ((guint32*)val)[i]), FALSE); + return ret; +} + +gchar* read_numbers(guchar *val, guint n, guint size) +{ + gchar *ret; + guint i; + + ret = NULL; + for (i = 0; i < n; ++i) + switch (size) { + case 8: + ret = append_int(ret, ((guint8*)val)[i]); + break; + case 16: + ret = append_int(ret, ((guint16*)val)[i]); + break; + case 32: + ret = append_int(ret, ((guint32*)val)[i]); + break; + default: + g_assert_not_reached(); /* unhandled size */ + } + + return ret; +} + +gboolean read_prop(Display *d, Window w, Atom prop, const gchar **type, gchar **val) +{ + guchar *ret; + guint nret; + gint size; + Atom ret_type; + + ret = NULL; + if (get_all(d, w, prop, &ret_type, &size, &ret, &nret)) { + *type = XGetAtomName(d, ret_type); + + if (strcmp(*type, "STRING") == 0) + *val = read_strings((gchar*)ret, nret, FALSE); + else if (strcmp(*type, "UTF8_STRING") == 0) + *val = read_strings((gchar*)ret, nret, TRUE); + else if (strcmp(*type, "ATOM") == 0) { + g_assert(size == 32); + *val = read_atoms(d, ret, nret); + } + else + *val = read_numbers(ret, nret, size); + + g_free(ret); + return TRUE; + } + return FALSE; +} + +void show_properties(Display *d, Window w) +{ + Atom* props; + int i, n; + + props = XListProperties(d, w, &n); + + for (i = 0; i < n; ++i) { + const char *type; + char *name, *val; + + name = XGetAtomName(d, props[i]); + + if (read_prop(d, w, props[i], &type, &val)) { + g_print("%s(%s) = %s\n", name, type, val); + g_free(val); + } + + XFree(name); + } + + XFree(props); +} + +int main(int argc, char **argv) +{ + Display *d; + Window id, userid = None; + int i; + char *dname = NULL; + + for (i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--help")) { + return fail(0); + } + else if (!strcmp(argv[i], "--id")) { + if (++i == argc) + return fail(0); + if (argv[i][0] == '0' && argv[i][1] == 'x') { + /* hex */ + userid = parse_hex(argv[i]+2); + } + else { + /* decimal */ + userid = atoi(argv[i]); + } + break; + } + else if (!strcmp(argv[i], "--display")) { + if (++i == argc) + return fail(0); + dname = argv[i]; + } + } + + d = XOpenDisplay(dname); + if (!d) { + return fail("Unable to find an X display. " + "Ensure you have permission to connect to the display."); + } + + if (userid == None) { + i = XGrabPointer(d, RootWindow(d, DefaultScreen(d)), + False, ButtonPressMask, + GrabModeAsync, GrabModeAsync, + None, XCreateFontCursor(d, XC_crosshair), + CurrentTime); + if (i != GrabSuccess) + return fail("Unable to grab the pointer device"); + while (1) { + XEvent ev; + + XNextEvent(d, &ev); + if (ev.type == ButtonPress) { + XUngrabPointer(d, CurrentTime); + userid = ev.xbutton.subwindow; + break; + } + } + } + + id = find_client(d, userid); + + if (id == None) + return fail("Unable to find window with the requested ID"); + + show_properties(d, id); + + XCloseDisplay(d); + + return 0; +} -- cgit v1.2.3