wayland: implement scaling
This involves many subsystems:
- config:
- allow setting the connector scale
- allow setting the cursor size
- cursors:
- load server cursors for all requested sizes and scales
- wl_surface:
- track the output the surface belongs to
- send wl_surface.enter/leave
- wl_output:
- implement wl_output.scale
- text:
- pre-render texts for all used scales
- renderer:
- properly align scale textures and rectangles
- wp_fractional_scale:
- new interface for fractional scaling
This commit is contained in:
parent
16aec8f87e
commit
e52a60b3b6
41 changed files with 1417 additions and 364 deletions
|
|
@ -12,16 +12,12 @@ use {
|
|||
};
|
||||
|
||||
pub struct SmallMap<K, V, const N: usize> {
|
||||
m: UnsafeCell<SmallVec<[(K, V); N]>>,
|
||||
m: UnsafeCell<SmallMapMut<K, V, N>>,
|
||||
}
|
||||
|
||||
impl<K: Debug, V: Debug, const N: usize> Debug for SmallMap<K, V, N> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
unsafe {
|
||||
f.debug_map()
|
||||
.entries(self.m.get().deref().iter().map(|e| (&e.0, &e.1)))
|
||||
.finish()
|
||||
}
|
||||
unsafe { self.m.get().deref().fmt(f) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -35,16 +31,14 @@ impl<K, V, const N: usize> Default for SmallMap<K, V, N> {
|
|||
|
||||
impl<K: Eq, V, const N: usize> SmallMap<K, V, N> {
|
||||
pub fn new_with(k: K, v: V) -> Self {
|
||||
let mut sv = SmallVec::new();
|
||||
sv.push((k, v));
|
||||
Self {
|
||||
m: UnsafeCell::new(sv),
|
||||
m: UnsafeCell::new(SmallMapMut::new_with(k, v)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
m: UnsafeCell::new(SmallVec::new_const()),
|
||||
m: UnsafeCell::new(SmallMapMut::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,42 +47,25 @@ impl<K: Eq, V, const N: usize> SmallMap<K, V, N> {
|
|||
}
|
||||
|
||||
pub fn insert(&self, k: K, v: V) -> Option<V> {
|
||||
unsafe {
|
||||
let m = self.m.get().deref_mut();
|
||||
for (ek, ev) in &mut *m {
|
||||
if ek == &k {
|
||||
return Some(mem::replace(ev, v));
|
||||
}
|
||||
}
|
||||
m.push((k, v));
|
||||
None
|
||||
}
|
||||
unsafe { self.m.get().deref_mut().insert(k, v) }
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
unsafe { self.m.get().deref_mut().is_empty() }
|
||||
unsafe { self.m.get().deref().is_empty() }
|
||||
}
|
||||
|
||||
pub fn remove(&self, k: &K) -> Option<V> {
|
||||
unsafe {
|
||||
let m = self.m.get().deref_mut();
|
||||
for (idx, (ek, _)) in m.iter_mut().enumerate() {
|
||||
if ek == k {
|
||||
return Some(m.swap_remove(idx).1);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
unsafe { self.m.get().deref_mut().remove(k) }
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
unsafe {
|
||||
let _v = mem::replace(self.m.get().deref_mut(), SmallVec::new());
|
||||
let _v = self.m.get().deref_mut().clear();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take(&self) -> SmallVec<[(K, V); N]> {
|
||||
unsafe { mem::take(self.m.get().deref_mut()) }
|
||||
unsafe { self.m.get().deref_mut().take() }
|
||||
}
|
||||
|
||||
pub fn pop(&self) -> Option<(K, V)> {
|
||||
|
|
@ -103,7 +80,7 @@ impl<K: Eq, V, const N: usize> SmallMap<K, V, N> {
|
|||
impl<K: Eq, V: UnsafeCellCloneSafe, const N: usize> SmallMap<K, V, N> {
|
||||
pub fn get(&self, k: &K) -> Option<V> {
|
||||
unsafe {
|
||||
let m = self.m.get().deref();
|
||||
let m = &self.m.get().deref().m;
|
||||
for (ek, ev) in m {
|
||||
if ek == k {
|
||||
return Some(ev.clone());
|
||||
|
|
@ -133,7 +110,7 @@ impl<'a, K: Copy, V: UnsafeCellCloneSafe, const N: usize> Iterator for SmallMapI
|
|||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
let v = self.map.m.get().deref();
|
||||
let v = &self.map.m.get().deref().m;
|
||||
if self.pos >= v.len() {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -143,3 +120,163 @@ impl<'a, K: Copy, V: UnsafeCellCloneSafe, const N: usize> Iterator for SmallMapI
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SmallMapMut<K, V, const N: usize> {
|
||||
m: SmallVec<[(K, V); N]>,
|
||||
}
|
||||
|
||||
impl<K: Debug, V: Debug, const N: usize> Debug for SmallMapMut<K, V, N> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_map()
|
||||
.entries(self.m.iter().map(|e| (&e.0, &e.1)))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, const N: usize> Default for SmallMapMut<K, V, N> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
m: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq, V, const N: usize> SmallMapMut<K, V, N> {
|
||||
pub fn new_with(k: K, v: V) -> Self {
|
||||
let mut sv = SmallVec::new();
|
||||
sv.push((k, v));
|
||||
Self { m: sv }
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
m: SmallVec::new_const(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.m.len()
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
|
||||
for (ek, ev) in &mut self.m {
|
||||
if ek == &k {
|
||||
return Some(mem::replace(ev, v));
|
||||
}
|
||||
}
|
||||
self.m.push((k, v));
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get(&self, k: &K) -> Option<&V> {
|
||||
for (ek, ev) in &self.m {
|
||||
if ek == k {
|
||||
return Some(ev);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_or_default_mut(&mut self, k: K) -> &mut V
|
||||
where
|
||||
V: Default,
|
||||
{
|
||||
for (ek, ev) in &mut self.m {
|
||||
if ek == &k {
|
||||
return unsafe { (ev as *mut V).deref_mut() };
|
||||
}
|
||||
}
|
||||
self.m.push((k, V::default()));
|
||||
&mut self.m.last_mut().unwrap().1
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.m.is_empty()
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, k: &K) -> Option<V> {
|
||||
for (idx, (ek, _)) in self.m.iter_mut().enumerate() {
|
||||
if ek == k {
|
||||
return Some(self.m.swap_remove(idx).1);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
let _v = mem::replace(&mut self.m, SmallVec::new());
|
||||
}
|
||||
|
||||
pub fn take(&mut self) -> SmallVec<[(K, V); N]> {
|
||||
mem::take(&mut self.m)
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Option<(K, V)> {
|
||||
self.m.pop()
|
||||
}
|
||||
|
||||
pub fn iter<'a>(&'a self) -> SmallMapMutIter<'a, K, V, N> {
|
||||
SmallMapMutIter { pos: 0, map: self }
|
||||
}
|
||||
|
||||
pub fn iter_mut<'a>(&'a mut self) -> SmallMapMutIterMut<'a, K, V, N> {
|
||||
SmallMapMutIterMut { pos: 0, map: self }
|
||||
}
|
||||
|
||||
pub fn remove_if<F: FnMut(&K, &V) -> bool>(&mut self, mut f: F) {
|
||||
let mut i = 0;
|
||||
while i < self.m.len() {
|
||||
let (k, v) = &self.m[i];
|
||||
if f(k, v) {
|
||||
self.m.swap_remove(i);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: Copy, V, const N: usize> IntoIterator for &'a SmallMapMut<K, V, N> {
|
||||
type Item = (&'a K, &'a V);
|
||||
type IntoIter = SmallMapMutIter<'a, K, V, N>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SmallMapMutIter { pos: 0, map: self }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SmallMapMutIter<'a, K, V, const N: usize> {
|
||||
pos: usize,
|
||||
map: &'a SmallMapMut<K, V, N>,
|
||||
}
|
||||
|
||||
impl<'a, K, V, const N: usize> Iterator for SmallMapMutIter<'a, K, V, N> {
|
||||
type Item = (&'a K, &'a V);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.pos >= self.map.m.len() {
|
||||
return None;
|
||||
}
|
||||
let (k, v) = &self.map.m[self.pos];
|
||||
self.pos += 1;
|
||||
Some((k, v))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SmallMapMutIterMut<'a, K, V, const N: usize> {
|
||||
pos: usize,
|
||||
map: &'a mut SmallMapMut<K, V, N>,
|
||||
}
|
||||
|
||||
impl<'a, K, V, const N: usize> Iterator for SmallMapMutIterMut<'a, K, V, N> {
|
||||
type Item = (&'a mut K, &'a mut V);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.pos >= self.map.m.len() {
|
||||
return None;
|
||||
}
|
||||
let (k, v) = &mut self.map.m[self.pos];
|
||||
self.pos += 1;
|
||||
unsafe { Some(((k as *mut K).deref_mut(), (v as *mut V).deref_mut())) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue