position popup window under the cursor */
| 305 | |
| 306 | /* position popup window under the cursor */ |
| 307 | void |
| 308 | positionpopup(Widget w, boolean bottom) /* position y on bottom? */ |
| 309 | { |
| 310 | Arg args[3]; |
| 311 | Cardinal num_args; |
| 312 | Dimension width, height, b_width; |
| 313 | int x, y, max_x, max_y; |
| 314 | Window root, child; |
| 315 | XSizeHints *hints; |
| 316 | int dummyx, dummyy; |
| 317 | unsigned int dummymask; |
| 318 | extern Widget toplevel; |
| 319 | |
| 320 | /* following line deals with a race condition w/brain-damaged WM's -dlc */ |
| 321 | XtUnrealizeWidget(w); |
| 322 | |
| 323 | XQueryPointer(XtDisplay(toplevel), XtWindow(toplevel), &root, &child, &x, |
| 324 | &y, &dummyx, &dummyy, &dummymask); |
| 325 | num_args = 0; |
| 326 | XtSetArg(args[num_args], XtNwidth, &width); num_args++; |
| 327 | XtSetArg(args[num_args], XtNheight, &height); num_args++; |
| 328 | XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++; |
| 329 | XtGetValues(w, args, num_args); |
| 330 | |
| 331 | /* position so that the cursor is center,center or center,bottom */ |
| 332 | width += 2 * b_width; |
| 333 | x -= ((Position) width / 2); |
| 334 | if (x < 0) |
| 335 | x = 0; |
| 336 | if (x > (max_x = (Position) (XtScreen(w)->width - width))) |
| 337 | x = max_x; |
| 338 | |
| 339 | if (bottom) { |
| 340 | y -= (height + b_width - 1); |
| 341 | height += 2 * b_width; |
| 342 | } else { |
| 343 | height += 2 * b_width; |
| 344 | y -= ((Position) height / 2); |
| 345 | } |
| 346 | if (y < 0) |
| 347 | y = 0; |
| 348 | if (y > (max_y = (Position) (XtScreen(w)->height - height))) |
| 349 | y = max_y; |
| 350 | |
| 351 | num_args = 0; |
| 352 | XtSetArg(args[num_args], XtNx, x); num_args++; |
| 353 | XtSetArg(args[num_args], XtNy, y); num_args++; |
| 354 | XtSetValues(w, args, num_args); |
| 355 | |
| 356 | /* Some older window managers ignore XtN{x,y}; hint the same values. |
| 357 | {x,y} are not used by newer window managers; older ones need them. */ |
| 358 | XtRealizeWidget(w); |
| 359 | hints = XAllocSizeHints(); |
| 360 | hints->flags = USPosition; |
| 361 | hints->x = x; |
| 362 | hints->y = y; |
| 363 | XSetWMNormalHints(XtDisplay(w), XtWindow(w), hints); |
| 364 | XFree(hints); |
no outgoing calls
no test coverage detected