From 62234b871fa169a97de510e15b599f87a14b6ddf Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 11 Oct 2018 20:18:04 +0300 Subject: [PATCH] X11: Remember perm_invent window geometry --- doc/fixes36.2 | 1 + include/winX.h | 4 ++++ win/X11/winX.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ win/X11/winmenu.c | 33 ++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 064f213e6..d470094ba 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -224,6 +224,7 @@ X11: implement menucolors and allow menus to obey inverse attribute X11: make key translations work with menus on Linux X11: allow mouse wheel scrolling to work in menus by default X11: handle paged menu control keys +X11: remember perm_invent window geometry General New Features diff --git a/include/winX.h b/include/winX.h index 3e6b67197..6939353c9 100644 --- a/include/winX.h +++ b/include/winX.h @@ -168,6 +168,9 @@ struct menu_info_t { boolean cancelled; /* Menu has been explicitly cancelled. */ boolean counting; /* true when menu_count has a valid value */ boolean permi; + + int permi_x, permi_y; /* perm_invent window x,y */ + int permi_w, permi_h; /* perm_invent window wid, hei */ }; /* @@ -293,6 +296,7 @@ E void FDECL(positionpopup, (Widget, BOOLEAN_P)); /* ### winX.c ### */ E struct xwindow *FDECL(find_widget, (Widget)); E Boolean FDECL(nhApproxColor, (Screen *, Colormap, char *, XColor *)); +E void FDECL(get_widget_window_geometry, (Widget, int *, int *, int *, int *)); E Dimension FDECL(nhFontHeight, (Widget)); E char FDECL(key_event_to_char, (XKeyEvent *)); E void FDECL(msgkey, (Widget, XtPointer, XEvent *)); diff --git a/win/X11/winX.c b/win/X11/winX.c index 8f0486a2e..fa94043cd 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -432,6 +432,58 @@ XtPointer *closure_ret; } } +/* Ask the WM for window frame size */ +void +get_window_frame_extents(w, top, bottom, left, right) +Widget w; +long *top, *bottom, *left, *right; +{ + XEvent event; + Display *dpy = XtDisplay(w); + Window win = XtWindow(w); + Atom prop, retprop; + int retfmt; + unsigned long nitems; + unsigned long nbytes; + unsigned char *data = 0; + long *extents; + + prop = XInternAtom(dpy, "_NET_FRAME_EXTENTS", True); + + while (XGetWindowProperty(dpy, win, prop, + 0, 4, False, AnyPropertyType, + &retprop, &retfmt, + &nitems, &nbytes, &data) != Success + || nitems != 4 || nbytes != 0) + { + XNextEvent(dpy, &event); + } + + extents = (long *) data; + + *left = extents[0]; + *right = extents[1]; + *top = extents[2]; + *bottom = extents[3]; +} + +void +get_widget_window_geometry(w, x,y, width, height) +Widget w; +int *x, *y, *width, *height; +{ + long top, bottom, left, right; + Arg args[5]; + XtSetArg(args[0], nhStr(XtNx), x); + XtSetArg(args[1], nhStr(XtNy), y); + XtSetArg(args[2], nhStr(XtNwidth), width); + XtSetArg(args[3], nhStr(XtNheight), height); + XtGetValues(w, args, 4); + get_window_frame_extents(w, &top, &bottom, &left, &right); + *x -= left; + *y -= top; +} + #ifdef TEXTCOLOR /* ARGSUSED */ static void diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 94ef59449..77009b8d7 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -521,6 +521,15 @@ static void menu_popdown(wp) struct xwindow *wp; { + if (iflags.perm_invent && wp == &window_list[WIN_INVEN] + && wp->menu_information->how == PICK_NONE) { + get_widget_window_geometry(wp->popup, + &wp->menu_information->permi_x, + &wp->menu_information->permi_y, + &wp->menu_information->permi_w, + &wp->menu_information->permi_h); + } + nh_XtPopdown(wp->popup); /* remove the event grab */ XtDestroyWidget(wp->popup); wp->w = wp->popup = (Widget) 0; @@ -922,6 +931,12 @@ menu_item **menu_list; num_args = 0; XtSetArg(args[num_args], XtNallowShellResize, True); num_args++; + if (permi && menu_info->permi_x != -1) { + XtSetArg(args[num_args], nhStr(XtNwidth), menu_info->permi_w); + num_args++; + XtSetArg(args[num_args], nhStr(XtNheight), menu_info->permi_h); + num_args++; + } wp->popup = XtCreatePopupShell((window == WIN_INVEN) ? "inventory" : "menu", (how == PICK_NONE) @@ -1022,8 +1037,22 @@ menu_item **menu_list; menu_info->is_up = TRUE; if (permi) { + if (permi && menu_info->permi_x != -1) { + /* Cannot set window x,y at creation time, + we must move the window now instead */ + XMoveWindow(XtDisplay(wp->popup), XtWindow(wp->popup), + menu_info->permi_x, menu_info->permi_y); + } /* cant use nh_XtPopup() because it may try to grab the focus */ XtPopup(wp->popup, (int) XtGrabNone); + if (permi && menu_info->permi_x == -1) { + /* remember perm_invent window geometry the first time */ + get_widget_window_geometry(wp->popup, + &menu_info->permi_x, + &menu_info->permi_y, + &menu_info->permi_w, + &menu_info->permi_h); + } if (!updated_inventory) { XMapRaised(XtDisplay(wp->popup), XtWindow(wp->popup)); } @@ -1245,6 +1274,10 @@ struct xwindow *wp; reset_menu_count(wp->menu_information); wp->w = wp->popup = (Widget) 0; wp->menu_information->nh_colors_inited = FALSE; + wp->menu_information->permi_x = -1; + wp->menu_information->permi_y = -1; + wp->menu_information->permi_w = -1; + wp->menu_information->permi_h = -1; } void