Merge lp:~mterry/compiz/unmaximize-regression into lp:compiz/raring

Proposed by Michael Terry
Status: Merged
Approved by: Łukasz Zemczak
Approved revision: 3639
Merged at revision: 3639
Proposed branch: lp:~mterry/compiz/unmaximize-regression
Merge into: lp:compiz/raring
Diff against target: 472 lines (+216/-150)
2 files modified
plugins/decor/src/decor.cpp (+201/-150)
plugins/decor/src/decor.h (+15/-0)
To merge this branch: bzr merge lp:~mterry/compiz/unmaximize-regression
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Łukasz Zemczak Approve
Review via email: mp+154994@code.launchpad.net

Commit message

Also decorate shadow-only windows. Strangely this fixes (LP: #1158161)

Description of the change

This fixes a regression; it is also landing in trunk.

It does cause a small regression with window size of some undecorated windows (notably, the workrave "rest break warning" window). We'll deal with that separately, since it's a less severe-regression than the one this fixes.

To post a comment you must log in.
Revision history for this message
Łukasz Zemczak (sil2100) wrote :

It's ok. Tested, the fix works and doesn't seem to have any regressions. The refactoring is not too big, so it should be fine.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/decor/src/decor.cpp'
--- plugins/decor/src/decor.cpp 2013-03-11 06:45:19 +0000
+++ plugins/decor/src/decor.cpp 2013-03-22 16:49:24 +0000
@@ -42,6 +42,8 @@
4242
43COMPIZ_PLUGIN_20090315 (decor, DecorPluginVTable)43COMPIZ_PLUGIN_20090315 (decor, DecorPluginVTable)
4444
45namespace cwe = compiz::window::extents;
46
45MatchedDecorClipGroup::MatchedDecorClipGroup (const CompMatch &match) :47MatchedDecorClipGroup::MatchedDecorClipGroup (const CompMatch &match) :
46 mMatch (match)48 mMatch (match)
47{49{
@@ -1399,6 +1401,181 @@
1399 return *cit;1401 return *cit;
1400}1402}
14011403
1404bool
1405DecorWindow::bareDecorationOnly ()
1406{
1407 bool shadowOnly = true;
1408 /* Only want to decorate windows which have a frame or are in the process
1409 * of waiting for an animation to be unmapped (in which case we can give
1410 * them a new pixmap type frame since we don't actually need an input
1411 * window to go along with that
1412 *
1413 * FIXME: That's not going to play nice with reparented decorations in core
1414 * since the window gets reparented right away before plugins are done
1415 * with it */
1416
1417 /* Unconditionally decorate switchers */
1418 if (!isSwitcher)
1419 {
1420 switch (window->type ()) {
1421 case CompWindowTypeDialogMask:
1422 case CompWindowTypeModalDialogMask:
1423 case CompWindowTypeUtilMask:
1424 case CompWindowTypeMenuMask:
1425 case CompWindowTypeNormalMask:
1426 if (window->mwmDecor () & (MwmDecorAll | MwmDecorTitle))
1427 shadowOnly = false;
1428 default:
1429 break;
1430 }
1431
1432 if (window->overrideRedirect ())
1433 shadowOnly = true;
1434
1435 if (window->wmType () & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
1436 shadowOnly = true;
1437
1438 if (!shadowOnly)
1439 {
1440 if (!dScreen->optionGetDecorationMatch ().evaluate (window))
1441 shadowOnly = true;
1442 }
1443
1444 /* Never on unmapped windows */
1445 if (!window->isViewable ())
1446 shadowOnly = false;
1447 }
1448 else
1449 shadowOnly = false;
1450
1451 return shadowOnly;
1452}
1453
1454Decoration::Ptr
1455DecorWindow::findRealDecoration ()
1456{
1457 Decoration::Ptr decoration;
1458
1459 /* Attempt to find a matching decoration */
1460 try
1461 {
1462 decoration = decor.findMatchingDecoration (window, true);
1463 }
1464 catch (...)
1465 {
1466 /* Find an appropriate default decoration to use */
1467 if (dScreen->dmSupports & WINDOW_DECORATION_TYPE_PIXMAP &&
1468 dScreen->cmActive &&
1469 !(dScreen->dmSupports & WINDOW_DECORATION_TYPE_WINDOW &&
1470 pixmapFailed))
1471 {
1472 try
1473 {
1474 decoration = dScreen->decor[DECOR_ACTIVE].findMatchingDecoration (window, false);
1475 }
1476 catch (...)
1477 {
1478 compLogMessage ("decor", CompLogLevelWarn, "No default decoration found, placement will not be correct");
1479 decoration.reset ();
1480 }
1481 }
1482 else if (dScreen->dmSupports & WINDOW_DECORATION_TYPE_WINDOW)
1483 decoration = dScreen->windowDefault;
1484 }
1485
1486 return decoration;
1487}
1488
1489Decoration::Ptr
1490DecorWindow::findBareDecoration ()
1491{
1492 Decoration::Ptr decoration;
1493 /* This window isn't "decorated" but it still gets a shadow as long
1494 * as it isn't shaped weirdly, since the shadow is just a quad rect */
1495 if (dScreen->optionGetShadowMatch ().evaluate (window))
1496 {
1497 if (window->region ().numRects () == 1 && !window->alpha () && dScreen->decor[DECOR_BARE].mList.size ())
1498 decoration = dScreen->decor[DECOR_BARE].mList.front ();
1499
1500 if (decoration)
1501 {
1502 if (!checkSize (decoration))
1503 decoration.reset ();
1504 }
1505 }
1506
1507 return decoration;
1508}
1509
1510void
1511DecorWindow::moveDecoratedWindowBy (const CompPoint &movement,
1512 bool instant)
1513{
1514 /* Need to actually move the window */
1515 if (window->placed () && !window->overrideRedirect () &&
1516 (movement.x () || movement.y ()))
1517 {
1518 XWindowChanges xwc;
1519 unsigned int mask = CWX | CWY;
1520
1521 memset (&xwc, 0, sizeof (XWindowChanges));
1522
1523 /* Grab the geometry last sent to server at configureXWindow
1524 * time and not here since serverGeometry may be updated by
1525 * the time that we do call configureXWindow */
1526 xwc.x = movement.x ();
1527 xwc.y = movement.y ();
1528
1529 /* Except if it's fullscreen, maximized or such */
1530 if (window->state () & CompWindowStateFullscreenMask)
1531 mask &= ~(CWX | CWY);
1532
1533 if (window->state () & CompWindowStateMaximizedHorzMask)
1534 mask &= ~CWX;
1535
1536 if (window->state () & CompWindowStateMaximizedVertMask)
1537 mask &= ~CWY;
1538
1539 if (window->saveMask () & CWX)
1540 window->saveWc ().x += movement.x ();
1541
1542 if (window->saveMask () & CWY)
1543 window->saveWc ().y += movement.y ();
1544
1545 if (mask)
1546 {
1547 /* instant is only true in the case of
1548 * the destructor calling the update function so since it
1549 * is not safe to put the function in a timer (since
1550 * it will get unref'd on the vtable destruction) we
1551 * need to do it immediately
1552 *
1553 * FIXME: CompTimer should really be PIMPL and allow
1554 * refcounting in case we need to keep it alive
1555 */
1556 if (instant)
1557 decorOffsetMove (window, xwc, mask);
1558 else
1559 moveUpdate.start (boost::bind (decorOffsetMove, window, xwc, mask), 0);
1560 }
1561 }
1562}
1563
1564namespace
1565{
1566bool
1567shouldDecorateWindow (CompWindow *w,
1568 bool shadowOnly,
1569 bool isSwitcher)
1570{
1571 const bool visible = (w->frame () ||
1572 w->hasUnmapReference ());
1573 const bool realDecoration = visible && !shadowOnly;
1574 const bool forceDecoration = isSwitcher;
1575
1576 return realDecoration || forceDecoration;
1577}
1578}
1402/*1579/*
1403 * DecorWindow::update1580 * DecorWindow::update
1404 * This is the master function for managing decorations on windows1581 * This is the master function for managing decorations on windows
@@ -1439,8 +1616,6 @@
1439DecorWindow::update (bool allowDecoration)1616DecorWindow::update (bool allowDecoration)
1440{1617{
1441 Decoration::Ptr old, decoration;1618 Decoration::Ptr old, decoration;
1442 bool decorate = false;
1443 bool shadowOnly = true;
1444 CompPoint oldShift, movement;1619 CompPoint oldShift, movement;
14451620
1446 if (wd)1621 if (wd)
@@ -1448,99 +1623,19 @@
1448 else1623 else
1449 old.reset ();1624 old.reset ();
14501625
1451 /* Only want to decorate windows which have a frame or are in the process1626 bool shadowOnly = bareDecorationOnly ();
1452 * of waiting for an animation to be unmapped (in which case we can give1627 bool decorate = shouldDecorateWindow (window, shadowOnly, isSwitcher);
1453 * them a new pixmap type frame since we don't actually need an input
1454 * window to go along with that
1455 *
1456 * FIXME: That's not going to play nice with reparented decorations in core
1457 * since the window gets reparented right away before plugins are done
1458 * with it */
1459
1460 /* Unconditionally decorate switchers */
1461 if (!isSwitcher)
1462 {
1463 switch (window->type ()) {
1464 case CompWindowTypeDialogMask:
1465 case CompWindowTypeModalDialogMask:
1466 case CompWindowTypeUtilMask:
1467 case CompWindowTypeMenuMask:
1468 case CompWindowTypeNormalMask:
1469 if (window->mwmDecor () & (MwmDecorAll | MwmDecorTitle))
1470 shadowOnly = false;
1471 default:
1472 break;
1473 }
1474
1475 if (window->overrideRedirect ())
1476 shadowOnly = true;
1477
1478 if (window->wmType () & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
1479 shadowOnly = true;
1480
1481 if (!shadowOnly)
1482 {
1483 if (!dScreen->optionGetDecorationMatch ().evaluate (window))
1484 shadowOnly = true;
1485 }
1486 }
1487 else
1488 shadowOnly = false;
1489
1490 decorate = ((window->frame () ||
1491 window->hasUnmapReference ()) && !shadowOnly) ||
1492 isSwitcher;
14931628
1494 if (decorate || frameExtentsRequested)1629 if (decorate || frameExtentsRequested)
1495 {1630 {
1496 /* Attempt to find a matching decoration */1631 decoration = findRealDecoration ();
1497 try
1498 {
1499 decoration = decor.findMatchingDecoration (window, true);
1500 }
1501 catch (...)
1502 {
1503 /* Find an appropriate default decoration to use */
1504 if (dScreen->dmSupports & WINDOW_DECORATION_TYPE_PIXMAP &&
1505 dScreen->cmActive &&
1506 !(dScreen->dmSupports & WINDOW_DECORATION_TYPE_WINDOW &&
1507 pixmapFailed))
1508 {
1509 try
1510 {
1511 decoration = dScreen->decor[DECOR_ACTIVE].findMatchingDecoration (window, false);
1512 }
1513 catch (...)
1514 {
1515 compLogMessage ("decor", CompLogLevelWarn, "No default decoration found, placement will not be correct");
1516 decoration.reset ();
1517 }
1518 }
1519 else if (dScreen->dmSupports & WINDOW_DECORATION_TYPE_WINDOW)
1520 decoration = dScreen->windowDefault;
1521 }
1522
1523 /* Do not allow windows which are later undecorated1632 /* Do not allow windows which are later undecorated
1524 * to have a set _NET_FRAME_EXTENTS */1633 * to have a set _NET_FRAME_EXTENTS */
1525 if (decorate)1634 if (decorate)
1526 frameExtentsRequested = false;1635 frameExtentsRequested = false;
1527 }1636 }
1528 else1637 else
1529 {1638 decoration = findBareDecoration ();
1530 /* This window isn't "decorated" but it still gets a shadow as long
1531 * as it isn't shaped weirdly, since the shadow is just a quad rect */
1532 if (dScreen->optionGetShadowMatch ().evaluate (window))
1533 {
1534 if (window->region ().numRects () == 1 && !window->alpha () && dScreen->decor[DECOR_BARE].mList.size ())
1535 decoration = dScreen->decor[DECOR_BARE].mList.front ();
1536
1537 if (decoration)
1538 {
1539 if (!checkSize (decoration))
1540 decoration.reset ();
1541 }
1542 }
1543 }
15441639
1545 /* Don't allow the windows to be decorated if1640 /* Don't allow the windows to be decorated if
1546 * we're tearing down or if a decorator isn't running1641 * we're tearing down or if a decorator isn't running
@@ -1555,25 +1650,14 @@
1555 if (decoration == old)1650 if (decoration == old)
1556 return false;1651 return false;
15571652
1558 /* We need to damage the current output extents
1559 * and recompute the shadow region if a compositor
1560 * is running
1561 */
1562 if (dScreen->cmActive)
1563 {
1564 cWindow->damageOutputExtents ();
1565 updateGroupShadows ();
1566 }
1567
1568 /* Determine how much we moved the window for the old1653 /* Determine how much we moved the window for the old
1569 * decoration and save that, also destroy the old1654 * decoration and save that, also destroy the old
1570 * WindowDecoration */1655 * WindowDecoration */
1571 if (old)1656 if (old)
1572 {1657 {
1573 oldShift = compiz::window::extents::shift (window->border (), window->sizeHints ().win_gravity);1658 oldShift = cwe::shift (window->border (), window->sizeHints ().win_gravity);
15741659
1575 WindowDecoration::destroy (wd);1660 WindowDecoration::destroy (wd);
1576
1577 wd = NULL;1661 wd = NULL;
1578 }1662 }
15791663
@@ -1595,8 +1679,10 @@
1595 window->setWindowFrameExtents (&decoration->border,1679 window->setWindowFrameExtents (&decoration->border,
1596 &decoration->input);1680 &decoration->input);
15971681
1598 /* We actually need to decorate this window */1682 /* This window actually needs its decoration contents updated
1599 if (decorate)1683 * as it was actually visible */
1684 if (decorate ||
1685 shadowOnly)
1600 {1686 {
1601 wd = WindowDecoration::create (decoration);1687 wd = WindowDecoration::create (decoration);
1602 if (!wd)1688 if (!wd)
@@ -1608,20 +1694,21 @@
1608 return false;1694 return false;
1609 }1695 }
16101696
1611 movement = compiz::window::extents::shift (window->border (), window->sizeHints ().win_gravity);1697 movement = cwe::shift (window->border (), window->sizeHints ().win_gravity);
1612 movement -= oldShift;1698 movement -= oldShift;
16131699
1614 /* Update the input and output frame */
1615 updateFrame ();
1616 window->updateWindowOutputExtents ();1700 window->updateWindowOutputExtents ();
16171701
1618 updateReg = true;1702 updateReg = true;
1619 updateMatrix = true;1703 updateMatrix = true;
1620 mOutputRegion = CompRegion (window->outputRect ());1704 mOutputRegion = CompRegion (window->outputRect ());
1621 updateGroupShadows ();
1622 if (dScreen->cmActive)1705 if (dScreen->cmActive)
1623 cWindow->damageOutputExtents ();1706 cWindow->damageOutputExtents ();
1624 updateDecorationScale ();1707 updateDecorationScale ();
1708
1709 /* Update the input and output frame */
1710 if (decorate)
1711 updateFrame ();
1625 }1712 }
1626 }1713 }
1627 else1714 else
@@ -1641,55 +1728,19 @@
1641 movement -= oldShift;1728 movement -= oldShift;
1642 }1729 }
16431730
1644 /* Need to actually move the window */1731 /* We need to damage the current output extents
1645 if (window->placed () && !window->overrideRedirect () &&1732 * and recompute the shadow region if a compositor
1646 (movement.x () || movement.y ()))1733 * is running
1734 */
1735 if (dScreen->cmActive)
1647 {1736 {
1648 XWindowChanges xwc;1737 cWindow->damageOutputExtents ();
1649 unsigned int mask = CWX | CWY;1738 updateGroupShadows ();
1650
1651 memset (&xwc, 0, sizeof (XWindowChanges));
1652
1653 /* Grab the geometry last sent to server at configureXWindow
1654 * time and not here since serverGeometry may be updated by
1655 * the time that we do call configureXWindow */
1656 xwc.x = movement.x ();
1657 xwc.y = movement.y ();
1658
1659 /* Except if it's fullscreen, maximized or such */
1660 if (window->state () & CompWindowStateFullscreenMask)
1661 mask &= ~(CWX | CWY);
1662
1663 if (window->state () & CompWindowStateMaximizedHorzMask)
1664 mask &= ~CWX;
1665
1666 if (window->state () & CompWindowStateMaximizedVertMask)
1667 mask &= ~CWY;
1668
1669 if (window->saveMask () & CWX)
1670 window->saveWc ().x += movement.x ();
1671
1672 if (window->saveMask () & CWY)
1673 window->saveWc ().y += movement.y ();
1674
1675 if (mask)
1676 {
1677 /* allowDecoration is only false in the case of
1678 * the destructor calling the update function so since it
1679 * is not safe to put the function in a timer (since
1680 * it will get unref'd on the vtable destruction) we
1681 * need to do it immediately
1682 *
1683 * FIXME: CompTimer should really be PIMPL and allow
1684 * refcounting in case we need to keep it alive
1685 */
1686 if (!allowDecoration)
1687 decorOffsetMove (window, xwc, mask);
1688 else
1689 moveUpdate.start (boost::bind (decorOffsetMove, window, xwc, mask), 0);
1690 }
1691 }1739 }
16921740
1741 moveDecoratedWindowBy (movement,
1742 !allowDecoration);
1743
1693 return true;1744 return true;
1694}1745}
16951746
16961747
=== modified file 'plugins/decor/src/decor.h'
--- plugins/decor/src/decor.h 2013-02-20 03:07:58 +0000
+++ plugins/decor/src/decor.h 2013-03-22 16:49:24 +0000
@@ -152,6 +152,13 @@
152152
153 unsigned int updateState;153 unsigned int updateState;
154 X11DecorPixmapReceiver mPixmapReceiver;154 X11DecorPixmapReceiver mPixmapReceiver;
155
156 private:
157
158 bool bareDecorationOnly ();
159 Decoration::Ptr findRealDecoration ();
160 Decoration::Ptr findBareDecoration ();
161 void moveDecoratedWindowBy (const CompPoint &movement);
155};162};
156163
157class DecorationList :164class DecorationList :
@@ -372,6 +379,14 @@
372 CompRegion mInputRegion;379 CompRegion mInputRegion;
373380
374 X11DecorPixmapRequestor mRequestor;381 X11DecorPixmapRequestor mRequestor;
382
383 private:
384
385 bool bareDecorationOnly ();
386 Decoration::Ptr findRealDecoration ();
387 Decoration::Ptr findBareDecoration ();
388 void moveDecoratedWindowBy (const CompPoint &movement,
389 bool instant);
375};390};
376391
377class DecorPluginVTable :392class DecorPluginVTable :

Subscribers

People subscribed via source and target branches