Windows: Fullscreen (#9728)
~~This is still a work in progress, but to show the public where I am working on it~~ Ready for review TODO: - [x] Justify fullscreen size to display - [x] Record and apply restored size Release Notes: - N/A
This commit is contained in:
parent
fc5a0885f3
commit
35b39e02ce
2 changed files with 82 additions and 9 deletions
|
@ -54,6 +54,7 @@ pub(crate) struct WindowsWindowInner {
|
||||||
display: RefCell<Rc<WindowsDisplay>>,
|
display: RefCell<Rc<WindowsDisplay>>,
|
||||||
last_ime_input: RefCell<Option<String>>,
|
last_ime_input: RefCell<Option<String>>,
|
||||||
click_state: RefCell<ClickState>,
|
click_state: RefCell<ClickState>,
|
||||||
|
fullscreen: Cell<Option<StyleAndBounds>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowsWindowInner {
|
impl WindowsWindowInner {
|
||||||
|
@ -115,6 +116,7 @@ impl WindowsWindowInner {
|
||||||
let display = RefCell::new(display);
|
let display = RefCell::new(display);
|
||||||
let last_ime_input = RefCell::new(None);
|
let last_ime_input = RefCell::new(None);
|
||||||
let click_state = RefCell::new(ClickState::new());
|
let click_state = RefCell::new(ClickState::new());
|
||||||
|
let fullscreen = Cell::new(None);
|
||||||
Self {
|
Self {
|
||||||
hwnd,
|
hwnd,
|
||||||
origin,
|
origin,
|
||||||
|
@ -129,17 +131,71 @@ impl WindowsWindowInner {
|
||||||
display,
|
display,
|
||||||
last_ime_input,
|
last_ime_input,
|
||||||
click_state,
|
click_state,
|
||||||
|
fullscreen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_maximized(&self) -> bool {
|
fn is_maximized(&self) -> bool {
|
||||||
unsafe { IsZoomed(self.hwnd) }.as_bool()
|
!self.is_fullscreen() && unsafe { IsZoomed(self.hwnd) }.as_bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_minimized(&self) -> bool {
|
fn is_minimized(&self) -> bool {
|
||||||
unsafe { IsIconic(self.hwnd) }.as_bool()
|
unsafe { IsIconic(self.hwnd) }.as_bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_fullscreen(&self) -> bool {
|
||||||
|
let fullscreen = self.fullscreen.take();
|
||||||
|
let is_fullscreen = fullscreen.is_some();
|
||||||
|
self.fullscreen.set(fullscreen);
|
||||||
|
is_fullscreen
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn toggle_fullscreen(self: Rc<Self>) {
|
||||||
|
let StyleAndBounds {
|
||||||
|
style,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
cx,
|
||||||
|
cy,
|
||||||
|
} = if let Some(state) = self.fullscreen.take() {
|
||||||
|
state
|
||||||
|
} else {
|
||||||
|
let style = WINDOW_STYLE(unsafe { get_window_long(self.hwnd, GWL_STYLE) } as _);
|
||||||
|
let mut rc = RECT::default();
|
||||||
|
unsafe { GetWindowRect(self.hwnd, &mut rc) }.log_err();
|
||||||
|
self.fullscreen.set(Some(StyleAndBounds {
|
||||||
|
style,
|
||||||
|
x: rc.left,
|
||||||
|
y: rc.top,
|
||||||
|
cx: rc.right - rc.left,
|
||||||
|
cy: rc.bottom - rc.top,
|
||||||
|
}));
|
||||||
|
let style = style
|
||||||
|
& !(WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_CAPTION);
|
||||||
|
let bounds = self.display.borrow().clone().bounds();
|
||||||
|
StyleAndBounds {
|
||||||
|
style,
|
||||||
|
x: bounds.left().0 as i32,
|
||||||
|
y: bounds.top().0 as i32,
|
||||||
|
cx: bounds.size.width.0 as i32,
|
||||||
|
cy: bounds.size.height.0 as i32,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
unsafe { set_window_long(self.hwnd, GWL_STYLE, style.0 as isize) };
|
||||||
|
unsafe {
|
||||||
|
SetWindowPos(
|
||||||
|
self.hwnd,
|
||||||
|
HWND::default(),
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
cx,
|
||||||
|
cy,
|
||||||
|
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.log_err();
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn title_bar_padding(&self) -> Pixels {
|
pub(crate) fn title_bar_padding(&self) -> Pixels {
|
||||||
// using USER_DEFAULT_SCREEN_DPI because GPUI handles the scale with the scale factor
|
// using USER_DEFAULT_SCREEN_DPI because GPUI handles the scale with the scale factor
|
||||||
let padding = unsafe { GetSystemMetricsForDpi(SM_CXPADDEDBORDER, USER_DEFAULT_SCREEN_DPI) };
|
let padding = unsafe { GetSystemMetricsForDpi(SM_CXPADDEDBORDER, USER_DEFAULT_SCREEN_DPI) };
|
||||||
|
@ -821,7 +877,7 @@ impl WindowsWindowInner {
|
||||||
|
|
||||||
/// SEE: https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize
|
/// SEE: https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize
|
||||||
fn handle_calc_client_size(&self, wparam: WPARAM, lparam: LPARAM) -> Option<isize> {
|
fn handle_calc_client_size(&self, wparam: WPARAM, lparam: LPARAM) -> Option<isize> {
|
||||||
if !self.hide_title_bar {
|
if !self.hide_title_bar || self.is_fullscreen() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,6 +997,10 @@ impl WindowsWindowInner {
|
||||||
return Some(hit.0);
|
return Some(hit.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.is_fullscreen() {
|
||||||
|
return Some(HTCLIENT as _);
|
||||||
|
}
|
||||||
|
|
||||||
let dpi = unsafe { GetDpiForWindow(self.hwnd) };
|
let dpi = unsafe { GetDpiForWindow(self.hwnd) };
|
||||||
let frame_y = unsafe { GetSystemMetricsForDpi(SM_CYFRAME, dpi) };
|
let frame_y = unsafe { GetSystemMetricsForDpi(SM_CYFRAME, dpi) };
|
||||||
let padding = unsafe { GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi) };
|
let padding = unsafe { GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi) };
|
||||||
|
@ -1425,12 +1485,16 @@ impl PlatformWindow for WindowsWindow {
|
||||||
unsafe { ShowWindowAsync(self.inner.hwnd, SW_MAXIMIZE) };
|
unsafe { ShowWindowAsync(self.inner.hwnd, SW_MAXIMIZE) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo(windows)
|
fn toggle_fullscreen(&self) {
|
||||||
fn toggle_fullscreen(&self) {}
|
self.inner
|
||||||
|
.platform_inner
|
||||||
|
.foreground_executor
|
||||||
|
.spawn(self.inner.clone().toggle_fullscreen())
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
|
||||||
// todo(windows)
|
|
||||||
fn is_fullscreen(&self) -> bool {
|
fn is_fullscreen(&self) -> bool {
|
||||||
false
|
self.inner.is_fullscreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo(windows)
|
// todo(windows)
|
||||||
|
@ -1790,6 +1854,14 @@ fn logical_point(x: f32, y: f32, scale_factor: f32) -> Point<Pixels> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StyleAndBounds {
|
||||||
|
style: WINDOW_STYLE,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
cx: i32,
|
||||||
|
cy: i32,
|
||||||
|
}
|
||||||
|
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-dragqueryfilew
|
// https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-dragqueryfilew
|
||||||
const DRAGDROP_GET_FILES_COUNT: u32 = 0xFFFFFFFF;
|
const DRAGDROP_GET_FILES_COUNT: u32 = 0xFFFFFFFF;
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/controls/ttm-setdelaytime?redirectedfrom=MSDN
|
// https://learn.microsoft.com/en-us/windows/win32/controls/ttm-setdelaytime?redirectedfrom=MSDN
|
||||||
|
|
|
@ -104,8 +104,9 @@ impl RenderOnce for TitleBar {
|
||||||
.w_full()
|
.w_full()
|
||||||
.children(self.children),
|
.children(self.children),
|
||||||
)
|
)
|
||||||
.when(self.platform_style == PlatformStyle::Windows, |title_bar| {
|
.when(
|
||||||
title_bar.child(WindowsWindowControls::new(height))
|
self.platform_style == PlatformStyle::Windows && !cx.is_fullscreen(),
|
||||||
})
|
|title_bar| title_bar.child(WindowsWindowControls::new(height)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue