Subject: CVS chrisr: Try to fix "variablility" in size of windows in pager; mini-window

From: CVS <[email-masked]>
Date: Fri, 16 Jun 2000 22:03:18 -0500 (CDT)

CVSROOT:	/home/cvs/fvwm
Module name:	fvwm
Changes by:	chrisr	00/06/16 22:03:18

Modified files:
	modules        : ChangeLog 
	modules/FvwmPager: x_pager.c 

Log message:
Try to fix "variablility" in size of windows in pager; mini-window
width and height now calculated by scaling original windows' width and
height. Also, since calculations are performed using integer
arithmetic, do all multiplications before the final division to
prevent division inaccuracies from being scaled up.

NOTE: this has reduced but not removed the "variablility" I am
seeing. The pager icon is still sometimes wrong when I minimise an
application and the animation has completed.

e.g.: the mini-window's size should be 1x1, which is converted to 3x3
to make it visible. However, the animated mini-window iconifies to
4x1, which is converted to 4x3. (OTOH, it used to 5x3 occasionally.)

--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]

---

From: Tim Phipps <[email-masked]>
Date: Mon, 19 Jun 2000 12:59:50 +0100

> height.

I think you'd better make this an option. I did it once and had lots of
complaints about it.

Cheers,
Tim.

---

From: Chris Rankin <[email-masked]>
Date: Tue, 20 Jun 2000 00:14:52 +1000 (EST)

> I think you'd better make this an option. I did it once and had lots of

Huh? What kind of complaints? Consider the original code:

virt1 = Scr.Vx + t->x;
edge = (virt1 * win_w) / Scr.VWidth;
virt2 = virt1 + t->width - 1;
size = (virt2 * win_w) / Scr.VWidth) - edge;

Therefore:
size = (((virt1 + t->width - 1) * win_w) / Scr.VWidth) - ((virt1 *
win_w) / Scr.VWidth);

     = ((virt1 + t->width - 1 - virt1) * win_w) / Scr.VWidth;
     = ((t->width - 1) * win_w) / Scr.VWidth;

This is assuming perfect arithmetic (which we don't have because we
lose the remainder terms in the division - which is why I make sure I
do the division last). As you can see, the only difference (apart from
operator precedence) is that the original mini-window's width was
underestimated slightly.

If necessary, I suppose I can put the "-1" back in to make the code
mathematically identical to the original, but I think I'd like to see
what happens for a bit. I searched the ChangeLog for FvwmPager and
didn't see anything in regards to this recently and so maybe the root
of the original complaints was some other bug (since fixed?) being
tickled...?

Chris.

---

From: Tim Phipps <[email-masked]>
Date: Mon, 19 Jun 2000 15:42:15 +0100

> Huh? What kind of complaints? Consider the original code:
xterm -geometry -0-0 doesn't look right on the pager. i.e. the
mini-window isn't up against the page boundary (it depends on the pager
scaling and the window size). By calculating the mini-window size from
the window size you can introduce another rounding error for the right
hand side of the mini-window. I prefer it the way you have it but others
don't and this way breaks backward compatibility.

Cheers,
Tim.

---

From: Chris Rankin <[email-masked]>
Date: Tue, 20 Jun 2000 01:00:28 +1000 (EST)

> don't and this way breaks backward compatibility.

Meaning that the mini-window size is UNDER estimated by the current
code? That doesn't seem possible, considering that the current code
scales "width" and the original scaled "width - 1". However, if you're
saying that the current code OVER estimates occasionally then I'll put
the -1 back in. "width - 1" is as good a constant as "width", and my
intent here is only to guarantee that the pager always calculates the
*same* width for a given-sized window.

Chris

---

From: Tim Phipps <[email-masked]>
Date: Tue, 20 Jun 2000 10:32:03 +0100

Chris Rankin wrote:
> code?

Yes, it's due to the way rounding errors accumulate. The original code:
  virt = Scr.Vx + t->x;
  edge = virt * win_w / Scr.VWidth;
  virt += t->width - 1;
  size = virt * win_w / Scr.VWidth - edge;

"edge" has a rounding error of 0 or -1, "virt * win_w / Scr.VWidth" has
a rounding error of 0 or -1 and so "size" has an error of +1, 0 or -1.
If you look at the right hand edge of the mini-window (edge + size) it
has an error of 0 or -1.

The new code:
  virt = Scr.Vx + t->x;
  edge = (virt * win_w) / Scr.VWidth;
  virt += t->width - 1;
  size = ((t->width - 1) * win_w) / Scr.VWidth;

"edge" has a rounding error of 0 or -1, "size" has an error of 0 or -1
and so the right hand edge of the mini-window has an error or 0, -1 or
-2.

