darkly 0.5.0

A GPU-native paint engine on wgpu: brushes, layers, blend modes, masks, selections, and undo.
Documentation
# 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"