new WM setup
This commit is contained in:
parent
b0d928d0f2
commit
44fbc7a4d4
10 changed files with 784 additions and 115 deletions
89
wrappers/desktop/gaypanel/default.nix
Normal file
89
wrappers/desktop/gaypanel/default.nix
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
bar = pkgs.writeText "top.blp" ''
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
$GayPanel panel {
|
||||
anchor-direction: top;
|
||||
monitor: "all";
|
||||
|
||||
CenterBox {
|
||||
margin-start: 4;
|
||||
margin-end: 4;
|
||||
margin-top: 4;
|
||||
margin-bottom: 4;
|
||||
|
||||
[start]
|
||||
$WorkspacesWidget {
|
||||
show-labels: false;
|
||||
}
|
||||
|
||||
[center]
|
||||
$ClockWidget {
|
||||
styles [
|
||||
"pill",
|
||||
"flat",
|
||||
]
|
||||
|
||||
format: "%b %d %H:%M";
|
||||
}
|
||||
|
||||
[end]
|
||||
$SystemControlsWidget {
|
||||
styles [
|
||||
"pill",
|
||||
"flat",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
'';
|
||||
|
||||
# GNOME-style workspace dots, with the active one stretched into a pill
|
||||
style = pkgs.writeText "style.css" ''
|
||||
.workspaces button {
|
||||
min-width: 8px;
|
||||
min-height: 8px;
|
||||
padding: 0;
|
||||
border-radius: 99px;
|
||||
background: alpha(var(--window-fg-color), 0.4);
|
||||
transition: min-width 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
|
||||
.workspaces button.selected {
|
||||
min-width: 32px;
|
||||
padding: 0;
|
||||
background: var(--window-fg-color);
|
||||
}
|
||||
|
||||
.workspaces button label {
|
||||
font-size: 0;
|
||||
}
|
||||
'';
|
||||
in
|
||||
{
|
||||
wrappers.gaypanel = {
|
||||
basePackage =
|
||||
inputs.gaypanel.packages.${pkgs.stdenv.hostPlatform.system}.default.overrideAttrs
|
||||
(old: {
|
||||
patches = (old.patches or [ ]) ++ [
|
||||
./no-sound-panic.patch
|
||||
];
|
||||
});
|
||||
|
||||
prependFlags = [
|
||||
"--config"
|
||||
# Copied rather than linked, since gaypanel ignores symlinks in bars/
|
||||
"${pkgs.runCommand "gaypanel-config" { } ''
|
||||
mkdir -p $out/bars
|
||||
cp ${bar} $out/bars/top.blp
|
||||
cp ${style} $out/style.css
|
||||
''}"
|
||||
];
|
||||
};
|
||||
}
|
||||
104
wrappers/desktop/gaypanel/no-sound-panic.patch
Normal file
104
wrappers/desktop/gaypanel/no-sound-panic.patch
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
--- a/src/system/sound.rs
|
||||
+++ b/src/system/sound.rs
|
||||
@@ -6,25 +6,21 @@
|
||||
|
||||
use crate::{senders, system::SystemModule};
|
||||
|
||||
-/// Gets the default mixer. Throws an error if it doesn't exist (this means you probably don't have ALSA installed)
|
||||
+/// Gets the default mixer. Returns None if it doesn't exist (yet), e.g. if the sound server hasn't started
|
||||
macro_rules! mixer {
|
||||
() => {
|
||||
- Mixer::new("default", false).expect("[fatal] alsa: Could not find a mixer named \"default\". gaypanel assumes this is the name of the default mixer. \n[fatal] alsa: **If you have ALSA installed and running and you're *sure* of it, open an issue at codeberg.org/pastthepixels/gaypanel!**")
|
||||
+ Mixer::new("default", false).ok()
|
||||
};
|
||||
}
|
||||
|
||||
/// Finds the first selem with a playback volume in a mixer. Assumes this is the "default"
|
||||
/// e.g. this reflects the actual output volume. I don't know how alsa works.
|
||||
-/// You must have a speaker of some kind or else this'll crap out
|
||||
+/// Returns None if there's no speaker of some kind (yet)
|
||||
macro_rules! sink {
|
||||
($m: expr) => {
|
||||
$m.iter()
|
||||
.flat_map(|e| Selem::new(e))
|
||||
.find(|s| s.has_playback_volume())
|
||||
- .expect(&format!(
|
||||
- "[fatal] alsa: Could not find default sink for mixer {:?}",
|
||||
- $m
|
||||
- ))
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,9 +50,9 @@
|
||||
senders!(VolumeModule);
|
||||
|
||||
fn get() -> Option<Self::ReturnType> {
|
||||
- let mixer = mixer!();
|
||||
+ let mixer = mixer!()?;
|
||||
// Sink stats
|
||||
- let sink = sink!(mixer);
|
||||
+ let sink = sink!(mixer)?;
|
||||
let vol = {
|
||||
let max = sink.get_playback_volume_range().1 as f64;
|
||||
let raw_vol = sink
|
||||
@@ -101,8 +97,12 @@
|
||||
|
||||
fn set(val: Self::ReturnType) {
|
||||
// Sets sink volume
|
||||
- let mixer = mixer!();
|
||||
- let sink = sink!(mixer);
|
||||
+ let Some(mixer) = mixer!() else {
|
||||
+ return;
|
||||
+ };
|
||||
+ let Some(sink) = sink!(mixer) else {
|
||||
+ return;
|
||||
+ };
|
||||
let max = sink.get_playback_volume_range().1 as f64;
|
||||
sink.set_playback_volume_all((val.0.volume * max) as i64)
|
||||
.unwrap();
|
||||
@@ -118,8 +118,17 @@
|
||||
|
||||
fn listen() {
|
||||
std::thread::spawn(|| {
|
||||
- let mixer = mixer!();
|
||||
- let sink = sink!(mixer);
|
||||
+ // Wait for the sound server to provide a mixer with a sink
|
||||
+ let mixer = loop {
|
||||
+ if let Some(mixer) = mixer!() {
|
||||
+ let has_sink = sink!(mixer).is_some();
|
||||
+ if has_sink {
|
||||
+ break mixer;
|
||||
+ }
|
||||
+ }
|
||||
+ std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
+ };
|
||||
+ let sink = sink!(mixer).unwrap();
|
||||
let source = source!(mixer);
|
||||
let mut pollfds = mixer.get().unwrap();
|
||||
|
||||
--- a/src/widgets/controls.rs
|
||||
+++ b/src/widgets/controls.rs
|
||||
@@ -400,7 +400,10 @@
|
||||
gtk::EventControllerScroll::new(gtk::EventControllerScrollFlags::VERTICAL);
|
||||
controller.connect_scroll(|_, _, b| {
|
||||
glib::spawn_future_local(async move {
|
||||
- let sound = (system::sound::VolumeModule::get().unwrap().0.volume
|
||||
+ let Some(stats) = system::sound::VolumeModule::get() else {
|
||||
+ return;
|
||||
+ };
|
||||
+ let sound = (stats.0.volume
|
||||
- b.signum() * VOLUME_SCROLL_STEP)
|
||||
.clamp(0., 1.);
|
||||
system::sound::VolumeModule::set((
|
||||
@@ -420,7 +423,10 @@
|
||||
// Setup volume
|
||||
let this = glib::clone::Downgrade::downgrade(&self);
|
||||
let rx = system::sound::VolumeModule::rx();
|
||||
- self.update_sound(system::sound::VolumeModule::get().unwrap());
|
||||
+ // The listener sends an update once sound is available, so it's fine to skip this
|
||||
+ if let Some(stats) = system::sound::VolumeModule::get() {
|
||||
+ self.update_sound(stats);
|
||||
+ }
|
||||
glib::spawn_future_local(async move {
|
||||
while let Ok(stats) = rx.recv().await {
|
||||
if let Some(this) = this.upgrade() {
|
||||
Loading…
Reference in a new issue