#![allow(clippy::module_name_repetitions)]
#[cfg(target_os = "macos")]
#[repr(C)]
#[derive(Clone, Copy)]
struct NsPoint {
x: f64,
y: f64,
}
#[cfg(target_os = "macos")]
#[repr(C)]
#[derive(Clone, Copy)]
struct NsSize {
width: f64,
height: f64,
}
#[cfg(target_os = "macos")]
#[repr(C)]
#[derive(Clone, Copy)]
struct NsRect {
origin: NsPoint,
size: NsSize,
}
#[cfg(target_os = "macos")]
pub fn reanchor_to_superview_top(handle: raw_window_handle::RawWindowHandle) {
use objc::{msg_send, sel, sel_impl};
let view_ptr = match handle {
raw_window_handle::RawWindowHandle::AppKit(h) => h.ns_view,
_ => return,
};
if view_ptr.is_null() {
return;
}
unsafe {
let view = view_ptr.cast::<objc::runtime::Object>();
let superview: *mut objc::runtime::Object = msg_send![view, superview];
if superview.is_null() {
return;
}
let parent_frame: NsRect = msg_send![superview, frame];
let child_frame: NsRect = msg_send![view, frame];
let new_y = parent_frame.size.height - child_frame.size.height;
if (new_y - child_frame.origin.y).abs() < f64::EPSILON {
return;
}
let new_origin = NsPoint {
x: child_frame.origin.x,
y: new_y,
};
let _: () = msg_send![view, setFrameOrigin: new_origin];
}
}
#[cfg(not(target_os = "macos"))]
pub fn reanchor_to_superview_top(_handle: raw_window_handle::RawWindowHandle) {}
#[cfg(target_os = "macos")]
#[must_use]
pub fn should_skip_frame(handle: raw_window_handle::RawWindowHandle) -> bool {
use objc::{msg_send, sel, sel_impl};
let view_ptr = match handle {
raw_window_handle::RawWindowHandle::AppKit(h) => h.ns_view,
_ => return false,
};
if view_ptr.is_null() {
return true;
}
unsafe {
let view = view_ptr.cast::<objc::runtime::Object>();
let window: *mut objc::runtime::Object = msg_send![view, window];
if window.is_null() {
return true;
}
let state: u64 = msg_send![window, occlusionState];
state & (1 << 1) == 0
}
}
#[cfg(target_os = "windows")]
#[must_use]
pub fn should_skip_frame(handle: raw_window_handle::RawWindowHandle) -> bool {
unsafe extern "system" {
fn IsWindowVisible(hwnd: *mut std::ffi::c_void) -> i32;
fn IsIconic(hwnd: *mut std::ffi::c_void) -> i32;
}
let hwnd = match handle {
raw_window_handle::RawWindowHandle::Win32(h) => h.hwnd,
_ => return false,
};
if hwnd.is_null() {
return true;
}
unsafe { IsWindowVisible(hwnd) == 0 || IsIconic(hwnd) != 0 }
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
#[must_use]
pub fn should_skip_frame(_handle: raw_window_handle::RawWindowHandle) -> bool {
false
}
#[cfg(target_os = "macos")]
pub fn reanchor_all_children_to_top(parent: *mut std::ffi::c_void) {
use objc::runtime::Object;
use objc::{msg_send, sel, sel_impl};
if parent.is_null() {
return;
}
unsafe {
let parent_obj = parent.cast::<Object>();
let window: *mut Object = msg_send![parent_obj, window];
if window.is_null() {
return;
}
let parent_frame: NsRect = msg_send![parent_obj, frame];
let subviews: *mut Object = msg_send![parent_obj, subviews];
if subviews.is_null() {
return;
}
let count: usize = msg_send![subviews, count];
for i in 0..count {
let child: *mut Object = msg_send![subviews, objectAtIndex: i];
if child.is_null() {
continue;
}
let child_frame: NsRect = msg_send![child, frame];
let new_y = parent_frame.size.height - child_frame.size.height;
if (new_y - child_frame.origin.y).abs() < f64::EPSILON {
continue;
}
let new_origin = NsPoint {
x: child_frame.origin.x,
y: new_y,
};
let _: () = msg_send![child, setFrameOrigin: new_origin];
}
}
}
#[cfg(not(target_os = "macos"))]
pub fn reanchor_all_children_to_top(_parent: *mut std::ffi::c_void) {}
#[cfg(target_os = "windows")]
#[must_use]
#[allow(clippy::cast_possible_truncation, clippy::unnecessary_cast)]
pub fn wgl_extensions_available() -> bool {
use windows_sys::Win32::Graphics::Gdi::{GetDC, ReleaseDC};
use windows_sys::Win32::Graphics::OpenGL::{
ChoosePixelFormat, PFD_DRAW_TO_WINDOW, PFD_MAIN_PLANE, PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA,
PIXELFORMATDESCRIPTOR, SetPixelFormat, wglCreateContext, wglDeleteContext,
wglGetProcAddress, wglMakeCurrent,
};
use windows_sys::Win32::System::LibraryLoader::GetModuleHandleW;
use windows_sys::Win32::UI::WindowsAndMessaging::{
CS_OWNDC, CreateWindowExW, DefWindowProcW, DestroyWindow, RegisterClassW, UnregisterClassW,
WNDCLASSW,
};
use windows_sys::core::s;
const CLASS_NAME: &[u16] = &[
0x74, 0x72, 0x75, 0x63, 0x65, 0x2d, 0x77, 0x67, 0x6c, 0x2d, 0x70, 0x72, 0x6f, 0x62, 0x65, 0,
];
unsafe {
let hinstance = GetModuleHandleW(std::ptr::null());
let class = WNDCLASSW {
style: CS_OWNDC,
lpfnWndProc: Some(DefWindowProcW),
cbClsExtra: 0,
cbWndExtra: 0,
hInstance: hinstance,
hIcon: std::ptr::null_mut(),
hCursor: std::ptr::null_mut(),
hbrBackground: std::ptr::null_mut(),
lpszMenuName: std::ptr::null(),
lpszClassName: CLASS_NAME.as_ptr(),
};
let atom = RegisterClassW(&raw const class);
if atom == 0 {
return false;
}
let hwnd = CreateWindowExW(
0,
CLASS_NAME.as_ptr(),
CLASS_NAME.as_ptr(),
0,
0,
0,
1,
1,
std::ptr::null_mut(),
std::ptr::null_mut(),
hinstance,
std::ptr::null(),
);
if hwnd.is_null() {
UnregisterClassW(CLASS_NAME.as_ptr(), hinstance);
return false;
}
let mut available = false;
let hdc = GetDC(hwnd);
if !hdc.is_null() {
let pfd = PIXELFORMATDESCRIPTOR {
nSize: size_of::<PIXELFORMATDESCRIPTOR>() as u16,
nVersion: 1,
dwFlags: PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
iPixelType: PFD_TYPE_RGBA as u8,
cColorBits: 32,
cDepthBits: 24,
cStencilBits: 8,
iLayerType: PFD_MAIN_PLANE as u8,
..std::mem::zeroed()
};
let format = ChoosePixelFormat(hdc, &raw const pfd);
if format != 0 && SetPixelFormat(hdc, format, &raw const pfd) != 0 {
let hglrc = wglCreateContext(hdc);
if !hglrc.is_null() {
wglMakeCurrent(hdc, hglrc);
available = wglGetProcAddress(s!("wglChoosePixelFormatARB")).is_some()
&& wglGetProcAddress(s!("wglCreateContextAttribsARB")).is_some();
wglMakeCurrent(hdc, std::ptr::null_mut());
wglDeleteContext(hglrc);
}
}
ReleaseDC(hwnd, hdc);
}
DestroyWindow(hwnd);
UnregisterClassW(CLASS_NAME.as_ptr(), hinstance);
available
}
}