From 9f2a675d459e92f5582bda45da731b47078e3e57 Mon Sep 17 00:00:00 2001 From: Zan <69921455+InZan17@users.noreply.github.com> Date: Sat, 21 Sep 2024 21:08:11 +0200 Subject: [PATCH 1/7] Add borderless field --- src/conf.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/conf.rs b/src/conf.rs index 6a6d0378..9a2203f1 100644 --- a/src/conf.rs +++ b/src/conf.rs @@ -162,6 +162,10 @@ pub struct Conf { /// /// Default: false pub fullscreen: bool, + /// Whether the window should be created without borders, ignored on wasm/android. + /// + /// Default: false + pub borderless: bool, /// MSAA sample count /// /// Default: 1 @@ -221,6 +225,7 @@ impl Default for Conf { window_height: 600, high_dpi: false, fullscreen: false, + borderless: false, sample_count: 1, window_resizable: true, icon: Some(Icon::miniquad_logo()), @@ -238,6 +243,7 @@ impl Default for Conf { window_height: 600, high_dpi: true, fullscreen: true, + borderless: false, sample_count: 1, window_resizable: false, icon: Some(Icon::miniquad_logo()), From 7e82fde634ef60a392753b1f397b16dbf3cb319e Mon Sep 17 00:00:00 2001 From: Zan <69921455+InZan17@users.noreply.github.com> Date: Sat, 21 Sep 2024 21:30:44 +0200 Subject: [PATCH 2/7] Use borderless field on Windows --- src/native/windows.rs | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/native/windows.rs b/src/native/windows.rs index a420e820..a8c19a1b 100644 --- a/src/native/windows.rs +++ b/src/native/windows.rs @@ -30,6 +30,7 @@ use libopengl32::LibOpengl32; pub(crate) struct WindowsDisplay { fullscreen: bool, + borderless: bool, dpi_aware: bool, window_resizable: bool, cursor_grabbed: bool, @@ -104,7 +105,7 @@ impl WindowsDisplay { rect.right = (rect.left + new_width as i32) as _; rect.top = (rect.bottom - new_height as i32) as _; - let win_style = get_win_style(self.fullscreen, self.window_resizable); + let win_style = get_win_style(self.fullscreen, self.borderless, self.window_resizable); let win_style_ex: DWORD = unsafe { GetWindowLongA(self.wnd, GWL_EXSTYLE) as _ }; if unsafe { AdjustWindowRectEx( @@ -155,7 +156,8 @@ impl WindowsDisplay { fn set_fullscreen(&mut self, fullscreen: bool) { self.fullscreen = fullscreen as _; - let win_style: DWORD = get_win_style(self.fullscreen, self.window_resizable); + let win_style: DWORD = + get_win_style(self.fullscreen, self.borderless, self.window_resizable); unsafe { #[cfg(target_arch = "x86_64")] @@ -196,12 +198,17 @@ impl WindowsDisplay { } } -fn get_win_style(is_fullscreen: bool, is_resizable: bool) -> DWORD { +fn get_win_style(is_fullscreen: bool, is_borderless: bool, is_resizable: bool) -> DWORD { if is_fullscreen { WS_POPUP | WS_SYSMENU | WS_VISIBLE } else { - let mut win_style: DWORD = - WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + let mut win_style: DWORD = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_MINIMIZEBOX; + + if !is_borderless { + win_style |= WS_CAPTION; + } else { + win_style |= WS_POPUP; + } if is_resizable { win_style |= WS_MAXIMIZEBOX | WS_SIZEBOX; @@ -606,6 +613,7 @@ unsafe fn set_icon(wnd: HWND, icon: &Icon) { unsafe fn create_window( window_title: &str, fullscreen: bool, + borderless: bool, resizable: bool, width: i32, height: i32, @@ -623,7 +631,7 @@ unsafe fn create_window( wndclassw.cbWndExtra = std::mem::size_of::<*mut std::ffi::c_void>() as i32; RegisterClassW(&wndclassw); - let win_style: DWORD; + let win_style: DWORD = get_win_style(fullscreen, borderless, resizable); let win_ex_style: DWORD = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; let mut rect = RECT { left: 0, @@ -633,22 +641,9 @@ unsafe fn create_window( }; if fullscreen { - win_style = WS_POPUP | WS_SYSMENU | WS_VISIBLE; rect.right = GetSystemMetrics(SM_CXSCREEN); rect.bottom = GetSystemMetrics(SM_CYSCREEN); } else { - win_style = if resizable { - WS_CLIPSIBLINGS - | WS_CLIPCHILDREN - | WS_CAPTION - | WS_SYSMENU - | WS_MINIMIZEBOX - | WS_MAXIMIZEBOX - | WS_SIZEBOX - } else { - WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX - }; - rect.right = width; rect.bottom = height; } @@ -857,6 +852,7 @@ where let (wnd, dc) = create_window( &conf.window_title, conf.fullscreen, + conf.borderless, conf.window_resizable, conf.window_width as _, conf.window_height as _, @@ -870,6 +866,7 @@ where let (msg_wnd, msg_dc) = create_msg_window(); let mut display = WindowsDisplay { fullscreen: false, + borderless: false, dpi_aware: false, window_resizable: conf.window_resizable, cursor_grabbed: false, From 993c49c5e01ed83f199108c486ff2c11b81416c2 Mon Sep 17 00:00:00 2001 From: Zan <69921455+InZan17@users.noreply.github.com> Date: Sat, 21 Sep 2024 22:11:28 +0200 Subject: [PATCH 3/7] Use borderless field on Linux X11 --- src/native/linux_x11.rs | 30 +++++++++++++++++++++++++++++- src/native/linux_x11/libx11.rs | 9 +++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/native/linux_x11.rs b/src/native/linux_x11.rs index 12aeea03..2201cbdf 100644 --- a/src/native/linux_x11.rs +++ b/src/native/linux_x11.rs @@ -16,7 +16,7 @@ use crate::{ use libx11::*; -use std::collections::HashMap; +use std::{collections::HashMap, mem}; #[derive(Debug, PartialEq, Eq, Clone)] pub enum X11Error { @@ -261,6 +261,31 @@ impl X11Display { } } + unsafe fn set_borderless(&mut self, window: Window, borderless: bool) { + let hints_atom = (self.libx11.XInternAtom)( + self.display, + b"_MOTIF_WM_HINTS\x00" as *const u8 as *const _, + false as _, + ); + + let mut hints: MWMHints = mem::zeroed(); + + hints.flags = hints_atom; + hints.decorations = if borderless { 0 } else { 1 }; + + (self.libx11.XChangeProperty)( + self.display, + window, + hints_atom as _, + 4 as _, + 32, + PropModeReplace, + &mut hints as *mut _ as *mut _, + 5, + ); + (self.libx11.XFlush)(self.display); + } + unsafe fn set_window_size(&mut self, window: Window, new_width: i32, new_height: i32) { (self.libx11.XResizeWindow)(self.display, window, new_width, new_height); (self.libx11.XFlush)(self.display); @@ -419,6 +444,9 @@ where if conf.fullscreen { display.set_fullscreen(display.window, true); } + if conf.borderless { + display.set_borderless(display.window, true); + } let mut event_handler = (f.take().unwrap())(); diff --git a/src/native/linux_x11/libx11.rs b/src/native/linux_x11/libx11.rs index 8000b342..6c38402b 100644 --- a/src/native/linux_x11/libx11.rs +++ b/src/native/linux_x11/libx11.rs @@ -722,6 +722,15 @@ pub mod Xutil_h { } #[derive(Copy, Clone)] #[repr(C)] + pub struct MWMHints { + pub flags: libc::c_ulong, + pub functions: libc::c_ulong, + pub decorations: libc::c_ulong, + pub input_mode: libc::c_long, + pub status: libc::c_ulong, + } + #[derive(Copy, Clone)] + #[repr(C)] pub struct XWMHints { pub flags: libc::c_long, pub input: libc::c_int, From e0ef13789eef6ee60e6779eb90740adcaea40533 Mon Sep 17 00:00:00 2001 From: Zan <69921455+InZan17@users.noreply.github.com> Date: Sat, 21 Sep 2024 22:21:53 +0200 Subject: [PATCH 4/7] Fix an accidental undo --- src/native/linux_x11.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/linux_x11.rs b/src/native/linux_x11.rs index 2201cbdf..643b37cd 100644 --- a/src/native/linux_x11.rs +++ b/src/native/linux_x11.rs @@ -277,7 +277,7 @@ impl X11Display { self.display, window, hints_atom as _, - 4 as _, + hints_atom as _, 32, PropModeReplace, &mut hints as *mut _ as *mut _, From accb7aea25519796feb738254bdb80294c7d5148 Mon Sep 17 00:00:00 2001 From: Zan <69921455+InZan17@users.noreply.github.com> Date: Sun, 22 Sep 2024 15:58:57 +0200 Subject: [PATCH 5/7] Add set_borderless function for Linux X11 --- src/lib.rs | 7 +++++++ src/native.rs | 1 + src/native/linux_x11.rs | 1 + 3 files changed, 9 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 939758b5..f544eb34 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -266,6 +266,13 @@ pub mod window { .unwrap(); } + pub fn set_borderless(borderless: bool) { + let d = native_display().lock().unwrap(); + d.native_requests + .send(native::Request::SetBorderless(borderless)) + .unwrap(); + } + /// Get current OS clipboard value pub fn clipboard_get() -> Option { let mut d = native_display().lock().unwrap(); diff --git a/src/native.rs b/src/native.rs index 88640a55..45c976a2 100644 --- a/src/native.rs +++ b/src/native.rs @@ -70,6 +70,7 @@ pub(crate) enum Request { SetWindowSize { new_width: u32, new_height: u32 }, SetWindowPosition { new_x: u32, new_y: u32 }, SetFullscreen(bool), + SetBorderless(bool), ShowKeyboard(bool), } diff --git a/src/native/linux_x11.rs b/src/native/linux_x11.rs index 643b37cd..592e611b 100644 --- a/src/native/linux_x11.rs +++ b/src/native/linux_x11.rs @@ -384,6 +384,7 @@ impl X11Display { self.set_window_position(self.window, new_x as _, new_y as _) } SetFullscreen(fullscreen) => self.set_fullscreen(self.window, fullscreen), + SetBorderless(borderless) => self.set_borderless(self.window, borderless), ShowKeyboard(..) => { eprintln!("Not implemented for X11") } From 8950ab0737621b9a8a361f088d903471d03bbfdf Mon Sep 17 00:00:00 2001 From: Zan <69921455+InZan17@users.noreply.github.com> Date: Sun, 24 Nov 2024 00:41:56 +0100 Subject: [PATCH 6/7] Fix borderless not working on Linux --- src/native/linux_x11.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/linux_x11.rs b/src/native/linux_x11.rs index 592e611b..68a5ddd0 100644 --- a/src/native/linux_x11.rs +++ b/src/native/linux_x11.rs @@ -270,7 +270,7 @@ impl X11Display { let mut hints: MWMHints = mem::zeroed(); - hints.flags = hints_atom; + hints.flags = 2; // MWM_HINTS_DECORATIONS hints.decorations = if borderless { 0 } else { 1 }; (self.libx11.XChangeProperty)( From fe94e5b51ca973f0d102ec63cd085745537412c7 Mon Sep 17 00:00:00 2001 From: Zan <69921455+InZan17@users.noreply.github.com> Date: Sun, 24 Nov 2024 00:49:34 +0100 Subject: [PATCH 7/7] Add set_borderless function for Windows --- src/native/windows.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/native/windows.rs b/src/native/windows.rs index a8c19a1b..72c94484 100644 --- a/src/native/windows.rs +++ b/src/native/windows.rs @@ -196,6 +196,22 @@ impl WindowsDisplay { ShowWindow(self.wnd, SW_SHOW); }; } + + fn set_borderless(&mut self, borderless: bool) { + self.borderless = borderless as _; + + let win_style: DWORD = + get_win_style(self.fullscreen, self.borderless, self.window_resizable); + + unsafe { + #[cfg(target_arch = "x86_64")] + SetWindowLongPtrA(self.wnd, GWL_STYLE, win_style as _); + #[cfg(target_arch = "i686")] + SetWindowLong(self.wnd, GWL_STYLE, win_style as _); + + ShowWindow(self.wnd, SW_SHOW); + }; + } } fn get_win_style(is_fullscreen: bool, is_borderless: bool, is_resizable: bool) -> DWORD { @@ -833,6 +849,7 @@ impl WindowsDisplay { } => self.set_window_size(new_width as _, new_height as _), SetWindowPosition { new_x, new_y } => self.set_window_position(new_x, new_y), SetFullscreen(fullscreen) => self.set_fullscreen(fullscreen), + SetBorderless(borderless) => self.set_borderless(borderless), ShowKeyboard(show) => { eprintln!("Not implemented for windows") }