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
|
- Menubar with dropdown and buttons
|
||||||
- Button grid
|
- Button grid
|
||||||
- Volume slider using PulseAudio
|
- Volume slider using PulseAudio
|
||||||
|
- Backlight slider
|
||||||
|
|
||||||
## Planned Features
|
## Planned Features
|
||||||
|
|
||||||
|
@@ -206,6 +206,7 @@ config file to be able to detect config errors
|
|||||||
multiple of same widget: ++
|
multiple of same widget: ++
|
||||||
Append a # with any value to the end of the widget name. ++
|
Append a # with any value to the end of the widget name. ++
|
||||||
Example: "title#TheMainTitle" ++
|
Example: "title#TheMainTitle" ++
|
||||||
|
To address this widget specifically in the css file use the css class .TheMainTitle ++
|
||||||
example:
|
example:
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
@@ -223,6 +224,7 @@ config file to be able to detect config errors
|
|||||||
multiple of same widget: ++
|
multiple of same widget: ++
|
||||||
Append a # with any value to the end of the widget name. ++
|
Append a # with any value to the end of the widget name. ++
|
||||||
Example: "title#TheMainTitle" ++
|
Example: "title#TheMainTitle" ++
|
||||||
|
To address this widget specifically in the css file use the css class .TheMainTitle ++
|
||||||
Widgets to customize: ++
|
Widgets to customize: ++
|
||||||
*title*++
|
*title*++
|
||||||
type: object ++
|
type: object ++
|
||||||
@@ -380,6 +382,32 @@ config file to be able to detect config errors
|
|||||||
default: "Volume" ++
|
default: "Volume" ++
|
||||||
description: Text displayed in front of the volume slider ++
|
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:
|
example:
|
||||||
```
|
```
|
||||||
|
@@ -295,6 +295,9 @@
|
|||||||
},
|
},
|
||||||
"^volume(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
|
"^volume(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
|
||||||
"$ref": "#/widgets/volume"
|
"$ref": "#/widgets/volume"
|
||||||
|
},
|
||||||
|
"^backlight(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
|
||||||
|
"$ref": "#/widgets/backlight"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -450,6 +453,34 @@
|
|||||||
"default": "Volume"
|
"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":
|
case "volume":
|
||||||
widget = new Volume (suffix, swaync_daemon, noti_daemon);
|
widget = new Volume (suffix, swaync_daemon, noti_daemon);
|
||||||
break;
|
break;
|
||||||
|
case "backlight":
|
||||||
|
widget = new Backlight (suffix, swaync_daemon, noti_daemon);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
warning ("Could not find widget: \"%s\"!", key);
|
warning ("Could not find widget: \"%s\"!", key);
|
||||||
return null;
|
return null;
|
||||||
|
@@ -44,6 +44,9 @@ widget_sources = [
|
|||||||
'controlCenter/widgets/volume/volume.vala',
|
'controlCenter/widgets/volume/volume.vala',
|
||||||
'controlCenter/widgets/volume/pulseDaemon.vala',
|
'controlCenter/widgets/volume/pulseDaemon.vala',
|
||||||
'controlCenter/widgets/volume/pulseDevice.vala',
|
'controlCenter/widgets/volume/pulseDevice.vala',
|
||||||
|
# Widget: Backlight Slider
|
||||||
|
'controlCenter/widgets/backlight/backlight.vala',
|
||||||
|
'controlCenter/widgets/backlight/backlightUtil.vala',
|
||||||
]
|
]
|
||||||
|
|
||||||
app_sources = [
|
app_sources = [
|
||||||
|
@@ -290,3 +290,11 @@
|
|||||||
margin: 8px;
|
margin: 8px;
|
||||||
border-radius: 12px;
|
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