summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2005-10-17 22:18:23 +0000
committerElijah Newren <newren@src.gnome.org>2005-10-17 22:18:23 +0000
commit35bcc0b815fbb4863e6b4f6c52da061db30df8eb (patch)
tree1af2ddf38c6050cce63d1864fe8e1063a1e420e9
parent611371df45718f3bff58cf08423621ae9feaca63 (diff)
downloadmetacity-35bcc0b815fbb4863e6b4f6c52da061db30df8eb.tar.gz
Get aspect ratio resizing to mostly work, and prevent size constraints
2005-10-17 Elijah Newren <newren@gmail.com> Get aspect ratio resizing to mostly work, and prevent size constraints from causing window movement during a resize operation. * constraints-ideas.txt: record what's still broken with aspect ratio resizing, record the new bug found with clicking on an XMMS window, reorder the TODO list so finished stuff is at the bottom * src/boxes.[ch] (meta_rectangle_resize_with_gravity): fix adjustment for the various centered-somewhere gravities, (meta_rectangle_find_linepoint_closest_to_point): new function which is useful for finding an optimal rectangle size when we need to chose from a range of candidates that are spread in a line-like way between two sizes. * src/constraints.c (setup_constraint_info): I have no clue what I was thinking when I wrote that pseudogravity stuff--it was very broken and stuff works great without it so just delete it, (constrain_aspect_ratio): totally rewritten * src/keybindings.c (process_keyboard_resize_grab): Use meta_window_resize_with_gravity() instead of meta_window_move_resize() in order to provide a gravity to constraints so that constraints.c knows how to correctly fix the size when needed for minimum size hints * src/window.c (meta_window_configure_request): Add a FIXME since clicking on an XMMS window results in a failed assertion
-rw-r--r--ChangeLog31
-rw-r--r--constraints-ideas.txt53
-rw-r--r--src/boxes.c71
-rw-r--r--src/boxes.h9
-rw-r--r--src/constraints.c267
-rw-r--r--src/keybindings.c2
-rw-r--r--src/window.c3
7 files changed, 241 insertions, 195 deletions
diff --git a/ChangeLog b/ChangeLog
index 1ebaf5eb..2a321f12 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2005-10-17 Elijah Newren <newren@gmail.com>
+
+ Get aspect ratio resizing to mostly work, and prevent size
+ constraints from causing window movement during a resize
+ operation.
+
+ * constraints-ideas.txt: record what's still broken with aspect
+ ratio resizing, record the new bug found with clicking on an XMMS
+ window, reorder the TODO list so finished stuff is at the bottom
+
+ * src/boxes.[ch] (meta_rectangle_resize_with_gravity): fix
+ adjustment for the various centered-somewhere gravities,
+ (meta_rectangle_find_linepoint_closest_to_point): new function
+ which is useful for finding an optimal rectangle size when we need
+ to chose from a range of candidates that are spread in a line-like
+ way between two sizes.
+
+ * src/constraints.c (setup_constraint_info): I have no clue what I
+ was thinking when I wrote that pseudogravity stuff--it was very
+ broken and stuff works great without it so just delete it,
+ (constrain_aspect_ratio): totally rewritten
+
+ * src/keybindings.c (process_keyboard_resize_grab): Use
+ meta_window_resize_with_gravity() instead of
+ meta_window_move_resize() in order to provide a gravity to
+ constraints so that constraints.c knows how to correctly fix the
+ size when needed for minimum size hints
+
+ * src/window.c (meta_window_configure_request): Add a FIXME since
+ clicking on an XMMS window results in a failed assertion
+
2005-10-16 Elijah Newren <newren@gmail.com>
* src/constraints.c:
diff --git a/constraints-ideas.txt b/constraints-ideas.txt
index 1a79abbc..d19ea45f 100644
--- a/constraints-ideas.txt
+++ b/constraints-ideas.txt
@@ -1,5 +1,26 @@
Short-term TODO list/reminders:
+ - Brokenness left in aspect-ratio resizing:
+ - gtk+ seems to be doing nit-picky fighting with us over which way to
+ round the size. This means that if the user increases the width of
+ an aspect-ratio'ed window, we increase the height of the window in a
+ way that keeps the center fixed, gtk+ doesn't like our selected size
+ and sends a configure request, and then we resize the window to the
+ configure request size using NorthWestGravity instead of
+ WestGravity--resulting in the window drifting slightly either upward
+ or downward. sucks.
+ - Interplay between various onscreen constraints is not very good
+ (resizing should stop when any window edge hits the screen edge,
+ instead of arbitrarily clipping that edge). Similar problems
+ probably occur for overlap with other constraints (do we care about
+ the others, though?).
+
+ - Need to add a test_find_closest_linepoint to testboxes.c to test that
+ function nice and thoroughly.
+
+ - Clicking on an XMMS window causes a failed assertion due to unfixed
+ FIXME in meta_window_configure_request()
+
- Once the window goes offscreen, clicking on the edge in order to
resize results in all kinds of weirdness: clipping the window to
the screen, sending the window totally and completely offscreen,
@@ -12,31 +33,33 @@ Short-term TODO list/reminders:
meta_rectangle_region_to_string(), and maybe move other printing
stuff there.
- - Holy cow, constrain_aspect_ratio is ABSOLUTELY COMPLETELY BORKEN!!!
-
- X Trying to _move_ the window offscreen results in clipping. Huh??
- Other weirdness afterwards happens too (keyboard resizing to the
- right went up and right)
-
- Might be good to optimize by storing spanning rects in MetaWorkspace
- X Need to nuke old #ifdef'd out code
-
- Need to replace xinerama and screen structures (screen.h?) and
maybe tabpopup stuff (see bug 98340, IIRC) with MetaRectangle's
- X Need to make shove_into_rect use shortest distance in addition to
- maximal overlap (especially for totally offscreen case)
-
- Need to clean out lots of FIXMEs in the code.
- Need to do the titlebar offscreen checking, partial maximization,
etc.
- X Need to add testboxes stuff to appropriate Makefile.am thingies
-
- It looks like I can nuke work_area_screen in ConstraintInfo
+ - Do I need the include_frame parameter to get_size_limits() anymore?
+
+ X Holy cow, constrain_aspect_ratio is ABSOLUTELY COMPLETELY BORKEN!!!
+
+ X Trying to _move_ the window offscreen results in clipping. Huh??
+ Other weirdness afterwards happens too (keyboard resizing to the
+ right went up and right)
+
+ X Need to nuke old #ifdef'd out code
+
+ X Need to make shove_into_rect use shortest distance in addition to
+ maximal overlap (especially for totally offscreen case)
+
+ X Need to add testboxes stuff to appropriate Makefile.am thingies
+
X Okay the on-single-xinerama/fully-onscreen/partially-onscreen
constraints aren't as simple as I thought, the boxes.[ch] is still the
wrong way to go about it and doesn't cover everything needed, and I
@@ -112,7 +135,7 @@ Short-term TODO list/reminders:
rect, do a whole bunch of intersection operations and see if we
ever get an intersection area greater than some threshold like 0)
- - My aspect ratio resizing may still not work because perhaps
+ X My aspect ratio resizing may still not work because perhaps
closest-in-area should trump whenever one of the two is very far
away in area (Think about grabbing the SE corner with the mouse,
resizing way to the right, not letting go of the left mouse
@@ -140,8 +163,6 @@ Short-term TODO list/reminders:
first, then explain the basic ideas behind the algorithm and how
it compares to the old method and why.
- - Do I need the include_frame parameter to get_size_limits() anymore?
-
X Need to add the require_fully_onscreen and require_on_single_xinerama
flags and get them all initialized and everything
diff --git a/src/boxes.c b/src/boxes.c
index 4c1be027..9035719b 100644
--- a/src/boxes.c
+++ b/src/boxes.c
@@ -224,8 +224,11 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
case NorthGravity:
case CenterGravity:
case SouthGravity:
+ /* FIXME: Needing to adjust new_width kind of sucks, but not doing so
+ * would cause drift.
+ */
+ new_width -= (old_rect->width - new_width) % 2;
rect->x = old_rect->x + (old_rect->width - new_width)/2;
- adjust = (old_rect->width - new_width) % 1;
break;
case NorthEastGravity:
@@ -239,12 +242,7 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
/* No need to modify rect->x */
break;
}
- /* FIXME; the need for adjust sucks but not using it would cause North,
- * Center, and South gravity to break when resizing multiple times with
- * odd differences in sizes. So we instead treat it like a
- * resize_increment kind of thing, though that's kinda weird.
- */
- rect->width = new_width - adjust;
+ rect->width = new_width;
/* Next, the y direction */
adjust = 0;
@@ -259,8 +257,11 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
case WestGravity:
case CenterGravity:
case EastGravity:
+ /* FIXME: Needing to adjust new_height kind of sucks, but not doing so
+ * would cause drift.
+ */
+ new_height -= (old_rect->height - new_height) % 2;
rect->y = old_rect->y + (old_rect->height - new_height)/2;
- adjust = (old_rect->height - new_height) % 1;
break;
case SouthWestGravity:
@@ -274,8 +275,7 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
/* No need to modify rect->y */
break;
}
- /* FIXME; this sucks; see previous FIXME in this function for details */
- rect->height = new_height - adjust;
+ rect->height = new_height;
}
/* Not so simple helper function for get_minimal_spanning_set_for_region() */
@@ -975,3 +975,54 @@ meta_rectangle_shove_into_region (const GList *spanning_rects,
}
}
}
+
+void
+meta_rectangle_find_linepoint_closest_to_point (double x1, double y1,
+ double x2, double y2,
+ double px, double py,
+ double *valx, double *valy)
+{
+ /* I'll use the shorthand rx, ry for the return values, valx & valy.
+ * Now, we need (rx,ry) to be on the line between (x1,y1) and (x2,y2).
+ * For that to happen, we first need the slope of the line from (x1,y1)
+ * to (rx,ry) must match the slope of (x1,y1) to (x2,y2), i.e.:
+ * (ry-y1) (y2-y1)
+ * ------- = -------
+ * (rx-x1) (x2-x1)
+ * If x1==x2, though, this gives divide by zero errors, so we want to
+ * rewrite the equation by multiplying both sides by (rx-x1)*(x2-x1):
+ * (ry-y1)(x2-x1) = (y2-y1)(rx-x1)
+ * This is a valid requirement even when x1==x2 (when x1==x2, this latter
+ * equation will basically just mean that rx must also be equal to x1 and
+ * x2)
+ *
+ * The other requirement that we have is that the line from (rx,ry) to
+ * (px,py) must be perpendicular to the line from (x1,y1) to (x2,y2). So
+ * we just need to get a vector in the direction of each line, take the
+ * dot product of the two, and ensure that the result is 0:
+ * (rx-px)*(x2-x1) + (ry-py)*(y2-y1) = 0.
+ *
+ * This gives us two equations and two unknowns:
+ *
+ * (ry-y1)(x2-x1) = (y2-y1)(rx-x1)
+ * (rx-px)*(x2-x1) + (ry-py)*(y2-y1) = 0.
+ *
+ * This particular pair of equations is always solvable so long as
+ * (x1,y1) and (x2,y2) are not the same point (and note that anyone who
+ * calls this function that way is braindead because it means that they
+ * really didn't specify a line after all). However, the caller should
+ * be careful to avoid making (x1,y1) and (x2,y2) too close (e.g. like
+ * 10^{-8} apart in each coordinate), otherwise roundoff error could
+ * cause issues. Solving these equations by hand (or using Maple(TM) or
+ * Mathematica(TM) or whatever) results in slightly messy expressions,
+ * but that's all the below few lines do.
+ */
+
+ double diffx, diffy, den;
+ diffx = x2 - x1;
+ diffy = y2 - y1;
+ den = diffx*diffx + diffy*diffy;
+
+ *valx = (py*diffx*diffy + px*diffx*diffx + y2*x1*diffy - y1*x2*diffy) / den;
+ *valy = (px*diffx*diffy + py*diffy*diffy + x2*y1*diffx - x1*y2*diffx) / den;
+}
diff --git a/src/boxes.h b/src/boxes.h
index 1ad8683e..eca02eba 100644
--- a/src/boxes.h
+++ b/src/boxes.h
@@ -156,4 +156,13 @@ void meta_rectangle_shove_into_region(
FixedDirections fixed_directions,
MetaRectangle *rect);
+/* Finds the point on the line connecting (x1,y1) to (x2,y2) which is closest
+ * to (px, py). Useful for finding an optimal rectangle size when given a
+ * range between two sizes that are all candidates.
+ */
+void meta_rectangle_find_linepoint_closest_to_point (double x1, double y1,
+ double x2, double y2,
+ double px, double py,
+ double *valx, double *valy);
+
#endif /* META_BOXES_H */
diff --git a/src/constraints.c b/src/constraints.c
index eed8f6cc..c369f103 100644
--- a/src/constraints.c
+++ b/src/constraints.c
@@ -26,6 +26,7 @@
#include "place.h"
#include <stdlib.h>
+#include <math.h>
/* Stupid disallowing of nested C comments makes a #if 0 mandatory... */
#if 0
@@ -492,36 +493,6 @@ setup_constraint_info (ConstraintInfo *info,
info->is_user_action = (flags & META_IS_USER_ACTION);
info->resize_gravity = resize_gravity;
- /* We need to get a pseduo_gravity for user resize operations (so
- * that user resize followed by min size hints don't end up moving
- * window--see bug 312007).
- *
- * Note that only corner gravities are used here. The reason is simply
- * because we don't allow complex user resizing. West gravity would
- * correspond to resizing the right side, but since only one dimension is
- * being changed by the user, we can lump this in with either NorthWest
- * gravity or SouthWest. Center gravity and Static gravity just don't
- * make sense in this context.
- */
- if (info->is_user_action && info->action_type == ACTION_RESIZE)
- {
- int pseudo_gravity = NorthWestGravity;
- if (orig->x == new->x)
- {
- if (orig->y == new->y)
- pseudo_gravity = NorthWestGravity;
- else if (orig->y + orig->height == new->y + new->height)
- pseudo_gravity = SouthWestGravity;
- }
- else if (orig->x + orig->width == new->x + new->width)
- {
- if (orig->y == new->y)
- pseudo_gravity = NorthEastGravity;
- else if (orig->y + orig->height == new->y + new->height)
- pseudo_gravity = SouthEastGravity;
- }
- info->resize_gravity = pseudo_gravity;
- }
/* Note that although resize_gravity and fixed_directions look similar,
* they are used for different purposes and I believe it helps code
@@ -958,158 +929,118 @@ constrain_aspect_ratio (MetaWindow *window,
if (priority > PRIORITY_ASPECT_RATIO)
return TRUE;
- /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
- /* This is absolutely totally busted -- disable it for now */
- return TRUE;
- /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */
-
/* Determine whether constraint applies; exit if it doesn't. */
- int min_ax, min_ay, max_ax, max_ay;
- min_ax = window->size_hints.min_aspect.x;
- min_ay = window->size_hints.min_aspect.y;
- max_ax = window->size_hints.max_aspect.x;
- max_ay = window->size_hints.max_aspect.y;
- gboolean constraints_are_inconsistent =
- min_ax / ((double)min_ay) > max_ax / ((double)max_ay);
+ double minr, maxr;
+ minr = window->size_hints.min_aspect.x /
+ (double)window->size_hints.min_aspect.y;
+ maxr = window->size_hints.max_aspect.x /
+ (double)window->size_hints.max_aspect.y;
+ gboolean constraints_are_inconsistent = minr > maxr;
if (constraints_are_inconsistent || window->maximized || window->fullscreen ||
info->action_type == ACTION_MOVE)
return TRUE;
- /* Determine whether constraint is already satisfied; exit if it is */
- int slop_allowed_for_min, slop_allowed_for_max;
- slop_allowed_for_min = (min_ax % min_ay == 0) ? 0 : 1;
- slop_allowed_for_max = (max_ax % max_ay == 0) ? 0 : 1;
- /* min_ax width max_ax
- * Need: ------ <= ------ <= ------
- * min_ay height max_ay
+ /* Determine whether constraint is already satisfied; exit if it is. We
+ * need the following to hold:
+ *
+ * width
+ * minr <= ------ <= maxr
+ * height
+ *
+ * But we need to allow for some slight fudging since width and height
+ * are integers instead of floating point numbers (this is particularly
+ * important when minr == maxr), so we allow width and height to be off
+ * a little bit from strictly satisfying these equations. For just one
+ * sided resizing, we have to make the fudge factor a little bigger
+ * because of how meta_rectangle_resize_with_gravity treats those as
+ * being a resize increment (FIXME: I should handle real resize
+ * increments better here...)
*/
+ int fudge;
+ switch (info->resize_gravity)
+ {
+ case WestGravity:
+ case NorthGravity:
+ case SouthGravity:
+ case EastGravity:
+ fudge = 2;
+ break;
+
+ case NorthWestGravity:
+ case SouthWestGravity:
+ case CenterGravity:
+ case NorthEastGravity:
+ case SouthEastGravity:
+ case StaticGravity:
+ default:
+ fudge = 1;
+ break;
+ }
gboolean constraint_already_satisfied =
- info->current.width >=
- (info->current.height * min_ax / min_ay) - slop_allowed_for_min &&
- info->current.width <=
- (info->current.height * max_ax / max_ay) + slop_allowed_for_max;
+ info->current.width - (info->current.height * minr ) > -minr*fudge &&
+ info->current.width - (info->current.height * maxr ) < maxr*fudge;
if (check_only || constraint_already_satisfied)
return constraint_already_satisfied;
/*** Enforce constraint ***/
-#if 0
- if (info->current.width == info->orig.width)
- {
- /* User changed height; change width to match */
- int min_width, max_width, new_width;
- min_width = info->current.height * min_ax / min_ay;
- max_width = info->current.height * max_ax / max_ay;
- new_width = MIN (max_width, MAX (min_width, info->current.width));
- resize_with_gravity (info->current,
- info->resize_gravity,
- new_width,
- info->current.height);
- }
- else if (info->current.height == info->orig.height)
+ int new_width, new_height;
+ double best_width, best_height;
+ double alt_width, alt_height;
+ new_width = info->current.width;
+ new_height = info->current.height;
+
+ switch (info->resize_gravity)
{
- /* User changed width; change height to match */
- int min_height, max_height, new_height;
- min_height = info->current.width * min_ay / min_ax;
- max_height = info->current.width * max_ay / max_ax;
- new_height = MIN (max_height, MAX (min_height, info->current.height));
- resize_with_gravity (info->current,
- info->resize_gravity,
- info->current.width,
- new_height);
+ case WestGravity:
+ case EastGravity:
+ /* Yeah, I suck for doing implicit rounding -- sue me */
+ new_height = CLAMP (new_height, new_width / maxr, new_width / minr);
+ break;
+
+ case NorthGravity:
+ case SouthGravity:
+ /* Yeah, I suck for doing implicit rounding -- sue me */
+ new_width = CLAMP (new_width, new_height * minr, new_height * maxr);
+ break;
+
+ case NorthWestGravity:
+ case SouthWestGravity:
+ case CenterGravity:
+ case NorthEastGravity:
+ case SouthEastGravity:
+ case StaticGravity:
+ default:
+ /* Find what width would correspond to new_height, and what height would
+ * correspond to new_width */
+ alt_width = CLAMP (new_width, new_height * minr, new_height * maxr);
+ alt_height = CLAMP (new_height, new_width / maxr, new_width / minr);
+
+ /* The line connecting the points (alt_width, new_height) and
+ * (new_width, alt_height) provide a range of
+ * valid-for-the-aspect-ratio-constraint sizes. We want the
+ * size in that range closest to the value requested, i.e. the
+ * point on the line which is closest to the point (new_width,
+ * new_height)
+ */
+ meta_rectangle_find_linepoint_closest_to_point (alt_width, new_height,
+ new_width, alt_height,
+ new_width, new_height,
+ &best_width, &best_height);
+
+ /* Yeah, I suck for doing implicit rounding -- sue me */
+ new_width = best_width;
+ new_height = best_height;
+
+ break;
}
-#endif
- /* Pseudocode:
- *
- * 1) Find new rect, A, based on keeping height fixed
- * 2) Find new rect, B, based on keeping width fixed
- * 3) If info->current is strictly larger than info->orig
- * (i.e. could contain it), then discard either of A and B
- * that represent an decrease of area relative to info->orig
- * 4) If info->current is strictly smaller than info->orig
- * (i.e. could be contained in it), then discard either of A and
- * B that represent an increase of area relative to info->orig
- * 5) If both A and B remain (possible in the cases of the user
- * changing both width and height simultaneously), choose the one
- * which is closer in area to info->orig.
- */
- MetaRectangle A, B;
- int min_size, max_size, new_size;
-
- /* Find new rect A */
- A = B = info->current;
- min_size = info->current.height * min_ax / min_ay;
- max_size = info->current.height * max_ax / max_ay;
- new_size = MIN (max_size, MAX (min_size, info->current.width));
- A.width = new_size;
-
- /* Find new rect B */
- B = info->current;
- min_size = info->current.width * min_ay / min_ax;
- max_size = info->current.width * max_ay / max_ax;
- new_size = MIN (max_size, MAX (min_size, info->current.height));
- B.height = new_size;
-
- gboolean a_valid, b_valid;
- int ref_area, a_area, b_area;
- a_valid = b_valid = TRUE;
- ref_area = meta_rectangle_area (&info->orig);
- a_area = meta_rectangle_area (&A);
- b_area = meta_rectangle_area (&B);
-
- /* Discard too-small rects if we're increasing in size */
- if (meta_rectangle_could_fit_rect (&info->current, &info->orig))
- {
- if (a_area < ref_area)
- a_valid = FALSE;
-
- if (b_area < ref_area)
- b_valid = FALSE;
- }
-
- /* Discard too-large rects if we're decreasing in size */
- if (meta_rectangle_could_fit_rect (&info->orig, &info->current))
- {
- if (a_area > ref_area)
- a_valid = FALSE;
-
- if (b_area > ref_area)
- b_valid = FALSE;
- }
-
- /* If both are still valid, use the one closer in area to info->orig */
- if (a_valid && b_valid)
- {
- if (abs (a_area - ref_area) < abs (b_area - ref_area))
- b_valid = FALSE;
- else
- a_valid = FALSE;
- }
-
- if (!a_valid && !b_valid)
- /* This should only be possible for initial placement; we just
- * punt and pick one */
- meta_rectangle_resize_with_gravity (&info->orig,
- &info->current,
- info->resize_gravity,
- A.width,
- A.height);
- else if (!b_valid)
- meta_rectangle_resize_with_gravity (&info->orig,
- &info->current,
- info->resize_gravity,
- A.width,
- A.height);
- else if (!a_valid)
- meta_rectangle_resize_with_gravity (&info->orig,
- &info->current,
- info->resize_gravity,
- A.width,
- A.height);
- else
- g_error ("Was this programmed by monkeys?!?\n");
-
- return TRUE;
+ meta_rectangle_resize_with_gravity (&info->orig,
+ &info->current,
+ info->resize_gravity,
+ new_width,
+ new_height);
+
+ return TRUE;
}
static gboolean
diff --git a/src/keybindings.c b/src/keybindings.c
index c9af2404..0f9f31f2 100644
--- a/src/keybindings.c
+++ b/src/keybindings.c
@@ -2366,7 +2366,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
}
else
{
- meta_window_move_resize (window, TRUE, x, y, width, height);
+ meta_window_resize_with_gravity (window, TRUE, width, height, gravity);
}
meta_window_update_keyboard_resize (window, FALSE);
}
diff --git a/src/window.c b/src/window.c
index 3f275524..53c497d7 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4079,6 +4079,9 @@ meta_window_configure_request (MetaWindow *window,
* have a different setup for meta_window_move_resize_internal()...
*/
+ /* FIXME: This causes a failed assertion on window.c:2543 of
+ * (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
+ */
MetaMoveResizeFlags flags =
META_IS_CONFIGURE_REQUEST;
if (event->xconfigurerequest.value_mask & (CWX | CWY))