~smspillaz/compiz-core/compiz-core.variant-prpoposed-fix

« back to all changes in this revision

Viewing changes to src/window.cpp

Use the tested constrainment to hints code path and fix unsigned int / long conversion

Merge lp:~smspillaz/compiz-core/compiz-core.use-constrainment into lp:compiz-core

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
 
41
41
#include <core/icon.h>
42
42
#include <core/atoms.h>
 
43
#include "core/windowconstrainment.h"
43
44
#include "privatewindow.h"
44
45
#include "privatescreen.h"
45
46
#include "privatestackdebugger.h"
4702
4703
                                    int        *newWidth,
4703
4704
                                    int        *newHeight)
4704
4705
{
4705
 
    const XSizeHints *hints = &priv->sizeHints;
4706
 
    int              oldWidth = width;
4707
 
    int              oldHeight = height;
4708
 
    int              min_width = 0;
4709
 
    int              min_height = 0;
4710
 
    int              base_width = 0;
4711
 
    int              base_height = 0;
4712
 
    int              xinc = 1;
4713
 
    int              yinc = 1;
4714
 
    int              max_width = MAXSHORT;
4715
 
    int              max_height = MAXSHORT;
4716
 
    long             flags = hints->flags;
4717
 
    long             resizeIncFlags = (flags & PResizeInc) ? ~0 : 0;
 
4706
    CompSize         size (width, height);
 
4707
    long             ignoredHints = 0;
 
4708
    long             ignoredResizeHints = 0;
4718
4709
 
4719
4710
    if (screen->priv->optionGetIgnoreHintsWhenMaximized ())
4720
4711
    {
4721
 
        if (priv->state & MAXIMIZE_STATE)
4722
 
        {
4723
 
            flags &= ~PAspect;
4724
 
 
4725
 
            if (priv->state & CompWindowStateMaximizedHorzMask)
4726
 
                resizeIncFlags &= ~PHorzResizeInc;
4727
 
 
4728
 
            if (priv->state & CompWindowStateMaximizedVertMask)
4729
 
                resizeIncFlags &= ~PVertResizeInc;
4730
 
        }
4731
 
    }
4732
 
 
4733
 
    /* Ater gdk_window_constrain_size(), which is partially borrowed from fvwm.
4734
 
     *
4735
 
     * Copyright 1993, Robert Nation
4736
 
     *     You may use this code for any purpose, as long as the original
4737
 
     *     copyright remains in the source code and all documentation
4738
 
     *
4739
 
     * which in turn borrows parts of the algorithm from uwm
4740
 
     */
4741
 
 
4742
 
#define FLOOR(value, base) (((int) ((value) / (base))) * (base))
4743
 
#define FLOOR64(value, base) (((uint64_t) ((value) / (base))) * (base))
4744
 
 
4745
 
    if ((flags & PBaseSize) && (flags & PMinSize))
4746
 
    {
4747
 
        base_width = hints->base_width;
4748
 
        base_height = hints->base_height;
4749
 
        min_width = hints->min_width;
4750
 
        min_height = hints->min_height;
4751
 
    }
4752
 
    else if (flags & PBaseSize)
4753
 
    {
4754
 
        base_width = hints->base_width;
4755
 
        base_height = hints->base_height;
4756
 
        min_width = hints->base_width;
4757
 
        min_height = hints->base_height;
4758
 
    }
4759
 
    else if (flags & PMinSize)
4760
 
    {
4761
 
        base_width = hints->min_width;
4762
 
        base_height = hints->min_height;
4763
 
        min_width = hints->min_width;
4764
 
        min_height = hints->min_height;
4765
 
    }
4766
 
 
4767
 
    if (flags & PMaxSize)
4768
 
    {
4769
 
        max_width = hints->max_width;
4770
 
        max_height = hints->max_height;
4771
 
    }
4772
 
 
4773
 
    if (resizeIncFlags & PHorzResizeInc)
4774
 
        xinc = MAX (xinc, hints->width_inc);
4775
 
 
4776
 
    if (resizeIncFlags & PVertResizeInc)
4777
 
        yinc = MAX (yinc, hints->height_inc);
4778
 
 
4779
 
    /* clamp width and height to min and max values */
4780
 
    width  = CLAMP (width, min_width, max_width);
4781
 
    height = CLAMP (height, min_height, max_height);
4782
 
 
4783
 
    /* shrink to base + N * inc */
4784
 
    width  = base_width + FLOOR (width - base_width, xinc);
4785
 
    height = base_height + FLOOR (height - base_height, yinc);
4786
 
 
4787
 
    /* constrain aspect ratio, according to:
4788
 
     *
4789
 
     * min_aspect.x       width      max_aspect.x
4790
 
     * ------------  <= -------- <=  -----------
4791
 
     * min_aspect.y       height     max_aspect.y
4792
 
     */
4793
 
    if ((flags & PAspect) && hints->min_aspect.y > 0 && hints->max_aspect.x > 0)
4794
 
    {
4795
 
        /* Use 64 bit arithmetic to prevent overflow */
4796
 
 
4797
 
        uint64_t min_aspect_x = hints->min_aspect.x;
4798
 
        uint64_t min_aspect_y = hints->min_aspect.y;
4799
 
        uint64_t max_aspect_x = hints->max_aspect.x;
4800
 
        uint64_t max_aspect_y = hints->max_aspect.y;
4801
 
        uint64_t delta;
4802
 
 
4803
 
        if (min_aspect_x * height > width * min_aspect_y)
4804
 
        {
4805
 
            delta = FLOOR64 (height - width * min_aspect_y / min_aspect_x,
4806
 
                             yinc);
4807
 
            if (height - (int) delta >= min_height)
4808
 
                height -= delta;
4809
 
            else
4810
 
            {
4811
 
                delta = FLOOR64 (height * min_aspect_x / min_aspect_y - width,
4812
 
                                 xinc);
4813
 
                if (width + (int) delta <= max_width)
4814
 
                    width += delta;
4815
 
            }
4816
 
        }
4817
 
 
4818
 
        if (width * max_aspect_y > max_aspect_x * height)
4819
 
        {
4820
 
            delta = FLOOR64 (width - height * max_aspect_x / max_aspect_y,
4821
 
                             xinc);
4822
 
            if (width - (int) delta >= min_width)
4823
 
                width -= delta;
4824
 
            else
4825
 
            {
4826
 
                delta = FLOOR64 (width * min_aspect_y / min_aspect_x - height,
4827
 
                                 yinc);
4828
 
                if (height + (int) delta <= max_height)
4829
 
                    height += delta;
4830
 
            }
4831
 
        }
4832
 
    }
4833
 
 
4834
 
#undef CLAMP
4835
 
#undef FLOOR64
4836
 
#undef FLOOR
4837
 
 
4838
 
    if (width != oldWidth || height != oldHeight)
4839
 
    {
4840
 
        *newWidth  = width;
4841
 
        *newHeight = height;
4842
 
 
4843
 
        return true;
4844
 
    }
4845
 
 
4846
 
    return false;
 
4712
        ignoredHints |= PAspect;
 
4713
 
 
4714
        if (priv->state & CompWindowStateMaximizedHorzMask)
 
4715
            ignoredResizeHints |= PHorzResizeInc;
 
4716
 
 
4717
        if (priv->state & CompWindowStateMaximizedVertMask)
 
4718
            ignoredResizeHints |= PVertResizeInc;
 
4719
    }
 
4720
 
 
4721
    CompSize ret = compiz::window::constrainment::constrainToHints (priv->sizeHints,
 
4722
                                                                    size,
 
4723
                                                                    ignoredHints, ignoredResizeHints);
 
4724
 
 
4725
    *newWidth = ret.width ();
 
4726
    *newHeight = ret.height ();
 
4727
 
 
4728
    return ret != size;
4847
4729
}
4848
4730
 
4849
4731
void