~townsend/compiz/fix-auto-vp-switch-0.9.10

« back to all changes in this revision

Viewing changes to plugins/decor/src/decor.cpp

  • Committer: Tarmac
  • Author(s): Chris Townsend
  • Date: 2013-09-09 13:05:20 UTC
  • mfrom: (3786.1.1 compiz-0.9.10)
  • Revision ID: tarmac-20130909130520-tb8f2jwfrbe5rco1
Work done by Sam Spilsbury:
- Ensure that the frame region is always set as soon as the window is decorated.
- Further ensure that the window decoration isn't needlessly reset if the window already had one.
- Refactored XShape usage into a common function.
- Added tests to verify the behaviour of shape set on initially creating a decorated window and also upon changing the input frame window shape. Fixes: https://bugs.launchpad.net/bugs/1158267.

Approved by Brandon Schaefer, PS Jenkins bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
 
45
45
namespace cwe = compiz::window::extents;
46
46
 
 
47
namespace
 
48
{
 
49
void updateRegionWithShapeRectangles (Display    *dpy,
 
50
                                      Window     w,
 
51
                                      CompRegion &region)
 
52
{
 
53
    int n = 0;
 
54
    int order = 0;
 
55
    XRectangle *shapeRects = NULL;
 
56
 
 
57
    shapeRects =
 
58
        XShapeGetRectangles (dpy,
 
59
            w, ShapeInput,
 
60
            &n, &order);
 
61
    if (!shapeRects)
 
62
        return;
 
63
 
 
64
    for (int i = 0; i < n; i++)
 
65
        region +=
 
66
            CompRegion (shapeRects[i].x,
 
67
                        shapeRects[i].y,
 
68
                        shapeRects[i].width,
 
69
                        shapeRects[i].height);
 
70
 
 
71
    XFree (shapeRects);
 
72
}
 
73
}
 
74
 
47
75
MatchedDecorClipGroup::MatchedDecorClipGroup (const CompMatch &match) :
48
76
    mMatch (match)
49
77
{
1590
1618
        lastMaximizedStateDecorated == decorMaximizeState)
1591
1619
        return false;
1592
1620
 
1593
 
    /* Destroy the old WindowDecoration */
1594
 
    if (old)
1595
 
    {
1596
 
        WindowDecoration::destroy (wd);
1597
 
        wd = NULL;
1598
 
    }
1599
 
 
1600
1621
    /* If a decoration was found for this window, create
1601
1622
     * a new WindowDecoration for it and set the frame
1602
1623
     * extents accordingly. We should also move the
1622
1643
        if (decorate ||
1623
1644
            shadowOnly)
1624
1645
        {
 
1646
            if (wd)
 
1647
                WindowDecoration::destroy (wd);
1625
1648
            wd = WindowDecoration::create (decoration);
1626
1649
            if (!wd)
1627
1650
            {
1649
1672
    else
1650
1673
    {
1651
1674
        CompWindowExtents emptyExtents;
1652
 
        wd = NULL;
 
1675
 
 
1676
        if (wd)
 
1677
        {
 
1678
            WindowDecoration::destroy (wd);
 
1679
            wd = NULL;
 
1680
        }
1653
1681
 
1654
1682
        /* _NET_FRAME_EXTENTS should be updated before the frame
1655
1683
         * atom is */
1903
1931
                                 ShapeSet, YXBanded);
1904
1932
 
1905
1933
        frameRegion = CompRegion ();
 
1934
 
 
1935
        /* Immediately query shape rectangles so that we can
 
1936
         * report them if core asks for them */
 
1937
        updateRegionWithShapeRectangles (screen->dpy (),
 
1938
                                         inputFrame,
 
1939
                                         frameRegion);
 
1940
        window->updateFrameRegion ();
1906
1941
    }
1907
1942
 
1908
1943
    XUngrabServer (screen->dpy ());
2045
2080
                                 ShapeSet, YXBanded);
2046
2081
 
2047
2082
        frameRegion = CompRegion ();
 
2083
 
 
2084
        /* Immediately query shape rectangles so that we can
 
2085
         * report them if core asks for them */
 
2086
        updateRegionWithShapeRectangles (screen->dpy (),
 
2087
                                         outputFrame,
 
2088
                                         frameRegion);
 
2089
        window->updateFrameRegion ();
2048
2090
    }
2049
2091
 
2050
2092
    XUngrabServer (screen->dpy ());
2168
2210
DecorWindow::updateFrameRegion (CompRegion &region)
2169
2211
{
2170
2212
    window->updateFrameRegion (region);
 
2213
 
2171
2214
    if (wd)
2172
2215
    {
2173
2216
        if (!frameRegion.isEmpty ())
2180
2223
            region += frameRegion.translated (x - wd->decor->input.left,
2181
2224
                                              y - wd->decor->input.top);
2182
2225
        }
2183
 
        else
2184
 
        {
2185
 
            region += infiniteRegion;
2186
 
        }
2187
2226
    }
2188
2227
 
2189
2228
    updateReg = true;
2602
2641
                        if (dw->inputFrame ==
2603
2642
                            ((XShapeEvent *) event)->window)
2604
2643
                        {
2605
 
                            XRectangle *shapeRects = 0;
2606
 
                            int order, n;
2607
 
 
2608
2644
                            dw->frameRegion = CompRegion ();
2609
2645
 
2610
 
                            shapeRects =
2611
 
                                XShapeGetRectangles (screen->dpy (),
2612
 
                                    dw->inputFrame, ShapeInput,
2613
 
                                    &n, &order);
2614
 
                            if (!shapeRects || !n)
2615
 
                                break;
2616
 
 
2617
 
                            for (int i = 0; i < n; i++)
2618
 
                                dw->frameRegion +=
2619
 
                                    CompRegion (shapeRects[i].x,
2620
 
                                                shapeRects[i].y,
2621
 
                                                shapeRects[i].width,
2622
 
                                                shapeRects[i].height);
 
2646
                            updateRegionWithShapeRectangles (screen->dpy (),
 
2647
                                                             dw->inputFrame,
 
2648
                                                             dw->frameRegion);
2623
2649
 
2624
2650
                            w->updateFrameRegion ();
2625
 
 
2626
 
                            XFree (shapeRects);
2627
2651
                        }
2628
2652
                        else if (dw->outputFrame ==
2629
2653
                                 ((XShapeEvent *) event)->window)
2630
2654
                        {
2631
 
                            XRectangle *shapeRects = 0;
2632
 
                            int order, n;
2633
 
 
2634
2655
                            dw->frameRegion = CompRegion ();
2635
2656
 
2636
 
                            shapeRects =
2637
 
                                XShapeGetRectangles (screen->dpy (),
2638
 
                                    dw->outputFrame, ShapeBounding,
2639
 
                                    &n, &order);
2640
 
                            if (!n || !shapeRects)
2641
 
                                break;
2642
 
 
2643
 
                            for (int i = 0; i < n; i++)
2644
 
                                dw->frameRegion +=
2645
 
                                    CompRegion (shapeRects[i].x,
2646
 
                                                shapeRects[i].y,
2647
 
                                                shapeRects[i].width,
2648
 
                                                shapeRects[i].height);
 
2657
                            updateRegionWithShapeRectangles (screen->dpy (),
 
2658
                                                             dw->outputFrame,
 
2659
                                                             dw->frameRegion);
2649
2660
 
2650
2661
                            w->updateFrameRegion ();
2651
 
 
2652
 
                            XFree (shapeRects);
2653
2662
                        }
2654
2663
                    }
2655
2664
                }