-
Notifications
You must be signed in to change notification settings - Fork 1.2k
wayland: use ext-background-effect if available
#4496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| use std::sync::Arc; | ||
|
|
||
| use dpi::LogicalSize; | ||
| use sctk::compositor::CompositorState; | ||
| 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::BackgroundEffectManager; | ||
| use crate::types::kwin_blur::KWinBlurManager; | ||
|
|
||
| #[derive(Debug)] | ||
| pub enum BlurSurface { | ||
| Ext(WlSurface, ExtBackgroundEffectSurfaceV1), | ||
| Kwin(OrgKdeKwinBlur), | ||
| } | ||
|
|
||
| impl BlurSurface { | ||
| pub fn commit(&self) { | ||
| match self { | ||
| BlurSurface::Ext(s, _) => s.commit(), | ||
| BlurSurface::Kwin(s) => s.commit(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl Drop for BlurSurface { | ||
| fn drop(&mut self) { | ||
| match self { | ||
| BlurSurface::Ext(_, s) => s.destroy(), | ||
| BlurSurface::Kwin(s) => s.release(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[derive(Debug, Clone)] | ||
| pub enum BlurManager { | ||
| Ext(BackgroundEffectManager), | ||
| KWin(KWinBlurManager), | ||
| } | ||
|
|
||
| impl BlurManager { | ||
| pub fn new( | ||
| globals: &GlobalList, | ||
| queue_handle: &QueueHandle<WinitState>, | ||
| ) -> Result<Self, BindError> { | ||
| match BackgroundEffectManager::new(globals, queue_handle) { | ||
| Ok(m) => Ok(Self::Ext(m)), | ||
| Err(e) => { | ||
| if let Ok(m) = KWinBlurManager::new(globals, queue_handle) { | ||
| Ok(Self::KWin(m)) | ||
| } else { | ||
| Err(e) | ||
| } | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| pub fn blur( | ||
| &mut self, | ||
| compositor_state: &Arc<CompositorState>, | ||
| surface: &WlSurface, | ||
| queue_handle: &QueueHandle<WinitState>, | ||
| size: LogicalSize<u32>, | ||
| ) -> BlurSurface { | ||
| match self { | ||
| BlurManager::Ext(m) => BlurSurface::Ext( | ||
| surface.clone(), | ||
| m.blur(compositor_state, surface, queue_handle, size), | ||
| ), | ||
| BlurManager::KWin(m) => BlurSurface::Kwin(m.blur(surface, queue_handle)), | ||
| } | ||
| } | ||
|
|
||
| pub fn unset(&mut self, surface: &WlSurface) { | ||
| match self { | ||
| BlurManager::Ext(m) => m.unset(surface), | ||
| BlurManager::KWin(m) => m.unset(surface), | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| use std::collections::HashMap; | ||
| use std::ops::Deref; | ||
| use std::sync::Arc; | ||
|
|
||
| use dpi::LogicalSize; | ||
| use sctk::compositor::{CompositorState, Region}; | ||
| use sctk::globals::GlobalData; | ||
| use sctk::reexports::client::backend::ObjectId; | ||
| 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 BackgroundEffectManager { | ||
| manager: ExtBackgroundEffectManagerV1, | ||
| surfaces: HashMap<ObjectId, ExtBackgroundEffectSurfaceV1>, | ||
| } | ||
|
|
||
| impl BackgroundEffectManager { | ||
| pub fn new( | ||
| globals: &GlobalList, | ||
| queue_handle: &QueueHandle<WinitState>, | ||
| ) -> Result<Self, BindError> { | ||
| let manager = globals.bind(queue_handle, 1..=1, GlobalData)?; | ||
| Ok(Self { manager, surfaces: HashMap::new() }) | ||
| } | ||
|
|
||
| pub fn blur( | ||
| &mut self, | ||
| compositor_state: &Arc<CompositorState>, | ||
| surface: &WlSurface, | ||
| queue_handle: &QueueHandle<WinitState>, | ||
| size: LogicalSize<u32>, | ||
| ) -> ExtBackgroundEffectSurfaceV1 { | ||
| let region = Region::new(compositor_state.deref()).unwrap(); | ||
| region.add(0, 0, size.width as i32, size.height as i32); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we just follow
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I asked Yalter about this and he said that the surface object when created has no effect, so the client have to call |
||
| let surface = if let Some(existing) = self.surfaces.get(&surface.id()) { | ||
| existing.clone() | ||
| } else { | ||
| let surface = self.manager.get_background_effect(surface, queue_handle, ()); | ||
| self.surfaces.insert(surface.id(), surface.clone()); | ||
| surface | ||
| }; | ||
| surface.set_blur_region(Some(region.wl_region())); | ||
| surface | ||
| } | ||
|
|
||
| pub fn unset(&mut self, surface: &WlSurface) { | ||
| self.surfaces.remove(&surface.id()); | ||
| } | ||
| } | ||
|
|
||
| impl Dispatch<ExtBackgroundEffectManagerV1, GlobalData, WinitState> for BackgroundEffectManager { | ||
| fn event( | ||
| _: &mut WinitState, | ||
| _: &ExtBackgroundEffectManagerV1, | ||
| _: <ExtBackgroundEffectManagerV1 as Proxy>::Event, | ||
| _: &GlobalData, | ||
| _: &Connection, | ||
| _: &QueueHandle<WinitState>, | ||
| ) { | ||
| } | ||
| } | ||
|
|
||
| impl Dispatch<ExtBackgroundEffectSurfaceV1, (), WinitState> for BackgroundEffectManager { | ||
| fn event( | ||
| _: &mut WinitState, | ||
| _: &ExtBackgroundEffectSurfaceV1, | ||
| _: <ExtBackgroundEffectSurfaceV1 as Proxy>::Event, | ||
| _: &(), | ||
| _: &Connection, | ||
| _: &QueueHandle<WinitState>, | ||
| ) { | ||
| // There is no event | ||
| } | ||
| } | ||
|
|
||
| delegate_dispatch!(WinitState: [ExtBackgroundEffectManagerV1: GlobalData] => BackgroundEffectManager); | ||
| delegate_dispatch!(WinitState: [ExtBackgroundEffectSurfaceV1: ()] => BackgroundEffectManager); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be an extreme nitpick but should this comment say "or", so it's clear that blur works with either the KDE or the generic protocol? Instead of sounding like it might require both
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah good idea.