mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-06-05 03:30:03 +00:00
fix: disable panel dragging during text input and dialog interaction
NPanel: disable DragHandler when popups open, block drag over text inputs BarWidgetSettingsDialog: notify panel of open/close state BarSectionEditor: pass panel reference to dialog
This commit is contained in:
@@ -23,6 +23,9 @@ NBox {
|
|||||||
signal dragPotentialStarted
|
signal dragPotentialStarted
|
||||||
signal dragPotentialEnded
|
signal dragPotentialEnded
|
||||||
|
|
||||||
|
property bool hasOpenDialog: false
|
||||||
|
property bool hasOpenPopup: false
|
||||||
|
|
||||||
color: Color.mSurface
|
color: Color.mSurface
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.minimumHeight: {
|
Layout.minimumHeight: {
|
||||||
@@ -189,11 +192,15 @@ NBox {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
var component = Qt.createComponent(Qt.resolvedUrl("BarWidgetSettingsDialog.qml"))
|
var component = Qt.createComponent(Qt.resolvedUrl("BarWidgetSettingsDialog.qml"))
|
||||||
function instantiateAndOpen() {
|
function instantiateAndOpen() {
|
||||||
|
// Find the settings panel
|
||||||
|
var settingsPanel = findSettingsPanel()
|
||||||
|
|
||||||
var dialog = component.createObject(root, {
|
var dialog = component.createObject(root, {
|
||||||
"widgetIndex": index,
|
"widgetIndex": index,
|
||||||
"widgetData": modelData,
|
"widgetData": modelData,
|
||||||
"widgetId": modelData.id,
|
"widgetId": modelData.id,
|
||||||
"parent": Overlay.overlay
|
"parent": Overlay.overlay,
|
||||||
|
"settingsPanel": settingsPanel
|
||||||
})
|
})
|
||||||
if (dialog) {
|
if (dialog) {
|
||||||
dialog.open()
|
dialog.open()
|
||||||
@@ -201,6 +208,11 @@ NBox {
|
|||||||
Logger.error("BarSectionEditor", "Failed to create settings dialog instance")
|
Logger.error("BarSectionEditor", "Failed to create settings dialog instance")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findSettingsPanel() {
|
||||||
|
var panel = PanelService.getPanel("settingsPanel")
|
||||||
|
return panel
|
||||||
|
}
|
||||||
if (component.status === Component.Ready) {
|
if (component.status === Component.Ready) {
|
||||||
instantiateAndOpen()
|
instantiateAndOpen()
|
||||||
} else if (component.status === Component.Error) {
|
} else if (component.status === Component.Error) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Popup {
|
|||||||
property int widgetIndex: -1
|
property int widgetIndex: -1
|
||||||
property var widgetData: null
|
property var widgetData: null
|
||||||
property string widgetId: ""
|
property string widgetId: ""
|
||||||
|
property var settingsPanel: null
|
||||||
|
|
||||||
// Center popup in parent
|
// Center popup in parent
|
||||||
x: (parent.width - width) * 0.5
|
x: (parent.width - width) * 0.5
|
||||||
@@ -23,6 +24,7 @@ Popup {
|
|||||||
height: content.implicitHeight + padding * 2
|
height: content.implicitHeight + padding * 2
|
||||||
padding: Style.marginXL * scaling
|
padding: Style.marginXL * scaling
|
||||||
modal: true
|
modal: true
|
||||||
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
id: bgRect
|
id: bgRect
|
||||||
@@ -37,6 +39,20 @@ Popup {
|
|||||||
if (widgetData && widgetId) {
|
if (widgetData && widgetId) {
|
||||||
loadWidgetSettings()
|
loadWidgetSettings()
|
||||||
}
|
}
|
||||||
|
notifySettingsPanel(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
notifySettingsPanel(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function notifySettingsPanel(isOpen) {
|
||||||
|
if (settingsPanel && settingsPanel.hasOwnProperty('hasOpenPopup')) {
|
||||||
|
settingsPanel.hasOpenPopup = isOpen
|
||||||
|
Logger.log("BarWidgetSettingsDialog", "Notified settings panel popup state:", isOpen, "Panel:", settingsPanel.objectName || "unnamed")
|
||||||
|
} else {
|
||||||
|
Logger.warn("BarWidgetSettingsDialog", "No settings panel reference available to notify popup state:", isOpen)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadWidgetSettings() {
|
function loadWidgetSettings() {
|
||||||
|
|||||||
+121
-2
@@ -33,6 +33,7 @@ Loader {
|
|||||||
|
|
||||||
property bool panelKeyboardFocus: false
|
property bool panelKeyboardFocus: false
|
||||||
property bool backgroundClickEnabled: true
|
property bool backgroundClickEnabled: true
|
||||||
|
property bool hasOpenPopup: false
|
||||||
|
|
||||||
// Animation properties
|
// Animation properties
|
||||||
readonly property real originalScale: 0.7
|
readonly property real originalScale: 0.7
|
||||||
@@ -155,6 +156,70 @@ Loader {
|
|||||||
dimmingOpacity = Style.opacityHeavy
|
dimmingOpacity = Style.opacityHeavy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to check if any popups are open
|
||||||
|
function checkForOpenPopups() {
|
||||||
|
// Check if this panel has an open popup
|
||||||
|
if (root.hasOpenPopup) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var contentItem = panelContentLoader.item
|
||||||
|
if (!contentItem)
|
||||||
|
return false
|
||||||
|
|
||||||
|
// Check for BarSectionEditor dialogs
|
||||||
|
if (hasOpenDialogInContent(contentItem)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasOpenPopupRecursive(contentItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasOpenDialogInContent(item) {
|
||||||
|
if (!item)
|
||||||
|
return false
|
||||||
|
|
||||||
|
// Check if this item is a BarSectionEditor with an open dialog
|
||||||
|
if (item.hasOwnProperty('hasOpenDialog') && item.hasOpenDialog) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check children recursively
|
||||||
|
if (item.children) {
|
||||||
|
for (var i = 0; i < item.children.length; i++) {
|
||||||
|
var child = item.children[i]
|
||||||
|
if (child && hasOpenDialogInContent(child)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasOpenPopupRecursive(item) {
|
||||||
|
if (!item)
|
||||||
|
return false
|
||||||
|
|
||||||
|
// Check if this item is a popup and is open
|
||||||
|
if (item.hasOwnProperty('opened') && item.opened)
|
||||||
|
return true
|
||||||
|
if (item.hasOwnProperty('visible') && item.visible && item.toString().includes("Popup"))
|
||||||
|
return true
|
||||||
|
|
||||||
|
// Check children recursively
|
||||||
|
if (item.children) {
|
||||||
|
for (var i = 0; i < item.children.length; i++) {
|
||||||
|
var child = item.children[i]
|
||||||
|
if (child && hasOpenPopupRecursive(child)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ScalingService
|
target: ScalingService
|
||||||
function onScaleChanged(screenName, scale) {
|
function onScaleChanged(screenName, scale) {
|
||||||
@@ -413,15 +478,64 @@ Loader {
|
|||||||
sourceComponent: root.panelContent
|
sourceComponent: root.panelContent
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle drag move on the whole panel area
|
// FIXED: Handle drag move with text input exclusion
|
||||||
DragHandler {
|
DragHandler {
|
||||||
id: dragHandler
|
id: dragHandler
|
||||||
target: null
|
target: null
|
||||||
enabled: panelBackground.draggable
|
enabled: panelBackground.draggable && !panelWindow.checkForOpenPopups()
|
||||||
|
|
||||||
|
// Add grab permissions to be more selective
|
||||||
|
grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType
|
||||||
|
|
||||||
property real dragStartX: 0
|
property real dragStartX: 0
|
||||||
property real dragStartY: 0
|
property real dragStartY: 0
|
||||||
|
|
||||||
|
// Helper function to check if an item is a text input
|
||||||
|
function isTextInputItem(item) {
|
||||||
|
if (!item)
|
||||||
|
return false
|
||||||
|
|
||||||
|
var itemString = item.toString()
|
||||||
|
return (itemString.indexOf("TextField") >= 0 || itemString.indexOf("TextInput") >= 0 || itemString.indexOf("TextEdit") >= 0 || (item.objectName && (item.objectName.indexOf("textField") >= 0 || item.objectName.indexOf("textInput") >= 0 || item.objectName.indexOf("input") >= 0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to check if we're over a text input (walks up parent chain)
|
||||||
|
function isOverTextInput(x, y) {
|
||||||
|
var item = panelContentLoader.childAt(x, y)
|
||||||
|
var maxDepth = 10 // Prevent infinite loops
|
||||||
|
var depth = 0
|
||||||
|
|
||||||
|
while (item && depth < maxDepth) {
|
||||||
|
if (isTextInputItem(item)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this item has text input children
|
||||||
|
for (var i = 0; i < item.children.length; i++) {
|
||||||
|
if (isTextInputItem(item.children[i])) {
|
||||||
|
// Check if the point is within this child
|
||||||
|
var childPos = item.children[i].mapToItem(panelBackground, 0, 0)
|
||||||
|
if (x >= childPos.x && x <= childPos.x + item.children[i].width && y >= childPos.y && y <= childPos.y + item.children[i].height) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item = item.parent
|
||||||
|
depth++
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
onActiveChanged: {
|
onActiveChanged: {
|
||||||
if (active) {
|
if (active) {
|
||||||
|
// Check if we're starting drag over a text input
|
||||||
|
var localPos = mapToItem(panelBackground, centroid.position)
|
||||||
|
if (isOverTextInput(localPos.x, localPos.y)) {
|
||||||
|
// Cancel drag by returning early
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Capture current position into manual coordinates BEFORE toggling isDragged
|
// Capture current position into manual coordinates BEFORE toggling isDragged
|
||||||
panelBackground.manualX = panelBackground.x
|
panelBackground.manualX = panelBackground.x
|
||||||
panelBackground.manualY = panelBackground.y
|
panelBackground.manualY = panelBackground.y
|
||||||
@@ -436,7 +550,12 @@ Loader {
|
|||||||
root.enableBackgroundClick()
|
root.enableBackgroundClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTranslationChanged: {
|
onTranslationChanged: {
|
||||||
|
// Only process if we're actually dragging (not cancelled)
|
||||||
|
if (!panelBackground.isDragged)
|
||||||
|
return
|
||||||
|
|
||||||
// Proposed new coordinates from fixed drag origin
|
// Proposed new coordinates from fixed drag origin
|
||||||
var nx = dragStartX + translation.x
|
var nx = dragStartX + translation.x
|
||||||
var ny = dragStartY + translation.y
|
var ny = dragStartY + translation.y
|
||||||
|
|||||||
Reference in New Issue
Block a user