feat: add combo mode with combo counter, score and escalating effects

A 'Combo mode' toggle turns the display into a game-style counter.
Chords containing a modifier (Super/Ctrl/Alt/Shift/Menu/AltGr) are
combos: they build a combo counter, apply a multiplier (x2 at 5, x3 at
10 ... x8 at 50) and escalate the effects. Plain characters and shifted
chars typed alone are hits: +10 score only, they never touch the combo
counter or its window. Scoring: hit = 10, combo = (20 + 15*(mods-1) +
5*(keys-1)) * multiplier.

Counted once per physical chord on the Lua's empty payload (release),
so the intermediate growing emits of a chord never double-count. The
banner (COMBO 12 x3 - 3,450) sits below the history for bottom
positions and above it for top positions, with a floating +N pop per
press. Effects scale with modifiers and chain length: banner pulse,
hue shift, screen shake (up to 5px), continuous hue cycling at 10+
combos and a constant subtle vibration at 20+. The combo resets after
comboWindowMs (2s) without a new combo; the score accumulates for the
shell session.

Also fixes the README Behavior section: the history bullet was never
applied (a failed multi-edit call), now restored alongside the combo
mode docs. Manifest bumped to 1.7.0.
This commit is contained in:
felixzsh
2026-08-12 10:45:16 -05:00
parent 58cca5ec4f
commit 0a4aa59ee1
4 changed files with 378 additions and 11 deletions
+33 -1
View File
@@ -29,6 +29,7 @@ Panel {
property int margin: 67
property int lingerMs: 1000
property int historyCount: 1
property bool comboMode: false
// Config lives outside the plugin folder (the shell reloads all plugin
// code on any file change under ~/.config/omarchy/plugins/), so editing it
@@ -76,6 +77,7 @@ Panel {
if (isFinite(cfg.margin) && cfg.margin >= 0) root.margin = Math.round(cfg.margin)
if (isFinite(cfg.lingerMs) && cfg.lingerMs >= 0) root.lingerMs = Math.round(cfg.lingerMs)
if (isFinite(cfg.historyCount)) root.historyCount = Math.max(1, Math.min(5, Math.round(cfg.historyCount)))
root.comboMode = cfg.comboMode === true
}
// Round-trips every option so a menu edit never drops values the display
@@ -86,12 +88,14 @@ Panel {
position: root.position,
margin: root.margin,
lingerMs: root.lingerMs,
historyCount: root.historyCount
historyCount: root.historyCount,
comboMode: root.comboMode
}
for (var k in update) cfg[k] = update[k]
if (update.mode !== undefined) root.mode = update.mode
if (update.position !== undefined) root.position = update.position
if (update.historyCount !== undefined) root.historyCount = update.historyCount
if (update.comboMode !== undefined) root.comboMode = update.comboMode
writeProc.command = ["sh", "-c",
"printf '%s\\n' '" + JSON.stringify(cfg) + "' > " + Util.shellQuote(root.configPath)]
writeProc.running = true
@@ -168,6 +172,34 @@ Panel {
}
}
// Combo mode -----------------------------------------------------
// Game mode: combo counter + score with escalating effects (pulse,
// hue, screen shake). Chords with modifiers build the combo; plain
// characters are hits that only add score.
Item {
width: parent.width
height: comboSwitch.implicitHeight
Text {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
text: "Combo mode"
font.family: Style.font.family
font.pixelSize: Style.font.body
color: Color.popups.text
}
ToggleSwitch {
id: comboSwitch
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
checked: root.comboMode
foreground: Color.popups.text
accent: Color.accent
onToggled: root.writeConfig({ comboMode: !root.comboMode })
}
}
// Mode ----------------------------------------------------------
Item {
width: parent.width