Well, 2 years after and no answers before... I will tell my whole history so nobody tries the same things that we did and loose time. Go below the line (a bit under the image) to skip that.
We had the same problem, even bigger, because we designed all our system with the phrase you said,
even if is supposedly backwards compatible with mouse input
in mind, time after we saw we were in trouble.
After thinking how we could solve the problem we first tried a recursive function to search all mouseareas, and for each touch point, generate a fake mouse event with the flag Qt.MouseEventSynthesizedByApplication active, and the mousearea might be suposed to process that event, and trigger the corresponding callbacks.
Here I put an image of the failed code, so people in a hurry don't copy it... It is unfinished and we still had problens figuring out how to handle multiple touches.

It seems that when you have more than one touch in the mousearea, there is no behaviour coded for that scenario, wich, makes sense because you should only have one mouse in the system.
Then we searched in web, and found a deleted post of 2009 in webarchive of qt forum of someone with a similar issue, and posted a weird code (that doesn't work on qt5) to trick the mousearea to accept those events. That gave us the idea of generating ourselfes the event that should occur, and call the signal from the corresponding mousearea with the fake mouse event.
That worked except for the pressed(MouseEvent mouse) signal, wich couldnt be triggered. It gave errors.
After that, we tried to make public the signals (by explicit declaration on the mousearea)
property var toques = []
visible: false
property var pressed
onPressed: pressed = true
onReleased: pressed = false
That got us a step closer, but it will require the implementation of each mouse event, and furthermore, thre is an intermitency between all touches (since we may trigger each signal for each touch) and behaviur may be undefined. Also the fact that no order in the touches to keep track of what happend, made us reject the mousearea for this porpuse.
Then what we did is to use MutiPointTouchArea to handle the events. We saw that using multiple MultiPointTouchArea(s) does not give errors, and can handle multiple clicks (from touches) for the applicattion.
The things you'll have to do is to replace MouseAreas with the Multitouch ones, and implement yourself all the behavoiurs you want, concepts like hover doesn't make sense in this context, since we are handling touches. you may use pressure for doing something similar. We put the component Rectangle to keep the variables/signals of our interest, and to be changed from the MultiTouchArea when certain actions occur. Here I will implement your trivial example based on that idea:
Window {
id: main
visible: true
width: 600
height: 300
Row {
Rectangle {
width: main.width * .5
height: main.height
property var lol: false
color: ispressed ? "blue" : "black"
MultiPointTouchArea {
id: m1
anchors.fill: parent
onPressed: parent.ispressed= true
onReleased: parent.ispressed= false
}
}
Rectangle {
width: main.width * .5
height: main.height
x:main.width * .5
property var ispressed: false
color: ispressed ? "red" : "black"
MultiPointTouchArea {
id: m2
anchors.fill: parent
onPressed: parent.ispressed= true
onReleased: parent.ispressed= false
}
}
}
}
As you see is the Rectangle (your button or whatever) the one that has the properties that matter, in this case ispressed and it gets changed by the child (MultipointToucArea) according to our defined behavoiur, in this case activate when its pressed, and release when it releases, note that in this case, the color goes off only by pulling one finger, because onReleased is triggered.
You may have to decide which is the correct behavoiur for you application in each case. The signals given for programming this were more than enough in our case:
canceled(list<TouchPoint> touchPoints)
gestureStarted(GestureEvent gesture)
pressed(list<TouchPoint> touchPoints)
released(list<TouchPoint> touchPoints)
touchUpdated(list<TouchPoint> touchPoints)
updated(list<TouchPoint> touchPoints)
Also you may see that the pressed only occur in the first area thet is touched, so if you keep holding the finger accross others mouseareas, those won't get the pressed event triggered, so playing with updated() you might be able to get wheter it should activate things or not.
This is the solution we got, and worked for us, we couldn't figure anything better and for clicks/pressing events, this makes the trick.
Hope it helps.