From adb7821bcbd4c8bbfc67ed54372ad636e433ac08 Mon Sep 17 00:00:00 2001 From: deepin-wm Date: Thu, 18 Jun 2026 21:19:03 +0800 Subject: [PATCH] fix(workspace): prevent dock covering titlebar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Compute effectiveZone as max(exclusiveZone, surfaceDimension + margin) in arrangeLayerSurface() to ensure exclusive zone covers actual layer surface size including margins 2. Add layerSizeChanged detection in arrangeLayerSurfaces() to trigger arrangeNonLayerSurfaces() when layer surface dimensions change even if exclusive zone value stays the same 3. Use pixel-level comparison (qAbs > 0.5) for floating-point size difference checks to avoid missed updates from floating-point drift Log: Fixed dock overlapping window titlebar by ensuring exclusive zone covers actual surface dimensions and triggering re-layout on size changes Influence: 1. Test dock height changes with maximized and normal windows 2. Verify windows are pushed aside when dock grows larger 3. Test dock on all four screen edges (top, bottom, left, right) 4. Verify dock with margins set via layer-shell protocol fix(workspace): 防止dock遮挡窗口标题栏 1. 在arrangeLayerSurface()中计算effectiveZone为 max(exclusiveZone, surfaceDimension + margin), 确保独占区域覆盖包含边距的实际 layer surface尺寸 2. 在arrangeLayerSurfaces()中增加layerSizeChanged 检测,当layer surface尺寸变化但exclusive zone 值未变时也触发arrangeNonLayerSurfaces()重排 3. 浮点数尺寸比较使用像素级阈值(qAbs > 0.5), 避免浮点漂移导致更新遗漏 Log: 修复dock遮挡窗口标题栏问题,确保独占区域覆盖 实际surface尺寸并在尺寸变化时触发重排 Influence: 1. 测试dock高度变化时最大化窗口和普通窗口的行为 2. 验证dock增大时窗口被正确推移 3. 测试dock在屏幕四个边(上、下、左、右)的表现 4. 验证通过layer-shell协议设置边距的dock行为 PMS: BUG-344911 --- src/output/output.cpp | 48 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/output/output.cpp b/src/output/output.cpp index bf1be4f4b..802c6badc 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -595,20 +595,40 @@ void Output::arrangeLayerSurface(SurfaceWrapper *surface) } if (layer->exclusiveZone() > 0) { - // TODO: support set_exclusive_edge in layer-shell v5/wlroots 0.19 + int effectiveZone = layer->exclusiveZone(); switch (layer->getExclusiveZoneEdge()) { using enum WLayerSurface::AnchorType; case Top: - setExclusiveZone(Qt::TopEdge, layer, layer->exclusiveZone()); + effectiveZone = qMax(effectiveZone, static_cast(surfaceGeo.height()) + layer->topMargin()); break; case Bottom: - setExclusiveZone(Qt::BottomEdge, layer, layer->exclusiveZone()); + effectiveZone = qMax(effectiveZone, static_cast(surfaceGeo.height()) + layer->bottomMargin()); break; case Left: - setExclusiveZone(Qt::LeftEdge, layer, layer->exclusiveZone()); + effectiveZone = qMax(effectiveZone, static_cast(surfaceGeo.width()) + layer->leftMargin()); break; case Right: - setExclusiveZone(Qt::RightEdge, layer, layer->exclusiveZone()); + effectiveZone = qMax(effectiveZone, static_cast(surfaceGeo.width()) + layer->rightMargin()); + break; + default: + break; + } + // When desiredSize is 0 in the relevant dimension, surfaceGeo will be 0 + // there, so qMax falls back to the original exclusiveZone value. + // exclusiveZone == -1 (overlay mode) is excluded by the > 0 check above. + switch (layer->getExclusiveZoneEdge()) { + using enum WLayerSurface::AnchorType; + case Top: + setExclusiveZone(Qt::TopEdge, layer, effectiveZone); + break; + case Bottom: + setExclusiveZone(Qt::BottomEdge, layer, effectiveZone); + break; + case Left: + setExclusiveZone(Qt::LeftEdge, layer, effectiveZone); + break; + case Right: + setExclusiveZone(Qt::RightEdge, layer, effectiveZone); break; default: qCWarning(lcTlOutput) << layer->appId() @@ -624,10 +644,12 @@ void Output::arrangeLayerSurface(SurfaceWrapper *surface) void Output::arrangeLayerSurfaces() { auto oldExclusiveZone = m_exclusiveZone; + QHash oldSizes; for (auto *s : std::as_const(surfaces())) { if (s->type() != SurfaceWrapper::Type::Layer) continue; + oldSizes.insert(s, s->size()); removeExclusiveZone(s->shellSurface()); } @@ -651,9 +673,21 @@ void Output::arrangeLayerSurfaces() arrangeLayerSurface(s); } - if (oldExclusiveZone != m_exclusiveZone) { + bool layerSizeChanged = false; + for (auto it = oldSizes.constBegin(); it != oldSizes.constEnd(); ++it) { + auto newSize = it.key()->size(); + auto oldSize = it.value(); + if (qAbs(newSize.width() - oldSize.width()) > 0.5 + || qAbs(newSize.height() - oldSize.height()) > 0.5) { + layerSizeChanged = true; + break; + } + } + + if (oldExclusiveZone != m_exclusiveZone || layerSizeChanged) { arrangeNonLayerSurfaces(); - Q_EMIT exclusiveZoneChanged(); + if (oldExclusiveZone != m_exclusiveZone) + Q_EMIT exclusiveZoneChanged(); } }