feat: persist fill/fit view mode in window.json (v1.5.0)
Build & Release / build-linux (push) Has been cancelled
Build & Release / build-windows (push) Has been cancelled
Build & Release / create-release (push) Has been cancelled

The double-click fill/fit mode was hardcoded (image_canvas: _isFilled = true) and
reset on every image change, so it never survived a restart. It is now stored as
"filled" in window.json and restored on launch and on image switch.

WindowPersistence.saveSync() now merges with the existing file, otherwise the
startup/move/resize geometry writes would drop the mode key.

Also: version 1.5.0, CHANGELOG entry, dist/ ships imajviewer_1.5.0_amd64.deb
(replaces 1.4.2).
This commit is contained in:
Alhan committed 2026-10-12 22:33:43 +03:00
1 parent b3bd540549
commit 2cd9e6c357
6 files changed
+50 -11

No files matched your search

+1 -1
View File
@@ -49,7 +49,7 @@ app.*.map.json
*.deb *.deb
*.tar.gz *.tar.gz
*.exe *.exe
!dist/imajviewer_1.4.2_amd64.deb !dist/imajviewer_1.5.0_amd64.deb
!dist/imajviewer_setup_1.1.0.exe !dist/imajviewer_setup_1.1.0.exe
deb/usr/lib/imajviewer/ deb/usr/lib/imajviewer/
release/ release/
+6
View File
@@ -4,6 +4,12 @@ All notable changes to imajViewer are documented in this file.
## [Unreleased] ## [Unreleased]
## [1.5.0] - 2026-10-12
### Added
- Fill/fit mode (double-click) is now persisted in `window.json` and restored on the next launch
and when switching images, instead of always resetting to fill.
## [1.4.2] - 2026-10-12 ## [1.4.2] - 2026-10-12
### Fixed ### Fixed
+38 -7
View File
@@ -15,28 +15,59 @@ class WindowPersistence {
return File('$dir/window.json'); return File('$dir/window.json');
} }
/// Görüntü ekran modu: true = pencereyi kapla (cover), false = sığdır (contain).
/// Anahtar yoksa/bozuksa true (eski davranış).
static bool get filled {
final v = _read()?['filled'];
return v is bool ? v : true;
}
/// Sadece modu günceller; x/y/w/h korunur.
static void saveFilled(bool value) => _write({'filled': value});
/// Save window rect synchronously (safe to call before destroy). /// Save window rect synchronously (safe to call before destroy).
static void saveSync({ static void saveSync({
required Offset position, required Offset position,
required Size size, required Size size,
}) { }) {
final file = _configFile; _write({
file.parent.createSync(recursive: true);
file.writeAsStringSync(jsonEncode({
'x': position.dx.toInt(), 'x': position.dx.toInt(),
'y': position.dy.toInt(), 'y': position.dy.toInt(),
'width': size.width.toInt(), 'width': size.width.toInt(),
'height': size.height.toInt(), 'height': size.height.toInt(),
})); });
}
/// Dosyayı oku (yok/bozuksa null).
static Map<String, dynamic>? _read() {
final file = _configFile;
if (!file.existsSync()) return null;
try {
return jsonDecode(file.readAsStringSync()) as Map<String, dynamic>;
} catch (_) {
return null;
}
}
/// Verilen anahtarları yaz; dosyadaki diğer anahtarlar korunur.
static void _write(Map<String, dynamic> values) {
try {
final file = _configFile;
file.parent.createSync(recursive: true);
final data = _read() ?? <String, dynamic>{};
data.addAll(values);
file.writeAsStringSync(jsonEncode(data));
} catch (_) {
// Disk hatası uygulamayı durdurmasın.
}
} }
/// Restore saved window rect. Returns null if no saved config. /// Restore saved window rect. Returns null if no saved config.
static ({Offset position, Size size})? restore() { static ({Offset position, Size size})? restore() {
final file = _configFile; final data = _read();
if (!file.existsSync()) return null; if (data == null) return null;
try { try {
final data = jsonDecode(file.readAsStringSync()) as Map<String, dynamic>;
final x = (data['x'] as num?)?.toDouble() ?? 0; final x = (data['x'] as num?)?.toDouble() ?? 0;
final y = (data['y'] as num?)?.toDouble() ?? 0; final y = (data['y'] as num?)?.toDouble() ?? 0;
final w = (data['width'] as num?)?.toDouble() ?? 1280; final w = (data['width'] as num?)?.toDouble() ?? 1280;
+4 -2
View File
@@ -6,6 +6,7 @@ import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import '../l10n/app_localizations.dart'; import '../l10n/app_localizations.dart';
import '../services/crop_save_service.dart'; import '../services/crop_save_service.dart';
import '../services/window_persistence.dart';
class ImageCanvas extends StatefulWidget { class ImageCanvas extends StatefulWidget {
final String filePath; final String filePath;
@@ -15,7 +16,7 @@ class ImageCanvas extends StatefulWidget {
} }
class ImageCanvasState extends State<ImageCanvas> { class ImageCanvasState extends State<ImageCanvas> {
bool _isFilled = true; bool _isFilled = WindowPersistence.filled;
final GlobalKey _imageKey = GlobalKey(); final GlobalKey _imageKey = GlobalKey();
double _tx = 0, _ty = 0, _sc = 1.0; double _tx = 0, _ty = 0, _sc = 1.0;
Size _vpSize = Size.zero; Size _vpSize = Size.zero;
@@ -199,7 +200,7 @@ class ImageCanvasState extends State<ImageCanvas> {
} }
void _resetView() { void _resetView() {
_tx = 0; _ty = 0; _sc = 1.0; _isFilled = true; _tx = 0; _ty = 0; _sc = 1.0; _isFilled = WindowPersistence.filled;
_angle = 0; _contrast = 1.0; _saturation = 1.0; _brightness = 0; _angle = 0; _contrast = 1.0; _saturation = 1.0; _brightness = 0;
_usingFullRes = false; _usingFullRes = false;
_imageSize = Size.zero; _imageSize = Size.zero;
@@ -209,6 +210,7 @@ class ImageCanvasState extends State<ImageCanvas> {
void _toggleFillFit() { void _toggleFillFit() {
_isFilled = !_isFilled; _tx = 0; _ty = 0; _sc = 1.0; _isFilled = !_isFilled; _tx = 0; _ty = 0; _sc = 1.0;
_angle = 0; _contrast = 1.0; _saturation = 1.0; _brightness = 0; _angle = 0; _contrast = 1.0; _saturation = 1.0; _brightness = 0;
WindowPersistence.saveFilled(_isFilled);
_markRenderDirty(); _markRenderDirty();
} }
+1 -1
View File
@@ -1,7 +1,7 @@
name: imajviewer name: imajviewer
description: "Ultra-lightweight image viewer for Linux and Windows." description: "Ultra-lightweight image viewer for Linux and Windows."
publish_to: 'none' publish_to: 'none'
version: 1.4.2+10 version: 1.5.0+11
msix_config: msix_config:
display_name: ImajViewer display_name: ImajViewer