Kleines Floating-Fenster als Drag-and-Drop-Quelle für Screenshots — Verzeichnisinhalt nach ctime rückwärts sortiert, mit großer Bildvorschau.
  • HTML 38%
  • Shell 34.2%
  • JavaScript 27.3%
  • Nix 0.5%
Find a file
2026-08-30 11:49:54 +02:00
renderer feat: FlipDrop-App — Floating-Fenster als XDND-Drag-Quelle 2026-08-23 21:23:27 +02:00
.gitignore chore: Standard-Dateien ergänzen 2026-08-23 21:12:05 +02:00
CHANGELOG.md chore(release): v0.2.2 2026-08-30 11:49:40 +02:00
CLAUDE.md chore: Standard-Dateien ergänzen 2026-08-23 21:12:05 +02:00
cliff.toml chore: Standard-Dateien ergänzen 2026-08-23 21:12:05 +02:00
flipdrop.sh feat: conky-Spur als Standard-Anker 2026-08-23 22:12:50 +02:00
LICENSE chore: Standard-Dateien ergänzen 2026-08-23 21:12:05 +02:00
main.js fix: Fenster rechts andocken und Launcher-Robustheit 2026-08-23 21:50:49 +02:00
package.json feat: FlipDrop-App — Floating-Fenster als XDND-Drag-Quelle 2026-08-23 21:23:27 +02:00
pemmikan.md docs: Drop nach Alacritty als Upstream-Einschränkung dokumentiert 2026-08-30 11:49:39 +02:00
preload.js feat: FlipDrop-App — Floating-Fenster als XDND-Drag-Quelle 2026-08-23 21:23:27 +02:00
README.md docs: Drop nach Alacritty als Upstream-Einschränkung dokumentiert 2026-08-30 11:49:39 +02:00
shell.nix fix: Fenster rechts andocken und Launcher-Robustheit 2026-08-23 21:50:49 +02:00

FlipDrop

License: MIT Platform: Linux/X11 Stack: Electron WM: i3

Kleines Floating-Fenster als Drag-and-Drop-Quelle für Screenshots — Verzeichnisinhalt nach ctime rückwärts sortiert, mit großer Bildvorschau.

Zweck

Ein immer-obenauf-Fenster (X11/i3), das ein Verzeichnis nach ctime absteigend zeigt — also danach, wann die Datei dort aufgetaucht ist, nicht nach mtime. Das ist der Unterschied, auf den es ankommt: bei Kopien aus Nextcloud oder aus dem SyncDir bleibt die mtime die des Originals, die ctime ist der Moment des Ankommens. Sortiert nach mtime landet der frische Screenshot irgendwo in der Mitte, sortiert nach ctime ganz oben.

Gedacht als Drag-and-Drop-Quelle, um Screenshots schnell nach Claude zu schieben — in VSCodium, in den Browser oder in ein Terminal.

Features

  • Immer-obenauf-Fenster (X11/i3), klein und aus dem Weg
  • Listet ein Verzeichnis (Default ~/SyncDir/Screenshots) nach ctime absteigend
  • Große Bildvorschau statt Dateinamen-Raten
  • Datei per Drag-and-Drop (XDND) nach außen ziehen — VSCodium, Browser, Terminal
  • Klick kopiert den Dateipfad ins Clipboard (CLIPBOARD und PRIMARY)
  • Aktualisiert sich automatisch per fs.watch, zeigt maximal 200 Einträge

Aufruf

./flipdrop.sh                    # Default-Verzeichnis, auf conkys Spur
./flipdrop.sh -d ~/Bilder        # anderes Verzeichnis
./flipdrop.sh --dir=~/Bilder     # gleichbedeutend
./flipdrop.sh -l                 # linke Kante
./flipdrop.sh -r                 # rechte Kante (Default)
./flipdrop.sh -c                 # auf conkys Spur
./flipdrop.sh -w 420             # feste Breite in Pixeln
./flipdrop.sh --help             # Kurzhilfe

Flags:

Flag Wirkung
-d, --dir VERZEICHNIS, --dir=VERZEICHNIS Verzeichnis, das gezeigt wird
-l, --left Fenster an die linke Kante des Ankerbereichs
-r, --right Fenster an die rechte Kante (Default)
-c, --conky Anker conky — exakt auf conkys Spur (Default)
-m, --monitor Anker monitor — 380 px breiter Streifen am Bildschirmrand
-w, --width PX Fensterbreite in Pixeln
-h, --help Kurzhilfe

