Saturday, December 7, 2024

Controll Hue On Linux Using Python

 Redshift Wasn't working for me on linux mint because geoclue couldn't find location. I added the coordinates to the config and it still didn't work in redshift-gtk. I ran the CLI version with the location as arguments and it worked but the shift was pretty weak. Looked into alternatives, xrandr can adjust the hue using gamma. Heres a python script that uses tkinter to create a GUI to manipulate the values. I added brightness and limited it to 0.10 min (FOR SAFETY).




import tkinter as tk
import subprocess

# Function to update the gamma values using xrandr
def update_display(brightness, r, g, b):
    # Get the output name (e.g., HDMI-1, eDP-1)
    output = subprocess.getoutput("xrandr | grep ' connected' | cut -d' ' -f1")
    
    # Construct the xrandr command to change brightness and gamma for red, green, and blue channels
    command = f"xrandr --output {output} --brightness {brightness} --gamma {r}:{g}:{b}"
    
    # Run the command using subprocess
    subprocess.run(command, shell=True)

# Function to handle the slider change and update the display
def on_slider_change(val):
    # Get the values from the sliders (brightness, r, g, b)
    brightness = slider_brightness.get()
    r = float(slider_r.get())
    g = float(slider_g.get())
    b = float(slider_b.get())
    
    # Update the display settings based on the slider values
    update_display(brightness, r, g, b)

# Function to reset the gamma and brightness back to default
def reset_display():
    # Get the output name
    output = subprocess.getoutput("xrandr | grep ' connected' | cut -d' ' -f1")
    
    # Reset to default gamma (1.0:1.0:1.0) and brightness (1.0)
    command = f"xrandr --output {output} --brightness 1.0 --gamma 1.0:1.0:1.0"
    subprocess.run(command, shell=True)

# Create the main Tkinter window
root = tk.Tk()
root.title("Gamma and Brightness Control")

# Set up slider for Brightness (range 0.1 to 1.0)
slider_brightness = tk.Scale(root, from_=0.1, to_=1.0, orient="horizontal", label="Brightness", resolution=0.01, command=on_slider_change)
slider_brightness.set(1.0)  # Set initial value to 1 (default brightness)
slider_brightness.pack()

# Set up sliders for Red, Green, and Blue
slider_r = tk.Scale(root, from_=0.5, to_=2.0, orient="horizontal", label="Red", resolution=0.01, command=on_slider_change)
slider_r.set(1.0)  # Set initial value to 1 (default gamma)
slider_r.pack()

slider_g = tk.Scale(root, from_=0.5, to_=2.0, orient="horizontal", label="Green", resolution=0.01, command=on_slider_change)
slider_g.set(1.0)
slider_g.pack()

slider_b = tk.Scale(root, from_=0.5, to_=2.0, orient="horizontal", label="Blue", resolution=0.01, command=on_slider_change)
slider_b.set(1.0)
slider_b.pack()

# When the Tkinter window is closed, reset gamma and brightness to default
root.protocol("WM_DELETE_WINDOW", lambda: (reset_display(), root.destroy()))

# Start the Tkinter event loop
root.mainloop()

This one is a curses TUI instead of tkinter


import curses
import subprocess

# Function to update the brightness using xrandr
def update_display(brightness):
    # Get the output name (e.g., HDMI-1, eDP-1)
    output = subprocess.getoutput("xrandr | grep ' connected' | cut -d' ' -f1")
    
    # Construct the xrandr command to change brightness
    command = f"xrandr --output {output} --brightness {brightness}"
    
    # Run the command using subprocess
    subprocess.run(command, shell=True)

# Function to handle the slider change and update the display
def update_slider(brightness, direction):
    if direction == 'up':
        brightness = min(brightness + 0.10, 1.0)  # max value for brightness is 1.0
    elif direction == 'down':
        brightness = max(brightness - 0.10, 0.20)  # min value for brightness is 0.20
    return brightness

def draw_slider(window, y, x, brightness, min_value, max_value):
    # Create the vertical slider representation
    slider_length = 10
    filled_length = int((brightness - min_value) / (max_value - min_value) * slider_length)
    
    # Draw the slider on the terminal
    window.addstr(y, x, "Brightness:")
    for i in range(slider_length):
        if i == slider_length - 1 - filled_length:
            window.addstr(y + i, x + 15, "*")  # This represents the slider's current value
        else:
            window.addstr(y + i, x + 15, "|")
    
    # Add value next to the slider
    window.addstr(y + slider_length + 1, x + 15, f"Value: {brightness:.2f}")

def main(stdscr):
    curses.curs_set(0)  # Hide cursor
    stdscr.nodelay(1)  # Make getch non-blocking
    stdscr.timeout(100)  # Refresh every 100ms

    # Initial value for brightness slider
    brightness = 1.0
    min_value = 0.20
    max_value = 1.0

    while True:
        stdscr.clear()

        # Draw the vertical brightness slider
        draw_slider(stdscr, 2, 2, brightness, min_value, max_value)

        # Instructions
        stdscr.addstr(14, 2, "Use Up/Down arrows to change brightness, q to quit")

        # Refresh the screen
        stdscr.refresh()

        key = stdscr.getch()

        if key == ord('q'):
            break
        elif key == curses.KEY_UP:
            brightness = update_slider(brightness, 'up')
        elif key == curses.KEY_DOWN:
            brightness = update_slider(brightness, 'down')

        # Update the display based on the brightness value
        update_display(brightness)

# Run the curses application
curses.wrapper(main)

No comments:

Post a Comment