From f252636744937f073587209e0eb61e0d686d526f Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Wed, 29 Jul 2009 16:17:54 +0200 Subject: [PATCH] Menu: Improve mouse event management in menu_manage_event. (Add Button{4, 5} management and quit when clicking on another window) --- src/client.c | 9 ++++++--- src/config_struct.h | 46 ++++++++++++++++++++++----------------------- src/ewmh.c | 11 ++++++++++- src/infobar.c | 2 +- src/menu.c | 27 +++++++++++++++++++++++--- src/mouse.c | 5 ++--- src/structs.h | 2 +- src/wmfs.c | 20 ++++++++++++++------ 8 files changed, 81 insertions(+), 41 deletions(-) diff --git a/src/client.c b/src/client.c index 92af3fa..05ee77a 100644 --- a/src/client.c +++ b/src/client.c @@ -614,7 +614,7 @@ client_geo_hints(XRectangle *geo, Client *c) void client_moveresize(Client *c, XRectangle geo, Bool r) { - if(!c || c->state_dock) + if(!c) return; if(r) @@ -890,10 +890,13 @@ client_unmanage(Client *c) /* To focus the previous client */ for(c_next = clients; - c_next && c_next != c->prev && c_next->tag != c->tag && c_next->screen != c->screen; + c_next && c_next != c->prev + && c_next->tag != c->tag + && c_next->screen != c->screen; c_next = c_next->next); - if(c_next && c_next->tag == seltag[selscreen] && c_next->screen == selscreen) + if(c_next && c_next->tag == seltag[selscreen] + && c_next->screen == selscreen) client_focus(c_next); free(c); diff --git a/src/config_struct.h b/src/config_struct.h index bff90e1..78d23ee 100644 --- a/src/config_struct.h +++ b/src/config_struct.h @@ -32,7 +32,7 @@ #include "wmfs.h" -#define FILE_NAME ".config/wmfs/wmfsrc" +#define FILE_NAME ".config/wmfs/wmfsrc" cfg_t *cfg, *cfgtmp; char final_path[128]; @@ -50,7 +50,7 @@ cfg_opt_t misc_opts[] = cfg_opt_t mouse_button_opts[] = { CFG_INT("tag", -1, CFGF_NONE), - CFG_INT("screen", -1, CFGF_NONE), + CFG_INT("screen", -1, CFGF_NONE), CFG_STR("button", "Button1", CFGF_NONE), CFG_STR("func", "", CFGF_NONE), CFG_STR("cmd", "", CFGF_NONE), @@ -85,7 +85,7 @@ cfg_opt_t line_opts[] = cfg_opt_t button_opts[] = { CFG_SEC("mouse", mouse_button_opts, CFGF_MULTI), - CFG_SEC("line", line_opts, CFGF_MULTI), + CFG_SEC("line", line_opts, CFGF_MULTI), CFG_END() }; @@ -104,16 +104,16 @@ cfg_opt_t titlebar_opts[] = cfg_opt_t client_opts[]= { - CFG_BOOL("place_at_mouse", cfg_false, CFGF_NONE), - CFG_BOOL("border_shadow", cfg_false, CFGF_NONE), - CFG_INT("border_height", 1, CFGF_NONE), - CFG_STR("border_normal", "#354B5C", CFGF_NONE), - CFG_STR("border_focus", "#6286A1", CFGF_NONE), - CFG_STR("resize_corner_normal", "#ff0000", CFGF_NONE), - CFG_STR("resize_corner_focus", "#ff0000", CFGF_NONE), - CFG_STR("modifier", "Alt", CFGF_NONE), - CFG_SEC("mouse", mouse_button_opts, CFGF_MULTI), - CFG_SEC("titlebar", titlebar_opts, CFGF_NONE), + CFG_BOOL("place_at_mouse", cfg_false, CFGF_NONE), + CFG_BOOL("border_shadow", cfg_false, CFGF_NONE), + CFG_INT("border_height", 1, CFGF_NONE), + CFG_STR("border_normal", "#354B5C", CFGF_NONE), + CFG_STR("border_focus", "#6286A1", CFGF_NONE), + CFG_STR("resize_corner_normal", "#ff0000", CFGF_NONE), + CFG_STR("resize_corner_focus", "#ff0000", CFGF_NONE), + CFG_STR("modifier", "Alt", CFGF_NONE), + CFG_SEC("mouse", mouse_button_opts, CFGF_MULTI), + CFG_SEC("titlebar", titlebar_opts, CFGF_NONE), CFG_END() }; @@ -151,7 +151,7 @@ cfg_opt_t tag_opts[] = CFG_STR("layout", "tile_right", CFGF_NONE), CFG_STR("infobar_position", "top", CFGF_NONE), CFG_BOOL("resizehint", cfg_false, CFGF_NONE), - CFG_STR_LIST("clients", "{}", CFGF_NONE), + CFG_STR_LIST("clients", "{}", CFGF_NONE), CFG_END() }; @@ -181,15 +181,15 @@ cfg_opt_t menu_items_opts[] = cfg_opt_t menus_opts[] = { - CFG_STR("name", "menu_wname", CFGF_NONE), - CFG_BOOL("place_at_mouse", cfg_true, CFGF_NONE), - CFG_INT("x", 0, CFGF_NONE), - CFG_INT("y", 0, CFGF_NONE), - CFG_STR("fg_normal", "#ffffff", CFGF_NONE), - CFG_STR("bg_normal", "#000000", CFGF_NONE), - CFG_STR("fg_focus", "#ffffff", CFGF_NONE), - CFG_STR("bg_focus", "#000000", CFGF_NONE), - CFG_SEC("item", menu_items_opts, CFGF_MULTI), + CFG_STR("name", "menu_wname", CFGF_NONE), + CFG_BOOL("place_at_mouse", cfg_true, CFGF_NONE), + CFG_INT("x", 0, CFGF_NONE), + CFG_INT("y", 0, CFGF_NONE), + CFG_STR("fg_normal", "#ffffff", CFGF_NONE), + CFG_STR("bg_normal", "#000000", CFGF_NONE), + CFG_STR("fg_focus", "#ffffff", CFGF_NONE), + CFG_STR("bg_focus", "#000000", CFGF_NONE), + CFG_SEC("item", menu_items_opts, CFGF_MULTI), CFG_END() }; diff --git a/src/ewmh.c b/src/ewmh.c index 0354e2f..2b9a59b 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -339,17 +339,26 @@ ewmh_manage_window_type(Client *c) False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n) { atom = (Atom*)data; + for(i = 0; i < n; ++i) { /* Manage _NET_WM_WINDOW_TYPE_DOCK & _NET_WM_WINDOW_TYPE_SPLASH */ if(atom[i] == net_atom[net_wm_window_type_dock] || atom[i] == net_atom[net_wm_window_type_splash]) { + /* Unmap frame, decoration.. */ client_unmap(c); + + /* Map only window */ XMapWindow(dpy, c->win); + + /* Reparent it to ROOT win */ XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y); XRaiseWindow(dpy, c->win); - c->state_dock = True; + + /* This window will not be managed anymore, + * so let's detach it. */ + client_detach(c); } /* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */ else if(atom[i] == net_atom[net_wm_window_type_dialog]) diff --git a/src/infobar.c b/src/infobar.c index 7482f0e..88a15a8 100644 --- a/src/infobar.c +++ b/src/infobar.c @@ -152,7 +152,7 @@ infobar_draw_taglist(int sc) { if(c->screen == sc) { - infobar[sc].tags[c->tag]->bg = ((c->tag == seltag[sc]) ? conf.colors.tagselbg : conf.colors.tag_occupied_bg); + infobar[sc].tags[c->tag]->bg = ((c->tag == seltag[sc]) ? conf.colors.tagselbg : conf.colors.tag_occupied_bg); barwin_refresh_color(infobar[sc].tags[i]); } } diff --git a/src/menu.c b/src/menu.c index 71dc89f..0beca3d 100644 --- a/src/menu.c +++ b/src/menu.c @@ -114,21 +114,37 @@ menu_draw(Menu menu, int x, int y) Bool menu_manage_event(XEvent *ev, Menu *menu, BarWindow *winitem[]) { - int i; + int i, c = 0; KeySym ks; Bool quit = False; switch(ev->type) { - /* Mouse Buttons */ + /* Mouse events */ case ButtonPress: /* Execute the function linked with the item */ for(i = 0; i < menu->nitem; ++i) + { if(ev->xbutton.window == winitem[i]->win && (ev->xbutton.button == Button1 || ev->xbutton.button == Button2)) + { if(menu->item[i].func) menu->item[i].func(menu->item[i].cmd); - quit = True; + + quit = True; + } + else if(ev->xbutton.window != winitem[i]->win) + ++c; + else if(ev->xbutton.button == Button4) + menu_focus_item(menu, menu->focus_item - 1, winitem); + else if(ev->xbutton.button == Button5) + menu_focus_item(menu, menu->focus_item + 1, winitem); + } + + /* If the clicked window is not one of menu wins (items), quit. */ + if(c == i) + quit = True; + break; /* Keys */ @@ -139,17 +155,21 @@ menu_manage_event(XEvent *ev, Menu *menu, BarWindow *winitem[]) case XK_Up: menu_focus_item(menu, menu->focus_item - 1, winitem); break; + case XK_Down: menu_focus_item(menu, menu->focus_item + 1, winitem); break; + case XK_Return: if(menu->item[menu->focus_item].func) menu->item[menu->focus_item].func(menu->item[menu->focus_item].cmd); quit = True; break; + case XK_Escape: quit = True; break; + } break; @@ -160,6 +180,7 @@ menu_manage_event(XEvent *ev, Menu *menu, BarWindow *winitem[]) if(ev->xcrossing.window == winitem[i]->win) menu_focus_item(menu, i, winitem); break; + default: getevent(*ev); break; diff --git a/src/mouse.c b/src/mouse.c index 20f245b..dcddcbd 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -62,7 +62,7 @@ mouse_move(Client *c) GC gci; XEvent ev; - if(c->max || c->state_fullscreen || c->state_dock) + if(c->max || c->state_fullscreen) return; ocx = c->geo.x; @@ -179,8 +179,7 @@ mouse_resize(Client *c) GC gci; float mwf = tags[selscreen][seltag[selscreen]].mwfact; - if(c->max || c->lmax - || c->state_fullscreen || c->state_dock) + if(c->max || c->lmax || c->state_fullscreen) return; XQueryPointer(dpy, ROOT, &w, &w, &omx, &omy, &d, &d, (uint *)&u); diff --git a/src/structs.h b/src/structs.h index 38c16c3..830412b 100644 --- a/src/structs.h +++ b/src/structs.h @@ -162,7 +162,7 @@ struct Client /* Client Information */ Bool max, tile, free, hide; Bool hint, lmax, unmapped; - Bool state_dock, state_fullscreen; + Bool state_fullscreen; /* Struct in chains */ Client *next; Client *prev; diff --git a/src/wmfs.c b/src/wmfs.c index 34432af..f322ea6 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -349,12 +349,14 @@ main(int argc, char **argv) while ((i = getopt(argc, argv, "hvic:s:g:")) != -1) { - if(i == 'c' || i == 's' || i == 'g') - if(!(dpy = XOpenDisplay(NULL))) - { - fprintf(stderr, "WMFS: cannot open X server.\n"); - exit(EXIT_FAILURE); - } + + /* For options who need WMFS running */ + if((i == 'c' || i == 's' || i == 'g') + && !(dpy = XOpenDisplay(NULL))) + { + fprintf(stderr, "WMFS: cannot open X server.\n"); + exit(EXIT_FAILURE); + } switch(i) { @@ -369,10 +371,12 @@ main(int argc, char **argv) " -v Show WMFS version\n", argv[0]); exit(EXIT_SUCCESS); break; + case 'i': printf("WMFS - Window Manager From Scratch By Martin Duquesnoy\n"); exit(EXIT_SUCCESS); break; + case 'v': printf("WMFS version : "WMFS_VERSION".\n" " Compilation settings :\n" @@ -381,16 +385,19 @@ main(int argc, char **argv) " - On "WMFS_COMPILE_MACHINE" by "WMFS_COMPILE_BY".\n"); exit(EXIT_SUCCESS); break; + case 'c': exec_uicb_function(argv[2], ((argv[3]) ? argv[3] : NULL)); XCloseDisplay(dpy); exit(EXIT_SUCCESS); break; + case 's': set_statustext(optarg); XCloseDisplay(dpy); exit(EXIT_SUCCESS); break; + case 'g': getinfo(optarg); XCloseDisplay(dpy); @@ -399,6 +406,7 @@ main(int argc, char **argv) } } + /* Check if WMFS can open X server */ if(!(dpy = XOpenDisplay(NULL))) { fprintf(stderr, "WMFS: cannot open X server.\n");