Merge branch 'master' into fixes

This commit is contained in:
contribuewwt 2021-11-15 18:35:30 +05:30 committed by GitHub
commit 165a230b0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 2481 additions and 376 deletions

View File

@ -1,19 +1,19 @@
package = "bling" package = "bling"
version = "scm-5" version = "dev-1"
source = { source = {
url = "git://github.com/Nooo37/bling", url = "git://github.com/BlingCorp/bling",
branch = "master", branch = "master",
} }
description = { description = {
summary = "Utilities for the AwesomeWM", summary = "Utilities for the AwesomeWM",
detailed = [[ detailed = [[
This module extends the Awesome window manager with alternative layouts, This module extends the Awesome window manager with alternative layouts,
flash focus, tabbing, a simple tiling wallpaper generator, a declarative flash focus, tabbing, a simple tiling wallpaper generator, a declarative
wallpaper setter, window swallowing and a playerctl signal. wallpaper setter, window swallowing and a playerctl signal.
]], ]],
homepage = "https://github.com/Nooo37/bling", homepage = "https://github.com/BlingCorp/bling",
license = "MIT", license = "MIT",
} }
@ -23,32 +23,41 @@ dependencies = {
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["bling"] = "init.lua", ["bling"] = "init.lua",
["bling.layout"] = "layout/init.lua",
["bling.layout.centered"] = "layout/centered.lua",
["bling.layout.equalarea"] = "layout/equalarea.lua",
["bling.layout.horizontal"] = "layout/horizontal.lua",
["bling.layout.mstab"] = "layout/mstab.lua",
["bling.layout.vertical"] = "layout/vertical.lua",
["bling.helpers"] = "helpers/init.lua", ["bling.helpers"] = "helpers/init.lua",
["bling.helpers.client"] = "helpers/client.lua", ["bling.helpers.client"] = "helpers/client.lua",
["bling.helpers.color"] = "helpers/color.lua", ["bling.helpers.color"] = "helpers/color.lua",
["bling.helpers.filesystem"] = "helpers/filesystem.lua", ["bling.helpers.filesystem"] = "helpers/filesystem.lua",
["bling.helpers.shape"] = "helpers/shape.lua", ["bling.helpers.shape"] = "helpers/shape.lua",
["bling.helpers.time"] = "helpers/time.lua", ["bling.helpers.time"] = "helpers/time.lua",
["bling.layout"] = "layout/init.lua",
["bling.layout.centered"] = "layout/centered.lua",
["bling.layout.deck"] = "layout/deck.lua",
["bling.layout.equalarea"] = "layout/equalarea.lua",
["bling.layout.horizontal"] = "layout/horizontal.lua",
["bling.layout.mstab"] = "layout/mstab.lua",
["bling.layout.vertical"] = "layout/vertical.lua",
["bling.module"] = "module/init.lua", ["bling.module"] = "module/init.lua",
["bling.module.flash_focus"] = "module/flash_focus.lua", ["bling.module.flash_focus"] = "module/flash_focus.lua",
["bling.module.scratchpad"] = "module/scratchpad.lua",
["bling.module.tabbed"] = "module/tabbed.lua", ["bling.module.tabbed"] = "module/tabbed.lua",
["bling.module.tiled_wallpaper"] = "module/tiled_wallpaper.lua", ["bling.module.tiled_wallpaper"] = "module/tiled_wallpaper.lua",
["bling.module.wallpaper"] = "module/wallpaper.lua", ["bling.module.wallpaper"] = "module/wallpaper.lua",
["bling.module.window_swallowing"] = "module/window_swallowing.lua", ["bling.module.window_swallowing"] = "module/window_swallowing.lua",
["bling.signal"] = "signal/init.lua", ["bling.signal"] = "signal/init.lua",
["bling.signal.playerctl"] = "signal/playerctl.lua", ["bling.signal.playerctl"] = "signal/playerctl/init.lua",
["bling.signal.playerctl.playerctl_cli"] = "signal/playerctl/playerctl_cli.lua",
["bling.signal.playerctl.playerctl_lib"] = "signal/playerctl/playerctl_lib.lua",
["bling.widget"] = "widget/init.lua",
["bling.widget.tabbar.boxes"] = "widget/tabbar/boxes.lua", ["bling.widget.tabbar.boxes"] = "widget/tabbar/boxes.lua",
["bling.widget.tabbar.default"] = "widget/tabbar/default.lua", ["bling.widget.tabbar.default"] = "widget/tabbar/default.lua",
["bling.widget.tabbar.modern"] = "widget/tabbar/modern.lua", ["bling.widget.tabbar.modern"] = "widget/tabbar/modern.lua",
["bling.widget.tabbed_misc"] = "widget/tabbed_misc/init.lua",
["bling.widget.tabbed_misc.custom_tasklist"] = "widget/tabbed_misc/custom_tasklist.lua",
["bling.widget.tabbed_misc.titlebar_indicator"] = "widget/tabbed_misc/titlebar_indicator.lua",
["bling.widget.tag_preview"] = "widget/tag_preview.lua", ["bling.widget.tag_preview"] = "widget/tag_preview.lua",
["bling.widget"] = "widget/init.lua", ["bling.widget.task_preview"] = "widget/task_preview.lua",
["bling.widget.window_switcher"] = "widget/window_switcher.lua",
}, },
} }

View File

@ -17,6 +17,7 @@
- [Tag Preview](widgets/tag_preview.md) - [Tag Preview](widgets/tag_preview.md)
- [Task Preview](widgets/task_preview.md) - [Task Preview](widgets/task_preview.md)
- [Tabbed Misc](widgets/tabbed_misc.md) - [Tabbed Misc](widgets/tabbed_misc.md)
- [Window Switcher](widgets/window_switcher.md)
- Extra - Extra
- [Theme Variable Template](theme.md) - [Theme Variable Template](theme.md)

View File