Plugging some numbers in: Scr.Vx = 0, Scr.VWidth = 100, t->x = 51,
t->width = 48 and win_w = 50.
Old style: edge = 25, virt = 98, size = 24, right hand edge = 49.
New style: edge = 25, size = 23, right hand edge = 48

To me and you Chris size is important and so we like the new method, it
also means that the mini-window size doesn't change if the window moves.
Other people like the old style as it looks more like a shrunken version
of the screen. I don't think either is right or wrong but the new style
is a change and users will complain. I think it should be a config
option with the old style the default.

> That doesn't seem possible, considering that the current code

I'm not sure about the "- 1". I put it there so that windows on the
right hand edge of a page boundary wouldn't draw over the dashed lines
in the pager. And so that windows that are next to each other don't get
drawn overlapping in the pager. It may be buggy.

Cheers,
Tim.

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 20 Jun 2000 17:29:35 +0300

On 20 Jun 2000 10:32:03 +0100, Tim Phipps wrote:
> 
> I think it should be a config option with the old style the default.

It may be an option, but probably it is possible to invent the third way
combining the good feature of the old style (correct window possitions at
edges) and the good feature of the "new" style (constant window size).
I.e. while having the constant window size, insert a gravity - if more
than 50% of the window is in the right page half, it tends to the right.

I think this compromise can be happily acceptable to both sides.
Although it means even more mathematics will be envolved.
The test case - fully maximized window with resize step 1 - should
be shown in the pager without gaps. Resizing of such window should only
introduce gaps in the corresponding sides (not opposite as it is now).

Regards,
Mikhael.

---

From: Dan Espen <[email-masked]>
Date: Tue, 20 Jun 2000 10:46:01 -0400

> introduce gaps in the corresponding sides (not opposite as it is now).

Would it be simpler to treat a window up against a screen edge as a special
case and force any edge against a screen edge up against a pager edge?
I don't think there would be much mathematics to it.

I don't think the gravity approach would work for maximized windows.

--
Dan Espen
444 Hoes Lane  Room RRC 1C-214           E-mail: [email-masked]
Piscataway, NJ 08854                     Phone: (732) 699-5570
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]

---

From: Tim Phipps <[email-masked]>
Date: Tue, 20 Jun 2000 16:11:11 +0100

> I don't think there would be much mathematics to it.

It's not just up against screen edges it's also a problem when you tile
windows. I don't think we can have a compromise tha works for both, you
either have pager display that looks like a shrunken version of the
screen or you don't. The first way means that mini-window sizes will
vary with window position. The second way means they don't but there
will be inaccuracies in the layout of the pager.

With an option there would be an if-else statement with one line of code
in each branch. It's about a ten line patch (another few for the man
page) and about a 0% risk of bugs.

Cheers,
Tim.

---

From: Chris Rankin <[email-masked]>
Date: Wed, 21 Jun 2000 01:24:27 +1000 (EST)

> I don't think there would be much mathematics to it.

I like this approach; simple and to the point. I suppose it would go
something like:

leftPage = edge / Scr.MyDisplayWidth;
rightPage = (edge + size) / Scr.MyDisplayWidth;

BTW: what is the conventional definition of "width" here? Consider:

...XXXXX...
...X...X...
01234567890

the left edge is at pixel 3, the right edge is at pixel 7 but the
number of pixels involved is 5. Does "t->width" account for this extra
pixel already? Or is width defined to be (right - left)?

Anyway:

if (rightPage != leftPage)
{
  size = (rightPage * Scr.MyDisplayWidth) - edge;
}

or thereabouts. I'll put this change in if nobody objects, or restore
the original if there's no consensus.

Chris

---

From: Chris Rankin <[email-masked]>
Date: Wed, 21 Jun 2000 01:31:01 +1000 (EST)

> will be inaccuracies in the layout of the pager.

OK, so scratch my last post! Maybe I should just revert it for now.

Chris

---

From: Mikhael Goikhman <[email-masked]>
Date: Tue, 20 Jun 2000 19:55:55 +0300

> page) and about a 0% risk of bugs.

Ok, then, a new pager option.

But supposing that one would like to have both features (correct layout &
constant size), Tim, are there conditions, when both of them are fulfilled
(say, pager size is 1/8 of the page size) for any of the ways?

Regards,
Mikhael.

---

From: Tim Phipps <[email-masked]>
Date: Wed, 21 Jun 2000 11:34:47 +0100

> (say, pager size is 1/8 of the page size) for any of the ways?

I doubt it since I came up with an example that shows a difference with
a pager scale of 1/2.

Cheers,
Tim.