--- ./src/wconfig.h.in.orig-mapmenu Mon Aug 13 03:26:17 2001 +++ ./src/wconfig.h.in Mon Aug 13 03:33:39 2001 @@ -555,6 +555,9 @@ #define MAX_MENU_TEXT_LENGTH 512 +#define MAX_MENU_RELPOS 1000 +#define DEF_MENU_RELPOS (MAX_MENU_RELPOS / 2) + #define MAX_RESTART_ARGS 16 #define MAX_COMMAND_SIZE 1024 --- ./src/menu.h.orig-mapmenu Mon Mar 6 15:52:43 2000 +++ ./src/menu.h Mon Aug 13 03:31:48 2001 @@ -133,6 +133,8 @@ WMenu *wMenuUnderPointer(WScreen *screen); void wMenuSaveState(WScreen *scr); void wMenuRestoreState(WScreen *scr); +void wMenuCalculatePosition(WMenu *menu, int x, int y, int relpos, + int *mx, int *my); #endif --- ./src/menu.c.orig-mapmenu Mon Jul 23 15:17:58 2001 +++ ./src/menu.c Mon Aug 13 03:37:09 2001 @@ -2731,6 +2731,65 @@ } +/* Calculate the optimal position at which to map the given menu, + * if the cursor position is (,) and the percentage * 10 of the + * menu that should be to the left of the cursor is given by + * . Return the calculated position in and . + * + * If is less than 0, the calculated position will be + * (+delta, ) where `delta' is some small number of pixels. If + * is greater than 1000, the calculated position will be + * (-(w + delta), ), where `w' is the width of the menu. + * Otherwise, the calculated position is equivalent to + * (-(w * / 1000), ). + * + * After the above calculation, the position is adjusted for appearing + * off the screen horizontally, with a bias toward the lefthand edge. + * That is, if w is less than or equal to the width of the screen, the + * menu position is adjusted so the that menu appears entirely on the + * screen. If w is greater than the width of the screen, the menu + * position is adjusted such that the left edge of the menu appears at + * the left edge of the screen. + */ +#define DELTA_X 2 +void +wMenuCalculatePosition(WMenu *menu, int x, int y, int relpos, int *mx, int *my) +{ + WScreen *wscr; + int sw; + int mw; + int dx; + + *mx = x; + *my = y; + + if ((NULL == menu) || (NULL == menu->frame) || + (NULL == menu->frame->core) || (NULL == menu->frame->screen_ptr)) { + return; + } + wscr = menu->frame->screen_ptr; + sw = wscr->scr_width; + mw = menu->frame->core->width + (2 * FRAME_BORDER_WIDTH); + + if (relpos < 0) { + *mx = x + DELTA_X; + } else if (relpos > MAX_MENU_RELPOS) { + *mx = x - (mw + DELTA_X); + } else { + *mx = x - (mw * relpos) / MAX_MENU_RELPOS; + } + + dx = sw - (*mx + mw); + if (dx < 0) { + *mx += dx; + } + if (*mx < 0) { + *mx = 0; + } +} +#undef DELTA_X + + void OpenWorkspaceMenu(WScreen *scr, int x, int y) { --- ./src/rootmenu.c.orig-mapmenu Mon Jul 23 15:22:34 2001 +++ ./src/rootmenu.c Mon Aug 13 04:09:21 2001 @@ -1760,6 +1760,7 @@ OpenRootMenu(WScreen *scr, int x, int y, int keyboard) { WMenu *menu=NULL; + int mx, my; proplist_t definition; /* static proplist_t domain=NULL; @@ -1782,8 +1783,10 @@ if (keyboard) wMenuMapAt(menu, 0, 0, True); - else - wMenuMapCopyAt(menu, x-menu->frame->core->width/2, y); + else { + wMenuCalculatePosition(menu, x, y, DEF_MENU_RELPOS, &mx, &my); + wMenuMapCopyAt(menu, mx, my); + } } return; } @@ -1838,8 +1841,7 @@ newx = x - menu->frame->core->width/2; newy = y - menu->frame->core->height/2; } else { - newx = x - menu->frame->core->width/2; - newy = y; + wMenuCalculatePosition(menu, x, y, DEF_MENU_RELPOS, &newx, &newy); } wMenuMapAt(menu, newx, newy, keyboard); } --- ./src/appicon.c.orig-mapmenu Mon Jul 23 13:32:46 2001 +++ ./src/appicon.c Mon Aug 13 04:11:47 2001 @@ -608,6 +608,7 @@ { WMenu *menu; WScreen *scr = wapp->main_window_desc->screen_ptr; + int mx, my; int i; if (!scr->icon_menu) { @@ -632,17 +633,13 @@ menu->flags.realized = 0; wMenuRealize(menu); - x -= menu->frame->core->width/2; - if (x + menu->frame->core->width > scr->scr_width) - x = scr->scr_width - menu->frame->core->width; - if (x < 0) - x = 0; + wMenuCalculatePosition(menu, x, y, DEF_MENU_RELPOS, &mx, &my); /* set client data */ for (i = 0; i < menu->entry_no; i++) { menu->entries[i]->clientdata = wapp; } - wMenuMapAt(menu, x, y, False); + wMenuMapAt(menu, mx, my, False); } --- ./src/switchmenu.c.orig-mapmenu Mon Jul 23 12:55:39 2001 +++ ./src/switchmenu.c Mon Aug 13 04:17:50 2001 @@ -91,6 +91,7 @@ { WMenu *switchmenu = scr->switch_menu; WWindow *wwin; + int mx, my; if (switchmenu) { if (switchmenu->flags.mapped) { @@ -101,13 +102,15 @@ if (keyboard) wMenuMapAt(switchmenu, 0, 0, True); - else - wMenuMapCopyAt(switchmenu, - x-switchmenu->frame->core->width/2, y); + else { + wMenuCalculatePosition(switchmenu, x, y, DEF_MENU_RELPOS, + &mx, &my); + wMenuMapCopyAt(switchmenu, mx, my); + } } } else { - wMenuMapAt(switchmenu, x-switchmenu->frame->core->width/2, y, - keyboard); + wMenuCalculatePosition(switchmenu, x, y, DEF_MENU_RELPOS, &mx, &my); + wMenuMapAt(switchmenu, mx, my, keyboard); } return; } @@ -134,8 +137,8 @@ newx = x - switchmenu->frame->core->width/2; newy = y - switchmenu->frame->core->height/2; } else { - newx = x - switchmenu->frame->core->width/2; - newy = y; + wMenuCalculatePosition(switchmenu, x, y, DEF_MENU_RELPOS, + &newx, &newy); } wMenuMapAt(switchmenu, newx, newy, keyboard); } --- ./src/dock.c.orig-mapmenu Mon Jul 23 13:37:25 2001 +++ ./src/dock.c Mon Aug 13 04:25:04 2001 @@ -3303,6 +3303,7 @@ WApplication *wapp = NULL; int index = 0; int x_pos; + int mx, my; int n_selected; int appIsRunning = aicon->running && aicon->icon && aicon->icon->owner; @@ -3437,14 +3438,9 @@ if (!dock->menu->flags.realized) wMenuRealize(dock->menu); - if (dock->type == WM_CLIP) { - x_pos = event->xbutton.x_root+2; - } else { - x_pos = dock->on_right_side ? - scr->scr_width - dock->menu->frame->core->width - 2 : 0; - } - - wMenuMapAt(dock->menu, x_pos, event->xbutton.y_root+2, False); + wMenuCalculatePosition(dock->menu, event->xbutton.x_root, + event->xbutton.y_root+2, DEF_MENU_RELPOS, &mx, &my); + wMenuMapAt(dock->menu, mx, my, False); /* allow drag select */ event->xany.send_event = True; @@ -3456,11 +3452,14 @@ static void openClipWorkspaceMenu(WScreen *scr, int x, int y) { + int mx, my; + if (!scr->clip_ws_menu) { scr->clip_ws_menu = wWorkspaceMenuMake(scr, False); } wWorkspaceMenuUpdate(scr, scr->clip_ws_menu); - wMenuMapAt(scr->clip_ws_menu, x, y, False); + wMenuCalculatePosition(scr->clip_ws_menu, x, y, DEF_MENU_RELPOS, &mx, &my); + wMenuMapAt(scr->clip_ws_menu, mx, my, False); } --- ./src/winmenu.c.orig-mapmenu Mon Jul 23 12:51:49 2001 +++ ./src/winmenu.c Mon Aug 13 04:22:27 2001 @@ -629,6 +629,7 @@ { WMenu *menu; WScreen *scr = wwin->screen_ptr; + int mx, my; wwin->flags.menu_open_for_me = 1; @@ -653,14 +654,14 @@ updateMenuForWindow(menu, wwin); - x -= menu->frame->core->width/2; - if (x + menu->frame->core->width > wwin->frame_x+wwin->frame->core->width) - x = wwin->frame_x+wwin->frame->core->width - menu->frame->core->width; - if (x < wwin->frame_x) - x = wwin->frame_x; + wMenuCalculatePosition(menu, x, y, DEF_MENU_RELPOS, &mx, &my); + if (mx + menu->frame->core->width > wwin->frame_x+wwin->frame->core->width) + mx = wwin->frame_x+wwin->frame->core->width - menu->frame->core->width; + if (mx < wwin->frame_x) + mx = wwin->frame_x; if (!wwin->flags.internal_window) - wMenuMapAt(menu, x, y, keyboard); + wMenuMapAt(menu, mx, my, keyboard); } @@ -669,6 +670,7 @@ { WMenu *menu; WScreen *scr = wwin->screen_ptr; + int mx, my; wwin->flags.menu_open_for_me = 1; @@ -693,8 +695,7 @@ updateMenuForWindow(menu, wwin); - x -= menu->frame->core->width/2; - - wMenuMapAt(menu, x, y, False); + wMenuCalculatePosition(menu, x, y, DEF_MENU_RELPOS, &mx, &my); + wMenuMapAt(menu, mx, my, False); }