aboutsummaryrefslogtreecommitdiff
path: root/.config/awesome
diff options
context:
space:
mode:
authordelta <darkussdelta@gmail.com>2026-04-17 08:10:30 +0200
committerdelta <darkussdelta@gmail.com>2026-04-17 08:10:30 +0200
commita7c79cb5a04562be10347856642a80f0c4be89fc (patch)
tree98fac95855d84f5037a1c6f44061cbe94b550600 /.config/awesome
parent225eeafcea67d63a608f9c666faf2a2ef014be4a (diff)
Diffstat (limited to '.config/awesome')
-rw-r--r--.config/awesome/misc/autostart.lua2
-rw-r--r--.config/awesome/misc/cfg.lua1
-rw-r--r--.config/awesome/misc/init.lua2
-rw-r--r--.config/awesome/misc/keys.lua30
-rw-r--r--.config/awesome/misc/rules.lua12
-rw-r--r--.config/awesome/prismite.lua4
-rw-r--r--.config/awesome/quarrel/native/Cargo.toml2
-rw-r--r--.config/awesome/quarrel/native/src/lenses/application.rs14
-rw-r--r--.config/awesome/quarrel/native/src/lenses/calculator.rs27
-rw-r--r--.config/awesome/quarrel/native/src/lenses/mod.rs90
-rw-r--r--.config/awesome/quarrel/native/src/net/mod.rs4
-rw-r--r--.config/awesome/quarrel/native/src/net/wireless.rs4
-rw-r--r--.config/awesome/quarrel/ui/init.lua87
-rw-r--r--.config/awesome/services/mpris/consts.lua13
-rw-r--r--.config/awesome/services/mpris/init.lua178
-rw-r--r--.config/awesome/services/osd.lua18
-rw-r--r--.config/awesome/services/wifi.lua0
-rw-r--r--.config/awesome/ui/fresnel/init.lua19
-rw-r--r--.config/awesome/ui/fresnel/text_input.lua4
-rw-r--r--.config/awesome/ui/osd/init.lua136
-rw-r--r--.config/awesome/ui/statusbar/init.lua31
-rw-r--r--.config/awesome/ui/statusbar/panel/widgets/mpris.lua158
22 files changed, 559 insertions, 277 deletions
diff --git a/.config/awesome/misc/autostart.lua b/.config/awesome/misc/autostart.lua
index de79c65..85b91c0 100644
--- a/.config/awesome/misc/autostart.lua
+++ b/.config/awesome/misc/autostart.lua
@@ -1,7 +1,7 @@
local awful = require "awful"
local qpersistent = require "quarrel.persistent"
-if qpersistent.is_restart() then
+if qpersistent.is_restart() or awesome.release == "somewm" then
return
end
diff --git a/.config/awesome/misc/cfg.lua b/.config/awesome/misc/cfg.lua
index f62612f..a05f911 100644
--- a/.config/awesome/misc/cfg.lua
+++ b/.config/awesome/misc/cfg.lua
@@ -1,7 +1,6 @@
local awful = require "awful"
local cfg = {
- terminal = "wezterm",
tags = {
-- home
{
diff --git a/.config/awesome/misc/init.lua b/.config/awesome/misc/init.lua
index 069046a..d3c36b2 100644
--- a/.config/awesome/misc/init.lua
+++ b/.config/awesome/misc/init.lua
@@ -1,3 +1,3 @@
require "misc.keys"
require "misc.rules"
--- require "misc.autostart"
+require "misc.autostart"
diff --git a/.config/awesome/misc/keys.lua b/.config/awesome/misc/keys.lua
index b7dc4c4..9a5e481 100644
--- a/.config/awesome/misc/keys.lua
+++ b/.config/awesome/misc/keys.lua
@@ -2,7 +2,10 @@ local awful = require "awful"
local backlight = require "services.backlight"
local beautiful = require "beautiful"
local cfg = require "misc.cfg"
-local fresnel = require "ui.fresnel"
+local fresnel = { show = function() end}
+if awesome.release ~= "somewm" then
+ fresnel = require "ui.fresnel"
+end
local gtable = require "gears.table"
local gtimer = require "gears.timer"
local insightful = require "ui.insightful"
@@ -13,6 +16,7 @@ local playerctl = require "services.playerctl"
local powermenu = require "ui.powermenu"
local qbind = require "quarrel.bind"
local dnd = require "services.dnd"
+-- local osd = require "ui.osd"
local recording = { false, "" }
@@ -30,6 +34,17 @@ client.connect_signal("request::default_mousebindings", function()
},
qbind {
mods = qbind.mods.M,
+ triggers = qbind.btns.middle,
+ press = function(c)
+ c:activate {
+ context = "mouse_click",
+ }
+ end,
+ group = "client",
+ desc = "raise client",
+ },
+ qbind {
+ mods = qbind.mods.M,
triggers = qbind.btns.left,
press = function(c)
c:activate {
@@ -115,6 +130,15 @@ awful.keyboard.append_global_keybindings {
group = "awesome",
desc = "toggle insightful",
},
+ -- qbind {
+ -- mods = qbind.mods.M,
+ -- triggers = "u",
+ -- press = function()
+ -- osd:toggle()
+ -- end,
+ -- group = "awesome",
+ -- desc = "toggle osd",
+ -- },
qbind {
mods = qbind.mods.M,
triggers = "space",
@@ -229,7 +253,7 @@ awful.keyboard.append_global_keybindings {
mods = qbind.mods.M,
triggers = "Return",
press = function()
- awful.spawn(cfg.terminal)
+ awful.spawn("xdg-terminal-exec")
end,
group = "launcher",
desc = "launch terminal",
@@ -293,7 +317,7 @@ awful.keyboard.append_global_keybindings {
else
recording[1] = true
recording[2] = os.getenv "HOME" .. "/Videos/" .. os.date "%Y%m%d_%H%M%S" .. ".mp4"
- awful.spawn("giph --format mp4 --framerate 30 " .. recording[2])
+ awful.spawn("giph -a --format mp4 --framerate 30 " .. recording[2])
naughty.notification {
app_name = "Giph",
title = "Recording started",
diff --git a/.config/awesome/misc/rules.lua b/.config/awesome/misc/rules.lua
index 18b11f1..3f59929 100644
--- a/.config/awesome/misc/rules.lua
+++ b/.config/awesome/misc/rules.lua
@@ -54,6 +54,18 @@ ruled.client.connect_signal("request::rules", function()
},
{
+ id = "dragon-drop",
+ rule = {
+ class = "Dragon-drop"
+ },
+ properties = {
+ ontop = true,
+ sticky = true,
+ floating = true
+ }
+ },
+
+ {
id = "browser_tag",
rule_any = {
instance = { "Navigator" },
diff --git a/.config/awesome/prismite.lua b/.config/awesome/prismite.lua
index b9423e8..610ab9b 100644
--- a/.config/awesome/prismite.lua
+++ b/.config/awesome/prismite.lua
@@ -25,6 +25,10 @@ theme.border_normal = qcolor.palette.border()
theme.border_focus = qcolor.palette.border()
theme.border_marked = qcolor.palette.border()
+theme.snap_bg = qcolor.palette.yellow()
+theme.snap_border_width = qui.BORDER_WIDTH * 2
+theme.snap_shape = qui.shape
+
theme.notification_icon_size = dpi(32)
theme.notification_border_width = qui.BORDER_WIDTH
theme.notification_border_color = theme.border_normal
diff --git a/.config/awesome/quarrel/native/Cargo.toml b/.config/awesome/quarrel/native/Cargo.toml
index 1b98681..8d1bd80 100644
--- a/.config/awesome/quarrel/native/Cargo.toml
+++ b/.config/awesome/quarrel/native/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "qnative"
version = "0.1.0"
-edition = "2021"
+edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/.config/awesome/quarrel/native/src/lenses/application.rs b/.config/awesome/quarrel/native/src/lenses/application.rs
index 38a7762..cc12e82 100644
--- a/.config/awesome/quarrel/native/src/lenses/application.rs
+++ b/.config/awesome/quarrel/native/src/lenses/application.rs
@@ -3,13 +3,13 @@ use std::{
fs::read_dir,
path::PathBuf,
sync::{
+ Arc,
+ OnceLock,
+ RwLock,
atomic::{
AtomicBool,
Ordering,
},
- Arc,
- OnceLock,
- RwLock,
},
};
@@ -20,7 +20,10 @@ use rayon::prelude::*;
use url::Url;
use crate::lenses::{
- Cache, Entries, Entry, Lense
+ Cache,
+ Entries,
+ Entry,
+ Lense,
};
static APPS_DIR: &'static str = "/usr/share/applications";
@@ -34,6 +37,7 @@ pub struct Application {
impl Lense for Application {
const NAME: &str = "Application";
+ const PREFIX: Option<&'static str> = None;
fn init() -> Arc<Self> {
let this = Arc::new(Application::default());
@@ -94,7 +98,7 @@ impl Lense for Application {
// self.should_interrupt.load(Ordering::Relaxed)
}
- fn entries(&self, _: &Lua, _: String) -> Result<Entries, anyhow::Error> {
+ fn entries(&self, _: &Lua, _: &str) -> Result<Entries, anyhow::Error> {
let entries = read_dir(APPS_DIR)?
.map(|result| result.map(|e| e.path()))
.collect::<Result<Vec<_>, std::io::Error>>()?;
diff --git a/.config/awesome/quarrel/native/src/lenses/calculator.rs b/.config/awesome/quarrel/native/src/lenses/calculator.rs
index 36f9805..a483d10 100644
--- a/.config/awesome/quarrel/native/src/lenses/calculator.rs
+++ b/.config/awesome/quarrel/native/src/lenses/calculator.rs
@@ -1,22 +1,25 @@
use std::sync::{
+ Arc,
+ LazyLock,
+ Mutex,
atomic::{
AtomicBool,
Ordering,
},
- Arc,
- LazyLock,
- Mutex,
};
use fend_core::{
- evaluate_with_interrupt,
Context,
Interrupt,
+ evaluate_with_interrupt,
};
use mlua::prelude::*;
use crate::lenses::{
- Cache, Entries, Entry, Lense
+ Cache,
+ Entries,
+ Entry,
+ Lense,
};
static CTX: LazyLock<Mutex<Context>> = LazyLock::new(|| {
@@ -32,6 +35,7 @@ pub struct Calculator {
impl Lense for Calculator {
const NAME: &str = "Calculator";
+ const PREFIX: Option<&'static str> = Some("#");
fn init() -> std::sync::Arc<Self> {
Arc::new(Calculator::default())
@@ -55,18 +59,14 @@ impl Lense for Calculator {
self.should_interrupt.load(Ordering::Relaxed)
}
- fn entries(&self, _: &Lua, input: String) -> Result<Entries, anyhow::Error> {
+ fn entries(&self, _: &Lua, input: &str) -> Result<Entries, anyhow::Error> {
let result = match evaluate_with_interrupt(
input.trim(),
&mut CTX.lock().expect("Failed to acquire Fend context lock"),
self,
) {
- Ok(result) => {
- result.get_main_result().to_string()
- }
- Err(err) => {
- err
- }
+ Ok(result) => result.get_main_result().to_string(),
+ Err(err) => err,
};
Ok(if result.is_empty() {
@@ -77,11 +77,10 @@ impl Lense for Calculator {
exec: None,
})
})
-
}
#[inline]
- fn filter(&self, entries: Entries, _: String) -> Entries {
+ fn filter(&self, entries: Entries, _: &str) -> Entries {
entries
}
}
diff --git a/.config/awesome/quarrel/native/src/lenses/mod.rs b/.config/awesome/quarrel/native/src/lenses/mod.rs
index bb7f727..0b7864e 100644
--- a/.config/awesome/quarrel/native/src/lenses/mod.rs
+++ b/.config/awesome/quarrel/native/src/lenses/mod.rs
@@ -5,8 +5,8 @@ use std::sync::Arc;
use itertools::Itertools;
use mlua::{
- prelude::*,
LuaSerdeExt,
+ prelude::*,
};
use rayon::iter::FromParallelIterator;
use serde::{
@@ -18,7 +18,7 @@ use serde::{
pub enum Entries {
Multiple(Vec<Entry>),
Single(Entry),
- None
+ None,
}
impl FromIterator<Entry> for Entries {
@@ -32,7 +32,7 @@ impl FromIterator<Entry> for Entries {
let mut vec = Vec::from([first, second]);
vec.extend(iter);
Self::Multiple(vec)
- },
+ }
}
}
}
@@ -44,8 +44,8 @@ impl From<Vec<Entry>> for Entries {
1 => {
let entry = entries.into_iter().exactly_one().unwrap();
Self::Single(entry)
- },
- _ => Self::Multiple(entries)
+ }
+ _ => Self::Multiple(entries),
}
}
}
@@ -55,7 +55,7 @@ impl IntoLua for Entries {
match self {
Entries::Multiple(entries) => entries.into_lua(lua),
Entries::Single(entry) => entry.into_lua(lua),
- Entries::None => Ok(LuaValue::Nil)
+ Entries::None => Ok(LuaValue::Nil),
}
}
}
@@ -89,6 +89,7 @@ pub struct _Lense<T: Lense>(pub Arc<T>);
pub trait Lense {
const NAME: &'static str;
+ const PREFIX: Option<&'static str>;
fn init() -> Arc<Self>;
@@ -98,51 +99,70 @@ pub trait Lense {
fn set_interrupt(&self, interrupt: bool);
fn get_interrupt(&self) -> bool;
- fn entries(&self, lua: &Lua, input: String) -> Result<Entries, anyhow::Error>;
- fn filter(&self, entries: Entries, input: String) -> Entries {
- let entry_contains = |entry: &Entry| {
- entry.message.to_lowercase().contains(&input.to_lowercase())
- };
+ fn entries(&self, lua: &Lua, input: &str) -> Result<Entries, anyhow::Error>;
+ fn filter(&self, entries: Entries, input: &str) -> Entries {
+ let entry_contains =
+ |entry: &Entry| entry.message.to_lowercase().contains(&input.to_lowercase());
match entries {
- Entries::Multiple(entries) => entries.into_iter()
- .filter(entry_contains)
- .collect(),
- Entries::Single(entry) => if entry_contains(&entry) { Entries::Single(entry) } else { Entries::None }
- Entries::None => Entries::None
+ Entries::Multiple(entries) => entries.into_iter().filter(entry_contains).collect(),
+ Entries::Single(entry) => {
+ if entry_contains(&entry) {
+ Entries::Single(entry)
+ } else {
+ Entries::None
+ }
+ }
+ Entries::None => Entries::None,
}
}
}
impl<T: Lense + 'static> LuaUserData for _Lense<T> {
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
- fields.add_field_method_get("stale", |_, this| {
- Ok(matches!(this.0.get_cache(), Cache::Stale))
+ fields.add_field_method_get("stale", |_, Self(this)| {
+ Ok(matches!(this.get_cache(), Cache::Stale))
});
fields.add_field("name", T::NAME);
}
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
- methods.add_method_mut("query", |lua, this, input: String| {
- this.0.set_interrupt(false); // reset interrupt so that we can use the lense again
- return Ok(match this.0.get_cache() {
- Cache::Valid(entries) => this.0.filter(entries.clone(), input),
- Cache::Stale => {
- let entries = this.0.entries(lua, input.clone()).map_err(LuaError::external)?;
- let mut entries = this.0.filter(entries, input);
- match entries {
- Entries::Multiple(ref mut entries) => entries.sort_by(|a, b| a.message.cmp(&b.message)),
- _ => {}
- }
- this.0.set_cache(Cache::Valid(entries.clone()));
- entries
+ methods.add_method_mut("query", |lua, Self(this), input: String| {
+ if T::PREFIX.is_some_and(|prefix| input.starts_with(prefix)) || T::PREFIX.is_none() {
+ let input = if let Some(prefix) = T::PREFIX {
+ input.trim_start_matches(prefix)
+ } else {
+ &input
}
- });
+ .trim();
+
+ this.set_interrupt(false); // reset interrupt so that we can use the lense again
+
+ return Ok(match this.get_cache() {
+ Cache::Valid(entries) => this.filter(entries.clone(), input),
+ Cache::Stale => {
+ let entries = this.entries(lua, input).map_err(LuaError::external)?;
+ let mut entries = this.filter(entries, input);
+ match entries {
+ Entries::Multiple(ref mut entries) => {
+ entries.sort_by(|a, b| a.message.cmp(&b.message))
+ }
+ _ => {}
+ }
+ this.set_cache(Cache::Valid(entries.clone()));
+ entries
+ }
+ });
+ } else {
+ return Ok(Entries::None);
+ }
});
- methods.add_method_mut("mark_stale", |_, this, _: ()| {
- Ok(this.0.set_cache(Cache::Stale))
+ methods.add_method_mut("mark_stale", |_, Self(this), _: ()| {
+ Ok(this.set_cache(Cache::Stale))
+ });
+ methods.add_method_mut("interrupt", |_, Self(this), _: ()| {
+ Ok(this.set_interrupt(true))
});
- methods.add_method_mut("interrupt", |_, this, _: ()| Ok(this.0.set_interrupt(true)));
}
}
diff --git a/.config/awesome/quarrel/native/src/net/mod.rs b/.config/awesome/quarrel/native/src/net/mod.rs
index 383e800..728e6ec 100644
--- a/.config/awesome/quarrel/native/src/net/mod.rs
+++ b/.config/awesome/quarrel/native/src/net/mod.rs
@@ -20,21 +20,21 @@ use nix::{
ioctl_read_bad,
libc::IF_NAMESIZE,
sys::socket::{
- socket as open_socket,
AddressFamily,
SockFlag,
SockType,
+ socket as open_socket,
},
unistd::close,
};
use wireless::{
+ IW_ESSID_MAX_SIZE,
IfConf,
IfConfData,
IwPoint,
IwReq,
IwReqData,
IwReqName,
- IW_ESSID_MAX_SIZE,
SIOCGIFCONF,
SIOCGIWESSID,
};
diff --git a/.config/awesome/quarrel/native/src/net/wireless.rs b/.config/awesome/quarrel/native/src/net/wireless.rs
index d3999db..3500751 100644
--- a/.config/awesome/quarrel/native/src/net/wireless.rs
+++ b/.config/awesome/quarrel/native/src/net/wireless.rs
@@ -7,11 +7,11 @@ use std::ffi::{
use nix::libc::{
__s16,
__s32,
- __u16,
__u8,
+ __u16,
+ IF_NAMESIZE,
ifreq as IfReq,
sockaddr as SockAddr,
- IF_NAMESIZE,
};
pub static SIOCGIFCONF: c_int = 0x8912;
diff --git a/.config/awesome/quarrel/ui/init.lua b/.config/awesome/quarrel/ui/init.lua
index 5e68b1d..7ba6a58 100644
--- a/.config/awesome/quarrel/ui/init.lua
+++ b/.config/awesome/quarrel/ui/init.lua
@@ -4,7 +4,9 @@ local gshape = require "gears.shape"
local gtable = require "gears.table"
local qbind = require "quarrel.bind"
local qcolor = require "quarrel.color"
+local qdelegate = require "quarrel.delegate"
local wibox = require "wibox"
+local cairo = require("lgi").cairo
--- Clip Cairo context
---@param cr cairo_surface Cairo surface
@@ -199,4 +201,89 @@ function M.hoverable(widget, cursor)
return widget
end
+---@param wibox wibox
+function M.animateable_shape(wibox)
+ local old_apply_shape = wibox._apply_shape
+
+ wibox:disconnect_signal("property::geometry", old_apply_shape)
+ wibox:disconnect_signal("property::border_width", old_apply_shape)
+
+ function wibox:set_shape_width(value)
+ self._shape_width = value
+ self:emit_signal("property::shape_width")
+ end
+
+ function wibox:get_shape_width(value)
+ return self._shape_width
+ end
+
+ function wibox:set_shape_height(value)
+ self._shape_height = value
+ self:emit_signal("property::shape_height")
+ end
+
+ function wibox:get_shape_height(value)
+ return self._shape_height
+ end
+
+ -- override to allow us to override shape
+ wibox._apply_shape = qdelegate(function(env, self)
+ local shape = self._shape
+
+ if not shape then
+ self.shape_bounding = nil
+ self.shape_clip = nil
+ return
+ end
+
+ local geo = self:geometry()
+ local bw = self.border_width
+
+ if self.shape_width then
+ geo.width = self.shape_width
+ end
+
+ if self.shape_height then
+ geo.height = self.shape_height
+ end
+
+ -- First handle the bounding shape (things including the border)
+ local img = cairo.ImageSurface(cairo.Format.A1, geo.width + 2*bw, geo.height + 2*bw)
+ local cr = cairo.Context(img)
+
+ -- We just draw the shape in its full size
+ shape(cr, geo.width + 2*bw, geo.height + 2*bw)
+ cr:set_operator(cairo.Operator.SOURCE)
+ cr:fill()
+ self.shape_bounding = img._native
+ img:finish()
+
+ -- Now handle the clip shape (things excluding the border)
+ img = cairo.ImageSurface(cairo.Format.A1, geo.width, geo.height)
+ cr = cairo.Context(img)
+
+ -- We give the shape the same arguments as for the bounding shape and draw
+ -- it in its full size (the translate is to compensate for the smaller
+ -- surface)
+ cr:translate(-bw, -bw)
+ shape(cr, geo.width + 2*bw, geo.height + 2*bw)
+ cr:set_operator(cairo.Operator.SOURCE)
+ cr:fill_preserve()
+ -- Now we remove an area of width 'bw' again around the shape (We use 2*bw
+ -- since half of that is on the outside and only half on the inside)
+ cr:set_source_rgba(0, 0, 0, 0)
+ cr:set_line_width(2*bw)
+ cr:stroke()
+ self.shape_clip = img._native
+ img:finish()
+ end, old_apply_shape)
+
+ wibox:connect_signal("property::geometry", wibox._apply_shape)
+ wibox:connect_signal("property::border_width", wibox._apply_shape)
+ wibox:connect_signal("property::shape_width", wibox._apply_shape)
+ wibox:connect_signal("property::shape_height", wibox._apply_shape)
+
+ return wibox
+end
+
return M
diff --git a/.config/awesome/services/mpris/consts.lua b/.config/awesome/services/mpris/consts.lua
new file mode 100644
index 0000000..e86e50e
--- /dev/null
+++ b/.config/awesome/services/mpris/consts.lua
@@ -0,0 +1,13 @@
+local M = {}
+
+M.EXCLUDED_PLAYERS = {}
+
+M.TRACKED_METADATA = {
+ length = "mpris:length",
+ album = "xesam:album",
+ title = "xesam:title",
+ artist = "xesam:artist",
+ art = "mpris:artUrl",
+}
+
+return M
diff --git a/.config/awesome/services/mpris/init.lua b/.config/awesome/services/mpris/init.lua
index 3659a3a..1c907e7 100644
--- a/.config/awesome/services/mpris/init.lua
+++ b/.config/awesome/services/mpris/init.lua
@@ -1,100 +1,132 @@
local gobject = require "gears.object"
local playerctl = require "services.mpris.playerctl"
local qpersistent = require "quarrel.persistent"
+local playerctl = require("lgi").Playerctl
---@class ServiceMpris : gears.object
----@field inner Playerctl
---@field index number the index of the currently active player
-local M = {}
+---@field manager lgi.Playerctl.PlayerManager
+local M = { object = {} }
----@param self ServiceMpris
----@param player Playerctl.data
-local function update_player(self, player)
- self:emit_signal("player::metadata", player)
- self:emit_signal("player::position", player)
- -- handle_position(nil, player)
+---@class WrappedPlayer : gears.object
+---@field inner lgi.Playerctl.Player
+---@field _position_timer gears.timer
+
+---@param self WrappedPlayer
+function M.object:_update_position(by_user)
+ self:emit_signal("property::position", by_user)
end
----@param diff_player Playerctl.data
-local function recalculate_active_player(diff_player, vanished)
- if type(diff_player) ~= "table" then
- return
+---@param self WrappedPlayer
+function M.object:_update_position_timer()
+ if self.inner.playback_status == "PLAYING" then
+ self._position_timer:again()
+ else
+ self._position_timer:stop()
end
- -- if #layout.children == 0 then
- -- M.active_player_index = 1
- -- update_player()
- -- return
- -- end
+end
- local active_player = players[M.active_player_index]
- if not active_player then -- we're recovering from a state with no players
- update_player(diff_player)
- return
- end
+---@param self WrappedPlayer
+---@param value boolean
+function M.object:set_shuffle(value)
+ self.inner:set_shuffle(value)
+end
- if diff_player.instance == active_player.instance and vanished then -- active player vanished; fall back to previous player
- M.previous_player()
- else -- non-active player appeared/vanished; try to find active player
- for i, p in ipairs(playerctl:list()) do
- if p.instance == active_player.instance then
- M.active_player_index = i
- update_player(p)
- return
- end
- end
+---@param self WrappedPlayer
+---@param value number
+function M.object:set_volume(value)
+ self.inner:set_volume(value)
+end
- gdebug.print_warning(
- "failed to find active player:\n " .. gdebug.dump_return(active_player, nil, 2):gsub("\n", "\n ")
- )
- M.active_player_index = 1
- update_player(playerctl:list()[M.active_player_index])
- end
+---@param self WrappedPlayer
+---@param value integer
+function M.object:set_position(value)
+ self.inner:set_position(value)
+end
+
+---@param self WrappedPlayer
+---@param value lgi.Playerctl.LoopStatus
+function M.object:set_loop_status(value)
+ self.inner:set_loop_status(value)
+end
+
+---@param self WrappedPlayer
+function M.object:play_pause()
+ self.inner:play_pause()
+end
+
+---@param self WrappedPlayer
+function M.object:play()
+ self.inner:play()
+end
+
+---@param self WrappedPlayer
+function M.object:pause()
+ self.inner:pause()
end
-function M:next_player()
- local players = self.inner:list()
+---@param self WrappedPlayer
+function M.object:stop()
+ self.inner:stop()
+end
- if #players == 0 then
- return
- elseif self.index + 1 > #players then
- self.index = 1
+---@param self WrappedPlayer
+function M.object:previous()
+ self.inner:previous()
+end
+
+---@param self WrappedPlayer
+function M.object:next()
+ self.inner:next()
+end
+
+---@param self Playerctl
+---@param player_a lgi.Playerctl.Player
+---@param player_b lgi.Playerctl.Player
+---@return sign
+local function compare_players(self, player_a, player_b)
+ if player_a.player_name < player_b.player_name then
+ return -1
+ elseif player_a.player_name > player_b.player_name then
+ return 1
else
- self.index = self.index + 1
+ return 0
end
+end
+
+local function manage_player(self, full_name)
+ local player = playerctl.Player.new_from_name(full_name)
- -- update_player(playerctl:list()[M.active_player_index])
- local player = players[self.index]
- self:emit_signal("player::metadata", player)
- self:emit_signal("player::position", player)
+ function player.on_metadata(p, metadata)
+
+ end
end
-function M:previous_player()
- local players = self.inner:list()
- if #players == 0 then
- return
- elseif self.index - 1 < #players then
- self.index = #players
- else
- self.index = self.index - 1
+local function init_manager(self)
+ self.manager = playerctl.PlayerManager()
+ self.manager:set_sort_func(function(a, b)
+ local player_a = playerctl.Player(a)
+ local player_b = playerctl.Player(b)
+ return compare_players(self, player_a, player_b)
+ end)
+
+ function self.manager.on_name_appeared(_, full_name)
+
+ end
+
+ function self.manager.on_player_appeared()
+
end
+end
+
+local function new()
+ local self = gobject {}
+
+ init_manager(self)
- local player = players[self.index]
- self:emit_signal("player::metadata", player)
- self:emit_signal("player::position", player)
+ return self
end
-M.inner = playerctl.new {
- players = {},
- metadata = {
- album = "xesam:album",
- title = "xesam:title",
- artist = "xesam:artist",
- art = "mpris:artUrl",
- },
-}
+local instance = new()
-local instance = gobject { class = M }
-instance:connect_signal("property::index", function(self, index)
- qpersistent.store("active_player_index", self.index)
-end)
return instance
diff --git a/.config/awesome/services/osd.lua b/.config/awesome/services/osd.lua
index c4fa3e7..1851016 100644
--- a/.config/awesome/services/osd.lua
+++ b/.config/awesome/services/osd.lua
@@ -1,7 +1,25 @@
+local gobject = require "gears.object"
local battery = require "services.battery"
local osd = require "ui.osd"
local phosphor = require "assets.phosphor"
+local inner = false
+
+local M = gobject {
+ class = {
+ set_dnd = function(self, value)
+ inner = value
+ self:emit_signal("dnd", inner)
+ end,
+ get_dnd = function()
+ return inner
+ end
+ },
+ enable_properties = true,
+}
+
+return M
+
-- battery:connect_signal("icon", function (self, icon, _)
-- osd.notify(icon, self.level, 100)
-- end)
diff --git a/.config/awesome/services/wifi.lua b/.config/awesome/services/wifi.lua
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.config/awesome/services/wifi.lua
diff --git a/.config/awesome/ui/fresnel/init.lua b/.config/awesome/ui/fresnel/init.lua
index dc8e333..613bc9c 100644
--- a/.config/awesome/ui/fresnel/init.lua
+++ b/.config/awesome/ui/fresnel/init.lua
@@ -1,7 +1,5 @@
local text_input = require "ui.fresnel.text_input"
local awful = require "awful"
-local qdebug = require "quarrel.debug"
-local cfg = require "misc.cfg"
local gshape = require "gears.shape"
local gtable = require "gears.table"
local qanim = require "quarrel.animation"
@@ -152,7 +150,7 @@ function fresnel:_exec_entry(entry)
local exec = entry.exec
if type(exec) ~= "userdata" and type(exec) ~= "nil" then
if exec[2] then
- awful.spawn(cfg.terminal .. " -e /bin/sh -c " .. exec[1] .. " 1>/dev/null 2>&1")
+ awful.spawn.with_shell("xdg-terminal-exec /bin/sh -c '" .. exec[1]:gsub("'", [[\']]) .. "' 1>/dev/null 2>&1")
else
awful.spawn.with_shell(exec[1] .. " 1>/dev/null 2>&1")
end
@@ -318,17 +316,17 @@ fresnel._w_status = wibox.widget {
widget = wibox.widget.textbox,
text = "0/0",
}
-fresnel._w_popup = qui.popup {
+fresnel._w_popup = qui.animateable_shape(qui.popup {
-- visible = false,
ontop = true,
placement = false,
- shape = function(cr, w)
- gshape.partially_rounded_rect(cr, w, 0, false, false, true, true, qui.BORDER_RADIUS)
+ shape = function(cr, w, h)
+ gshape.partially_rounded_rect(cr, w, h, false, false, true, true, qui.BORDER_RADIUS)
end,
x = width / 2,
+ y = -qui.BORDER_WIDTH,
minimum_width = width,
maximum_width = width,
- -- maximum_height = max_height,
widget = {
qui.styled {
widget = wibox.container.background,
@@ -373,7 +371,7 @@ fresnel._w_popup = qui.popup {
},
layout = wibox.layout.align.vertical,
},
-}
+})
function fresnel:show()
self._prev_scroll_amount = DEFAULT_SCROLL_AMOUNT
@@ -406,13 +404,10 @@ fresnel._t_height = qanim:new {
pos = 0,
easing = qvars.easing,
subscribed = function(pos)
- fresnel._w_popup.shape = function(cr, w)
- gshape.partially_rounded_rect(cr, w, pos, false, false, true, true, qui.BORDER_RADIUS)
- end
+ fresnel._w_popup.shape_height = pos
end,
}
--- TODO: optimize the search algo to be more efficient and not require making fresnel invisible
fresnel._t_opacity = rubato.timed {
duration = qvars.anim_duration,
pos = 0,
diff --git a/.config/awesome/ui/fresnel/text_input.lua b/.config/awesome/ui/fresnel/text_input.lua
index 2dc7368..5b6525b 100644
--- a/.config/awesome/ui/fresnel/text_input.lua
+++ b/.config/awesome/ui/fresnel/text_input.lua
@@ -3,8 +3,8 @@
-- @copyright 2021-2025 Kasper24
-------------------------------------------
local lgi = require('lgi')
-local Gtk = lgi.require('Gtk', '3.0')
-local Gdk = lgi.require('Gdk', '3.0')
+local Gtk = lgi.require('Gtk', '3.0')-- somewm:ignore
+local Gdk = lgi.require('Gdk', '3.0')-- somewm:ignore
local Pango = lgi.Pango
local awful = require("awful")
local gtable = require("gears.table")
diff --git a/.config/awesome/ui/osd/init.lua b/.config/awesome/ui/osd/init.lua
index 4310f17..85cb1d7 100644
--- a/.config/awesome/ui/osd/init.lua
+++ b/.config/awesome/ui/osd/init.lua
@@ -4,24 +4,49 @@ local gtimer = require "gears.timer"
local phosphor = require "assets.phosphor"
local qmath = require "quarrel.math"
local qui = require "quarrel.ui"
+local qdebug = require "quarrel.debug"
+local gshape = require "gears.shape"
+local qanim = require "quarrel.animation"
local qvars = require "quarrel.vars"
local rubato = require "lib.rubato"
local wibox = require "wibox"
-- local mpris_widget = require "ui.osd.mpris"
-local osd = {}
+local MAX_HEIGHT = qui.BIG_PADDING * 2 + qui.CHAR_HEIGHT
-local widget = awful.popup(qui.styled {
+local M = {
+ _toggled = false
+}
+
+local geo = awful.screen.focused().geometry
+
+M._w_popup = qui.animateable_shape(qui.popup {
ontop = true,
visible = true,
- placement = function(d)
- awful.placement.top(d, {
- margins = {
- top = beautiful.useless_gap * 2,
- },
+ shape = function(cr, w, h)
+ gshape.partially_rounded_rect(cr, w, h, true, true, false, false, qui.BORDER_RADIUS)
+ end,
+ placement = function (d)
+ return (awful.placement.bottom + awful.placement.center_horizontal)(d, {
+ offset = {
+ y = qui.BORDER_WIDTH + 1 -- Needs one more pixel to fully occlude the bottom border for some reason
+ }
})
end,
- minimum_height = qui.CHAR_HEIGHT * 3,
+ -- placement = function(d)
+ -- awful.placement.bottom(d, {
+ -- margins = {
+ -- top = beautiful.useless_gap * 2,
+ -- },
+ -- })
+ -- end,
+ -- x = geo.width / 2,
+ -- y = geo.height - 10,
+ minimum_height = qui.CHAR_HEIGHT,
+ widget = {
+ widget = wibox.widget.textbox,
+ text = "blah"
+ }
-- widget = mpris_widget
-- minimum_width = awful.screen.focused().geometry.width / 2,
-- widget = {
@@ -65,38 +90,85 @@ local widget = awful.popup(qui.styled {
-- },
})
-local timer
+M._t_height = qanim:new {
+ duration = qvars.anim_duration,
+ pos = 0,
+ easing = qvars.easing,
+ subscribed = function(pos)
+ M._w_popup.shape_height = pos
+ end,
+}
-local anim = rubato.timed {
+-- TODO: optimize the search algo to be more efficient and not require making fresnel invisible
+M._t_opacity = rubato.timed {
duration = qvars.anim_duration,
- intro = qvars.anim_intro,
- pos = 1,
+ pos = 0,
subscribed = function(pos)
- widget.opacity = pos
+ M._w_popup.opacity = pos
+
if pos == 0 then
- widget.visible = false
- elseif not widget.visible then
- widget.visible = true
- elseif pos == 1 then
- -- timer:start()
+ M._w_popup.visible = false
+ else
+ M._w_popup.visible = true
end
end,
}
-timer = gtimer {
- timeout = 1,
- callback = function()
- -- anim.target = 0
- end,
- single_shot = true,
-}
+M._t_height:set(qui.BIG_PADDING * 2 + qui.CHAR_HEIGHT)
+M._t_opacity.target = 1
+
+function M:show()
+ self._toggled = true
+ self._t_opacity.target = 1
+ self._t_height:set(MAX_HEIGHT)
+end
-function osd.notify(icon, value, max)
- anim.target = 1
- widget:get_children_by_id("icon")[1].image = icon
- widget:get_children_by_id("progress")[1].value = value
- widget:get_children_by_id("progress")[1].max_value = max
- widget:get_children_by_id("percentage")[1].text = tostring(qmath.percentage(value, max)) .. "%"
+function M:hide()
+ self._toggled = false
+ self._t_opacity.target = 0
+ self._t_height:set(0)
end
-return osd
+function M:toggle()
+ if self._toggled then
+ self:hide()
+ else
+ self:show()
+ end
+end
+
+-- local timer
+--
+-- local anim = rubato.timed {
+-- duration = qvars.anim_duration,
+-- intro = qvars.anim_intro,
+-- pos = 1,
+-- subscribed = function(pos)
+-- widget.opacity = pos
+-- if pos == 0 then
+-- widget.visible = false
+-- elseif not widget.visible then
+-- widget.visible = true
+-- elseif pos == 1 then
+-- -- timer:start()
+-- end
+-- end,
+-- }
+--
+-- timer = gtimer {
+-- timeout = 1,
+-- callback = function()
+-- -- anim.target = 0
+-- end,
+-- single_shot = true,
+-- }
+
+-- function M.notify(icon, value, max)
+-- anim.target = 1
+-- widget:get_children_by_id("icon")[1].image = icon
+-- widget:get_children_by_id("progress")[1].value = value
+-- widget:get_children_by_id("progress")[1].max_value = max
+-- widget:get_children_by_id("percentage")[1].text = tostring(qmath.percentage(value, max)) .. "%"
+-- end
+
+return M
diff --git a/.config/awesome/ui/statusbar/init.lua b/.config/awesome/ui/statusbar/init.lua
index 0a1198a..baaf2fa 100644
--- a/.config/awesome/ui/statusbar/init.lua
+++ b/.config/awesome/ui/statusbar/init.lua
@@ -15,7 +15,7 @@ local keyboardlayout = require "ui.statusbar.widgets.keyboardlayout"
local taglist = require "ui.statusbar.widgets.taglist_new"
screen.connect_signal("request::desktop_decoration", function(s)
- local bar = qui.popup {
+ local bar = qui.animateable_shape(qui.popup {
placement = function(d)
return awful.placement.left(d, {
margins = beautiful.useless_gap * 2,
@@ -59,13 +59,14 @@ screen.connect_signal("request::desktop_decoration", function(s)
},
toggled = false,
- }
+ })
- local bar_width = bar.width + qui.BORDER_WIDTH * 2
+ local bar_width = bar.width
- bar.shape = function(cr, _, h)
- qui.shape(cr, bar_width, h)
- end
+ bar.shape_width = bar_width
+ -- bar.shape = function(cr, _, h)
+ -- qui.shape(cr, bar_width, h)
+ -- end
bar:struts {
left = bar_width + beautiful.useless_gap * 4,
@@ -73,20 +74,30 @@ screen.connect_signal("request::desktop_decoration", function(s)
bar.widget.widget.third = panel
+ local idle = true
+
local timed = qanim:new {
duration = qvars.anim_duration,
pos = bar_width,
easing = qvars.easing,
subscribed = function(pos)
- if pos ~= bar_width and bar.toggled then
+ if idle and pos ~= bar_width and bar.toggled then
bar.ontop = true
+ -- panel.visible = true
+ idle = false
elseif pos == bar_width and not bar.toggled then
bar.ontop = false
+ -- panel.visible = false
+ idle = true
+ elseif pos == bar_width + M.EXPANDED_BAR_SIZE then
+ idle = true
end
- bar.shape = function(cr, _, h)
- qui.shape(cr, pos, h)
- end
+ bar.shape_width = pos
+
+ -- bar.shape = function(cr, _, h)
+ --
+ -- end
end,
}
diff --git a/.config/awesome/ui/statusbar/panel/widgets/mpris.lua b/.config/awesome/ui/statusbar/panel/widgets/mpris.lua
index 687bbb1..f462ea3 100644
--- a/.config/awesome/ui/statusbar/panel/widgets/mpris.lua
+++ b/.config/awesome/ui/statusbar/panel/widgets/mpris.lua
@@ -99,106 +99,98 @@ M.widget = wibox.widget(qui.styled {
{
widget = client_background,
{
- nil,
- qui.padded_big {
+ nil,
+ qui.padded_big {
+ {
+ {
+ widget = wibox.widget.textbox,
+ text = DEFAULTS.progresstext.position .. " / " .. DEFAULTS.progresstext.length, -- position / length
+ id = "progresstext",
+ },
{
+ widget = wibox.container.place,
{
- widget = wibox.container.background,
- bg = qcolor.palette.bg(),
+ widget = wibox.widget.progressbar,
+ value = DEFAULTS.position,
+ max_value = DEFAULTS.length,
+ background_color = qcolor.palette.bg.lowest,
+ color = qcolor.palette.yellow(),
+ forced_height = qui.BORDER_RADIUS,
+ border_width = 0,
shape = qui.shape,
- {
- widget = wibox.widget.imagebox,
- image = DEFAULTS.art,
- forced_height = qui.CHAR_HEIGHT * 5,
- forced_width = qui.CHAR_HEIGHT * 5,
- valign = "center",
- halign = "center",
- stylesheet = qui.recolor(qcolor.palette.bg.highest),
- id = "cover",
- },
+ -- - forced_width = qui.CHAR_HEIGHT,
+ id = "progressbar",
},
+ },
+ layout = wibox.layout.fixed.horizontal,
+ spacing = qui.BIG_PADDING,
+ },
+ -- {
+ -- widget = wibox.container.background,
+ -- bg = qcolor.palette.bg(),
+ -- shape = qui.shape,
+ {
+ widget = wibox.widget.imagebox,
+ image = DEFAULTS.art,
+ forced_height = qui.CHAR_HEIGHT * 8,
+ forced_width = qui.CHAR_HEIGHT * 8,
+ valign = "center",
+ halign = "center",
+ stylesheet = qui.recolor(qcolor.palette.bg.highest),
+ clip_shape = qui.shape,
+ id = "cover",
+ },
+ -- },
+ {
+ {
+ widget = wibox.container.constraint,
+ height = qui.CHAR_HEIGHT * 2.5,
+ strategy = "max",
{
- widget = wibox.container.margin,
- left = qui.BIG_PADDING,
- {
- {
- widget = wibox.container.constraint,
- height = qui.CHAR_HEIGHT * 2.5,
- strategy = "max",
- {
- widget = wibox.widget.textbox,
- text = DEFAULTS.title, -- Song
- id = "song",
- valign = "top",
- },
- },
- {
- widget = wibox.container.constraint,
- height = qui.CHAR_HEIGHT * 2.5,
- strategy = "max",
- {
- widget = wibox.container.background,
- fg = qcolor.palette.fg.low,
- {
- widget = wibox.widget.textbox,
- text = DEFAULTS.artist_album, -- Artist - Album Name
- id = "artist_album",
- valign = "top",
- },
- },
- },
- layout = wibox.layout.fixed.vertical,
- },
+ widget = wibox.widget.textbox,
+ text = DEFAULTS.title, -- Song
+ id = "song",
+ valign = "top",
},
- layout = wibox.layout.fixed.horizontal,
},
- nil,
{
- widget = wibox.container.margin,
- top = qui.BIG_PADDING,
+ widget = wibox.container.constraint,
+ height = qui.CHAR_HEIGHT * 2.5,
+ strategy = "max",
{
+ widget = wibox.container.background,
+ fg = qcolor.palette.fg.low,
{
widget = wibox.widget.textbox,
- text = DEFAULTS.progresstext.position .. " / " .. DEFAULTS.progresstext.length, -- position / length
- id = "progresstext",
- },
- {
- widget = wibox.container.place,
- {
- widget = wibox.widget.progressbar,
- forced_height = qui.PADDING,
- color = qcolor.palette.yellow(),
- value = DEFAULTS.position,
- max_value = DEFAULTS.length,
- background_color = qcolor.palette.bg.lowest,
- bar_shape = qui.shape,
- shape = qui.shape,
- id = "progressbar",
- },
+ text = DEFAULTS.artist_album, -- Artist - Album Name
+ id = "artist_album",
+ valign = "top",
},
- layout = wibox.layout.fixed.horizontal,
- spacing = qui.BIG_PADDING,
},
},
- layout = wibox.layout.align.vertical,
+ layout = wibox.layout.fixed.vertical,
+ spacing = qui.PADDING
+ },
+ layout = wibox.layout.fixed.vertical,
+ spacing = qui.BIG_PADDING,
+ },
+ {
+ qui.separator {
+ size = qui.BORDER_WIDTH,
+ vertical = true
},
{
- qui.separator {
- size = qui.BORDER_WIDTH,
- vertical = true
- },
- {
- widget = wibox.container.background,
- bg = qcolor.palette.bg.high,
- qui.padded_big {
- layout = wibox.layout.flex.vertical,
- spacing = qui.BIG_PADDING,
- id = "client_list",
- }
- },
- layout = wibox.layout.fixed.horizontal,
+ widget = wibox.container.background,
+ bg = qcolor.palette.bg.high,
+ qui.padded_big {
+ layout = wibox.layout.flex.vertical,
+ spacing = qui.BIG_PADDING,
+ id = "client_list",
+ }
},
- layout = wibox.layout.align.horizontal,
+ layout = wibox.layout.fixed.horizontal,
+ },
+ layout = wibox.layout.align.horizontal,
},
},
})