diff --git a/effects/desktopgrid/desktopgrid.cpp b/effects/desktopgrid/desktopgrid.cpp index 759ecaf4ba..50b2cce7a1 100644 --- a/effects/desktopgrid/desktopgrid.cpp +++ b/effects/desktopgrid/desktopgrid.cpp @@ -278,8 +278,16 @@ void DesktopGridEffect::paintWindow(EffectWindow* w, int mask, QRegion region, W if (isUsingPresentWindows() && w == windowMove && wasWindowMove) { return; // will be painted on top of all other windows } - if (m_desktopButtonsViews.values().contains(w)) - return; // will be painted on top of all other windows + for (QHash< DesktopButtonsView*, EffectWindow*>::const_iterator it = m_desktopButtonsViews.constBegin(), + end = m_desktopButtonsViews.constEnd(); + it != end; ++it) { + if (it.value() == w) { + if (!activated && timeline.currentValue() < 0.05) { + it.key()->hide(); + } + return; // will be painted on top of all other windows + } + } qreal xScale = data.xScale(); qreal yScale = data.yScale(); @@ -416,13 +424,6 @@ void DesktopGridEffect::slotWindowClosed(EffectWindow* w) } } } - for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin(); - it != m_desktopButtonsViews.end(); ++it) { - if (it.value() && it.value() == w) { - w->refWindow(); - break; - } - } effects->addRepaintFull(); } @@ -433,8 +434,7 @@ void DesktopGridEffect::slotWindowDeleted(EffectWindow* w) for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin(); it != m_desktopButtonsViews.end(); ++it) { if (it.value() && it.value() == w) { - it.key()->deleteLater(); - m_desktopButtonsViews.erase(it); + it.value() = nullptr; break; } } @@ -1053,10 +1053,6 @@ void DesktopGridEffect::setActive(bool active) } } setHighlightedDesktop(effects->currentDesktop()); // Ensure selected desktop is highlighted - for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin(); - it != m_desktopButtonsViews.end(); ++it) { - it.key()->hide(); - } } effects->addRepaintFull(); } @@ -1134,14 +1130,12 @@ void DesktopGridEffect::setup() view->setAddDesktopEnabled(enableAdd); view->setRemoveDesktopEnabled(enableRemove); const QRect screenRect = effects->clientArea(FullScreenArea, i, 1); + view->show(); // pseudo show must happen before geometry changes view->setGeometry(screenRect.right() + 1 - view->width(), screenRect.bottom() + 1 - view->height(), view->width(), view->height()); - view->show(); } while (it != m_desktopButtonsViews.end()) { - if (*it && (*it)->isDeleted()) - (*it)->unrefWindow(); DesktopButtonsView *view = it.key(); it = m_desktopButtonsViews.erase(it); view->deleteLater(); @@ -1402,6 +1396,8 @@ bool DesktopGridEffect::isRelevantWithPresentWindows(EffectWindow *w) const ************************************************/ DesktopButtonsView::DesktopButtonsView(QWindow *parent) : QQuickView(parent) + , m_visible(false) + , m_posIsValid(false) { setFlags(Qt::X11BypassWindowManagerHint); setColor(Qt::transparent); @@ -1440,6 +1436,31 @@ void DesktopButtonsView::setRemoveDesktopEnabled(bool enable) rootContext()->setContextProperty(QStringLiteral("remove"), QVariant(enable)); } +bool DesktopButtonsView::isVisible() const +{ + return m_visible; +} + +void DesktopButtonsView::show() +{ + if (!m_visible && m_posIsValid) { + setPosition(m_pos); + m_posIsValid = false; + } + m_visible = true; + QQuickView::show(); +} + +void DesktopButtonsView::hide() +{ + if (!m_posIsValid) { + m_pos = position(); + m_posIsValid = true; + setPosition(-width(), -height()); + } + m_visible = false; +} + } // namespace #include "desktopgrid.moc" diff --git a/effects/desktopgrid/desktopgrid.h b/effects/desktopgrid/desktopgrid.h index 9c31b6729e..5a4e17437b 100644 --- a/effects/desktopgrid/desktopgrid.h +++ b/effects/desktopgrid/desktopgrid.h @@ -40,9 +40,16 @@ public: void windowInputMouseEvent(QMouseEvent* e); void setAddDesktopEnabled(bool enable); void setRemoveDesktopEnabled(bool enable); + bool isVisible() const; + void show(); + void hide(); Q_SIGNALS: void addDesktop(); void removeDesktop(); +private: + bool m_visible; + QPoint m_pos; + bool m_posIsValid; }; class DesktopGridEffect diff --git a/geometry.cpp b/geometry.cpp index c460da2632..7c3277bebc 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -1926,6 +1926,7 @@ void Client::setGeometry(int x, int y, int w, int h, ForceGeometry_t force) pending_geometry_update = PendingGeometryNormal; return; } + QSize oldClientSize = m_frame.geometry().size(); bool resized = (geom_before_block.size() != geom.size() || pending_geometry_update == PendingGeometryForced); if (resized) { resizeDecoration(); @@ -1966,7 +1967,8 @@ void Client::setGeometry(int x, int y, int w, int h, ForceGeometry_t force) // - maximize mode is changed to MaximizeRestore, when size unchanged // which can happen when untabbing maximized windows if (resized) { - discardWindowPixmap(); + if (oldClientSize != QSize(w,h)) + discardWindowPixmap(); emit geometryShapeChanged(this, geom_before_block); } const QRect deco_rect = visibleRect(); @@ -2016,6 +2018,7 @@ void Client::plainResize(int w, int h, ForceGeometry_t force) pending_geometry_update = PendingGeometryNormal; return; } + QSize oldClientSize = m_frame.geometry().size(); resizeDecoration(); m_frame.resize(w, h); // resizeDecoration( s ); @@ -2030,7 +2033,8 @@ void Client::plainResize(int w, int h, ForceGeometry_t force) updateWindowRules(Rules::Position|Rules::Size); screens()->setCurrent(this); workspace()->updateStackingOrder(); - discardWindowPixmap(); + if (oldClientSize != QSize(w,h)) + discardWindowPixmap(); emit geometryShapeChanged(this, geom_before_block); const QRect deco_rect = visibleRect(); addLayerRepaint(deco_rect_before_block); @@ -2366,6 +2370,35 @@ void Client::changeMaximize(bool vertical, bool horizontal, bool adjust) r.moveRight(qMin(clientArea.right(), r.right())); } else { r.moveCenter(clientArea.center()); + const bool closeHeight = r.height() > 97*clientArea.height()/100; + const bool closeWidth = r.width() > 97*clientArea.width() /100; + const bool overHeight = r.height() > clientArea.height(); + const bool overWidth = r.width() > clientArea.width(); + if (closeWidth || closeHeight) { + Position titlePos = titlebarPosition(); + const QRect screenArea = workspace()->clientArea(ScreenArea, clientArea.center(), desktop()); + if (closeHeight) { + bool tryBottom = titlePos == PositionBottom; + if ((overHeight && titlePos == PositionTop) || + screenArea.top() == clientArea.top()) + r.setTop(clientArea.top()); + else + tryBottom = true; + if (tryBottom && + (overHeight || screenArea.bottom() == clientArea.bottom())) + r.setBottom(clientArea.bottom()); + } + if (closeWidth) { + bool tryLeft = titlePos == PositionLeft; + if ((overWidth && titlePos == PositionRight) || + screenArea.right() == clientArea.right()) + r.setRight(clientArea.right()); + else + tryLeft = true; + if (tryLeft && (overWidth || screenArea.left() == clientArea.left())) + r.setLeft(clientArea.left()); + } + } } r.moveTopLeft(rules()->checkPosition(r.topLeft())); } diff --git a/xcbutils.h b/xcbutils.h index 78ce467201..9f9f35d165 100644 --- a/xcbutils.h +++ b/xcbutils.h @@ -1385,6 +1385,7 @@ public: * Configures the window with a new geometry. * @param geometry The new window geometry to be used **/ + inline const QRect &geometry() const { return m_logicGeometry; } void setGeometry(const QRect &geometry); void setGeometry(uint32_t x, uint32_t y, uint32_t width, uint32_t height); void move(const QPoint &pos); @@ -1419,6 +1420,7 @@ public: void kill(); operator xcb_window_t() const; private: + QRect m_logicGeometry; xcb_window_t doCreate(const QRect &geometry, uint16_t windowClass, uint32_t mask = 0, const uint32_t *values = NULL, xcb_window_t parent = rootWindow()); void destroy(); xcb_window_t m_window; @@ -1490,6 +1492,7 @@ void Window::create(const QRect &geometry, uint32_t mask, const uint32_t *values inline xcb_window_t Window::doCreate(const QRect &geometry, uint16_t windowClass, uint32_t mask, const uint32_t *values, xcb_window_t parent) { + m_logicGeometry = geometry; xcb_window_t w = xcb_generate_id(connection()); xcb_create_window(connection(), XCB_COPY_FROM_PARENT, w, parent, geometry.x(), geometry.y(), geometry.width(), geometry.height(), @@ -1514,6 +1517,7 @@ void Window::setGeometry(const QRect &geometry) inline void Window::setGeometry(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { + m_logicGeometry.setRect(x, y, width, height); if (!isValid()) { return; } @@ -1531,6 +1535,7 @@ void Window::move(const QPoint &pos) inline void Window::move(uint32_t x, uint32_t y) { + m_logicGeometry.moveTo(x, y); if (!isValid()) { return; } @@ -1546,6 +1551,7 @@ void Window::resize(const QSize &size) inline void Window::resize(uint32_t width, uint32_t height) { + m_logicGeometry.setSize(QSize(width, height)); if (!isValid()) { return; }