Merge pull request #453 from tomaka/transparency

Add API for transparency and decorations and add support for win32
This commit is contained in:
tomaka 2015-05-24 13:09:22 +02:00
commit d089ea8674
6 changed files with 80 additions and 4 deletions

View file

@ -37,16 +37,18 @@ glutin_core_graphics = "0"
glutin_core_foundation = "0" glutin_core_foundation = "0"
[target.i686-pc-windows-gnu.dependencies] [target.i686-pc-windows-gnu.dependencies]
winapi = "0.1" winapi = "~0.1.18"
gdi32-sys = "0.1" gdi32-sys = "0.1"
user32-sys = "~0.1.1" user32-sys = "~0.1.1"
kernel32-sys = "0.1" kernel32-sys = "0.1"
dwmapi-sys = "0.1"
[target.x86_64-pc-windows-gnu.dependencies] [target.x86_64-pc-windows-gnu.dependencies]
winapi = "0.1" winapi = "~0.1.18"
gdi32-sys = "0.1" gdi32-sys = "0.1"
user32-sys = "~0.1.1" user32-sys = "~0.1.1"
kernel32-sys = "0.1" kernel32-sys = "0.1"
dwmapi-sys = "0.1"
[target.i686-unknown-linux-gnu.dependencies] [target.i686-unknown-linux-gnu.dependencies]
osmesa-sys = "0.0.5" osmesa-sys = "0.0.5"

38
examples/transparent.rs Normal file
View file

@ -0,0 +1,38 @@
#[cfg(target_os = "android")]
#[macro_use]
extern crate android_glue;
extern crate glutin;
mod support;
#[cfg(target_os = "android")]
android_start!(main);
#[cfg(not(feature = "window"))]
fn main() { println!("This example requires glutin to be compiled with the `window` feature"); }
#[cfg(feature = "window")]
fn resize_callback(width: u32, height: u32) {
println!("Window resized to {}x{}", width, height);
}
#[cfg(feature = "window")]
fn main() {
let mut window = glutin::WindowBuilder::new().with_decorations(false).with_transparency(true)
.build().unwrap();
window.set_title("A fantastic window!");
window.set_window_resize_callback(Some(resize_callback as fn(u32, u32)));
unsafe { window.make_current() };
println!("Pixel format of the window: {:?}", window.get_pixel_format());
let context = support::load(&window);
while !window.is_closed() {
context.draw_frame((0.0, 0.0, 0.0, 0.0));
window.swap_buffers();
println!("{:?}", window.wait_events().next());
}
}

View file

@ -44,6 +44,7 @@ fn send_event(input_window: winapi::HWND, event: Event) {
/// This is the callback that is called by `DispatchMessage` in the events loop. /// This is the callback that is called by `DispatchMessage` in the events loop.
/// ///
/// Returning 0 tells the Win32 API that the message has been processed. /// Returning 0 tells the Win32 API that the message has been processed.
// FIXME: detect WM_DWMCOMPOSITIONCHANGED and call DwmEnableBlurBehindWindow if necessary
pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT,
wparam: winapi::WPARAM, lparam: winapi::LPARAM) wparam: winapi::WPARAM, lparam: winapi::LPARAM)
-> winapi::LRESULT -> winapi::LRESULT

View file

@ -25,6 +25,7 @@ use std::sync::mpsc::channel;
use winapi; use winapi;
use kernel32; use kernel32;
use dwmapi;
use user32; use user32;
use api::wgl; use api::wgl;
@ -102,7 +103,7 @@ unsafe fn init(title: Vec<u16>, builder: BuilderAttribs<'static>,
} }
// computing the style and extended style of the window // computing the style and extended style of the window
let (ex_style, style) = if builder.monitor.is_some() { let (ex_style, style) = if builder.monitor.is_some() || builder.decorations == false {
(winapi::WS_EX_APPWINDOW, winapi::WS_POPUP | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN) (winapi::WS_EX_APPWINDOW, winapi::WS_POPUP | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN)
} else { } else {
(winapi::WS_EX_APPWINDOW | winapi::WS_EX_WINDOWEDGE, (winapi::WS_EX_APPWINDOW | winapi::WS_EX_WINDOWEDGE,
@ -214,6 +215,20 @@ unsafe fn init(title: Vec<u16>, builder: BuilderAttribs<'static>,
} }
}; };
// making the window transparent
if builder.transparent {
let bb = winapi::DWM_BLURBEHIND {
dwFlags: 0x1, // FIXME: DWM_BB_ENABLE;
fEnable: 1,
hRgnBlur: ptr::null_mut(),
fTransitionOnMaximized: 0,
};
unsafe {
dwmapi::DwmEnableBlurBehindWindow(real_window.0, &bb);
}
}
// calling SetForegroundWindow if fullscreen // calling SetForegroundWindow if fullscreen
if builder.monitor.is_some() { if builder.monitor.is_some() {
user32::SetForegroundWindow(real_window.0); user32::SetForegroundWindow(real_window.0);

View file

@ -40,6 +40,8 @@ extern crate kernel32;
extern crate gdi32; extern crate gdi32;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
extern crate user32; extern crate user32;
#[cfg(target_os = "windows")]
extern crate dwmapi;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
#[macro_use] #[macro_use]
extern crate objc; extern crate objc;
@ -295,6 +297,8 @@ pub struct BuilderAttribs<'a> {
alpha_bits: Option<u8>, alpha_bits: Option<u8>,
stereoscopy: bool, stereoscopy: bool,
srgb: Option<bool>, srgb: Option<bool>,
transparent: bool,
decorations: bool,
} }
impl BuilderAttribs<'static> { impl BuilderAttribs<'static> {
@ -318,6 +322,8 @@ impl BuilderAttribs<'static> {
alpha_bits: None, alpha_bits: None,
stereoscopy: false, stereoscopy: false,
srgb: None, srgb: None,
transparent: false,
decorations: true,
} }
} }
} }
@ -346,6 +352,8 @@ impl<'a> BuilderAttribs<'a> {
alpha_bits: self.alpha_bits, alpha_bits: self.alpha_bits,
stereoscopy: self.stereoscopy, stereoscopy: self.stereoscopy,
srgb: self.srgb, srgb: self.srgb,
transparent: self.transparent,
decorations: self.decorations,
}; };
(new_attribs, sharing) (new_attribs, sharing)

View file

@ -137,10 +137,22 @@ impl<'a> WindowBuilder<'a> {
self self
} }
/// Sets whether the background of the window should be transparent.
pub fn with_transparency(mut self, transparent: bool) -> WindowBuilder<'a> {
self.attribs.transparent = transparent;
self
}
/// Sets whether the window should have a border, a title bar, etc.
pub fn with_decorations(mut self, decorations: bool) -> WindowBuilder<'a> {
self.attribs.decorations = decorations;
self
}
/// Builds the window. /// Builds the window.
/// ///
/// Error should be very rare and only occur in case of permission denied, incompatible system, /// Error should be very rare and only occur in case of permission denied, incompatible system,
/// out of memory, etc. /// out of memory, etc.
pub fn build(mut self) -> Result<Window, CreationError> { pub fn build(mut self) -> Result<Window, CreationError> {
// resizing the window to the dimensions of the monitor when fullscreen // resizing the window to the dimensions of the monitor when fullscreen
if self.attribs.dimensions.is_none() && self.attribs.monitor.is_some() { if self.attribs.dimensions.is_none() && self.attribs.monitor.is_some() {