fix: right-button double click no longer wipes rotation mid-drag (v1.7.2)
Build & Release / build-linux (push) Canceled after 0s
Build & Release / build-windows (push) Canceled after 0s
Build & Release / create-release (push) Canceled after 0s

Two rotate drags started quickly at nearly the same spot were treated as a
double click: the reset was detected on button down against the previous down
time/position, so it wiped all effects and ignored the second drag, leaving
Ctrl+S to save an unrotated crop.

- Double click is now only counted for actual clicks (movement <= 4px) and is
  decided on button up; a drag breaks the chain.
- Pointer up is matched by pointer id, so a left-drag pan never counts as a click.
- dist: 1.7.2 .deb replaces the tracked 1.7.1 package.
This commit is contained in:
Alhan committed 2026-10-25 20:48:59 +03:00
1 parent 32fb12c210
commit 3b1fad18fa
6 files changed
+48 -20

No files matched your search

+1 -1
View File
@@ -17,7 +17,7 @@ import '../shortcuts/app_shortcuts.dart';
import '../services/window_persistence.dart';
import '../l10n/app_localizations.dart';
const appVersion = '1.7.1';
const appVersion = '1.7.2';
class ViewerScreen extends StatefulWidget {
final List<String> initialFiles;
+34 -17
View File
@@ -41,6 +41,11 @@ class ImageCanvasState extends State<ImageCanvas> {
double _startBrightness = 0;
DateTime? _lastRightTapTime;
Offset _lastRightTapPos = Offset.zero;
/// Sağ tuş basılıyken anlamlı hareket oldu mu? (tıklama mı sürükleme mi)
bool _rightDragMoved = false;
int? _rightPointerId;
/// Sürükleme sayılma eşiği (px) — rotate/contrast ince ayarında el titremesi.
static const double _dragClickSlop = 4;
// ── Klavye modifier tracking ──
bool _ctrlPressed = false;
@@ -311,23 +316,8 @@ class ImageCanvasState extends State<ImageCanvas> {
if (e.buttons != kSecondaryMouseButton) return;
_pointerDownPos = e.localPosition;
final now = DateTime.now();
if (_lastRightTapTime != null &&
now.difference(_lastRightTapTime!) < const Duration(milliseconds: 400) &&
(e.localPosition - _lastRightTapPos).distance < 20) {
_angle = 0;
_contrast = 1.0;
_saturation = 1.0;
_brightness = 0;
_flipH = false;
_interactionMode = 'none';
_markRenderDirty();
_lastRightTapTime = null;
return;
}
_lastRightTapTime = now;
_lastRightTapPos = e.localPosition;
_rightDragMoved = false;
_rightPointerId = e.pointer;
if (_ctrlPressed && _shiftPressed) {
_interactionMode = 'brightness';
@@ -346,6 +336,10 @@ class ImageCanvasState extends State<ImageCanvas> {
void _onPointerMove(PointerMoveEvent e) {
if (e.buttons != kSecondaryMouseButton) return;
if (!_rightDragMoved &&
(e.localPosition - _pointerDownPos).distance > _dragClickSlop) {
_rightDragMoved = true;
}
final dy = e.localPosition.dy - _pointerDownPos.dy;
@@ -367,7 +361,30 @@ class ImageCanvasState extends State<ImageCanvas> {
}
void _onPointerUp(PointerUpEvent e) {
if (e.pointer != _rightPointerId) return;
_rightPointerId = null;
_interactionMode = 'none';
// Sürükleme ile biten etkileşim sağ çift tık zincirini keser; yalnızca
// gerçek tıklamalar (hareketsiz bas-bırak) çift tık sayılır.
if (_rightDragMoved) {
_lastRightTapTime = null;
_rightDragMoved = false;
return;
}
final now = DateTime.now();
final isDouble = _lastRightTapTime != null &&
now.difference(_lastRightTapTime!) < const Duration(milliseconds: 400) &&
(e.localPosition - _lastRightTapPos).distance < 20;
_lastRightTapTime = isDouble ? null : now;
_lastRightTapPos = e.localPosition;
if (isDouble) {
_angle = 0;
_contrast = 1.0;
_saturation = 1.0;
_brightness = 0;
_flipH = false;
_markRenderDirty();
}
}
// ── Combined color filter (brightness × saturation × contrast) ──