I have been bothered by a situation where I create a window and manually place it at one location, but the window actually appears in a different location. It is easy to reproduce with a very small .fvwm2rc:
Style * ManualPlacement EdgeResistance 0 100 Start by placing an xterm in the lower right corner of the screen, touching the side and bottom. Place the mouse near the upper left corner of the window, within the window. Type "xterm" and press enter. You will see the new window outline appear exactly over the border of the first xterm; that is, it appears snapped to the edges of the screen. Press enter to place the window. Note that it is placed not where the outline was, but at the pointer position. I investigated the code in __move_loop, in move_resize.c. (I am using fvwm 2.5.16, but the file is identical in the 20060529 snapshot I just checked). The problem is that in "case ButtonRelease" (line 2445), there is a test that says if the mouse is in the same position it started in, don't apply the snap. This idea is that if the mouse didn't move, the outline never snapped, so the window shouldn't snap either. This is an ill-conceived test for two reasons. One, the mouse could have moved and moved back to its original position! It's not actually that hard to achieve this. Two, there are cases other than mouse movement that causes the window outline to snap. For example, if an EnterNotify or LeaveNotify event is received (2301), a MotionNotify event is faked up, and in "case MotionNotify" (2483), DoSnapAttract is called to snap the outline. This is in fact what happens in the test case above. However, it is not always the case that the initial outline is snapped. If there were not already a window below the mouse when I ran xterm, no EnterNotify event would have been received, and thus the outline would have appeared unsnapped, at the pointer. This inconsistency is cause of further confusion to the user: Why does the outline initially appear snapped sometimes and not other times? To resolve this issue, we must 1. decide whether the outline should initially appear snapped or unsnapped; 2. ensure that the outline in fact initially appears snapped or unsnapped consistently; 3. ensure that the window gets placed where the outline appeared. I took what seems to be the simplest approach (a necessity for me, given the serpentine nature of this function), which is also the behavior I find the most natural: I decided that the outline should always start out snapped. It is only a couple of lines to snap the outline at the top of the function, and then unconditionally snap on ButtonRelease. The below patch Works For Me. Andrew PS. Please Cc: me, as I am not subscribed. --- move_resize.c.orig 2006-05-29 14:15:16.000000000 -0700 +++ move_resize.c 2006-05-29 14:18:37.000000000 -0700 @@ -2197,6 +2197,10 @@ xl_orig = xl; yt_orig = yt; + /* Without this, the outline sometimes initially shows snapped, + * sometimes unsnapped. At least this is consistent. */ + DoSnapAttract(fw, Width, Height, &xl, &yt); + /* draw initial outline */ if (!IS_ICONIFIED(fw) && ((!do_move_opaque && !Scr.gs.do_emulate_mwm) || !IS_MAPPED(fw))) @@ -2463,15 +2467,9 @@ xl = xl2; yt = yt2; } - if (xl != xl_orig || yt != yt_orig || vx != Scr.Vx || - vy != Scr.Vy) + if (do_snap) { - /* only snap if the window actually moved! */ - if (do_snap) - { - DoSnapAttract( - fw, Width, Height, &xl, &yt); - } + DoSnapAttract(fw, Width, Height, &xl, &yt); } *FinalX = xl;