From a088f7fd6e3f29ffad210c7ef4c3ebc6dbb0df0f Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 4 Jul 2022 15:27:08 +0200 Subject: [PATCH] utils: Adding additional helpers --- src/utils.rs | 43 ------------------------------- src/utils/ids.rs | 41 +++++++++++++++++++++++++++++ src/utils/mod.rs | 6 +++++ src/utils/prelude.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 43 deletions(-) delete mode 100644 src/utils.rs create mode 100644 src/utils/ids.rs create mode 100644 src/utils/mod.rs create mode 100644 src/utils/prelude.rs diff --git a/src/utils.rs b/src/utils.rs deleted file mode 100644 index eeab09b1..00000000 --- a/src/utils.rs +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only - -use smithay::reexports::wayland_server::{Global, Interface, Resource}; -use std::{ - convert::{AsRef, From}, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, -}; - -pub struct GlobalDrop> + From>>(Option>); - -impl> + From>> From> for GlobalDrop { - fn from(g: Global) -> GlobalDrop { - GlobalDrop(Some(g)) - } -} - -impl> + From>> Drop for GlobalDrop { - fn drop(&mut self) { - if let Some(global) = self.0.take() { - global.destroy(); - } - } -} - -// This hack will hopefully will be superseeded by a better solution, when smithay transitions to wayland-rs 0.30. -// But until then there is not really a better way to schedule a repaint on surface destruction -#[derive(Debug)] -pub struct SurfaceDropNotifier(Arc); - -impl From<&crate::state::Common> for SurfaceDropNotifier { - fn from(state: &crate::state::Common) -> Self { - SurfaceDropNotifier(state.dirty_flag.clone()) - } -} - -impl Drop for SurfaceDropNotifier { - fn drop(&mut self) { - self.0.store(true, Ordering::SeqCst); - } -} diff --git a/src/utils/ids.rs b/src/utils/ids.rs new file mode 100644 index 00000000..afdcbf77 --- /dev/null +++ b/src/utils/ids.rs @@ -0,0 +1,41 @@ +// TODO: Remove once desktop is back +#![allow(unused)] + +macro_rules! id_gen { + ($func_name:ident, $id_name:ident, $ids_name:ident) => { + static $id_name: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0); + lazy_static::lazy_static! { + static ref $ids_name: std::sync::Mutex> = + std::sync::Mutex::new(std::collections::HashSet::new()); + } + + fn $func_name() -> usize { + let mut ids = $ids_name.lock().unwrap(); + if ids.len() == usize::MAX { + panic!("Out of ids"); + } + + let id = loop { + let new_id = $id_name.fetch_update( + std::sync::atomic::Ordering::SeqCst, + std::sync::atomic::Ordering::SeqCst, + |mut id| { + while ids.iter().any(|k| *k == id) { + id += 1; + } + id += 1; + Some(id) + }, + ); + if let Ok(id) = new_id { + break id; + } + }; + + ids.insert(id); + id + } + }; +} + +pub(crate) use id_gen; diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 00000000..afa523d0 --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0-only + +mod ids; +pub(crate) use self::ids::id_gen; + +pub mod prelude; diff --git a/src/utils/prelude.rs b/src/utils/prelude.rs new file mode 100644 index 00000000..dde908a1 --- /dev/null +++ b/src/utils/prelude.rs @@ -0,0 +1,61 @@ +use std::cell::RefCell; +use smithay::{ + wayland::{ + output::Output, + seat::Seat, + }, + utils::{Rectangle, Transform, Logical}, +}; +use crate::{ + input::ActiveOutput, + state::Common, +}; + +pub use crate::{ + state::State, +}; + +pub trait OutputExt { + fn geometry(&self) -> Rectangle; +} + +impl OutputExt for Output { + fn geometry(&self) -> Rectangle { + Rectangle::from_loc_and_size( + self.current_location(), + { + Transform::from(self.current_transform()).transform_size( + self.current_mode().map(|m| m.size).unwrap_or_else(|| (0,0).into()) + ).to_f64().to_logical(self.current_scale().fractional_scale()).to_i32_round() + }, + ) + } +} + +pub fn active_output(seat: &Seat, state: &Common) -> Output { + seat.user_data() + .get::() + .map(|x| x.0.borrow().clone()) + .unwrap_or_else(|| { + state + .shell + .outputs() + .next() + .cloned() + .expect("Backend has no outputs?") + }) +} + +pub fn set_active_output(seat: &Seat, output: &Output) { + if !seat + .user_data() + .insert_if_missing(|| ActiveOutput(RefCell::new(output.clone()))) + { + *seat + .user_data() + .get::() + .unwrap() + .0 + .borrow_mut() = output.clone(); + } +}