Wl-gammarelay - Wayland utility for changing color temperature using hotkeys

wl-gammarelay

This utility was developed from gammastep, a fork of redshift as well as examples from wlroots.

It allows using keybindings to dynamically change the color temperature and software brightness.

This used to be possible using redshift using the -P -O flags, but since wayland requires the client to keep running, I developed this tool that spins up a daemon and can be controlled via unix domain socket.

The first invocation to wl-gammarelay will spin up a daemon. This can be disabled using the --no-daemon/-D flag, but if the daemon isn't already running in the background the requests will fail. After the daemon starts up, the temperature and brightess will be set to the desired levels.

All other invocations act as clients only send requests via unix domain socket. The path of the socket for both the daemon and the client can be controlled using the --sock/-s flag.

The --temperature/-t flag accepts an integer in the range of [1000, 10000], when set to an absolute values. Relative changes can be specified by adding a + or - prefix before the integer.

The --brigtness/-b flag behaves similarly to temperature, only its range is [0, 1.0] and it accepts floats.

The --subscribe/-S flag can be used to subscribe to certain changes. Currently only color is supported.

Below are some examples on how this utility can be used to change the color temperature via keybindings in swaywm:

bindsym $mod+Control+Minus      exec wl-gammarelay -t -100
bindsym $mod+Control+Equal      exec wl-gammarelay -t +100
bindsym $mod+Control+0          exec killall wl-gammarelay
bindsym $mod+Control+Underscore exec wl-gammarelay -b -0.02
bindsym $mod+Control+Plus       exec wl-gammarelay -b +0.02

Sample configuration for waybar:

"modules-right": ["custom/wl-gammarelay"],
"custom/wl-gammarelay": {
    "format": "{} ",
    "exec": "wl-gammarelay --subscribe color | jq --unbuffered --compact-output -r -c '.updates[] | select(.key == \"color\") | .color | .temperature + \" \" + .brightness'"
}

Tested on Arch Linux and Ubuntu 20.04 LTS using swaywm.

Installation

make
sudo make install

To install to /usr/bin set the PREFIX variable when running make:

sudo make install PREFIX=/usr

Arch Linux

This package is also on AUR: https://aur.archlinux.org/packages/wl-gammarelay/

Unix Domain Socket Protocol

The default path of the unix socket will be set to $XDG_RUNTIME_DIR/wl-gammarelay.sock.

The daemon expects a JSON message terminated by a newline \n character. Multiple simultaneous connections to the service are possible, but the daemon will handle each request one by one.

The daemon currently only only writes the temperature updates to the connection that made the request, but this might change in the future. For example, we might want to enable sending updates to all other connections so that applications that are interested can update the UI.

The types folder contains all the type definitions used by the protocol.

The clients send a types.Request and the server will respones with a types.Response.

The -v flag can be used to enable logging of requests and responses in both the daemon and the client.

Some examples:

$ wl-gammarelay
Daemon started

$ wl-gammarelay --no-daemon -v -t 4000 -b 0.8
{"color":{"temperature":"4000","brightness":"0.8"}}
{"color":{"temperature":"4000","brightness":"0.8"}}

$ wl-gammarelay --no-daemon -v -t 4000
{"color":{"temperature":"4000"}}
{"color":{"temperature":"4000","brightness":"0.8"}}

$ wl-gammarelay --no-daemon -v -t +100
{"color":{"temperature":"+100"}}
{"color":{"temperature":"4100","brightness":"0.8"}}

$ wl-gammarelay --no-daemon -v -t -100
{"color":{"temperature":"-100"}}
{"color":{"temperature":"4000","brightness":"0.8"}}

$ wl-gammarelay --no-daemon --subscribe color
{"updates":[{"key":"color","color":{"temperature":"4500","brightness":"1.00"}}],"subscribed":["color"]}
{"updates":[{"key":"color","color":{"temperature":"4400","brightness":"1.00"}}]}
{"updates":[{"key":"color","color":{"temperature":"4300","brightness":"1.00"}}]}
{"updates":[{"key":"color","color":{"temperature":"4200","brightness":"1.00"}}]}
{"updates":[{"key":"color","color":{"temperature":"4100","brightness":"1.00"}}]}
{"updates":[{"key":"color","color":{"temperature":"4000","brightness":"1.00"}}]}

