The attached patch mostly fixes the problem.  However, there is one
thing left to think about:

Normally, an application is not allowed to move a shaded window,
but is is allowed to resize it.  That is in order to not confuse
the user with shaded windows jumping around.

However, if a window has northwest gravity and is shaded to the
right and the application increases its width by, say, 200 pixels,
then the window shade jumps 200 pixels to the right.  Since
windows are often shaded to the page's border, the window shade
even jumps to a different page.

This effect can always happen if the gravity of the window shade
is different from the gravity of the unshaded window, e.g. the
window has north... gravity and is shaded to the bottom,
bottom left or bottom right etc.

There are thre options that all have drawbacks:

1. Use the window's gravity if a shaded window is resized.
   ==> The current jumping window effect implemented with the
       patch.

2. Override the window's gravity with the window shade direction,
   i.e. NW becomes NE on a window shaded to the right and SW on a
   window shaded to the bottom etc.
   ==> The window may have moved to a funny place after unshading,
       for example partially off screen.
   ==> Requires some careful coding in
       event.c:__handle_cr_on_client().

3. Forbid resizing of shaded window (possibly only if gravities do
   not match).
   ==> Limits fvwm's behaviour in many useful cases.

I think I prefer solution 2 because although the window might end
up in a different position than it would have if it had been
resized without being shaded, this may be the least surprising
solution for the user as unshading is a process with a result that
is easy to understand.

However, I'd like to hear some more opinions.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
Index: events.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/events.c,v
retrieving revision 1.567
diff -u -u -r1.567 events.c
--- events.c	4 Jan 2010 12:00:38 -0000	1.567
+++ events.c	9 Oct 2010 12:09:51 -0000
@@ -926,6 +926,7 @@
 	int *ret_do_send_event, XConfigureRequestEvent cre,
 	const evh_args_t *ea, FvwmWindow *fw, Bool force, int force_gravity)
 {
+	rectangle current_g;
 	rectangle new_g;
 	rectangle d_g;
 	size_rect constr_dim;
@@ -1048,6 +1049,14 @@
 	{
 		gravity = fw->hints.win_gravity;
 	}
+	if (IS_SHADED(fw))
+	{
+		get_unshaded_geometry(fw, &current_g);
+	}
+	else
+	{
+		current_g = fw->g.frame;
+	}
 	if (!(cre.value_mask & (CWX | CWY)))
 	{
 		/* nothing */
@@ -1066,13 +1075,13 @@
 		{
 			ref_x = cre.x -
 				((grav_x + 1) * b.total_size.width) / 2;
-			d_g.x = ref_x - fw->g.frame.x;
+			d_g.x = ref_x - current_g.x;
 		}
 		if (cre.value_mask & CWY)
 		{
 			ref_y = cre.y -
 				((grav_y + 1) * b.total_size.height) / 2;
-			d_g.y = ref_y - fw->g.frame.y;
+			d_g.y = ref_y - current_g.y;
 		}
 	}
 	else /* ..._USE_GRAV or ..._AUTO */
@@ -1080,20 +1089,21 @@
 		/* default: traditional cr handling */
 		if (cre.value_mask & CWX)
 		{
-			d_g.x = cre.x - fw->g.frame.x - b.top_left.width;
+			d_g.x = cre.x - current_g.x - b.top_left.width;
 		}
 		if (cre.value_mask & CWY)
 		{
-			d_g.y = cre.y - fw->g.frame.y - b.top_left.height;
+			d_g.y = cre.y - current_g.y - b.top_left.height;
 		}
 	}
+
 	if (cre.value_mask & CWHeight)
 	{
 		if (cre.height <
 		    (WINDOW_FREAKED_OUT_SIZE - b.total_size.height))
 		{
 			d_g.height = cre.height -
-				(fw->g.frame.height - b.total_size.height);
+				(current_g.height - b.total_size.height);
 		}
 		else
 		{
@@ -1112,7 +1122,7 @@
 		if (cre.width < (WINDOW_FREAKED_OUT_SIZE - b.total_size.width))
 		{
 			d_g.width = cre.width -
-				(fw->g.frame.width - b.total_size.width);
+				(current_g.width - b.total_size.width);
 		}
 		else
 		{
@@ -1127,12 +1137,7 @@
 	 * the same as the requested client window width; the inner height is
 	 * the same as the requested client window height plus any title bar
 	 * slop. */
-	new_g = fw->g.frame;
-	if (IS_SHADED(fw))
-	{
-		new_g.width = fw->g.normal.width;
-		new_g.height = fw->g.normal.height;
-	}
+	new_g = current_g;
 	oldnew_dim.width = new_g.width + d_g.width;
 	oldnew_dim.height = new_g.height + d_g.height;
 	constr_dim.width = oldnew_dim.width;
@@ -1144,12 +1149,12 @@
 	d_g.height += (constr_dim.height - oldnew_dim.height);
 	if ((cre.value_mask & CWX) && d_g.width)
 	{
-		new_g.x = fw->g.frame.x + d_g.x;
-		new_g.width = fw->g.frame.width + d_g.width;
+		new_g.x = current_g.x + d_g.x;
+		new_g.width = current_g.width + d_g.width;
 	}
 	else if ((cre.value_mask & CWX) && !d_g.width)
 	{
-		new_g.x = fw->g.frame.x + d_g.x;
+		new_g.x = current_g.x + d_g.x;
 	}
 	else if (!(cre.value_mask & CWX) && d_g.width)
 	{
@@ -1157,21 +1162,21 @@
 	}
 	if ((cre.value_mask & CWY) && d_g.height)
 	{
-		new_g.y = fw->g.frame.y + d_g.y;
-		new_g.height = fw->g.frame.height + d_g.height;
+		new_g.y = current_g.y + d_g.y;
+		new_g.height = current_g.height + d_g.height;
 	}
 	else if ((cre.value_mask & CWY) && !d_g.height)
 	{
-		new_g.y = fw->g.frame.y + d_g.y;
+		new_g.y = current_g.y + d_g.y;
 	}
 	else if (!(cre.value_mask & CWY) && d_g.height)
 	{
 		gravity_resize(gravity, &new_g, 0, d_g.height);
 	}
 
-	if (new_g.x == fw->g.frame.x && new_g.y == fw->g.frame.y &&
-	    new_g.width == fw->g.frame.width &&
-	    new_g.height == fw->g.frame.height)
+	if (new_g.x == current_g.x && new_g.y == current_g.y &&
+	    new_g.width == current_g.width &&
+	    new_g.height == current_g.height)
 	{
 		/* Window will not be moved or resized; send a synthetic
 		 * ConfigureNotify. */
@@ -1182,6 +1187,7 @@
 	{
 		if (IS_SHADED(fw))
 		{
+			fw->g.normal = new_g;
 			get_shaded_geometry(fw, &new_g, &new_g);
 		}
 		frame_setup_window_app_request(

Reply via email to