A slight issue I've noticed with calmwm (under OpenBSD 6.4) is that the
mouse can occasionally get "stuck" inside of a window, and can't be
moved out of it. This most often seems to occur with modal dialogs (in
particular, most of the configuration dialogs for graphics/ipe exhibit
this behavior, but I've seen it occur in other programs as well. The
specific symptom seems to be that moving the mouse beyond the edge of an
effected window causes it to "teleport" back to the exact center of the
window. Also, affected windows cannot be lowered by using the window-
cycle binding, as they immediate re-capture focus. However, the menu-
window binding can be used to search for another window and raise it,
and lowering the entire group of the effected group allows it to be
switched away from. 

I'm not sure if this is a bug or intended behavior, but if it is the
latter I feel there should be a config flag to disable it (I would be
willing to do the legwork if someone knowledgeable with CWM can guide
me).

I believe the issue lies in client.c in the fragments noted below, as
this is the only place that the mouse position seems to be modified.
That said, my xlib skills are not very good, and I haven't worked with
the CWM codebase before.

~ Charles

...
struct client_ctx *
client_init(Window win, struct screen_ctx *sc, int active)
{
...
        if (wattr.map_state != IsViewable) {
                client_placecalc(cc);
...
static void
client_placecalc(struct client_ctx *cc)
{
...
        if (cc->hint.flags & (USPosition | PPosition)) {
                if (cc->geom.x >= sc->view.w)
                        cc->geom.x = sc->view.w - cc->bwidth - 1;
                if (cc->geom.x + cc->geom.w + cc->bwidth <= 0)
                        cc->geom.x = -(cc->geom.w + cc->bwidth - 1);
                if (cc->geom.y >= sc->view.h)
                        cc->geom.x = sc->view.h - cc->bwidth - 1;
                if (cc->geom.y + cc->geom.h + cc->bwidth <= 0)
                        cc->geom.y = -(cc->geom.h + cc->bwidth - 1);
        } else {
                struct geom              area;
                int                      xmouse, ymouse;

                xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
                area = screen_area(sc, xmouse, ymouse, CWM_GAP);
                area.w += area.x;
                area.h += area.y;
                xmouse = MAX(xmouse, area.x) - cc->geom.w / 2;
                ymouse = MAX(ymouse, area.y) - cc->geom.h / 2;

                xmouse = MAX(xmouse, area.x);
                ymouse = MAX(ymouse, area.y);

                xslack = area.w - cc->geom.w - cc->bwidth * 2;
                yslack = area.h - cc->geom.h - cc->bwidth * 2;

                if (xslack >= area.x) {
                        cc->geom.x = MAX(MIN(xmouse, xslack), area.x);
                } else {
                        cc->geom.x = area.x;
                        cc->geom.w = area.w;
                }
                if (yslack >= area.y) {
                        cc->geom.y = MAX(MIN(ymouse, yslack), area.y);
                } else {
                        cc->geom.y = area.y;
                        cc->geom.h = area.h;
                }
        }
...

Reply via email to