mirror of
https://github.com/Stremio/stremio-shell-ng.git
synced 2026-05-18 19:21:50 +00:00
Merge a022426b14 into bbbe882faf
This commit is contained in:
commit
0b6d8bb355
3 changed files with 93 additions and 1 deletions
|
|
@ -19,6 +19,7 @@ winapi = { version = "0.3.9", features = [
|
||||||
"wincon",
|
"wincon",
|
||||||
"winuser",
|
"winuser",
|
||||||
"namedpipeapi",
|
"namedpipeapi",
|
||||||
|
"dwmapi",
|
||||||
] }
|
] }
|
||||||
webview2 = "0.1.4"
|
webview2 = "0.1.4"
|
||||||
webview2-sys = "0.1.1"
|
webview2-sys = "0.1.1"
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,11 @@ impl MainWindow {
|
||||||
self.webview.dev_tools.set(self.dev_tools).ok();
|
self.webview.dev_tools.set(self.dev_tools).ok();
|
||||||
if let Some(hwnd) = self.window.handle.hwnd() {
|
if let Some(hwnd) = self.window.handle.hwnd() {
|
||||||
if let Ok(mut saved_style) = self.saved_window_style.try_borrow_mut() {
|
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) {
|
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 {
|
if let nwg::EventData::OnWindowClose(data) = data {
|
||||||
data.close(false);
|
data.close(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,49 @@
|
||||||
use std::{cmp, mem};
|
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::shared::windef::HWND;
|
||||||
use winapi::um::winuser::{
|
use winapi::um::winuser::{
|
||||||
GetForegroundWindow, GetMonitorInfoA, GetSystemMetrics, GetWindowLongA, GetWindowRect,
|
GetForegroundWindow, GetMonitorInfoA, GetSystemMetrics, GetWindowLongA, GetWindowRect,
|
||||||
|
|
@ -148,6 +193,42 @@ impl WindowStyle {
|
||||||
}
|
}
|
||||||
self.ex_style = unsafe { GetWindowLongA(hwnd, GWL_EXSTYLE) };
|
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) {
|
pub fn set_active(&mut self, hwnd: HWND) {
|
||||||
unsafe {
|
unsafe {
|
||||||
SetForegroundWindow(hwnd);
|
SetForegroundWindow(hwnd);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue