Implement layer rules: opacity and block-out-from

This commit is contained in:
Ivan Molodetskikh
2024-11-14 11:33:08 +03:00
parent fbbd3ba349
commit 1a0612cbfd
11 changed files with 401 additions and 17 deletions
+48 -17
View File
@@ -28,8 +28,8 @@ use smithay::backend::renderer::element::utils::{
select_dmabuf_feedback, Relocate, RelocateRenderElement,
};
use smithay::backend::renderer::element::{
default_primary_scanout_output_compare, AsRenderElements, Element as _, Id, Kind,
PrimaryScanoutOutput, RenderElementStates,
default_primary_scanout_output_compare, Element as _, Id, Kind, PrimaryScanoutOutput,
RenderElementStates,
};
use smithay::backend::renderer::gles::GlesRenderer;
use smithay::backend::renderer::sync::SyncPoint;
@@ -116,6 +116,8 @@ use crate::input::{
apply_libinput_settings, mods_with_finger_scroll_binds, mods_with_wheel_binds, TabletData,
};
use crate::ipc::server::IpcServer;
use crate::layer::mapped::LayerSurfaceRenderElement;
use crate::layer::MappedLayer;
use crate::layout::tile::TileRenderElement;
use crate::layout::workspace::WorkspaceId;
use crate::layout::{Layout, LayoutElement as _, MonitorRenderElement};
@@ -191,6 +193,9 @@ pub struct Niri {
/// Layer surfaces which don't have a buffer attached yet.
pub unmapped_layer_surfaces: HashSet<WlSurface>,
/// Extra data for mapped layer surfaces.
pub mapped_layer_surfaces: HashMap<LayerSurface, MappedLayer>,
// Cached root surface for every surface, so that we can access it in destroyed() where the
// normal get_parent() is cleared out.
pub root_surface: HashMap<WlSurface, WlSurface>,
@@ -1012,6 +1017,7 @@ impl State {
let mut output_config_changed = false;
let mut preserved_output_config = None;
let mut window_rules_changed = false;
let mut layer_rules_changed = false;
let mut debug_config_changed = false;
let mut shaders_changed = false;
let mut cursor_inactivity_timeout_changed = false;
@@ -1071,6 +1077,10 @@ impl State {
window_rules_changed = true;
}
if config.layer_rules != old_config.layer_rules {
layer_rules_changed = true;
}
if config.animations.window_resize.custom_shader
!= old_config.animations.window_resize.custom_shader
{
@@ -1153,6 +1163,10 @@ impl State {
self.niri.recompute_window_rules();
}
if layer_rules_changed {
self.niri.recompute_layer_rules();
}
if shaders_changed {
self.niri.layout.update_shaders();
}
@@ -1816,6 +1830,7 @@ impl Niri {
let _span = tracy_client::span!("startup timeout");
state.niri.is_at_startup = false;
state.niri.recompute_window_rules();
state.niri.recompute_layer_rules();
TimeoutAction::Drop
},
)
@@ -1839,6 +1854,7 @@ impl Niri {
output_state: HashMap::new(),
unmapped_windows: HashMap::new(),
unmapped_layer_surfaces: HashSet::new(),
mapped_layer_surfaces: HashMap::new(),
root_surface: HashMap::new(),
dmabuf_pre_commit_hook: HashMap::new(),
blocker_cleared_tx,
@@ -3110,7 +3126,7 @@ impl Niri {
// Get layer-shell elements.
let layer_map = layer_map_for_output(output);
let mut extend_from_layer = |elements: &mut Vec<OutputRenderElements<R>>, layer| {
self.render_layer(renderer, output_scale, &layer_map, layer, elements);
self.render_layer(renderer, target, output_scale, &layer_map, layer, elements);
};
// The upper layer-shell elements go next.
@@ -3144,7 +3160,8 @@ impl Niri {
fn render_layer<R: NiriRenderer>(
&self,
renderer: &mut R,
output_scale: Scale<f64>,
target: RenderTarget,
scale: Scale<f64>,
layer_map: &LayerMap,
layer: Layer,
elements: &mut Vec<OutputRenderElements<R>>,
@@ -3152,20 +3169,13 @@ impl Niri {
let iter = layer_map
.layers_on(layer)
.filter_map(|surface| {
layer_map
.layer_geometry(surface)
.map(|geo| (geo.loc, surface))
let mapped = self.mapped_layer_surfaces.get(surface)?;
let geo = layer_map.layer_geometry(surface)?;
Some((mapped, geo))
})
.flat_map(|(loc, surface)| {
surface
.render_elements(
renderer,
loc.to_physical_precise_round(output_scale),
output_scale,
1.,
)
.into_iter()
.map(OutputRenderElements::Wayland)
.flat_map(|(mapped, geo)| {
let elements = mapped.render(renderer, geo, scale, target);
elements.into_iter().map(OutputRenderElements::LayerSurface)
});
elements.extend(iter);
}
@@ -4805,6 +4815,26 @@ impl Niri {
}
}
pub fn recompute_layer_rules(&mut self) {
let _span = tracy_client::span!("Niri::recompute_layer_rules");
let mut changed = false;
{
let rules = &self.config.borrow().layer_rules;
for mapped in self.mapped_layer_surfaces.values_mut() {
if mapped.recompute_layer_rules(rules, self.is_at_startup) {
changed = true;
}
}
}
if changed {
// FIXME: granular.
self.queue_redraw_all();
}
}
pub fn reset_pointer_inactivity_timer(&mut self) {
let _span = tracy_client::span!("Niri::reset_pointer_inactivity_timer");
@@ -4850,6 +4880,7 @@ niri_render_elements! {
OutputRenderElements<R> => {
Monitor = MonitorRenderElement<R>,
Tile = TileRenderElement<R>,
LayerSurface = LayerSurfaceRenderElement<R>,
Wayland = WaylandSurfaceRenderElement<R>,
NamedPointer = MemoryRenderBufferRenderElement<R>,
SolidColor = SolidColorRenderElement,