loader image

GUI Multi-Monitor Brightness [Linux]

What makes us different from other similar websites? Forums Tech GUI Multi-Monitor Brightness [Linux]

Viewing 1 post (of 1 total)
  • Author
    Posts
  • #8227
    thumbtak
    Moderator

    🛠️ Guide: Adapting the Dual Brightness Control Script

    This script allows you to control the brightness of multiple screens (laptop display, secondary ScreenPad, external monitor, etc.) from a single GUI, but you must first tell it the system names for your monitors.

    Step 1: Find Your Monitor Device Names

    You need to know the specific device name your Linux system uses for each screen’s backlight. Open a terminal and run the following command:

    $ brightnessctl devices

    💡 Example Output:

    The output will list the controllable devices. For example:

    Device 'intel_backlight'
    Device 'acpi_video0'

    In this example, the two device names you’d use are intel_backlight and acpi_video0.

    Step 2: Edit the brightness.py File

    Open the brightness.py file in a text editor. Look for the DEVICES dictionary near the top of the file:

    # --- Configuration ---
    # These are the device names you provided.
    DEVICES = {
    "Primary Laptop Display": "intel_backlight",
    "Secondary ScreenPad": "asus_screenpad",
    }

    Step 3: Change the Configuration for Your Setup

    You need to change the Label (the friendly name that appears in the GUI) and the Device Name (the name you found in Step 1) for each screen you want to control.

    📝 Example of Changes:

    If your brightnessctl devices output was intel_backlight and acpi_video0, you would change the code to:

    DEVICES = {
    "My Laptop Display": "intel_backlight",
    "Office External Monitor": "acpi_video0",
    }

    Note: If you have more or fewer screens than the original file, simply add or remove lines in the dictionary, ensuring each device name is unique and wrapped in quotes.

    Step 4: Run the Script

    Save the file and run it from your terminal:

    $ python3 brightness.py

    You will now have a GUI where each slider controls the brightness of the monitor corresponding to the device name you configured!

    Important Reminder: The script uses sudo brightnessctl to change the brightness. If you are prompted for a password repeatedly, you must configure your sudoers file to allow passwordless execution of the brightnessctl command for your user.

    Full Script:

    import tkinter as tk
    from tkinter import ttk, messagebox
    import subprocess
    import re
    
    # --- Configuration ---
    # These are the device names you provided.
    DEVICES = {
    "Primary Laptop Display": "intel_backlight",
    "Secondary ScreenPad": "asus_screenpad",
    }
    
    class BrightnessApp:
    def __init__(self, root):
    self.root = root
    root.title("Dual Display Brightness Control")
    root.geometry("450x250")
    root.resizable(False, False)
    
    # Set up modern styling
    style = ttk.Style()
    style.theme_use('clam')
    style.configure("TLabel", font=('Arial', 10, 'bold'), foreground="#333")
    style.configure("TFrame", background="#f0f0f0")
    style.configure("TScale", background="#f0f0f0", troughcolor="#ddd")
    
    main_frame = ttk.Frame(root, padding="20 20 20 20", style="TFrame")
    main_frame.pack(fill=tk.BOTH, expand=True)
    
    self.sliders = {}
    row = 0
    
    for label, device_name in DEVICES.items():
    # Get initial brightness value for slider positioning
    initial_percentage = self._get_initial_brightness_percentage(device_name)
    
    # Label for the monitor
    ttk.Label(main_frame, text=f"{label} ({device_name})", style="TLabel").grid(
    row=row, column=0, sticky='w', pady=(10, 5)
    )
    
    # Brightness value display (initially shows the percentage)
    value_label = ttk.Label(main_frame, text=f"{initial_percentage}%", width=5)
    value_label.grid(row=row, column=2, sticky='e', padx=(10, 0))
    
    # Slider widget (Scale)
    slider = ttk.Scale(
    main_frame,
    from_=1, # Minimum brightness is typically 1 to avoid full off
    to=100, # Maximum brightness is 100%
    orient=tk.HORIZONTAL,
    length=300,
    command=lambda val, d=device_name, l=value_label: self.set_brightness(d, float(val), l)
    )
    slider.set(initial_percentage)
    slider.grid(row=row + 1, column=0, columnspan=2, sticky='we', padx=(0, 10))
    
    self.sliders[device_name] = slider
    row += 2
    
    # Add a note about permissions
    ttk.Label(
    main_frame,
    text="Note: This app runs 'sudo brightnessctl'. Configure sudoers for passwordless operation.",
    font=('Arial', 8, 'italic'),
    foreground="#888"
    ).grid(row=row, column=0, columnspan=3, sticky='w', pady=(15, 0))
    
    def _run_cmd(self, command, check=False):
    """Helper to execute a command and handle errors."""
    try:
    # We use <code>shell=True</code> here because of the <code>sudo</code> prefix
    result = subprocess.run(
    command,
    shell=True,
    capture_output=True,
    text=True,
    check=check
    )
    return result
    except subprocess.CalledProcessError as e:
    error_msg = f"Command failed: {command}\nError: {e.stderr}"
    print(error_msg)
    messagebox.showerror("Execution Error", error_msg)
    return None
    except FileNotFoundError:
    messagebox.showerror("Error", "brightnessctl command not found. Please ensure it is installed.")
    return None
    
    def _get_initial_brightness_percentage(self, device_name):
    """Gets the current brightness percentage from brightnessctl info."""
    # Use the unprivileged info command to read the current state
    result = self._run_cmd(f"brightnessctl -d {device_name} info")
    
    if result and result.stdout:
    # Look for the current percentage (e.g., "520 (98%)")
    match = re.search(r'\((?P\d+)%\)', result.stdout)
    if match:
    return int(match.group('percent'))
    
    # Default to 50% if retrieval fails
    return 50
    
    def set_brightness(self, device_name, percentage, value_label):
    """
    Sets the brightness of the given device using subprocess.
    
    Args:
    device_name (str): The backlight device name (e.g., "intel_backlight").
    percentage (float): The target brightness percentage (1.0 to 100.0).
    value_label (ttk.Label): The label widget to update with the current value.
    """
    # Ensure percentage is an integer for clean command execution
    int_percentage = int(percentage)
    
    # Update the GUI label immediately
    value_label.config(text=f"{int_percentage}%")
    
    # The core command that requires sudo
    command = f"sudo brightnessctl -d {device_name} set {int_percentage}%"
    
    # Execute the command without checking for errors, as sudo requires interactivity
    # The user must handle the password prompt or configure sudoers.
    self._run_cmd(command)
    
    # --- Run the Application ---
    if __name__ == '__main__':
    # This prevents the initial Tkinter window from looking dated on some systems
    try:
    from ctypes import windll
    windll.shcore.SetProcessDpiAwareness(1)
    except:
    pass
    
    root = tk.Tk()
    app = BrightnessApp(root)
    root.mainloop()
Viewing 1 post (of 1 total)
  • You must be logged in to reply to this topic.
TAKs Shack
Wishing you and yours a very happy Thanksgiving!
This is default text for notification bar