diff --git a/client.c b/client.c index 89b3bae..dbfbfe6 100644 --- a/client.c +++ b/client.c @@ -19,7 +19,6 @@ extern struct Library *XLibBase; extern Display *dpy; extern XContext client_context, screen_context; extern Client *activeclient; -extern Scrn *menuactive; extern void setfocus(Window); Client *clients=NULL; @@ -322,8 +321,6 @@ void rmclient(Client *c) closescreen(); scr = c->scr; if(c->active) { - if(!menuactive) - setfocus(None); c->active=False; activeclient = NULL; XInstallColormap(dpy, scr->cmap); diff --git a/main.c b/main.c index c2a93ea..a50aabe 100644 --- a/main.c +++ b/main.c @@ -73,7 +73,6 @@ typedef struct _DragIcon { Display *dpy = NULL; Client *activeclient=NULL; -Scrn *menuactive=NULL; Bool shape_extn=False; char *x_server=NULL; char *free_screentitle=NULL; @@ -105,12 +104,10 @@ extern void click_close(Client *c, Time time); extern void click_iconify(Client *c, Time time); extern void click_zoom(Client *c, Time time); extern void click_depth(Client *c, Time time); -extern void menu_on(void); -extern void menu_off(void); +extern void drag_menu(Scrn *s); extern void menubar_enter(Window); extern void menubar_leave(Window); extern void *getitembyhotkey(KeySym); -extern void menuaction(void *); extern Scrn *getscreenbyroot(Window); extern void assimilate(Window, int, int); extern void deselect_all_icons(Scrn *); @@ -379,7 +376,8 @@ static Bool grab_for_motion(Window w, Window confine, Cursor curs, Time time, in void get_drag_event(XEvent *event) { - static const unsigned int DRAG_MASK = ButtonPressMask|ButtonReleaseMask|Button1MotionMask; + static const unsigned int DRAG_MASK = + ButtonPressMask|ButtonReleaseMask|PointerMotionMask|EnterWindowMask|LeaveWindowMask; for (;;) { fd_set rfds = master_fd_set; @@ -1184,8 +1182,6 @@ int main(int argc, char *argv[]) XGrabButton(dpy, Button1, AnyModifier, c->parent, True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, wm_curs); - if(!menuactive) - setfocus(None); } if(c && (event.xunmap.window==c->window)) { if((!c->reparenting) && c->parent != c->scr->root) { @@ -1361,10 +1357,7 @@ int main(int argc, char *argv[]) } break; case EnterNotify: - if(menuactive) { - scr=menuactive; - menubar_enter(event.xcrossing.window); - } else if(c) { + if(c) { if((!c->active) && (c->state==NormalState) && prefs.focus!=FOC_CLICKTOTYPE) { if(activeclient) { @@ -1383,15 +1376,10 @@ int main(int argc, char *argv[]) } break; case LeaveNotify: - if(menuactive) { - scr=menuactive; - menubar_leave(event.xcrossing.window); - } else if(c) { + if(c) { if(c->active && event.xcrossing.window==c->parent && event.xcrossing.detail!=NotifyInferior && prefs.focus == FOC_FOLLOWMOUSE) { - if(!menuactive) - setfocus(None); c->active=False; activeclient = NULL; instcmap(None); @@ -1403,7 +1391,7 @@ int main(int argc, char *argv[]) } break; case ButtonPress: - if(event.xbutton.button==Button1 && !menuactive) { + if(event.xbutton.button==Button1) { if(c) { if((!c->active) && prefs.focus==FOC_CLICKTOTYPE && (c->state==NormalState)) { @@ -1473,22 +1461,17 @@ int main(int argc, char *argv[]) event.xbutton.x, event.xbutton.y); } else ; } else if(event.xbutton.button==3) { - if(scr&&!menuactive) { - menu_on(); - menuactive=scr; + if(c == NULL && scr != NULL) { + drag_menu(scr); } } - if(prefs.focus == FOC_CLICKTOTYPE && !menuactive) { + if(prefs.focus == FOC_CLICKTOTYPE) { XSync(dpy,0); XAllowEvents(dpy,ReplayPointer,CurrentTime); XSync(dpy,0); } break; case ButtonRelease: - if(event.xbutton.button==Button3 && (scr=menuactive)) { - menu_off(); - menuactive=NULL; - } break; case MotionNotify: break; diff --git a/menu.c b/menu.c index 4b8ccda..f6c04a1 100644 --- a/menu.c +++ b/menu.c @@ -642,6 +642,8 @@ void redrawmenubar(Scrn *scr, Window w) static void leave_item(struct Item *i, Window w) { + if (i == NULL) + return; if(i==activesubitem) activesubitem=NULL; if(i==activeitem) { @@ -708,7 +710,7 @@ static void enter_menu(struct Menu *m, Window w) } } -void menubar_enter(Window w) +static void menubar_enter(Window w) { struct Menu *m; struct Item *i; @@ -732,7 +734,7 @@ void menubar_enter(Window w) } } -void menubar_leave(Window w) +static void menubar_leave(Window w) { if(activesubitem && activesubitem->win==w) leave_item(activesubitem, w); @@ -740,24 +742,6 @@ void menubar_leave(Window w) leave_item(activeitem, w); } -void menu_on() -{ - Window r, c; - int rx, ry, x, y; - unsigned int m; - - if(scr->menubarparent) { - XMapRaised(dpy, scr->menubarparent); - XRaiseWindow(dpy, scr->menubar); - XGrabPointer(dpy, scr->back, True, ButtonPressMask|ButtonReleaseMask| - EnterWindowMask|LeaveWindowMask, GrabModeAsync, GrabModeAsync, - scr->back, wm_curs, CurrentTime); - XSetInputFocus(dpy, scr->menubar, RevertToParent, CurrentTime); - if(XQueryPointer(dpy, scr->menubarparent, &r, &c, &rx, &ry, &x, &y, &m)) - menubar_enter(c); - } -} - void menuaction(struct Item *i, struct Item *si) { extern void restart_amiwm(void); @@ -887,57 +871,6 @@ void menuaction(struct Item *i, struct Item *si) } } -void menu_off() -{ - struct Menu *oa; - struct Item *oi, *osi; - - if(scr->menubarparent) { - Window r,p,*children; - unsigned int nchildren; - XUngrabPointer(dpy, CurrentTime); - setfocus((activeclient && activeclient->state==NormalState? - activeclient->window:None)); - XUnmapWindow(dpy, scr->menubarparent); - if(XQueryTree(dpy, scr->back, &r, &p, &children, &nchildren)) { - int n; - Client *c2; - for(n=0; nparent) - break; - if(nmenubar; - XRestackWindows(dpy, ws, 2); - } - if(children) XFree(children); - } - } - if((osi=activesubitem)) - leave_item(osi, osi->win); - if((oi=activeitem)) - leave_item(oi, oi->win); - if((oa=activesubmenu)) { - activesubmenu=NULL; - if(oa->parent) - XUnmapWindow(dpy, oa->parent); - } - if((oa=activemenu)) { - activemenu=NULL; - if(oa->parent) - XUnmapWindow(dpy, oa->parent); - XSetWindowBackground(dpy, oa->win, scr->dri.dri_Pens[BARBLOCKPEN]); - XClearWindow(dpy, oa->win); - redraw_menu(oa, oa->win); - } - if(oi) { - XSync(dpy, False); - menuaction(oi, osi); - } -} - struct Item *getitembyhotkey(KeySym key) { struct Menu *m; @@ -1023,3 +956,61 @@ struct Item *own_items(struct module *m, Scrn *s, endlink->next = c; return chain; } + +void drag_menu(Scrn *s) +{ + extern void get_drag_event(XEvent *event); + Window w; + struct Item *saved_item = NULL; + struct Item *saved_subitem = NULL; + + if (s->menubarparent == None) + return; + XMapRaised(dpy, s->menubarparent); + XRaiseWindow(dpy, s->menubar); + XGrabPointer(dpy, s->back, True, ButtonPressMask|ButtonReleaseMask| + EnterWindowMask|LeaveWindowMask, GrabModeAsync, GrabModeAsync, + s->back, wm_curs, CurrentTime); + if(XQueryPointer(dpy, s->menubarparent, &(Window){0}, &w, + &(int){0}, &(int){0}, &(int){0}, &(int){0}, &(unsigned){0})) + menubar_enter(w); + for (;;) { + XEvent event; + + get_drag_event(&event); + if (event.type == ButtonRelease && event.xbutton.button == Button3) { + XUngrabPointer(dpy, event.xbutton.time); + break; + } else if (event.type == EnterNotify) { + menubar_enter(event.xcrossing.window); + } else if (event.type == LeaveNotify) { + menubar_leave(event.xcrossing.window); + } + } + XUnmapWindow(dpy, s->menubarparent); + saved_item = activeitem; + saved_subitem = activesubitem; + if(activesubitem != NULL) + leave_item(activesubitem, activesubitem->win); + if(activeitem != NULL) + leave_item(activeitem, activeitem->win); + if(activesubmenu != NULL) { + if(activesubmenu->parent) + XUnmapWindow(dpy, activesubmenu->parent); + activesubmenu=NULL; + } + if(activemenu != NULL) { + struct Menu *saved_menu = activemenu; + activemenu=NULL; + if(saved_menu->parent) + XUnmapWindow(dpy, saved_menu->parent); + XSetWindowBackground(dpy, saved_menu->win, s->dri.dri_Pens[BARBLOCKPEN]); + XClearWindow(dpy, saved_menu->win); + redraw_menu(saved_menu, saved_menu->win); + } + if(saved_item != NULL) { + XSync(dpy, False); + menuaction(saved_item, saved_subitem); + } + XLowerWindow(dpy, s->menubar); +}