mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-28 09:54:33 +00:00
Windows: Add transparency effect (#20400)
Release Notes: - Added Transparency effect for Windows #19405 ![image](https://github.com/user-attachments/assets/b0750020-5a89-48c9-b26e-13b30874cf8d) ![image](https://github.com/user-attachments/assets/80609a14-b8c3-4159-b909-1e61f4c3eac3) --------- Co-authored-by: thedeveloper-sharath <35845141+thedeveloper-sharath@users.noreply.github.com>
This commit is contained in:
parent
21c785ede4
commit
b421ffafb5
1 changed files with 94 additions and 3 deletions
|
@ -647,11 +647,47 @@ impl PlatformWindow for WindowsWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_background_appearance(&self, background_appearance: WindowBackgroundAppearance) {
|
fn set_background_appearance(&self, background_appearance: WindowBackgroundAppearance) {
|
||||||
self.0
|
let mut window_state = self.0.state.borrow_mut();
|
||||||
.state
|
window_state
|
||||||
.borrow_mut()
|
|
||||||
.renderer
|
.renderer
|
||||||
.update_transparency(background_appearance != WindowBackgroundAppearance::Opaque);
|
.update_transparency(background_appearance != WindowBackgroundAppearance::Opaque);
|
||||||
|
let mut version = unsafe { std::mem::zeroed() };
|
||||||
|
let status = unsafe { windows::Wdk::System::SystemServices::RtlGetVersion(&mut version) };
|
||||||
|
if status.is_ok() {
|
||||||
|
if background_appearance == WindowBackgroundAppearance::Blurred {
|
||||||
|
if version.dwBuildNumber >= 17763 {
|
||||||
|
set_window_composition_attribute(window_state.hwnd, Some((0, 0, 0, 10)), 4);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if version.dwBuildNumber >= 17763 {
|
||||||
|
set_window_composition_attribute(window_state.hwnd, None, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Transparent effect might cause some flickering and performance issues due `WS_EX_COMPOSITED` is enabled
|
||||||
|
//if `WS_EX_COMPOSITED` is removed the window instance won't initiate
|
||||||
|
if background_appearance == WindowBackgroundAppearance::Transparent {
|
||||||
|
unsafe {
|
||||||
|
let current_style = GetWindowLongW(window_state.hwnd, GWL_EXSTYLE);
|
||||||
|
SetWindowLongW(
|
||||||
|
window_state.hwnd,
|
||||||
|
GWL_EXSTYLE,
|
||||||
|
current_style | WS_EX_LAYERED.0 as i32 | WS_EX_COMPOSITED.0 as i32,
|
||||||
|
);
|
||||||
|
SetLayeredWindowAttributes(window_state.hwnd, COLORREF(0), 225, LWA_ALPHA)
|
||||||
|
.inspect_err(|e| log::error!("Unable to set window to transparent: {e}"))
|
||||||
|
.ok();
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
let current_style = GetWindowLongW(window_state.hwnd, GWL_EXSTYLE);
|
||||||
|
SetWindowLongW(
|
||||||
|
window_state.hwnd,
|
||||||
|
GWL_EXSTYLE,
|
||||||
|
current_style & !WS_EX_LAYERED.0 as i32 & !WS_EX_COMPOSITED.0 as i32,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn minimize(&self) {
|
fn minimize(&self) {
|
||||||
|
@ -932,6 +968,23 @@ struct StyleAndBounds {
|
||||||
cy: i32,
|
cy: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct WINDOWCOMPOSITIONATTRIBDATA {
|
||||||
|
attrib: u32,
|
||||||
|
pv_data: *mut std::ffi::c_void,
|
||||||
|
cb_data: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct AccentPolicy {
|
||||||
|
accent_state: u32,
|
||||||
|
accent_flags: u32,
|
||||||
|
gradient_color: u32,
|
||||||
|
animation_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Color = (u8, u8, u8, u8);
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
pub(crate) struct WindowBorderOffset {
|
pub(crate) struct WindowBorderOffset {
|
||||||
width_offset: i32,
|
width_offset: i32,
|
||||||
|
@ -1136,6 +1189,44 @@ fn retrieve_window_placement(
|
||||||
Ok(placement)
|
Ok(placement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_window_composition_attribute(hwnd: HWND, color: Option<Color>, state: u32) {
|
||||||
|
unsafe {
|
||||||
|
type SetWindowCompositionAttributeType =
|
||||||
|
unsafe extern "system" fn(HWND, *mut WINDOWCOMPOSITIONATTRIBDATA) -> BOOL;
|
||||||
|
let module_name = PCSTR::from_raw("user32.dll\0".as_ptr());
|
||||||
|
let user32 = GetModuleHandleA(module_name);
|
||||||
|
if user32.is_ok() {
|
||||||
|
let func_name = PCSTR::from_raw("SetWindowCompositionAttribute\0".as_ptr());
|
||||||
|
let set_window_composition_attribute: SetWindowCompositionAttributeType =
|
||||||
|
std::mem::transmute(GetProcAddress(user32.unwrap(), func_name));
|
||||||
|
let mut color = color.unwrap_or_default();
|
||||||
|
let is_acrylic = state == 4;
|
||||||
|
if is_acrylic && color.3 == 0 {
|
||||||
|
color.3 = 1;
|
||||||
|
}
|
||||||
|
let accent = AccentPolicy {
|
||||||
|
accent_state: state,
|
||||||
|
accent_flags: if is_acrylic { 0 } else { 2 },
|
||||||
|
gradient_color: (color.0 as u32)
|
||||||
|
| ((color.1 as u32) << 8)
|
||||||
|
| ((color.2 as u32) << 16)
|
||||||
|
| (color.3 as u32) << 24,
|
||||||
|
animation_id: 0,
|
||||||
|
};
|
||||||
|
let mut data = WINDOWCOMPOSITIONATTRIBDATA {
|
||||||
|
attrib: 0x13,
|
||||||
|
pv_data: &accent as *const _ as *mut _,
|
||||||
|
cb_data: std::mem::size_of::<AccentPolicy>(),
|
||||||
|
};
|
||||||
|
let _ = set_window_composition_attribute(hwnd, &mut data as *mut _ as _);
|
||||||
|
} else {
|
||||||
|
let _ = user32
|
||||||
|
.inspect_err(|e| log::error!("Error getting module: {e}"))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod windows_renderer {
|
mod windows_renderer {
|
||||||
use std::{num::NonZeroIsize, sync::Arc};
|
use std::{num::NonZeroIsize, sync::Arc};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue