fix(hyprdrive,hyprlua): anchor the audio mixer panel top-right and shrink it
Layer-shell surfaces can only anchor to a screen edge with a margin, not to another process's widget, so this can't truly follow the invoking volume button — but every bar variant in this repo (station-bar, eww/eww-touch/ eww-nobattery) keeps its volume control in the top-right zone, so anchoring there approximates "under the control that opened it" well enough. Also shrunk the panel (900px -> 460px, smaller cards/meters/tab height) so it reads as a compact popover instead of a full-width mixer. hyprlua's audio-panel is regenerated via regen-audio-panel.sh; its hand-maintained plain theme seed (audio-panel-theme/style.css) got the same sizing tweaks by hand since the regen script doesn't touch it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDGmain
parent
bda4640b54
commit
516adeb5ae
|
|
@ -68,7 +68,7 @@ drawingarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
.sb-tab-page {
|
.sb-tab-page {
|
||||||
min-height: 260px;
|
min-height: 190px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- horizontal scroll row of cards --------------------------------------- */
|
/* ---- horizontal scroll row of cards --------------------------------------- */
|
||||||
|
|
@ -85,8 +85,8 @@ drawingarea {
|
||||||
background-color: alpha(@violet, 0.30);
|
background-color: alpha(@violet, 0.30);
|
||||||
border: 2px solid #8A5CFF;
|
border: 2px solid #8A5CFF;
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
padding: 10px 12px;
|
padding: 8px 10px;
|
||||||
min-width: 170px;
|
min-width: 150px;
|
||||||
}
|
}
|
||||||
.sb-card-head { margin-bottom: 2px; }
|
.sb-card-head { margin-bottom: 2px; }
|
||||||
.sb-card-title {
|
.sb-card-title {
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class VolumeMeter(Gtk.Box):
|
||||||
self.scale.set_draw_value(True)
|
self.scale.set_draw_value(True)
|
||||||
self.scale.set_value_pos(Gtk.PositionType.RIGHT)
|
self.scale.set_value_pos(Gtk.PositionType.RIGHT)
|
||||||
self.scale.set_hexpand(True)
|
self.scale.set_hexpand(True)
|
||||||
self.scale.set_size_request(120, -1)
|
self.scale.set_size_request(90, -1)
|
||||||
self.scale.add_css_class("sb-meter")
|
self.scale.add_css_class("sb-meter")
|
||||||
self.scale.add_mark(100, Gtk.PositionType.BOTTOM, None)
|
self.scale.add_mark(100, Gtk.PositionType.BOTTOM, None)
|
||||||
self.scale.connect("value-changed", self._on_value_changed)
|
self.scale.connect("value-changed", self._on_value_changed)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,18 @@
|
||||||
"""The popup: a content-sized floating layer-shell panel anchored top-centre,
|
"""The popup: a content-sized floating layer-shell panel anchored top-right,
|
||||||
matching transmitter-panel/astro-menu's window.py idiom — dismissed with the
|
matching transmitter-panel/astro-menu's window.py idiom — dismissed with the
|
||||||
launcher toggle, Esc, or the ✕ button, no click-outside-to-close.
|
launcher toggle, Esc, or the ✕ button, no click-outside-to-close.
|
||||||
|
|
||||||
Gtk.Window (layer TOP, anchored TOP -> horizontally centred, height = content)
|
Anchored top-right (not centred) so it sits roughly under the volume control
|
||||||
|
that invokes it — station-bar's volume badge and every eww variant's volume
|
||||||
|
slider all live in the right-hand zone of their bar. This is a fixed
|
||||||
|
approximation, not a live "appear under this exact widget" position: the
|
||||||
|
wlr-layer-shell protocol only supports anchor+margin-to-screen-edge
|
||||||
|
placement, not popup-relative-to-another-surface placement, and the panel is
|
||||||
|
a separate process from whichever bar invoked it, so it has no way to learn
|
||||||
|
that bar's precise pixel geometry. Tune RIGHT_MARGIN below if it drifts from
|
||||||
|
whichever bar/build you're running against.
|
||||||
|
|
||||||
|
Gtk.Window (layer TOP, anchored TOP+RIGHT, height/width = content)
|
||||||
└ Gtk.Overlay
|
└ Gtk.Overlay
|
||||||
main : .sb-panel (title, tab switcher, Gtk.Stack of the four tabs)
|
main : .sb-panel (title, tab switcher, Gtk.Stack of the four tabs)
|
||||||
over : hologram overlay
|
over : hologram overlay
|
||||||
|
|
@ -33,8 +43,9 @@ from ui.input_tab import InputTab
|
||||||
from ui.output_tab import OutputTab
|
from ui.output_tab import OutputTab
|
||||||
from ui.tabs import TabSwitcher
|
from ui.tabs import TabSwitcher
|
||||||
|
|
||||||
PANEL_WIDTH = 900
|
PANEL_WIDTH = 460
|
||||||
EDGE_MARGIN = 28
|
TOP_MARGIN = 28
|
||||||
|
RIGHT_MARGIN = 160 # approximate horizontal offset to sit under the volume control
|
||||||
|
|
||||||
|
|
||||||
class SupersonicWindow(Gtk.ApplicationWindow):
|
class SupersonicWindow(Gtk.ApplicationWindow):
|
||||||
|
|
@ -119,7 +130,9 @@ class SupersonicWindow(Gtk.ApplicationWindow):
|
||||||
LayerShell.set_namespace(self, "supersonic-booster")
|
LayerShell.set_namespace(self, "supersonic-booster")
|
||||||
LayerShell.set_keyboard_mode(self, LayerShell.KeyboardMode.ON_DEMAND)
|
LayerShell.set_keyboard_mode(self, LayerShell.KeyboardMode.ON_DEMAND)
|
||||||
LayerShell.set_anchor(self, LayerShell.Edge.TOP, True)
|
LayerShell.set_anchor(self, LayerShell.Edge.TOP, True)
|
||||||
LayerShell.set_margin(self, LayerShell.Edge.TOP, EDGE_MARGIN)
|
LayerShell.set_anchor(self, LayerShell.Edge.RIGHT, True)
|
||||||
|
LayerShell.set_margin(self, LayerShell.Edge.TOP, TOP_MARGIN)
|
||||||
|
LayerShell.set_margin(self, LayerShell.Edge.RIGHT, RIGHT_MARGIN)
|
||||||
|
|
||||||
# -- visibility -----------------------------------------------------------------
|
# -- visibility -----------------------------------------------------------------
|
||||||
def show_panel(self) -> None:
|
def show_panel(self) -> None:
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ drawingarea {
|
||||||
color: @bg;
|
color: @bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sb-tab-page { min-height: 260px; }
|
.sb-tab-page { min-height: 190px; }
|
||||||
|
|
||||||
/* ---- horizontal scroll row of cards ---------------------------------------- */
|
/* ---- horizontal scroll row of cards ---------------------------------------- */
|
||||||
.sb-scroll-row { padding: 4px 2px 10px 2px; }
|
.sb-scroll-row { padding: 4px 2px 10px 2px; }
|
||||||
|
|
@ -79,8 +79,8 @@ drawingarea {
|
||||||
background-color: alpha(@violet, 0.5);
|
background-color: alpha(@violet, 0.5);
|
||||||
border: 2px solid @violet;
|
border: 2px solid @violet;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 10px 12px;
|
padding: 8px 10px;
|
||||||
min-width: 170px;
|
min-width: 150px;
|
||||||
}
|
}
|
||||||
.sb-card-head { margin-bottom: 2px; }
|
.sb-card-head { margin-bottom: 2px; }
|
||||||
.sb-card-title {
|
.sb-card-title {
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ drawingarea {
|
||||||
color: @bg;
|
color: @bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sb-tab-page { min-height: 260px; }
|
.sb-tab-page { min-height: 190px; }
|
||||||
|
|
||||||
/* ---- horizontal scroll row of cards ---------------------------------------- */
|
/* ---- horizontal scroll row of cards ---------------------------------------- */
|
||||||
.sb-scroll-row { padding: 4px 2px 10px 2px; }
|
.sb-scroll-row { padding: 4px 2px 10px 2px; }
|
||||||
|
|
@ -79,8 +79,8 @@ drawingarea {
|
||||||
background-color: alpha(@violet, 0.5);
|
background-color: alpha(@violet, 0.5);
|
||||||
border: 2px solid @violet;
|
border: 2px solid @violet;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 10px 12px;
|
padding: 8px 10px;
|
||||||
min-width: 170px;
|
min-width: 150px;
|
||||||
}
|
}
|
||||||
.sb-card-head { margin-bottom: 2px; }
|
.sb-card-head { margin-bottom: 2px; }
|
||||||
.sb-card-title {
|
.sb-card-title {
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class VolumeMeter(Gtk.Box):
|
||||||
self.scale.set_draw_value(True)
|
self.scale.set_draw_value(True)
|
||||||
self.scale.set_value_pos(Gtk.PositionType.RIGHT)
|
self.scale.set_value_pos(Gtk.PositionType.RIGHT)
|
||||||
self.scale.set_hexpand(True)
|
self.scale.set_hexpand(True)
|
||||||
self.scale.set_size_request(120, -1)
|
self.scale.set_size_request(90, -1)
|
||||||
self.scale.add_css_class("sb-meter")
|
self.scale.add_css_class("sb-meter")
|
||||||
self.scale.add_mark(100, Gtk.PositionType.BOTTOM, None)
|
self.scale.add_mark(100, Gtk.PositionType.BOTTOM, None)
|
||||||
self.scale.connect("value-changed", self._on_value_changed)
|
self.scale.connect("value-changed", self._on_value_changed)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,18 @@
|
||||||
"""The popup: a content-sized floating layer-shell panel anchored top-centre,
|
"""The popup: a content-sized floating layer-shell panel anchored top-right,
|
||||||
matching transmitter-panel/astro-menu's window.py idiom — dismissed with the
|
matching transmitter-panel/astro-menu's window.py idiom — dismissed with the
|
||||||
launcher toggle, Esc, or the ✕ button, no click-outside-to-close.
|
launcher toggle, Esc, or the ✕ button, no click-outside-to-close.
|
||||||
|
|
||||||
Gtk.Window (layer TOP, anchored TOP -> horizontally centred, height = content)
|
Anchored top-right (not centred) so it sits roughly under the volume control
|
||||||
|
that invokes it — station-bar's volume badge and every eww variant's volume
|
||||||
|
slider all live in the right-hand zone of their bar. This is a fixed
|
||||||
|
approximation, not a live "appear under this exact widget" position: the
|
||||||
|
wlr-layer-shell protocol only supports anchor+margin-to-screen-edge
|
||||||
|
placement, not popup-relative-to-another-surface placement, and the panel is
|
||||||
|
a separate process from whichever bar invoked it, so it has no way to learn
|
||||||
|
that bar's precise pixel geometry. Tune RIGHT_MARGIN below if it drifts from
|
||||||
|
whichever bar/build you're running against.
|
||||||
|
|
||||||
|
Gtk.Window (layer TOP, anchored TOP+RIGHT, height/width = content)
|
||||||
└ Gtk.Overlay
|
└ Gtk.Overlay
|
||||||
main : .sb-panel (title, tab switcher, Gtk.Stack of the four tabs)
|
main : .sb-panel (title, tab switcher, Gtk.Stack of the four tabs)
|
||||||
over : hologram overlay
|
over : hologram overlay
|
||||||
|
|
@ -33,8 +43,9 @@ from ui.input_tab import InputTab
|
||||||
from ui.output_tab import OutputTab
|
from ui.output_tab import OutputTab
|
||||||
from ui.tabs import TabSwitcher
|
from ui.tabs import TabSwitcher
|
||||||
|
|
||||||
PANEL_WIDTH = 900
|
PANEL_WIDTH = 460
|
||||||
EDGE_MARGIN = 28
|
TOP_MARGIN = 28
|
||||||
|
RIGHT_MARGIN = 160 # approximate horizontal offset to sit under the volume control
|
||||||
|
|
||||||
|
|
||||||
class AudioPanelWindow(Gtk.ApplicationWindow):
|
class AudioPanelWindow(Gtk.ApplicationWindow):
|
||||||
|
|
@ -119,7 +130,9 @@ class AudioPanelWindow(Gtk.ApplicationWindow):
|
||||||
LayerShell.set_namespace(self, "audio-panel")
|
LayerShell.set_namespace(self, "audio-panel")
|
||||||
LayerShell.set_keyboard_mode(self, LayerShell.KeyboardMode.ON_DEMAND)
|
LayerShell.set_keyboard_mode(self, LayerShell.KeyboardMode.ON_DEMAND)
|
||||||
LayerShell.set_anchor(self, LayerShell.Edge.TOP, True)
|
LayerShell.set_anchor(self, LayerShell.Edge.TOP, True)
|
||||||
LayerShell.set_margin(self, LayerShell.Edge.TOP, EDGE_MARGIN)
|
LayerShell.set_anchor(self, LayerShell.Edge.RIGHT, True)
|
||||||
|
LayerShell.set_margin(self, LayerShell.Edge.TOP, TOP_MARGIN)
|
||||||
|
LayerShell.set_margin(self, LayerShell.Edge.RIGHT, RIGHT_MARGIN)
|
||||||
|
|
||||||
# -- visibility -----------------------------------------------------------------
|
# -- visibility -----------------------------------------------------------------
|
||||||
def show_panel(self) -> None:
|
def show_panel(self) -> None:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue