control panel: compact audio rows, per-view sizing, bigger action icons

- the audio page's master rows now match the home page: an icon, a bar and a
  percentage, no 'Output'/'Microphone' captions
- GtkStack was vhomogeneous, so every view was padded to the tallest one and
  the scrolled list clipped while empty space sat below it. Views size
  themselves now, and the scrollers propagate natural height up to a cap.
- power and action row glyphs 15px -> 20px

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cn3dHfbgNYdbZvzb1b3GQt
This commit is contained in:
Sarthak 2026-09-04 08:52:41 +05:30
parent ddf9321901
commit d6129334b1

View file

@ -85,8 +85,8 @@ window.panel { background-color: transparent; }
border: 1px solid rgba(146, 185, 234, 0.10);
border-radius: 12px;
color: #e9eefb;
font-size: 15px;
padding: 11px 8px;
font-size: 20px;
padding: 13px 8px;
}
.pw:hover { background-color: rgba(146, 185, 234, 0.22); }
.pw.danger:hover { background-color: rgba(207, 106, 128, 0.32); color: #ffe9ee; }
@ -265,6 +265,8 @@ class Panel(Gtk.Window):
self.stack = Gtk.Stack()
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
self.stack.set_transition_duration(140)
self.stack.set_vhomogeneous(False)
self.stack.set_hhomogeneous(True)
self.stack.add_named(self.build_main(), "main")
self.stack.add_named(self.build_list_view("Bluetooth", self.fill_bt), "bt")
@ -436,7 +438,9 @@ class Panel(Gtk.Window):
scroller = Gtk.ScrolledWindow()
scroller.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
scroller.set_min_content_height(260)
scroller.set_min_content_height(120)
scroller.set_max_content_height(520)
scroller.set_propagate_natural_height(True)
listbox = Gtk.ListBox()
listbox.set_selection_mode(Gtk.SelectionMode.NONE)
listbox.get_style_context().add_class("card")
@ -458,7 +462,9 @@ class Panel(Gtk.Window):
scroller = Gtk.ScrolledWindow()
scroller.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
scroller.set_min_content_height(300)
scroller.set_min_content_height(120)
scroller.set_max_content_height(520)
scroller.set_propagate_natural_height(True)
self.audio_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
scroller.add(self.audio_box)
outer.add(scroller)
@ -488,13 +494,16 @@ class Panel(Gtk.Window):
b.connect("clicked", lambda *_: self.set_device(kind, name))
return b
def app_row(self, idx, app, vol, muted):
def app_row(self, idx, app, vol, muted, show_label=True, icon=None):
wp = str(idx).startswith("@")
card = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
lbl = Gtk.Label(label=app, xalign=0)
lbl.get_style_context().add_class("subtle")
row = Gtk.Box(spacing=10)
mb = Gtk.Button(label=ICON["vol_mute"] if muted else ICON["vol"])
base = icon or ICON["vol"]
muted_icon = {ICON["vol"]: ICON["vol_mute"],
ICON["mic"]: ICON["mic_mute"]}.get(base, ICON["vol_mute"])
mb = Gtk.Button(label=muted_icon if muted else base)
mb.get_style_context().add_class("rowbtn")
mb.connect("clicked", lambda *_: (
sh(f"wpctl set-mute {idx} toggle" if wp
@ -513,7 +522,8 @@ class Panel(Gtk.Window):
row.pack_start(mb, False, False, 0)
row.pack_start(sc, True, True, 0)
row.pack_end(pct, False, False, 0)
card.add(lbl)
if show_label:
card.add(lbl)
card.add(row)
return card
@ -531,13 +541,14 @@ class Panel(Gtk.Window):
for c in self.audio_box.get_children():
self.audio_box.remove(c)
self.audio_box.add(self.section("Volume"))
card = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
card.get_style_context().add_class("card")
v, vm = vol_get()
m, mm = mic_get()
card.add(self.app_row("@DEFAULT_AUDIO_SINK@", "Output", v, vm))
card.add(self.app_row("@DEFAULT_AUDIO_SOURCE@", "Microphone", m, mm))
card.add(self.app_row("@DEFAULT_AUDIO_SINK@", "", v, vm,
show_label=False, icon=ICON["vol"]))
card.add(self.app_row("@DEFAULT_AUDIO_SOURCE@", "", m, mm,
show_label=False, icon=ICON["mic"]))
self.audio_box.add(card)
self.audio_box.add(self.section("Output"))