~charles/gmixerctl

c08fe9f3d12af787addb9bc0f639f1f59d93199f — Charles Daniels 5 years ago 11d0057 0.1.2
0.1.2 release various minor fixes (see CHANGELOG)
4 files changed, 49 insertions(+), 14 deletions(-)

M CHANGELOG
M gmixerctl/constants.py
M gmixerctl/gui.py
M gmixerctl/mixerctl.py
M CHANGELOG => CHANGELOG +10 -0
@@ 16,3 16,13 @@

	* If the basic tab fails to build, an error dialog is displayed before
	  crashing.

0.1.2

    * Updated project homepage to point to SourceHut.

    * Prevent switching to unconfigured mixer devices.

    * Default logging level has been changed to INFO.

    * About tab now links to project page.

M gmixerctl/constants.py => gmixerctl/constants.py +7 -4
@@ 6,11 6,11 @@ update_interval = 250
label_width = 20
control_width = 30

log_level = logging.DEBUG
log_level = logging.INFO

mixer_device = "/dev/mixer"

project_homepage = "https://github.com/charlesdaniels/gmixerctl"
project_homepage = "https://git.sr.ht/~charles/gmixerctl"

# control names to appear in the basic tab
basic_controls = [


@@ 23,10 23,10 @@ basic_controls = [
    "record.slaves"
]

version = "0.1.1"
version = "0.1.2"

license = """
Copyright (c) 2018, Charles Daniels (except where otherwise noted)
Copyright (c) 2018-2019, Charles Daniels (except where otherwise noted)
All rights reserved.

Redistribution and use in source and binary forms, with or without


@@ 63,5 63,8 @@ If you see this message, one of the assumptions gmixerctl makes about your
audio setup is so fundamentally wrong that it can't generate a "basic"
tab for you. Either this is a bug in gmixerctl, or a problem with your system.

This message can also appear if you ask gmixerctl to open an unconfigured mixer
device.

Please report this issue on the gmixerctl homepage: {}
""".format(project_homepage)

M gmixerctl/gui.py => gmixerctl/gui.py +26 -7
@@ 1,10 1,11 @@
import glob
import logging
import subprocess
import sys
import time
import tkinter
import tkinter.ttk as ttk
import tkinter.messagebox
import time
import subprocess
import glob
import tkinter.ttk as ttk

from . import mixerctl
from . import util


@@ 18,6 19,7 @@ def update_state(root, tkvars):
    """

    controls = mixerctl.get_state()

    for name in controls:
        control = controls[name]
        if control["type"] == "value":


@@ 84,13 86,24 @@ class SndiodButton(tkinter.Button):
                    )

class SetMixerDevice:
    def __init__(this, parent):
    def __init__(this, parent, selector_var):
        this.parent = parent
        this.selector_var = selector_var

    def __call__(this, val):
        # implement callback for setting mixer device

        old_device = constants.mixer_device
        constants.mixer_device = val

        if mixerctl.get_state() is None:
            constants.mixer_device = old_device
            tkinter.messagebox.showerror("Error",
                    "The requested device '{}' is not configured.".format(val))
            this.selector_var.set(old_device)
            return


        logging.debug("updated mixer device to {}".format(val))
        this.parent.destroy()
        main()


@@ 227,6 240,10 @@ def main():

    # get initial state
    controls = mixerctl.get_state()

    if controls is None:
        controls = []

    util.log_pretty(logging.debug, controls)

    tabs = {}


@@ 255,15 272,16 @@ def main():

    if "basic" not in tabs:
        tkinter.messagebox.showerror("Error", constants.basic_error)
        sys.exit(1)

    # add mixer device selector to basic tab
    dev_selector_label = tkinter.Label(tabs[tab_name],
            text = "select mixer device")
    dev_selector_label.grid(row = row_counter, column = 0)

    callback = SetMixerDevice(root)
    available_device = []
    dev_selector_var = tkinter.StringVar()
    callback = SetMixerDevice(root, dev_selector_var)
    dev_selector_var.set(constants.mixer_device)
    mixer_dev_selector = tkinter.OptionMenu(
            tabs[tab_name],


@@ 336,7 354,8 @@ def main():
    about = ttk.Frame(nb)
    version = tkinter.Label(
            about,
            text = "gmixerctl version {}".format(constants.version),
            text = "gmixerctl version {}\n\n{}".format(
                constants.version, constants.project_homepage),
    )
    version.pack()


M gmixerctl/mixerctl.py => gmixerctl/mixerctl.py +6 -3
@@ 83,9 83,12 @@ def get_state():
    Get the current mixer state.
    """

    raw = subprocess.check_output(["mixerctl", "-f", constants.mixer_device,
        "-v"], stderr=subprocess.STDOUT)
    raw = raw.decode()
    try:
        raw = subprocess.check_output(["mixerctl", "-f", constants.mixer_device,
            "-v"], stderr=subprocess.STDOUT)
        raw = raw.decode()
    except subprocess.CalledProcessError:
        return None

    control = {}