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
@@ -49,7 +49,7 @@ app.*.map.json
*.deb
*.tar.gz
*.exe
!dist/imajviewer_1.7.1_amd64.deb
!dist/imajviewer_1.7.2_amd64.deb
!dist/imajviewer_setup_1.1.0.exe
deb/usr/lib/imajviewer/
release/
+11
View File
@@ -4,6 +4,17 @@ All notable changes to imajViewer are documented in this file.
## [Unreleased]
## [1.7.2] - 2026-10-25
### Fixed
- Rotating sometimes vanished before saving: the right-button double-click reset was
detected on button *down* against the previous down time and position, so two rotate
drags started quickly at nearly the same spot were treated as a double click — all
effects (rotation included) were wiped and the second drag was ignored, so `Ctrl+S`
saved an unrotated crop. A double click is now only counted for actual clicks
(movement ≤ 4 px, decided on button up), a drag breaks the chain, and
`pointer up` is matched by pointer id so a left-drag pan never counts as a click.
## [1.7.1] - 2026-10-25
### Added
+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) ──
+1 -1
View File
@@ -1,7 +1,7 @@
name: imajviewer
description: "Ultra-lightweight image viewer for Linux and Windows."
publish_to: 'none'
version: 1.7.1+17
version: 1.7.2+18
msix_config:
display_name: ImajViewer