--- ./src/menu.h.orig-mapmenu Mon Apr 3 01:05:54 2000 +++ ./src/menu.h Mon Apr 3 02:12:19 2000 @@ -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/wconfig.h.in.orig-mapmenu Mon Apr 3 02:07:57 2000 +++ ./src/wconfig.h.in Mon Apr 3 02:12:19 2000 @@ -564,6 +564,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.c.orig-mapmenu Mon Apr 3 01:05:54 2000 +++ ./src/menu.c Mon Apr 3 02:12:19 2000 @@ -2721,6 +2721,73 @@ } +/* 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 Apr 3 01:06:04 2000 +++ ./src/rootmenu.c Mon Apr 3 02:12:19 2000 @@ -1711,6 +1711,7 @@ OpenRootMenu(WScreen *scr, int x, int y, int keyboard) { WMenu *menu=NULL; + int mx, my; proplist_t definition; /* static proplist_t domain=NULL; @@ -1732,8 +1733,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; } @@ -1779,7 +1782,8 @@ scr->root_menu = menu; } if (menu) { - wMenuMapAt(menu, x-menu->frame->core->width/2, y, keyboard); + wMenuCalculatePosition(menu, x, y, DEF_MENU_RELPOS, &mx, &my); + wMenuMapAt(menu, mx, my, keyboard); } if (scr->flags.root_menu_changed_shortcuts) --- ./src/appicon.c.orig-mapmenu Mon Apr 3 01:05:44 2000 +++ ./src/appicon.c Mon Apr 3 02:12:19 2000 @@ -615,6 +615,7 @@ { WMenu *menu; WScreen *scr = wapp->main_window_desc->screen_ptr; + int mx, my; int i; if (!scr->icon_menu) { @@ -633,17 +634,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 Apr 26 21:38:11 1999 +++ ./src/switchmenu.c Mon Apr 3 02:12:19 2000 @@ -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; } @@ -125,8 +128,8 @@ if (switchmenu) { if (!switchmenu->flags.realized) wMenuRealize(switchmenu); - wMenuMapAt(switchmenu, x-switchmenu->frame->core->width/2, y, - keyboard); + wMenuCalculatePosition(switchmenu, x, y, DEF_MENU_RELPOS, &mx, &my); + wMenuMapAt(switchmenu, mx, my, keyboard); } } --- ./src/winmenu.c.orig-mapmenu Tue Sep 21 22:09:43 1999 +++ ./src/winmenu.c Mon Apr 3 02:12:19 2000 @@ -633,6 +633,7 @@ { WMenu *menu; WScreen *scr = wwin->screen_ptr; + int mx, my; wwin->flags.menu_open_for_me = 1; @@ -657,14 +658,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); } @@ -673,6 +674,7 @@ { WMenu *menu; WScreen *scr = wwin->screen_ptr; + int mx, my; wwin->flags.menu_open_for_me = 1; @@ -697,8 +699,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); } --- ./src/dock.c.orig-mapmenu Mon Apr 3 01:05:47 2000 +++ ./src/dock.c Mon Apr 3 02:12:19 2000 @@ -3350,6 +3350,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; @@ -3490,14 +3491,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; @@ -3509,11 +3505,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); }