This commit is contained in:
Kayleigh McMillan 2026-04-30 19:06:15 +05:30 committed by GitHub
commit 0b6d8bb355
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 93 additions and 1 deletions

View file

@ -19,6 +19,7 @@ winapi = { version = "0.3.9", features = [
"wincon",
"winuser",
"namedpipeapi",
"dwmapi",
] }
webview2 = "0.1.4"
webview2-sys = "0.1.1"

View file

@ -130,7 +130,11 @@ impl MainWindow {
self.webview.dev_tools.set(self.dev_tools).ok();
if let Some(hwnd) = self.window.handle.hwnd() {
if let Ok(mut saved_style) = self.saved_window_style.try_borrow_mut() {
saved_style.center_window(hwnd, WINDOW_MIN_WIDTH, WINDOW_MIN_HEIGHT);
if !saved_style.restore_window_state(hwnd) {
saved_style.center_window(hwnd, WINDOW_MIN_WIDTH, WINDOW_MIN_HEIGHT);
}
// Set title bar to Stremio purple (#6B5B95 -> COLORREF 0x00955B6B)
saved_style.set_title_bar_color(hwnd, 0x00955B6B);
}
}
@ -419,6 +423,12 @@ impl MainWindow {
}
}
fn on_quit(&self, data: &nwg::EventData) {
if let (Some(hwnd), Ok(saved_style)) = (
self.window.handle.hwnd(),
self.saved_window_style.try_borrow(),
) {
saved_style.save_window_state(hwnd);
}
if let nwg::EventData::OnWindowClose(data) = data {
data.close(false);
}

View file

@ -1,4 +1,49 @@
use std::{cmp, mem};
use std::path::PathBuf;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct SavedWindowGeometry {
x: i32,
y: i32,
width: i32,
height: i32,
maximized: bool,
}
impl SavedWindowGeometry {
fn config_path() -> Option<PathBuf> {
std::env::current_exe().ok().and_then(|p| p.parent().map(|d| d.join("window_state.json")))
}
pub fn save(hwnd: HWND) {
use winapi::um::winuser::{GetWindowPlacement, WINDOWPLACEMENT, IsZoomed};
let maximized = unsafe { IsZoomed(hwnd) } != 0;
let mut wp: WINDOWPLACEMENT = unsafe { mem::zeroed() };
wp.length = mem::size_of::<WINDOWPLACEMENT>() as u32;
if unsafe { GetWindowPlacement(hwnd, &mut wp) } == 0 {
return;
}
let state = SavedWindowGeometry {
x: wp.rcNormalPosition.left,
y: wp.rcNormalPosition.top,
width: wp.rcNormalPosition.right - wp.rcNormalPosition.left,
height: wp.rcNormalPosition.bottom - wp.rcNormalPosition.top,
maximized,
};
if let Some(path) = Self::config_path() {
if let Ok(json) = serde_json::to_string_pretty(&state) {
std::fs::write(path, json).ok();
}
}
}
pub fn load() -> Option<SavedWindowGeometry> {
let path = Self::config_path()?;
let json = std::fs::read_to_string(path).ok()?;
serde_json::from_str(&json).ok()
}
}
use winapi::shared::windef::HWND;
use winapi::um::winuser::{
GetForegroundWindow, GetMonitorInfoA, GetSystemMetrics, GetWindowLongA, GetWindowRect,
@ -148,6 +193,42 @@ impl WindowStyle {
}
self.ex_style = unsafe { GetWindowLongA(hwnd, GWL_EXSTYLE) };
}
/// Restores window position from saved state. Returns true if restored.
pub fn restore_window_state(&mut self, hwnd: HWND) -> bool {
if let Some(state) = SavedWindowGeometry::load() {
self.pos = (state.x, state.y);
self.size = (state.width, state.height);
self.show_window_at(hwnd, HWND_NOTOPMOST);
if state.maximized {
use winapi::um::winuser::{ShowWindow, SW_SHOWMAXIMIZED};
unsafe { ShowWindow(hwnd, SW_SHOWMAXIMIZED); }
}
true
} else {
false
}
}
/// Saves current window position and state to disk.
pub fn save_window_state(&self, hwnd: HWND) {
SavedWindowGeometry::save(hwnd);
}
/// Sets the window title bar color using DWM API (Windows 10 build 22000+).
/// Color format is COLORREF (0x00BBGGRR).
pub fn set_title_bar_color(&self, hwnd: HWND, color: u32) {
use winapi::um::dwmapi::DwmSetWindowAttribute;
const DWMWA_CAPTION_COLOR: u32 = 35;
unsafe {
DwmSetWindowAttribute(
hwnd,
DWMWA_CAPTION_COLOR,
&color as *const u32 as *const _,
std::mem::size_of::<u32>() as u32,
);
}
}
pub fn set_active(&mut self, hwnd: HWND) {
unsafe {
SetForegroundWindow(hwnd);