Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions man/dim.1.scd
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ detected after its timeout, swaylock will be run, locking the screen.
Set the *alpha* value of the overlay, 0.0 being transparent and 1.0 being
solid black. When solid, cursor will be hidden. Default is 0.5.

\-f, --fade <FADE_DURATION>
Duration of fade-in animation in seconds. Must be at least 0, and at most
equal to the duration option above. Default is 0.5.

\-p, --passthrough
Make dim ignore input, passing it to the surfaces behind it, making dim act as
a way to lower your brightness artificially. You probably want to set the
Expand Down Expand Up @@ -69,5 +73,6 @@ options are alpha, duration and passthrough as seen above, example config:
# i am a comment!
duration = 30
alpha = 0.5
fade = 0.5
passthrough = false
```
17 changes: 10 additions & 7 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,18 @@ impl BufferManager {
.create_buffer(1, 1, 4, wl_shm::Format::Argb8888)
.expect("Failed to get buffer from slot pool!");

// ARGB is actually backwards being little-endian, so we set BGR to 0 for black so
(0..3).for_each(|i| {
canvas[i] = 0;
});
// then, we set pre-multiplied alpha
canvas[3] = (u8::MAX as f32 * alpha) as u8;

BufferManager::paint(canvas, alpha);
BufferType::Shared(buffer)
}
}
}

pub fn paint(canvas: &mut [u8], alpha: f32) {
// RGB
(0..3).for_each(|i| {
canvas[i] = 0;
});
// ...A
canvas[3] = (u8::MAX as f32 * alpha) as u8;
}
}
51 changes: 39 additions & 12 deletions src/dim.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::{collections::HashMap, time::Instant};

use log::{debug, error, warn};
use smithay_client_toolkit::{
Expand Down Expand Up @@ -59,6 +59,9 @@ pub struct DimData {

alpha: f32,
passthrough: bool,
start_time: Instant,
fade_sec: f32,
fade_done: bool,
surfaces: HashMap<WlOutput, DimSurface>,

keyboard: Option<wl_keyboard::WlKeyboard>,
Expand Down Expand Up @@ -99,6 +102,9 @@ impl DimData {

alpha: opts.alpha(),
passthrough: opts.passthrough,
start_time: Instant::now(),
fade_sec: opts.fade(),
fade_done: false,
surfaces: HashMap::new(),

keyboard: None,
Expand All @@ -117,6 +123,7 @@ impl DimData {
&self,
qh: &QueueHandle<Self>,
buffer: BufferType,
back_buffer: BufferType,
output: &WlOutput,
) -> DimSurface {
let layer = self.layer_shell.create_layer_surface(
Expand Down Expand Up @@ -155,7 +162,7 @@ impl DimData {
.expect("wp_viewporter failed")
.get_viewport(layer.wl_surface(), qh, ());

DimSurface::new(qh, buffer, viewport, layer)
DimSurface::new(qh, buffer, back_buffer, viewport, layer)
}
}

Expand Down Expand Up @@ -187,12 +194,8 @@ impl LayerShellHandler for DimData {
return;
};

if view.first_configure() {
let (width, height) = configure.new_size;
view.set_size(width, height);
view.viewport_mut().set_destination(width as _, height as _);
view.set_first_configure(false);
}
let (width, height) = configure.new_size;
view.set_size(width, height);

view.draw(qh);
}
Expand Down Expand Up @@ -225,6 +228,28 @@ impl CompositorHandler for DimData {
_time: u32,
) {
for view in self.surfaces.values_mut() {
let elapsed_sec = self.start_time.elapsed().as_millis() as f32 / 1000.;

if !self.fade_done {
let alpha = (self.alpha * (elapsed_sec / self.fade_sec)).clamp(0., self.alpha);
match &mut self.buffer_mgr {
BufferManager::SinglePixel(..) => {
view.set_back_buffer(self.buffer_mgr.get_buffer(qh, alpha));
}
BufferManager::Shm(_, pool) => {
if let BufferType::Shared(buffer) = view.back_buffer_mut() {
let canvas = buffer.canvas(pool).expect("Canvas is not drawable.");
BufferManager::paint(canvas, alpha);
}
}
}

if elapsed_sec > self.fade_sec {
self.fade_done = true;
debug!("Fade done!")
}
}

view.draw(qh);
}
}
Expand Down Expand Up @@ -259,8 +284,9 @@ impl OutputHandler for DimData {
qh: &QueueHandle<Self>,
output: smithay_client_toolkit::reexports::client::protocol::wl_output::WlOutput,
) {
let buffer = self.buffer_mgr.get_buffer(qh, self.alpha);
let view = self.new_surface(qh, buffer, &output);
let buffer = self.buffer_mgr.get_buffer(qh, 0.);
let back_buffer = self.buffer_mgr.get_buffer(qh, 0.);
let view = self.new_surface(qh, buffer, back_buffer, &output);
self.surfaces.insert(output, view);
}

Expand All @@ -270,8 +296,9 @@ impl OutputHandler for DimData {
qh: &QueueHandle<Self>,
output: smithay_client_toolkit::reexports::client::protocol::wl_output::WlOutput,
) {
let buffer = self.buffer_mgr.get_buffer(qh, self.alpha);
let new_view = self.new_surface(qh, buffer, &output);
let buffer = self.buffer_mgr.get_buffer(qh, 0.);
let back_buffer = self.buffer_mgr.get_buffer(qh, 0.);
let new_view = self.new_surface(qh, buffer, back_buffer, &output);

if let Some(view) = self.surfaces.get_mut(&output) {
*view = new_view;
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub use surface::DimSurface;
pub mod consts {
pub const DEFAULT_DURATION: u64 = 30;
pub const DEFAULT_ALPHA: f32 = 0.5;
pub const DEFAULT_FADE: f32 = 0.5;

pub const CONFIG_FILENAME: &str = "config.toml";

Expand Down
23 changes: 22 additions & 1 deletion src/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use clap::{CommandFactory, Parser, ValueEnum};
use clap_complete::{generate_to, Shell};
use serde::Deserialize;

use crate::{consts::DEFAULT_ALPHA, consts::DEFAULT_DURATION};
use crate::consts::{DEFAULT_ALPHA, DEFAULT_DURATION, DEFAULT_FADE};

#[derive(Debug, Deserialize, Parser)]
#[command(author, version, about)]
Expand All @@ -24,6 +24,14 @@ pub struct DimOpts {
)]
alpha: Option<f32>,

#[arg(
short,
long,
help = format!("Fade-in animation duration in seconds. [default: {DEFAULT_FADE}]")
)]
#[serde(default)]
pub fade: Option<f32>,

#[arg(
short,
long,
Expand Down Expand Up @@ -73,6 +81,14 @@ impl DimOpts {
}
}

if let Some(fade) = self.fade {
if !(0.0..=self.duration() as f32).contains(&fade) {
return Err(anyhow!(
"Fade must be at least 0 and as much as the duration option."
));
}
}

Ok(())
}

Expand All @@ -85,4 +101,9 @@ impl DimOpts {
pub fn duration(&self) -> u64 {
self.duration.unwrap_or(DEFAULT_DURATION)
}

/// Get user desired fade or the default value.
pub fn fade(&self) -> f32 {
self.fade.unwrap_or(DEFAULT_FADE)
}
}
32 changes: 19 additions & 13 deletions src/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ use smithay_client_toolkit::{
use crate::{buffer::BufferType, consts::INIT_SIZE, DimData};

pub struct DimSurface {
first_configure: bool,
damaged: bool,

width: u32,
height: u32,

buffer: BufferType,
back_buffer: BufferType,

viewport: WpViewport,
layer: LayerSurface,
}
Expand All @@ -21,17 +22,18 @@ impl DimSurface {
pub fn new(
_qh: &QueueHandle<DimData>,
buffer: BufferType,
back_buffer: BufferType,
viewport: WpViewport,
layer: LayerSurface,
) -> Self {
Self {
first_configure: true,
damaged: true,

width: INIT_SIZE,
height: INIT_SIZE,

buffer,
back_buffer,
viewport,
layer,
}
Expand All @@ -42,13 +44,17 @@ impl DimSurface {
return;
}

let wl_buffer = match &self.buffer {
let wl_buffer = match &self.back_buffer {
BufferType::Wl(wl_buffer) => wl_buffer,
BufferType::Shared(buffer) => buffer.wl_buffer(),
};

self.layer.wl_surface().attach(Some(wl_buffer), 0, 0);
self.layer
.wl_surface()
.damage(0, 0, self.width as _, self.height as _);
self.damaged = false;
std::mem::swap(&mut self.buffer, &mut self.back_buffer);

// request next frame
self.layer
Expand All @@ -58,25 +64,25 @@ impl DimSurface {
self.layer.commit();
}

pub fn first_configure(&self) -> bool {
self.first_configure
}

pub fn layer(&self) -> &LayerSurface {
&self.layer
}

pub fn set_first_configure(&mut self, value: bool) {
self.first_configure = value;
}

pub fn set_size(&mut self, width: u32, height: u32) {
self.width = width;
self.height = height;
self.viewport
.set_destination(self.width as _, self.height as _);
}

pub fn set_back_buffer(&mut self, back_buffer: BufferType) {
self.back_buffer = back_buffer;
self.damaged = true;
}

pub fn viewport_mut(&mut self) -> &mut WpViewport {
&mut self.viewport
pub fn back_buffer_mut(&mut self) -> &mut BufferType {
self.damaged = true; // we're most likely changing something.
&mut self.back_buffer
}
}

Expand Down
Loading