This commit is contained in:
Luca 2022-11-22 13:25:44 +01:00
parent 8268fba83d
commit 7ed2a6e110
9565 changed files with 1315332 additions and 90 deletions

View file

@ -0,0 +1,23 @@
- [Home](home.md)
- [Layouts](layouts/layout.md)
- Modules
- [Flash Focus](module/flash.md)
- [Tabbed](module/tabbed.md)
- [Tiled Wallpaper](module/twall.md)
- [Wallpaper Easy Setup](module/wall.md)
- [Window Swallowing](module/swal.md)
- [Scratchpad](module/scratch.md)
- Signals
- [Playerctl](signals/pctl.md)
- Widgets
- [Tag Preview](widgets/tag_preview.md)
- [Task Preview](widgets/task_preview.md)
- [Tabbed Misc](widgets/tabbed_misc.md)
- [Window Switcher](widgets/window_switcher.md)
- Extra
- [Theme Variable Template](theme.md)

View file

@ -0,0 +1,34 @@
# <center> 🌟 Bling - Utilities for AwesomeWM 🌟 </center>
## Why
[AwesomeWM](https://awesomewm.org/) is literally what it stands for, an awesome window manager.
Its unique selling point has always been the widget system, which allows for fancy buttons, sliders, bars, dashboards and anything you can imagine. But that feature can be a curse. Most modules focus on the widget side of things which leave the actual window managing part of AwesomeWM underdeveloped compared to, for example, [xmonad](https://xmonad.org/) even though it's probably just as powerfull in that area.
This project focuses on that problem - adding new layouts and modules that make use of the widget system, but primarily focus on the new window managing features.
## Installation
- clone this repo into your `~/.config/awesome` folder
- `git clone https://github.com/BlingCorp/bling.git ~/.config/awesome/bling`
- require the module in your `rc.lua`, and make sure it's under the beautiful module initialization
```lua
-- other imports
local beautiful = require("beautiful")
-- other configuration stuff here
beautiful.init("some_theme.lua")
local bling = require("bling")
```
## Contributors
A special thanks to all our contributors...
<a href="https://github.com/BlingCorp/bling/graphs/contributors">
<img src="https://contrib.rocks/image?repo=BlingCorp/bling" />
</a>
Made with [contributors-img](https://contrib.rocks).

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bling Docs</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Utilities for the awesome window manager">
<meta name="og:image" content="https://raw.githubusercontent.com/BlingCorp/bling/master/images/bling_banner.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="javacafe.css">
</head>
<body>
<div id="app"></div>
<script>
window.$docsify = {
name: 'Bling',
nameLink: '/',
repo: 'https://github.com/BlingCorp/bling',
loadSidebar: true,
subMaxLevel: 3,
homepage: 'home.md'
}
</script>
<!-- Docsify v4 -->
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script src="//unpkg.com/prismjs/components/prism-lua.js"></script>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,65 @@
## 📎 Layouts <!-- {docsify-ignore} -->
Choose layouts from the list below and add them to to your `awful.layouts` list in your `rc.lua`.
Everyone of them supports multiple master clients and master width factor making them easy to use.
The mstab layout uses the tab theme from the tabbed module.
```lua
bling.layout.mstab
bling.layout.centered
bling.layout.vertical
bling.layout.horizontal
bling.layout.equalarea
bling.layout.deck
```
### Theme Variables
```lua
-- mstab
theme.mstab_bar_disable = false -- disable the tabbar
theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients
theme.mstab_dont_resize_slaves = false -- whether the tabbed stack windows should be smaller than the
-- currently focused stack window (set it to true if you use
-- transparent terminals. False if you use shadows on solid ones
theme.mstab_bar_padding = "default" -- how much padding there should be between clients and your tabbar
-- by default it will adjust based on your useless gaps.
-- If you want a custom value. Set it to the number of pixels (int)
theme.mstab_border_radius = 0 -- border radius of the tabbar
theme.mstab_bar_height = 40 -- height of the tabbar
theme.mstab_tabbar_position = "top" -- position of the tabbar (mstab currently does not support left,right)
theme.mstab_tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern")
-- defaults to the tabbar_style so only change if you want a
-- different style for mstab and tabbed
```
### Previews
#### Mstab (dynamic tabbing layout)
![](https://imgur.com/HZRgApE.png)
*screenshot by [JavaCafe01](https://github.com/JavaCafe01)*
#### Centered
![](https://media.discordapp.net/attachments/769673106842845194/780095998239834142/unknown.png)
*screenshot by [HeavyRain266](https://github.com/HeavyRain266)*
#### Equal area
![](https://imgur.com/JCFFywv.png)
*screenshot by [bysmutheye](https://github.com/bysmutheye)*
#### Deck
The left area shows the deck layout in action. In this screenshot it is used together with [layout machi](https://github.com/xinhaoyuan/layout-machi) and its sublayout support.
![](https://cdn.discordapp.com/attachments/635625954219261982/877957824225894430/unknown.png)
*screenshot by [JavaCafe01](https://github.com/JavaCafe01)*

View file

@ -0,0 +1,33 @@
## 🔦 Flash Focus <!-- {docsify-ignore} -->
Flash focus does an opacity animation effect on a client when it is focused.
### Usage
There are two ways in which you can use this module. You can enable it by calling the `enable()` function:
```lua
bling.module.flash_focus.enable()
```
This connects to the focus signal of a client, which means that the flash focus will activate however you focus the client.
The other way is to call the function itself like this: `bling.module.flash_focus.flashfocus(someclient)`. This allows you to activate on certain keybinds like so:
```lua
awful.key({modkey}, "Up",
function()
awful.client.focus.bydirection("up")
bling.module.flash_focus.flashfocus(client.focus)
end, {description = "focus up", group = "client"})
```
### Theme Variables
```lua
theme.flash_focus_start_opacity = 0.6 -- the starting opacity
theme.flash_focus_step = 0.01 -- the step of animation
```
### Preview
![](https://imgur.com/5txYrlV.gif)
*gif by [JavaCafe01](https://github.com/JavaCafe01)*

View file

@ -0,0 +1,75 @@
## 🍃 Scratchpad <!-- {docsify-ignore} -->
An easy way to create multiple scratchpads.
### A... what?
You can think about a scratchpad as a window whose visibility can be toggled, but still runs in the background without being visible (or minimized) most of the time. Many people use it to have one terminal in which to perform minor tasks, but it is the most useful for windows which only need a couple seconds in between your actual activity, such as music players or chat applications.
### Rubato Animation Support
#### Awestore is now deprecated from Bling, we are switching to Rubato.
Please go over to the [rubato](https://github.com/andOrlando/rubato) repository for installation instructions. Give it a star as well! The animations are completely optional, and if you choose not to use it, you do not need rubato installed.
### Usage
To initalize a scratchpad you can do something like the following:
```lua
local bling = require("bling")
local rubato = require("rubato") -- Totally optional, only required if you are using animations.
-- These are example rubato tables. You can use one for just y, just x, or both.
-- The duration and easing is up to you. Please check out the rubato docs to learn more.
local anim_y = rubato.timed {
pos = 1090,
rate = 60,
easing = rubato.quadratic,
intro = 0.1,
duration = 0.3,
awestore_compat = true -- This option must be set to true.
}
local anim_x = rubato.timed {
pos = -970,
rate = 60,
easing = rubato.quadratic,
intro = 0.1,
duration = 0.3,
awestore_compat = true -- This option must be set to true.
}
local term_scratch = bling.module.scratchpad {
command = "wezterm start --class spad", -- How to spawn the scratchpad
rule = { instance = "spad" }, -- The rule that the scratchpad will be searched by
sticky = true, -- Whether the scratchpad should be sticky
autoclose = true, -- Whether it should hide itself when losing focus
floating = true, -- Whether it should be floating (MUST BE TRUE FOR ANIMATIONS)
geometry = {x=360, y=90, height=900, width=1200}, -- The geometry in a floating state
reapply = true, -- Whether all those properties should be reapplied on every new opening of the scratchpad (MUST BE TRUE FOR ANIMATIONS)
dont_focus_before_close = false, -- When set to true, the scratchpad will be closed by the toggle function regardless of whether its focused or not. When set to false, the toggle function will first bring the scratchpad into focus and only close it on a second call
rubato = {x = anim_x, y = anim_y} -- Optional. This is how you can pass in the rubato tables for animations. If you don't want animations, you can ignore this option.
}
```
Once initalized, you can use the object (which in this case is named `term_scratch`) like this:
```lua
term_scratch:toggle() -- toggles the scratchpads visibility
term_scratch:turn_on() -- turns the scratchpads visibility on
term_scratch:turn_off() -- turns the scratchpads visibility off
```
You can also connect to signals as you are used to for further customization. For example like that:
```lua
term_scratch:connect_signal("turn_on", function(c) naughty.notify({title = "Turned on!"}) end)
```
The following signals are currently available. `turn_on`, `turn_off` and `inital_apply` pass the client on which they operated as an argument:
- `turn_on` fires when the scratchpad is turned on on a tag that it wasn't present on before
- `turn_off` fires when the scratchpad is turned off on a tag
- `spawn` fires when the scratchpad is launched with the given command
- `inital_apply` fires after `spawn`, when a corresponding client has been found and the properties have been applied

View file

@ -0,0 +1,25 @@
## 😋 Window Swallowing <!-- {docsify-ignore} -->
Can your window manager swallow? It probably can...
### Usage
To activate and deactivate window swallowing here are the following functions. If you want to activate it, just call the `start` function once in your `rc.lua`.
```lua
bling.module.window_swallowing.start() -- activates window swallowing
bling.module.window_swallowing.stop() -- deactivates window swallowing
bling.module.window_swallowing.toggle() -- toggles window swallowing
```
### Theme Variables
```lua
theme.parent_filter_list = {"firefox", "Gimp"} -- class names list of parents that should not be swallowed
theme.child_filter_list = { "Dragon" } -- class names list that should not swallow their parents
theme.swallowing_filter = true -- whether the filters above should be active
```
### Preview
![](https://media.discordapp.net/attachments/635625813143978012/769180910683684864/20-10-23-14-40-32.gif)
*gif by [Nooo37](https://github.com/Nooo37)*

View file

@ -0,0 +1,66 @@
## 📑 Tabbed <!-- {docsify-ignore} -->
Tabbed implements a tab container. There are also different themes for the tabs.
### Usage
You should bind these functions to keys in order to use the tabbed module effectively:
```lua
bling.module.tabbed.pick() -- picks a client with your cursor to add to the tabbing group
bling.module.tabbed.pop() -- removes the focused client from the tabbing group
bling.module.tabbed.iter() -- iterates through the currently focused tabbing group
bling.module.tabbed.pick_with_dmenu() -- picks a client with a dmenu application (defaults to rofi, other options can be set with a string parameter like "dmenu")
bling.module.tabbed.pick_by_direction(dir) -- picks a client based on direction ("up", "down", "left" or "right")
```
### Theme Variables
```lua
-- For tabbed only
theme.tabbed_spawn_in_tab = false -- whether a new client should spawn into the focused tabbing container
-- For tabbar in general
theme.tabbar_ontop = false
theme.tabbar_radius = 0 -- border radius of the tabbar
theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern")
theme.tabbar_font = "Sans 11" -- font of the tabbar
theme.tabbar_size = 40 -- size of the tabbar
theme.tabbar_position = "top" -- position of the tabbar
theme.tabbar_bg_normal = "#000000" -- background color of the focused client on the tabbar
theme.tabbar_fg_normal = "#ffffff" -- foreground color of the focused client on the tabbar
theme.tabbar_bg_focus = "#1A2026" -- background color of unfocused clients on the tabbar
theme.tabbar_fg_focus = "#ff0000" -- foreground color of unfocused clients on the tabbar
theme.tabbar_bg_focus_inactive = nil -- background color of the focused client on the tabbar when inactive
theme.tabbar_fg_focus_inactive = nil -- foreground color of the focused client on the tabbar when inactive
theme.tabbar_bg_normal_inactive = nil -- background color of unfocused clients on the tabbar when inactive
theme.tabbar_fg_normal_inactive = nil -- foreground color of unfocused clients on the tabbar when inactive
theme.tabbar_disable = false -- disable the tab bar entirely
-- the following variables are currently only for the "modern" tabbar style
theme.tabbar_color_close = "#f9929b" -- chnges the color of the close button
theme.tabbar_color_min = "#fbdf90" -- chnges the color of the minimize button
theme.tabbar_color_float = "#ccaced" -- chnges the color of the float button
```
### Preview
Modern theme:
<img src="https://imgur.com/omowmIQ.png" width="600"/>
*screenshot by [JavaCafe01](https://github.com/JavaCafe01)*
### Signals
The tabbed module emits a few signals for the purpose of integration,
```lua
-- bling::tabbed::update -- triggered whenever a tabbed object is updated
-- tabobj -- the object that caused the update
-- bling::tabbed::client_added -- triggered whenever a new client is added to a tab group
-- tabobj -- the object that the client was added to
-- client -- the client that added
-- bling::tabbed::client_removed -- triggered whenever a client is removed from a tab group
-- tabobj -- the object that the client was removed from
-- client -- the client that was removed
-- bling::tabbed::changed_focus -- triggered whenever a tab group's focus is changed
-- tabobj -- the modified tab group
```

View file

@ -0,0 +1,26 @@
## 🏬 Tiled Wallpaper <!-- {docsify-ignore} -->
### Usage
The function to set an automatically created tiled wallpaper can be called the following way (you don't need to set every option in the table):
```lua
awful.screen.connect_for_each_screen(function(s) -- that way the wallpaper is applied to every screen
bling.module.tiled_wallpaper("x", s, { -- call the actual function ("x" is the string that will be tiled)
fg = "#ff0000", -- define the foreground color
bg = "#00ffff", -- define the background color
offset_y = 25, -- set a y offset
offset_x = 25, -- set a x offset
font = "Hack", -- set the font (without the size)
font_size = 14, -- set the font size
padding = 100, -- set padding (default is 100)
zickzack = true -- rectangular pattern or criss cross
})
end)
```
### Preview
![](https://media.discordapp.net/attachments/702548913999314964/773887721294135296/tiled-wallpapers.png?width=1920&height=1080)
*screenshots by [Nooo37](https://github.com/Nooo37)*

View file

@ -0,0 +1,142 @@
## 🎇 Wallpaper Easy Setup <!-- {docsify-ignore} -->
This is a simple-to-use, extensible, declarative wallpaper manager.
### Practical Examples
```lua
-- A default Awesome wallpaper
bling.module.wallpaper.setup()
-- A slideshow with pictures from different sources changing every 30 minutes
bling.module.wallpaper.setup {
wallpaper = {"/images/my_dog.jpg", "/images/my_cat.jpg"},
change_timer = 1800
}
-- A random wallpaper with images from multiple folders
bling.module.wallpaper.setup {
set_function = bling.module.wallpaper.setters.random,
wallpaper = {"/path/to/a/folder", "/path/to/another/folder"},
change_timer = 631, -- prime numbers are better for timers
position = "fit",
background = "#424242"
}
-- wallpapers based on a schedule, like awesome-glorious-widgets dynamic wallpaper
-- https://github.com/manilarome/awesome-glorious-widgets/tree/master/dynamic-wallpaper
bling.module.wallpaper.setup {
set_function = bling.module.wallpaper.setters.simple_schedule,
wallpaper = {
["06:22:00"] = "morning-wallpaper.jpg",
["12:00:00"] = "noon-wallpaper.jpg",
["17:58:00"] = "night-wallpaper.jpg",
["24:00:00"] = "midnight-wallpaper.jpg",
},
position = "maximized",
}
-- random wallpapers, from different folder depending on time of the day
bling.module.wallpaper.setup {
set_function = bling.module.wallpaper.setters.simple_schedule,
wallpaper = {
["09:00:00"] = "~/Pictures/safe_for_work",
["18:00:00"] = "~/Pictures/personal",
},
schedule_set_function = bling.module.wallpaper.setters.random
position = "maximized",
recursive = false,
change_timer = 600
}
-- setup for multiple screens at once
-- the 'screen' argument can be a table of screen objects
bling.module.wallpaper.setup {
set_function = bling.module.wallpaper.setters.random,
screen = screen, -- The awesome 'screen' variable is an array of all screen objects
wallpaper = {"/path/to/a/folder", "/path/to/another/folder"},
change_timer = 631
}
```
### Details
The setup function will do 2 things: call the set-function when awesome requests a wallpaper, and manage a timer to call `set_function` periodically.
Its argument is a args table that is passed to ohter functions (setters and wallpaper functions), so you define everything with setup.
The `set_function` is a function called every times a wallpaper is needed.
The module provides some setters:
* `bling.module.wallpaper.setters.awesome_wallpaper`: beautiful.theme_assets.wallpaper with defaults from beautiful.
* `bling.module.wallpaper.setters.simple`: slideshow from the `wallpaper` argument.
* `bling.module.wallpaper.setters.random`: same as simple but in a random way.
* `bling.module.wallpaper.setters.simple_schedule`: takes a table of `["HH:MM:SS"] = wallpaper` arguments, where wallpaper is the `wallpaper` argument used by `schedule_set_function`.
A wallpaper is one of the following elements:
* a color
* an image
* a folder containing images
* a function that sets a wallpaper
* everything gears.wallpaper functions can manage (cairo surface, cairo pattern string)
* a list containing any of the elements above
To set up for multiple screens, two possible methods are:
* Call the `setup` function for each screen, passing the appropriate configuration and `screen` arg
* Call the `setup` function once, passing a table of screens as the `screen` arg. This applies the same configuration to all screens in the table
_Note_: Multiple screen setup only works for the `simple` and `random` setters
```lua
-- This is a valid wallpaper definition
bling.module.wallpaper.setup {
wallpaper = { -- a list
"black", "#112233", -- colors
"wall1.jpg", "wall2.png", -- files
"/path/to/wallpapers", -- folders
-- cairo patterns
"radial:600,50,100:105,550,900:0,#2200ff:0.5,#00ff00:1,#101010",
-- or functions that set a wallpaper
function(args) bling.module.tiled_wallpaper("\\o/", args.screen) end,
bling.module.wallpaper.setters.awesome_wallpaper,
},
change_timer = 10,
}
```
The provided setters `simple` and `random` will use 2 internal functions that you can use to write your own setter:
* `bling.module.wallpaper.prepare_list`: return a list of wallpapers directly usable by `apply` (for now, it just explores folders)
* `bling.module.wallpaper.apply`: a wrapper for gears.wallpaper functions, using the args table of setup
Here are the defaults:
```lua
-- Default parameters
bling.module.wallpaper.setup {
screen = nil, -- the screen to apply the wallpaper, as seen in gears.wallpaper functions
screens = nil, -- an array of screens to apply the wallpaper on. If 'screen' is also provided, this is overridden
change_timer = nil, -- the timer in seconds. If set, call the set_function every change_timer seconds
set_function = nil, -- the setter function
-- parameters used by bling.module.wallpaper.prepare_list
wallpaper = nil, -- the wallpaper object, see simple or simple_schedule documentation
image_formats = {"jpg", "jpeg", "png", "bmp"}, -- when searching in folder, consider these files only
recursive = true, -- when searching in folder, search also in subfolders
-- parameters used by bling.module.wallpaper.apply
position = nil, -- use a function of gears.wallpaper when applicable ("centered", "fit", "maximized", "tiled")
background = beautiful.bg_normal or "black", -- see gears.wallpaper functions
ignore_aspect = false, -- see gears.wallpaper.maximized
offset = {x = 0, y = 0}, -- see gears.wallpaper functions
scale = 1, -- see gears.wallpaper.centered
-- parameters that only apply to bling.module.wallpaper.setter.awesome (as a setter or as a wallpaper function)
colors = { -- see beautiful.theme_assets.wallpaper
bg = beautiful.bg_color, -- the actual default is this color but darkened or lightned
fg = beautiful.fg_color,
alt_fg = beautiful.fg_focus
}
}
```
Check documentation in [module/wallpaper.lua](module/wallpaper.lua) for more details.

View file

@ -0,0 +1,240 @@
## 🎵 Playerctl <!-- {docsify-ignore} -->
This is a signal module in which you can connect to certain bling signals to grab playerctl info. Currently, this is what it supports:
- Song title and artist
- Album art (the path this module downloaded the art to)
- If playing or not
- Position
- Song length
- If there are no players on
This module relies on `playerctl` and `curl`. If you have this module disabled, you won't need those programs. With this module, you can create a widget like below without worrying about the backend.
![](https://user-images.githubusercontent.com/33443763/107377569-fa807900-6a9f-11eb-93c1-174c58eb7bf1.png)
*screenshot by [javacafe](https://github.com/JavaCafe01)*
### Usage
To enable: `playerctl = bling.signal.playerctl.lib/cli()`
To disable: `playerctl:disable()`
#### Playerctl_lib Signals
**Note**: When connecting to signals with the new `playerctl` module, the object itself is always given to you as the first parameter.
```lua
-- metadata
-- title (string)
-- artist (string)
-- album_path (string)
-- album (string)
-- new (bool)
-- player_name (string)
-- position
-- interval_sec (number)
-- length_sec (number)
-- player_name (string)
-- playback_status
-- playing (boolean)
-- player_name (string)
-- seeked
-- position (number)
-- player_name (string)
-- volume
-- volume (number)
-- player_name (string)
-- loop_status
-- loop_status (string)
-- player_name (string)
-- shuffle
-- shuffle (boolean)
-- player_name (string)
-- exit
-- player_name (string)
-- no_players
-- (No parameters)
```
#### Playerctl_cli Signals
```lua
-- metadata
-- title (string)
-- artist (string)
-- album_path (string)
-- album (string)
-- player_name (string)
-- position
-- interval_sec (number)
-- length_sec (number)
-- playback_status
-- playing (boolean)
-- volume
-- volume (number)
-- loop_status
-- loop_status (string)
-- shuffle
-- shuffle (bool)
-- no_players
-- (No parameters)
```
#### Playerctl Functions
With this library we also give the user a way to interact with Playerctl, such as playing, pausing, seeking, etc.
Here are the functions provided:
```lua
-- disable()
-- pause(player)
-- play(player)
-- stop(player)
-- play_pause(player)
-- previous(player)
-- next(player)
-- set_loop_status(loop_status, player)
-- cycle_loop_status(player)
-- set_position(position, player)
-- set_shuffle(shuffle, player)
-- cycle_shuffle(player)
-- set_volume(volume, player)
-- get_manager()
-- get_active_player()
-- get_player_of_name(name)
```
### Example Implementation
Lets say we have an imagebox. If I wanted to set the imagebox to show the album art, all I have to do is this:
```lua
local art = wibox.widget {
image = "default_image.png",
resize = true,
forced_height = dpi(80),
forced_width = dpi(80),
widget = wibox.widget.imagebox
}
local name_widget = wibox.widget {
markup = 'No players',
align = 'center',
valign = 'center',
widget = wibox.widget.textbox
}
local title_widget = wibox.widget {
markup = 'Nothing Playing',
align = 'center',
valign = 'center',
widget = wibox.widget.textbox
}
local artist_widget = wibox.widget {
markup = 'Nothing Playing',
align = 'center',
valign = 'center',
widget = wibox.widget.textbox
}
-- Get Song Info
local playerctl = bling.signal.playerctl.lib()
playerctl:connect_signal("metadata",
function(_, title, artist, album_path, album, new, player_name)
-- Set art widget
art:set_image(gears.surface.load_uncached(album_path))
-- Set player name, title and artist widgets
name_widget:set_markup_silently(player_name)
title_widget:set_markup_silently(title)
artist_widget:set_markup_silently(artist)
end)
```
Thats all! You don't even have to worry about updating the widgets, the signals will handle that for you.
Here's another example in which you get a notification with the album art, title, and artist whenever the song changes.
```lua
local naughty = require("naughty")
local playerctl = bling.signal.playerctl.lib()
playerctl:connect_signal("metadata",
function(_, title, artist, album_path, album, new, player_name)
if new == true then
naughty.notify({title = title, text = artist, image = album_path})
end
end)
```
We can also link a playerctl function to a button click!
```lua
local playerctl = bling.signal.playerctl.lib()
button:buttons(gears.table.join(
awful.button({}, 1, function()
playerctl:play_pause()
end)
))
```
### Theme Variables and Configuration
By default, this module will output signals from the most recently active player. If you wish to customize the behavior furthur, the following configuration options are available depending on the selected backend. Here is a summary of the two backends and which configuration options they support.
| Option | playerctl_cli | playerctl_lib |
| ------------------- | ------------------ | ------------------ |
| ignore | :heavy_check_mark: | :heavy_check_mark: |
| player | :heavy_check_mark: | :heavy_check_mark: |
| update_on_activity | | :heavy_check_mark: |
| interval | :heavy_check_mark: | :heavy_check_mark: |
| debounce_delay | :heavy_check_mark: | :heavy_check_mark: |
- `ignore`: This option is either a string with a single name or a table of strings containing names of players that will be ignored by this module. It is empty by default.
- `player`: This option is either a string with a single name or a table of strings containing names of players this module will emit signals for. It also acts as a way to prioritize certain players over others with players listed earlier in the table being preferred over players listed later. The special name `%any` can be used once to match any player not found in the list. It is empty by default.
- `update_on_activity`: This option is a boolean that, when true, will cause the module to output signals from the most recently active player while still adhering to the player priority specified with the `player` option. If `false`, the module will output signals from the player that started first, again, while still adhering to the player priority. It is `true` by default.
- `interval`: This option is a number specifying the update interval for fetching the player position. It is 1 by default.
- `debounce_delay`: This option is a number specifying the debounce timer interval. If a new metadata signal gets emitted before debounce_delay has passed, the last signal will be dropped.
This is to help with some players sending multiple signals. It is `0.35` by default.
These options can be set through a call to `bling.signal.playerctl.lib/cli()` or these theme variables:
```lua
theme.playerctl_ignore = {}
theme.playerctl_player = {}
theme.playerctl_update_on_activity = true
theme.playerctl_position_update_interval = 1
```
#### Example Configurations
```lua
-- Prioritize ncspot over all other players and ignore firefox players (e.g. YouTube and Twitch tabs) completely
playerctl = bling.signal.playerctl.lib {
ignore = "firefox",
player = {"ncspot", "%any"}
}
-- OR in your theme file:
-- Same config as above but with theme variables
theme.playerctl_ignore = "firefox"
theme.playerctl_player = {"ncspot", "%any"}
-- Prioritize vlc over all other players and deprioritize spotify
theme.playerctl_backend = "playerctl_lib"
theme.playerctl_player = {"vlc", "%any", "spotify"}
-- Disable priority of most recently active players
theme.playerctl_update_on_activity = false
-- Only emit the position signal every 2 seconds
theme.playerctl_position_update_interval = 2
```

View file

@ -0,0 +1,117 @@
```lua
--[[ Bling theme variables template
This file has all theme variables of the bling module.
Every variable has a small comment on what it does.
You might just want to copy that whole part into your theme.lua and start adjusting from there.
--]]
-- window swallowing
theme.dont_swallow_classname_list = {"firefox", "Gimp"} -- list of class names that should not be swallowed
theme.dont_swallow_filter_activated = true -- whether the filter above should be active
-- flash focus
theme.flash_focus_start_opacity = 0.6 -- the starting opacity
theme.flash_focus_step = 0.01 -- the step of animation
-- playerctl signal
theme.playerctl_backend = "playerctl_cli" -- backend to use
theme.playerctl_ignore = {} -- list of players to be ignored
theme.playerctl_player = {} -- list of players to be used in priority order
theme.playerctl_update_on_activity = true -- whether to prioritize the most recently active players or not
theme.playerctl_position_update_interval = 1 -- the update interval for fetching the position from playerctl
-- tabbed
theme.tabbed_spawn_in_tab = false -- whether a new client should spawn into the focused tabbing container
-- tabbar general
theme.tabbar_ontop = false
theme.tabbar_radius = 0 -- border radius of the tabbar
theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern")
theme.tabbar_font = "Sans 11" -- font of the tabbar
theme.tabbar_size = 40 -- size of the tabbar
theme.tabbar_position = "top" -- position of the tabbar
theme.tabbar_bg_normal = "#000000" -- background color of the focused client on the tabbar
theme.tabbar_fg_normal = "#ffffff" -- foreground color of the focused client on the tabbar
theme.tabbar_bg_focus = "#1A2026" -- background color of unfocused clients on the tabbar
theme.tabbar_fg_focus = "#ff0000" -- foreground color of unfocused clients on the tabbar
theme.tabbar_bg_focus_inactive = nil -- background color of the focused client on the tabbar when inactive
theme.tabbar_fg_focus_inactive = nil -- foreground color of the focused client on the tabbar when inactive
theme.tabbar_bg_normal_inactive = nil -- background color of unfocused clients on the tabbar when inactive
theme.tabbar_fg_normal_inactive = nil -- foreground color of unfocused clients on the tabbar when inactive
theme.tabbar_disable = false -- disable the tab bar entirely
-- mstab
theme.mstab_bar_disable = false -- disable the tabbar
theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients
theme.mstab_dont_resize_slaves = false -- whether the tabbed stack windows should be smaller than the
-- currently focused stack window (set it to true if you use
-- transparent terminals. False if you use shadows on solid ones
theme.mstab_bar_padding = "default" -- how much padding there should be between clients and your tabbar
-- by default it will adjust based on your useless gaps.
-- If you want a custom value. Set it to the number of pixels (int)
theme.mstab_border_radius = 0 -- border radius of the tabbar
theme.mstab_bar_height = 40 -- height of the tabbar
theme.mstab_tabbar_position = "top" -- position of the tabbar (mstab currently does not support left,right)
theme.mstab_tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern")
-- defaults to the tabbar_style so only change if you want a
-- different style for mstab and tabbed
-- the following variables are currently only for the "modern" tabbar style
theme.tabbar_color_close = "#f9929b" -- chnges the color of the close button
theme.tabbar_color_min = "#fbdf90" -- chnges the color of the minimize button
theme.tabbar_color_float = "#ccaced" -- chnges the color of the float button
-- tag preview widget
theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
theme.tag_preview_client_border_radius = 0 -- Border radius of each client in the widget (With AA)
theme.tag_preview_client_opacity = 0.5 -- Opacity of each client
theme.tag_preview_client_bg = "#000000" -- The bg color of each client
theme.tag_preview_client_border_color = "#ffffff" -- The border color of each client
theme.tag_preview_client_border_width = 3 -- The border width of each client
theme.tag_preview_widget_bg = "#000000" -- The bg color of the widget
theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget
theme.tag_preview_widget_border_width = 3 -- The border width of the widget
theme.tag_preview_widget_margin = 0 -- The margin of the widget
-- task preview widget
theme.task_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
theme.task_preview_widget_bg = "#000000" -- The bg color of the widget
theme.task_preview_widget_border_color = "#ffffff" -- The border color of the widget
theme.task_preview_widget_border_width = 3 -- The border width of the widget
theme.task_preview_widget_margin = 0 -- The margin of the widget
-- tabbed misc widget(s)
theme.bling_tabbed_misc_titlebar_indicator = {
layout_spacing = dpi(4),
icon_size = dpi(20),
icon_margin = dpi(4),
bg_color_focus = "#ff0000",
bg_color = "#00000000",
icon_shape = function(cr, w, h)
gears.shape.rounded_rect(cr, w, h, 0)
end,
layout = wibox.layout.fixed.horizontal
}
-- window switcher widget
theme.window_switcher_widget_bg = "#000000" -- The bg color of the widget
theme.window_switcher_widget_border_width = 3 -- The border width of the widget
theme.window_switcher_widget_border_radius = 0 -- The border radius of the widget
theme.window_switcher_widget_border_color = "#ffffff" -- The border color of the widget
theme.window_switcher_clients_spacing = 20 -- The space between each client item
theme.window_switcher_client_icon_horizontal_spacing = 5 -- The space between client icon and text
theme.window_switcher_client_width = 150 -- The width of one client widget
theme.window_switcher_client_height = 250 -- The height of one client widget
theme.window_switcher_client_margins = 10 -- The margin between the content and the border of the widget
theme.window_switcher_thumbnail_margins = 10 -- The margin between one client thumbnail and the rest of the widget
theme.thumbnail_scale = false -- If set to true, the thumbnails fit policy will be set to "fit" instead of "auto"
theme.window_switcher_name_margins = 10 -- The margin of one clients title to the rest of the widget
theme.window_switcher_name_valign = "center" -- How to vertically align one clients title
theme.window_switcher_name_forced_width = 200 -- The width of one title
theme.window_switcher_name_font = "sans 11" -- The font of all titles
theme.window_switcher_name_normal_color = "#ffffff" -- The color of one title if the client is unfocused
theme.window_switcher_name_focus_color = "#ff0000" -- The color of one title if the client is focused
theme.window_switcher_icon_valign = "center" -- How to vertically align the one icon
theme.window_switcher_icon_width = 40 -- The width of one icon
```

View file

@ -0,0 +1,117 @@
## 🧱 Tabbed Miscellaneous <!-- {docsify-ignore} -->
This comprises a few widgets to better represent tabbed groups (from the tabbed module) in your desktop.
The widgets currently included are:
- Titlebar Indicator
- Tasklist
![Preview Image](https://i.imgur.com/ZeYSrxY.png)
## Titlebar Indicator
### Usage
To use the task list indicator:
**NOTE:** Options can be set as theme vars under the table `theme.bling_tabbed_misc_titlebar_indicator`
```lua
bling.widget.tabbed_misc.titlebar_indicator(client, {
layout = wibox.layout.fixed.vertical,
layout_spacing = dpi(5), -- Set spacing in between items
icon_size = dpi(24), -- Set icon size
icon_margin = 0, -- Set icon margin
fg_color = "#cccccc", -- Normal color for text
fg_color_focus = "#ffffff", -- Color for focused text
bg_color_focus = "#282828", -- Color for the focused items
bg_color = "#1d2021", -- Color for normal / unfocused items
icon_shape = gears.shape.circle -- Set icon shape,
})
```
a widget_template option is also available:
```lua
bling.widget.tabbed_misc.titlebar_indicator(client, {
widget_template = {
{
widget = awful.widget.clienticon,
id = 'icon_role'
},
widget = wibox.container.margin,
margins = 2,
id = 'bg_role',
update_callback = function(self, client, group)
if client == group.clients[group.focused_idx] then
self.margins = 5
end
end
}
})
```
### Example Implementation
You normally embed the widget in your titlebar...
```lua
awful.titlebar(c).widget = {
{ -- Left
bling.widget.tabbed_misc.titlebar_indicator(c),
layout = wibox.layout.fixed.horizontal
},
{ -- Middle
{ -- Title
align = "center",
widget = awful.titlebar.widget.titlewidget(c)
},
buttons = buttons,
layout = wibox.layout.flex.horizontal
},
{ -- Right
awful.titlebar.widget.maximizedbutton(c),
awful.titlebar.widget.closebutton (c),
layout = wibox.layout.fixed.horizontal
},
layout = wibox.layout.align.horizontal
}
```
## Tasklist
The module exports a function that can be added to your tasklist as a `update_callback`
### Usage
```lua
awful.widget.tasklist({
screen = s,
filter = awful.widget.tasklist.filter.currenttags,
layout = {
spacing = dpi(10),
layout = wibox.layout.fixed.vertical,
},
style = {
bg_normal = "#00000000",
},
widget_template = {
{
{
widget = wibox.widget.imagebox,
id = "icon_role",
align = "center",
valign = "center",
},
width = dpi(24),
height = dpi(24),
widget = wibox.container.constraint,
},
widget = wibox.container.background, -- IT MUST BE A CONTAINER WIDGET AS THAT IS WHAT THE FUNCTION EXPECTS
update_callback = require("bling.widget.tabbed_misc").custom_tasklist,
id = "background_role",
},
})
```
If you need to do something else, it can be used like so
```lua
update_callback = function(self, client, index, clients)
require("bling.widget.tabbed_misc").custom_tasklist(self, client, index, clients)
require("naughty").notify({ text = "Tasklist was updated" })
end
```

View file

@ -0,0 +1,155 @@
## 🔍 Tag Preview <!-- {docsify-ignore} -->
This is a popup widget that will show a preview of a specified tag that illustrates the position, size, content, and icon of all clients.
![](https://imgur.com/zFdvs4K.gif)
*gif by [javacafe](https://github.com/JavaCafe01)*
### Usage
To enable:
```lua
bling.widget.tag_preview.enable {
show_client_content = false, -- Whether or not to show the client content
x = 10, -- The x-coord of the popup
y = 10, -- The y-coord of the popup
scale = 0.25, -- The scale of the previews compared to the screen
honor_padding = false, -- Honor padding when creating widget size
honor_workarea = false, -- Honor work area when creating widget size
placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y)
awful.placement.top_left(c, {
margins = {
top = 30,
left = 30
}
})
end,
background_widget = wibox.widget { -- Set a background image (like a wallpaper) for the widget
image = beautiful.wallpaper,
horizontal_fit_policy = "fit",
vertical_fit_policy = "fit",
widget = wibox.widget.imagebox
}
}
```
Here are the signals available:
```lua
-- bling::tag_preview::update -- first line is the signal
-- t (tag) -- indented lines are function parameters
-- bling::tag_preview::visibility
-- s (screen)
-- v (boolean)
```
By default, the widget is not visible. You must implement when it will update and when it will show.
### Example Implementation
We can trigger the widget to show the specific tag when hovering over it in the taglist. The code shown below is the example taglist from the [AwesomeWM docs](https://awesomewm.org/doc/api/classes/awful.widget.taglist.html). Basically, we are going to update the widget and toggle it through the taglist's `create_callback`. (The bling addons are commented)
```lua
s.mytaglist = awful.widget.taglist {
screen = s,
filter = awful.widget.taglist.filter.all,
style = {
shape = gears.shape.powerline
},
layout = {
spacing = -12,
spacing_widget = {
color = '#dddddd',
shape = gears.shape.powerline,
widget = wibox.widget.separator,
},
layout = wibox.layout.fixed.horizontal
},
widget_template = {
{
{
{
{
{
id = 'index_role',
widget = wibox.widget.textbox,
},
margins = 4,
widget = wibox.container.margin,
},
bg = '#dddddd',
shape = gears.shape.circle,
widget = wibox.container.background,
},
{
{
id = 'icon_role',
widget = wibox.widget.imagebox,
},
margins = 2,
widget = wibox.container.margin,
},
{
id = 'text_role',
widget = wibox.widget.textbox,
},
layout = wibox.layout.fixed.horizontal,
},
left = 18,
right = 18,
widget = wibox.container.margin
},
id = 'background_role',
widget = wibox.container.background,
-- Add support for hover colors and an index label
create_callback = function(self, c3, index, objects) --luacheck: no unused args
self:get_children_by_id('index_role')[1].markup = '<b> '..index..' </b>'
self:connect_signal('mouse::enter', function()
-- BLING: Only show widget when there are clients in the tag
if #c3:clients() > 0 then
-- BLING: Update the widget with the new tag
awesome.emit_signal("bling::tag_preview::update", c3)
-- BLING: Show the widget
awesome.emit_signal("bling::tag_preview::visibility", s, true)
end
if self.bg ~= '#ff0000' then
self.backup = self.bg
self.has_backup = true
end
self.bg = '#ff0000'
end)
self:connect_signal('mouse::leave', function()
-- BLING: Turn the widget off
awesome.emit_signal("bling::tag_preview::visibility", s, false)
if self.has_backup then self.bg = self.backup end
end)
end,
update_callback = function(self, c3, index, objects) --luacheck: no unused args
self:get_children_by_id('index_role')[1].markup = '<b> '..index..' </b>'
end,
},
buttons = taglist_buttons
}
```
### Theme Variables
```lua
theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
theme.tag_preview_client_border_radius = 0 -- Border radius of each client in the widget (With AA)
theme.tag_preview_client_opacity = 0.5 -- Opacity of each client
theme.tag_preview_client_bg = "#000000" -- The bg color of each client
theme.tag_preview_client_border_color = "#ffffff" -- The border color of each client
theme.tag_preview_client_border_width = 3 -- The border width of each client
theme.tag_preview_widget_bg = "#000000" -- The bg color of the widget
theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget
theme.tag_preview_widget_border_width = 3 -- The border width of the widget
theme.tag_preview_widget_margin = 0 -- The margin of the widget
```
NOTE: I recommend to only use the widget border radius theme variable when not using shadows with a compositor, as anti-aliased rounding with the outer widgets made with AwesomeWM rely on the actual bg being transparent. If you want rounding with shadows on the widget, use a compositor like [jonaburg's fork](https://github.com/jonaburg/picom).

View file

@ -0,0 +1,152 @@
## 🔍 Task Preview <!-- {docsify-ignore} -->
This is a popup widget that will show a preview of the specified client. It is supposed to mimic the small popup that Windows has when hovering over the application icon.
![](https://user-images.githubusercontent.com/33443763/124705653-d7b98b80-deaa-11eb-8091-42bbe62365be.png)
*image by [javacafe](https://github.com/JavaCafe01)*
### Usage
To enable:
```lua
bling.widget.task_preview.enable {
x = 20, -- The x-coord of the popup
y = 20, -- The y-coord of the popup
height = 200, -- The height of the popup
width = 200, -- The width of the popup
placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y)
awful.placement.bottom(c, {
margins = {
bottom = 30
}
})
end
}
```
To allow for more customization, there is also a `widget_structure` property (as seen in some default awesome widgets) which is optional. An example is as follows -
```lua
bling.widget.task_preview.enable {
x = 20, -- The x-coord of the popup
y = 20, -- The y-coord of the popup
height = 200, -- The height of the popup
width = 200, -- The width of the popup
placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y)
awful.placement.bottom(c, {
margins = {
bottom = 30
}
})
end,
-- Your widget will automatically conform to the given size due to a constraint container.
widget_structure = {
{
{
{
id = 'icon_role',
widget = awful.widget.clienticon, -- The client icon
},
{
id = 'name_role', -- The client name / title
widget = wibox.widget.textbox,
},
layout = wibox.layout.flex.horizontal
},
widget = wibox.container.margin,
margins = 5
},
{
id = 'image_role', -- The client preview
resize = true,
valign = 'center',
halign = 'center',
widget = wibox.widget.imagebox,
},
layout = wibox.layout.fixed.vertical
}
}
```
Here are the signals available:
```lua
-- bling::task_preview::visibility -- first line is the signal
-- s (screen) -- indented lines are function parameters
-- v (boolean)
-- c (client)
```
By default, the widget is not visible. You must implement when it will update and when it will show.
### Example Implementation
We can trigger the widget to show the specific client when hovering over it in the tasklist. The code shown below is the example icon only tasklist from the [AwesomeWM docs](https://awesomewm.org/doc/api/classes/awful.widget.tasklist.html). Basically, we are going to toggle the widget through the tasklist's `create_callback`. (The bling addons are commented)
```lua
s.mytasklist = awful.widget.tasklist {
screen = s,
filter = awful.widget.tasklist.filter.currenttags,
buttons = tasklist_buttons,
layout = {
spacing_widget = {
{
forced_width = 5,
forced_height = 24,
thickness = 1,
color = '#777777',
widget = wibox.widget.separator
},
valign = 'center',
halign = 'center',
widget = wibox.container.place,
},
spacing = 1,
layout = wibox.layout.fixed.horizontal
},
-- Notice that there is *NO* wibox.wibox prefix, it is a template,
-- not a widget instance.
widget_template = {
{
wibox.widget.base.make_widget(),
forced_height = 5,
id = 'background_role',
widget = wibox.container.background,
},
{
{
id = 'clienticon',
widget = awful.widget.clienticon,
},
margins = 5,
widget = wibox.container.margin
},
nil,
create_callback = function(self, c, index, objects) --luacheck: no unused args
self:get_children_by_id('clienticon')[1].client = c
-- BLING: Toggle the popup on hover and disable it off hover
self:connect_signal('mouse::enter', function()
awesome.emit_signal("bling::task_preview::visibility", s,
true, c)
end)
self:connect_signal('mouse::leave', function()
awesome.emit_signal("bling::task_preview::visibility", s,
false, c)
end)
end,
layout = wibox.layout.align.vertical,
},
}
```
### Theme Variables
```lua
theme.task_preview_widget_border_radius = 0 -- Border radius of the widget (With AA)
theme.task_preview_widget_bg = "#000000" -- The bg color of the widget
theme.task_preview_widget_border_color = "#ffffff" -- The border color of the widget
theme.task_preview_widget_border_width = 3 -- The border width of the widget
theme.task_preview_widget_margin = 0 -- The margin of the widget
```
NOTE: I recommend to only use the widget border radius theme variable when not using shadows with a compositor, as anti-aliased rounding with the outer widgets made with AwesomeWM rely on the actual bg being transparent. If you want rounding with shadows on the widget, use a compositor like [jonaburg's fork](https://github.com/jonaburg/picom).

View file

@ -0,0 +1,67 @@
## 🎨 Window Switcher <!-- {docsify-ignore} -->
A popup with client previews that allows you to switch clients similar to the alt-tab menu in MacOS, GNOME, and Windows.
![](https://user-images.githubusercontent.com/70270606/133311802-8aef1012-346f-4f4c-843d-10d9de54ffeb.png)
*image by [No37](https://github.com/Nooo37)*
### Usage
To enable:
```lua
bling.widget.window_switcher.enable {
type = "thumbnail", -- set to anything other than "thumbnail" to disable client previews
-- keybindings (the examples provided are also the default if kept unset)
hide_window_switcher_key = "Escape", -- The key on which to close the popup
minimize_key = "n", -- The key on which to minimize the selected client
unminimize_key = "N", -- The key on which to unminimize all clients
kill_client_key = "q", -- The key on which to close the selected client
cycle_key = "Tab", -- The key on which to cycle through all clients
previous_key = "Left", -- The key on which to select the previous client
next_key = "Right", -- The key on which to select the next client
vim_previous_key = "h", -- Alternative key on which to select the previous client
vim_next_key = "l", -- Alternative key on which to select the next client
cycleClientsByIdx = awful.client.focus.byidx, -- The function to cycle the clients
filterClients = awful.widget.tasklist.filter.currenttags, -- The function to filter the viewed clients
}
```
To run the window swicher you have to emit this signal from within your configuration (usually using a keybind).
```lua
awesome.emit_signal("bling::window_switcher::turn_on")
```
For example:
```lua
awful.key({Mod1}, "Tab", function()
awesome.emit_signal("bling::window_switcher::turn_on")
end, {description = "Window Switcher", group = "bling"})
```
### Theme Variables
```lua
theme.window_switcher_widget_bg = "#000000" -- The bg color of the widget
theme.window_switcher_widget_border_width = 3 -- The border width of the widget
theme.window_switcher_widget_border_radius = 0 -- The border radius of the widget
theme.window_switcher_widget_border_color = "#ffffff" -- The border color of the widget
theme.window_switcher_clients_spacing = 20 -- The space between each client item
theme.window_switcher_client_icon_horizontal_spacing = 5 -- The space between client icon and text
theme.window_switcher_client_width = 150 -- The width of one client widget
theme.window_switcher_client_height = 250 -- The height of one client widget
theme.window_switcher_client_margins = 10 -- The margin between the content and the border of the widget
theme.window_switcher_thumbnail_margins = 10 -- The margin between one client thumbnail and the rest of the widget
theme.thumbnail_scale = false -- If set to true, the thumbnails fit policy will be set to "fit" instead of "auto"
theme.window_switcher_name_margins = 10 -- The margin of one clients title to the rest of the widget
theme.window_switcher_name_valign = "center" -- How to vertically align one clients title
theme.window_switcher_name_forced_width = 200 -- The width of one title
theme.window_switcher_name_font = "sans 11" -- The font of all titles
theme.window_switcher_name_normal_color = "#ffffff" -- The color of one title if the client is unfocused
theme.window_switcher_name_focus_color = "#ff0000" -- The color of one title if the client is focused
theme.window_switcher_icon_valign = "center" -- How to vertically align the one icon
theme.window_switcher_icon_width = 40 -- The width of one icon
```