mirror of
https://github.com/Stremio/stremio-shell-ng.git
synced 2026-05-12 21:40:47 +00:00
Merge pull request #11 from Stremio/fix-full-screen
fix: Retrieve active monitor before going full screen
This commit is contained in:
commit
c58cbafa69
1 changed files with 156 additions and 147 deletions
|
|
@ -1,147 +1,156 @@
|
||||||
use std::{cmp, mem};
|
use std::{cmp, mem};
|
||||||
use winapi::shared::windef::HWND;
|
use winapi::shared::windef::HWND;
|
||||||
use winapi::um::winuser::{
|
use winapi::um::winuser::{
|
||||||
GetForegroundWindow, GetSystemMetrics, GetWindowLongA, GetWindowRect, IsIconic, IsZoomed,
|
GetForegroundWindow, GetMonitorInfoA, GetSystemMetrics, GetWindowLongA, GetWindowRect,
|
||||||
SetForegroundWindow, SetWindowLongA, SetWindowPos, GWL_EXSTYLE, GWL_STYLE, HWND_NOTOPMOST,
|
IsIconic, IsZoomed, MonitorFromWindow, SetForegroundWindow, SetWindowLongA, SetWindowPos,
|
||||||
HWND_TOPMOST, SM_CXSCREEN, SM_CYSCREEN, SWP_FRAMECHANGED, SWP_NOMOVE, SWP_NOSIZE, WS_CAPTION,
|
GWL_EXSTYLE, GWL_STYLE, HWND_NOTOPMOST, HWND_TOPMOST, MONITORINFO, MONITOR_DEFAULTTONEAREST,
|
||||||
WS_EX_CLIENTEDGE, WS_EX_DLGMODALFRAME, WS_EX_STATICEDGE, WS_EX_TOPMOST, WS_EX_WINDOWEDGE,
|
SM_CXSCREEN, SM_CYSCREEN, SWP_FRAMECHANGED, SWP_NOMOVE, SWP_NOSIZE, WS_CAPTION,
|
||||||
WS_THICKFRAME,
|
WS_EX_CLIENTEDGE, WS_EX_DLGMODALFRAME, WS_EX_STATICEDGE, WS_EX_TOPMOST, WS_EX_WINDOWEDGE,
|
||||||
};
|
WS_THICKFRAME,
|
||||||
// https://doc.qt.io/qt-5/qt.html#WindowState-enum
|
};
|
||||||
bitflags! {
|
// https://doc.qt.io/qt-5/qt.html#WindowState-enum
|
||||||
struct WindowState: u8 {
|
bitflags! {
|
||||||
const MINIMIZED = 0x01;
|
struct WindowState: u8 {
|
||||||
const MAXIMIZED = 0x02;
|
const MINIMIZED = 0x01;
|
||||||
const FULL_SCREEN = 0x04;
|
const MAXIMIZED = 0x02;
|
||||||
const ACTIVE = 0x08;
|
const FULL_SCREEN = 0x04;
|
||||||
}
|
const ACTIVE = 0x08;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#[derive(Default, Clone)]
|
|
||||||
pub struct WindowStyle {
|
#[derive(Default, Clone)]
|
||||||
pub full_screen: bool,
|
pub struct WindowStyle {
|
||||||
pub pos: (i32, i32),
|
pub full_screen: bool,
|
||||||
pub size: (i32, i32),
|
pub pos: (i32, i32),
|
||||||
pub style: i32,
|
pub size: (i32, i32),
|
||||||
pub ex_style: i32,
|
pub style: i32,
|
||||||
}
|
pub ex_style: i32,
|
||||||
|
}
|
||||||
impl WindowStyle {
|
|
||||||
pub fn get_window_state(self, hwnd: HWND) -> u32 {
|
impl WindowStyle {
|
||||||
let mut state: WindowState = WindowState::empty();
|
pub fn get_window_state(self, hwnd: HWND) -> u32 {
|
||||||
if 0 != unsafe { IsIconic(hwnd) } {
|
let mut state: WindowState = WindowState::empty();
|
||||||
state |= WindowState::MINIMIZED;
|
if 0 != unsafe { IsIconic(hwnd) } {
|
||||||
}
|
state |= WindowState::MINIMIZED;
|
||||||
if 0 != unsafe { IsZoomed(hwnd) } {
|
}
|
||||||
state |= WindowState::MAXIMIZED;
|
if 0 != unsafe { IsZoomed(hwnd) } {
|
||||||
}
|
state |= WindowState::MAXIMIZED;
|
||||||
if hwnd == unsafe { GetForegroundWindow() } {
|
}
|
||||||
state |= WindowState::ACTIVE
|
if hwnd == unsafe { GetForegroundWindow() } {
|
||||||
}
|
state |= WindowState::ACTIVE
|
||||||
if self.full_screen {
|
}
|
||||||
state |= WindowState::FULL_SCREEN;
|
if self.full_screen {
|
||||||
}
|
state |= WindowState::FULL_SCREEN;
|
||||||
state.bits() as u32
|
}
|
||||||
}
|
state.bits() as u32
|
||||||
pub fn is_window_minimized(&self, hwnd: HWND) -> bool {
|
}
|
||||||
0 != unsafe { IsIconic(hwnd) }
|
pub fn is_window_minimized(&self, hwnd: HWND) -> bool {
|
||||||
}
|
0 != unsafe { IsIconic(hwnd) }
|
||||||
pub fn show_window_at(&self, hwnd: HWND, pos: HWND) {
|
}
|
||||||
unsafe {
|
pub fn show_window_at(&self, hwnd: HWND, pos: HWND) {
|
||||||
SetWindowPos(
|
unsafe {
|
||||||
hwnd,
|
SetWindowPos(
|
||||||
pos,
|
hwnd,
|
||||||
self.pos.0,
|
pos,
|
||||||
self.pos.1,
|
self.pos.0,
|
||||||
self.size.0,
|
self.pos.1,
|
||||||
self.size.1,
|
self.size.0,
|
||||||
SWP_FRAMECHANGED,
|
self.size.1,
|
||||||
);
|
SWP_FRAMECHANGED,
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
pub fn center_window(&mut self, hwnd: HWND, min_width: i32, min_height: i32) {
|
}
|
||||||
let monitor_w = unsafe { GetSystemMetrics(SM_CXSCREEN) };
|
pub fn center_window(&mut self, hwnd: HWND, min_width: i32, min_height: i32) {
|
||||||
let monitor_h = unsafe { GetSystemMetrics(SM_CYSCREEN) };
|
let monitor_w = unsafe { GetSystemMetrics(SM_CXSCREEN) };
|
||||||
let small_side = cmp::min(monitor_w, monitor_h) * 70 / 100;
|
let monitor_h = unsafe { GetSystemMetrics(SM_CYSCREEN) };
|
||||||
self.size = (
|
let small_side = cmp::min(monitor_w, monitor_h) * 70 / 100;
|
||||||
cmp::max(small_side * 16 / 9, min_width),
|
self.size = (
|
||||||
cmp::max(small_side, min_height),
|
cmp::max(small_side * 16 / 9, min_width),
|
||||||
);
|
cmp::max(small_side, min_height),
|
||||||
self.pos = ((monitor_w - self.size.0) / 2, (monitor_h - self.size.1) / 2);
|
);
|
||||||
self.show_window_at(hwnd, HWND_NOTOPMOST);
|
self.pos = ((monitor_w - self.size.0) / 2, (monitor_h - self.size.1) / 2);
|
||||||
}
|
self.show_window_at(hwnd, HWND_NOTOPMOST);
|
||||||
pub fn toggle_full_screen(&mut self, hwnd: HWND) {
|
}
|
||||||
if self.full_screen {
|
pub fn toggle_full_screen(&mut self, hwnd: HWND) {
|
||||||
let topmost = if self.ex_style as u32 & WS_EX_TOPMOST == WS_EX_TOPMOST {
|
if self.full_screen {
|
||||||
HWND_TOPMOST
|
let topmost = if self.ex_style as u32 & WS_EX_TOPMOST == WS_EX_TOPMOST {
|
||||||
} else {
|
HWND_TOPMOST
|
||||||
HWND_NOTOPMOST
|
} else {
|
||||||
};
|
HWND_NOTOPMOST
|
||||||
unsafe {
|
};
|
||||||
SetWindowLongA(hwnd, GWL_STYLE, self.style);
|
unsafe {
|
||||||
SetWindowLongA(hwnd, GWL_EXSTYLE, self.ex_style);
|
SetWindowLongA(hwnd, GWL_STYLE, self.style);
|
||||||
}
|
SetWindowLongA(hwnd, GWL_EXSTYLE, self.ex_style);
|
||||||
self.show_window_at(hwnd, topmost);
|
}
|
||||||
self.full_screen = false;
|
self.show_window_at(hwnd, topmost);
|
||||||
} else {
|
self.full_screen = false;
|
||||||
unsafe {
|
} else {
|
||||||
let mut rect = mem::zeroed();
|
unsafe {
|
||||||
GetWindowRect(hwnd, &mut rect);
|
let mut rect = mem::zeroed();
|
||||||
self.pos = (rect.left, rect.top);
|
GetWindowRect(hwnd, &mut rect);
|
||||||
self.size = ((rect.right - rect.left), (rect.bottom - rect.top));
|
self.pos = (rect.left, rect.top);
|
||||||
self.style = GetWindowLongA(hwnd, GWL_STYLE);
|
self.size = ((rect.right - rect.left), (rect.bottom - rect.top));
|
||||||
self.ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
|
self.style = GetWindowLongA(hwnd, GWL_STYLE);
|
||||||
SetWindowLongA(
|
self.ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
|
||||||
hwnd,
|
|
||||||
GWL_STYLE,
|
let monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||||
self.style & !(WS_CAPTION as i32 | WS_THICKFRAME as i32),
|
let mut monitor_info: MONITORINFO = mem::zeroed();
|
||||||
);
|
monitor_info.cbSize = mem::size_of_val(&monitor_info) as u32;
|
||||||
SetWindowLongA(
|
if GetMonitorInfoA(monitor, &mut monitor_info) == 0 {
|
||||||
hwnd,
|
println!("GetMonitorInfoA failed");
|
||||||
GWL_EXSTYLE,
|
return;
|
||||||
self.ex_style
|
}
|
||||||
& !(WS_EX_DLGMODALFRAME as i32
|
SetWindowLongA(
|
||||||
| WS_EX_WINDOWEDGE as i32
|
hwnd,
|
||||||
| WS_EX_CLIENTEDGE as i32
|
GWL_STYLE,
|
||||||
| WS_EX_STATICEDGE as i32),
|
self.style & !(WS_CAPTION as i32 | WS_THICKFRAME as i32),
|
||||||
);
|
);
|
||||||
SetWindowPos(
|
SetWindowLongA(
|
||||||
hwnd,
|
hwnd,
|
||||||
HWND_NOTOPMOST,
|
GWL_EXSTYLE,
|
||||||
0,
|
self.ex_style
|
||||||
0,
|
& !(WS_EX_DLGMODALFRAME as i32
|
||||||
GetSystemMetrics(SM_CXSCREEN),
|
| WS_EX_WINDOWEDGE as i32
|
||||||
GetSystemMetrics(SM_CYSCREEN),
|
| WS_EX_CLIENTEDGE as i32
|
||||||
SWP_FRAMECHANGED,
|
| WS_EX_STATICEDGE as i32),
|
||||||
);
|
);
|
||||||
}
|
SetWindowPos(
|
||||||
self.full_screen = true;
|
hwnd,
|
||||||
}
|
HWND_NOTOPMOST,
|
||||||
}
|
monitor_info.rcMonitor.left,
|
||||||
pub fn toggle_topmost(&mut self, hwnd: HWND) {
|
monitor_info.rcMonitor.top,
|
||||||
let topmost = if unsafe { GetWindowLongA(hwnd, GWL_EXSTYLE) } as u32 & WS_EX_TOPMOST
|
monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
|
||||||
== WS_EX_TOPMOST
|
monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
|
||||||
{
|
SWP_FRAMECHANGED,
|
||||||
HWND_NOTOPMOST
|
);
|
||||||
} else {
|
}
|
||||||
HWND_TOPMOST
|
self.full_screen = true;
|
||||||
};
|
}
|
||||||
unsafe {
|
}
|
||||||
SetWindowPos(
|
pub fn toggle_topmost(&mut self, hwnd: HWND) {
|
||||||
hwnd,
|
let topmost = if unsafe { GetWindowLongA(hwnd, GWL_EXSTYLE) } as u32 & WS_EX_TOPMOST
|
||||||
topmost,
|
== WS_EX_TOPMOST
|
||||||
0,
|
{
|
||||||
0,
|
HWND_NOTOPMOST
|
||||||
0,
|
} else {
|
||||||
0,
|
HWND_TOPMOST
|
||||||
SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED,
|
};
|
||||||
);
|
unsafe {
|
||||||
}
|
SetWindowPos(
|
||||||
self.ex_style = unsafe { GetWindowLongA(hwnd, GWL_EXSTYLE) };
|
hwnd,
|
||||||
}
|
topmost,
|
||||||
pub fn set_active(&mut self, hwnd: HWND) {
|
0,
|
||||||
unsafe {
|
0,
|
||||||
SetForegroundWindow(hwnd);
|
0,
|
||||||
}
|
0,
|
||||||
}
|
SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED,
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
self.ex_style = unsafe { GetWindowLongA(hwnd, GWL_EXSTYLE) };
|
||||||
|
}
|
||||||
|
pub fn set_active(&mut self, hwnd: HWND) {
|
||||||
|
unsafe {
|
||||||
|
SetForegroundWindow(hwnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue