Shortcuts you invent, rules you write, gestures you own - all still just data
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -16,6 +16,109 @@ SettingsPage {
|
||||
title: "Tiling"
|
||||
lede: "How windows share the space, and where their edges are."
|
||||
|
||||
// The rule being edited, or null while the editor is closed. Held here
|
||||
// rather than in the editor so that opening one row's Edit closes another's.
|
||||
property var editingRule: null
|
||||
property bool addingRule: false
|
||||
|
||||
readonly property bool ruleEditorOpen: root.addingRule || root.editingRule !== null
|
||||
|
||||
function closeRuleEditor(): void {
|
||||
root.addingRule = false;
|
||||
root.editingRule = null;
|
||||
}
|
||||
|
||||
// Per-application behavior, above the general tiling settings: a rule for
|
||||
// one application is what somebody came here to write, and the gaps and
|
||||
// borders below are set once and left alone.
|
||||
SettingsCard {
|
||||
title: "App rules"
|
||||
subtitle: "How specific applications behave when they open. Behaviors, not regexes: pick an application, tick what it should do. Panama's own surfaces cannot be matched."
|
||||
|
||||
Repeater {
|
||||
id: ruleRows
|
||||
|
||||
model: WindowRules.rules
|
||||
|
||||
WindowRuleRow {
|
||||
id: ruleRow
|
||||
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
rule: ruleRow.modelData
|
||||
divider: ruleRow.index < ruleRows.count - 1
|
||||
|
||||
onEditRequested: {
|
||||
root.addingRule = false;
|
||||
root.editingRule = ruleRow.modelData;
|
||||
ruleEditor.load(ruleRow.modelData);
|
||||
}
|
||||
|
||||
onRemoveRequested: {
|
||||
if (root.editingRule === ruleRow.modelData)
|
||||
root.closeRuleEditor();
|
||||
WindowRules.removeRule(String(ruleRow.modelData.class ?? ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
visible: WindowRules.rules.length === 0 && !root.ruleEditorOpen
|
||||
text: "No rules yet. Every application opens the way the compositor decides."
|
||||
color: Theme.fgMuted
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSize
|
||||
topPadding: 10
|
||||
bottomPadding: 10
|
||||
}
|
||||
|
||||
WindowRuleEditor {
|
||||
id: ruleEditor
|
||||
|
||||
width: parent.width
|
||||
visible: root.ruleEditorOpen
|
||||
|
||||
onCommitted: rule => {
|
||||
const saved = root.editingRule === null
|
||||
? WindowRules.addRule(rule)
|
||||
: WindowRules.updateRule(String(root.editingRule.class ?? ""), rule);
|
||||
if (saved)
|
||||
root.closeRuleEditor();
|
||||
}
|
||||
|
||||
onCanceled: root.closeRuleEditor()
|
||||
}
|
||||
|
||||
SettingRow {
|
||||
visible: !root.ruleEditorOpen
|
||||
label: "Add a rule"
|
||||
detail: WindowRules.rules.length === 0
|
||||
? "Applies on save, with a compositor reload"
|
||||
: (WindowRules.applied
|
||||
? "Applied on the last reload — Hyprland publishes no rule listing, so this is the reload's word, not a read-back of the rules themselves"
|
||||
: "Saved, waiting on the reload that puts it in effect")
|
||||
controlWidth: 130
|
||||
divider: false
|
||||
|
||||
SettingsButton {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
tone: "accent"
|
||||
text: "+ Add a rule"
|
||||
enabled: !WindowRules.reloading
|
||||
onClicked: {
|
||||
root.editingRule = null;
|
||||
ruleEditor.reset();
|
||||
root.addingRule = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ErrorRow { message: WindowRules.lastError }
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
title: "Window layout"
|
||||
subtitle: "Follows the Forge mental model, with native Hyprland tiling."
|
||||
|
||||
Reference in New Issue
Block a user