mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
Fix lots of little issues with min/max constraints and size increment
2004-04-04 Elijah Newren <newren gmail com> Fix lots of little issues with min/max constraints and size increment constraints. Fixes #329152, #418395, and possibly others. * src/window-props.c (meta_set_normal_hints): Do more checking to make sure application specified constraints are self-consistent, modifying the size_hints as necessary to achieve self-consistency. * src/constraints.c (setup_constraint_info): remove ugly copy-pasto, (constrain_size_increments): be careful that fixing violation of the constraints doesn't cause a violation of the minimum size constraints. * src/window.c (ensure_size_hints_satisfied): new function, (meta_window_unmaximize, meta_window_unmake_fullscreen): the saved_rect may no longer be valid (as in the case of #329152) so call ensure_size_hints_satisfied to fix it up. * doc/how-to-get-focus-right.txt: Some minor spacing and wording fixes completely unrelated to the rest of this commit svn path=/trunk/; revision=3155
This commit is contained in:
parent
7a799b3a63
commit
921661e91d
24
ChangeLog
24
ChangeLog
@ -1,3 +1,27 @@
|
|||||||
|
2004-04-04 Elijah Newren <newren gmail com>
|
||||||
|
|
||||||
|
Fix lots of little issues with min/max constraints and size
|
||||||
|
increment constraints. Fixes #329152, #418395, and possibly
|
||||||
|
others.
|
||||||
|
|
||||||
|
* src/window-props.c (meta_set_normal_hints):
|
||||||
|
Do more checking to make sure application specified constraints
|
||||||
|
are self-consistent, modifying the size_hints as necessary to
|
||||||
|
achieve self-consistency.
|
||||||
|
|
||||||
|
* src/constraints.c (setup_constraint_info): remove ugly
|
||||||
|
copy-pasto, (constrain_size_increments): be careful that fixing
|
||||||
|
violation of the constraints doesn't cause a violation of the
|
||||||
|
minimum size constraints.
|
||||||
|
|
||||||
|
* src/window.c (ensure_size_hints_satisfied): new function,
|
||||||
|
(meta_window_unmaximize, meta_window_unmake_fullscreen): the
|
||||||
|
saved_rect may no longer be valid (as in the case of #329152) so
|
||||||
|
call ensure_size_hints_satisfied to fix it up.
|
||||||
|
|
||||||
|
* doc/how-to-get-focus-right.txt: Some minor spacing and wording
|
||||||
|
fixes completely unrelated to the rest of this commit
|
||||||
|
|
||||||
2007-04-03 Elijah Newren <newren gmail com>
|
2007-04-03 Elijah Newren <newren gmail com>
|
||||||
|
|
||||||
* src/window.c (meta_window_unmaximize):
|
* src/window.c (meta_window_unmaximize):
|
||||||
|
@ -21,7 +21,6 @@ Focus method Invariant
|
|||||||
sloppy If the mouse is in a window, then it is focused; if the
|
sloppy If the mouse is in a window, then it is focused; if the
|
||||||
mouse is not in a window, then the most recently used
|
mouse is not in a window, then the most recently used
|
||||||
window is focused.
|
window is focused.
|
||||||
|
|
||||||
mouse If the mouse is in a non-DESKTOP window, then it is focused;
|
mouse If the mouse is in a non-DESKTOP window, then it is focused;
|
||||||
otherwise, the designated "no_focus_window" is focused
|
otherwise, the designated "no_focus_window" is focused
|
||||||
|
|
||||||
@ -36,7 +35,6 @@ Focus method Behavior
|
|||||||
on top)
|
on top)
|
||||||
sloppy Focus the window containing the pointer if there is such
|
sloppy Focus the window containing the pointer if there is such
|
||||||
a window, otherwise focus the most recently used window.
|
a window, otherwise focus the most recently used window.
|
||||||
|
|
||||||
mouse Focus the non-DESKTOP window containing the pointer if
|
mouse Focus the non-DESKTOP window containing the pointer if
|
||||||
there is one, otherwise focus the designated
|
there is one, otherwise focus the designated
|
||||||
"no_focus_window".
|
"no_focus_window".
|
||||||
@ -66,9 +64,9 @@ cases in which a new window shouldn't be focused:
|
|||||||
|
|
||||||
To handle these cases, Metacity compares timestamps of the event that
|
To handle these cases, Metacity compares timestamps of the event that
|
||||||
caused the launch and the timestamp of the last interaction with the
|
caused the launch and the timestamp of the last interaction with the
|
||||||
focused window. (Case 2 is handled by providing a special timestamp
|
focused window. (Case 2 is handled by the application providing a
|
||||||
of 0 for the launch time, which ensures that the window that appears
|
special timestamp of 0 for the launch time, which ensures that the
|
||||||
doesn't get focus)
|
window that appears doesn't get focus)
|
||||||
|
|
||||||
If the newly launched window isn't focused, some things should be done
|
If the newly launched window isn't focused, some things should be done
|
||||||
to alert the user that there is a window to work with:
|
to alert the user that there is a window to work with:
|
||||||
@ -88,10 +86,10 @@ attempt to handle the INHERENTLY CONFLICTING CONSTRAINTS. Metacity does
|
|||||||
this by having a mouse_mode boolean used to determine which of the two
|
this by having a mouse_mode boolean used to determine which of the two
|
||||||
sets of invariants holds. This mode is set according to which method was
|
sets of invariants holds. This mode is set according to which method was
|
||||||
most recently used to choose a focus window:
|
most recently used to choose a focus window:
|
||||||
1) When receiving EnterNotify/LeaveNotify events from mouse movement, set
|
1) When receiving EnterNotify events from mouse movement, set
|
||||||
mouse_mode to TRUE.
|
mouse_mode to TRUE.
|
||||||
2) When using keynav to choose a focus window (e.g. alt-tab, alt-esc,
|
2) When using keynav to choose a focus window (e.g. alt-tab, alt-esc,
|
||||||
move-window-to-workspace keybindings), set mouse_mode to FALSE.
|
alt-f2, move-window-to-workspace keybindings), set mouse_mode to FALSE.
|
||||||
3) When handling events that don't choose a focus window but rather need
|
3) When handling events that don't choose a focus window but rather need
|
||||||
a focus_window chosen for them (e.g. switch-to-workspace keybindings),
|
a focus_window chosen for them (e.g. switch-to-workspace keybindings),
|
||||||
don't change the mouse_mode and just use the current value.
|
don't change the mouse_mode and just use the current value.
|
||||||
|
@ -350,7 +350,7 @@ setup_constraint_info (ConstraintInfo *info,
|
|||||||
else if (flags & META_IS_RESIZE_ACTION)
|
else if (flags & META_IS_RESIZE_ACTION)
|
||||||
info->action_type = ACTION_RESIZE;
|
info->action_type = ACTION_RESIZE;
|
||||||
else if (flags & META_IS_MOVE_ACTION)
|
else if (flags & META_IS_MOVE_ACTION)
|
||||||
info->action_type = ACTION_MOVE_AND_RESIZE;
|
info->action_type = ACTION_MOVE;
|
||||||
else
|
else
|
||||||
g_error ("BAD, BAD developer! No treat for you! (Fix your calls to "
|
g_error ("BAD, BAD developer! No treat for you! (Fix your calls to "
|
||||||
"meta_window_move_resize_internal()).\n");
|
"meta_window_move_resize_internal()).\n");
|
||||||
@ -809,6 +809,7 @@ constrain_size_increments (MetaWindow *window,
|
|||||||
gboolean check_only)
|
gboolean check_only)
|
||||||
{
|
{
|
||||||
int bh, hi, bw, wi, extra_height, extra_width;
|
int bh, hi, bw, wi, extra_height, extra_width;
|
||||||
|
int new_width, new_height;
|
||||||
gboolean constraint_already_satisfied;
|
gboolean constraint_already_satisfied;
|
||||||
|
|
||||||
if (priority > PRIORITY_SIZE_HINTS_INCREMENTS)
|
if (priority > PRIORITY_SIZE_HINTS_INCREMENTS)
|
||||||
@ -826,10 +827,12 @@ constrain_size_increments (MetaWindow *window,
|
|||||||
wi = window->size_hints.width_inc;
|
wi = window->size_hints.width_inc;
|
||||||
extra_height = (info->current.height - bh) % hi;
|
extra_height = (info->current.height - bh) % hi;
|
||||||
extra_width = (info->current.width - bw) % wi;
|
extra_width = (info->current.width - bw) % wi;
|
||||||
|
/* ignore size increments for maximized windows */
|
||||||
if (window->maximized_horizontally)
|
if (window->maximized_horizontally)
|
||||||
extra_width *= 0;
|
extra_width *= 0;
|
||||||
if (window->maximized_vertically)
|
if (window->maximized_vertically)
|
||||||
extra_height *= 0;
|
extra_height *= 0;
|
||||||
|
/* constraint is satisfied iff there is no extra height or width */
|
||||||
constraint_already_satisfied =
|
constraint_already_satisfied =
|
||||||
(extra_height == 0 && extra_width == 0);
|
(extra_height == 0 && extra_width == 0);
|
||||||
|
|
||||||
@ -837,12 +840,24 @@ constrain_size_increments (MetaWindow *window,
|
|||||||
return constraint_already_satisfied;
|
return constraint_already_satisfied;
|
||||||
|
|
||||||
/*** Enforce constraint ***/
|
/*** Enforce constraint ***/
|
||||||
/* Shrink to base + N * inc */
|
new_width = info->current.width - extra_width;
|
||||||
|
new_height = info->current.height - extra_height;
|
||||||
|
|
||||||
|
/* Adjusting down instead of up (as done in the above two lines) may
|
||||||
|
* violate minimum size constraints; fix the adjustment if this
|
||||||
|
* happens.
|
||||||
|
*/
|
||||||
|
if (new_width < window->size_hints.min_width)
|
||||||
|
new_width += ((window->size_hints.min_width - new_width)/wi + 1)*wi;
|
||||||
|
if (new_height < window->size_hints.min_height)
|
||||||
|
new_height += ((window->size_hints.min_height - new_height)/hi + 1)*hi;
|
||||||
|
|
||||||
|
/* Resize to the new size */
|
||||||
meta_rectangle_resize_with_gravity (&info->orig,
|
meta_rectangle_resize_with_gravity (&info->orig,
|
||||||
&info->current,
|
&info->current,
|
||||||
info->resize_gravity,
|
info->resize_gravity,
|
||||||
info->current.width - extra_width,
|
new_width,
|
||||||
info->current.height - extra_height);
|
new_height);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,6 +912,11 @@ meta_set_normal_hints (MetaWindow *window,
|
|||||||
XSizeHints *hints)
|
XSizeHints *hints)
|
||||||
{
|
{
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
|
double minr, maxr;
|
||||||
|
/* Some convenience vars */
|
||||||
|
int minw, minh, maxw, maxh; /* min/max width/height */
|
||||||
|
int basew, baseh, winc, hinc; /* base width/height, width/height increment */
|
||||||
|
|
||||||
/* Save the last ConfigureRequest, which we put here.
|
/* Save the last ConfigureRequest, which we put here.
|
||||||
* Values here set in the hints are supposed to
|
* Values here set in the hints are supposed to
|
||||||
* be ignored.
|
* be ignored.
|
||||||
@ -944,6 +949,7 @@ meta_set_normal_hints (MetaWindow *window,
|
|||||||
window->size_hints.width = w;
|
window->size_hints.width = w;
|
||||||
window->size_hints.height = h;
|
window->size_hints.height = h;
|
||||||
|
|
||||||
|
/* Get base size hints */
|
||||||
if (window->size_hints.flags & PBaseSize)
|
if (window->size_hints.flags & PBaseSize)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets base size %d x %d\n",
|
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets base size %d x %d\n",
|
||||||
@ -963,6 +969,7 @@ meta_set_normal_hints (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
window->size_hints.flags |= PBaseSize;
|
window->size_hints.flags |= PBaseSize;
|
||||||
|
|
||||||
|
/* Get min size hints */
|
||||||
if (window->size_hints.flags & PMinSize)
|
if (window->size_hints.flags & PMinSize)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min size %d x %d\n",
|
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min size %d x %d\n",
|
||||||
@ -982,6 +989,7 @@ meta_set_normal_hints (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
window->size_hints.flags |= PMinSize;
|
window->size_hints.flags |= PMinSize;
|
||||||
|
|
||||||
|
/* Get max size hints */
|
||||||
if (window->size_hints.flags & PMaxSize)
|
if (window->size_hints.flags & PMaxSize)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max size %d x %d\n",
|
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max size %d x %d\n",
|
||||||
@ -996,31 +1004,64 @@ meta_set_normal_hints (MetaWindow *window,
|
|||||||
window->size_hints.flags |= PMaxSize;
|
window->size_hints.flags |= PMaxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->size_hints.max_width < window->size_hints.min_width)
|
/* Get resize increment hints */
|
||||||
|
if (window->size_hints.flags & PResizeInc)
|
||||||
{
|
{
|
||||||
/* someone is on crack */
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
"Window %s sets max width %d less than min width %d, disabling resize\n",
|
"Window %s sets resize width inc: %d height inc: %d\n",
|
||||||
window->desc,
|
window->desc,
|
||||||
window->size_hints.max_width,
|
window->size_hints.width_inc,
|
||||||
window->size_hints.min_width);
|
window->size_hints.height_inc);
|
||||||
window->size_hints.max_width = window->size_hints.min_width;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->size_hints.width_inc = 1;
|
||||||
|
window->size_hints.height_inc = 1;
|
||||||
|
window->size_hints.flags |= PResizeInc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->size_hints.max_height < window->size_hints.min_height)
|
/* Get aspect ratio hints */
|
||||||
|
if (window->size_hints.flags & PAspect)
|
||||||
{
|
{
|
||||||
/* another cracksmoker */
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
"Window %s sets max height %d less than min height %d, disabling resize\n",
|
"Window %s sets min_aspect: %d/%d max_aspect: %d/%d\n",
|
||||||
window->desc,
|
window->desc,
|
||||||
window->size_hints.max_height,
|
window->size_hints.min_aspect.x,
|
||||||
window->size_hints.min_height);
|
window->size_hints.min_aspect.y,
|
||||||
window->size_hints.max_height = window->size_hints.min_height;
|
window->size_hints.max_aspect.x,
|
||||||
|
window->size_hints.max_aspect.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->size_hints.min_aspect.x = 1;
|
||||||
|
window->size_hints.min_aspect.y = G_MAXINT;
|
||||||
|
window->size_hints.max_aspect.x = G_MAXINT;
|
||||||
|
window->size_hints.max_aspect.y = 1;
|
||||||
|
window->size_hints.flags |= PAspect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get gravity hint */
|
||||||
|
if (window->size_hints.flags & PWinGravity)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets gravity %d\n",
|
||||||
|
window->desc,
|
||||||
|
window->size_hints.win_gravity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s doesn't set gravity, using NW\n",
|
||||||
|
window->desc);
|
||||||
|
window->size_hints.win_gravity = NorthWestGravity;
|
||||||
|
window->size_hints.flags |= PWinGravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Lots of sanity checking ***/
|
||||||
|
|
||||||
|
/* Verify all min & max hints are at least 1 pixel */
|
||||||
if (window->size_hints.min_width < 1)
|
if (window->size_hints.min_width < 1)
|
||||||
{
|
{
|
||||||
/* another cracksmoker */
|
/* someone is on crack */
|
||||||
meta_topic (META_DEBUG_GEOMETRY,
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
"Window %s sets min width to 0, which makes no sense\n",
|
"Window %s sets min width to 0, which makes no sense\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
@ -1051,66 +1092,160 @@ meta_set_normal_hints (MetaWindow *window,
|
|||||||
window->size_hints.max_height = 1;
|
window->size_hints.max_height = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->size_hints.flags & PResizeInc)
|
/* Verify size increment hints are at least 1 pixel */
|
||||||
{
|
if (window->size_hints.width_inc < 1)
|
||||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets resize width inc: %d height inc: %d\n",
|
|
||||||
window->desc,
|
|
||||||
window->size_hints.width_inc,
|
|
||||||
window->size_hints.height_inc);
|
|
||||||
if (window->size_hints.width_inc == 0)
|
|
||||||
{
|
{
|
||||||
|
/* app authors find so many ways to smoke crack */
|
||||||
window->size_hints.width_inc = 1;
|
window->size_hints.width_inc = 1;
|
||||||
meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1\n");
|
meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1\n");
|
||||||
}
|
}
|
||||||
if (window->size_hints.height_inc == 0)
|
if (window->size_hints.height_inc < 1)
|
||||||
{
|
{
|
||||||
|
/* another cracksmoker */
|
||||||
window->size_hints.height_inc = 1;
|
window->size_hints.height_inc = 1;
|
||||||
meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 height_inc to 1\n");
|
meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 height_inc to 1\n");
|
||||||
}
|
}
|
||||||
}
|
/* divide by 0 cracksmokers; note that x & y in (min|max)_aspect are
|
||||||
else
|
* numerator & denominator
|
||||||
{
|
*/
|
||||||
window->size_hints.width_inc = 1;
|
|
||||||
window->size_hints.height_inc = 1;
|
|
||||||
window->size_hints.flags |= PResizeInc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->size_hints.flags & PAspect)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min_aspect: %d/%d max_aspect: %d/%d\n",
|
|
||||||
window->desc,
|
|
||||||
window->size_hints.min_aspect.x,
|
|
||||||
window->size_hints.min_aspect.y,
|
|
||||||
window->size_hints.max_aspect.x,
|
|
||||||
window->size_hints.max_aspect.y);
|
|
||||||
|
|
||||||
/* don't divide by 0 */
|
|
||||||
if (window->size_hints.min_aspect.y < 1)
|
if (window->size_hints.min_aspect.y < 1)
|
||||||
window->size_hints.min_aspect.y = 1;
|
window->size_hints.min_aspect.y = 1;
|
||||||
if (window->size_hints.max_aspect.y < 1)
|
if (window->size_hints.max_aspect.y < 1)
|
||||||
window->size_hints.max_aspect.y = 1;
|
window->size_hints.max_aspect.y = 1;
|
||||||
}
|
|
||||||
else
|
minw = window->size_hints.min_width; minh = window->size_hints.min_height;
|
||||||
|
maxw = window->size_hints.max_width; maxh = window->size_hints.max_height;
|
||||||
|
basew = window->size_hints.base_width; baseh = window->size_hints.base_height;
|
||||||
|
winc = window->size_hints.width_inc; hinc = window->size_hints.height_inc;
|
||||||
|
|
||||||
|
/* Make sure min and max size hints are consistent with the base + increment
|
||||||
|
* size hints. If they're not, it's not a real big deal, but it means the
|
||||||
|
* effective min and max size are more restrictive than the application
|
||||||
|
* specified values.
|
||||||
|
*/
|
||||||
|
if ((minw - basew) % winc != 0)
|
||||||
{
|
{
|
||||||
|
/* Take advantage of integer division throwing away the remainder... */
|
||||||
|
window->size_hints.min_width = basew + ((minw - basew)/winc + 1)*winc;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s has width_inc (%d) that does not evenly divide "
|
||||||
|
"min_width - base_width (%d - %d); thus effective "
|
||||||
|
"min_width is really %d\n",
|
||||||
|
window->desc,
|
||||||
|
winc, minw, basew, window->size_hints.min_width);
|
||||||
|
minw = window->size_hints.min_width;
|
||||||
|
}
|
||||||
|
if (maxw != G_MAXINT && (maxw - basew) % winc != 0)
|
||||||
|
{
|
||||||
|
/* Take advantage of integer division throwing away the remainder... */
|
||||||
|
window->size_hints.max_width = basew + ((maxw - basew)/winc)*winc;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s has width_inc (%d) that does not evenly divide "
|
||||||
|
"max_width - base_width (%d - %d); thus effective "
|
||||||
|
"max_width is really %d\n",
|
||||||
|
window->desc,
|
||||||
|
winc, maxw, basew, window->size_hints.max_width);
|
||||||
|
maxw = window->size_hints.max_width;
|
||||||
|
}
|
||||||
|
if ((minh - baseh) % hinc != 0)
|
||||||
|
{
|
||||||
|
/* Take advantage of integer division throwing away the remainder... */
|
||||||
|
window->size_hints.min_height = baseh + ((minh - baseh)/hinc + 1)*hinc;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s has height_inc (%d) that does not evenly divide "
|
||||||
|
"min_height - base_height (%d - %d); thus effective "
|
||||||
|
"min_height is really %d\n",
|
||||||
|
window->desc,
|
||||||
|
hinc, minh, baseh, window->size_hints.min_height);
|
||||||
|
minh = window->size_hints.min_height;
|
||||||
|
}
|
||||||
|
if (maxh != G_MAXINT && (maxh - baseh) % hinc != 0)
|
||||||
|
{
|
||||||
|
/* Take advantage of integer division throwing away the remainder... */
|
||||||
|
window->size_hints.max_height = baseh + ((maxh - baseh)/hinc)*hinc;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s has height_inc (%d) that does not evenly divide "
|
||||||
|
"max_height - base_height (%d - %d); thus effective "
|
||||||
|
"max_height is really %d\n",
|
||||||
|
window->desc,
|
||||||
|
hinc, maxh, baseh, window->size_hints.max_height);
|
||||||
|
maxh = window->size_hints.max_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure maximum size hints are compatible with minimum size hints; min
|
||||||
|
* size hints take precedence.
|
||||||
|
*/
|
||||||
|
if (window->size_hints.max_width < window->size_hints.min_width)
|
||||||
|
{
|
||||||
|
/* another cracksmoker */
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s sets max width %d less than min width %d, "
|
||||||
|
"disabling resize\n",
|
||||||
|
window->desc,
|
||||||
|
window->size_hints.max_width,
|
||||||
|
window->size_hints.min_width);
|
||||||
|
maxw = window->size_hints.max_width = window->size_hints.min_width;
|
||||||
|
}
|
||||||
|
if (window->size_hints.max_height < window->size_hints.min_height)
|
||||||
|
{
|
||||||
|
/* another cracksmoker */
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s sets max height %d less than min height %d, "
|
||||||
|
"disabling resize\n",
|
||||||
|
window->desc,
|
||||||
|
window->size_hints.max_height,
|
||||||
|
window->size_hints.min_height);
|
||||||
|
maxh = window->size_hints.max_height = window->size_hints.min_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure the aspect ratio hints are sane. */
|
||||||
|
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;
|
||||||
|
if (minr > maxr)
|
||||||
|
{
|
||||||
|
/* another cracksmoker; not even minimally (self) consistent */
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s sets min aspect ratio larger than max aspect "
|
||||||
|
"ratio; disabling aspect ratio constraints.\n",
|
||||||
|
window->desc);
|
||||||
window->size_hints.min_aspect.x = 1;
|
window->size_hints.min_aspect.x = 1;
|
||||||
window->size_hints.min_aspect.y = G_MAXINT;
|
window->size_hints.min_aspect.y = G_MAXINT;
|
||||||
window->size_hints.max_aspect.x = G_MAXINT;
|
window->size_hints.max_aspect.x = G_MAXINT;
|
||||||
window->size_hints.max_aspect.y = 1;
|
window->size_hints.max_aspect.y = 1;
|
||||||
window->size_hints.flags |= PAspect;
|
|
||||||
}
|
}
|
||||||
|
else /* check consistency of aspect ratio hints with other hints */
|
||||||
if (window->size_hints.flags & PWinGravity)
|
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets gravity %d\n",
|
if (minh > 0 && minr > (maxw / (double)minh))
|
||||||
window->desc,
|
|
||||||
window->size_hints.win_gravity);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s doesn't set gravity, using NW\n",
|
/* another cracksmoker */
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s sets min aspect ratio larger than largest "
|
||||||
|
"aspect ratio possible given min/max size constraints; "
|
||||||
|
"disabling min aspect ratio constraint.\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
window->size_hints.win_gravity = NorthWestGravity;
|
window->size_hints.min_aspect.x = 1;
|
||||||
window->size_hints.flags |= PWinGravity;
|
window->size_hints.min_aspect.y = G_MAXINT;
|
||||||
|
}
|
||||||
|
if (maxr < (minw / (double)maxh))
|
||||||
|
{
|
||||||
|
/* another cracksmoker */
|
||||||
|
meta_topic (META_DEBUG_GEOMETRY,
|
||||||
|
"Window %s sets max aspect ratio smaller than smallest "
|
||||||
|
"aspect ratio possible given min/max size constraints; "
|
||||||
|
"disabling max aspect ratio constraint.\n",
|
||||||
|
window->desc);
|
||||||
|
window->size_hints.max_aspect.x = G_MAXINT;
|
||||||
|
window->size_hints.max_aspect.y = 1;
|
||||||
|
}
|
||||||
|
/* FIXME: Would be nice to check that aspect ratios are
|
||||||
|
* consistent with base and size increment constraints.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
src/window.c
54
src/window.c
@ -2232,6 +2232,39 @@ meta_window_unminimize (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ensure_size_hints_satisfied (MetaRectangle *rect,
|
||||||
|
const XSizeHints *size_hints)
|
||||||
|
{
|
||||||
|
int minw, minh, maxw, maxh; /* min/max width/height */
|
||||||
|
int basew, baseh, winc, hinc; /* base width/height, width/height increment */
|
||||||
|
int extra_width, extra_height;
|
||||||
|
|
||||||
|
minw = size_hints->min_width; minh = size_hints->min_height;
|
||||||
|
maxw = size_hints->max_width; maxh = size_hints->max_height;
|
||||||
|
basew = size_hints->base_width; baseh = size_hints->base_height;
|
||||||
|
winc = size_hints->width_inc; hinc = size_hints->height_inc;
|
||||||
|
|
||||||
|
/* First, enforce min/max size constraints */
|
||||||
|
rect->width = CLAMP (rect->width, minw, maxw);
|
||||||
|
rect->height = CLAMP (rect->height, minh, maxh);
|
||||||
|
|
||||||
|
/* Now, verify size increment constraints are satisfied, or make them be */
|
||||||
|
extra_width = (rect->width - basew) % winc;
|
||||||
|
extra_height = (rect->height - baseh) % hinc;
|
||||||
|
|
||||||
|
rect->width -= extra_width;
|
||||||
|
rect->height -= extra_height;
|
||||||
|
|
||||||
|
/* Adjusting width/height down, as done above, may violate minimum size
|
||||||
|
* constraints, so one last fix.
|
||||||
|
*/
|
||||||
|
if (rect->width < minw)
|
||||||
|
rect->width += ((minw - rect->width)/winc + 1)*winc;
|
||||||
|
if (rect->height < minh)
|
||||||
|
rect->height += ((minh - rect->height)/hinc + 1)*hinc;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_save_rect (MetaWindow *window)
|
meta_window_save_rect (MetaWindow *window)
|
||||||
{
|
{
|
||||||
@ -2424,6 +2457,11 @@ meta_window_unmaximize (MetaWindow *window,
|
|||||||
target_rect.height = window->saved_rect.height;
|
target_rect.height = window->saved_rect.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Window's size hints may have changed while maximized, making
|
||||||
|
* saved_rect invalid. #329152
|
||||||
|
*/
|
||||||
|
ensure_size_hints_satisfied (&target_rect, &window->size_hints);
|
||||||
|
|
||||||
/* When we unmaximize, if we're doing a mouse move also we could
|
/* When we unmaximize, if we're doing a mouse move also we could
|
||||||
* get the window suddenly jumping to the upper left corner of
|
* get the window suddenly jumping to the upper left corner of
|
||||||
* the workspace, since that's where it was when the grab op
|
* the workspace, since that's where it was when the grab op
|
||||||
@ -2520,17 +2558,25 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
if (window->fullscreen)
|
if (window->fullscreen)
|
||||||
{
|
{
|
||||||
|
MetaRectangle target_rect;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||||
"Unfullscreening %s\n", window->desc);
|
"Unfullscreening %s\n", window->desc);
|
||||||
|
|
||||||
window->fullscreen = FALSE;
|
window->fullscreen = FALSE;
|
||||||
|
target_rect = window->saved_rect;
|
||||||
|
|
||||||
|
/* Window's size hints may have changed while maximized, making
|
||||||
|
* saved_rect invalid. #329152
|
||||||
|
*/
|
||||||
|
ensure_size_hints_satisfied (&target_rect, &window->size_hints);
|
||||||
|
|
||||||
meta_window_move_resize (window,
|
meta_window_move_resize (window,
|
||||||
FALSE,
|
FALSE,
|
||||||
window->saved_rect.x,
|
target_rect.x,
|
||||||
window->saved_rect.y,
|
target_rect.y,
|
||||||
window->saved_rect.width,
|
target_rect.width,
|
||||||
window->saved_rect.height);
|
target_rect.height);
|
||||||
|
|
||||||
meta_window_update_layer (window);
|
meta_window_update_layer (window);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user