mirror of
https://github.com/rust-windowing/winit.git
synced 2026-08-31 05:40:04 -04:00
winit-wayland: use ext-background-effect if available
A more modern protocol compared to the KDE one.
This commit is contained in:
85
winit-wayland/src/types/bgr_effects.rs
Normal file
85
winit-wayland/src/types/bgr_effects.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
use sctk::compositor::Region;
|
||||
use sctk::reexports::client::QueueHandle;
|
||||
use sctk::reexports::client::globals::{BindError, GlobalList};
|
||||
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
||||
use sctk::reexports::protocols::ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1;
|
||||
use wayland_protocols_plasma::blur::client::org_kde_kwin_blur::OrgKdeKwinBlur;
|
||||
|
||||
use crate::state::WinitState;
|
||||
use crate::types::ext_background_effect::ExtBackgroundEffectManager;
|
||||
use crate::types::kwin_blur::KWinBlurManager;
|
||||
|
||||
/// Wrapper around various background effects for [`WlSurface`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum BgrEffectManager {
|
||||
Ext(ExtBackgroundEffectManager),
|
||||
KWin(KWinBlurManager),
|
||||
}
|
||||
|
||||
impl BgrEffectManager {
|
||||
pub fn new(
|
||||
globals: &GlobalList,
|
||||
queue_handle: &QueueHandle<WinitState>,
|
||||
) -> Result<Self, BindError> {
|
||||
ExtBackgroundEffectManager::new(globals, queue_handle)
|
||||
.map(Self::Ext)
|
||||
.or_else(|_| KWinBlurManager::new(globals, queue_handle).map(Self::KWin))
|
||||
}
|
||||
|
||||
/// Creates a new blur effect for the surface.
|
||||
pub fn new_blur_effect(
|
||||
&mut self,
|
||||
surface: &WlSurface,
|
||||
queue_handle: &QueueHandle<WinitState>,
|
||||
) -> SurfaceBlurEffect {
|
||||
match self {
|
||||
BgrEffectManager::Ext(mgr) => SurfaceBlurEffect::Ext(mgr.blur(surface, queue_handle)),
|
||||
BgrEffectManager::KWin(mgr) => SurfaceBlurEffect::Kwin(
|
||||
mgr.blur(surface, queue_handle),
|
||||
mgr.clone(),
|
||||
surface.clone(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SurfaceBlurEffect {
|
||||
Ext(ExtBackgroundEffectSurfaceV1),
|
||||
Kwin(OrgKdeKwinBlur, KWinBlurManager, WlSurface),
|
||||
}
|
||||
|
||||
impl SurfaceBlurEffect {
|
||||
/// Returns `true` if the main surface commit is required.
|
||||
///
|
||||
/// `None` clears the blur.
|
||||
#[must_use]
|
||||
pub fn set_blur(&self, region: Option<&Region>) -> bool {
|
||||
let region = region.map(|region| region.wl_region());
|
||||
match self {
|
||||
SurfaceBlurEffect::Ext(surface) => {
|
||||
surface.set_blur_region(region);
|
||||
true
|
||||
},
|
||||
SurfaceBlurEffect::Kwin(blur, ..) => {
|
||||
blur.set_region(region);
|
||||
blur.commit();
|
||||
true
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SurfaceBlurEffect {
|
||||
fn drop(&mut self) {
|
||||
match self {
|
||||
SurfaceBlurEffect::Ext(surface) => surface.destroy(),
|
||||
SurfaceBlurEffect::Kwin(blur, mgr, wl_surface) => {
|
||||
blur.set_region(None);
|
||||
blur.commit();
|
||||
blur.release();
|
||||
mgr.unset(wl_surface);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
59
winit-wayland/src/types/ext_background_effect.rs
Normal file
59
winit-wayland/src/types/ext_background_effect.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use sctk::globals::GlobalData;
|
||||
use sctk::reexports::client::globals::{BindError, GlobalList};
|
||||
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
||||
use sctk::reexports::client::{Connection, Dispatch, Proxy, QueueHandle, delegate_dispatch};
|
||||
use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_manager_v1::ExtBackgroundEffectManagerV1;
|
||||
use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1;
|
||||
|
||||
use crate::state::WinitState;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExtBackgroundEffectManager {
|
||||
manager: ExtBackgroundEffectManagerV1,
|
||||
}
|
||||
|
||||
impl ExtBackgroundEffectManager {
|
||||
pub fn new(
|
||||
globals: &GlobalList,
|
||||
queue_handle: &QueueHandle<WinitState>,
|
||||
) -> Result<Self, BindError> {
|
||||
let manager = globals.bind(queue_handle, 1..=1, GlobalData)?;
|
||||
Ok(Self { manager })
|
||||
}
|
||||
|
||||
pub fn blur(
|
||||
&mut self,
|
||||
surface: &WlSurface,
|
||||
queue_handle: &QueueHandle<WinitState>,
|
||||
) -> ExtBackgroundEffectSurfaceV1 {
|
||||
self.manager.get_background_effect(surface, queue_handle, ())
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispatch<ExtBackgroundEffectManagerV1, GlobalData, WinitState> for ExtBackgroundEffectManager {
|
||||
fn event(
|
||||
_: &mut WinitState,
|
||||
_: &ExtBackgroundEffectManagerV1,
|
||||
_: <ExtBackgroundEffectManagerV1 as Proxy>::Event,
|
||||
_: &GlobalData,
|
||||
_: &Connection,
|
||||
_: &QueueHandle<WinitState>,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispatch<ExtBackgroundEffectSurfaceV1, (), WinitState> for ExtBackgroundEffectManager {
|
||||
fn event(
|
||||
_: &mut WinitState,
|
||||
_: &ExtBackgroundEffectSurfaceV1,
|
||||
_: <ExtBackgroundEffectSurfaceV1 as Proxy>::Event,
|
||||
_: &(),
|
||||
_: &Connection,
|
||||
_: &QueueHandle<WinitState>,
|
||||
) {
|
||||
// There is no event
|
||||
}
|
||||
}
|
||||
|
||||
delegate_dispatch!(WinitState: [ExtBackgroundEffectManagerV1: GlobalData] => ExtBackgroundEffectManager);
|
||||
delegate_dispatch!(WinitState: [ExtBackgroundEffectSurfaceV1: ()] => ExtBackgroundEffectManager);
|
||||
@@ -1,6 +1,8 @@
|
||||
//! Wayland protocol implementation boilerplate.
|
||||
|
||||
pub mod bgr_effects;
|
||||
pub mod cursor;
|
||||
pub mod ext_background_effect;
|
||||
pub mod kwin_blur;
|
||||
pub mod wp_fractional_scaling;
|
||||
pub mod wp_tablet_input_v2;
|
||||
|
||||
Reference in New Issue
Block a user