tiling: highlight backgrounds

This commit is contained in:
Victoria Brekenfeld 2023-05-30 13:20:46 +02:00
parent 20f4dcb466
commit 24d3b794fe
4 changed files with 116 additions and 74 deletions

View file

@ -82,8 +82,7 @@ pub type GlMultiFrame<'a, 'b, 'frame> =
pub type GlMultiError = MultiError<GbmGlesBackend<GlowRenderer>, GbmGlesBackend<GlowRenderer>>;
pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0];
pub static ACTIVE_GROUP_COLOR: [f32; 3] = [0.678, 0.635, 0.619];
pub static GROUP_COLOR: [f32; 3] = [0.431, 0.404, 0.396];
pub static GROUP_COLOR: [f32; 3] = [0.788, 0.788, 0.788];
pub static FOCUS_INDICATOR_COLOR: [f32; 3] = [0.580, 0.921, 0.921];
pub static OUTLINE_SHADER: &str = include_str!("./shaders/rounded_outline.frag");
@ -136,6 +135,7 @@ impl From<Id> for Key {
#[derive(PartialEq)]
struct IndicatorSettings {
thickness: u8,
radius: u8,
alpha: f32,
color: [f32; 3],
}
@ -158,13 +158,20 @@ impl IndicatorShader {
mut element_geo: Rectangle<i32, Logical>,
thickness: u8,
alpha: f32,
color: [f32; 3],
) -> PixelShaderElement {
let t = thickness as i32;
element_geo.loc -= (t, t).into();
element_geo.size += (t * 2, t * 2).into();
IndicatorShader::element(renderer, key, element_geo, thickness, alpha, color)
IndicatorShader::element(
renderer,
key,
element_geo,
thickness,
thickness * 2,
alpha,
FOCUS_INDICATOR_COLOR,
)
}
pub fn element<R: AsGlowRenderer>(
@ -172,11 +179,13 @@ impl IndicatorShader {
key: impl Into<Key>,
geo: Rectangle<i32, Logical>,
thickness: u8,
radius: u8,
alpha: f32,
color: [f32; 3],
) -> PixelShaderElement {
let settings = IndicatorSettings {
thickness,
radius,
alpha,
color,
};
@ -210,7 +219,7 @@ impl IndicatorShader {
vec![
Uniform::new("color", color),
Uniform::new("thickness", thickness),
Uniform::new("radius", thickness * 2.0),
Uniform::new("radius", radius as f32),
],
);
cache.insert(key.clone(), (settings, elem));

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::{
backend::render::{element::AsGlowRenderer, IndicatorShader, FOCUS_INDICATOR_COLOR},
backend::render::{element::AsGlowRenderer, IndicatorShader},
shell::{
element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement},
focus::target::{KeyboardFocusTarget, PointerFocusTarget},
@ -64,13 +64,12 @@ impl MoveGrabState {
let mut elements: Vec<I> = Vec::new();
if self.indicator_thickness > 0 {
elements.push(
CosmicMappedRenderElement::from(IndicatorShader::element(
CosmicMappedRenderElement::from(IndicatorShader::focus_element(
renderer,
self.window.clone(),
Rectangle::from_loc_and_size(render_location, self.window.geometry().size),
self.indicator_thickness,
1.0,
FOCUS_INDICATOR_COLOR,
))
.into(),
);

View file

@ -13,7 +13,7 @@ use smithay::{
use std::collections::HashMap;
use crate::{
backend::render::{element::AsGlowRenderer, IndicatorShader, FOCUS_INDICATOR_COLOR},
backend::render::{element::AsGlowRenderer, IndicatorShader},
shell::{
element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement},
grabs::ResizeEdge,
@ -388,7 +388,6 @@ impl FloatingLayout {
),
indicator_thickness,
alpha,
FOCUS_INDICATOR_COLOR,
);
elements.insert(0, element.into());
}

View file

@ -2,8 +2,8 @@
use crate::{
backend::render::{
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, ACTIVE_GROUP_COLOR,
FOCUS_INDICATOR_COLOR, GROUP_COLOR,
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, FOCUS_INDICATOR_COLOR,
GROUP_COLOR,
},
shell::{
element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement},
@ -1651,7 +1651,7 @@ impl TilingLayout {
non_exclusive_zone,
seat, // TODO: Would be better to be an old focus,
// but for that we have to associate focus with a tree (and animate focus changes properly)
1.0 - percentage,
1.0 - transition,
transition,
)
} else {
@ -1680,7 +1680,7 @@ impl TilingLayout {
renderer,
non_exclusive_zone,
seat,
percentage,
transition,
transition,
)
} else {
@ -1699,7 +1699,7 @@ impl TilingLayout {
output_scale,
percentage,
if let Some(transition) = draw_groups {
let diff = (3u8.abs_diff(indicator_thickness) as f32 * transition).round() as u8;
let diff = (4u8.abs_diff(indicator_thickness) as f32 * transition).round() as u8;
if 3 > indicator_thickness {
indicator_thickness + diff
} else {
@ -1738,63 +1738,76 @@ where
{
// we need to recalculate geometry for all elements, if we are drawing groups
if let Some(root) = tree.root_node_id() {
let mut stack = vec![non_exclusive_zone];
const OUTER_GAP: i32 = 8;
let outer_gap: i32 = (OUTER_GAP as f32 * transition).round() as i32;
const INNER_GAP: i32 = 16;
let inner_gap: i32 = (INNER_GAP as f32 * transition).round() as i32;
let mut stack = vec![Rectangle::from_loc_and_size(
non_exclusive_zone.loc + Point::from((outer_gap, outer_gap)),
(non_exclusive_zone.size.to_point() - Point::from((outer_gap * 2, outer_gap * 2)))
.to_size(),
)];
let mut elements = Vec::new();
let mut geometries = HashMap::new();
const GAP: i32 = 16;
let gap: i32 = (GAP as f32 * transition).round() as i32;
let alpha = alpha * transition;
let focused = seat
.and_then(|seat| TilingLayout::currently_focused_node(&tree, seat))
.map(|(id, _)| id);
let has_potential_groups = if let Some(focused_id) = focused.as_ref() {
let focused_node = tree.get(focused_id).unwrap();
if let Some(parent) = focused_node.parent() {
let parent_node = tree.get(parent).unwrap();
parent_node.children().len() > 2
|| parent_node.children().iter().any(|id| {
let data = tree.get(id).unwrap().data();
data.is_group() && data.orientation() == parent_node.data().orientation()
})
} else {
false
}
} else {
false
};
for node_id in tree.traverse_pre_order_ids(root).unwrap() {
if let Some(mut geo) = stack.pop() {
// zoom in windows
geo.loc += (gap, gap).into();
geo.size -= (gap * 2, gap * 2).into();
let node: &Node<Data> = tree.get(&node_id).unwrap();
let data = node.data();
let is_potential_group = if let Some(focused_id) = focused.as_ref() {
// 1. focused can move into us directly
if let Some(parent) = node.parent() {
let parent_data = tree.get(parent).unwrap().data();
let render_potential_group = has_potential_groups
&& (if let Some(focused_id) = focused.as_ref() {
// `focused` can move into us directly
if let Some(parent) = node.parent() {
let parent_data = tree.get(parent).unwrap().data();
let idx = tree
.children_ids(parent)
.unwrap()
.position(|id| id == &node_id)
.unwrap();
if let Some(focused_idx) = tree
.children_ids(parent)
.unwrap()
.position(|id| id == focused_id)
{
// only direct neighbors
focused_idx.abs_diff(idx) == 1
let idx = tree
.children_ids(parent)
.unwrap()
.position(|id| id == &node_id)
.unwrap();
if let Some(focused_idx) = tree
.children_ids(parent)
.unwrap()
.position(|id| id == focused_id)
{
// only direct neighbors
focused_idx.abs_diff(idx) == 1
// skip neighbors, if this is a group of two windows
&& !(parent_data.len() == 2 && data.is_mapped(None))
// skip groups of two in opposite orientation to indicate move between
&& !(parent_data.len() == 2 && if data.is_group() { parent_data.orientation() != data.orientation() } else { false } )
} else {
false
}
} else {
false
}
}
// 2. focused can move out into us
else {
tree.children_ids(&node_id).unwrap().any(|child_id| {
tree.children_ids(child_id)
.unwrap()
.any(|child_id| child_id == focused_id)
})
}
} else {
false
};
} else {
false
});
match data {
Data::Group {
@ -1803,30 +1816,29 @@ where
sizes,
alive,
} => {
let has_active_child = if let Some(focused_id) = focused.as_ref() {
tree.children_ids(&node_id)
.unwrap()
.any(|child_id| child_id == focused_id)
let render_active_child = if let Some(focused_id) = focused.as_ref() {
!has_potential_groups
&& tree
.children_ids(&node_id)
.unwrap()
.any(|child_id| child_id == focused_id)
} else {
false
};
if (is_potential_group || has_active_child) && &node_id != root {
if (render_potential_group || render_active_child) && &node_id != root {
elements.push(
IndicatorShader::element(
renderer,
Key::Group(Arc::downgrade(&alive)),
geo,
3,
alpha,
if has_active_child {
ACTIVE_GROUP_COLOR
} else {
GROUP_COLOR
},
4,
if render_active_child { 16 } else { 8 },
alpha * if render_potential_group { 0.14 } else { 1.0 },
GROUP_COLOR,
)
.into(),
)
);
}
geometries.insert(node_id.clone(), geo);
@ -1876,26 +1888,50 @@ where
}
}
Data::Mapped { mapped, .. } => {
if is_potential_group {
geo.loc += (outer_gap, outer_gap).into();
geo.size -= (outer_gap * 2, outer_gap * 2).into();
if render_potential_group {
elements.push(
IndicatorShader::element(
renderer,
mapped.clone(),
geo,
3,
alpha,
4,
8,
alpha * if render_potential_group { 0.4 } else { 1.0 },
GROUP_COLOR,
)
.into(),
);
geo.loc += (outer_gap, outer_gap).into();
geo.size -= (outer_gap * 2, outer_gap * 2).into();
}
if is_potential_group
|| node.parent().map(|parent| parent == root).unwrap_or(false)
{
geo.loc += (gap, gap).into();
geo.size -= (gap * 2, gap * 2).into();
}
elements.push(
BackdropShader::element(
renderer,
mapped.clone(),
geo,
8.,
alpha
* if focused
.as_ref()
.map(|focused_id| focused_id == &node_id)
.unwrap_or(false)
{
0.4
} else {
0.15
},
GROUP_COLOR,
)
.into(),
);
geo.loc += (inner_gap, inner_gap).into();
geo.size -= (inner_gap * 2, inner_gap * 2).into();
geometries.insert(node_id.clone(), geo);
}
@ -2157,7 +2193,6 @@ where
geo,
indicator_thickness,
1.0,
FOCUS_INDICATOR_COLOR,
);
elements.push(element.into());
}