Add Brightness slider widget (#211)

This commit is contained in:
Jannis
2023-02-22 18:16:19 +01:00
committed by GitHub
parent befd6267b4
commit c7644dbf91
8 changed files with 279 additions and 2 deletions

View File

@@ -53,6 +53,7 @@ These widgets can be customized, added, removed and even reordered
- Menubar with dropdown and buttons
- Button grid
- Volume slider using PulseAudio
- Backlight slider
## Planned Features

View File

@@ -206,6 +206,7 @@ config file to be able to detect config errors
multiple of same widget: ++
Append a # with any value to the end of the widget name. ++
Example: "title#TheMainTitle" ++
To address this widget specifically in the css file use the css class .TheMainTitle ++
example:
```
{
@@ -223,6 +224,7 @@ config file to be able to detect config errors
multiple of same widget: ++
Append a # with any value to the end of the widget name. ++
Example: "title#TheMainTitle" ++
To address this widget specifically in the css file use the css class .TheMainTitle ++
Widgets to customize: ++
*title*++
type: object ++
@@ -379,7 +381,33 @@ config file to be able to detect config errors
optional: true ++
default: "Volume" ++
description: Text displayed in front of the volume slider ++
description: Slider to control pulse volume ++
description: Slider to control pulse volume ++
*backlight*++
type: object ++
css class: widget-backlight ++
properties: ++
label: ++
type: string ++
optional: true ++
default: "Brightness" ++
description: Text displayed in front of the backlight slider ++
device: ++
type: string ++
optional: true ++
default: "intel_backlight" ++
description: Device in `/sys/class/backlight` or `/sys/class/leds` ++
subsystem: ++
type: string ++
optional: true ++
default: "backlight" ++
description: Kernel subsystem for brightness control ++
enum: ["backlight", "leds"] ++
min: ++
type: integer ++
optional: true ++
default: 0 ++
description: Lowest possible value for brightness ++
description: Slider to control screen brightness ++
example:
```

View File

@@ -295,6 +295,9 @@
},
"^volume(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
"$ref": "#/widgets/volume"
},
"^backlight(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
"$ref": "#/widgets/backlight"
}
}
}
@@ -449,7 +452,35 @@
"description": "Text displayed in front of the volume slider",
"default": "Volume"
}
}
}
},
"backlight": {
"type": "object",
"description": "Slider to control monitor brightness",
"additionalProperties": false,
"properties": {
"label": {
"type": "string",
"description": "Text displayed in front of the backlight slider",
"default": "Brightness"
},
"device": {
"type": "string",
"description": "Name of monitor (find possible devices using `ls /sys/class/backlight` or `ls /sys/class/leds`)",
"default": "intel_backlight"
},
"subsystem": {
"type": "string",
"description": "Kernel subsystem for brightness control",
"default": "backlight",
"enum": ["backlight", "leds"]
},
"min": {
"type": "integer",
"default": 0,
"description": "Lowest possible value for brightness"
}
}
}
}
}

View File

@@ -0,0 +1,73 @@
using GLib;
namespace SwayNotificationCenter.Widgets {
public class Backlight : BaseWidget {
public override string widget_name {
get {
return "backlight";
}
}
BacklightUtil client;
Gtk.Label label_widget = new Gtk.Label (null);
Gtk.Scale slider = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL, 0, 100, 1);
public Backlight (string suffix, SwayncDaemon swaync_daemon, NotiDaemon noti_daemon) {
base (suffix, swaync_daemon, noti_daemon);
Json.Object ? config = get_config (this);
if (config != null) {
string ? label = get_prop<string> (config, "label");
label_widget.set_label (label ?? "Brightness");
string device = (get_prop<string> (config, "device") ?? "intel_backlight");
string subsystem = (get_prop<string> (config, "subsystem") ?? "backlight");
int min = int.max (0, get_prop<int> (config, "min"));
switch (subsystem) {
default:
case "backlight":
if (subsystem != "backlight")
info ("Invalid subsystem %s for device %s. " +
"Use 'backlight' or 'leds'. Using default: 'backlight'",
subsystem, device);
client = new BacklightUtil ("backlight", device);
slider.set_range (min, 100);
break;
case "leds":
client = new BacklightUtil ("leds", device);
slider.set_range (min, this.client.get_max_value ());
break;
}
}
this.client.brightness_change.connect ((percent) => {
if (percent < 0) { // invalid device path
hide ();
} else {
slider.set_value (percent);
}
});
slider.set_draw_value (false);
slider.set_round_digits (0);
slider.value_changed.connect (() => {
this.client.set_brightness ((float) slider.get_value ());
slider.tooltip_text = ((int) slider.get_value ()).to_string ();
});
add (label_widget);
pack_start (slider, true, true, 0);
show_all ();
}
public override void on_cc_visibility_change (bool val) {
if (val) {
this.client.start ();
} else {
this.client.close ();
}
}
}
}

