rem: d_data.magic = NULL;
add: d_data.magic = NULL; }
context: menuMouseDown(WObjDescriptor *desc, XEvent *event){    XButtonEvent *bev = &event->xbutton;    WMenu *menu = desc->parent;    WMenu *smenu;    WScreen *scr=menu->frame->screen_ptr;    WMenuEntry *entry=NULL;    XEvent ev;    int close_on_exit=0;    int done=0;    int delayed_select = 0;    int entry_no;    int x, y;    int prevx, prevy;    int old_frame_x = 0;    int old_frame_y = 0;    delay_data d_data = {NULL, NULL, NULL};    if (!wPreferences.wrap_menus) {        smenu = parentMenu(menu);        old_frame_x = smenu->frame_x;        old_frame_y = smenu->frame_y;    } else if (event->xbutton.window == menu->frame->core->window) {        /* This is true if the menu was launched with right click on root window */        delayed_select = 1;        d_data.delayed_select = &delayed_select;        d_data.menu = menu;        d_data.magic = WMAddTimerHandler(wPreferences.dblclick_time,                                         delaySelection, &d_data);    }    if (menu->flags.inside_handler) {        return;    }    menu->flags.inside_handler = 1;    wRaiseFrame(menu->frame->core);    close_on_exit = (bev->send_event || menu->flags.brother);    smenu = findMenu(scr, &x, &y);    if (!smenu) {        x = -1;        y = -1;    } else {        menu = smenu;    }    if (menu->flags.editing) {        goto byebye;    }    entry_no = getEntryAt(menu, x, y);    if (entry_no>=0) {        entry = menu->entries[entry_no];        if (!close_on_exit && (bev->state & ControlMask) && smenu            && entry->flags.editable) {            editEntry(smenu, entry);            goto byebye;        } else if (bev->state & ControlMask) {            goto byebye;        }        if (entry->flags.enabled && entry->cascade>=0 && menu->cascades) {            WMenu *submenu = menu->cascades[entry->cascade];            /* map cascade */            if (submenu->flags.mapped && !submenu->flags.buttoned &&                menu->selected_entry!=entry_no) {                wMenuUnmap(submenu);            }            if (!submenu->flags.mapped && !delayed_select) {                selectEntry(menu, entry_no);            } else if (!submenu->flags.buttoned) {                selectEntry(menu, -1);            }        } else if (!delayed_select) {            selectEntry(menu, entry_no);        }        if (!wPreferences.wrap_menus && !wPreferences.scrollable_menus) {            if (!menu->timer)                dragScrollMenuCallback(menu);        }    }#ifdef VIRTUAL_DESKTOP    if (wPreferences.vedge_thickness) {        wWorkspaceLowerEdge(scr);    }#endif    prevx = bev->x_root;    prevy = bev->y_root;    while (!done) {        int x, y;        XAllowEvents(dpy, AsyncPointer|SyncPointer, CurrentTime);        WMMaskEvent(dpy, ExposureMask|ButtonMotionMask|ButtonReleaseMask                    |ButtonPressMask, &ev);        switch (ev.type) {        case MotionNotify:            smenu = findMenu(scr, &x, &y);            if (smenu == NULL) {                /* moved mouse out of menu */                if (!delayed_select && d_data.magic) {                    WMDeleteTimerHandler(d_data.magic);                    d_data.magic = NULL;                }                if (menu==NULL                    || (menu->selected_entry>=0                        && menu->entries[menu->selected_entry]->cascade>=0)) {                    prevx = ev.xmotion.x_root;                    prevy = ev.xmotion.y_root;                    break;                }                selectEntry(menu, -1);                menu = smenu;                prevx = ev.xmotion.x_root;                prevy = ev.xmotion.y_root;                break;            } else if (menu && menu!=smenu                       && (menu->selected_entry<0                           || menu->entries[menu->selected_entry]->cascade<0)) {                selectEntry(menu, -1);                if (!delayed_select && d_data.magic) {                    WMDeleteTimerHandler(d_data.magic);                    d_data.magic = NULL;                }            } else {                /* hysteresis for item selection */                /* check if the motion was to the side, indicating that                 * the user may want to cross to a submenu */                if (!delayed_select && menu) {                    int dx;                    Bool moved_to_submenu;/* moved to direction of submenu */                    dx = abs(prevx - ev.xmotion.x_root);                    moved_to_submenu = False;                    if (dx > 0 /* if moved enough to the side */                        /* maybe a open submenu */                        && menu->selected_entry>=0                        /* moving to the right direction */                        && (wPreferences.align_menus                            || ev.xmotion.y_root >= prevy)) {                        int index;                        index = menu->entries[menu->selected_entry]->cascade;                        if (index>=0) {                            if (menu->cascades[index]->frame_x>menu->frame_x) {                                if (prevx < ev.xmotion.x_root)                                    moved_to_submenu = True;                            } else {                                if (prevx > ev.xmotion.x_root)                                    moved_to_submenu = True;                            }                        }                    }                    if (menu != smenu) {                        if (d_data.magic) {                            WMDeleteTimerHandler(d_data.magic);                        }                        d_data.magic = NULL;                    } else if (moved_to_submenu) {                        /* while we are moving, postpone the selection */                        if (d_data.magic) {                            WMDeleteTimerHandler(d_data.magic);                        }                        d_data.delayed_select = NULL;                        d_data.menu = menu;                        d_data.magic = WMAddTimerHandler(MENU_SELECT_DELAY,                                                         delaySelection,                                                         &d_data);                        prevx = ev.xmotion.x_root;                        prevy = ev.xmotion.y_root;                        break;                    } else {                        if (d_data.magic)                            WMDeleteTimerHandler(d_data.magic);                        d_data.magic = NULL;                    }                }            }            prevx = ev.xmotion.x_root;            prevy = ev.xmotion.y_root;            if (menu!=smenu) {                /* pointer crossed menus */                if (menu && menu->timer) {                    WMDeleteTimerHandler(menu->timer);                    menu->timer = NULL;                }                if (smenu)                    dragScrollMenuCallback(smenu);            }            menu = smenu;            if (!menu->timer)                dragScrollMenuCallback(menu);            if (!delayed_select) {                entry_no = getEntryAt(menu, x, y);                if (entry_no>=0) {                    entry = menu->entries[entry_no];                    if (entry->flags.enabled && entry->cascade>=0 &&                        menu->cascades) {                        WMenu *submenu = menu->cascades[entry->cascade];                        if (submenu->flags.mapped && !submenu->flags.buttoned                            && menu->selected_entry!=entry_no) {                            wMenuUnmap(submenu);                        }                    }                }                selectEntry(menu, entry_no);            }            break;        case ButtonPress:            break;        case ButtonRelease:            if (ev.xbutton.button == event->xbutton.button)                done=1;            break;        case Expose:            WMHandleEvent(&ev);#ifdef VIRTUAL_DESKTOP            /* since expose will raise edge up.. I need another ugly hack here */            if (wPreferences.vedge_thickness) {                wWorkspaceLowerEdge(scr);            }#endif            break;        }    }    if (menu && menu->timer) {        WMDeleteTimerHandler(menu->timer);        menu->timer = NULL;    }    if (d_data.magic!=NULL)        WMDeleteTimerHandler(d_data.magic);    if (menu && menu->selected_entry>=0) {        entry = menu->entries[menu->selected_entry];        if (entry->callback!=NULL && entry->flags.enabled            && entry->cascade < 0) {            /* blink and erase menu selection */#if (MENU_BLINK_DELAY > 0)            int sel = menu->selected_entry;            int i;            for (i=0; i<MENU_BLINK_COUNT; i++) {                paintEntry(menu, sel, False);                XSync(dpy, 0);                wusleep(MENU_BLINK_DELAY);                paintEntry(menu, sel, True);                XSync(dpy, 0);                wusleep(MENU_BLINK_DELAY);            }#endif            /* unmap the menu, it's parents and call the callback */            if (!menu->flags.buttoned &&                (!menu->flags.app_menu||menu->parent!=NULL)) {                closeCascade(menu);            } else {                selectEntry(menu, -1);            }            (*entry->callback)(menu, entry);            /* If the user double clicks an entry, the entry will             * be executed twice, which is not good for things like             * the root menu. So, ignore any clicks that were generated             * while the entry was being executed */            while (XCheckTypedWindowEvent(dpy, menu->menu->window,                                          ButtonPress, &ev));        } else if (entry->callback!=NULL && entry->cascade<0) {            selectEntry(menu, -1);        } else {            if (entry->cascade>=0 && menu->cascades                && menu->cascades[entry->cascade]->flags.brother) {                selectEntry(menu, -1);            }        }    }    if (((WMenu*)desc->parent)->flags.brother || close_on_exit || !smenu)        closeCascade(desc->parent);    /* close the cascade windows that should not remain opened */    closeBrotherCascadesOf(desc->parent);    if (!wPreferences.wrap_menus)        wMenuMove(parentMenu(desc->parent), old_frame_x, old_frame_y, True);byebye:    ((WMenu*)desc->parent)->flags.inside_handler = 0;#ifdef VIRTUAL_DESKTOP    if (wPreferences.vedge_thickness) {        wWorkspaceRaiseEdge(scr);    }#endif}