1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Editor-AGNOSTIC defaults. Bottom layer of the three-layer config resolution:
#
# user override → overlay[active editor] → defaults (this file)
#
# Hotkeys / mouse_clicks inclusion rule:
#
# 1. A binding lives here iff Krita, Photoshop, and GIMP all agree on its
# value. Verify against the actual editor sources (krita/, gimp/, and
# Photoshop docs) — not against memory or web claims — before adding.
#
# 2. Darkly-original actions (no reference editor has any prior art) also
# live here. Mark them explicitly so reviewers don't mistake them for #1.
#
# 3. Anything else — any binding where the editors disagree, or where some
# editors have an opinion and others don't — must be split into each
# per-editor overlay (krita.yaml / photoshop.yaml / gimp.yaml). The
# `user → overlay → defaults` fallthrough makes silent inheritance the
# default; this rule keeps the per-editor file authoritative for any
# action that any editor would assign a key to, so an overlay can't
# accidentally reuse the same key for a different action.
#
# Settings inclusion rule: Darkly-specific configuration (canvas size,
# animation rates, theme, …) that has no direct reference-editor analog
# lives here; settings the editors disagree on (e.g.
# tools.colorPickerSampleSource) are split into the per-editor overlays.
hotkeys:
# Universal edit / clipboard / file bindings — all three editors agree.
# (redo, pasteInPlace differ between editors and live per-overlay.)
undo: $mod+KeyZ
copy: $mod+KeyC
cut: $mod+KeyX
paste: $mod+KeyV
saveDocument: $mod+KeyS
saveDocumentAs: $mod+Shift+KeyS
open: $mod+KeyO
selectAll: $mod+KeyA
# Floating-selection commit / cancel. Enter / Escape are the universal
# commit/cancel keys across PS, Krita, and GIMP's floating-selection
# handlers.
clearSelectionContents: Delete
commitFloating: Enter
cancelFloating: Escape
# Colors — all three editors use D to reset, X to swap.
resetColors: KeyD
swapColors: KeyX
# Brush parameter hotkeys — `[` / `]` is the universal sizing convention.
brushSizeUp: BracketRight
brushSizeDown: BracketLeft
# Photoshop binds Edit > Preferences to $mod+K; Krita/GIMP have no
# default. Darkly picks the macOS preferences convention.
openSettings: $mod+Comma
# Photoshop & GIMP both have export (Photoshop: $mod+Alt+W for "Export
# As"; GIMP: $mod+Shift+E for "Export As…"). Krita's `file_export_file`
# is explicitly `none`. Darkly picks GIMP's binding.
exportImage: $mod+Shift+KeyE
# Photoshop binds Lasso to L and Polygonal Lasso to Shift+L; Krita's
# selection-tool .action files have empty <shortcut>; GIMP's analog is
# "Free Select" (KeyF) with no polygonal counterpart. Darkly inherits
# Photoshop's choice; per-editor overlays can override.
lassoSelectTool: KeyL
polygonSelectTool: Shift+KeyL
# Krita binds View > Mirror View to M; Photoshop/GIMP have no default.
mirrorViewH: KeyM
# Canvas resize. Photoshop binds Image Size to $mod+Alt+I and Canvas Size
# to $mod+Alt+C; GIMP/Krita have no default for canvas size. Darkly takes
# Photoshop's Canvas Size binding. `cropToSelection` stays menu-only (no
# reference editor binds it).
resizeCanvas: $mod+Alt+KeyC
# Darkly-original (brush builder) — no reference-editor prior art.
addBrushNode: Shift+KeyA
# Darkly-original (command palette). No Krita/PS/GIMP prior art, so it
# belongs here rather than a per-editor overlay. Follows the VS Code
# convention for a command palette.
commandPalette: $mod+Shift+KeyP
# PS + Krita both bind Quick Group to Ctrl+G. GIMP has no default
# (the Layer menu's group commands aren't bound). With layers
# selected, the action handler wraps them in the new group; with
# nothing selected, creates an empty group.
newGroup: $mod+KeyG
# PS + Krita both bind Merge Down to Ctrl+E. GIMP's only layer-merge
# default is Ctrl+M for "Merge Visible Layers" — semantically
# different. The `mergeDown` action handler is selection-aware:
# with ≥2 selected it bakes the selection via merge_layers, with 1
# it does the classic single-layer merge-down. One hotkey, two ops.
mergeDown: $mod+KeyE
# `flatten` and `addMask` are intentionally left unbound here:
# - addMask: no reference editor has a default key (PS, Krita,
# and GIMP all expose mask creation through a button click).
# Inventing a Darkly-only binding would surprise users with no
# prior-art expectation, and commit a key slot we'd later have
# to fight if we register e.g. GIMP's Ctrl+M "Merge Visible".
# - flatten: Krita binds Ctrl+Shift+E to "Flatten image" (the
# whole-canvas composite, which is Darkly's `flatten_image`
# engine op — not yet a registered action). Borrowing that key
# for Darkly's single-layer flatten (apply-mask / flatten-group)
# would mislead Krita users. If someone registers `flattenImage`
# as an action, that's where Ctrl+Shift+E belongs.
settings:
# Canvas defaults.
canvas.width: 1920
canvas.height: 1080
canvas.backgroundColor: "#000000"
# Autosave / crash recovery. Darkly-original (no reference-editor analog).
autosave.enabled: true
autosave.intervalSeconds: 120
# Animation tick divisors.
animation.veil_divisor: 2
animation.overlay_divisor: 4
animation.void_divisor: 2
# Rendering.
rendering.veil_scale: 1.0
# Display.
display.pixelFilter: auto
# Navigation.
nav.panSensitivity: 0.5
hotkeys.nav.trigger: Space
hotkeys.nav.rotate: Shift
hotkeys.nav.zoom: Ctrl
# UI.
ui.theme: dark
ui.brushBuilder.previewVisible: true
ui.brushBuilder.previewWidth: 320
ui.brushBuilder.previewHeight: 120
# Input.
input.fingerPainting: true
# Editing.
edit.activateTransformAfterPaste: true
# Colors.
colors.defaultForeground: "#ffffff"
colors.defaultBackground: "#000000"