I created a frameless Window
in QML
and added multiple MouseArea
and event handlers for moving and resizing it.
Initially, I only created the moving area and part of the resizing areas as a sample.
However, when I started, I noticed that events were only triggered for 3 out of the 4 areas, and they appeared to be intersecting despite not overlapping.
The cursor also changed in the correct place.
This problem occurred on both Linux and Windows.
What could be the reason for the active zones of different MouseArea
intersecting, even though they should not?
To debug, I added a colored Rectangle
s for each MouseArea
and increased their sizes."
I have also uploaded a sample video on Google Drive.
import QtQuick 6.2
import QtQuick.Controls 6.2
Window {
id: win
width: 200
height: 100
flags: Qt.FramelessWindowHint | Qt.Window
property alias topPanel: topPanel
Rectangle {
anchors.fill: parent
color: "#610161"
Rectangle {
id: topPanel
z: 0
height: 30
color: "#4c4c4c"
border.width: 0
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: 0
anchors.leftMargin: 0
anchors.topMargin: 0
ActionButton {
id: close
width: 20
height: 20
anchors.right: parent.right
anchors.top: parent.top
z: 10
image: "icons/close.svg"
anchors.topMargin: 5
anchors.rightMargin: 5
backColor: "#00000000"
Connections {
function onClicked() {
win.close()
}
}
}
}
MouseArea {
id: moved
z: 2
Rectangle {
anchors.fill: parent
z: 32
color: "#6a30e4"
}
property real lastX: 0
property real lastY: 0
x: 35
y: 0
anchors.left: lt.right
anchors.right: topPanel.right
anchors.top: topPanel.top
anchors.bottom: topPanel.bottom
anchors.rightMargin: 0
anchors.bottomMargin: 0
anchors.topMargin: 0
anchors.leftMargin: 0
Connections {
target: moved
function onPressed(mouse) {
console.debug("Pressed move", mouse.x, mouse.y, "MOVED:",
moved.x, moved.y, "|", moved.width, "x",
moved.height)
moved.lastX = mouse.x
moved.lastY = mouse.y
mouse.accepted = true
}
function onPositionChanged(mouse) {
mouse.accepted = true
let dx = (mouse.x - moved.lastX)
let dy = (mouse.y - moved.lastY)
console.debug("move dx:", dx, " dy:", dy, " mouse:",
mouse.x, mouse.y, mouse.modifiers)
win.x += dx
win.y += dy
}
}
}
MouseArea {
id: lbord
z: 2
width: 5
anchors.top: lt.bottom
anchors.left: parent.left
anchors.bottom: lb.top
anchors.topMargin: 0
Rectangle {
color: "#43ca28"
anchors.fill: parent
z: 32
}
property real lastX: 0
property real lastY: 0
Connections {
target: lbord
function onPressed(mouse) {
console.debug("Pressed lbord")
lbord.lastX = mouse.x
}
function onPositionChanged(mouse) {
let dx = (mouse.x - lbord.lastX)
console.debug("lbord dx:", dx, " lastX:", lbord.lastX,
" mouse:", mouse.x, mouse.y)
win.x += dx
win.width -= dx
// lbord.lastX += dx
}
}
}
MouseArea {
id: lb
z: 2
width: 15
height: 15
anchors.left: parent.left
anchors.bottom: parent.bottom
Rectangle {
color: "#28cac7"
anchors.fill: parent
z: 32
}
property real lastX: 0
property real lastY: 0
Connections {
target: moved
function onPressed(mouse) {
console.debug("Pressed lb", mouse.x, mouse.y, "LB:", lb.x,
lb.y, "|", lb.width, "x", lb.height)
lb.lastX = mouse.x
lb.lastY = mouse.y
}
function onPositionChanged(mouse) {
let dx = (mouse.x - lb.lastX)
let dy = (mouse.y - lb.lastY)
console.debug("lb dx:", dx, " dy:", dy, " mouse:", mouse.x,
mouse.y, mouse.modifiers)
win.x += dx
win.y += dy
win.width -= dx
win.height += dy
}
}
}
MouseArea {
id: lt
z: 2
width: 35
height: 35
anchors.left: parent.left
anchors.top: parent.top
cursorShape: Qt.SizeFDiagCursor
Rectangle {
color: "#eb1892"
anchors.fill: parent
z: 32
}
property real lastX: 0
property real lastY: 0
Connections {
target: moved
function onPressed(mouse) {
console.debug("Pressed lt", mouse.x, mouse.y, "LT:", lt.x,
lt.y, "|", lt.width, "x", lt.height)
lt.lastX = mouse.x
lt.lastY = mouse.y
}
function onPositionChanged(mouse) {
let dx = (mouse.x - lt.lastX)
let dy = (mouse.y - lt.lastY)
console.debug("lt dx:", dx, " dy:", dy, " mouse:", mouse.x,
mouse.y, mouse.modifiers)
win.x += dx
win.y += dy
win.width -= dx
win.height -= dy
}
}
}
}
}
A video showing the bugs Google Drive
You signal handler function are triggered in 3 out of 4 of your Connections
objects because you assigned the same target
for 3 of them.
You don't even have to use Connections
since you are the one instantiating your MouseArea
:
MouseArea {
id: mouseArea
Connections {
target: mouseArea
function onPressed(mouse) { ... }
}
}
Is the equivalent of
MouseArea {
onPressed(mouse) { ... }
}
Also I would advise to use startSystemMove and startSystemResize.