mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 11:28:07 +00:00
Fix Contact edit on messing mouse focus (regression from Qt 5.15.12)
This commit is contained in:
parent
4532e278ac
commit
669f47858b
4 changed files with 226 additions and 204 deletions
|
|
@ -16,7 +16,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Mute option for each chatrooms.
|
||||
- New Chat Layout.
|
||||
|
||||
## 5.0.11 - undefined
|
||||
|
||||
## 5.0.12 - undefined
|
||||
|
||||
## Fixed
|
||||
- Unusable Contact sheet.
|
||||
|
||||
## 5.0.11 - 2023-02-24
|
||||
|
||||
### Fixed
|
||||
- Display of non-Ascii avatar
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ function addValue (value) {
|
|||
}
|
||||
|
||||
function handleEditionFinished (index, text) {
|
||||
if(index<0) return
|
||||
var model = values.model
|
||||
var oldValue = model.get(index).$value
|
||||
|
||||
|
|
|
|||
|
|
@ -8,104 +8,117 @@ import Common.Styles 1.0
|
|||
// =============================================================================
|
||||
|
||||
Item {
|
||||
property alias color: textInput.color
|
||||
property alias font: textInput.font
|
||||
property alias inputMethodHints: textInput.inputMethodHints
|
||||
property alias placeholder: placeholder.text
|
||||
property alias readOnly: textInput.readOnly
|
||||
property alias text: textInput.text
|
||||
property bool forceFocus: false
|
||||
property bool isInvalid: false
|
||||
property int padding: TransparentTextInputStyle.padding
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
signal editingFinished
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
textInput.focus = true
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
|
||||
color: (textInput.activeFocus || parent.forceFocus) && !textInput.readOnly
|
||||
? TransparentTextInputStyle.backgroundColor.color
|
||||
: // No Style constant, see component name.
|
||||
// It's a `transparent` TextInput.
|
||||
'transparent'
|
||||
height: parent.height
|
||||
width: {
|
||||
var width = textInput.contentWidth + parent.padding * 2
|
||||
return width < parent.width ? width : parent.width
|
||||
}
|
||||
|
||||
InvertedMouseArea {
|
||||
anchors.fill: parent
|
||||
enabled: textInput.activeFocus
|
||||
|
||||
onPressed: textInput.focus = false
|
||||
}
|
||||
}
|
||||
|
||||
Icon {
|
||||
id: icon
|
||||
|
||||
anchors.left: background.right
|
||||
height: background.height
|
||||
icon: 'generic_error'
|
||||
iconSize: TransparentTextInputStyle.iconSize
|
||||
visible: parent.isInvalid
|
||||
}
|
||||
|
||||
Text {
|
||||
id: placeholder
|
||||
|
||||
anchors.centerIn: parent
|
||||
color: TransparentTextInputStyle.placeholder.colorModel.color
|
||||
elide: Text.ElideRight
|
||||
|
||||
font {
|
||||
italic: true
|
||||
pointSize: TransparentTextInputStyle.placeholder.pointSize
|
||||
}
|
||||
|
||||
height: textInput.height
|
||||
width: textInput.width
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
visible: textInput.text.length === 0 && (!textInput.activeFocus || textInput.readOnly)
|
||||
}
|
||||
|
||||
TextInput {
|
||||
id: textInput
|
||||
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
width: parent.width - parent.padding * 2
|
||||
|
||||
clip: true
|
||||
color: activeFocus && !readOnly
|
||||
? TransparentTextInputStyle.text.color.focused.color
|
||||
: TransparentTextInputStyle.text.color.normal.color
|
||||
font.pointSize: TransparentTextInputStyle.text.pointSize
|
||||
selectByMouse: true
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
|
||||
Keys.onEscapePressed: focus = false
|
||||
Keys.onEnterPressed: focus = false
|
||||
Keys.onReturnPressed: focus = false
|
||||
|
||||
onEditingFinished: {
|
||||
cursorPosition = 0
|
||||
|
||||
if (!parent.readOnly) {
|
||||
parent.editingFinished()
|
||||
}
|
||||
}
|
||||
}
|
||||
property alias color: textInput.color
|
||||
property alias font: textInput.font
|
||||
property alias inputMethodHints: textInput.inputMethodHints
|
||||
property alias placeholder: placeholder.text
|
||||
property alias readOnly: textInput.readOnly
|
||||
property alias text: textInput.oldText
|
||||
property bool forceFocus: false
|
||||
property bool isInvalid: false
|
||||
property int padding: TransparentTextInputStyle.padding
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
signal editingFinished
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
textInput.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
property bool displayBackground: (textInput.activeFocus || parent.forceFocus) && !textInput.readOnly
|
||||
color: displayBackground
|
||||
? TransparentTextInputStyle.backgroundColor.color
|
||||
: // No Style constant, see component name.
|
||||
// It's a `transparent` TextInput.
|
||||
'transparent'
|
||||
height: parent.height
|
||||
width: {
|
||||
var width = textInput.contentWidth + parent.padding * 2
|
||||
return width < parent.width ? width : parent.width
|
||||
}
|
||||
|
||||
InvertedMouseArea {
|
||||
anchors.fill: parent
|
||||
enabled: textInput.activeFocus
|
||||
|
||||
onPressed: textInput.updateText()
|
||||
}
|
||||
}
|
||||
|
||||
Icon {
|
||||
id: icon
|
||||
|
||||
anchors.left: background.right
|
||||
height: background.height
|
||||
icon: 'generic_error'
|
||||
iconSize: TransparentTextInputStyle.iconSize
|
||||
visible: parent.isInvalid
|
||||
}
|
||||
|
||||
Text {
|
||||
id: placeholder
|
||||
|
||||
anchors.centerIn: parent
|
||||
color: TransparentTextInputStyle.placeholder.colorModel.color
|
||||
elide: Text.ElideRight
|
||||
|
||||
font {
|
||||
italic: true
|
||||
pointSize: TransparentTextInputStyle.placeholder.pointSize
|
||||
}
|
||||
|
||||
height: textInput.height
|
||||
width: textInput.width
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
visible: textInput.text.length === 0 && (!textInput.activeFocus || textInput.readOnly)
|
||||
}
|
||||
|
||||
TextInput {
|
||||
id: textInput
|
||||
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
width: parent.width - parent.padding * 2
|
||||
|
||||
clip: true
|
||||
color: activeFocus && !readOnly
|
||||
? TransparentTextInputStyle.text.color.focused.color
|
||||
: TransparentTextInputStyle.text.color.normal.color
|
||||
font.pointSize: TransparentTextInputStyle.text.pointSize
|
||||
selectByMouse: true
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
|
||||
Keys.onEscapePressed: cancelText()
|
||||
Keys.onEnterPressed: textInput.updateText()
|
||||
Keys.onReturnPressed: textInput.updateText()
|
||||
|
||||
property string oldText
|
||||
onOldTextChanged: if(text!=oldText) text = oldText
|
||||
function cancelText(){
|
||||
text = oldText
|
||||
focus = false
|
||||
}
|
||||
function updateText(){
|
||||
cursorPosition = 0
|
||||
oldText = text
|
||||
|
||||
if (!parent.readOnly) {
|
||||
parent.editingFinished()
|
||||
}
|
||||
focus = false
|
||||
}
|
||||
onEditingFinished: {
|
||||
if(focus){
|
||||
updateText()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,107 +8,109 @@ import Utils 1.0
|
|||
// =============================================================================
|
||||
|
||||
Item {
|
||||
id: item
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
property bool _mouseAlwaysOutside
|
||||
property var _mouseArea: null
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// When emitted, returns a function to test if the click
|
||||
// is on a specific item. It takes only a item parameter.
|
||||
signal pressed (var pointIsInItem)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function _createMouseArea () {
|
||||
var parent = Utils.getTopParent(item, true)
|
||||
|
||||
if (_mouseArea == null) {
|
||||
_mouseArea = builder.createObject()
|
||||
}
|
||||
|
||||
_mouseArea.parent = parent
|
||||
|
||||
// Must be true if a fake parent is used and if `mouseArea`
|
||||
// is not in the same window that `item`.
|
||||
_mouseAlwaysOutside =
|
||||
_mouseArea.parent !== Utils.getTopParent(item)
|
||||
}
|
||||
|
||||
function _deleteMouseArea () {
|
||||
if (_mouseArea != null) {
|
||||
_mouseArea.destroy()
|
||||
_mouseArea = null
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// It's necessary to use a `enabled` variable.
|
||||
// See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal
|
||||
//
|
||||
// The creation order of components in a view is undefined,
|
||||
// so the mouse area must be created only when the target component
|
||||
// was completed.
|
||||
Component.onCompleted: enabled && _createMouseArea()
|
||||
Component.onDestruction: _deleteMouseArea()
|
||||
|
||||
onEnabledChanged: {
|
||||
_deleteMouseArea()
|
||||
|
||||
if (enabled) {
|
||||
_createMouseArea()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: builder
|
||||
|
||||
MouseArea {
|
||||
cursorShape: Qt.ArrowCursor
|
||||
property var _timeout
|
||||
|
||||
function _checkPosition (positionEvent) {
|
||||
// Propagate event.
|
||||
positionEvent.accepted = false
|
||||
|
||||
// Click is outside or not.
|
||||
if (
|
||||
_mouseAlwaysOutside ||
|
||||
!Utils.pointIsInItem(this, item, positionEvent)
|
||||
) {
|
||||
if (_timeout != null) {
|
||||
// Remove existing timeout to avoid the creation of
|
||||
// many children.
|
||||
Utils.clearTimeout(_timeout)
|
||||
}
|
||||
|
||||
// Use a asynchronous call that is executed
|
||||
// after the propagated event.
|
||||
//
|
||||
// It's useful to ensure the window's context is not
|
||||
// modified with the positionEvent before the `onPressed`
|
||||
// call.
|
||||
//
|
||||
// The timeout is destroyed with the `MouseArea` component.
|
||||
_timeout = Utils.setTimeout(this, 0, item.pressed.bind(
|
||||
this,
|
||||
(function (point, item) {
|
||||
return Utils.pointIsInItem(this, item, point)
|
||||
}).bind(this, { x: positionEvent.x, y: positionEvent.y })
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
z: Constants.zMax
|
||||
|
||||
onPressed: _checkPosition.call(this, mouse)
|
||||
onWheel: _checkPosition.call(this, wheel)
|
||||
}
|
||||
}
|
||||
id: mainItem
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
property bool _mouseAlwaysOutside
|
||||
property var _mouseArea: null
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// When emitted, returns a function to test if the click
|
||||
// is on a specific item. It takes only a item parameter.
|
||||
signal pressed (var pointIsInItem)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function _createMouseArea () {
|
||||
var parent = Utils.getTopParent(mainItem, true)
|
||||
|
||||
if (_mouseArea == null) {
|
||||
_mouseArea = builder.createObject()
|
||||
}
|
||||
|
||||
_mouseArea.parent = parent
|
||||
|
||||
// Must be true if a fake parent is used and if `mouseArea`
|
||||
// is not in the same window that `item`.
|
||||
_mouseAlwaysOutside =
|
||||
_mouseArea.parent !== Utils.getTopParent(mainItem)
|
||||
}
|
||||
|
||||
function _deleteMouseArea () {
|
||||
if (_mouseArea != null) {
|
||||
_mouseArea.destroy()
|
||||
_mouseArea = null
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// It's necessary to use a `enabled` variable.
|
||||
// See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal
|
||||
//
|
||||
// The creation order of components in a view is undefined,
|
||||
// so the mouse area must be created only when the target component
|
||||
// was completed.
|
||||
Component.onCompleted: enabled && _createMouseArea()
|
||||
Component.onDestruction: _deleteMouseArea()
|
||||
|
||||
onEnabledChanged: {
|
||||
_deleteMouseArea()
|
||||
|
||||
if (enabled) {
|
||||
_createMouseArea()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: builder
|
||||
|
||||
MouseArea {
|
||||
id: area
|
||||
cursorShape: Qt.ArrowCursor
|
||||
preventStealing: true
|
||||
property var _timeout
|
||||
|
||||
function _checkPosition (positionEvent) {
|
||||
// Propagate event.
|
||||
positionEvent.accepted = false
|
||||
|
||||
// Click is outside or not.
|
||||
if (
|
||||
_mouseAlwaysOutside ||
|
||||
!Utils.pointIsInItem(area, mainItem, positionEvent)
|
||||
) {
|
||||
if (_timeout != null) {
|
||||
// Remove existing timeout to avoid the creation of
|
||||
// many children.
|
||||
Utils.clearTimeout(_timeout)
|
||||
}
|
||||
|
||||
// Use a asynchronous call that is executed
|
||||
// after the propagated event.
|
||||
//
|
||||
// It's useful to ensure the window's context is not
|
||||
// modified with the positionEvent before the `onPressed`
|
||||
// call.
|
||||
//
|
||||
// The timeout is destroyed with the `MouseArea` component.
|
||||
_timeout = Utils.setTimeout(area, 0, mainItem.pressed.bind(
|
||||
this,
|
||||
(function (point, item) {
|
||||
return Utils.pointIsInItem(area, item, point)
|
||||
}).bind(this, { x: positionEvent.x, y: positionEvent.y })
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
z: Constants.zMax
|
||||
|
||||
onPressed: _checkPosition.call(area, mouse)
|
||||
onWheel: _checkPosition.call(area, wheel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue