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时执行手动调整,避免系统缩放和应用逻辑同时改变窗口尺寸。
备注:内容仅供参考。
