Add Brightness slider widget (#211)
This commit is contained in:
@@ -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
|
||||
|
||||
|
@@ -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:
|
||||
```
|
||||
|
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
73
src/controlCenter/widgets/backlight/backlight.vala
Normal file
73
src/controlCenter/widgets/backlight/backlight.vala
Normal 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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
130
src/controlCenter/widgets/backlight/backlightUtil.vala
Normal file
130
src/controlCenter/widgets/backlight/backlightUtil.vala
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
|
@@ -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 = [
|
||||
|
@@ -290,3 +290,11 @@
|
||||
margin: 8px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* Backlight widget */
|
||||
.widget-backlight {
|
||||
background-color: @noti-bg;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
Reference in New Issue
Block a user