feat: add readme and clean up comments and code quality. Also update metadata so that it reads better in settings
This commit is contained in:
@@ -0,0 +1,47 @@
|
|||||||
|
# DDC Brightness Control
|
||||||
|
|
||||||
|
This project aims to be a simple and easy to use DDC brightness control plugin for Gnome
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Brightness control via panel
|
||||||
|
- Adjustable keybindings for brightness controls
|
||||||
|
- Active screen detection
|
||||||
|
- By default, keybinding is alt+shift+f1/f2 for down/up on the active display
|
||||||
|
- Display linking if you want to adjust all displays at once
|
||||||
|
|
||||||
|
## Planned Features?
|
||||||
|
|
||||||
|
- Would be nice to get this added to the system status menu at some point isntead of its own dot
|
||||||
|
- Support for direct i2c or better ddc controllers (not ddcutil)
|
||||||
|
- You tell me
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
(Examples use arch, but all packages should be available on other distros as well)
|
||||||
|
|
||||||
|
Be sure to have [ddcutil](https://www.ddcutil.com/) installed it is a hard requirement for now
|
||||||
|
|
||||||
|
Also, if installing from source install just which is the chosen command runner for this project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pacman -Syu ddcutil just
|
||||||
|
```
|
||||||
|
|
||||||
|
Add your user to the i2c group so it can use i2c without root and reboot/login+out
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo usermod -aG i2c $USER
|
||||||
|
reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
Now install the extension from version control
|
||||||
|
(until we get to the gnome extension store)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -38,5 +38,8 @@ live-debug:
|
|||||||
lint:
|
lint:
|
||||||
pnpm run lint
|
pnpm run lint
|
||||||
|
|
||||||
|
lint-fix:
|
||||||
|
pnpm run lint --fix
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
pnpm run clean
|
pnpm run clean
|
||||||
|
|||||||
+1
-4
@@ -1,12 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "ddc-brightness-control",
|
"name": "DDC Brightness Controller",
|
||||||
"description": "Control display brightness via DDC/CI using ddcutil. Bind keyboard shortcuts or use the panel menu to adjust monitor brightness.",
|
"description": "Control display brightness via DDC/CI using ddcutil. Bind keyboard shortcuts or use the panel menu to adjust monitor brightness.",
|
||||||
"uuid": "ddcbrightness@lucaso.io",
|
"uuid": "ddcbrightness@lucaso.io",
|
||||||
"settings-schema": "org.gnome.shell.extensions.ddcbrightness",
|
"settings-schema": "org.gnome.shell.extensions.ddcbrightness",
|
||||||
"shell-version": [
|
"shell-version": [
|
||||||
"47",
|
|
||||||
"48",
|
|
||||||
"49",
|
|
||||||
"50"
|
"50"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ export const SCHEMA_ID = 'org.gnome.shell.extensions.ddcbrightness';
|
|||||||
/** VCP feature code used when none is configured (10 = brightness). */
|
/** VCP feature code used when none is configured (10 = brightness). */
|
||||||
export const DEFAULT_VCP_CODE = '10';
|
export const DEFAULT_VCP_CODE = '10';
|
||||||
|
|
||||||
/**
|
|
||||||
* Scales the mandatory I2C delays ddcutil inserts around DDC/CI transactions.
|
|
||||||
* Lower = faster but less tolerant of flaky monitors. Tune per hardware.
|
|
||||||
*/
|
|
||||||
export const DDCUTIL_SLEEP_MULTIPLIER = '0.5';
|
export const DDCUTIL_SLEEP_MULTIPLIER = '0.5';
|
||||||
|
|
||||||
/** Prefix for all console logging from this extension. */
|
/** Prefix for all console logging from this extension. */
|
||||||
|
|||||||
+5
-18
@@ -1,10 +1,9 @@
|
|||||||
import Gio from 'gi://Gio';
|
import Gio from 'gi://Gio';
|
||||||
import St from 'gi://St';
|
import St from 'gi://St';
|
||||||
import * as Slider from 'resource:///org/gnome/shell/ui/slider.js';
|
import * as Slider from 'resource:///org/gnome/shell/ui/slider.js';
|
||||||
import { DEFAULT_VCP_CODE, LOG_PREFIX } from './constants.js';
|
import {DEFAULT_VCP_CODE, LOG_PREFIX} from './constants.js';
|
||||||
import * as Ddcutil from './ddcutil.js';
|
import * as Ddcutil from './ddcutil.js';
|
||||||
|
|
||||||
/** A detected display plus the UI refs and runtime state attached to it. */
|
|
||||||
export interface DisplayInfo {
|
export interface DisplayInfo {
|
||||||
bus: string;
|
bus: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -13,30 +12,18 @@ export interface DisplayInfo {
|
|||||||
currentValue: number;
|
currentValue: number;
|
||||||
slider: Slider.Slider | null;
|
slider: Slider.Slider | null;
|
||||||
valueLabel: St.Label | null;
|
valueLabel: St.Label | null;
|
||||||
// Reconciliation state for writes: `sentValue` is the value of the most
|
|
||||||
// recent write handed to ddcutil; `inFlight` is true while that write runs.
|
|
||||||
sentValue: number;
|
sentValue: number;
|
||||||
inFlight: boolean;
|
inFlight: boolean;
|
||||||
reading: boolean;
|
reading: boolean;
|
||||||
updatingFromCode: boolean;
|
updatingFromCode: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Owns the set of detected displays and all brightness operations on them
|
|
||||||
* (detection, monitor mapping, reads, and writes via ddcutil).
|
|
||||||
*
|
|
||||||
* Writes use a reconciliation model rather than debouncing: `currentValue` is
|
|
||||||
* the user's target and at most one write per display is ever in flight. When a
|
|
||||||
* write finishes, if the target has since moved we immediately send the latest
|
|
||||||
* value — so intermediate values are coalesced and we never queue stale writes.
|
|
||||||
*/
|
|
||||||
export class DisplayController {
|
export class DisplayController {
|
||||||
private _settings: Gio.Settings;
|
private _settings: Gio.Settings;
|
||||||
private _displays: DisplayInfo[] = [];
|
private _displays: DisplayInfo[] = [];
|
||||||
private _detectComplete = false;
|
private _detectComplete = false;
|
||||||
private _disposed = false;
|
private _disposed = false;
|
||||||
|
|
||||||
/** Invoked after detection finishes so the UI can rebuild itself. */
|
|
||||||
onDetectComplete: (() => void) | null = null;
|
onDetectComplete: (() => void) | null = null;
|
||||||
|
|
||||||
constructor(settings: Gio.Settings) {
|
constructor(settings: Gio.Settings) {
|
||||||
@@ -55,18 +42,15 @@ export class DisplayController {
|
|||||||
return this._settings.get_string('vcp-code') || DEFAULT_VCP_CODE;
|
return this._settings.get_string('vcp-code') || DEFAULT_VCP_CODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear all state back to the pre-detection condition. */
|
|
||||||
reset(): void {
|
reset(): void {
|
||||||
this._displays = [];
|
this._displays = [];
|
||||||
this._detectComplete = false;
|
this._detectComplete = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stop issuing further writes. Call before disposal. */
|
|
||||||
cleanup(): void {
|
cleanup(): void {
|
||||||
this._disposed = true;
|
this._disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Detect displays, map them to monitors, then read their brightness. */
|
|
||||||
detect(): void {
|
detect(): void {
|
||||||
Ddcutil.detectDisplays((parsed) => {
|
Ddcutil.detectDisplays((parsed) => {
|
||||||
this._displays = parsed.map((p) => ({
|
this._displays = parsed.map((p) => ({
|
||||||
@@ -117,7 +101,10 @@ export class DisplayController {
|
|||||||
return global.display.get_primary_monitor();
|
return global.display.get_primary_monitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The display to act on for global actions, honoring "link displays". */
|
/**
|
||||||
|
* The display to act on for global actions, honoring "link displays".
|
||||||
|
* This should grab the display that the active window is part of for adjusting when not linked
|
||||||
|
*/
|
||||||
getActiveDisplay(): DisplayInfo | null {
|
getActiveDisplay(): DisplayInfo | null {
|
||||||
if (this._settings.get_boolean('link-displays')) {
|
if (this._settings.get_boolean('link-displays')) {
|
||||||
return this._displays[0] ?? null;
|
return this._displays[0] ?? null;
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ export class BrightnessIndicator {
|
|||||||
this.rebuildMenu();
|
this.rebuildMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The underlying panel button, for adding to the status area. */
|
|
||||||
get button(): PanelMenu.Button {
|
get button(): PanelMenu.Button {
|
||||||
return this._button;
|
return this._button;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-7
@@ -3,16 +3,11 @@ import Meta from 'gi://Meta';
|
|||||||
import Shell from 'gi://Shell';
|
import Shell from 'gi://Shell';
|
||||||
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
|
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
|
||||||
|
|
||||||
/** Map of settings key -> callback to run when the shortcut fires. */
|
|
||||||
export type KeybindingActions = Record<string, () => void>;
|
export type KeybindingActions = Record<string, () => void>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the extension's keyboard shortcuts with the window manager and
|
|
||||||
* keeps them in sync as their settings change.
|
|
||||||
*/
|
|
||||||
export class KeybindingManager {
|
export class KeybindingManager {
|
||||||
private _settings: Gio.Settings;
|
private readonly _settings: Gio.Settings;
|
||||||
private _actions: KeybindingActions;
|
private readonly _actions: KeybindingActions;
|
||||||
private _bindings: Map<string, number> = new Map();
|
private _bindings: Map<string, number> = new Map();
|
||||||
|
|
||||||
constructor(settings: Gio.Settings, actions: KeybindingActions) {
|
constructor(settings: Gio.Settings, actions: KeybindingActions) {
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
/* DDC Brightness Control styling */
|
|
||||||
|
|
||||||
.ddc-brightness-slider-box {
|
.ddc-brightness-slider-box {
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
spacing: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ddc-brightness-value-label {
|
.ddc-brightness-value-label {
|
||||||
@@ -13,7 +10,6 @@
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom slider */
|
|
||||||
.slider {
|
.slider {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
|||||||
Reference in New Issue
Block a user