mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2025-12-06 06:36:15 +00:00
WidgetSetting: fixes not being able to type when opening settings through context menu
This commit is contained in:
@@ -29,10 +29,13 @@ PanelWindow {
|
||||
|
||||
// Use Top layer (same as MainScreen) for proper event handling
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
WlrLayershell.keyboardFocus: hasDialog ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
WlrLayershell.namespace: "noctalia-" + windowType + "-" + (screen?.name || "unknown")
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
// Track if a dialog is currently open (needed for keyboard focus)
|
||||
property bool hasDialog: false
|
||||
|
||||
// Register with PanelService so widgets can find this window
|
||||
Component.onCompleted: {
|
||||
objectName = "popupMenuWindow-" + (screen?.name || "unknown");
|
||||
|
||||
@@ -29,6 +29,8 @@ Popup {
|
||||
if (widgetData && widgetId) {
|
||||
loadWidgetSettings();
|
||||
}
|
||||
// Request focus to ensure keyboard input works
|
||||
forceActiveFocus();
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
@@ -40,71 +42,108 @@ Popup {
|
||||
border.width: Style.borderM
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
id: content
|
||||
contentItem: FocusScope {
|
||||
id: focusScope
|
||||
focus: true
|
||||
|
||||
width: parent.width
|
||||
spacing: Style.marginM
|
||||
|
||||
// Title
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: I18n.tr("system.widget-settings-title", {
|
||||
"widget": root.widgetId
|
||||
})
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mPrimary
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "close"
|
||||
tooltipText: I18n.tr("tooltips.close")
|
||||
onClicked: root.close()
|
||||
}
|
||||
}
|
||||
|
||||
// Separator
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
}
|
||||
|
||||
// Settings based on widget type
|
||||
// Will be triggered via settingsLoader.setSource()
|
||||
Loader {
|
||||
id: settingsLoader
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
// Action buttons
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginM
|
||||
ColumnLayout {
|
||||
id: content
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginM
|
||||
|
||||
Item {
|
||||
// Title
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: I18n.tr("system.widget-settings-title", {
|
||||
"widget": root.widgetId
|
||||
})
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mPrimary
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "close"
|
||||
tooltipText: I18n.tr("tooltips.close")
|
||||
onClicked: root.close()
|
||||
}
|
||||
}
|
||||
|
||||
NButton {
|
||||
text: I18n.tr("bar.widget-settings.dialog.cancel")
|
||||
outlined: true
|
||||
onClicked: root.close()
|
||||
// Separator
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
}
|
||||
|
||||
NButton {
|
||||
text: I18n.tr("bar.widget-settings.dialog.apply")
|
||||
icon: "check"
|
||||
onClicked: {
|
||||
if (settingsLoader.item && settingsLoader.item.saveSettings) {
|
||||
var newSettings = settingsLoader.item.saveSettings();
|
||||
root.updateWidgetSettings(root.sectionId, root.widgetIndex, newSettings);
|
||||
root.close();
|
||||
// Settings based on widget type
|
||||
// Will be triggered via settingsLoader.setSource()
|
||||
Loader {
|
||||
id: settingsLoader
|
||||
Layout.fillWidth: true
|
||||
onLoaded: {
|
||||
// Try to focus the first focusable item in the loaded settings
|
||||
if (item) {
|
||||
Qt.callLater(() => {
|
||||
var firstInput = findFirstFocusable(item);
|
||||
if (firstInput) {
|
||||
firstInput.forceActiveFocus();
|
||||
} else {
|
||||
focusScope.forceActiveFocus();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function findFirstFocusable(item) {
|
||||
if (!item)
|
||||
return null;
|
||||
// Check if this item can accept focus
|
||||
if (item.focus !== undefined && item.focus === true)
|
||||
return item;
|
||||
// Check children
|
||||
if (item.children) {
|
||||
for (var i = 0; i < item.children.length; i++) {
|
||||
var child = item.children[i];
|
||||
if (child && child.focus !== undefined && child.focus === true)
|
||||
return child;
|
||||
var found = findFirstFocusable(child);
|
||||
if (found)
|
||||
return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Action buttons
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginM
|
||||
spacing: Style.marginM
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NButton {
|
||||
text: I18n.tr("bar.widget-settings.dialog.cancel")
|
||||
outlined: true
|
||||
onClicked: root.close()
|
||||
}
|
||||
|
||||
NButton {
|
||||
text: I18n.tr("bar.widget-settings.dialog.apply")
|
||||
icon: "check"
|
||||
onClicked: {
|
||||
if (settingsLoader.item && settingsLoader.item.saveSettings) {
|
||||
var newSettings = settingsLoader.item.saveSettings();
|
||||
root.updateWidgetSettings(root.sectionId, root.widgetIndex, newSettings);
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,8 +330,11 @@ Singleton {
|
||||
Settings.saveImmediate();
|
||||
}
|
||||
});
|
||||
// Enable keyboard focus for the popup menu window when dialog is open
|
||||
popupMenuWindow.hasDialog = true;
|
||||
// Close the popup menu window when dialog closes
|
||||
dialog.closed.connect(() => {
|
||||
popupMenuWindow.hasDialog = false;
|
||||
popupMenuWindow.close();
|
||||
dialog.destroy();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user