Dependencies

  • go 1.17
  • wayland (libwayland-dev)
Owner
Jerko Steiner
Coder, guitarist, traveler, photographer. Software architect, creator of Peer Calls & founder of rondomoon
Jerko Steiner
Comments
  • Check for added or removed outputs before setting temperature

    Check for added or removed outputs before setting temperature

    Hey @MaxVerevkin,

    I think I have something working. The trick is to call wl_display_roundtrip to execute all pending events, then all the callbacks will be executed synchronously.

    The current implementation will check for any new outputs on every call to wl_gammarelay_color_set and initialize the gamma for those.

    Ideally this would happen automatically, but that requires some more careful considerations because we'd have to access the state from different threads and that could cause race conditions, so I'm not sure if I have time to implement it at this point.

    Would be great if you could test and see if this works for you!

    Cheers!

    Closes #3.

  • Expose the UNIX socket as public API

    Expose the UNIX socket as public API

    First of all, thanks for this project! Finally there is a tool to change the temperature without flickering under wayland.

    The README mentions that daemon and clients communicate via unix socket. It would be really nice if the API to communicate with this socket was public and documented, in which case status bars like i3status-rust could directly communicate with the daemon.

  • Initialize display after connecting to DBus

    Initialize display after connecting to DBus

    This fixes a bug where the color temperature would be reset and the service would fail to start if there was already another service registered as a primary owner of the rs.wl-gammarelay service.

    Closes #6

  • Use dbus instead of internal service

    Use dbus instead of internal service

    The same interface is implemented as wl-gammarelay-rs.

    Usage examples:

    busctl --user -- call rs.wl-gammarelay / rs.wl.gammarelay UpdateTemperature n -500
    busctl --user -- call rs.wl-gammarelay / rs.wl.gammarelay UpdateTemperature n +500
    
    busctl --user -- call rs.wl-gammarelay / rs.wl.gammarelay UpdateBrightness d -0.2
    busctl --user -- call rs.wl-gammarelay / rs.wl.gammarelay UpdateBrightness d +0.2
    
    busctl --user -- set-property rs.wl-gammarelay / rs.wl.gammarelay Brightness d 0.5
    busctl --user -- set-property rs.wl-gammarelay / rs.wl.gammarelay Brightness d 1
    
    busctl --user -- set-property rs.wl-gammarelay / rs.wl.gammarelay Temperature q 4000
    busctl --user -- set-property rs.wl-gammarelay / rs.wl.gammarelay Temperature q 6500
    

    Introspection:

    $ busctl --user introspect rs.wl-gammarelay / rs.wl.gammarelay
    NAME               TYPE      SIGNATURE RESULT/VALUE FLAGS
    .UpdateBrightness  method    d         -            -
    .UpdateTemperature method    n         -            -
    .Brightness        property  d         1            emits-change writable
    .Temperature       property  q         6500         emits-change writable
    

    Closes #3

  • Watch for new outputs

    Watch for new outputs

    The daemon only sets the color for outputs that were presented on the startup: if I start the daemon, then connect a new display and then try to modify the color, newly connected display is unaffected.

  • Handle the case when the instance is already running

    Handle the case when the instance is already running

    Current behavior

    The second instance panics, while the running instance is no longer able to control the gamma table.

    Expected behavior

    The second instance exits. I've implemented this in wl-gammarelay-rs by:

    • Starting the dbus server before messing with wayland
    • Catching the "dbus name already taken" error
Go package to generate and manage color palettes & schemes 🎨
Go package to generate and manage color palettes & schemes 🎨

Go package to generate and manage color palettes & schemes

Dec 29, 2022
Color generator with golang
Color generator with golang

color-generator How to use this repo <img src="https://color-pallete-gen.herokuapp.com/hexCode" /> Like this: Getting Started Copy sample.env to .env