@ -6,7 +6,7 @@ Everyone of them supports multiple master clients and master width factor making
The mstab layout uses the tab theme from the tabbed module. The mstab layout uses the tab theme from the tabbed module.
```Lua ```lua
bling.layout.mstab bling.layout.mstab
bling.layout.centered bling.layout.centered
bling.layout.vertical bling.layout.vertical
@ -16,36 +16,40 @@ bling.layout.deck
``` ```
### Theme Variables ### Theme Variables
```lua ```lua
-- mstab -- mstab
theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients 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 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 -- currently focused stack window (set it to true if you use
-- transparent terminals. False if you use shadows on solid ones -- 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 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. -- by default it will adjust based on your useless gaps.
-- If you want a custom value. Set it to the number of pixels (int) -- 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_border_radius = 0 -- border radius of the tabbar
theme.mstab_bar_height = 40 -- height 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_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") 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 -- defaults to the tabbar_style so only change if you want a
-- different style for mstab and tabbed -- different style for mstab and tabbed
``` ```
### Previews ### Previews
#### Mstab (dynamic tabbing layout) #### Mstab (dynamic tabbing layout)
![](https://imgur.com/HZRgApE.png) ![](https://imgur.com/HZRgApE.png)
*screenshot by [javacafe](https://github.com/JavaCafe01)* *screenshot by [JavaCafe01](https://github.com/JavaCafe01)*
#### Centered #### Centered
![](https://media.discordapp.net/attachments/769673106842845194/780095998239834142/unknown.png) ![](https://media.discordapp.net/attachments/769673106842845194/780095998239834142/unknown.png)
*screenshot by [branwright](https://github.com/branwright1)* *screenshot by [HeavyRain266](https://github.com/HeavyRain266)*
#### Equal area #### Equal area
![](https://imgur.com/JCFFywv.png) ![](https://imgur.com/JCFFywv.png)
*screenshot by [bysmutheye](https://github.com/bysmutheye)* *screenshot by [bysmutheye](https://github.com/bysmutheye)*
@ -56,4 +60,5 @@ The left area shows the deck layout in action. In this screenshot it is used tog
![](https://cdn.discordapp.com/attachments/635625954219261982/877957824225894430/unknown.png) ![](https://cdn.discordapp.com/attachments/635625954219261982/877957824225894430/unknown.png)
*screenshot by [javacafe](https://github.com/JavaCafe01)* *screenshot by [JavaCafe01](https://github.com/JavaCafe01)*

View File

@ -22,8 +22,8 @@ awful.key({modkey}, "Up",
### Theme Variables ### Theme Variables
```lua ```lua
theme.flash_focus_start_opacity = 0.6 -- the starting opacity theme.flash_focus_start_opacity = 0.6 -- the starting opacity
theme.flash_focus_step = 0.01 -- the step of animation theme.flash_focus_step = 0.01 -- the step of animation
``` ```
### Preview ### Preview

View File

@ -18,7 +18,7 @@ To initalize a scratchpad you can do something like the following:
```lua ```lua
local bling = require("bling") local bling = require("bling")
local rubato = require("rubato") -- Totally optional, only required if you are using animations. 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. -- 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. -- The duration and easing is up to you. Please check out the rubato docs to learn more.
@ -28,7 +28,7 @@ local anim_y = rubato.timed {
easing = rubato.quadratic, easing = rubato.quadratic,
intro = 0.1, intro = 0.1,
duration = 0.3, duration = 0.3,
awestore_compat = true -- This option must be set to true. awestore_compat = true -- This option must be set to true.
} }
local anim_x = rubato.timed { local anim_x = rubato.timed {
@ -37,7 +37,7 @@ local anim_x = rubato.timed {
easing = rubato.quadratic, easing = rubato.quadratic,
intro = 0.1, intro = 0.1,
duration = 0.3, duration = 0.3,
awestore_compat = true -- This option must be set to true. awestore_compat = true -- This option must be set to true.
} }
local term_scratch = bling.module.scratchpad { local term_scratch = bling.module.scratchpad {
@ -49,7 +49,7 @@ local term_scratch = bling.module.scratchpad {
geometry = {x=360, y=90, height=900, width=1200}, -- The geometry in a floating state 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) 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 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. 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.
} }
``` ```

View File

@ -6,15 +6,15 @@ Can your window manager swallow? It probably can...
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`. 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 ```lua
bling.module.window_swallowing.start() -- activates window swallowing bling.module.window_swallowing.start() -- activates window swallowing
bling.module.window_swallowing.stop() -- deactivates window swallowing bling.module.window_swallowing.stop() -- deactivates window swallowing
bling.module.window_swallowing.toggle() -- toggles window swallowing bling.module.window_swallowing.toggle() -- toggles window swallowing
``` ```
### Theme Variables ### Theme Variables
```lua ```lua
theme.dont_swallow_classname_list = {"firefox", "Gimp"} -- list of class names that should not be swallowed 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 theme.dont_swallow_filter_activated = true -- whether the filter above should be active
``` ```
### Preview ### Preview

View File

@ -6,10 +6,10 @@ Tabbed implements a tab container. There are also different themes for the tabs.
You should bind these functions to keys in order to use the tabbed module effectively: You should bind these functions to keys in order to use the tabbed module effectively:
```lua ```lua
bling.module.tabbed.pick() -- picks a client with your cursor to add to the tabbing group 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.pop() -- removes the focused client from the tabbing group
bling.module.tabbed.iter() -- iterates through the currently focused 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_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") bling.module.tabbed.pick_by_direction(dir) -- picks a client based on direction ("up", "down", "left" or "right")
``` ```
@ -17,25 +17,29 @@ bling.module.tabbed.pick_by_direction(dir) -- picks a client based on direction
```lua ```lua
-- For tabbed only -- For tabbed only
theme.tabbed_spawn_in_tab = false -- whether a new client should spawn into the focused tabbing container theme.tabbed_spawn_in_tab = false -- whether a new client should spawn into the focused tabbing container
-- For tabbar in general -- For tabbar in general
theme.tabbar_ontop = false theme.tabbar_ontop = false
theme.tabbar_radius = 0 -- border radius of the tabbar theme.tabbar_radius = 0 -- border radius of the tabbar
theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern")
theme.tabbar_font = "Sans 11" -- font of the tabbar theme.tabbar_font = "Sans 11" -- font of the tabbar
theme.tabbar_size = 40 -- size of the tabbar theme.tabbar_size = 40 -- size of the tabbar
theme.tabbar_position = "top" -- position 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_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_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_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_fg_focus = "#ff0000" -- foreground color of unfocused clients on the tabbar
theme.tabbar_disable = false -- disable the tab bar entirely 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 -- 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_close = "#f9929b" -- chnges the color of the close button
theme.tabbar_color_min = "#fbdf90" -- chnges the color of the minimize 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 theme.tabbar_color_float = "#ccaced" -- chnges the color of the float button
``` ```
### Preview ### Preview
@ -44,19 +48,19 @@ Modern theme:
<img src="https://imgur.com/omowmIQ.png" width="600"/> <img src="https://imgur.com/omowmIQ.png" width="600"/>
*screenshot by [javacafe](https://github.com/JavaCafe01)* *screenshot by [JavaCafe01](https://github.com/JavaCafe01)*
### Signals ### Signals
The tabbed module emits a few signals for the purpose of integration, The tabbed module emits a few signals for the purpose of integration,
```lua ```lua
-- bling::tabbed::update -- triggered whenever a tabbed object is updated -- bling::tabbed::update -- triggered whenever a tabbed object is updated
-- tabobj -- the object that caused the update -- tabobj -- the object that caused the update
-- bling::tabbed::client_added -- triggered whenever a new client is added to a tab group -- bling::tabbed::client_added -- triggered whenever a new client is added to a tab group
-- tabobj -- the object that the client was added to -- tabobj -- the object that the client was added to
-- client -- the client that added -- client -- the client that added
-- bling::tabbed::client_removed -- triggered whenever a client is removed from a tab group -- bling::tabbed::client_removed -- triggered whenever a client is removed from a tab group
-- tabobj -- the object that the client was removed from -- tabobj -- the object that the client was removed from
-- client -- the client that was removed -- client -- the client that was removed
-- bling::tabbed::changed_focus -- triggered whenever a tab group's focus is changed -- bling::tabbed::changed_focus -- triggered whenever a tab group's focus is changed
-- tabobj -- the modified tab group -- tabobj -- the modified tab group
``` ```

View File

@ -4,16 +4,16 @@
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): 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 ```lua
awful.screen.connect_for_each_screen(function(s) -- that way the wallpaper is applied to every screen 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) bling.module.tiled_wallpaper("x", s, { -- call the actual function ("x" is the string that will be tiled)
fg = "#ff0000", -- define the foreground color fg = "#ff0000", -- define the foreground color
bg = "#00ffff", -- define the background color bg = "#00ffff", -- define the background color
offset_y = 25, -- set a y offset offset_y = 25, -- set a y offset
offset_x = 25, -- set a x offset offset_x = 25, -- set a x offset
font = "Hack", -- set the font (without the size) font = "Hack", -- set the font (without the size)
font_size = 14, -- set the font size font_size = 14, -- set the font size
padding = 100, -- set padding (default is 100) padding = 100, -- set padding (default is 100)
zickzack = true -- rectangular pattern or criss cross zickzack = true -- rectangular pattern or criss cross
}) })
end) end)
``` ```
@ -23,3 +23,4 @@ end)
![](https://media.discordapp.net/attachments/702548913999314964/773887721294135296/tiled-wallpapers.png?width=1920&height=1080) ![](https://media.discordapp.net/attachments/702548913999314964/773887721294135296/tiled-wallpapers.png?width=1920&height=1080)
*screenshots by [Nooo37](https://github.com/Nooo37)* *screenshots by [Nooo37](https://github.com/Nooo37)*

View File

@ -18,7 +18,7 @@ bling.module.wallpaper.setup {
bling.module.wallpaper.setup { bling.module.wallpaper.setup {
set_function = bling.module.wallpaper.setters.random, set_function = bling.module.wallpaper.setters.random,
wallpaper = {"/path/to/a/folder", "/path/to/another/folder"}, wallpaper = {"/path/to/a/folder", "/path/to/another/folder"},
change_timer = 631, -- prime numbers are better for timers change_timer = 631, -- prime numbers are better for timers
position = "fit", position = "fit",
background = "#424242" background = "#424242"
} }
@ -99,14 +99,14 @@ Here are the defaults:
```lua ```lua
-- Default parameters -- Default parameters
bling.module.wallpaper.setup { bling.module.wallpaper.setup {
screen = nil, -- the screen to apply the wallpaper, as seen in gears.wallpaper functions screen = nil, -- the screen to apply the wallpaper, as seen in gears.wallpaper functions
change_timer = nil, -- the timer in seconds. If set, call the set_function every change_timer seconds change_timer = nil, -- the timer in seconds. If set, call the set_function every change_timer seconds
set_function = nil, -- the setter function set_function = nil, -- the setter function
-- parameters used by bling.module.wallpaper.prepare_list -- parameters used by bling.module.wallpaper.prepare_list
wallpaper = nil, -- the wallpaper object, see simple or simple_schedule documentation 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 image_formats = {"jpg", "jpeg", "png", "bmp"}, -- when searching in folder, consider these files only
recursive = true, -- when searching in folder, search also in subfolders recursive = true, -- when searching in folder, search also in subfolders
-- parameters used by bling.module.wallpaper.apply -- parameters used by bling.module.wallpaper.apply
position = nil, -- use a function of gears.wallpaper when applicable ("centered", "fit", "maximized", "tiled") position = nil, -- use a function of gears.wallpaper when applicable ("centered", "fit", "maximized", "tiled")
@ -116,8 +116,8 @@ bling.module.wallpaper.setup {
scale = 1, -- see gears.wallpaper.centered scale = 1, -- see gears.wallpaper.centered
-- parameters that only apply to bling.module.wallpaper.setter.awesome (as a setter or as a wallpaper function) -- parameters that only apply to bling.module.wallpaper.setter.awesome (as a setter or as a wallpaper function)
colors = { -- see beautiful.theme_assets.wallpaper colors = { -- see beautiful.theme_assets.wallpaper
bg = beautiful.bg_color, -- the actual default is this color but darkened or lightned bg = beautiful.bg_color, -- the actual default is this color but darkened or lightned
fg = beautiful.fg_color, fg = beautiful.fg_color,
alt_fg = beautiful.fg_focus alt_fg = beautiful.fg_focus
} }

View File

@ -24,20 +24,20 @@ To disable: `bling.signal.playerctl.disable()`
Here are the signals available: Here are the signals available:
```lua ```lua
-- bling::playerctl::status -- first line is the signal -- bling::playerctl::status -- first line is the signal
-- playing (boolean) -- indented lines are function parameters -- playing (boolean) -- indented lines are function parameters
-- player_name (string) -- player_name (string)
-- bling::playerctl::title_artist_album -- bling::playerctl::title_artist_album
-- title (string) -- title (string)
-- artist (string) -- artist (string)
-- album_path (string) -- album_path (string)
-- player_name (string) -- player_name (string)
-- bling::playerctl::position -- bling::playerctl::position
-- interval_sec (number) -- interval_sec (number)
-- length_sec (number) -- length_sec (number)
-- player_name (string) -- player_name (string)
-- bling::playerctl::no_players -- bling::playerctl::no_players
-- (No parameters) -- (No parameters)
``` ```
### Example Implementation ### Example Implementation
@ -122,8 +122,8 @@ By default, this module will output signals from the most recently active player
These options can be set through a call to `bling.signal.playerctl.enable()` or these theme variables: These options can be set through a call to `bling.signal.playerctl.enable()` or these theme variables:
```lua ```lua
theme.playerctl_backend = "playerctl_cli" theme.playerctl_backend = "playerctl_cli"
theme.playerctl_ignore = {} theme.playerctl_ignore = {}
theme.playerctl_player = {} theme.playerctl_player = {}
theme.playerctl_update_on_activity = true theme.playerctl_update_on_activity = true
theme.playerctl_position_update_interval = 1 theme.playerctl_position_update_interval = 1
``` ```
@ -140,12 +140,12 @@ bling.signal.playerctl.enable {
-- OR in your theme file: -- OR in your theme file:
-- Same config as above but with theme variables -- Same config as above but with theme variables
theme.playerctl_backend = "playerctl_lib" theme.playerctl_backend = "playerctl_lib"
theme.playerctl_ignore = "firefox" theme.playerctl_ignore = "firefox"
theme.playerctl_player = {"ncspot", "%any"} theme.playerctl_player = {"ncspot", "%any"}
-- Prioritize vlc over all other players and deprioritize spotify -- Prioritize vlc over all other players and deprioritize spotify
theme.playerctl_backend = "playerctl_lib" theme.playerctl_backend = "playerctl_lib"
theme.playerctl_player = {"vlc", "%any", "spotify"} theme.playerctl_player = {"vlc", "%any", "spotify"}
-- Disable priority of most recently active players -- Disable priority of most recently active players
theme.playerctl_backend = "playerctl_lib" theme.playerctl_backend = "playerctl_lib"

View File

@ -26,15 +26,20 @@ theme.tabbed_spawn_in_tab = false -- whether a new client should spawn
-- tabbar general -- tabbar general
theme.tabbar_ontop = false theme.tabbar_ontop = false
theme.tabbar_radius = 0 -- border radius of the tabbar theme.tabbar_radius = 0 -- border radius of the tabbar
theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern")
theme.tabbar_font = "Sans 11" -- font of the tabbar theme.tabbar_font = "Sans 11" -- font of the tabbar
theme.tabbar_size = 40 -- size of the tabbar theme.tabbar_size = 40 -- size of the tabbar
theme.tabbar_position = "top" -- position 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_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_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_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_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 -- mstab
theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients
@ -87,4 +92,25 @@ theme.bling_tabbed_misc_titlebar_indicator = {
end, end,
layout = wibox.layout.fixed.horizontal 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

@ -18,8 +18,8 @@ To use the task list indicator:
bling.widget.tabbed_misc.titlebar_indicator(client, { bling.widget.tabbed_misc.titlebar_indicator(client, {
layout = wibox.layout.fixed.vertical, layout = wibox.layout.fixed.vertical,
layout_spacing = dpi(5), -- Set spacing in between items layout_spacing = dpi(5), -- Set spacing in between items
icon_size = dpi(24), icon_size = dpi(24), -- Set icon size
icon_margin = 0, icon_margin = 0, -- Set icon margin
fg_color = "#cccccc", -- Normal color for text fg_color = "#cccccc", -- Normal color for text
fg_color_focus = "#ffffff", -- Color for focused text fg_color_focus = "#ffffff", -- Color for focused text
bg_color_focus = "#282828", -- Color for the focused items bg_color_focus = "#282828", -- Color for the focused items
@ -80,32 +80,32 @@ The module exports a function that can be added to your tasklist as a `update_ca
### Usage ### Usage
```lua ```lua
awful.widget.tasklist({ awful.widget.tasklist({
screen = s, screen = s,
filter = awful.widget.tasklist.filter.currenttags, filter = awful.widget.tasklist.filter.currenttags,
layout = { layout = {
spacing = dpi(10), spacing = dpi(10),
layout = wibox.layout.fixed.vertical, layout = wibox.layout.fixed.vertical,
}, },
style = { style = {
bg_normal = "#00000000", bg_normal = "#00000000",
}, },
widget_template = { widget_template = {
{ {
{ {
widget = wibox.widget.imagebox, widget = wibox.widget.imagebox,
id = "icon_role", id = "icon_role",
align = "center", align = "center",
valign = "center", valign = "center",
}, },
width = dpi(24), width = dpi(24),
height = dpi(24), height = dpi(24),
widget = wibox.container.constraint, widget = wibox.container.constraint,
}, },
widget = wibox.container.background, -- IT MUST BE A CONTAINER WIDGET AS THAT IS WHAT THE FUNCTION EXPECTS 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, update_callback = require("bling.widget.tabbed_misc").custom_tasklist,
id = "background_role", id = "background_role",
}, },
}) })
``` ```
If you need to do something else, it can be used like so If you need to do something else, it can be used like so

View File

@ -2,7 +2,7 @@
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. 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/3nYe1e8.gif) ![](https://imgur.com/zFdvs4K.gif)
*gif by [javacafe](https://github.com/JavaCafe01)* *gif by [javacafe](https://github.com/JavaCafe01)*
@ -24,19 +24,25 @@ bling.widget.tag_preview.enable {
top = 30, top = 30,
left = 30 left = 30
} }
}) })
end 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: Here are the signals available:
```lua ```lua
-- bling::tag_preview::update -- first line is the signal -- bling::tag_preview::update -- first line is the signal
-- t (tag) -- indented lines are function parameters -- t (tag) -- indented lines are function parameters
-- bling::tag_preview::visibility -- bling::tag_preview::visibility
-- s (screen) -- s (screen)
-- v (boolean) -- v (boolean)
``` ```
By default, the widget is not visible. You must implement when it will update and when it will show. By default, the widget is not visible. You must implement when it will update and when it will show.
@ -100,7 +106,7 @@ s.mytaglist = awful.widget.taglist {
create_callback = function(self, c3, index, objects) --luacheck: no unused args create_callback = function(self, c3, index, objects) --luacheck: no unused args
self:get_children_by_id('index_role')[1].markup = '<b> '..index..' </b>' self:get_children_by_id('index_role')[1].markup = '<b> '..index..' </b>'
self:connect_signal('mouse::enter', function() self:connect_signal('mouse::enter', function()
-- BLING: Only show widget when there are clients in the tag -- BLING: Only show widget when there are clients in the tag
if #c3:clients() > 0 then if #c3:clients() > 0 then
-- BLING: Update the widget with the new tag -- BLING: Update the widget with the new tag
@ -119,7 +125,7 @@ s.mytaglist = awful.widget.taglist {
-- BLING: Turn the widget off -- BLING: Turn the widget off
awesome.emit_signal("bling::tag_preview::visibility", s, false) awesome.emit_signal("bling::tag_preview::visibility", s, false)
if self.has_backup then self.bg = self.backup end if self.has_backup then self.bg = self.backup end
end) end)
end, end,
@ -132,17 +138,18 @@ s.mytaglist = awful.widget.taglist {
``` ```
### Theme Variables ### Theme Variables
```lua ```lua
theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA) 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_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_opacity = 0.5 -- Opacity of each client
theme.tag_preview_client_bg = "#000000" -- The bg color 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_color = "#ffffff" -- The border color of each client
theme.tag_preview_client_border_width = 3 -- The border width 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_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_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_border_width = 3 -- The border width of the widget
theme.tag_preview_widget_margin = 0 -- The margin 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). 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

@ -12,46 +12,46 @@ To enable:
```lua ```lua
bling.widget.task_preview.enable { bling.widget.task_preview.enable {
x = 20, -- The x-coord of the popup x = 20, -- The x-coord of the popup
y = 20, -- The y-coord of the popup y = 20, -- The y-coord of the popup
height = 200, -- The height of the popup height = 200, -- The height of the popup
width = 200, -- The width of the popup width = 200, -- The width of the popup
placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y) placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y)
awful.placement.bottom(c, { awful.placement.bottom(c, {
margins = { margins = {
bottom = 30 bottom = 30
} }
}) })
end 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 - 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 ```lua
bling.widget.task_preview.enable { bling.widget.task_preview.enable {
x = 20, -- The x-coord of the popup x = 20, -- The x-coord of the popup
y = 20, -- The y-coord of the popup y = 20, -- The y-coord of the popup
height = 200, -- The height of the popup height = 200, -- The height of the popup
width = 200, -- The width of the popup width = 200, -- The width of the popup
placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y) placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y)
awful.placement.bottom(c, { awful.placement.bottom(c, {
margins = { margins = {
bottom = 30 bottom = 30
} }
}) })
end, end,
-- Your widget will automatically conform to the given size due to a constraint container. -- Your widget will automatically conform to the given size due to a constraint container.
widget_structure = { widget_structure = {
{ {
{ {
{ {
id = 'icon_role', id = 'icon_role',
widget = awful.widget.clienticon, -- The client icon widget = awful.widget.clienticon, -- The client icon
}, },
{ {
id = 'name_role' -- The client name / title id = 'name_role', -- The client name / title
widget = wibox.widget.textbox, widget = wibox.widget.textbox,
} },
layout = wibox.layout.flex.horizontal layout = wibox.layout.flex.horizontal
}, },
widget = wibox.container.margin, widget = wibox.container.margin,
@ -66,16 +66,16 @@ bling.widget.task_preview.enable {
}, },
layout = wibox.layout.fixed.vertical layout = wibox.layout.fixed.vertical
} }
} }
``` ```
Here are the signals available: Here are the signals available:
```lua ```lua
-- bling::task_preview::visibility -- first line is the signal -- bling::task_preview::visibility -- first line is the signal
-- s (screen) -- indented lines are function parameters -- s (screen) -- indented lines are function parameters
-- v (boolean) -- v (boolean)
-- c (client) -- c (client)
``` ```
By default, the widget is not visible. You must implement when it will update and when it will show. By default, the widget is not visible. You must implement when it will update and when it will show.
@ -124,7 +124,7 @@ s.mytasklist = awful.widget.tasklist {
nil, nil,
create_callback = function(self, c, index, objects) --luacheck: no unused args create_callback = function(self, c, index, objects) --luacheck: no unused args
self:get_children_by_id('clienticon')[1].client = c self:get_children_by_id('clienticon')[1].client = c
-- BLING: Toggle the popup on hover and disable it off hover -- BLING: Toggle the popup on hover and disable it off hover
self:connect_signal('mouse::enter', function() self:connect_signal('mouse::enter', function()
awesome.emit_signal("bling::task_preview::visibility", s, awesome.emit_signal("bling::task_preview::visibility", s,
@ -142,11 +142,11 @@ s.mytasklist = awful.widget.tasklist {
### Theme Variables ### Theme Variables
```lua ```lua
theme.task_preview_widget_border_radius = 0 -- Border radius of the widget (With AA) 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_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_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_border_width = 3 -- The border width of the widget
theme.task_preview_widget_margin = 0 -- The margin 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). 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,64 @@
## 🎨 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
}
```
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
```

View File

@ -1,3 +1,12 @@
local tonumber = tonumber
local string = string
local math = math
local floor = math.floor
local max = math.max
local min = math.min
local abs = math.abs
local format = string.format
local _color = {} local _color = {}
--- Try to guess if a color is dark or light. --- Try to guess if a color is dark or light.
@ -13,6 +22,14 @@ function _color.is_dark(color)
return (numeric_value < 383) return (numeric_value < 383)
end end
function _color.is_opaque(color)
if type(color) == "string" then
color = _color.hex_to_rgba(color)
end
return color.a < 0.01
end
--- Lighten a color. --- Lighten a color.
-- --
-- @string color The color to lighten with hexadecimal HTML format `"#RRGGBB"`. -- @string color The color to lighten with hexadecimal HTML format `"#RRGGBB"`.
@ -49,4 +66,93 @@ function _color.darken(color, amount)
return _color.lighten(color, -amount) return _color.lighten(color, -amount)
end end
-- Returns a value that is clipped to interval edges if it falls outside the interval
function _color.clip(num, min_num, max_num)
return max(min(num, max_num), min_num)
end
-- Converts the given hex color to rgba
function _color.hex_to_rgba(color)
color = color:gsub("#", "")
return { r = tonumber("0x" .. color:sub(1, 2)),
g = tonumber("0x" .. color:sub(3, 4)),
b = tonumber("0x" .. color:sub(5, 6)),
a = #color == 8 and tonumber("0x" .. color:sub(7, 8)) or 255 }
end
-- Converts the given rgba color to hex
function _color.rgba_to_hex(color)
local r = _color.clip(color.r or color[1], 0, 255)
local g = _color.clip(color.g or color[2], 0, 255)
local b = _color.clip(color.b or color[3], 0, 255)
local a = _color.clip(color.a or color[4] or 255, 0, 255)
return "#" .. format("%02x%02x%02x%02x",
floor(r),
floor(g),
floor(b),
floor(a))
end
-- Converts the given hex color to hsv
function _color.hex_to_hsv(color)
local color = _color.hex2rgb(color)
local C_max = max(color.r, color.g, color.b)
local C_min = min(color.r, color.g, color.b)
local delta = C_max - C_min
local H, S, V
if delta == 0 then
H = 0
elseif C_max == color.r then
H = 60 * (((color.g - color.b) / delta) % 6)
elseif C_max == color.g then
H = 60 * (((color.b - color.r) / delta) + 2)
elseif C_max == color.b then
H = 60 * (((color.r - color.g) / delta) + 4)
end
if C_max == 0 then
S = 0
else
S = delta / C_max
end
V = C_max
return { h = H,
s = S * 100,
v = V * 100 }
end
-- Converts the given hsv color to hex
function _color.hsv_to_hex(H, S, V)
S = S / 100
V = V / 100
if H > 360 then H = 360 end
if H < 0 then H = 0 end
local C = V * S
local X = C * (1 - abs(((H / 60) % 2) - 1))
local m = V - C
local r_, g_, b_ = 0, 0, 0
if H >= 0 and H < 60 then
r_, g_, b_ = C, X, 0
elseif H >= 60 and H < 120 then
r_, g_, b_ = X, C, 0
elseif H >= 120 and H < 180 then
r_, g_, b_ = 0, C, X
elseif H >= 180 and H < 240 then
r_, g_, b_ = 0, X, C
elseif H >= 240 and H < 300 then
r_, g_, b_ = X, 0, C
elseif H >= 300 and H < 360 then
r_, g_, b_ = C, 0, X
end
local r, g, b = (r_ + m) * 255, (g_ + m) * 255, (b_ + m) * 255
return ("#%02x%02x%02x"):format(floor(r), floor(g), floor(b))
end
function _color.multiply(color, amount)
return { _color.clip(color.r * amount, 0, 255),
_color.clip(color.g * amount, 0, 255),
_color.clip(color.b * amount, 0, 255),
255 }
end
return _color return _color

134
helpers/icon_theme.lua Normal file
View File

@ -0,0 +1,134 @@
local Gio = require("lgi").Gio
local Gtk = require("lgi").Gtk
local gobject = require("gears.object")
local gtable = require("gears.table")
local helpers = require("helpers")
local setmetatable = setmetatable
local ipairs = ipairs
local icon_theme = { mt = {} }
function icon_theme:get_client_icon_path(client)
local function find_icon(class)
if self._private.client_icon_cache[class] ~= nil then
return self._private.client_icon_cache[class]
end
for _, app in ipairs(Gio.AppInfo.get_all()) do
local id = Gio.AppInfo.get_id(app)
if id:match(helpers.misc.case_insensitive_pattern(class)) then
self._private.client_icon_cache[class] = self:get_gicon_path(Gio.AppInfo.get_icon(app))
return self._private.client_icon_cache[class]
end
end
return nil
end
local class = client.class
if class == "jetbrains-studio" then
class = "android-studio"
end
local icon = self:get_icon_path("gnome-window-manager")
if class ~= nil then
class = class:gsub("[%-]", "%%%0")
icon = find_icon(class) or icon
class = client.class
class = class:gsub("[%-]", "")
icon = find_icon(class) or icon
class = client.class
class = class:gsub("[%-]", ".")
icon = find_icon(class) or icon
class = client.class
class = class:match("(.-)-") or class
class = class:match("(.-)%.") or class
class = class:match("(.-)%s+") or class
class = class:gsub("[%-]", "%%%0")
icon = find_icon(class) or icon
end
return icon
end
function icon_theme:choose_icon(icons_names)
local icon_info = Gtk.IconTheme.choose_icon(self.gtk_theme, icons_names, self.icon_size, 0);
if icon_info then
local icon_path = Gtk.IconInfo.get_filename(icon_info)
if icon_path then
return icon_path
end
end
return ""
end
function icon_theme:get_gicon_path(gicon)
if gicon == nil then
return ""
end
if self._private.icon_cache[gicon] ~= nil then
return self._private.icon_cache[gicon]
end
local icon_info = Gtk.IconTheme.lookup_by_gicon(self.gtk_theme, gicon, self.icon_size, 0);
if icon_info then
local icon_path = Gtk.IconInfo.get_filename(icon_info)
if icon_path then
self._private.icon_cache[gicon] = icon_path
return icon_path
end
end
return ""
end
function icon_theme:get_icon_path(icon_name)
if self._private.icon_cache[icon_name] ~= nil then
return self._private.icon_cache[icon_name]
end
local icon_info = Gtk.IconTheme.lookup_icon(self.gtk_theme, icon_name, self.icon_size, 0);
if icon_info then
local icon_path = Gtk.IconInfo.get_filename(icon_info)
if icon_path then
self._private.icon_cache[icon_name] = icon_path
return icon_path
end
end
return ""
end
local function new(theme_name, icon_size)
local ret = gobject{}
gtable.crush(ret, icon_theme, true)
ret._private = {}
ret._private.client_icon_cache = {}
ret._private.icon_cache = {}
ret.name = theme_name or nil
ret.icon_size = icon_size or 48
if theme_name then
ret.gtk_theme = Gtk.IconTheme.new()
Gtk.IconTheme.set_custom_theme(ret.gtk_theme, theme_name);
else
ret.gtk_theme = Gtk.IconTheme.get_default()
end
return ret
end
function icon_theme.mt:__call(...)
return new(...)
end
return setmetatable(icon_theme, icon_theme.mt)

View File

@ -1,7 +1,4 @@
local awful = require("awful") local awful = require("awful")
local gears = require("gears")
local gcolor = require("gears.color")
local beautiful = require("beautiful")
local math = math local math = math
local mylayout = {} local mylayout = {}
@ -58,6 +55,7 @@ function mylayout.arrange(p)
-- iterate through slaves -- iterate through slaves
for idx = 1, nslaves do -- idx=nmaster+1,#p.clients do for idx = 1, nslaves do -- idx=nmaster+1,#p.clients do
local c = p.clients[idx + nmaster] local c = p.clients[idx + nmaster]
local g
if idx % 2 == 0 then if idx % 2 == 0 then
g = { g = {
x = area.x, x = area.x,
@ -83,20 +81,4 @@ function mylayout.arrange(p)
end end
end end
local icon_raw = gears.filesystem.get_configuration_dir() return mylayout
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/centered.png"
local function get_icon()
if icon_raw ~= nil then
return gcolor.recolor_image(icon_raw, beautiful.fg_normal)
else
return nil
end
end
return {
layout = mylayout,
icon_raw = icon_raw,
get_icon = get_icon,
}

View File

@ -1,8 +1,3 @@
local awful = require("awful")
local gears = require("gears")
local gcolor = require("gears.color")
local beautiful = require("beautiful")
local mylayout = {} local mylayout = {}
mylayout.name = "deck" mylayout.name = "deck"
@ -39,20 +34,4 @@ function mylayout.arrange(p)
end end
end end
local icon_raw = gears.filesystem.get_configuration_dir() return mylayout
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/deck.png"
local function get_icon()
if icon_raw ~= nil then
return gcolor.recolor_image(icon_raw, beautiful.fg_normal)
else
return nil
end
end
return {
layout = mylayout,
icon_raw = icon_raw,
get_icon = get_icon,
}

View File

@ -1,6 +1,3 @@
local gears = require("gears")
local gcolor = require("gears.color")
local beautiful = require("beautiful")
local math = math local math = math
local screen = screen local screen = screen
local mylayout = {} local mylayout = {}
@ -77,20 +74,4 @@ function mylayout.arrange(p)
divide(p, g, 1, #cls, cls, mwfact, mcount) divide(p, g, 1, #cls, cls, mwfact, mcount)
end end
local icon_raw = gears.filesystem.get_configuration_dir() return mylayout
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/equalarea.png"
local function get_icon()
if icon_raw ~= nil then
return gcolor.recolor_image(icon_raw, beautiful.fg_normal)
else
return nil
end
end
return {
layout = mylayout,
icon_raw = icon_raw,
get_icon = get_icon,
}

View File

@ -1,7 +1,3 @@
local awful = require("awful")
local gears = require("gears")
local gcolor = require("gears.color")
local beautiful = require("beautiful")
local math = math local math = math
local mylayout = {} local mylayout = {}
@ -57,20 +53,4 @@ function mylayout.arrange(p)
end end
end end
local icon_raw = gears.filesystem.get_configuration_dir() return mylayout
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/horizontal.png"
local function get_icon()
if icon_raw ~= nil then
return gcolor.recolor_image(icon_raw, beautiful.fg_normal)
else
return nil
end
end
return {
layout = mylayout,
icon_raw = icon_raw,
get_icon = get_icon,
}

View File

@ -1,30 +1,44 @@
local beautiful = require("beautiful") local beautiful = require("beautiful")
local gears = require("gears")
local mstab = require(... .. ".mstab") local M = {}
beautiful.layout_mstab = mstab.get_icon() local relative_lua_path = tostring(...)
local vertical = require(... .. ".vertical") local function get_layout_icon_path(name)
beautiful.layout_vertical = vertical.get_icon() local relative_icon_path = relative_lua_path
:match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/" .. name .. ".png"
local horizontal = require(... .. ".horizontal") for p in package.path:gmatch('([^;]+)') do
beautiful.layout_horizontal = horizontal.get_icon() p = p:gsub("?.*", "")
local absolute_icon_path = p .. relative_icon_path
if gears.filesystem.file_readable(absolute_icon_path) then
return absolute_icon_path
end
end
end
local centered = require(... .. ".centered") local function get_icon(icon_raw)
beautiful.layout_centered = centered.get_icon() if icon_raw ~= nil then
return gears.color.recolor_image(icon_raw, beautiful.fg_normal)
else
return nil
end
end
local equalarea = require(... .. ".equalarea") local layouts = {
beautiful.layout_equalarea = equalarea.get_icon() "mstab",
"vertical",
local deck = require(... .. ".deck") "horizontal",
beautiful.layout_deck = deck.get_icon() "centered",
"equalarea",
local layout = { "deck"
mstab = mstab.layout,
centered = centered.layout,
vertical = vertical.layout,
horizontal = horizontal.layout,
equalarea = equalarea.layout,
deck = deck.layout,
} }
return layout for _, layout_name in ipairs(layouts) do
local icon_raw = get_layout_icon_path(layout_name)
beautiful["layout_" .. layout_name] = get_icon(icon_raw)
M[layout_name] = require(... .. "." .. layout_name)
end
return M

View File

@ -1,7 +1,6 @@
local awful = require("awful") local awful = require("awful")
local gears = require("gears") local gears = require("gears")
local wibox = require("wibox") local wibox = require("wibox")
local gcolor = require("gears.color")
local beautiful = require("beautiful") local beautiful = require("beautiful")
local mylayout = {} local mylayout = {}
@ -242,16 +241,4 @@ function mylayout.arrange(p)
) )
end end
local icon_raw = gears.filesystem.get_configuration_dir() return mylayout
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/mstab.png"
local function get_icon()
if icon_raw ~= nil then
return gcolor.recolor_image(icon_raw, beautiful.fg_normal)
else
return nil
end
end
return { layout = mylayout, icon_raw = icon_raw, get_icon = get_icon }

View File

@ -1,7 +1,3 @@
local awful = require("awful")
local gears = require("gears")
local gcolor = require("gears.color")
local beautiful = require("beautiful")
local math = math local math = math
local mylayout = {} local mylayout = {}
@ -57,20 +53,4 @@ function mylayout.arrange(p)
end end
end end
local icon_raw = gears.filesystem.get_configuration_dir() return mylayout
.. tostring(...):match("^.*bling"):gsub("%.", "/")
.. "/icons/layouts/vertical.png"
local function get_icon()
if icon_raw ~= nil then
return gcolor.recolor_image(icon_raw, beautiful.fg_normal)
else
return nil
end
end
return {
layout = mylayout,
icon_raw = icon_raw,
get_icon = get_icon,
}

View File

@ -23,6 +23,14 @@ local bar = require(
tabbed = {} tabbed = {}
-- helper function to connect to the (un)focus signals
local function update_tabbar_from(c)
if not c or not c.bling_tabbed then
return
end
tabbed.update_tabbar(c.bling_tabbed)
end
-- used to change focused tab relative to the currently focused one -- used to change focused tab relative to the currently focused one
tabbed.iter = function(idx) tabbed.iter = function(idx)
if not idx then if not idx then
@ -50,6 +58,8 @@ tabbed.remove = function(c)
awful.titlebar.hide(c, bar.position) awful.titlebar.hide(c, bar.position)
end end
c.bling_tabbed = nil c.bling_tabbed = nil
c:disconnect_signal("focus", update_tabbar_from)
c:disconnect_signal("unfocus", update_tabbar_from)
awesome.emit_signal("bling::tabbed::client_removed", tabobj, c) awesome.emit_signal("bling::tabbed::client_removed", tabobj, c)
tabbed.switch_to(tabobj, 1) tabbed.switch_to(tabobj, 1)
end end
@ -67,6 +77,8 @@ tabbed.add = function(c, tabobj)
if c.bling_tabbed then if c.bling_tabbed then
tabbed.remove(c) tabbed.remove(c)
end end
c:connect_signal("focus", update_tabbar_from)
c:connect_signal("unfocus", update_tabbar_from)
helpers.client.sync(c, tabobj.clients[tabobj.focused_idx]) helpers.client.sync(c, tabobj.clients[tabobj.focused_idx])
tabobj.clients[#tabobj.clients + 1] = c tabobj.clients[#tabobj.clients + 1] = c
tabobj.focused_idx = #tabobj.clients tabobj.focused_idx = #tabobj.clients
@ -218,12 +230,15 @@ end
tabbed.update_tabbar = function(tabobj) tabbed.update_tabbar = function(tabobj)
local flexlist = bar.layout() local flexlist = bar.layout()
local tabobj_focused_client = tabobj.clients[tabobj.focused_idx]
local tabobj_is_focused = (client.focus == tabobj_focused_client)
-- itearte over all tabbed clients to create the widget tabbed list -- itearte over all tabbed clients to create the widget tabbed list
for idx, c in ipairs(tabobj.clients) do for idx, c in ipairs(tabobj.clients) do
local buttons = gears.table.join(awful.button({}, 1, function() local buttons = gears.table.join(awful.button({}, 1, function()
tabbed.switch_to(tabobj, idx) tabbed.switch_to(tabobj, idx)
end)) end))
wid_temp = bar.create(c, (idx == tabobj.focused_idx), buttons) local wid_temp = bar.create(c, (idx == tabobj.focused_idx), buttons,
not tabobj_is_focused)
flexlist:add(wid_temp) flexlist:add(wid_temp)
end end
-- add tabbar to each tabbed client (clients will be hided anyway) -- add tabbar to each tabbed client (clients will be hided anyway)
@ -240,6 +255,8 @@ end
tabbed.init = function(c) tabbed.init = function(c)
local tabobj = {} local tabobj = {}
tabobj.clients = { c } tabobj.clients = { c }
c:connect_signal("focus", update_tabbar_from)
c:connect_signal("unfocus", update_tabbar_from)
tabobj.focused_idx = 1 tabobj.focused_idx = 1
tabbed.update(tabobj) tabbed.update(tabobj)
end end

View File

@ -36,6 +36,10 @@ theme.tabbar_bg_normal = "#000000" -- background color of the focused client on
theme.tabbar_fg_normal = "#ffffff" -- foreground 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_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_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
-- mstab -- mstab
theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients
@ -76,4 +80,25 @@ theme.task_preview_widget_border_color = "#ffffff" -- The border color of the wi
theme.task_preview_widget_border_width = 3 -- The border width 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 theme.task_preview_widget_margin = 0 -- The margin of the widget
-- window switcher
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
-- LuaFormatter on -- LuaFormatter on

1053
widget/app_launcher/init.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,656 @@
---------------------------------------------------------------------------
--- Modified Prompt module.
-- @author Julien Danjou &lt;julien@danjou.info&gt;
-- @copyright 2008 Julien Danjou
---------------------------------------------------------------------------
local akey = require("awful.key")
local keygrabber = require("awful.keygrabber")
local gobject = require("gears.object")
local gdebug = require('gears.debug')
local gtable = require("gears.table")
local gcolor = require("gears.color")
local gstring = require("gears.string")
local gfs = require("gears.filesystem")
local wibox = require("wibox")
local beautiful = require("beautiful")
local io = io
local table = table
local math = math
local ipairs = ipairs
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
local capi = { selection = selection }
local prompt = { mt = {} }
--- Private data
local data = {}
data.history = {}
local function itera(inc,a, i)
i = i + inc
local v = a[i]
if v then return i,v end
end
local function history_check_load(id, max)
if id and id ~= "" and not data.history[id] then
data.history[id] = { max = 50, table = {} }
if max then
data.history[id].max = max
end
local f = io.open(id, "r")
if not f then return end
-- Read history file
for line in f:lines() do
if gtable.hasitem(data.history[id].table, line) == nil then
table.insert(data.history[id].table, line)
if #data.history[id].table >= data.history[id].max then
break
end
end
end
f:close()
end
end
local function is_word_char(c)
if string.find(c, "[{[(,.:;_-+=@/ ]") then
return false
else
return true
end
end
local function cword_start(s, pos)
local i = pos
if i > 1 then
i = i - 1
end
while i >= 1 and not is_word_char(s:sub(i, i)) do
i = i - 1
end
while i >= 1 and is_word_char(s:sub(i, i)) do
i = i - 1
end
if i <= #s then
i = i + 1
end
return i
end
local function cword_end(s, pos)
local i = pos
while i <= #s and not is_word_char(s:sub(i, i)) do
i = i + 1
end
while i <= #s and is_word_char(s:sub(i, i)) do
i = i + 1
end
return i
end
local function history_save(id)
if data.history[id] then
gfs.make_parent_directories(id)
local f = io.open(id, "w")
if not f then
gdebug.print_warning("Failed to write the history to "..id)
return
end
for i = 1, math.min(#data.history[id].table, data.history[id].max) do
f:write(data.history[id].table[i] .. "\n")
end
f:close()
end
end
local function history_items(id)
if data.history[id] then
return #data.history[id].table
else
return -1
end
end
local function history_add(id, command)
if data.history[id] and command ~= "" then
local index = gtable.hasitem(data.history[id].table, command)
if index == nil then
table.insert(data.history[id].table, command)
-- Do not exceed our max_cmd
if #data.history[id].table > data.history[id].max then
table.remove(data.history[id].table, 1)
end
history_save(id)
else
-- Bump this command to the end of history
table.remove(data.history[id].table, index)
table.insert(data.history[id].table, command)
history_save(id)
end
end
end
local function have_multibyte_char_at(text, position)
return text:sub(position, position):wlen() == -1
end
local function prompt_text_with_cursor(args)
local char, spacer, text_start, text_end, ret
local text = args.text or ""
local _prompt = args.prompt or ""
local underline = args.cursor_ul or "none"
if args.select_all then
if #text == 0 then char = " " else char = gstring.xml_escape(text) end
spacer = " "
text_start = ""
text_end = ""
elseif #text < args.cursor_pos then
char = " "
spacer = ""
text_start = gstring.xml_escape(text)
text_end = ""
else
local offset = 0
if have_multibyte_char_at(text, args.cursor_pos) then
offset = 1
end
char = gstring.xml_escape(text:sub(args.cursor_pos, args.cursor_pos + offset))
spacer = " "
text_start = gstring.xml_escape(text:sub(1, args.cursor_pos - 1))
text_end = gstring.xml_escape(text:sub(args.cursor_pos + 1 + offset))
end
local cursor_color = gcolor.ensure_pango_color(args.cursor_color)
local text_color = gcolor.ensure_pango_color(args.text_color)
if args.highlighter then
text_start, text_end = args.highlighter(text_start, text_end)
end
ret = _prompt .. text_start .. "<span background=\"" .. cursor_color ..
"\" foreground=\"" .. text_color .. "\" underline=\"" .. underline ..
"\">" .. char .. "</span>" .. text_end .. spacer
return ret
end
local function update(self)
self.textbox:set_font(self.font)
self.textbox:set_markup(prompt_text_with_cursor{
text = self.command, text_color = self.fg_cursor, cursor_color = self.bg_cursor,
cursor_pos = self._private_cur_pos, cursor_ul = self.ul_cursor, select_all = self.select_all,
prompt = self.prompt, highlighter = self.highlighter })
end
local function exec(self, cb, command_to_history)
self.textbox:set_markup("")
history_add(self.history_path, command_to_history)
keygrabber.stop(self._private.grabber)
if cb then cb(self.command) end
if self.done_callback then
self.done_callback()
end
end
function prompt:start()
-- The cursor position
if self.reset_on_stop == true or self._private_cur_pos == nil then
self._private_cur_pos = (self.select_all and 1) or self.text:wlen() + 1
end
if self.reset_on_stop == true then self.text = "" self.command = "" end
self.textbox:set_font(self.font)
self.textbox:set_markup(prompt_text_with_cursor{
text = self.reset_on_stop and self.text or self.command, text_color = self.fg_cursor, cursor_color = self.bg_cursor,
cursor_pos = self._private_cur_pos, cursor_ul = self.ul_cursor, select_all = self.select_all,
prompt = self.prompt, highlighter = self.highlighter})
self._private.search_term = nil
history_check_load(self.history_path, self.history_max)
local history_index = history_items(self.history_path) + 1
-- The completion element to use on completion request.
local ncomp = 1
local command_before_comp
local cur_pos_before_comp
self._private.grabber = keygrabber.run(function(modifiers, key, event)
-- Convert index array to hash table
local mod = {}
for _, v in ipairs(modifiers) do mod[v] = true end
if event ~= "press" then
if self.keyreleased_callback then
self.keyreleased_callback(mod, key, self.command)
end
return
end
-- Call the user specified callback. If it returns true as
-- the first result then return from the function. Treat the
-- second and third results as a new command and new prompt
-- to be set (if provided)
if self.keypressed_callback then
local user_catched, new_command, new_prompt =
self.keypressed_callback(mod, key, self.command)
if new_command or new_prompt then
if new_command then
self.command = new_command
end
if new_prompt then
self.prompt = new_prompt
end
update(self)
end
if user_catched then
if self.changed_callback then
self.changed_callback(self.command)
end
return
end
end
local filtered_modifiers = {}
-- User defined cases
if self.hooks[key] then
-- Remove caps and num lock
for _, m in ipairs(modifiers) do
if not gtable.hasitem(akey.ignore_modifiers, m) then
table.insert(filtered_modifiers, m)
end
end
for _,v in ipairs(self.hooks[key]) do
if #filtered_modifiers == #v[1] then
local match = true
for _,v2 in ipairs(v[1]) do
match = match and mod[v2]
end
if match then
local cb
local ret, quit = v[3](self.command)
local original_command = self.command
-- Support both a "simple" and a "complex" way to
-- control if the prompt should quit.
quit = quit == nil and (ret ~= true) or (quit~=false)
-- Allow the callback to change the command
self.command = (ret ~= true) and ret or self.command
-- Quit by default, but allow it to be disabled
if ret and type(ret) ~= "boolean" then
cb = self.exe_callback
if not quit then
self._private_cur_pos = ret:wlen() + 1
update(self)
end
elseif quit then
-- No callback.
cb = function() end
end
-- Execute the callback
if cb then
exec(self, cb, original_command)
end
return
end
end
end
end
-- Get out cases
if (mod.Control and (key == "c" or key == "g"))
or (not mod.Control and key == "Escape") then
self:stop()
return false
elseif (mod.Control and (key == "j" or key == "m"))
-- or (not mod.Control and key == "Return")
-- or (not mod.Control and key == "KP_Enter")
then
exec(self, self.exe_callback, self.command)
-- We already unregistered ourselves so we don't want to return
-- true, otherwise we may unregister someone else.
return
end
-- Control cases
if mod.Control then
self.select_all = nil
if key == "v" then
local selection = capi.selection()
if selection then
-- Remove \n
local n = selection:find("\n")
if n then
selection = selection:sub(1, n - 1)
end
self.command = self.command:sub(1, self._private_cur_pos - 1) .. selection .. self.command:sub(self._private_cur_pos)
self._private_cur_pos = self._private_cur_pos + #selection
end
elseif key == "a" then
self._private_cur_pos = 1
elseif key == "b" then
if self._private_cur_pos > 1 then
self._private_cur_pos = self._private_cur_pos - 1
if have_multibyte_char_at(self.command, self._private_cur_pos) then
self._private_cur_pos = self._private_cur_pos - 1
end
end
elseif key == "d" then
if self._private_cur_pos <= #self.command then
self.command = self.command:sub(1, self._private_cur_pos - 1) .. self.command:sub(self._private_cur_pos + 1)
end
elseif key == "p" then
if history_index > 1 then
history_index = history_index - 1
self.command = data.history[self.history_path].table[history_index]
self._private_cur_pos = #self.command + 2
end
elseif key == "n" then
if history_index < history_items(self.history_path) then
history_index = history_index + 1
self.command = data.history[self.history_path].table[history_index]
self._private_cur_pos = #self.command + 2
elseif history_index == history_items(self.history_path) then
history_index = history_index + 1
self.command = ""
self._private_cur_pos = 1
end
elseif key == "e" then
self._private_cur_pos = #self.command + 1
elseif key == "r" then
self._private.search_term = self._private.search_term or self.command:sub(1, self._private_cur_pos - 1)
for i,v in (function(a,i) return itera(-1,a,i) end), data.history[self.history_path].table, history_index do
if v:find(self._private.search_term,1,true) ~= nil then
self.command=v
history_index=i
self._private_cur_pos=#self.command+1
break
end
end
elseif key == "s" then
self._private.search_term = self._private.search_term or self.command:sub(1, self._private_cur_pos - 1)
for i,v in (function(a,i) return itera(1,a,i) end), data.history[self.history_path].table, history_index do
if v:find(self._private.search_term,1,true) ~= nil then
self.command=v
history_index=i
self._private_cur_pos=#self.command+1
break
end
end
elseif key == "f" then
if self._private_cur_pos <= #self.command then
if have_multibyte_char_at(self.command, self._private_cur_pos) then
self._private_cur_pos = self._private_cur_pos + 2
else
self._private_cur_pos = self._private_cur_pos + 1
end
end
elseif key == "h" then
if self._private_cur_pos > 1 then
local offset = 0
if have_multibyte_char_at(self.command, self._private_cur_pos - 1) then
offset = 1
end
self.command = self.command:sub(1, self._private_cur_pos - 2 - offset) .. self.command:sub(self._private_cur_pos)
self._private_cur_pos = self._private_cur_pos - 1 - offset
end
elseif key == "k" then
self.command = self.command:sub(1, self._private_cur_pos - 1)
elseif key == "u" then
self.command = self.command:sub(self._private_cur_pos, #self.command)
self._private_cur_pos = 1
elseif key == "Prior" then
self._private.search_term = self.command:sub(1, self._private_cur_pos - 1) or ""
for i,v in (function(a,i) return itera(-1,a,i) end), data.history[self.history_path].table, history_index do
if v:find(self._private.search_term,1,true) == 1 then
self.command=v
history_index=i
break
end
end
elseif key == "Next" then
self._private.search_term = self.command:sub(1, self._private_cur_pos - 1) or ""
for i,v in (function(a,i) return itera(1,a,i) end), data.history[self.history_path].table, history_index do
if v:find(self._private.search_term,1,true) == 1 then
self.command=v
history_index=i
break
end
end
elseif key == "w" or key == "BackSpace" then
local wstart = 1
local wend = 1
local cword_start_pos = 1
local cword_end_pos = 1
while wend < self._private_cur_pos do
wend = self.command:find("[{[(,.:;_-+=@/ ]", wstart)
if not wend then wend = #self.command + 1 end
if self._private_cur_pos >= wstart and self._private_cur_pos <= wend + 1 then
cword_start_pos = wstart
cword_end_pos = self._private_cur_pos - 1
break
end
wstart = wend + 1
end
self.command = self.command:sub(1, cword_start_pos - 1) .. self.command:sub(cword_end_pos + 1)
self._private_cur_pos = cword_start_pos
elseif key == "Delete" then
-- delete from history only if:
-- we are not dealing with a new command
-- the user has not edited an existing entry
if self.command == data.history[self.history_path].table[history_index] then
table.remove(data.history[self.history_path].table, history_index)
if history_index <= history_items(self.history_path) then
self.command = data.history[self.history_path].table[history_index]
self._private_cur_pos = #self.command + 2
elseif history_index > 1 then
history_index = history_index - 1
self.command = data.history[self.history_path].table[history_index]
self._private_cur_pos = #self.command + 2
else
self.command = ""
self._private_cur_pos = 1
end
end
end
elseif mod.Mod1 or mod.Mod3 then
if key == "b" then
self._private_cur_pos = cword_start(self.command, self._private_cur_pos)
elseif key == "f" then
self._private_cur_pos = cword_end(self.command, self._private_cur_pos)
elseif key == "d" then
self.command = self.command:sub(1, self._private_cur_pos - 1) .. self.command:sub(cword_end(self.command, self._private_cur_pos))
elseif key == "BackSpace" then
local wstart = cword_start(self.command, self._private_cur_pos)
self.command = self.command:sub(1, wstart - 1) .. self.command:sub(self._private_cur_pos)
self._private_cur_pos = wstart
end
else
if self.completion_callback then
if key == "Tab" or key == "ISO_Left_Tab" then
if key == "ISO_Left_Tab" or mod.Shift then
if ncomp == 1 then return end
if ncomp == 2 then
self.command = command_before_comp
self.textbox:set_font(self.font)
self.textbox:set_markup(prompt_text_with_cursor{
text = command_before_comp, text_color = self.fg_cursor, cursor_color = self.bg_cursor,
cursor_pos = self._private_cur_pos, cursor_ul = self.ul_cursor, select_all = self.select_all,
prompt = self.prompt })
self._private_cur_pos = cur_pos_before_comp
ncomp = 1
return
end
ncomp = ncomp - 2
elseif ncomp == 1 then
command_before_comp = self.command
cur_pos_before_comp = self._private_cur_pos
end
local matches
self.command, self._private_cur_pos, matches = self.completion_callback(command_before_comp, cur_pos_before_comp, ncomp)
ncomp = ncomp + 1
key = ""
-- execute if only one match found and autoexec flag set
if matches and #matches == 1 and args.autoexec then
exec(self, self.exe_callback)
return
end
elseif key ~= "Shift_L" and key ~= "Shift_R" then
ncomp = 1
end
end
-- Typin cases
if mod.Shift and key == "Insert" then
local selection = capi.selection()
if selection then
-- Remove \n
local n = selection:find("\n")
if n then
selection = selection:sub(1, n - 1)
end
self.command = self.command:sub(1, self._private_cur_pos - 1) .. selection .. self.command:sub(self._private_cur_pos)
self._private_cur_pos = self._private_cur_pos + #selection
end
elseif key == "Home" then
self._private_cur_pos = 1
elseif key == "End" then
self._private_cur_pos = #self.command + 1
elseif key == "BackSpace" then
if self._private_cur_pos > 1 then
local offset = 0
if have_multibyte_char_at(self.command, self._private_cur_pos - 1) then
offset = 1
end
self.command = self.command:sub(1, self._private_cur_pos - 2 - offset) .. self.command:sub(self._private_cur_pos)
self._private_cur_pos = self._private_cur_pos - 1 - offset
end
elseif key == "Delete" then
self.command = self.command:sub(1, self._private_cur_pos - 1) .. self.command:sub(self._private_cur_pos + 1)
elseif key == "Left" then
self._private_cur_pos = self._private_cur_pos - 1
elseif key == "Right" then
self._private_cur_pos = self._private_cur_pos + 1
elseif key == "Prior" then
if history_index > 1 then
history_index = history_index - 1
self.command = data.history[self.history_path].table[history_index]
self._private_cur_pos = #self.command + 2
end
elseif key == "Next" then
if history_index < history_items(self.history_path) then
history_index = history_index + 1
self.command = data.history[self.history_path].table[history_index]
self._private_cur_pos = #self.command + 2
elseif history_index == history_items(self.history_path) then
history_index = history_index + 1
self.command = ""
self._private_cur_pos = 1
end
else
-- wlen() is UTF-8 aware but #key is not,
-- so check that we have one UTF-8 char but advance the cursor of # position
if key:wlen() == 1 then
if self.select_all then self.command = "" end
self.command = self.command:sub(1, self._private_cur_pos - 1) .. key .. self.command:sub(self._private_cur_pos)
self._private_cur_pos = self._private_cur_pos + #key
end
end
if self._private_cur_pos < 1 then
self._private_cur_pos = 1
elseif self._private_cur_pos > #self.command + 1 then
self._private_cur_pos = #self.command + 1
end
self.select_all = nil
end
update(self)
if self.changed_callback then
self.changed_callback(self.command)
end
end)
end
function prompt:stop()
keygrabber.stop(self._private.grabber)
history_save(self.history_path)
if self.done_callback then self.done_callback() end
return false
end
local function new(args)
args = args or {}
args.command = args.text or ""
args.prompt = args.prompt or ""
args.text = args.text or ""
args.font = args.font or beautiful.prompt_font or beautiful.font
args.bg_cursor = args.bg_cursor or beautiful.prompt_bg_cursor or beautiful.bg_focus or "white"
args.fg_cursor = args.fg_cursor or beautiful.prompt_fg_cursor or beautiful.fg_focus or "black"
args.ul_cursor = args.ul_cursor or nil
args.reset_on_stop = args.reset_on_stop == nil and true or args.reset_on_stop
args.select_all = args.select_all or nil
args.highlighter = args.highlighter or nil
args.hooks = args.hooks or {}
args.keypressed_callback = args.keypressed_callback or nil
args.changed_callback = args.changed_callback or nil
args.done_callback = args.done_callback or nil
args.history_max = args.history_max or nil
args.history_path = args.history_path or nil
args.completion_callback = args.completion_callback or nil
args.exe_callback = args.exe_callback or nil
args.textbox = args.textbox or wibox.widget.textbox()
-- Build the hook map
local hooks = {}
for _,v in ipairs(args.hooks) do
if #v == 3 then
local _,key,callback = unpack(v)
if type(callback) == "function" then
hooks[key] = hooks[key] or {}
hooks[key][#hooks[key]+1] = v
else
gdebug.print_warning("The hook's 3rd parameter has to be a function.")
end
else
gdebug.print_warning("The hook has to have 3 parameters.")
end
end
args.hooks = hooks
local ret = gobject({})
ret._private = {}
gtable.crush(ret, prompt)
gtable.crush(ret, args)
return ret
end
function prompt.mt:__call(...)
return new(...)
end
return setmetatable(prompt, prompt.mt)

View File

@ -3,4 +3,5 @@ return {
task_preview = require(... .. ".task_preview"), task_preview = require(... .. ".task_preview"),
window_switcher = require(... .. ".window_switcher"), window_switcher = require(... .. ".window_switcher"),
tabbed_misc = require(... .. ".tabbed_misc"), tabbed_misc = require(... .. ".tabbed_misc"),
app_launcher = require(... .. ".app_launcher"),
} }

View File

@ -8,16 +8,20 @@ local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff"
local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000" local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000"
local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000" local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000"
local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff" local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff"
local bg_focus_inactive = beautiful.tabbar_bg_focus_inactive or bg_focus
local fg_focus_inactive = beautiful.tabbar_fg_focus_inactive or fg_focus
local bg_normal_inactive = beautiful.tabbar_bg_normal_inactive or bg_normal
local fg_normal_inactive = beautiful.tabbar_fg_normal_inactive or fg_normal
local font = beautiful.tabbar_font or beautiful.font or "Hack 15" local font = beautiful.tabbar_font or beautiful.font or "Hack 15"
local size = beautiful.tabbar_size or 40 local size = beautiful.tabbar_size or 40
local position = beautiful.tabbar_position or "bottom" local position = beautiful.tabbar_position or "bottom"
local function create(c, focused_bool, buttons) local function create(c, focused_bool, buttons, inactive_bool)
local bg_temp = bg_normal local bg_temp = inactive_bool and bg_normal_inactive or bg_normal
local fg_temp = fg_normal local fg_temp = inactive_bool and fg_normal_inactive or fg_normal
if focused_bool then if focused_bool then
bg_temp = bg_focus bg_temp = inactive_bool and bg_focus_inactive or bg_focus
fg_temp = fg_focus fg_temp = inactive_bool and fg_focus_inactive or fg_focus
end end
local wid_temp = wibox.widget({ local wid_temp = wibox.widget({
{ {

View File

@ -7,18 +7,22 @@ local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff"
local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000" local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000"
local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000" local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000"
local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff" local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff"
local bg_focus_inactive = beautiful.tabbar_bg_focus_inactive or bg_focus
local fg_focus_inactive = beautiful.tabbar_fg_focus_inactive or fg_focus
local bg_normal_inactive = beautiful.tabbar_bg_normal_inactive or bg_normal
local fg_normal_inactive = beautiful.tabbar_fg_normal_inactive or fg_normal
local font = beautiful.tabbar_font or beautiful.font or "Hack 15" local font = beautiful.tabbar_font or beautiful.font or "Hack 15"
local size = beautiful.tabbar_size or 20 local size = beautiful.tabbar_size or 20
local position = beautiful.tabbar_position or "top" local position = beautiful.tabbar_position or "top"
local function create(c, focused_bool, buttons) local function create(c, focused_bool, buttons, inactive_bool)
local flexlist = wibox.layout.flex.horizontal() local flexlist = wibox.layout.flex.horizontal()
local title_temp = c.name or c.class or "-" local title_temp = c.name or c.class or "-"
local bg_temp = bg_normal local bg_temp = inactive_bool and bg_normal_inactive or bg_normal
local fg_temp = fg_normal local fg_temp = inactive_bool and fg_normal_inactive or fg_normal
if focused_bool then if focused_bool then
bg_temp = bg_focus bg_temp = inactive_bool and bg_focus_inactive or bg_focus
fg_temp = fg_focus fg_temp = inactive_bool and fg_focus_inactive or fg_focus
end end
local text_temp = wibox.widget.textbox() local text_temp = wibox.widget.textbox()
text_temp.align = "center" text_temp.align = "center"

View File

@ -10,6 +10,10 @@ local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff"
local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000" local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000"
local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000" local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000"
local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff" local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff"
local bg_focus_inactive = beautiful.tabbar_bg_focus_inactive or bg_focus
local fg_focus_inactive = beautiful.tabbar_fg_focus_inactive or fg_focus
local bg_normal_inactive = beautiful.tabbar_bg_normal_inactive or bg_normal
local fg_normal_inactive = beautiful.tabbar_fg_normal_inactive or fg_normal
local font = beautiful.tabbar_font or beautiful.font or "Hack 15" local font = beautiful.tabbar_font or beautiful.font or "Hack 15"
local size = beautiful.tabbar_size or dpi(40) local size = beautiful.tabbar_size or dpi(40)
local border_radius = beautiful.mstab_border_radius local border_radius = beautiful.mstab_border_radius
@ -66,14 +70,14 @@ local function create_title_button(c, color_focus, color_unfocus)
return tb return tb
end end
local function create(c, focused_bool, buttons) local function create(c, focused_bool, buttons, inactive_bool)
-- local flexlist = wibox.layout.flex.horizontal() -- local flexlist = wibox.layout.flex.horizontal()
local title_temp = c.name or c.class or "-" local title_temp = c.name or c.class or "-"
local bg_temp = bg_normal local bg_temp = inactive_bool and bg_normal_inactive or bg_normal
local fg_temp = fg_normal local fg_temp = inactive_bool and fg_normal_inactive or fg_normal
if focused_bool then if focused_bool then
bg_temp = bg_focus bg_temp = inactive_bool and bg_focus_inactive or bg_focus
fg_temp = fg_focus fg_temp = inactive_bool and fg_focus_inactive or fg_focus
end end
local text_temp = wibox.widget.textbox() local text_temp = wibox.widget.textbox()
text_temp.align = "center" text_temp.align = "center"

View File

@ -8,13 +8,21 @@ local bg_normal = beautiful.tabbar_bg_normal or beautiful.bg_normal or "#ffffff"
local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000" local fg_normal = beautiful.tabbar_fg_normal or beautiful.fg_normal or "#000000"
local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000" local bg_focus = beautiful.tabbar_bg_focus or beautiful.bg_focus or "#000000"
local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff" local fg_focus = beautiful.tabbar_fg_focus or beautiful.fg_focus or "#ffffff"
local bg_focus_inactive = beautiful.tabbar_bg_focus_inactive or bg_focus
local fg_focus_inactive = beautiful.tabbar_fg_focus_inactive or fg_focus
local bg_normal_inactive = beautiful.tabbar_bg_normal_inactive or bg_normal
local fg_normal_inactive = beautiful.tabbar_fg_normal_inactive or fg_normal
local font = beautiful.tabbar_font or beautiful.font or "Hack 15" local font = beautiful.tabbar_font or beautiful.font or "Hack 15"
local size = beautiful.tabbar_size or 20 local size = beautiful.tabbar_size or 20
local position = beautiful.tabbar_position or "top" local position = beautiful.tabbar_position or "top"
local function create(c, focused_bool, buttons) local function create(c, focused_bool, buttons, inactive_bool)
local bg_temp = focused_bool and bg_focus or bg_normal local bg_temp = inactive_bool and bg_normal_inactive or bg_normal
local fg_temp = focused_bool and fg_focus or fg_normal local fg_temp = inactive_bool and fg_normal_inactive or fg_normal
if focused_bool then
bg_temp = inactive_bool and bg_focus_inactive or bg_focus
fg_temp = inactive_bool and fg_focus_inactive or fg_focus
end
local wid_temp = wibox.widget({ local wid_temp = wibox.widget({
{ {

View File

@ -28,7 +28,8 @@ local function draw_widget(
widget_border_color, widget_border_color,
widget_border_width, widget_border_width,
geo, geo,
margin margin,
background_image
) )
local client_list = wibox.layout.manual() local client_list = wibox.layout.manual()
client_list.forced_height = geo.height client_list.forced_height = geo.height
@ -36,15 +37,20 @@ local function draw_widget(
local tag_screen = t.screen local tag_screen = t.screen
for i, c in ipairs(t:clients()) do for i, c in ipairs(t:clients()) do
if not c.hidden and not c.minimized then if not c.hidden and not c.minimized then
local img_box = wibox.widget({
image = gears.surface.load(c.icon), local img_box = wibox.widget ({
resize = true, resize = true,
forced_height = 100 * scale, forced_height = 100 * scale,
forced_width = 100 * scale, forced_width = 100 * scale,
widget = wibox.widget.imagebox, widget = wibox.widget.imagebox,
}) })
-- If fails to set image, fallback to a awesome icon
if not pcall(function() img_box.image = gears.surface.load(c.icon) end) then
img_box.image = beautiful.theme_assets.awesome_icon (24, "#222222", "#fafafa")
end
if tag_preview_image then if tag_preview_image then
if c.prev_content or t.selected then if c.prev_content or t.selected then
local content local content
@ -108,22 +114,26 @@ local function draw_widget(
end end
end end
return { return wibox.widget {
{ {
background_image,
{ {
{ {
{ {
client_list, {
forced_height = geo.height, client_list,
forced_width = geo.width, forced_height = geo.height,
widget = wibox.container.place, forced_width = geo.width,
widget = wibox.container.place,
},
layout = wibox.layout.align.horizontal,
}, },
layout = wibox.layout.align.horizontal, layout = wibox.layout.align.vertical,
}, },
layout = wibox.layout.align.vertical, margins = margin,
widget = wibox.container.margin,
}, },
margins = margin, layout = wibox.layout.stack
widget = wibox.container.margin,
}, },
bg = widget_bg, bg = widget_bg,
shape_border_width = widget_border_width, shape_border_width = widget_border_width,
@ -143,6 +153,7 @@ local enable = function(opts)
local work_area = opts.honor_workarea or false local work_area = opts.honor_workarea or false
local padding = opts.honor_padding or false local padding = opts.honor_padding or false
local placement_fn = opts.placement_fn or nil local placement_fn = opts.placement_fn or nil
local background_image = opts.background_widget or nil
local margin = beautiful.tag_preview_widget_margin or dpi(0) local margin = beautiful.tag_preview_widget_margin or dpi(0)
local screen_radius = beautiful.tag_preview_widget_border_radius or dpi(0) local screen_radius = beautiful.tag_preview_widget_border_radius or dpi(0)
@ -170,9 +181,22 @@ local enable = function(opts)
}) })
tag.connect_signal("property::selected", function(t) tag.connect_signal("property::selected", function(t)
for _, c in ipairs(t:clients()) do -- Awesome switches up tags on startup really fast it seems, probably depends on what rules you have set
c.prev_content = gears.surface.duplicate_surface(c.content) -- which can cause the c.content to not show the correct image
end gears.timer
{
timeout = 0.1,
call_now = false,
autostart = true,
single_shot = true,
callback = function()
if t.selected == true then
for _, c in ipairs(t:clients()) do
c.prev_content = gears.surface.duplicate_surface(c.content)
end
end
end
}
end) end)
awesome.connect_signal("bling::tag_preview::update", function(t) awesome.connect_signal("bling::tag_preview::update", function(t)
@ -184,14 +208,24 @@ local enable = function(opts)
tag_preview_box.maximum_width = scale * geo.width + margin * 2 tag_preview_box.maximum_width = scale * geo.width + margin * 2
tag_preview_box.maximum_height = scale * geo.height + margin * 2 tag_preview_box.maximum_height = scale * geo.height + margin * 2
-- TODO: Use a table here
tag_preview_box:setup(draw_widget(t, tag_preview_image, scale, tag_preview_box.widget = draw_widget(
screen_radius, client_radius, t,
client_opacity, client_bg, tag_preview_image,
client_border_color, scale,
client_border_width, widget_bg, screen_radius,
widget_border_color, client_radius,
widget_border_width, geo, margin)) client_opacity,
client_bg,
client_border_color,
client_border_width,
widget_bg,
widget_border_color,
widget_border_width,
geo,
margin,
background_image
)
end) end)
awesome.connect_signal("bling::tag_preview::visibility", function(s, v) awesome.connect_signal("bling::tag_preview::visibility", function(s, v)
@ -200,6 +234,11 @@ local enable = function(opts)
tag_preview_box.y = s.geometry.y + widget_y tag_preview_box.y = s.geometry.y + widget_y
end end
if v == false then
tag_preview_box.widget = nil
collectgarbage("collect")
end
tag_preview_box.visible = v tag_preview_box.visible = v
end) end)
end end

View File

@ -30,14 +30,24 @@ local function draw_widget(
end) then end) then
return return
end end
local content = gears.surface(c.content)
local cr = cairo.Context(content) local content = nil
local x, y, w, h = cr:clip_extents() if c.active then
local img = cairo.ImageSurface.create(cairo.Format.ARGB32, w - x, h - y) content = gears.surface(c.content)
cr = cairo.Context(img) elseif c.prev_content then
cr:set_source_surface(content, 0, 0) content = gears.surface(c.prev_content)
cr.operator = cairo.Operator.SOURCE end
cr:paint()
local img = nil
if content ~= nil then
local cr = cairo.Context(content)
local x, y, w, h = cr:clip_extents()
img = cairo.ImageSurface.create(cairo.Format.ARGB32, w - x, h - y)
cr = cairo.Context(img)
cr:set_source_surface(content, 0, 0)
cr.operator = cairo.Operator.SOURCE
cr:paint()
end
local widget = wibox.widget({ local widget = wibox.widget({
(widget_template or { (widget_template or {
@ -139,6 +149,25 @@ local enable = function(opts)
bg = "#00000000", bg = "#00000000",
}) })
tag.connect_signal("property::selected", function(t)
-- Awesome switches up tags on startup really fast it seems, probably depends on what rules you have set
-- which can cause the c.content to not show the correct image
gears.timer
{
timeout = 0.1,
call_now = false,
autostart = true,
single_shot = true,
callback = function()
if t.selected == true then
for _, c in ipairs(t:clients()) do
c.prev_content = gears.surface.duplicate_surface(c.content)
end
end
end
}
end)
awesome.connect_signal("bling::task_preview::visibility", function(s, v, c) awesome.connect_signal("bling::task_preview::visibility", function(s, v, c)
if v then if v then
-- Update task preview contents -- Update task preview contents
@ -153,6 +182,9 @@ local enable = function(opts)
widget_width, widget_width,
widget_height widget_height
) )
else
task_preview_box.widget = nil
collectgarbage("collect")
end end
if not placement_fn then if not placement_fn then

View File

@ -59,6 +59,8 @@ local window_switcher_hide = function(window_switcher_box)
-- Stop and hide window_switcher -- Stop and hide window_switcher
awful.keygrabber.stop(window_switcher_grabber) awful.keygrabber.stop(window_switcher_grabber)
window_switcher_box.visible = false window_switcher_box.visible = false
window_switcher_box.widget = nil
collectgarbage("collect")
end end
local function draw_widget( local function draw_widget(