View File

@@ -0,0 +1,130 @@
namespace SwayNotificationCenter.Widgets {
class BacklightUtil {
[DBus (name = "org.freedesktop.login1.Session")]
interface Login1 : Object {
public abstract void set_brightness (string subsystem,
string name, uint32 brightness) throws GLib.Error;
}
string path_current;
string path_max;
File fd;
FileMonitor monitor = null;
int max;
Login1 login1;
string device;
string subsystem;
public signal void brightness_change (int percent);
public BacklightUtil (string s, string d) {
this.subsystem = s;
this.device = d;
path_current = Path.build_path (Path.DIR_SEPARATOR_S,
"/sys", "class", subsystem, device, "brightness");
path_max = Path.build_path (Path.DIR_SEPARATOR_S,
"/sys", "class", subsystem, device, "max_brightness");
fd = File.new_for_path (path_current);
if (fd.query_exists ()) {
set_max_value ();
try {
monitor = fd.monitor (FileMonitorFlags.NONE, null);
} catch (Error e) {
error ("Error %s\n", e.message);
}
} else {
this.brightness_change (-1);
warning ("Could not find device %s\n", path_current);
close ();
}
try {
// setup DBus for setting brightness
login1 = Bus.get_proxy_sync (BusType.SYSTEM,
"org.freedesktop.login1", "/org/freedesktop/login1/session/auto");
} catch (Error e) {
error ("Error %s\n", e.message);
}
}
public void start () {
if (fd.query_exists ()) {
// get changes made while controlCenter not shown
get_brightness ();
connect_monitor ();
} else {
this.brightness_change (-1);
warning ("Could not find device %s\n", path_current);
close ();
}
}
private void connect_monitor () {
if (monitor != null) {
// connect monitor to monitor changes
monitor.changed.connect ((src, dest, event) => {
get_brightness ();
});
}
}
public void close () {
if (monitor != null) monitor.cancel ();
}
public void set_brightness (float percent) {
this.close ();
try {
if (subsystem == "backlight") {
int actual = calc_actual (percent);
login1.set_brightness (subsystem, device, actual);
} else {
login1.set_brightness (subsystem, device, (uint32) percent);
}
} catch (Error e) {
error ("Error %s\n", e.message);
}
connect_monitor ();
}
// get current brightness and emit signal
private void get_brightness () {
try {
var dis = new DataInputStream (fd.read (null));
string data = dis.read_line (null);
int val = calc_percent (int.parse (data));
this.brightness_change (val);
} catch (Error e) {
error ("Error %s\n", e.message);
}
}
private void set_max_value () {
try {
File fd_max = File.new_for_path (path_max);
DataInputStream dis_max = new DataInputStream (fd_max.read (null));
string data = dis_max.read_line (null);
max = int.parse (data);
} catch (Error e) {
error ("Error %s\n", e.message);
}
}
private int calc_percent (int val) {
return val * 100 / max;
}
private int calc_actual (float val) {
return (int) val * max / 100;
}
public int get_max_value () {
return this.max;
}
}
}

View File

@@ -29,6 +29,9 @@ namespace SwayNotificationCenter.Widgets {
case "volume":
widget = new Volume (suffix, swaync_daemon, noti_daemon);
break;
case "backlight":
widget = new Backlight (suffix, swaync_daemon, noti_daemon);
break;
default:
warning ("Could not find widget: \"%s\"!", key);
return null;

View File

@@ -44,6 +44,9 @@ widget_sources = [
'controlCenter/widgets/volume/volume.vala',
'controlCenter/widgets/volume/pulseDaemon.vala',
'controlCenter/widgets/volume/pulseDevice.vala',
# Widget: Backlight Slider
'controlCenter/widgets/backlight/backlight.vala',
'controlCenter/widgets/backlight/backlightUtil.vala',
]
app_sources = [

View File

@@ -290,3 +290,11 @@
margin: 8px;
border-radius: 12px;
}
/* Backlight widget */
.widget-backlight {
background-color: @noti-bg;
padding: 8px;
margin: 8px;
border-radius: 12px;
}