mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00: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>
|
||||
|
||||
* 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
|
||||
mouse is not in a window, then the most recently used
|
||||
window is focused.
|
||||
|
||||
mouse If the mouse is in a non-DESKTOP window, then it is focused;
|
||||
otherwise, the designated "no_focus_window" is focused
|
||||
|
||||
@ -36,7 +35,6 @@ Focus method Behavior
|
||||
on top)
|
||||
sloppy Focus the window containing the pointer if there is such
|
||||
a window, otherwise focus the most recently used window.
|
||||
|
||||
mouse Focus the non-DESKTOP window containing the pointer if
|
||||
there is one, otherwise focus the designated
|
||||
"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
|
||||
caused the launch and the timestamp of the last interaction with the
|
||||
focused window. (Case 2 is handled by providing a special timestamp
|
||||
of 0 for the launch time, which ensures that the window that appears
|
||||
doesn't get focus)
|
||||
focused window. (Case 2 is handled by the application providing a
|
||||
special timestamp of 0 for the launch time, which ensures that the
|
||||
window that appears doesn't get focus)
|
||||
|
||||
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:
|
||||
@ -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
|
||||
sets of invariants holds. This mode is set according to which method was
|
||||
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.
|
||||
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
|
||||
a focus_window chosen for them (e.g. switch-to-workspace keybindings),
|
||||
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)
|
||||
info->action_type = ACTION_RESIZE;
|
||||
else if (flags & META_IS_MOVE_ACTION)
|
||||
info->action_type = ACTION_MOVE_AND_RESIZE;
|
||||
info->action_type = ACTION_MOVE;
|
||||
else
|
||||
g_error ("BAD, BAD developer! No treat for you! (Fix your calls to "
|
||||
"meta_window_move_resize_internal()).\n");
|
||||
@ -809,6 +809,7 @@ constrain_size_increments (MetaWindow *window,
|
||||
gboolean check_only)
|
||||
{
|
||||
int bh, hi, bw, wi, extra_height, extra_width;
|
||||
int new_width, new_height;
|
||||
gboolean constraint_already_satisfied;
|
||||
|
||||
if (priority > PRIORITY_SIZE_HINTS_INCREMENTS)
|
||||
@ -826,10 +827,12 @@ constrain_size_increments (MetaWindow *window,
|
||||
wi = window->size_hints.width_inc;
|
||||
extra_height = (info->current.height - bh) % hi;
|
||||
extra_width = (info->current.width - bw) % wi;
|
||||
/* ignore size increments for maximized windows */
|
||||
if (window->maximized_horizontally)
|
||||
extra_width *= 0;
|
||||
if (window->maximized_vertically)
|
||||
extra_height *= 0;
|
||||
/* constraint is satisfied iff there is no extra height or width */
|
||||
constraint_already_satisfied =
|
||||
(extra_height == 0 && extra_width == 0);
|
||||
|
||||
@ -837,12 +840,24 @@ constrain_size_increments (MetaWindow *window,
|
||||
return constraint_already_satisfied;
|
||||
|
||||
/*** 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,
|
||||
&info->current,
|
||||
info->resize_gravity,
|
||||
info->current.width - extra_width,
|
||||
info->current.height - extra_height);
|
||||
new_width,
|
||||
new_height);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -909,9 +909,14 @@ spew_size_hints_differences (const XSizeHints *old,
|
||||
|
||||
void
|
||||
meta_set_normal_hints (MetaWindow *window,
|
||||
XSizeHints *hints)
|
||||
XSizeHints *hints)
|
||||
{
|
||||
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.
|
||||
* Values here set in the hints are supposed to
|
||||
* be ignored.
|
||||
@ -944,12 +949,13 @@ meta_set_normal_hints (MetaWindow *window,
|
||||
window->size_hints.width = w;
|
||||
window->size_hints.height = h;
|
||||
|
||||
/* Get base size hints */
|
||||
if (window->size_hints.flags & PBaseSize)
|
||||
{
|
||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets base size %d x %d\n",
|
||||
window->desc,
|
||||
window->size_hints.base_width,
|
||||
window->size_hints.base_height);
|
||||
window->desc,
|
||||
window->size_hints.base_width,
|
||||
window->size_hints.base_height);
|
||||
}
|
||||
else if (window->size_hints.flags & PMinSize)
|
||||
{
|
||||
@ -963,12 +969,13 @@ meta_set_normal_hints (MetaWindow *window,
|
||||
}
|
||||
window->size_hints.flags |= PBaseSize;
|
||||
|
||||
/* Get min size hints */
|
||||
if (window->size_hints.flags & PMinSize)
|
||||
{
|
||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min size %d x %d\n",
|
||||
window->desc,
|
||||
window->size_hints.min_width,
|
||||
window->size_hints.min_height);
|
||||
window->desc,
|
||||
window->size_hints.min_width,
|
||||
window->size_hints.min_height);
|
||||
}
|
||||
else if (window->size_hints.flags & PBaseSize)
|
||||
{
|
||||
@ -982,12 +989,13 @@ meta_set_normal_hints (MetaWindow *window,
|
||||
}
|
||||
window->size_hints.flags |= PMinSize;
|
||||
|
||||
/* Get max size hints */
|
||||
if (window->size_hints.flags & PMaxSize)
|
||||
{
|
||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max size %d x %d\n",
|
||||
window->desc,
|
||||
window->size_hints.max_width,
|
||||
window->size_hints.max_height);
|
||||
window->desc,
|
||||
window->size_hints.max_width,
|
||||
window->size_hints.max_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -996,77 +1004,14 @@ meta_set_normal_hints (MetaWindow *window,
|
||||
window->size_hints.flags |= PMaxSize;
|
||||
}
|
||||
|
||||
if (window->size_hints.max_width < window->size_hints.min_width)
|
||||
{
|
||||
/* someone is on crack */
|
||||
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);
|
||||
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);
|
||||
window->size_hints.max_height = window->size_hints.min_height;
|
||||
}
|
||||
|
||||
if (window->size_hints.min_width < 1)
|
||||
{
|
||||
/* another cracksmoker */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Window %s sets min width to 0, which makes no sense\n",
|
||||
window->desc);
|
||||
window->size_hints.min_width = 1;
|
||||
}
|
||||
if (window->size_hints.max_width < 1)
|
||||
{
|
||||
/* another cracksmoker */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Window %s sets max width to 0, which makes no sense\n",
|
||||
window->desc);
|
||||
window->size_hints.max_width = 1;
|
||||
}
|
||||
if (window->size_hints.min_height < 1)
|
||||
{
|
||||
/* another cracksmoker */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Window %s sets min height to 0, which makes no sense\n",
|
||||
window->desc);
|
||||
window->size_hints.min_height = 1;
|
||||
}
|
||||
if (window->size_hints.max_height < 1)
|
||||
{
|
||||
/* another cracksmoker */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Window %s sets max height to 0, which makes no sense\n",
|
||||
window->desc);
|
||||
window->size_hints.max_height = 1;
|
||||
}
|
||||
|
||||
/* Get resize increment hints */
|
||||
if (window->size_hints.flags & PResizeInc)
|
||||
{
|
||||
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)
|
||||
{
|
||||
window->size_hints.width_inc = 1;
|
||||
meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1\n");
|
||||
}
|
||||
if (window->size_hints.height_inc == 0)
|
||||
{
|
||||
window->size_hints.height_inc = 1;
|
||||
meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 height_inc to 1\n");
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1075,20 +1020,16 @@ meta_set_normal_hints (MetaWindow *window,
|
||||
window->size_hints.flags |= PResizeInc;
|
||||
}
|
||||
|
||||
/* Get aspect ratio hints */
|
||||
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)
|
||||
window->size_hints.min_aspect.y = 1;
|
||||
if (window->size_hints.max_aspect.y < 1)
|
||||
window->size_hints.max_aspect.y = 1;
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1099,19 +1040,213 @@ meta_set_normal_hints (MetaWindow *window,
|
||||
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);
|
||||
window->desc,
|
||||
window->size_hints.win_gravity);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_topic (META_DEBUG_GEOMETRY, "Window %s doesn't set gravity, using NW\n",
|
||||
window->desc);
|
||||
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)
|
||||
{
|
||||
/* someone is on crack */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Window %s sets min width to 0, which makes no sense\n",
|
||||
window->desc);
|
||||
window->size_hints.min_width = 1;
|
||||
}
|
||||
if (window->size_hints.max_width < 1)
|
||||
{
|
||||
/* another cracksmoker */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Window %s sets max width to 0, which makes no sense\n",
|
||||
window->desc);
|
||||
window->size_hints.max_width = 1;
|
||||
}
|
||||
if (window->size_hints.min_height < 1)
|
||||
{
|
||||
/* another cracksmoker */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Window %s sets min height to 0, which makes no sense\n",
|
||||
window->desc);
|
||||
window->size_hints.min_height = 1;
|
||||
}
|
||||
if (window->size_hints.max_height < 1)
|
||||
{
|
||||
/* another cracksmoker */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Window %s sets max height to 0, which makes no sense\n",
|
||||
window->desc);
|
||||
window->size_hints.max_height = 1;
|
||||
}
|
||||
|
||||
/* Verify size increment hints are at least 1 pixel */
|
||||
if (window->size_hints.width_inc < 1)
|
||||
{
|
||||
/* app authors find so many ways to smoke crack */
|
||||
window->size_hints.width_inc = 1;
|
||||
meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1\n");
|
||||
}
|
||||
if (window->size_hints.height_inc < 1)
|
||||
{
|
||||
/* another cracksmoker */
|
||||
window->size_hints.height_inc = 1;
|
||||
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
|
||||
* numerator & denominator
|
||||
*/
|
||||
if (window->size_hints.min_aspect.y < 1)
|
||||
window->size_hints.min_aspect.y = 1;
|
||||
if (window->size_hints.max_aspect.y < 1)
|
||||
window->size_hints.max_aspect.y = 1;
|
||||
|
||||
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.y = G_MAXINT;
|
||||
window->size_hints.max_aspect.x = G_MAXINT;
|
||||
window->size_hints.max_aspect.y = 1;
|
||||
}
|
||||
else /* check consistency of aspect ratio hints with other hints */
|
||||
{
|
||||
if (minh > 0 && minr > (maxw / (double)minh))
|
||||
{
|
||||
/* 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->size_hints.min_aspect.x = 1;
|
||||
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.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
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
|
||||
meta_window_save_rect (MetaWindow *window)
|
||||
{
|
||||
@ -2424,6 +2457,11 @@ meta_window_unmaximize (MetaWindow *window,
|
||||
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
|
||||
* get the window suddenly jumping to the upper left corner of
|
||||
* 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)
|
||||
{
|
||||
MetaRectangle target_rect;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Unfullscreening %s\n", window->desc);
|
||||
|
||||
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,
|
||||
FALSE,
|
||||
window->saved_rect.x,
|
||||
window->saved_rect.y,
|
||||
window->saved_rect.width,
|
||||
window->saved_rect.height);
|
||||
target_rect.x,
|
||||
target_rect.y,
|
||||
target_rect.width,
|
||||
target_rect.height);
|
||||
|
||||
meta_window_update_layer (window);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user