Environment-Variablen:

Variable Default Bedeutung
FLIPDROP_DIR ~/SyncDir/Screenshots Verzeichnis, das gezeigt wird
FLIPDROP_SIDE right Seite: right, left oder center
FLIPDROP_ANCHOR conky (Default) Bezugsrechteck: conky, monitor oder workspace
FLIPDROP_WIDTH conkys Breite Fensterbreite; bei Anker monitor ohne Angabe 380
FLIPDROP_MARGIN 6 Rand in Pixeln zu den Kanten des Ankerbereichs
FLIPDROP_DEBUG leer gesetzt: berechnete Geometrie auf stderr ausgeben
FLIPDROP_GEOM — übersteuert die Größe, Format "Breite Höhe"
FLIPDROP_POS — übersteuert die Position, Format "X Y"

Flags gewinnen gegen die gleichnamigen Variablen; FLIPDROP_GEOM/FLIPDROP_POS übersteuern am Ende alles.

Positionierung

Vertikal richtet sich FlipDrop immer am i3-Workspace aus. i3 kennt den nutzbaren Bereich exakt — Polybar und andere Struts sind im Workspace-Rechteck bereits abgezogen, das Fenster verschwindet also nicht unter der Leiste. Fehlt i3 (oder jq), dient das Monitor-Rechteck aus xrandr als Ersatz.

Horizontal entscheidet der Anker, welches Rechteck gilt:

Anker Bezug
conky (Default) exakt conkys Spur — Position und Breite werden aus den conky-Fenstern gemessen
monitor ganzer Bildschirm — ignoriert, was conky für sich reserviert
workspace der i3-Bereich; bei holm endet der vor conky

Für den Anker conky sucht der Launcher per xdotool alle Fenster der Klasse conky und bildet deren Hüllrechteck — conky läuft oft als mehrere Fenster übereinander in derselben Spalte; Fenster mit weniger als 400 px² Fläche gelten als Hilfsfenster und werden übersprungen. Findet sich kein conky-Fenster, fällt der Launcher mit einer Meldung auf den Anker monitor zurück.

conkys Spur wird bei jedem Start neu gemessen und nie fest verdrahtet: conky sitzt auch bei anderen Auflösungen am Bildschirmrand, und die gemessene Position folgt ihm dorthin.

Innerhalb des Ankerbereichs setzt FLIPDROP_SIDE das Fenster an die rechte Kante (Default), an die linke oder mittig; FLIPDROP_MARGIN hält den Abstand zu den Kanten.

Der Launcher rechnet die Geometrie fertig aus und übergibt sie der App als --geom=BxH+X+Y; die App setzt sie beim Erzeugen des Fensters selbst. Mit gesetztem FLIPDROP_DEBUG schreibt der Launcher Ankerbereich und Ergebnis nach stderr:

flipdrop: anker=conky bereich=380x1052@1534,28 -> fenster 380x1040@1534,34

Bedienung

Aktion Wirkung
Klick Pfad ins Clipboard (CLIPBOARD und PRIMARY)
Doppelklick Datei öffnen
Ziehen Datei per XDND ans Ziel übergeben
+ / - Spaltenzahl 1–4 (wird in localStorage gemerkt)
r / F5 Liste neu laden
q / Esc Fenster schließen
Titelleiste ziehen Fenster verschieben

Voraussetzungen

  • Linux mit X11 (Wayland ist ungetestet)
  • Electron — über shell.nix aus nixpkgs, getestet mit 41.9.1
  • xrandr und sed — Monitor-Rechteck
  • i3-msg und jq — Workspace-Rechteck unter i3; fehlt beides, gilt der Monitor
  • xdotool — nur für den Anker conky, zum Messen der conky-Fenster

Kein Perl, kein xclip — das Clipboard bedient Electron selbst.

Installation

git clone ssh://git@forgejo.mueller.network:2222/holm.tools.public/FlipDrop.git
cd FlipDrop
./flipdrop.sh

Symlink in den Pfad:

ln -s "$PWD/flipdrop.sh" ~/bin/flipdrop

FlipDrop steht in der distribution/registry.list von toolctl und lässt sich darüber wie die übrigen Tools ausrollen; bei holm existiert der Symlink ~/bin/flipdrop bereits.

i3-Regel

i3 legt das Fenster per Default tiled an. Mit dieser Regel in der i3-Config sitzt es sofort richtig:

for_window [class="(?i)flipdrop"] floating enable, sticky enable, border pixel 2, resize set 380 900, move position 60 60