Oct 22, 2021
Simple library to handle ANSI functions and parsing of color formatting strings

Emerald A basic color library for use in my Go projects, built on top of mgutz/ansi. Package ansi is a small, fast library to create ANSI colored stri

Oct 28, 2022
Color lets you use colorized outputs in terms of ANSI Escape Codes in Go (Golang)
Color lets you use colorized outputs in terms of ANSI Escape Codes in Go (Golang)

Color lets you use colorized outputs in terms of ANSI Escape Codes in Go (Golang). It has support for Windows too! The API can be used in several ways, pick one that suits you.

Feb 5, 2022
A color manipulation and conversion library for Go. 🌈 ✨

Khroma Khroma is a color manipulation and conversion library for Go. ✨ ?? Example package main import ( "log" "github.com/qbee-org/khroma" ) func

May 30, 2022
Easy to use open source hardware to drive WS2811 LEDs with high-quality color

STOP DOING FADECANDY LEDs were not supposed to be given data pins YEARS of "temporal dithering" but no real-world use found for having more than three

Dec 29, 2022
Use is a go utility library using go1.18 generics

use use is a go utility library using go1.18 generics created by halpdesk 2022-01-22 use/slice Map updates a slice by applying a function to all membe

Jan 22, 2022
A super simple Lodash like utility library with essential functions that empowers the development in Go
A super simple Lodash like utility library with essential functions that empowers the development in Go

A simple Utility library for Go Go does not provide many essential built in functions when it comes to the data structure such as slice and map. This

Jan 4, 2023
Robust & Easy to use struct mapper and utility methods for Go

go-model Robust & Easy to use model mapper and utility methods for Go struct. Typical methods increase productivity and make Go development more fun ?

Dec 30, 2022
gopkg is a universal utility collection for Go, it complements offerings such as Boost, Better std, Cloud tools.

gopkg is a universal utility collection for Go, it complements offerings such as Boost, Better std, Cloud tools. Table of Contents Introduction

Jan 5, 2023
Utility to add network config file in apk

Utility to add network config file in apk. Which bypass the proxy intercept restriction for user installed burpsuit CA certificate.

Aug 19, 2022
Small utility to allow simpler, quicker testing of parsing files in crowdsec

cs_parser_test Small utility to allow simpler, quicker testing of parsing files in crowdsec Usage $ sudo cs_parser_test -t syslog /var/log/mail.log N

Jul 13, 2021
sigbypass4xx is a utility to automate well-know techniques used to bypass access control restrictions.

sigbypass4xx sigbypass4xx is a utility to automate well-know techniques used to bypass access control restrictions. Resources Usage Installation From

Nov 9, 2022
Nintendo 64 ROM utility written in Go.
Nintendo 64 ROM utility written in Go.

Nintendo 64 ROM utility written in Go. Commands ls - List information about all ROMs in a directory info - Show information about a single ROM convert

Dec 7, 2022
Utility functions for work with the Kubernetes Go-Client

go-k8s-utils This repository contains utils for the work with Kubernetes, in specific with the go-client library. Testing This package contains utils

Dec 14, 2022
Scylla-octopus is a backup and maintenance utility for scylladb.

scylla-octopus: a scylladb backup utility Scylla-octopus is a backup and maintenance utility for scylladb. It attempts to reproduce some functionality

Oct 19, 2022
A Go utility to convert Go example tests into jupyter notebooks.

go2colab Scientists (my main project's users) love jupyter notebook tutorials pkg.dev.go's runnable playground doesn't support file IO but I love exam

Jul 10, 2022
Simple utility to get/set the PWM duty cycle and to measure the RPM for a fan connected to the 4-pin header on the CM4IO.

cm4iofan Simple utility to get/set the PWM duty cycle and to measure the RPM for a fan connected to the 4-pin header on the CM4IO. Requirements Enable

Mar 31, 2022
Envoy utility to process envoy config for fast development and debugging.

envoyconf-tools Envoy is a proxy, really awesome and we are devs who often use it, face errors and struggle to debug it, when envoy config's source is

Oct 31, 2021