Changeset View
Changeset View
Standalone View
Standalone View
geometry.cpp
Show First 20 Lines • Show All 1317 Lines • ▼ Show 20 Line(s) | 1310 | { | |||
---|---|---|---|---|---|
1318 | } else if (geom->bottom() < screenArea.top()) { | 1318 | } else if (geom->bottom() < screenArea.top()) { | ||
1319 | geom->moveBottom(screenArea.top() + screenArea.width()/4); | 1319 | geom->moveBottom(screenArea.top() + screenArea.width()/4); | ||
1320 | } | 1320 | } | ||
1321 | } | 1321 | } | ||
1322 | 1322 | | |||
1323 | QSize AbstractClient::adjustedSize(const QSize& frame, Sizemode mode) const | 1323 | QSize AbstractClient::adjustedSize(const QSize& frame, Sizemode mode) const | ||
1324 | { | 1324 | { | ||
1325 | // first, get the window size for the given frame size s | 1325 | // first, get the window size for the given frame size s | ||
1326 | QSize wsize(frame.width() - (borderLeft() + borderRight()), | 1326 | QSize wsize = frameSizeToClientSize(frame); | ||
1327 | frame.height() - (borderTop() + borderBottom())); | | |||
1328 | if (wsize.isEmpty()) | 1327 | if (wsize.isEmpty()) | ||
1329 | wsize = QSize(qMax(wsize.width(), 1), qMax(wsize.height(), 1)); | 1328 | wsize = QSize(qMax(wsize.width(), 1), qMax(wsize.height(), 1)); | ||
1330 | 1329 | | |||
1331 | return sizeForClientSize(wsize, mode, false); | 1330 | return sizeForClientSize(wsize, mode, false); | ||
1332 | } | 1331 | } | ||
1333 | 1332 | | |||
1334 | // this helper returns proper size even if the window is shaded | 1333 | // this helper returns proper size even if the window is shaded | ||
1335 | // see also the comment in X11Client::setGeometry() | 1334 | // see also the comment in X11Client::setGeometry() | ||
▲ Show 20 Lines • Show All 166 Lines • ▼ Show 20 Line(s) | 1499 | #undef ASPECT_CHECK_GROW_H | |||
1502 | h += baseSize.height(); | 1501 | h += baseSize.height(); | ||
1503 | } | 1502 | } | ||
1504 | if (!rules()->checkStrictGeometry(!isFullScreen())) { | 1503 | if (!rules()->checkStrictGeometry(!isFullScreen())) { | ||
1505 | // disobey increments and aspect by explicit rule | 1504 | // disobey increments and aspect by explicit rule | ||
1506 | w = w1; | 1505 | w = w1; | ||
1507 | h = h1; | 1506 | h = h1; | ||
1508 | } | 1507 | } | ||
1509 | 1508 | | |||
1509 | QSize size(w, h); | ||||
1510 | if (!noframe) { | 1510 | if (!noframe) { | ||
1511 | w += borderLeft() + borderRight(); | 1511 | size = clientSizeToFrameSize(size); | ||
1512 | h += borderTop() + borderBottom(); | | |||
1513 | } | 1512 | } | ||
1514 | return rules()->checkSize(QSize(w, h)); | 1513 | return rules()->checkSize(size); | ||
1515 | } | 1514 | } | ||
1516 | 1515 | | |||
1517 | /** | 1516 | /** | ||
1518 | * Gets the client's normal WM hints and reconfigures itself respectively. | 1517 | * Gets the client's normal WM hints and reconfigures itself respectively. | ||
1519 | */ | 1518 | */ | ||
1520 | void X11Client::getWmNormalHints() | 1519 | void X11Client::getWmNormalHints() | ||
1521 | { | 1520 | { | ||
1522 | const bool hadFixedAspect = m_geometryHints.hasAspect(); | 1521 | const bool hadFixedAspect = m_geometryHints.hasAspect(); | ||
1523 | // roundtrip to X server | 1522 | // roundtrip to X server | ||
1524 | m_geometryHints.fetch(); | 1523 | m_geometryHints.fetch(); | ||
1525 | m_geometryHints.read(); | 1524 | m_geometryHints.read(); | ||
1526 | 1525 | | |||
1527 | if (!hadFixedAspect && m_geometryHints.hasAspect()) { | 1526 | if (!hadFixedAspect && m_geometryHints.hasAspect()) { | ||
1528 | // align to eventual new contraints | 1527 | // align to eventual new contraints | ||
1529 | maximize(max_mode); | 1528 | maximize(max_mode); | ||
1530 | } | 1529 | } | ||
1531 | if (isManaged()) { | 1530 | if (isManaged()) { | ||
1532 | // update to match restrictions | 1531 | // update to match restrictions | ||
1533 | QSize new_size = adjustedSize(); | 1532 | QSize new_size = adjustedSize(); | ||
1534 | if (new_size != size() && !isFullScreen()) { | 1533 | if (new_size != size() && !isFullScreen()) { | ||
1535 | QRect origClientGeometry(pos() + clientPos(), clientSize()); | 1534 | QRect origClientGeometry = m_clientGeometry; | ||
1536 | resizeWithChecks(new_size); | 1535 | resizeWithChecks(new_size); | ||
1537 | if ((!isSpecialWindow() || isToolbar()) && !isFullScreen()) { | 1536 | if ((!isSpecialWindow() || isToolbar()) && !isFullScreen()) { | ||
1538 | // try to keep the window in its xinerama screen if possible, | 1537 | // try to keep the window in its xinerama screen if possible, | ||
1539 | // if that fails at least keep it visible somewhere | 1538 | // if that fails at least keep it visible somewhere | ||
1540 | QRect area = workspace()->clientArea(MovementArea, this); | 1539 | QRect area = workspace()->clientArea(MovementArea, this); | ||
1541 | if (area.contains(origClientGeometry)) | 1540 | if (area.contains(origClientGeometry)) | ||
1542 | keepInArea(area); | 1541 | keepInArea(area); | ||
1543 | area = workspace()->clientArea(WorkArea, this); | 1542 | area = workspace()->clientArea(WorkArea, this); | ||
Show All 26 Lines | |||||
1570 | */ | 1569 | */ | ||
1571 | void X11Client::sendSyntheticConfigureNotify() | 1570 | void X11Client::sendSyntheticConfigureNotify() | ||
1572 | { | 1571 | { | ||
1573 | xcb_configure_notify_event_t c; | 1572 | xcb_configure_notify_event_t c; | ||
1574 | memset(&c, 0, sizeof(c)); | 1573 | memset(&c, 0, sizeof(c)); | ||
1575 | c.response_type = XCB_CONFIGURE_NOTIFY; | 1574 | c.response_type = XCB_CONFIGURE_NOTIFY; | ||
1576 | c.event = window(); | 1575 | c.event = window(); | ||
1577 | c.window = window(); | 1576 | c.window = window(); | ||
1578 | c.x = x() + clientPos().x(); | 1577 | c.x = m_clientGeometry.x(); | ||
1579 | c.y = y() + clientPos().y(); | 1578 | c.y = m_clientGeometry.y(); | ||
1580 | c.width = clientSize().width(); | 1579 | c.width = m_clientGeometry.width(); | ||
1581 | c.height = clientSize().height(); | 1580 | c.height = m_clientGeometry.height(); | ||
1582 | c.border_width = 0; | 1581 | c.border_width = 0; | ||
1583 | c.above_sibling = XCB_WINDOW_NONE; | 1582 | c.above_sibling = XCB_WINDOW_NONE; | ||
1584 | c.override_redirect = 0; | 1583 | c.override_redirect = 0; | ||
1585 | xcb_send_event(connection(), true, c.event, XCB_EVENT_MASK_STRUCTURE_NOTIFY, reinterpret_cast<const char*>(&c)); | 1584 | xcb_send_event(connection(), true, c.event, XCB_EVENT_MASK_STRUCTURE_NOTIFY, reinterpret_cast<const char*>(&c)); | ||
1586 | xcb_flush(connection()); | 1585 | xcb_flush(connection()); | ||
1587 | } | 1586 | } | ||
1588 | 1587 | | |||
1589 | const QPoint X11Client::calculateGravitation(bool invert, int gravity) const | 1588 | QPoint X11Client::gravityAdjustment(xcb_gravity_t gravity) const | ||
1590 | { | 1589 | { | ||
1591 | int dx, dy; | 1590 | int dx = 0; | ||
1592 | dx = dy = 0; | 1591 | int dy = 0; | ||
1593 | 1592 | | |||
1594 | if (gravity == 0) // default (nonsense) value for the argument | 1593 | // dx, dy specify how the client window moves to make space for the frame. | ||
1595 | gravity = m_geometryHints.windowGravity(); | 1594 | // In general we have to compute the reference point and from that figure | ||
1596 | 1595 | // out how much we need to shift the client, however given that we ignore | |||
1597 | // dx, dy specify how the client window moves to make space for the frame | 1596 | // the border width attribute and the extents of the server-side decoration | ||
1597 | // are known in advance, we can simplify the math quite a bit and express | ||||
1598 | // the required window gravity adjustment in terms of border sizes. | ||||
1598 | switch(gravity) { | 1599 | switch(gravity) { | ||
1599 | case XCB_GRAVITY_NORTH_WEST: // move down right | 1600 | case XCB_GRAVITY_NORTH_WEST: // move down right | ||
1600 | default: | 1601 | default: | ||
1601 | dx = borderLeft(); | 1602 | dx = borderLeft(); | ||
1602 | dy = borderTop(); | 1603 | dy = borderTop(); | ||
1603 | break; | 1604 | break; | ||
1604 | case XCB_GRAVITY_NORTH: // move right | 1605 | case XCB_GRAVITY_NORTH: // move right | ||
1605 | dx = 0; | 1606 | dx = 0; | ||
1606 | dy = borderTop(); | 1607 | dy = borderTop(); | ||
1607 | break; | 1608 | break; | ||
1608 | case XCB_GRAVITY_NORTH_EAST: // move down left | 1609 | case XCB_GRAVITY_NORTH_EAST: // move down left | ||
1609 | dx = -borderRight(); | 1610 | dx = -borderRight(); | ||
1610 | dy = borderTop(); | 1611 | dy = borderTop(); | ||
1611 | break; | 1612 | break; | ||
1612 | case XCB_GRAVITY_WEST: // move right | 1613 | case XCB_GRAVITY_WEST: // move right | ||
1613 | dx = borderLeft(); | 1614 | dx = borderLeft(); | ||
1614 | dy = 0; | 1615 | dy = 0; | ||
1615 | break; | 1616 | break; | ||
1616 | case XCB_GRAVITY_CENTER: | 1617 | case XCB_GRAVITY_CENTER: | ||
1617 | break; // will be handled specially | 1618 | dx = (borderLeft() - borderRight()) / 2; | ||
1619 | dy = (borderTop() - borderBottom()) / 2; | ||||
1620 | break; | ||||
1618 | case XCB_GRAVITY_STATIC: // don't move | 1621 | case XCB_GRAVITY_STATIC: // don't move | ||
1619 | dx = 0; | 1622 | dx = 0; | ||
1620 | dy = 0; | 1623 | dy = 0; | ||
1621 | break; | 1624 | break; | ||
1622 | case XCB_GRAVITY_EAST: // move left | 1625 | case XCB_GRAVITY_EAST: // move left | ||
1623 | dx = -borderRight(); | 1626 | dx = -borderRight(); | ||
1624 | dy = 0; | 1627 | dy = 0; | ||
1625 | break; | 1628 | break; | ||
1626 | case XCB_GRAVITY_SOUTH_WEST: // move up right | 1629 | case XCB_GRAVITY_SOUTH_WEST: // move up right | ||
1627 | dx = borderLeft() ; | 1630 | dx = borderLeft() ; | ||
1628 | dy = -borderBottom(); | 1631 | dy = -borderBottom(); | ||
1629 | break; | 1632 | break; | ||
1630 | case XCB_GRAVITY_SOUTH: // move up | 1633 | case XCB_GRAVITY_SOUTH: // move up | ||
1631 | dx = 0; | 1634 | dx = 0; | ||
1632 | dy = -borderBottom(); | 1635 | dy = -borderBottom(); | ||
1633 | break; | 1636 | break; | ||
1634 | case XCB_GRAVITY_SOUTH_EAST: // move up left | 1637 | case XCB_GRAVITY_SOUTH_EAST: // move up left | ||
1635 | dx = -borderRight(); | 1638 | dx = -borderRight(); | ||
1636 | dy = -borderBottom(); | 1639 | dy = -borderBottom(); | ||
1637 | break; | 1640 | break; | ||
1638 | } | 1641 | } | ||
1639 | if (gravity != XCB_GRAVITY_CENTER) { | 1642 | | ||
1640 | // translate from client movement to frame movement | 1643 | return QPoint(dx, dy); | ||
1641 | dx -= borderLeft(); | | |||
1642 | dy -= borderTop(); | | |||
1643 | } else { | | |||
1644 | // center of the frame will be at the same position client center without frame would be | | |||
1645 | dx = - (borderLeft() + borderRight()) / 2; | | |||
1646 | dy = - (borderTop() + borderBottom()) / 2; | | |||
1647 | } | 1644 | } | ||
1645 | | ||||
1646 | const QPoint X11Client::calculateGravitation(bool invert) const | ||||
1647 | { | ||||
1648 | const QPoint adjustment = gravityAdjustment(m_geometryHints.windowGravity()); | ||||
1649 | | ||||
1650 | // translate from client movement to frame movement | ||||
1651 | const int dx = adjustment.x() - borderLeft(); | ||||
1652 | const int dy = adjustment.y() - borderTop(); | ||||
1653 | | ||||
1648 | if (!invert) | 1654 | if (!invert) | ||
1649 | return QPoint(x() + dx, y() + dy); | 1655 | return QPoint(x() + dx, y() + dy); | ||
1650 | else | 1656 | else | ||
1651 | return QPoint(x() - dx, y() - dy); | 1657 | return QPoint(x() - dx, y() - dy); | ||
1652 | } | 1658 | } | ||
1653 | 1659 | | |||
1654 | void X11Client::configureRequest(int value_mask, int rx, int ry, int rw, int rh, int gravity, bool from_tool) | 1660 | void X11Client::configureRequest(int value_mask, int rx, int ry, int rw, int rh, int gravity, bool from_tool) | ||
1655 | { | 1661 | { | ||
Show All 39 Lines | 1699 | if (ignore) { | |||
1695 | return; // nothing to (left) to do for use - bugs #158974, #252314, #321491 | 1701 | return; // nothing to (left) to do for use - bugs #158974, #252314, #321491 | ||
1696 | } | 1702 | } | ||
1697 | 1703 | | |||
1698 | qCDebug(KWIN_CORE) << "PERMITTED" << this << bool(value_mask & configureGeometryMask); | 1704 | qCDebug(KWIN_CORE) << "PERMITTED" << this << bool(value_mask & configureGeometryMask); | ||
1699 | 1705 | | |||
1700 | if (gravity == 0) // default (nonsense) value for the argument | 1706 | if (gravity == 0) // default (nonsense) value for the argument | ||
1701 | gravity = m_geometryHints.windowGravity(); | 1707 | gravity = m_geometryHints.windowGravity(); | ||
1702 | if (value_mask & configurePositionMask) { | 1708 | if (value_mask & configurePositionMask) { | ||
1703 | QPoint new_pos = calculateGravitation(true, gravity); // undo gravitation | 1709 | QPoint new_pos = framePosToClientPos(pos()); | ||
1710 | new_pos -= gravityAdjustment(xcb_gravity_t(gravity)); | ||||
1704 | if (value_mask & XCB_CONFIG_WINDOW_X) { | 1711 | if (value_mask & XCB_CONFIG_WINDOW_X) { | ||
1705 | new_pos.setX(rx); | 1712 | new_pos.setX(rx); | ||
1706 | } | 1713 | } | ||
1707 | if (value_mask & XCB_CONFIG_WINDOW_Y) { | 1714 | if (value_mask & XCB_CONFIG_WINDOW_Y) { | ||
1708 | new_pos.setY(ry); | 1715 | new_pos.setY(ry); | ||
1709 | } | 1716 | } | ||
1710 | | ||||
1711 | // clever(?) workaround for applications like xv that want to set | 1717 | // clever(?) workaround for applications like xv that want to set | ||
1712 | // the location to the current location but miscalculate the | 1718 | // the location to the current location but miscalculate the | ||
1713 | // frame size due to kwin being a double-reparenting window | 1719 | // frame size due to kwin being a double-reparenting window | ||
1714 | // manager | 1720 | // manager | ||
1715 | if (new_pos.x() == x() + clientPos().x() && new_pos.y() == y() + clientPos().y() | 1721 | if (new_pos.x() == m_clientGeometry.x() && new_pos.y() == m_clientGeometry.y() | ||
1716 | && gravity == XCB_GRAVITY_NORTH_WEST && !from_tool) { | 1722 | && gravity == XCB_GRAVITY_NORTH_WEST && !from_tool) { | ||
1717 | new_pos.setX(x()); | 1723 | new_pos.setX(x()); | ||
1718 | new_pos.setY(y()); | 1724 | new_pos.setY(y()); | ||
1719 | } | 1725 | } | ||
1726 | new_pos += gravityAdjustment(xcb_gravity_t(gravity)); | ||||
1727 | new_pos = clientPosToFramePos(new_pos); | ||||
1720 | 1728 | | |||
1721 | int nw = clientSize().width(); | 1729 | int nw = clientSize().width(); | ||
1722 | int nh = clientSize().height(); | 1730 | int nh = clientSize().height(); | ||
1723 | if (value_mask & XCB_CONFIG_WINDOW_WIDTH) { | 1731 | if (value_mask & XCB_CONFIG_WINDOW_WIDTH) { | ||
1724 | nw = rw; | 1732 | nw = rw; | ||
1725 | } | 1733 | } | ||
1726 | if (value_mask & XCB_CONFIG_WINDOW_HEIGHT) { | 1734 | if (value_mask & XCB_CONFIG_WINDOW_HEIGHT) { | ||
1727 | nh = rh; | 1735 | nh = rh; | ||
1728 | } | 1736 | } | ||
1729 | QSize ns = sizeForClientSize(QSize(nw, nh)); // enforces size if needed | 1737 | QSize ns = sizeForClientSize(QSize(nw, nh)); // enforces size if needed | ||
1730 | new_pos = rules()->checkPosition(new_pos); | 1738 | new_pos = rules()->checkPosition(new_pos); | ||
1731 | int newScreen = screens()->number(QRect(new_pos, ns).center()); | 1739 | int newScreen = screens()->number(QRect(new_pos, ns).center()); | ||
1732 | if (newScreen != rules()->checkScreen(newScreen)) | 1740 | if (newScreen != rules()->checkScreen(newScreen)) | ||
1733 | return; // not allowed by rule | 1741 | return; // not allowed by rule | ||
1734 | 1742 | | |||
1735 | QRect origClientGeometry(pos() + clientPos(), clientSize()); | 1743 | QRect origClientGeometry = m_clientGeometry; | ||
1736 | GeometryUpdatesBlocker blocker(this); | 1744 | GeometryUpdatesBlocker blocker(this); | ||
1737 | move(new_pos); | 1745 | move(new_pos); | ||
1738 | plainResize(ns); | 1746 | plainResize(ns); | ||
1739 | setFrameGeometry(QRect(calculateGravitation(false, gravity), size())); | | |||
1740 | QRect area = workspace()->clientArea(WorkArea, this); | 1747 | QRect area = workspace()->clientArea(WorkArea, this); | ||
1741 | if (!from_tool && (!isSpecialWindow() || isToolbar()) && !isFullScreen() | 1748 | if (!from_tool && (!isSpecialWindow() || isToolbar()) && !isFullScreen() | ||
1742 | && area.contains(origClientGeometry)) | 1749 | && area.contains(origClientGeometry)) | ||
1743 | keepInArea(area); | 1750 | keepInArea(area); | ||
1744 | 1751 | | |||
1745 | // this is part of the kicker-xinerama-hack... it should be | 1752 | // this is part of the kicker-xinerama-hack... it should be | ||
1746 | // safe to remove when kicker gets proper ExtendedStrut support; | 1753 | // safe to remove when kicker gets proper ExtendedStrut support; | ||
1747 | // see Workspace::updateClientArea() and | 1754 | // see Workspace::updateClientArea() and | ||
Show All 9 Lines | 1763 | if (value_mask & XCB_CONFIG_WINDOW_WIDTH) { | |||
1757 | nw = rw; | 1764 | nw = rw; | ||
1758 | } | 1765 | } | ||
1759 | if (value_mask & XCB_CONFIG_WINDOW_HEIGHT) { | 1766 | if (value_mask & XCB_CONFIG_WINDOW_HEIGHT) { | ||
1760 | nh = rh; | 1767 | nh = rh; | ||
1761 | } | 1768 | } | ||
1762 | QSize ns = sizeForClientSize(QSize(nw, nh)); | 1769 | QSize ns = sizeForClientSize(QSize(nw, nh)); | ||
1763 | 1770 | | |||
1764 | if (ns != size()) { // don't restore if some app sets its own size again | 1771 | if (ns != size()) { // don't restore if some app sets its own size again | ||
1765 | QRect origClientGeometry(pos() + clientPos(), clientSize()); | 1772 | QRect origClientGeometry = m_clientGeometry; | ||
1766 | GeometryUpdatesBlocker blocker(this); | 1773 | GeometryUpdatesBlocker blocker(this); | ||
1767 | resizeWithChecks(ns, xcb_gravity_t(gravity)); | 1774 | resizeWithChecks(ns, xcb_gravity_t(gravity)); | ||
1768 | if (!from_tool && (!isSpecialWindow() || isToolbar()) && !isFullScreen()) { | 1775 | if (!from_tool && (!isSpecialWindow() || isToolbar()) && !isFullScreen()) { | ||
1769 | // try to keep the window in its xinerama screen if possible, | 1776 | // try to keep the window in its xinerama screen if possible, | ||
1770 | // if that fails at least keep it visible somewhere | 1777 | // if that fails at least keep it visible somewhere | ||
1771 | QRect area = workspace()->clientArea(MovementArea, this); | 1778 | QRect area = workspace()->clientArea(MovementArea, this); | ||
1772 | if (area.contains(origClientGeometry)) | 1779 | if (area.contains(origClientGeometry)) | ||
1773 | keepInArea(area); | 1780 | keepInArea(area); | ||
▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Line(s) | 1935 | { | |||
1933 | // from adjustedSize(). Such geometry comes here, and if the window is shaded, | 1940 | // from adjustedSize(). Such geometry comes here, and if the window is shaded, | ||
1934 | // the geometry is used only for client_size, since that one is not used when | 1941 | // the geometry is used only for client_size, since that one is not used when | ||
1935 | // shading. Then the frame geometry is adjusted for the shaded geometry. | 1942 | // shading. Then the frame geometry is adjusted for the shaded geometry. | ||
1936 | // This gets more complicated in the case the code does only something like | 1943 | // This gets more complicated in the case the code does only something like | ||
1937 | // setGeometry( geometry()) - geometry() will return the shaded frame geometry. | 1944 | // setGeometry( geometry()) - geometry() will return the shaded frame geometry. | ||
1938 | // Such code is wrong and should be changed to handle the case when the window is shaded, | 1945 | // Such code is wrong and should be changed to handle the case when the window is shaded, | ||
1939 | // for example using X11Client::clientSize() | 1946 | // for example using X11Client::clientSize() | ||
1940 | 1947 | | |||
1948 | QRect frameGeometry(x, y, w, h); | ||||
1949 | QRect bufferGeometry; | ||||
1950 | | ||||
1941 | if (shade_geometry_change) | 1951 | if (shade_geometry_change) | ||
1942 | ; // nothing | 1952 | ; // nothing | ||
1943 | else if (isShade()) { | 1953 | else if (isShade()) { | ||
1944 | if (h == borderTop() + borderBottom()) { | 1954 | if (frameGeometry.height() == borderTop() + borderBottom()) { | ||
1945 | qCDebug(KWIN_CORE) << "Shaded geometry passed for size:"; | 1955 | qCDebug(KWIN_CORE) << "Shaded geometry passed for size:"; | ||
1946 | } else { | 1956 | } else { | ||
1947 | client_size = QSize(w - borderLeft() - borderRight(), h - borderTop() - borderBottom()); | 1957 | m_clientGeometry = frameRectToClientRect(frameGeometry); | ||
1948 | h = borderTop() + borderBottom(); | 1958 | frameGeometry.setHeight(borderTop() + borderBottom()); | ||
1959 | } | ||||
1960 | } else { | ||||
1961 | m_clientGeometry = frameRectToClientRect(frameGeometry); | ||||
1949 | } | 1962 | } | ||
1963 | if (isDecorated()) { | ||||
1964 | bufferGeometry = frameGeometry; | ||||
1950 | } else { | 1965 | } else { | ||
1951 | client_size = QSize(w - borderLeft() - borderRight(), h - borderTop() - borderBottom()); | 1966 | bufferGeometry = m_clientGeometry; | ||
1952 | } | 1967 | } | ||
1953 | QRect g(x, y, w, h); | 1968 | if (!areGeometryUpdatesBlocked() && frameGeometry != rules()->checkGeometry(frameGeometry)) { | ||
1954 | if (!areGeometryUpdatesBlocked() && g != rules()->checkGeometry(g)) { | 1969 | qCDebug(KWIN_CORE) << "forced geometry fail:" << frameGeometry << ":" << rules()->checkGeometry(frameGeometry); | ||
1955 | qCDebug(KWIN_CORE) << "forced geometry fail:" << g << ":" << rules()->checkGeometry(g); | | |||
1956 | } | 1970 | } | ||
1957 | if (force == NormalGeometrySet && geom == g && pendingGeometryUpdate() == PendingGeometryNone) | 1971 | if (!canUpdateGeometry(frameGeometry, bufferGeometry, force)) { | ||
1958 | return; | 1972 | return; | ||
1959 | geom = g; | 1973 | } | ||
1974 | m_bufferGeometry = bufferGeometry; | ||||
1975 | geom = frameGeometry; | ||||
1960 | if (areGeometryUpdatesBlocked()) { | 1976 | if (areGeometryUpdatesBlocked()) { | ||
1961 | if (pendingGeometryUpdate() == PendingGeometryForced) | 1977 | if (pendingGeometryUpdate() == PendingGeometryForced) | ||
1962 | {} // maximum, nothing needed | 1978 | {} // maximum, nothing needed | ||
1963 | else if (force == ForceGeometrySet) | 1979 | else if (force == ForceGeometrySet) | ||
1964 | setPendingGeometryUpdate(PendingGeometryForced); | 1980 | setPendingGeometryUpdate(PendingGeometryForced); | ||
1965 | else | 1981 | else | ||
1966 | setPendingGeometryUpdate(PendingGeometryNormal); | 1982 | setPendingGeometryUpdate(PendingGeometryNormal); | ||
1967 | return; | 1983 | return; | ||
1968 | } | 1984 | } | ||
1969 | QSize oldClientSize = m_frame.geometry().size(); | 1985 | const QRect oldBufferGeometry = bufferGeometryBeforeUpdateBlocking(); | ||
1970 | bool resized = (frameGeometryBeforeUpdateBlocking().size() != geom.size() || pendingGeometryUpdate() == PendingGeometryForced); | 1986 | bool resized = (oldBufferGeometry.size() != m_bufferGeometry.size() || pendingGeometryUpdate() == PendingGeometryForced); | ||
1971 | if (resized) { | 1987 | if (resized) { | ||
1972 | resizeDecoration(); | 1988 | resizeDecoration(); | ||
1973 | m_frame.setGeometry(x, y, w, h); | 1989 | m_frame.setGeometry(m_bufferGeometry); | ||
1974 | if (!isShade()) { | 1990 | if (!isShade()) { | ||
1975 | QSize cs = clientSize(); | 1991 | QSize cs = clientSize(); | ||
1976 | m_wrapper.setGeometry(QRect(clientPos(), cs)); | 1992 | m_wrapper.setGeometry(QRect(clientPos(), cs)); | ||
1977 | if (!isResize() || syncRequest.counter == XCB_NONE) | 1993 | if (!isResize() || syncRequest.counter == XCB_NONE) | ||
1978 | m_client.setGeometry(0, 0, cs.width(), cs.height()); | 1994 | m_client.setGeometry(0, 0, cs.width(), cs.height()); | ||
1979 | // SELI - won't this be too expensive? | 1995 | // SELI - won't this be too expensive? | ||
1980 | // THOMAS - yes, but gtk+ clients will not resize without ... | 1996 | // THOMAS - yes, but gtk+ clients will not resize without ... | ||
1981 | sendSyntheticConfigureNotify(); | 1997 | sendSyntheticConfigureNotify(); | ||
1982 | } | 1998 | } | ||
1983 | updateShape(); | 1999 | updateShape(); | ||
1984 | } else { | 2000 | } else { | ||
1985 | if (isMoveResize()) { | 2001 | if (isMoveResize()) { | ||
1986 | if (compositing()) // Defer the X update until we leave this mode | 2002 | if (compositing()) // Defer the X update until we leave this mode | ||
1987 | needsXWindowMove = true; | 2003 | needsXWindowMove = true; | ||
1988 | else | 2004 | else | ||
1989 | m_frame.move(x, y); // sendSyntheticConfigureNotify() on finish shall be sufficient | 2005 | m_frame.move(m_bufferGeometry.topLeft()); // sendSyntheticConfigureNotify() on finish shall be sufficient | ||
1990 | } else { | 2006 | } else { | ||
1991 | m_frame.move(x, y); | 2007 | m_frame.move(m_bufferGeometry.topLeft()); | ||
1992 | sendSyntheticConfigureNotify(); | 2008 | sendSyntheticConfigureNotify(); | ||
1993 | } | 2009 | } | ||
1994 | 2010 | | |||
1995 | // Unconditionally move the input window: it won't affect rendering | 2011 | // Unconditionally move the input window: it won't affect rendering | ||
1996 | m_decoInputExtent.move(QPoint(x, y) + inputPos()); | 2012 | m_decoInputExtent.move(QPoint(x, y) + inputPos()); | ||
1997 | } | 2013 | } | ||
1998 | updateWindowRules(Rules::Position|Rules::Size); | 2014 | updateWindowRules(Rules::Position|Rules::Size); | ||
1999 | 2015 | | |||
2000 | // keep track of old maximize mode | 2016 | // keep track of old maximize mode | ||
2001 | // to detect changes | 2017 | // to detect changes | ||
2002 | screens()->setCurrent(this); | 2018 | screens()->setCurrent(this); | ||
2003 | workspace()->updateStackingOrder(); | 2019 | workspace()->updateStackingOrder(); | ||
2004 | 2020 | | |||
2005 | // need to regenerate decoration pixmaps when | 2021 | // Need to regenerate decoration pixmaps when the buffer size is changed. | ||
2006 | // - size is changed | 2022 | if (oldBufferGeometry.size() != m_bufferGeometry.size()) { | ||
2007 | if (resized) { | | |||
2008 | if (oldClientSize != QSize(w,h)) | | |||
2009 | discardWindowPixmap(); | 2023 | discardWindowPixmap(); | ||
2010 | } | 2024 | } | ||
2011 | emit geometryShapeChanged(this, frameGeometryBeforeUpdateBlocking()); | 2025 | emit geometryShapeChanged(this, frameGeometryBeforeUpdateBlocking()); | ||
2012 | addRepaintDuringGeometryUpdates(); | 2026 | addRepaintDuringGeometryUpdates(); | ||
2013 | updateGeometryBeforeUpdateBlocking(); | 2027 | updateGeometryBeforeUpdateBlocking(); | ||
2014 | // TODO: this signal is emitted too often | 2028 | // TODO: this signal is emitted too often | ||
2015 | emit geometryChanged(); | 2029 | emit geometryChanged(); | ||
2016 | } | 2030 | } | ||
2017 | 2031 | | |||
2018 | void X11Client::plainResize(int w, int h, ForceGeometry_t force) | 2032 | void X11Client::plainResize(int w, int h, ForceGeometry_t force) | ||
2019 | { | 2033 | { | ||
2034 | QSize frameSize(w, h); | ||||
2035 | QSize bufferSize; | ||||
2036 | | ||||
2020 | // this code is also duplicated in X11Client::setGeometry(), and it's also commented there | 2037 | // this code is also duplicated in X11Client::setGeometry(), and it's also commented there | ||
2021 | if (shade_geometry_change) | 2038 | if (shade_geometry_change) | ||
2022 | ; // nothing | 2039 | ; // nothing | ||
2023 | else if (isShade()) { | 2040 | else if (isShade()) { | ||
2024 | if (h == borderTop() + borderBottom()) { | 2041 | if (frameSize.height() == borderTop() + borderBottom()) { | ||
2025 | qCDebug(KWIN_CORE) << "Shaded geometry passed for size:"; | 2042 | qCDebug(KWIN_CORE) << "Shaded geometry passed for size:"; | ||
2026 | } else { | 2043 | } else { | ||
2027 | client_size = QSize(w - borderLeft() - borderRight(), h - borderTop() - borderBottom()); | 2044 | m_clientGeometry.setSize(frameSizeToClientSize(frameSize)); | ||
2028 | h = borderTop() + borderBottom(); | 2045 | frameSize.setHeight(borderTop() + borderBottom()); | ||
2046 | } | ||||
2047 | } else { | ||||
2048 | m_clientGeometry.setSize(frameSizeToClientSize(frameSize)); | ||||
2029 | } | 2049 | } | ||
2050 | if (isDecorated()) { | ||||
2051 | bufferSize = frameSize; | ||||
2030 | } else { | 2052 | } else { | ||
2031 | client_size = QSize(w - borderLeft() - borderRight(), h - borderTop() - borderBottom()); | 2053 | bufferSize = m_clientGeometry.size(); | ||
2032 | } | 2054 | } | ||
2033 | QSize s(w, h); | 2055 | if (!areGeometryUpdatesBlocked() && frameSize != rules()->checkSize(frameSize)) { | ||
2034 | if (!areGeometryUpdatesBlocked() && s != rules()->checkSize(s)) { | 2056 | qCDebug(KWIN_CORE) << "forced size fail:" << frameSize << ":" << rules()->checkSize(frameSize); | ||
2035 | qCDebug(KWIN_CORE) << "forced size fail:" << s << ":" << rules()->checkSize(s); | | |||
2036 | } | 2057 | } | ||
2037 | // resuming geometry updates is handled only in setGeometry() | 2058 | // resuming geometry updates is handled only in setGeometry() | ||
2038 | Q_ASSERT(pendingGeometryUpdate() == PendingGeometryNone || areGeometryUpdatesBlocked()); | 2059 | Q_ASSERT(pendingGeometryUpdate() == PendingGeometryNone || areGeometryUpdatesBlocked()); | ||
2039 | if (force == NormalGeometrySet && geom.size() == s) | 2060 | if (!canUpdateSize(frameSize, bufferSize, force)) { | ||
2040 | return; | 2061 | return; | ||
2041 | geom.setSize(s); | 2062 | } | ||
2063 | m_bufferGeometry.setSize(bufferSize); | ||||
2064 | geom.setSize(frameSize); | ||||
2042 | if (areGeometryUpdatesBlocked()) { | 2065 | if (areGeometryUpdatesBlocked()) { | ||
2043 | if (pendingGeometryUpdate() == PendingGeometryForced) | 2066 | if (pendingGeometryUpdate() == PendingGeometryForced) | ||
2044 | {} // maximum, nothing needed | 2067 | {} // maximum, nothing needed | ||
2045 | else if (force == ForceGeometrySet) | 2068 | else if (force == ForceGeometrySet) | ||
2046 | setPendingGeometryUpdate(PendingGeometryForced); | 2069 | setPendingGeometryUpdate(PendingGeometryForced); | ||
2047 | else | 2070 | else | ||
2048 | setPendingGeometryUpdate(PendingGeometryNormal); | 2071 | setPendingGeometryUpdate(PendingGeometryNormal); | ||
2049 | return; | 2072 | return; | ||
2050 | } | 2073 | } | ||
2051 | QSize oldClientSize = m_frame.geometry().size(); | | |||
2052 | resizeDecoration(); | 2074 | resizeDecoration(); | ||
2053 | m_frame.resize(w, h); | 2075 | m_frame.resize(m_bufferGeometry.size()); | ||
2054 | // resizeDecoration( s ); | | |||
2055 | if (!isShade()) { | 2076 | if (!isShade()) { | ||
2056 | QSize cs = clientSize(); | 2077 | QSize cs = clientSize(); | ||
2057 | m_wrapper.setGeometry(QRect(clientPos(), cs)); | 2078 | m_wrapper.setGeometry(QRect(clientPos(), cs)); | ||
2058 | m_client.setGeometry(0, 0, cs.width(), cs.height()); | 2079 | m_client.setGeometry(0, 0, cs.width(), cs.height()); | ||
2059 | } | 2080 | } | ||
2060 | updateShape(); | 2081 | updateShape(); | ||
2061 | 2082 | | |||
2062 | sendSyntheticConfigureNotify(); | 2083 | sendSyntheticConfigureNotify(); | ||
2063 | updateWindowRules(Rules::Position|Rules::Size); | 2084 | updateWindowRules(Rules::Position|Rules::Size); | ||
2064 | screens()->setCurrent(this); | 2085 | screens()->setCurrent(this); | ||
2065 | workspace()->updateStackingOrder(); | 2086 | workspace()->updateStackingOrder(); | ||
2066 | if (oldClientSize != QSize(w,h)) | 2087 | if (bufferGeometryBeforeUpdateBlocking().size() != m_bufferGeometry.size()) { | ||
2067 | discardWindowPixmap(); | 2088 | discardWindowPixmap(); | ||
2089 | } | ||||
2068 | emit geometryShapeChanged(this, frameGeometryBeforeUpdateBlocking()); | 2090 | emit geometryShapeChanged(this, frameGeometryBeforeUpdateBlocking()); | ||
2069 | addRepaintDuringGeometryUpdates(); | 2091 | addRepaintDuringGeometryUpdates(); | ||
2070 | updateGeometryBeforeUpdateBlocking(); | 2092 | updateGeometryBeforeUpdateBlocking(); | ||
2071 | // TODO: this signal is emitted too often | 2093 | // TODO: this signal is emitted too often | ||
2072 | emit geometryChanged(); | 2094 | emit geometryChanged(); | ||
2073 | } | 2095 | } | ||
2074 | 2096 | | |||
2075 | /** | 2097 | /** | ||
Show All 24 Lines | 2101 | { | |||
2100 | screens()->setCurrent(this); | 2122 | screens()->setCurrent(this); | ||
2101 | workspace()->updateStackingOrder(); | 2123 | workspace()->updateStackingOrder(); | ||
2102 | // client itself is not damaged | 2124 | // client itself is not damaged | ||
2103 | addRepaintDuringGeometryUpdates(); | 2125 | addRepaintDuringGeometryUpdates(); | ||
2104 | updateGeometryBeforeUpdateBlocking(); | 2126 | updateGeometryBeforeUpdateBlocking(); | ||
2105 | emit geometryChanged(); | 2127 | emit geometryChanged(); | ||
2106 | } | 2128 | } | ||
2107 | 2129 | | |||
2108 | void X11Client::doMove(int x, int y) | | |||
2109 | { | | |||
2110 | m_frame.move(x, y); | | |||
2111 | sendSyntheticConfigureNotify(); | | |||
2112 | } | | |||
2113 | | ||||
2114 | void AbstractClient::blockGeometryUpdates(bool block) | 2130 | void AbstractClient::blockGeometryUpdates(bool block) | ||
2115 | { | 2131 | { | ||
2116 | if (block) { | 2132 | if (block) { | ||
2117 | if (m_blockGeometryUpdates == 0) | 2133 | if (m_blockGeometryUpdates == 0) | ||
2118 | m_pendingGeometryUpdate = PendingGeometryNone; | 2134 | m_pendingGeometryUpdate = PendingGeometryNone; | ||
2119 | ++m_blockGeometryUpdates; | 2135 | ++m_blockGeometryUpdates; | ||
2120 | } else { | 2136 | } else { | ||
2121 | if (--m_blockGeometryUpdates == 0) { | 2137 | if (--m_blockGeometryUpdates == 0) { | ||
▲ Show 20 Lines • Show All 530 Lines • ▼ Show 20 Line(s) | 2667 | // FRAME update(); | |||
2652 | 2668 | | |||
2653 | emit clientFinishUserMovedResized(this); | 2669 | emit clientFinishUserMovedResized(this); | ||
2654 | } | 2670 | } | ||
2655 | 2671 | | |||
2656 | void X11Client::leaveMoveResize() | 2672 | void X11Client::leaveMoveResize() | ||
2657 | { | 2673 | { | ||
2658 | if (needsXWindowMove) { | 2674 | if (needsXWindowMove) { | ||
2659 | // Do the deferred move | 2675 | // Do the deferred move | ||
2660 | m_frame.move(geom.topLeft()); | 2676 | m_frame.move(m_bufferGeometry.topLeft()); | ||
2661 | needsXWindowMove = false; | 2677 | needsXWindowMove = false; | ||
2662 | } | 2678 | } | ||
2663 | if (!isResize()) | 2679 | if (!isResize()) | ||
2664 | sendSyntheticConfigureNotify(); // tell the client about it's new final position | 2680 | sendSyntheticConfigureNotify(); // tell the client about it's new final position | ||
2665 | if (geometryTip) { | 2681 | if (geometryTip) { | ||
2666 | geometryTip->hide(); | 2682 | geometryTip->hide(); | ||
2667 | delete geometryTip; | 2683 | delete geometryTip; | ||
2668 | geometryTip = nullptr; | 2684 | geometryTip = nullptr; | ||
▲ Show 20 Lines • Show All 436 Lines • ▼ Show 20 Line(s) | 3116 | { | |||
3105 | } | 3121 | } | ||
3106 | if (syncRequest.counter != XCB_NONE) { | 3122 | if (syncRequest.counter != XCB_NONE) { | ||
3107 | syncRequest.timeout->start(250); | 3123 | syncRequest.timeout->start(250); | ||
3108 | sendSyncRequest(); | 3124 | sendSyncRequest(); | ||
3109 | } else { // for clients not supporting the XSYNC protocol, we | 3125 | } else { // for clients not supporting the XSYNC protocol, we | ||
3110 | syncRequest.isPending = true; // limit the resizes to 30Hz to take pointless load from X11 | 3126 | syncRequest.isPending = true; // limit the resizes to 30Hz to take pointless load from X11 | ||
3111 | syncRequest.timeout->start(33); // and the client, the mouse is still moved at full speed | 3127 | syncRequest.timeout->start(33); // and the client, the mouse is still moved at full speed | ||
3112 | } // and no human can control faster resizes anyway | 3128 | } // and no human can control faster resizes anyway | ||
3113 | const QRect &moveResizeGeom = moveResizeGeometry(); | 3129 | const QRect moveResizeClientGeometry = frameRectToClientRect(moveResizeGeometry()); | ||
3114 | m_client.setGeometry(0, 0, moveResizeGeom.width() - (borderLeft() + borderRight()), moveResizeGeom.height() - (borderTop() + borderBottom())); | 3130 | m_client.setGeometry(0, 0, moveResizeClientGeometry.width(), moveResizeClientGeometry.height()); | ||
3115 | } | 3131 | } | ||
3116 | 3132 | | |||
3117 | void AbstractClient::performMoveResize() | 3133 | void AbstractClient::performMoveResize() | ||
3118 | { | 3134 | { | ||
3119 | const QRect &moveResizeGeom = moveResizeGeometry(); | 3135 | const QRect &moveResizeGeom = moveResizeGeometry(); | ||
3120 | if (isMove() || (isResize() && !haveResizeEffect())) { | 3136 | if (isMove() || (isResize() && !haveResizeEffect())) { | ||
3121 | setFrameGeometry(moveResizeGeom); | 3137 | setFrameGeometry(moveResizeGeom); | ||
3122 | } | 3138 | } | ||
▲ Show 20 Lines • Show All 273 Lines • Show Last 20 Lines |