Größe und Position kommen inzwischen vom Launcher (--geom=…); nötig ist an der Regel also nur noch floating enable, dazu nach Geschmack sticky/border — resize set und move position würden die berechnete Geometrie übersteuern.

Stolperfallen

ELECTRON_RUN_AS_NODE

Aus einem VSCodium-Terminal gestartet erbt der Prozess ELECTRON_RUN_AS_NODE=1. Electron läuft dann als reines Node und stirbt sofort mit Cannot find module 'electron' — was nach einem kaputten Setup aussieht, aber keins ist.

flipdrop.sh räumt diese Variable und ihre VSCODE_*-Geschwister vor dem Start ab. Wer stattdessen direkt electron . aufruft, muss das selbst tun:

unset ELECTRON_RUN_AS_NODE ELECTRON_NO_ATTACH_CONSOLE NODE_OPTIONS
unset VSCODE_ESM_ENTRYPOINT VSCODE_CODE_CACHE_PATH VSCODE_NLS_CONFIG VSCODE_CWD
electron .

Über ~/bin/flipdrop gestartet zeigt BASH_SOURCE auf den Symlink, nicht ins Repo — ohne Auflösung sucht der Launcher shell.nix in ~/bin und findet nichts. flipdrop.sh löst den eigenen Pfad deshalb mit readlink -f auf, bevor es das App-Verzeichnis bestimmt.

xdotool search und set -e

xdotool search endet mit Exit 1, wenn es nichts findet. In einer Zuweisung VAR="$(xdotool search …)" ist dieser Status der des ganzen Kommandos — unter set -e beendet ein völlig normaler Fall („kein conky da") also das Script. Deshalb steht dort || true.

Warum die Geometrie nicht per i3-msg nachgesetzt wird

Naheliegend wäre, das Fenster nach dem Start per i3-msg an seinen Platz zu schieben. Das setzt aber voraus, die Fenster-ID zu erraten, und daran hängen zwei Probleme: X11 recycelt IDs — ein frisches Fenster kann die des eben geschlossenen erben — und Electron legt zusätzlich Hilfsfenster derselben WM-Klasse an (10x10 und 200x200). Der Befehl landet dann auf dem falschen Fenster. Stattdessen berechnet der Launcher die Geometrie und gibt sie als --geom=BxH+X+Y mit; die App setzt sie beim Erzeugen des Fensters.

Bekannte Einschränkung: Drop nach Alacritty

Ein Drop in ein Alacritty-Fenster bewirkt nichts — kein Fehler, keine Reaktion. Das ist ein Upstream-Bug und liegt nicht an FlipDrop:

Test Ergebnis
FlipDrop → xdragon --target funktioniert, text/uri-list kommt korrekt an
xdragon → Alacritty funktioniert
FlipDrop → Alacritty schlägt fehl

Ursache: winit antwortet in XdndStatus/XdndFinished mit dem Action-Atom XdndActionPrivate. Chromiums AtomToDragOperation() kennt nur Copy/Move/Link und liefert für alles andere kNone; HandleMouseReleased() sendet XdndDrop nur bei != kNone. Chromium bricht den Drag deshalb still ab, das Ziel bekommt nie ein Drop-Event.

Auf winit master ist das behoben (Commit 156433e, auf XdndActionCopy geändert), aber in keinem Release enthalten. Alacritty v0.17.0 hängt an winit 0.30.9 und ist betroffen. Quellseitig ist nichts zu machen: startDrag reicht nur {file, icon} durch, und die MIME-Typen sind ohnehin korrekt — die Bruchstelle ist das Action-Atom, nicht der Typ.

Bis ein winit-Release mit dem Fix erscheint: Drop-Ziele außerhalb von Alacritty verwenden (VSCodium und Browser funktionieren), oder als Behelf die Kachel anklicken — der Pfad liegt dann in CLIPBOARD und PRIMARY.

Changelog

Siehe CHANGELOG.md. Wird per git-cliff aus Conventional Commits generiert. Manuell nicht editieren — stattdessen Commit-Messages sauber halten:

  • feat(scope): … → Added
  • fix(scope): … → Fixed
  • perf(scope): … → Performance
  • refactor(scope): … → Changed
  • BREAKING CHANGE: … im Body → Major-Bump

Lizenz

MIT — Copyright (c) 2026 holm / Christian Müller, unter Zuhilfenahme von Claude.ai (Anthropic).

Siehe LICENSE.