PAYATHON 2026

macOS 上 QML 的 startSystemResize 为什么始终返回 false?

数据小陈

结论

在 macOS 上,QWindow::startSystemResize() 返回 false 是 Qt 平台支持情况所致。Qt 文档说明,这个系统缩放接口支持 Wayland、X11 和 Windows,不支持 macOS。返回 false 表示当前平台没有接管系统缩放操作,因此问题通常与 Qt.LeftEdge、20 像素边距或 DragHandler 本身无关。Qt:Custom client-side window decorations in Qt 5.15 QWindow::startSystemResize() 文档

问题中的代码会在拖动激活时调用 mainWindow.startSystemResize(Qt.LeftEdge),然后检查返回值。这个检查可以用来判断系统缩放是否可用;如果不可用,就改由应用自行调整窗口几何尺寸。

在 macOS 上手动调整窗口尺寸

拖动左边缘时,可以根据拖动距离调整窗口的 x 和 width。左边缘向右移动,窗口就会变窄,左上角的 x 也会增大,而右边缘保持不动。下面的处理器只处理左边缘拖动,并用 minimumWidth 限制最小宽度:

DragHandler {
    id: leftResizeHandler
    target: null

    property real startX: 0
    property real startWidth: 0
    property bool manualResize: false

    onActiveChanged: {
        if (active) {
            startX = mainWindow.x
            startWidth = mainWindow.width
            manualResize = !mainWindow.startSystemResize(Qt.LeftEdge)
        }
    }

    onTranslationChanged: {
        if (!active || !manualResize)
            return

        var newWidth = Math.max(
            mainWindow.minimumWidth,
            startWidth - translation.x
        )

        mainWindow.width = newWidth
        mainWindow.x = startX + (startWidth - newWidth)
    }
}

要支持右侧边缘,可以用相应的 MouseArea 和 DragHandler:保持窗口的 x 不变,并将新宽度设为 Math.max(mainWindow.minimumWidth, startWidth + translation.x)。拖动角落时,需要同时调整宽度和高度,并根据拖动的角更新 x、y。

实现时注意

  • 上面的示例假设窗口可以通过 x、width 调整位置和尺寸,且已根据应用需要设置 minimumWidth。如果需要限制高度,也应设置并检查 minimumHeight。
  • DragHandler 会以激活时的窗口位置和尺寸为基准,因此用 translation 计算相对变化。如果窗口还有其他拖动处理器,也要检查它们是否与边缘缩放区域冲突。
  • 如果这段逻辑也用于支持系统缩放的平台,只在 startSystemResize() 返回 false 时执行手动调整,避免系统缩放和应用逻辑同时改变窗口尺寸。

备注:内容仅供参考。