On Sun, 15 May 2011 14:12:08 -0400
Okan Demirmen <[email protected]> wrote:
> On Sun 2011.05.15 at 16:44 +0300, Sviatoslav Chagaev wrote:
> > I switch Xinerama screens on and off quite often (with the help of
> > xrandr(1)). Sometimes, this results in windows ending up beyond the
> > screen boundries.
> > Like when a Xinerama screen has windows and is to the right or to the
> > bottom from another Xinerama screen and you turn it off.
> >
> > Correct me if I'm wrong, but there's no way to bring such windows
> > back to the screen.
> > Even the "kill-the-app-and-start-it-again" approach doesn't always work
> > (let alone it being inconvenient...) -- some apps remember their
> > position and start up at that same location the next time (Sylpheed,
> > Pidgin, epdfview...).
> >
> > This is how I solved it for myself: when an XRandR event comes, go thru
> > the list of all client windows and move those which are beyond the
> > screen boundries to (0,0) (or (gap_x, gap_y) if you configured them).
> > This also works when rotation is applied to the screen, it can
> > cause a window to fall off of the screen too.
>
> So this has hit me as well in the past, when I used to have another
> screen. I have a large re-work of all the xine stuff,
Oh, I see, I'll just wait for an update then.
While here, I noticed another thing today, due to poor performance,
when I was resizing windows, I could actually see how the window with
the current size of the window first appeared at (2*cc->geom.x,
2*cc->geom.y) and then jumped to (cc->geom.x, cc->geom.y), the
following diff made this go away:
Index: mousefunc.c
===================================================================
RCS file: /cvs/xenocara/app/cwm/mousefunc.c,v
retrieving revision 1.26
diff -u -p -r1.26 mousefunc.c
--- mousefunc.c 13 May 2011 12:53:19 -0000 1.26
+++ mousefunc.c 16 May 2011 18:59:39 -0000
@@ -65,10 +65,10 @@ mousefunc_sweep_draw(struct client_ctx *
width = MAX(width_size, width_name);
height = font_ascent(sc) + font_descent(sc) + 1;
- XMoveResizeWindow(X_Dpy, sc->menuwin, cc->geom.x, cc->geom.y,
+ XReparentWindow(X_Dpy, sc->menuwin, cc->win, 0, 0);
+ XMoveResizeWindow(X_Dpy, sc->menuwin, 0, 0,
width, height * 2);
XMapWindow(X_Dpy, sc->menuwin);
- XReparentWindow(X_Dpy, sc->menuwin, cc->win, 0, 0);
XClearWindow(X_Dpy, sc->menuwin);
font_draw(sc, cc->name, strlen(cc->name), sc->menuwin,
2, font_ascent(sc) + 1);
> but if I don't
> get that in soonish, I'll look at this more closely - however, also
> consider the fact that the w/h might also be out of range for the
> remaining xinerama screens as well;
Ah, thanks, didn't think of that.
> maybe scale to xmax and ymax as
> well if out of range.
>
> Thanks though!
>
> Cheers,
> Okan
>
> >
> > Index: calmwm.h
> > ===================================================================
> > RCS file: /cvs/xenocara/app/cwm/calmwm.h,v
> > retrieving revision 1.125
> > diff -u -p -r1.125 calmwm.h
> > --- calmwm.h 11 May 2011 13:53:51 -0000 1.125
> > +++ calmwm.h 15 May 2011 13:02:31 -0000
> > @@ -365,6 +365,9 @@ struct screen_ctx *screen_fromroot(Windo
> > void screen_init_xinerama(struct screen_ctx *);
> > void screen_update_geometry(struct screen_ctx *,
> > int, int);
> > void screen_updatestackingorder(struct screen_ctx
> > *);
> > +int screen_is_client_beyond(struct screen_ctx *,
> > + struct client_ctx *);
> > +void screen_assert_clients_within(struct screen_ctx
> > *);
> >
> > void kbfunc_client_cycle(struct client_ctx *, union
> > arg *);
> > void kbfunc_client_cyclegroup(struct client_ctx *,
> > Index: screen.c
> > ===================================================================
> > RCS file: /cvs/xenocara/app/cwm/screen.c,v
> > retrieving revision 1.28
> > diff -u -p -r1.28 screen.c
> > --- screen.c 11 May 2011 13:53:51 -0000 1.28
> > +++ screen.c 15 May 2011 13:02:31 -0000
> > @@ -131,3 +131,55 @@ screen_update_geometry(struct screen_ctx
> > XA_CARDINAL, 32, PropModeReplace,
> > (unsigned char *)workareas, CALMWM_NGROUPS * 4);
> > }
> > +
> > +/*
> > + * Return non-zero if client is beyond the screen.
> > + */
> > +int
> > +screen_is_client_beyond(struct screen_ctx *sc, struct client_ctx *cc)
> > +{
> > + int bw, top, left, right, bottom;
> > +
> > + bw = cc->bwidth * 2;
> > + top = cc->geom.y;
> > + left = cc->geom.x;
> > + right = cc->geom.x + cc->geom.width + bw - 1;
> > + bottom = cc->geom.y + cc->geom.height + bw - 1;
> > +
> > + if (HasXinerama) {
> > + if (screen_find_xinerama(sc, left, top))
> > + return 0;
> > + if (screen_find_xinerama(sc, left, bottom))
> > + return 0;
> > + if (screen_find_xinerama(sc, right, top))
> > + return 0;
> > + if (screen_find_xinerama(sc, right, bottom))
> > + return 0;
> > + return 1;
> > + } else {
> > + if (top > sc->ymax || left > sc->xmax)
> > + return 1;
> > + if (bottom < 0 || right < 0)
> > + return 1;
> > + return 0;
> > + }
> > +}
> > +
> > +/*
> > + * Bring clients which are beyond the screen back.
> > + */
> > +void
> > +screen_assert_clients_within(struct screen_ctx *sc)
> > +{
> > + struct client_ctx *cc;
> > +
> > + TAILQ_FOREACH(cc, &Clientq, entry) {
> > + if (cc->sc != sc)
> > + continue;
> > + if (screen_is_client_beyond(sc, cc)) {
> > + cc->geom.x = sc->gap.left;
> > + cc->geom.y = sc->gap.top;
> > + client_move(cc);
> > + }
> > + }
> > +}
> > Index: xevents.c
> > ===================================================================
> > RCS file: /cvs/xenocara/app/cwm/xevents.c,v
> > retrieving revision 1.53
> > diff -u -p -r1.53 xevents.c
> > --- xevents.c 11 May 2011 13:53:51 -0000 1.53
> > +++ xevents.c 15 May 2011 13:02:31 -0000
> > @@ -377,6 +377,7 @@ xev_handle_randr(XEvent *ee)
> > XRRUpdateConfiguration(ee);
> > screen_update_geometry(sc, rev->width, rev->height);
> > screen_init_xinerama(sc);
> > + screen_assert_clients_within(sc);
> > }
> > }
> > }