render: Add focus indicator
This commit is contained in:
parent
a8920f533e
commit
9b416b5779
11 changed files with 291 additions and 68 deletions
52
Cargo.lock
generated
52
Cargo.lock
generated
|
|
@ -455,7 +455,7 @@ dependencies = [
|
||||||
"fontdb 0.10.0",
|
"fontdb 0.10.0",
|
||||||
"libm",
|
"libm",
|
||||||
"log",
|
"log",
|
||||||
"ouroboros 0.15.5",
|
"ouroboros 0.15.6",
|
||||||
"rangemap",
|
"rangemap",
|
||||||
"rustybuzz 0.6.0",
|
"rustybuzz 0.6.0",
|
||||||
"swash",
|
"swash",
|
||||||
|
|
@ -1097,7 +1097,7 @@ checksum = "d52186a39c335aa6f79fc0bf1c3cf854870b6ad4e50a7bb8a59b4ba1331f478a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fontconfig-parser",
|
"fontconfig-parser",
|
||||||
"log",
|
"log",
|
||||||
"memmap2 0.5.8",
|
"memmap2 0.5.10",
|
||||||
"ttf-parser 0.17.1",
|
"ttf-parser 0.17.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1108,7 +1108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8131752b3f3b876a20f42b3d08233ad177d6e7ec6d18aaa6954489a201071be5"
|
checksum = "8131752b3f3b876a20f42b3d08233ad177d6e7ec6d18aaa6954489a201071be5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"memmap2 0.5.8",
|
"memmap2 0.5.10",
|
||||||
"ttf-parser 0.17.1",
|
"ttf-parser 0.17.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1355,9 +1355,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glyph_brush"
|
name = "glyph_brush"
|
||||||
version = "0.7.6"
|
version = "0.7.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b773a724cb29f6119043a46bd2fc6bfedce59ab9898a3c07df66082acbea0ca"
|
checksum = "4edefd123f28a0b1d41ec4a489c2b43020b369180800977801611084f342978d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glyph_brush_draw_cache",
|
"glyph_brush_draw_cache",
|
||||||
"glyph_brush_layout",
|
"glyph_brush_layout",
|
||||||
|
|
@ -1975,9 +1975,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
version = "0.5.8"
|
version = "0.5.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc"
|
checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
@ -2263,18 +2263,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_enum"
|
name = "num_enum"
|
||||||
version = "0.5.9"
|
version = "0.5.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d829733185c1ca374f17e52b762f24f535ec625d2cc1f070e34c8a9068f341b"
|
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num_enum_derive",
|
"num_enum_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_enum_derive"
|
name = "num_enum_derive"
|
||||||
version = "0.5.9"
|
version = "0.5.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2be1598bf1c313dcdd12092e3f1920f463462525a21b7b4e11b4168353d0123e"
|
checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
@ -2348,12 +2348,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ouroboros"
|
name = "ouroboros"
|
||||||
version = "0.15.5"
|
version = "0.15.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfbb50b356159620db6ac971c6d5c9ab788c9cc38a6f49619fca2a27acb062ca"
|
checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aliasable",
|
"aliasable",
|
||||||
"ouroboros_macro 0.15.5",
|
"ouroboros_macro 0.15.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2371,9 +2371,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ouroboros_macro"
|
name = "ouroboros_macro"
|
||||||
version = "0.15.5"
|
version = "0.15.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a0d9d1a6191c4f391f87219d1ea42b23f09ee84d64763cd05ee6ea88d9f384d"
|
checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
|
|
@ -2874,9 +2874,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rgb"
|
name = "rgb"
|
||||||
version = "0.8.35"
|
version = "0.8.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7495acf66551cdb696b7711408144bcd3194fc78e32f3a09e809bfe7dd4a7ce3"
|
checksum = "20ec2d3e3fc7a92ced357df9cebd5a10b6fb2aa1ee797bf7e9ce2f17dffc8f59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
@ -3114,9 +3114,9 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.7"
|
version = "0.4.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
|
checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
@ -3200,7 +3200,7 @@ dependencies = [
|
||||||
"dlib",
|
"dlib",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"memmap2 0.5.8",
|
"memmap2 0.5.10",
|
||||||
"nix 0.24.3",
|
"nix 0.24.3",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"wayland-client 0.29.5",
|
"wayland-client 0.29.5",
|
||||||
|
|
@ -3350,9 +3350,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.107"
|
version = "1.0.109"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -3862,9 +3862,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-backend"
|
name = "wayland-backend"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb23bfea266c92bb051ea36cce0eb1a52b743dc1c5f168021947eda79764656d"
|
checksum = "79ebd48bfc1178c9190c7ff80cc822b3335ffc83141e9aa723168f377257623e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"downcast-rs",
|
"downcast-rs",
|
||||||
|
|
@ -4450,7 +4450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "acbee136714379ab22da0280207fdb7f47e0bb940adea97731b65598b8c7a92e"
|
checksum = "acbee136714379ab22da0280207fdb7f47e0bb940adea97731b65598b8c7a92e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"memmap2 0.5.8",
|
"memmap2 0.5.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ mod drm_helpers;
|
||||||
mod socket;
|
mod socket;
|
||||||
use socket::*;
|
use socket::*;
|
||||||
|
|
||||||
use super::render::{CursorMode, GlMultiRenderer};
|
use super::render::{init_shaders, CursorMode, GlMultiRenderer};
|
||||||
// for now we assume we need at least 3ms
|
// for now we assume we need at least 3ms
|
||||||
const MIN_RENDER_TIME: Duration = Duration::from_millis(3);
|
const MIN_RENDER_TIME: Duration = Duration::from_millis(3);
|
||||||
|
|
||||||
|
|
@ -542,14 +542,18 @@ impl State {
|
||||||
render_node
|
render_node
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let mut renderer = match backend.api.single_renderer(&render_node) {
|
||||||
|
Ok(renderer) => renderer,
|
||||||
|
Err(err) => {
|
||||||
|
warn!(?err, "Failed to initialize output.");
|
||||||
|
backend.api.as_mut().remove_node(&render_node);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
init_shaders(&mut renderer).expect("Failed to initialize renderer");
|
||||||
|
|
||||||
for (crtc, conn) in outputs {
|
for (crtc, conn) in outputs {
|
||||||
let mut renderer = match backend.api.single_renderer(&render_node) {
|
|
||||||
Ok(renderer) => renderer,
|
|
||||||
Err(err) => {
|
|
||||||
warn!(?err, "Failed to initialize output.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
match device.setup_surface(crtc, conn, (w, 0), &mut renderer) {
|
match device.setup_surface(crtc, conn, (w, 0), &mut renderer) {
|
||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
w += output
|
w += output
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
borrow::{Borrow, BorrowMut},
|
||||||
|
cell::RefCell,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use crate::{debug::fps_ui, utils::prelude::*};
|
use crate::{debug::fps_ui, utils::prelude::*};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -26,15 +31,18 @@ use smithay::{
|
||||||
damage::{
|
damage::{
|
||||||
DamageTrackedRenderer, DamageTrackedRendererError as RenderError, OutputNoMode,
|
DamageTrackedRenderer, DamageTrackedRendererError as RenderError, OutputNoMode,
|
||||||
},
|
},
|
||||||
element::{RenderElement, RenderElementStates},
|
element::{Element, RenderElement, RenderElementStates},
|
||||||
gles2::Gles2Error,
|
gles2::{
|
||||||
|
element::PixelShaderElement, Gles2Error, Gles2PixelProgram, Gles2Renderer, Uniform,
|
||||||
|
UniformName, UniformType,
|
||||||
|
},
|
||||||
glow::GlowRenderer,
|
glow::GlowRenderer,
|
||||||
multigpu::{gbm::GbmGlesBackend, MultiFrame, MultiRenderer},
|
multigpu::{gbm::GbmGlesBackend, MultiFrame, MultiRenderer},
|
||||||
Bind, Blit, ExportMem, ImportAll, ImportMem, Offscreen, Renderer, TextureFilter,
|
Bind, Blit, ExportMem, ImportAll, ImportMem, Offscreen, Renderer, TextureFilter,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
output::Output,
|
output::Output,
|
||||||
utils::{Physical, Rectangle},
|
utils::{Logical, Physical, Point, Rectangle, Size},
|
||||||
wayland::dmabuf::get_dmabuf,
|
wayland::dmabuf::get_dmabuf,
|
||||||
};
|
};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
@ -50,6 +58,93 @@ pub type GlMultiFrame<'a, 'b, 'frame> =
|
||||||
MultiFrame<'a, 'a, 'b, 'frame, GbmGlesBackend<GlowRenderer>, GbmGlesBackend<GlowRenderer>>;
|
MultiFrame<'a, 'a, 'b, 'frame, GbmGlesBackend<GlowRenderer>, GbmGlesBackend<GlowRenderer>>;
|
||||||
|
|
||||||
pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0];
|
pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0];
|
||||||
|
pub static FOCUS_INDICATOR_COLOR: [f32; 4] = [0.580, 0.921, 0.921, 1.0];
|
||||||
|
pub static FOCUS_INDICATOR_THICKNESS: f32 = 4.0;
|
||||||
|
pub static FOCUS_INDICATOR_RADIUS: f32 = 8.0;
|
||||||
|
pub static FOCUS_INDICATOR_SHADER: &str = include_str!("./shaders/focus_indicator.frag");
|
||||||
|
|
||||||
|
pub struct IndicatorShader(pub Gles2PixelProgram);
|
||||||
|
struct IndicatorElement(pub RefCell<PixelShaderElement>);
|
||||||
|
|
||||||
|
impl IndicatorShader {
|
||||||
|
pub fn get<R: AsGlowRenderer>(renderer: &R) -> Gles2PixelProgram {
|
||||||
|
Borrow::<Gles2Renderer>::borrow(renderer.glow_renderer())
|
||||||
|
.egl_context()
|
||||||
|
.user_data()
|
||||||
|
.get::<IndicatorShader>()
|
||||||
|
.expect("Custom Shaders not initialized")
|
||||||
|
.0
|
||||||
|
.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn element<R: AsGlowRenderer>(
|
||||||
|
renderer: &R,
|
||||||
|
geo: Rectangle<i32, Logical>,
|
||||||
|
) -> PixelShaderElement {
|
||||||
|
let thickness = FOCUS_INDICATOR_THICKNESS;
|
||||||
|
let thickness_loc = (thickness as i32, thickness as i32);
|
||||||
|
let thickness_size = ((thickness * 2.0) as i32, (thickness * 2.0) as i32);
|
||||||
|
let geo = Rectangle::from_loc_and_size(
|
||||||
|
geo.loc - Point::from(thickness_loc),
|
||||||
|
geo.size + Size::from(thickness_size),
|
||||||
|
);
|
||||||
|
|
||||||
|
let user_data = Borrow::<Gles2Renderer>::borrow(renderer.glow_renderer())
|
||||||
|
.egl_context()
|
||||||
|
.user_data();
|
||||||
|
|
||||||
|
match user_data.get::<IndicatorElement>() {
|
||||||
|
Some(elem) => {
|
||||||
|
let mut elem = elem.0.borrow_mut();
|
||||||
|
if elem.geometry(1.0.into()).to_logical(1) != geo {
|
||||||
|
elem.resize(geo, None);
|
||||||
|
}
|
||||||
|
elem.clone()
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let shader = Self::get(renderer);
|
||||||
|
let color = FOCUS_INDICATOR_COLOR;
|
||||||
|
|
||||||
|
let elem = PixelShaderElement::new(
|
||||||
|
shader,
|
||||||
|
dbg!(geo),
|
||||||
|
None, //TODO
|
||||||
|
color[3],
|
||||||
|
vec![
|
||||||
|
Uniform::new("color", [color[0], color[1], color[2]]),
|
||||||
|
Uniform::new("thickness", thickness),
|
||||||
|
Uniform::new("radius", FOCUS_INDICATOR_RADIUS),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
if !user_data.insert_if_missing(|| IndicatorElement(RefCell::new(elem.clone()))) {
|
||||||
|
*user_data.get::<IndicatorElement>().unwrap().0.borrow_mut() = elem.clone();
|
||||||
|
}
|
||||||
|
elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_shaders<R: AsGlowRenderer>(renderer: &mut R) -> Result<(), Gles2Error> {
|
||||||
|
let glow_renderer = renderer.glow_renderer_mut();
|
||||||
|
let gles_renderer: &mut Gles2Renderer = glow_renderer.borrow_mut();
|
||||||
|
|
||||||
|
let indicator_shader = gles_renderer.compile_custom_pixel_shader(
|
||||||
|
FOCUS_INDICATOR_SHADER,
|
||||||
|
&[
|
||||||
|
UniformName::new("color", UniformType::_3f),
|
||||||
|
UniformName::new("thickness", UniformType::_1f),
|
||||||
|
UniformName::new("radius", UniformType::_1f),
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let egl_context = gles_renderer.egl_context();
|
||||||
|
egl_context
|
||||||
|
.user_data()
|
||||||
|
.insert_if_missing(|| IndicatorShader(indicator_shader));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum CursorMode {
|
pub enum CursorMode {
|
||||||
|
|
@ -248,6 +343,13 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let last_active_seat = state.last_active_seat().clone();
|
||||||
|
let move_active = last_active_seat
|
||||||
|
.user_data()
|
||||||
|
.get::<SeatMoveGrabState>()
|
||||||
|
.unwrap()
|
||||||
|
.borrow()
|
||||||
|
.is_some();
|
||||||
elements.extend(
|
elements.extend(
|
||||||
workspace
|
workspace
|
||||||
.render_output::<R>(
|
.render_output::<R>(
|
||||||
|
|
@ -255,6 +357,7 @@ where
|
||||||
output,
|
output,
|
||||||
&state.shell.override_redirect_windows,
|
&state.shell.override_redirect_windows,
|
||||||
state.xwayland_state.values_mut(),
|
state.xwayland_state.values_mut(),
|
||||||
|
(!move_active).then_some(&last_active_seat),
|
||||||
exclude_workspace_overview,
|
exclude_workspace_overview,
|
||||||
)
|
)
|
||||||
.map_err(|_| OutputNoMode)?
|
.map_err(|_| OutputNoMode)?
|
||||||
|
|
|
||||||
33
src/backend/render/shaders/focus_indicator.frag
Normal file
33
src/backend/render/shaders/focus_indicator.frag
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
precision mediump float;
|
||||||
|
uniform float alpha;
|
||||||
|
#if defined(DEBUG_FLAGS)
|
||||||
|
uniform float tint;
|
||||||
|
#endif
|
||||||
|
uniform vec2 size;
|
||||||
|
varying vec2 v_coords;
|
||||||
|
|
||||||
|
uniform vec3 color;
|
||||||
|
uniform float thickness;
|
||||||
|
uniform float radius;
|
||||||
|
|
||||||
|
float rounded_box(vec2 center, vec2 size, float radius) {
|
||||||
|
return length(max(abs(center) - size + radius, 0.0)) - radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 center = size / 2.0 - vec2(0.5);
|
||||||
|
vec2 location = v_coords * size;
|
||||||
|
vec4 mix_color;
|
||||||
|
|
||||||
|
float distance = rounded_box(location - center, size / 2.0 - vec2(thickness / 2.0), radius);
|
||||||
|
float smoothedAlpha = 1.0 - smoothstep(0.0, 2.0, abs(distance) - (thickness / 2.0));
|
||||||
|
|
||||||
|
mix_color = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(color, alpha), smoothedAlpha);
|
||||||
|
|
||||||
|
#if defined(DEBUG_FLAGS)
|
||||||
|
if (tint == 1.0)
|
||||||
|
mix_color = vec4(0.0, 0.3, 0.0, 0.2) + mix_color * 0.8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragColor = mix_color;
|
||||||
|
}
|
||||||
|
|
@ -32,7 +32,7 @@ use tracing::{error, info, warn};
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use crate::state::Fps;
|
use crate::state::Fps;
|
||||||
|
|
||||||
use super::render::CursorMode;
|
use super::render::{init_shaders, CursorMode};
|
||||||
|
|
||||||
pub struct WinitState {
|
pub struct WinitState {
|
||||||
// The winit backend currently has no notion of multiple windows
|
// The winit backend currently has no notion of multiple windows
|
||||||
|
|
@ -147,6 +147,7 @@ pub fn init_backend(
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let (mut backend, mut input) =
|
let (mut backend, mut input) =
|
||||||
winit::init().map_err(|_| anyhow!("Failed to initilize winit backend"))?;
|
winit::init().map_err(|_| anyhow!("Failed to initilize winit backend"))?;
|
||||||
|
init_shaders(backend.renderer()).expect("Failed to initialize renderer");
|
||||||
|
|
||||||
init_egl_client_side(dh, state, &mut backend)?;
|
init_egl_client_side(dh, state, &mut backend)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ use tracing::{debug, error, info, warn};
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use crate::state::Fps;
|
use crate::state::Fps;
|
||||||
|
|
||||||
|
use super::render::init_shaders;
|
||||||
|
|
||||||
enum Allocator {
|
enum Allocator {
|
||||||
Gbm(GbmAllocator<DrmDeviceFd>),
|
Gbm(GbmAllocator<DrmDeviceFd>),
|
||||||
Vulkan(PhysicalDevice),
|
Vulkan(PhysicalDevice),
|
||||||
|
|
@ -348,6 +350,7 @@ pub fn init_backend(
|
||||||
let mut renderer =
|
let mut renderer =
|
||||||
unsafe { GlowRenderer::new(context) }.with_context(|| "Failed to initialize renderer")?;
|
unsafe { GlowRenderer::new(context) }.with_context(|| "Failed to initialize renderer")?;
|
||||||
|
|
||||||
|
init_shaders(&mut renderer).expect("Failed to initialize renderer");
|
||||||
init_egl_client_side(dh, state, &mut renderer)?;
|
init_egl_client_side(dh, state, &mut renderer)?;
|
||||||
|
|
||||||
state.backend = BackendData::X11(X11State {
|
state.backend = BackendData::X11(X11State {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{element::AsGlowRenderer, GlMultiFrame, GlMultiRenderer},
|
backend::render::{
|
||||||
|
element::{AsGlowFrame, AsGlowRenderer},
|
||||||
|
GlMultiFrame, GlMultiRenderer,
|
||||||
|
},
|
||||||
state::State,
|
state::State,
|
||||||
utils::prelude::SeatExt,
|
utils::prelude::SeatExt,
|
||||||
};
|
};
|
||||||
|
|
@ -9,7 +12,9 @@ use smithay::{
|
||||||
input::KeyState,
|
input::KeyState,
|
||||||
renderer::{
|
renderer::{
|
||||||
element::{AsRenderElements, Element, RenderElement, UnderlyingStorage},
|
element::{AsRenderElements, Element, RenderElement, UnderlyingStorage},
|
||||||
|
gles2::element::PixelShaderElement,
|
||||||
glow::GlowRenderer,
|
glow::GlowRenderer,
|
||||||
|
multigpu::Error as MultiError,
|
||||||
ImportAll, ImportMem, Renderer,
|
ImportAll, ImportMem, Renderer,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -46,14 +51,10 @@ pub use self::stack::CosmicStack;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
pub use self::window::CosmicWindow;
|
pub use self::window::CosmicWindow;
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
|
||||||
use crate::backend::render::element::AsGlowFrame;
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use egui::plot::{Corner, Legend, Plot, PlotPoints, Polygon};
|
use egui::plot::{Corner, Legend, Plot, PlotPoints, Polygon};
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use smithay::backend::renderer::{
|
use smithay::backend::renderer::{element::texture::TextureRenderElement, gles2::Gles2Texture};
|
||||||
element::texture::TextureRenderElement, gles2::Gles2Texture, multigpu::Error as MultiError,
|
|
||||||
};
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
|
@ -659,6 +660,7 @@ where
|
||||||
{
|
{
|
||||||
Stack(self::stack::CosmicStackRenderElement<R>),
|
Stack(self::stack::CosmicStackRenderElement<R>),
|
||||||
Window(self::window::CosmicWindowRenderElement<R>),
|
Window(self::window::CosmicWindowRenderElement<R>),
|
||||||
|
Indicator(PixelShaderElement),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
Egui(TextureRenderElement<Gles2Texture>),
|
Egui(TextureRenderElement<Gles2Texture>),
|
||||||
}
|
}
|
||||||
|
|
@ -672,6 +674,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.id(),
|
CosmicMappedRenderElement::Stack(elem) => elem.id(),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.id(),
|
CosmicMappedRenderElement::Window(elem) => elem.id(),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => elem.id(),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => elem.id(),
|
CosmicMappedRenderElement::Egui(elem) => elem.id(),
|
||||||
}
|
}
|
||||||
|
|
@ -681,6 +684,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.current_commit(),
|
CosmicMappedRenderElement::Stack(elem) => elem.current_commit(),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.current_commit(),
|
CosmicMappedRenderElement::Window(elem) => elem.current_commit(),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => elem.current_commit(),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => elem.current_commit(),
|
CosmicMappedRenderElement::Egui(elem) => elem.current_commit(),
|
||||||
}
|
}
|
||||||
|
|
@ -690,6 +694,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.src(),
|
CosmicMappedRenderElement::Stack(elem) => elem.src(),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.src(),
|
CosmicMappedRenderElement::Window(elem) => elem.src(),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => elem.src(),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => elem.src(),
|
CosmicMappedRenderElement::Egui(elem) => elem.src(),
|
||||||
}
|
}
|
||||||
|
|
@ -699,6 +704,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.geometry(scale),
|
CosmicMappedRenderElement::Stack(elem) => elem.geometry(scale),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.geometry(scale),
|
CosmicMappedRenderElement::Window(elem) => elem.geometry(scale),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => elem.geometry(scale),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale),
|
CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale),
|
||||||
}
|
}
|
||||||
|
|
@ -708,6 +714,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.location(scale),
|
CosmicMappedRenderElement::Stack(elem) => elem.location(scale),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.location(scale),
|
CosmicMappedRenderElement::Window(elem) => elem.location(scale),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => elem.location(scale),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => elem.location(scale),
|
CosmicMappedRenderElement::Egui(elem) => elem.location(scale),
|
||||||
}
|
}
|
||||||
|
|
@ -717,6 +724,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.transform(),
|
CosmicMappedRenderElement::Stack(elem) => elem.transform(),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.transform(),
|
CosmicMappedRenderElement::Window(elem) => elem.transform(),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => elem.transform(),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => elem.transform(),
|
CosmicMappedRenderElement::Egui(elem) => elem.transform(),
|
||||||
}
|
}
|
||||||
|
|
@ -730,6 +738,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.damage_since(scale, commit),
|
CosmicMappedRenderElement::Stack(elem) => elem.damage_since(scale, commit),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.damage_since(scale, commit),
|
CosmicMappedRenderElement::Window(elem) => elem.damage_since(scale, commit),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => elem.damage_since(scale, commit),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit),
|
CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit),
|
||||||
}
|
}
|
||||||
|
|
@ -739,6 +748,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.opaque_regions(scale),
|
CosmicMappedRenderElement::Stack(elem) => elem.opaque_regions(scale),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.opaque_regions(scale),
|
CosmicMappedRenderElement::Window(elem) => elem.opaque_regions(scale),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => elem.opaque_regions(scale),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale),
|
CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale),
|
||||||
}
|
}
|
||||||
|
|
@ -756,6 +766,9 @@ impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> {
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage),
|
CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
|
CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => {
|
||||||
|
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
|
||||||
|
}
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => {
|
CosmicMappedRenderElement::Egui(elem) => {
|
||||||
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
|
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
|
||||||
|
|
@ -767,6 +780,7 @@ impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> {
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer),
|
CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer),
|
CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => elem.underlying_storage(renderer),
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer),
|
CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer),
|
||||||
}
|
}
|
||||||
|
|
@ -786,6 +800,10 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage),
|
CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
|
CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => {
|
||||||
|
RenderElement::<GlowRenderer>::draw(elem, frame.glow_frame_mut(), src, dst, damage)
|
||||||
|
.map_err(|err| MultiError::Render(err))
|
||||||
|
}
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => {
|
CosmicMappedRenderElement::Egui(elem) => {
|
||||||
let glow_frame = frame.glow_frame_mut();
|
let glow_frame = frame.glow_frame_mut();
|
||||||
|
|
@ -802,6 +820,9 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
|
||||||
match self {
|
match self {
|
||||||
CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer),
|
CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer),
|
||||||
CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer),
|
CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer),
|
||||||
|
CosmicMappedRenderElement::Indicator(elem) => {
|
||||||
|
elem.underlying_storage(renderer.glow_renderer_mut())
|
||||||
|
}
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
CosmicMappedRenderElement::Egui(elem) => {
|
CosmicMappedRenderElement::Egui(elem) => {
|
||||||
let glow_renderer = renderer.glow_renderer_mut();
|
let glow_renderer = renderer.glow_renderer_mut();
|
||||||
|
|
@ -836,6 +857,18 @@ where
|
||||||
CosmicMappedRenderElement::Window(elem)
|
CosmicMappedRenderElement::Window(elem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<R> From<PixelShaderElement> for CosmicMappedRenderElement<R>
|
||||||
|
where
|
||||||
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
|
<R as Renderer>::TextureId: 'static,
|
||||||
|
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||||
|
{
|
||||||
|
fn from(elem: PixelShaderElement) -> Self {
|
||||||
|
CosmicMappedRenderElement::Indicator(elem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
impl<R> From<TextureRenderElement<Gles2Texture>> for CosmicMappedRenderElement<R>
|
impl<R> From<TextureRenderElement<Gles2Texture>> for CosmicMappedRenderElement<R>
|
||||||
where
|
where
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::element::AsGlowRenderer,
|
backend::render::{element::AsGlowRenderer, IndicatorShader},
|
||||||
shell::{
|
shell::{
|
||||||
element::{CosmicMapped, CosmicMappedRenderElement},
|
element::{CosmicMapped, CosmicMappedRenderElement},
|
||||||
focus::target::{KeyboardFocusTarget, PointerFocusTarget},
|
focus::target::{KeyboardFocusTarget, PointerFocusTarget},
|
||||||
|
|
@ -56,13 +56,22 @@ impl MoveGrabState {
|
||||||
}
|
}
|
||||||
|
|
||||||
let scale = output.current_scale().fractional_scale().into();
|
let scale = output.current_scale().fractional_scale().into();
|
||||||
AsRenderElements::<R>::render_elements::<I>(
|
let mut elements: Vec<I> = vec![CosmicMappedRenderElement::from(IndicatorShader::element(
|
||||||
|
renderer,
|
||||||
|
Rectangle::from_loc_and_size(
|
||||||
|
location.to_i32_round() - output.geometry().loc,
|
||||||
|
self.window.geometry().size,
|
||||||
|
),
|
||||||
|
))
|
||||||
|
.into()];
|
||||||
|
elements.extend(AsRenderElements::<R>::render_elements::<I>(
|
||||||
&self.window,
|
&self.window,
|
||||||
renderer,
|
renderer,
|
||||||
(location.to_i32_round() - output.geometry().loc - self.window.geometry().loc)
|
(location.to_i32_round() - output.geometry().loc - self.window.geometry().loc)
|
||||||
.to_physical_precise_round(scale),
|
.to_physical_precise_round(scale),
|
||||||
scale,
|
scale,
|
||||||
)
|
));
|
||||||
|
elements
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_frames(
|
pub fn send_frames(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::{element::RenderElement, ImportAll, ImportMem, Renderer},
|
backend::renderer::{
|
||||||
|
element::{AsRenderElements, RenderElement},
|
||||||
|
ImportAll, ImportMem, Renderer,
|
||||||
|
},
|
||||||
desktop::{layer_map_for_output, space::SpaceElement, Space},
|
desktop::{layer_map_for_output, space::SpaceElement, Space},
|
||||||
input::{pointer::GrabStartData as PointerGrabStartData, Seat},
|
input::{pointer::GrabStartData as PointerGrabStartData, Seat},
|
||||||
output::Output,
|
output::Output,
|
||||||
|
|
@ -10,11 +13,11 @@ use smithay::{
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::element::AsGlowRenderer,
|
backend::render::{element::AsGlowRenderer, IndicatorShader},
|
||||||
shell::{
|
shell::{
|
||||||
element::{CosmicMapped, CosmicMappedRenderElement},
|
element::{CosmicMapped, CosmicMappedRenderElement},
|
||||||
grabs::ResizeEdge,
|
grabs::ResizeEdge,
|
||||||
CosmicSurface, OutputNotMapped,
|
CosmicSurface,
|
||||||
},
|
},
|
||||||
state::State,
|
state::State,
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
|
|
@ -342,16 +345,37 @@ impl FloatingLayout {
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
) -> Result<Vec<CosmicMappedRenderElement<R>>, OutputNotMapped>
|
focused: Option<&CosmicMapped>,
|
||||||
|
) -> Vec<CosmicMappedRenderElement<R>>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
<R as Renderer>::TextureId: 'static,
|
<R as Renderer>::TextureId: 'static,
|
||||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||||
{
|
{
|
||||||
let output_scale = output.current_scale().fractional_scale();
|
let output_scale = output.current_scale().fractional_scale();
|
||||||
let output_geo = self.space.output_geometry(output).ok_or(OutputNotMapped)?;
|
self.space
|
||||||
Ok(self
|
.elements_for_output(output)
|
||||||
.space
|
.rev()
|
||||||
.render_elements_for_region(renderer, &output_geo, output_scale))
|
.flat_map(|elem| {
|
||||||
|
let render_location =
|
||||||
|
self.space.element_location(elem).unwrap() - elem.geometry().loc;
|
||||||
|
let mut elements = elem.render_elements(
|
||||||
|
renderer,
|
||||||
|
render_location.to_physical_precise_round(output_scale),
|
||||||
|
output_scale.into(),
|
||||||
|
);
|
||||||
|
if focused == Some(elem) {
|
||||||
|
let element = IndicatorShader::element(
|
||||||
|
renderer,
|
||||||
|
Rectangle::from_loc_and_size(
|
||||||
|
self.space.element_location(elem).unwrap(),
|
||||||
|
elem.geometry().size,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
elements.insert(0, element.into());
|
||||||
|
}
|
||||||
|
elements
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::element::AsGlowRenderer,
|
backend::render::{element::AsGlowRenderer, IndicatorShader},
|
||||||
shell::{
|
shell::{
|
||||||
element::{CosmicMapped, CosmicMappedRenderElement},
|
element::{CosmicMapped, CosmicMappedRenderElement},
|
||||||
focus::{
|
focus::{
|
||||||
|
|
@ -1299,6 +1299,7 @@ impl TilingLayout {
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
|
focused: Option<&CosmicMapped>,
|
||||||
) -> Result<Vec<CosmicMappedRenderElement<R>>, OutputNotMapped>
|
) -> Result<Vec<CosmicMappedRenderElement<R>>, OutputNotMapped>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
|
|
@ -1360,16 +1361,25 @@ impl TilingLayout {
|
||||||
})
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
.flat_map(|(mapped, loc)| {
|
.flat_map(|(mapped, loc)| {
|
||||||
AsRenderElements::<R>::render_elements::<CosmicMappedRenderElement<R>>(
|
let mut elements =
|
||||||
mapped,
|
AsRenderElements::<R>::render_elements::<CosmicMappedRenderElement<R>>(
|
||||||
renderer,
|
mapped,
|
||||||
loc.to_physical_precise_round(output_scale)
|
renderer,
|
||||||
- mapped
|
loc.to_physical_precise_round(output_scale)
|
||||||
.geometry()
|
- mapped
|
||||||
.loc
|
.geometry()
|
||||||
.to_physical_precise_round(output_scale),
|
.loc
|
||||||
Scale::from(output_scale),
|
.to_physical_precise_round(output_scale),
|
||||||
)
|
Scale::from(output_scale),
|
||||||
|
);
|
||||||
|
if focused == Some(mapped) {
|
||||||
|
let element = IndicatorShader::element(
|
||||||
|
renderer,
|
||||||
|
Rectangle::from_loc_and_size(loc, mapped.geometry().size),
|
||||||
|
);
|
||||||
|
elements.insert(0, element.into());
|
||||||
|
}
|
||||||
|
elements
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>())
|
.collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -435,6 +435,7 @@ impl Workspace {
|
||||||
output: &Output,
|
output: &Output,
|
||||||
override_redirect_windows: &[X11Surface],
|
override_redirect_windows: &[X11Surface],
|
||||||
xwm_state: impl Iterator<Item = &'a mut XWaylandState>,
|
xwm_state: impl Iterator<Item = &'a mut XWaylandState>,
|
||||||
|
draw_focus_indicator: Option<&Seat<State>>,
|
||||||
exclude_workspace_overview: bool,
|
exclude_workspace_overview: bool,
|
||||||
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
|
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
|
||||||
where
|
where
|
||||||
|
|
@ -559,10 +560,12 @@ impl Workspace {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let focused =
|
||||||
|
draw_focus_indicator.and_then(|seat| self.focus_stack.get(seat).last().cloned());
|
||||||
// floating surfaces
|
// floating surfaces
|
||||||
render_elements.extend(
|
render_elements.extend(
|
||||||
self.floating_layer
|
self.floating_layer
|
||||||
.render_output::<R>(renderer, output)?
|
.render_output::<R>(renderer, output, focused.as_ref())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(WorkspaceRenderElement::from),
|
.map(WorkspaceRenderElement::from),
|
||||||
);
|
);
|
||||||
|
|
@ -570,7 +573,7 @@ impl Workspace {
|
||||||
//tiling surfaces
|
//tiling surfaces
|
||||||
render_elements.extend(
|
render_elements.extend(
|
||||||
self.tiling_layer
|
self.tiling_layer
|
||||||
.render_output::<R>(renderer, output)?
|
.render_output::<R>(renderer, output, focused.as_ref())?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(WorkspaceRenderElement::from),
|
.map(WorkspaceRenderElement::from),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue