@bobfrankston/msger 0.1.148 → 0.1.150
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/cli.js +6 -6
- package/cli.ts +5 -5
- package/msger-native/bin/msgernative-linux-aarch64 +0 -0
- package/msger-native/bin/msgernative.exe +0 -0
- package/msger-native/src/main.rs +160 -17
- package/msger.png +0 -0
- package/package.json +1 -1
- package/shower.d.ts +1 -1
- package/shower.ts +1 -1
package/README.md
CHANGED
|
@@ -141,7 +141,7 @@ msger -title "Test" -message "Saving config..." -save test.json
|
|
|
141
141
|
"autoSize": false,
|
|
142
142
|
"alwaysOnTop": false,
|
|
143
143
|
"fullscreen": false,
|
|
144
|
-
"
|
|
144
|
+
"zoom": 100,
|
|
145
145
|
"debug": false,
|
|
146
146
|
"icon": "path/to/icon.png",
|
|
147
147
|
"dev": false
|
|
@@ -172,7 +172,7 @@ msger -title "Test" -message "Saving config..." -save test.json
|
|
|
172
172
|
| `autoSize` | boolean | true when no size | Auto-resize window to fit content |
|
|
173
173
|
| `alwaysOnTop` | boolean | false | Keep window on top |
|
|
174
174
|
| `fullscreen` | boolean | false | Start in fullscreen mode |
|
|
175
|
-
| `
|
|
175
|
+
| `zoom` | number | 100 | Initial zoom level (100=100%, 150=150%) |
|
|
176
176
|
| `debug` | boolean | false | Return debug info in result |
|
|
177
177
|
| `icon` | string | null | Path to window icon (.png, .ico) |
|
|
178
178
|
| `dev` | boolean | false | Open DevTools automatically (for debugging HTML/URL content) |
|
|
@@ -383,7 +383,7 @@ interface MessageBoxOptions {
|
|
|
383
383
|
allowInput?: boolean; // Show input field (default: false)
|
|
384
384
|
autoSize?: boolean; // Auto-resize window to fit content (default: true when no size specified)
|
|
385
385
|
alwaysOnTop?: boolean; // Keep window on top of other windows (default: false)
|
|
386
|
-
|
|
386
|
+
zoom?: number; // Initial zoom level (100=100%, 150=150%, 50=50%)
|
|
387
387
|
timeout?: number; // Auto-close after N seconds
|
|
388
388
|
detach?: boolean; // Launch detached from parent process
|
|
389
389
|
fullscreen?: boolean; // Start window in fullscreen mode (F11 to toggle)
|
|
@@ -575,7 +575,7 @@ await showMessageBox({
|
|
|
575
575
|
title: 'Important Alert',
|
|
576
576
|
message: 'This window stays on top!',
|
|
577
577
|
alwaysOnTop: true,
|
|
578
|
-
|
|
578
|
+
zoom: 150
|
|
579
579
|
});
|
|
580
580
|
```
|
|
581
581
|
|
package/cli.js
CHANGED
|
@@ -61,8 +61,8 @@ export default async function main() {
|
|
|
61
61
|
finalOptions.alwaysOnTop = options.alwaysOnTop;
|
|
62
62
|
if (options.fullscreen !== undefined)
|
|
63
63
|
finalOptions.fullscreen = options.fullscreen;
|
|
64
|
-
if (options.
|
|
65
|
-
finalOptions.
|
|
64
|
+
if (options.zoom !== undefined)
|
|
65
|
+
finalOptions.zoom = options.zoom;
|
|
66
66
|
if (options.icon)
|
|
67
67
|
finalOptions.icon = options.icon;
|
|
68
68
|
if (options.dev !== undefined)
|
|
@@ -356,7 +356,7 @@ function parseCliArgs(args) {
|
|
|
356
356
|
if (i + 1 >= args.length) {
|
|
357
357
|
throw new Error('-zoom requires a percentage argument');
|
|
358
358
|
}
|
|
359
|
-
cli.
|
|
359
|
+
cli.zoom = parseFloat(args[++i]);
|
|
360
360
|
i++;
|
|
361
361
|
}
|
|
362
362
|
else if (arg === '-pos' || arg === '--pos') {
|
|
@@ -490,7 +490,7 @@ function parseCliArgs(args) {
|
|
|
490
490
|
detach: cli.detach,
|
|
491
491
|
fullscreen: cli.fullscreen,
|
|
492
492
|
alwaysOnTop: cli.alwaysOnTop,
|
|
493
|
-
|
|
493
|
+
zoom: cli.zoom,
|
|
494
494
|
icon: cli.icon,
|
|
495
495
|
dev: cli.dev,
|
|
496
496
|
debug: cli.debug
|
|
@@ -583,8 +583,8 @@ function saveConfigFile(filePath, options) {
|
|
|
583
583
|
config.alwaysOnTop = options.alwaysOnTop;
|
|
584
584
|
if (options.fullscreen)
|
|
585
585
|
config.fullscreen = options.fullscreen;
|
|
586
|
-
if (options.
|
|
587
|
-
config.
|
|
586
|
+
if (options.zoom && options.zoom !== 100)
|
|
587
|
+
config.zoom = options.zoom;
|
|
588
588
|
if (options.icon)
|
|
589
589
|
config.icon = options.icon;
|
|
590
590
|
if (options.dev)
|
package/cli.ts
CHANGED
|
@@ -52,7 +52,7 @@ export default async function main() {
|
|
|
52
52
|
if (options.timeout !== undefined) finalOptions.timeout = options.timeout;
|
|
53
53
|
if (options.alwaysOnTop !== undefined) finalOptions.alwaysOnTop = options.alwaysOnTop;
|
|
54
54
|
if (options.fullscreen !== undefined) finalOptions.fullscreen = options.fullscreen;
|
|
55
|
-
if (options.
|
|
55
|
+
if (options.zoom !== undefined) finalOptions.zoom = options.zoom;
|
|
56
56
|
if (options.icon) finalOptions.icon = options.icon;
|
|
57
57
|
if (options.dev !== undefined) finalOptions.dev = options.dev;
|
|
58
58
|
if (options.debug !== undefined) finalOptions.debug = options.debug;
|
|
@@ -169,7 +169,7 @@ interface CliOptions {
|
|
|
169
169
|
escapeCloses?: boolean;
|
|
170
170
|
reset?: boolean;
|
|
171
171
|
alwaysOnTop?: boolean;
|
|
172
|
-
|
|
172
|
+
zoom?: number;
|
|
173
173
|
posX?: number;
|
|
174
174
|
posY?: number;
|
|
175
175
|
screen?: number;
|
|
@@ -378,7 +378,7 @@ function parseCliArgs(args: string[]): {
|
|
|
378
378
|
if (i + 1 >= args.length) {
|
|
379
379
|
throw new Error('-zoom requires a percentage argument');
|
|
380
380
|
}
|
|
381
|
-
cli.
|
|
381
|
+
cli.zoom = parseFloat(args[++i]);
|
|
382
382
|
i++;
|
|
383
383
|
} else if (arg === '-pos' || arg === '--pos') {
|
|
384
384
|
if (i + 1 >= args.length) {
|
|
@@ -494,7 +494,7 @@ function parseCliArgs(args: string[]): {
|
|
|
494
494
|
detach: cli.detach,
|
|
495
495
|
fullscreen: cli.fullscreen,
|
|
496
496
|
alwaysOnTop: cli.alwaysOnTop,
|
|
497
|
-
|
|
497
|
+
zoom: cli.zoom,
|
|
498
498
|
icon: cli.icon,
|
|
499
499
|
dev: cli.dev,
|
|
500
500
|
debug: cli.debug
|
|
@@ -580,7 +580,7 @@ function saveConfigFile(filePath: string, options: MessageBoxOptions): void {
|
|
|
580
580
|
if (options.timeout) config.timeout = options.timeout;
|
|
581
581
|
if (options.alwaysOnTop) config.alwaysOnTop = options.alwaysOnTop;
|
|
582
582
|
if (options.fullscreen) config.fullscreen = options.fullscreen;
|
|
583
|
-
if (options.
|
|
583
|
+
if (options.zoom && options.zoom !== 100) config.zoom = options.zoom;
|
|
584
584
|
if (options.icon) config.icon = options.icon;
|
|
585
585
|
if (options.dev) config.dev = options.dev;
|
|
586
586
|
if (options.debug) config.debug = options.debug;
|
|
Binary file
|
|
Binary file
|
package/msger-native/src/main.rs
CHANGED
|
@@ -32,13 +32,33 @@ use windows::core::PCWSTR;
|
|
|
32
32
|
#[cfg(windows)]
|
|
33
33
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
34
34
|
|
|
35
|
-
// Custom menu
|
|
35
|
+
// Custom menu IDs (must be < 0xF000 to avoid conflicts with system commands)
|
|
36
36
|
#[cfg(windows)]
|
|
37
37
|
const IDM_ABOUT: u32 = 0x1000;
|
|
38
|
+
#[cfg(windows)]
|
|
39
|
+
const IDM_ZOOM_IN: u32 = 0x1001;
|
|
40
|
+
#[cfg(windows)]
|
|
41
|
+
const IDM_ZOOM_OUT: u32 = 0x1002;
|
|
42
|
+
#[cfg(windows)]
|
|
43
|
+
const IDM_ZOOM_RESET: u32 = 0x1003;
|
|
44
|
+
#[cfg(windows)]
|
|
45
|
+
const IDM_ZOOM_50: u32 = 0x1010;
|
|
46
|
+
#[cfg(windows)]
|
|
47
|
+
const IDM_ZOOM_75: u32 = 0x1011;
|
|
48
|
+
#[cfg(windows)]
|
|
49
|
+
const IDM_ZOOM_100: u32 = 0x1012;
|
|
50
|
+
#[cfg(windows)]
|
|
51
|
+
const IDM_ZOOM_125: u32 = 0x1013;
|
|
52
|
+
#[cfg(windows)]
|
|
53
|
+
const IDM_ZOOM_150: u32 = 0x1014;
|
|
54
|
+
#[cfg(windows)]
|
|
55
|
+
const IDM_ZOOM_200: u32 = 0x1015;
|
|
38
56
|
|
|
39
|
-
// Global
|
|
57
|
+
// Global flags
|
|
40
58
|
#[cfg(windows)]
|
|
41
59
|
static ABOUT_CLICKED: AtomicBool = AtomicBool::new(false);
|
|
60
|
+
#[cfg(windows)]
|
|
61
|
+
static ZOOM_ACTION: std::sync::atomic::AtomicI32 = std::sync::atomic::AtomicI32::new(0);
|
|
42
62
|
|
|
43
63
|
// Window subclass procedure to intercept WM_SYSCOMMAND
|
|
44
64
|
#[cfg(windows)]
|
|
@@ -52,10 +72,48 @@ unsafe extern "system" fn subclass_proc(
|
|
|
52
72
|
) -> LRESULT {
|
|
53
73
|
if msg == WM_SYSCOMMAND {
|
|
54
74
|
let cmd = wparam.0 & 0xFFF0;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
75
|
+
match cmd as u32 {
|
|
76
|
+
IDM_ABOUT => {
|
|
77
|
+
ABOUT_CLICKED.store(true, Ordering::SeqCst);
|
|
78
|
+
return LRESULT(0);
|
|
79
|
+
}
|
|
80
|
+
IDM_ZOOM_IN => {
|
|
81
|
+
ZOOM_ACTION.store(1, Ordering::SeqCst); // Zoom in
|
|
82
|
+
return LRESULT(0);
|
|
83
|
+
}
|
|
84
|
+
IDM_ZOOM_OUT => {
|
|
85
|
+
ZOOM_ACTION.store(2, Ordering::SeqCst); // Zoom out
|
|
86
|
+
return LRESULT(0);
|
|
87
|
+
}
|
|
88
|
+
IDM_ZOOM_RESET => {
|
|
89
|
+
ZOOM_ACTION.store(100, Ordering::SeqCst); // Reset to 100%
|
|
90
|
+
return LRESULT(0);
|
|
91
|
+
}
|
|
92
|
+
IDM_ZOOM_50 => {
|
|
93
|
+
ZOOM_ACTION.store(50, Ordering::SeqCst);
|
|
94
|
+
return LRESULT(0);
|
|
95
|
+
}
|
|
96
|
+
IDM_ZOOM_75 => {
|
|
97
|
+
ZOOM_ACTION.store(75, Ordering::SeqCst);
|
|
98
|
+
return LRESULT(0);
|
|
99
|
+
}
|
|
100
|
+
IDM_ZOOM_100 => {
|
|
101
|
+
ZOOM_ACTION.store(100, Ordering::SeqCst);
|
|
102
|
+
return LRESULT(0);
|
|
103
|
+
}
|
|
104
|
+
IDM_ZOOM_125 => {
|
|
105
|
+
ZOOM_ACTION.store(125, Ordering::SeqCst);
|
|
106
|
+
return LRESULT(0);
|
|
107
|
+
}
|
|
108
|
+
IDM_ZOOM_150 => {
|
|
109
|
+
ZOOM_ACTION.store(150, Ordering::SeqCst);
|
|
110
|
+
return LRESULT(0);
|
|
111
|
+
}
|
|
112
|
+
IDM_ZOOM_200 => {
|
|
113
|
+
ZOOM_ACTION.store(200, Ordering::SeqCst);
|
|
114
|
+
return LRESULT(0);
|
|
115
|
+
}
|
|
116
|
+
_ => {}
|
|
59
117
|
}
|
|
60
118
|
}
|
|
61
119
|
DefSubclassProc(hwnd, msg, wparam, lparam)
|
|
@@ -120,7 +178,7 @@ struct MessageBoxOptions {
|
|
|
120
178
|
#[serde(default)]
|
|
121
179
|
fullscreen: bool,
|
|
122
180
|
#[serde(default)]
|
|
123
|
-
|
|
181
|
+
zoom: Option<f64>,
|
|
124
182
|
#[serde(default)]
|
|
125
183
|
debug: bool,
|
|
126
184
|
#[serde(default)]
|
|
@@ -289,7 +347,7 @@ fn generate_html(options: &MessageBoxOptions) -> String {
|
|
|
289
347
|
.replace("{FULLSCREEN}", if options.fullscreen { "true" } else { "false" })
|
|
290
348
|
.replace("{ESCAPE_CLOSES}", if options.escape_closes { "true" } else { "false" })
|
|
291
349
|
.replace("{RESET}", if options.reset { "true" } else { "false" })
|
|
292
|
-
.replace("{ZOOM_PERCENT}", &options.
|
|
350
|
+
.replace("{ZOOM_PERCENT}", &options.zoom.unwrap_or(100.0).to_string())
|
|
293
351
|
.replace("{DEFAULT_BUTTON}", options.buttons.first().unwrap_or(&"Cancel".to_string()))
|
|
294
352
|
.replace("{TIMEOUT_SECONDS}", &options.timeout.map(|t| t.to_string()).unwrap_or_else(|| "0".to_string()));
|
|
295
353
|
|
|
@@ -389,8 +447,22 @@ fn main() {
|
|
|
389
447
|
let icon = if let Some(ref icon_path) = options.icon {
|
|
390
448
|
load_icon(icon_path)
|
|
391
449
|
} else {
|
|
392
|
-
// Try default
|
|
393
|
-
|
|
450
|
+
// Try default msger.png next to the binary
|
|
451
|
+
if let Ok(exe_path) = std::env::current_exe() {
|
|
452
|
+
if let Some(exe_dir) = exe_path.parent() {
|
|
453
|
+
let default_icon = exe_dir.join("msger.png");
|
|
454
|
+
if default_icon.exists() {
|
|
455
|
+
load_icon(default_icon.to_str().unwrap_or("msger.png"))
|
|
456
|
+
} else {
|
|
457
|
+
// Fallback to msger.png in current directory
|
|
458
|
+
load_icon("msger.png")
|
|
459
|
+
}
|
|
460
|
+
} else {
|
|
461
|
+
load_icon("msger.png")
|
|
462
|
+
}
|
|
463
|
+
} else {
|
|
464
|
+
load_icon("msger.png")
|
|
465
|
+
}
|
|
394
466
|
};
|
|
395
467
|
|
|
396
468
|
let mut window_builder = WindowBuilder::new()
|
|
@@ -434,9 +506,45 @@ fn main() {
|
|
|
434
506
|
if !hmenu.is_invalid() {
|
|
435
507
|
// Add separator
|
|
436
508
|
AppendMenuW(hmenu, MF_SEPARATOR, 0, PCWSTR::null()).ok();
|
|
509
|
+
|
|
437
510
|
// Add About item
|
|
438
|
-
let about_text: Vec<u16> = "About (Window Info)\0".encode_utf16().collect();
|
|
511
|
+
let about_text: Vec<u16> = "About msger (Window Info)\0".encode_utf16().collect();
|
|
439
512
|
AppendMenuW(hmenu, MF_STRING, IDM_ABOUT as usize, PCWSTR(about_text.as_ptr())).ok();
|
|
513
|
+
|
|
514
|
+
// Add another separator
|
|
515
|
+
AppendMenuW(hmenu, MF_SEPARATOR, 0, PCWSTR::null()).ok();
|
|
516
|
+
|
|
517
|
+
// Add Zoom controls
|
|
518
|
+
let zoom_in: Vec<u16> = "Zoom In\tCtrl++\0".encode_utf16().collect();
|
|
519
|
+
AppendMenuW(hmenu, MF_STRING, IDM_ZOOM_IN as usize, PCWSTR(zoom_in.as_ptr())).ok();
|
|
520
|
+
|
|
521
|
+
let zoom_out: Vec<u16> = "Zoom Out\tCtrl+-\0".encode_utf16().collect();
|
|
522
|
+
AppendMenuW(hmenu, MF_STRING, IDM_ZOOM_OUT as usize, PCWSTR(zoom_out.as_ptr())).ok();
|
|
523
|
+
|
|
524
|
+
let zoom_reset: Vec<u16> = "Reset Zoom\tCtrl+0\0".encode_utf16().collect();
|
|
525
|
+
AppendMenuW(hmenu, MF_STRING, IDM_ZOOM_RESET as usize, PCWSTR(zoom_reset.as_ptr())).ok();
|
|
526
|
+
|
|
527
|
+
// Add separator before preset zooms
|
|
528
|
+
AppendMenuW(hmenu, MF_SEPARATOR, 0, PCWSTR::null()).ok();
|
|
529
|
+
|
|
530
|
+
// Add preset zoom levels
|
|
531
|
+
let zoom_50: Vec<u16> = "Zoom 50%\0".encode_utf16().collect();
|
|
532
|
+
AppendMenuW(hmenu, MF_STRING, IDM_ZOOM_50 as usize, PCWSTR(zoom_50.as_ptr())).ok();
|
|
533
|
+
|
|
534
|
+
let zoom_75: Vec<u16> = "Zoom 75%\0".encode_utf16().collect();
|
|
535
|
+
AppendMenuW(hmenu, MF_STRING, IDM_ZOOM_75 as usize, PCWSTR(zoom_75.as_ptr())).ok();
|
|
536
|
+
|
|
537
|
+
let zoom_100: Vec<u16> = "Zoom 100%\0".encode_utf16().collect();
|
|
538
|
+
AppendMenuW(hmenu, MF_STRING, IDM_ZOOM_100 as usize, PCWSTR(zoom_100.as_ptr())).ok();
|
|
539
|
+
|
|
540
|
+
let zoom_125: Vec<u16> = "Zoom 125%\0".encode_utf16().collect();
|
|
541
|
+
AppendMenuW(hmenu, MF_STRING, IDM_ZOOM_125 as usize, PCWSTR(zoom_125.as_ptr())).ok();
|
|
542
|
+
|
|
543
|
+
let zoom_150: Vec<u16> = "Zoom 150%\0".encode_utf16().collect();
|
|
544
|
+
AppendMenuW(hmenu, MF_STRING, IDM_ZOOM_150 as usize, PCWSTR(zoom_150.as_ptr())).ok();
|
|
545
|
+
|
|
546
|
+
let zoom_200: Vec<u16> = "Zoom 200%\0".encode_utf16().collect();
|
|
547
|
+
AppendMenuW(hmenu, MF_STRING, IDM_ZOOM_200 as usize, PCWSTR(zoom_200.as_ptr())).ok();
|
|
440
548
|
}
|
|
441
549
|
// Install window subclass to intercept WM_SYSCOMMAND
|
|
442
550
|
let _ = SetWindowSubclass(hwnd, Some(subclass_proc), 1, 0).ok();
|
|
@@ -696,6 +804,13 @@ fn main() {
|
|
|
696
804
|
// Check for About menu click
|
|
697
805
|
#[cfg(windows)]
|
|
698
806
|
if ABOUT_CLICKED.swap(false, Ordering::SeqCst) {
|
|
807
|
+
// Get current zoom from the page
|
|
808
|
+
let zoom_script = "document.body.style.zoom || '100%'";
|
|
809
|
+
let current_zoom = match webview.evaluate_script(zoom_script) {
|
|
810
|
+
Ok(_) => "100%".to_string(), // Default if can't get it
|
|
811
|
+
Err(_) => "100%".to_string(),
|
|
812
|
+
};
|
|
813
|
+
|
|
699
814
|
// Get window information
|
|
700
815
|
let position = window_clone.outer_position().unwrap_or_default();
|
|
701
816
|
let inner_size = window_clone.inner_size();
|
|
@@ -712,27 +827,29 @@ fn main() {
|
|
|
712
827
|
let logical_outer_height = (outer_size.height as f64 / scale_factor) as i32;
|
|
713
828
|
|
|
714
829
|
let info = format!(
|
|
715
|
-
"
|
|
716
|
-
|
|
830
|
+
"msger v{}\\n\\n\
|
|
831
|
+
Rust/wry-based message viewer\\n\\n\
|
|
832
|
+
Position: x={}, y={}\\n\
|
|
717
833
|
Logical Size (API): {}x{} inner\\n\
|
|
718
834
|
Physical Size (Screen): {}x{} inner\\n\
|
|
719
835
|
Outer Size (Physical): {}x{}\\n\
|
|
720
836
|
Outer Size (Logical): {}x{}\\n\\n\
|
|
837
|
+
Current Zoom: {}\\n\
|
|
721
838
|
Scale Factor: {:.2} ({}% DPI)\\n\
|
|
722
839
|
Maximized: {}\\n\
|
|
723
840
|
Fullscreen: {}\\n\
|
|
724
|
-
Always On Top: {}
|
|
725
|
-
|
|
841
|
+
Always On Top: {}",
|
|
842
|
+
get_package_version().unwrap_or_else(|| "unknown".to_string()),
|
|
726
843
|
position.x, position.y,
|
|
727
844
|
logical_inner_width, logical_inner_height,
|
|
728
845
|
inner_size.width, inner_size.height,
|
|
729
846
|
outer_size.width, outer_size.height,
|
|
730
847
|
logical_outer_width, logical_outer_height,
|
|
848
|
+
current_zoom,
|
|
731
849
|
scale_factor, (scale_factor * 100.0) as i32,
|
|
732
850
|
is_maximized,
|
|
733
851
|
is_fullscreen,
|
|
734
|
-
is_always_on_top
|
|
735
|
-
get_package_version().unwrap_or_else(|| "unknown".to_string())
|
|
852
|
+
is_always_on_top
|
|
736
853
|
);
|
|
737
854
|
|
|
738
855
|
// Show the info in an alert
|
|
@@ -742,6 +859,32 @@ fn main() {
|
|
|
742
859
|
}
|
|
743
860
|
}
|
|
744
861
|
|
|
862
|
+
// Check for zoom menu actions
|
|
863
|
+
#[cfg(windows)]
|
|
864
|
+
{
|
|
865
|
+
let zoom_action = ZOOM_ACTION.swap(0, Ordering::SeqCst);
|
|
866
|
+
if zoom_action != 0 {
|
|
867
|
+
let zoom_script = match zoom_action {
|
|
868
|
+
1 => {
|
|
869
|
+
// Zoom in - get current and increase by 25%
|
|
870
|
+
"var currentZoom = parseFloat(document.body.style.zoom || '100'); document.body.style.zoom = (currentZoom + 25) + '%';"
|
|
871
|
+
}
|
|
872
|
+
2 => {
|
|
873
|
+
// Zoom out - get current and decrease by 25%
|
|
874
|
+
"var currentZoom = parseFloat(document.body.style.zoom || '100'); document.body.style.zoom = Math.max(25, currentZoom - 25) + '%';"
|
|
875
|
+
}
|
|
876
|
+
percent => {
|
|
877
|
+
// Set specific zoom level
|
|
878
|
+
&format!("document.body.style.zoom = '{}%';", percent)
|
|
879
|
+
}
|
|
880
|
+
};
|
|
881
|
+
|
|
882
|
+
if let Err(e) = webview.evaluate_script(zoom_script) {
|
|
883
|
+
eprintln!("Failed to set zoom: {}", e);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
745
888
|
// Check timeout
|
|
746
889
|
if let Some(deadline) = timeout_instant {
|
|
747
890
|
if std::time::Instant::now() >= deadline {
|
package/msger.png
ADDED
|
Binary file
|
package/package.json
CHANGED
package/shower.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export interface MessageBoxOptions {
|
|
|
24
24
|
y: number; /** Window Y position in pixels */
|
|
25
25
|
screen?: number; /** Optional screen index (0-based, Windows only) - NOT used by Rust binary */
|
|
26
26
|
};
|
|
27
|
-
|
|
27
|
+
zoom?: number; /** Initial zoom level as percentage (100=100%, 150=150%, 50=50%, etc.) */
|
|
28
28
|
autoSize?: boolean; /** Automatically resize window to fit content (default: false) */
|
|
29
29
|
alwaysOnTop?: boolean; /** Keep window on top of other windows (default: false) */
|
|
30
30
|
buttons?: string[]; /** Array of button labels to display (default: ['OK']) */
|
package/shower.ts
CHANGED
|
@@ -62,7 +62,7 @@ export interface MessageBoxOptions {
|
|
|
62
62
|
y: number; /** Window Y position in pixels */
|
|
63
63
|
screen?: number; /** Optional screen index (0-based, Windows only) - NOT used by Rust binary */
|
|
64
64
|
};
|
|
65
|
-
|
|
65
|
+
zoom?: number; /** Initial zoom level as percentage (100=100%, 150=150%, 50=50%, etc.) */
|
|
66
66
|
autoSize?: boolean; /** Automatically resize window to fit content (default: false) */
|
|
67
67
|
alwaysOnTop?: boolean; /** Keep window on top of other windows (default: false) */
|
|
68
68
|
buttons?: string[]; /** Array of button labels to display (default: ['OK']) */
|