Skip to content

Instantly share code, notes, and snippets.

@zeyonaut
Created August 12, 2023 10:36
Show Gist options
  • Save zeyonaut/7c1ef7d15debae36a55138c43730ab81 to your computer and use it in GitHub Desktop.
Save zeyonaut/7c1ef7d15debae36a55138c43730ab81 to your computer and use it in GitHub Desktop.
winit + wgpu: MRE for borderless fullscreen unfocus bug and fix (Windows 10)
[dependencies]
pollster = "0.3.0"
wgpu = "0.17.0"
winit = {git = "https://github.com/rust-windowing/winit.git", commit = "dc973883c9a4ddceb26b095ee78b793beaffebe9"}
use pollster::FutureExt;
use winit::{
event::{ElementState, Event, WindowEvent},
event_loop::EventLoop,
keyboard::Key,
window::{Fullscreen, WindowBuilder},
};
enum FixKind {
None,
Resize,
Minimize,
}
const FIX: FixKind = FixKind::None;
fn main() -> Result<(), impl std::error::Error> {
let event_loop = EventLoop::new();
let window = WindowBuilder::new().build(&event_loop).unwrap();
let mut size = window.inner_size();
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::all(),
dx12_shader_compiler: Default::default(),
});
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::LowPower,
compatible_surface: Some(&surface),
force_fallback_adapter: false,
})
.block_on()
.unwrap();
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
features: wgpu::Features::empty(),
limits: wgpu::Limits::downlevel_defaults().using_resolution(adapter.limits()),
label: None,
},
None,
)
.block_on()
.unwrap();
let surface_capabilities = surface.get_capabilities(&adapter);
let surface_format = surface_capabilities
.formats
.iter()
.copied()
.find(|f| f.is_srgb())
.unwrap_or(surface_capabilities.formats[0]);
let mut config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: surface_format,
width: size.width,
height: size.height,
present_mode: surface_capabilities.present_modes[0],
alpha_mode: surface_capabilities.alpha_modes[0],
view_formats: vec![],
};
surface.configure(&device, &config);
event_loop.run(move |event, _, control_flow| {
control_flow.set_wait();
match event {
Event::WindowEvent { event, window_id } if window_id == window.id() => match event {
WindowEvent::CloseRequested => {
control_flow.set_exit();
}
WindowEvent::KeyboardInput { event, .. }
if event.state == ElementState::Pressed =>
{
match event.logical_key {
Key::Character(s) => {
if s.as_str() == "f" {
window.set_fullscreen(window.fullscreen().map_or_else(
|| Some(Fullscreen::Borderless(window.current_monitor())),
|_| None,
));
}
}
_ => {}
}
}
WindowEvent::Resized(new_size) => {
if new_size.width * new_size.height > 0 {
size = new_size;
config.width = new_size.width;
config.height = new_size.height;
surface.configure(&device, &config);
}
}
WindowEvent::Focused(x) if window.fullscreen().is_some() => match FIX {
FixKind::None => {}
FixKind::Resize => {
config.height = size.height + if x { 0 } else { 1 };
surface.configure(&device, &config);
window.request_redraw();
}
FixKind::Minimize => window.set_minimized(!x),
},
_ => {}
},
Event::RedrawRequested(_) => {
let output = surface.get_current_texture().unwrap();
let view = output
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
{
let _render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: None,
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color {
r: 0.5,
g: 0.5,
b: 0.5,
a: 1.0,
}),
store: true,
},
})],
depth_stencil_attachment: None,
});
}
queue.submit(std::iter::once(encoder.finish()));
window.pre_present_notify();
output.present();
}
_ => (),
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment