diff --git a/.github/assets/awesome.png b/.github/assets/awesome.png index e0c180c..9aef974 100644 Binary files a/.github/assets/awesome.png and b/.github/assets/awesome.png differ diff --git a/.github/assets/contributors.png b/.github/assets/contributors.png deleted file mode 100644 index 44b5726..0000000 Binary files a/.github/assets/contributors.png and /dev/null differ diff --git a/bin/screensht b/bin/screensht index e7b8e37..9cca448 100755 --- a/bin/screensht +++ b/bin/screensht @@ -1,133 +1,120 @@ -#!/bin/bash +#!/bin/sh +# stolen from snap < $_SCREENSHOT_DIR_/_rounded_.mvg - check - - magick convert "$_LATEST_IMAGE_" -border $_BORDER_SIZE_ -alpha transparent \ - -background none -fill white -stroke none -strokewidth 0 \ - -draw "@"$_SCREENSHOT_DIR_"/_rounded_.mvg" $_SCREENSHOT_DIR_/_rounded_mask_.png - check - - magick convert "$_LATEST_IMAGE_" -border $_BORDER_SIZE_ -alpha transparent \ - -background none -fill none -stroke $_FG_COLOR_ -strokewidth $_BORDER_SIZE_ \ - -draw "@"$_SCREENSHOT_DIR_"/_rounded_.mvg" $_SCREENSHOT_DIR_/_rounded_overlay_.png - check - - magick convert "$_LATEST_IMAGE_" -alpha set -bordercolor none -border $_BORDER_SIZE_ \ - $_SCREENSHOT_DIR_/_rounded_mask_.png -compose DstIn -composite \ - $_SCREENSHOT_DIR_/_rounded_overlay_.png -compose Over -composite \ - "$_target_file_" && \ - rm -f $_SCREENSHOT_DIR_/_rounded_* - check - else - magick convert "$_LATEST_IMAGE_" \( +clone -alpha extract -draw 'fill black polygon 0,0 0,'"$_ROUNDED_CORNER_"' '"$_ROUNDED_CORNER_"',0 fill white circle '"$_ROUNDED_CORNER_"','"$_ROUNDED_CORNER_"' '"$_ROUNDED_CORNER_"',0' \ - \( +clone -flip \) -compose Multiply -composite \ - \( +clone -flop \) -compose Multiply -composite \ - \) -alpha off -compose CopyOpacity -composite -compose over "$_target_file_" - check - fi - - magick convert "$_target_file_" \( +clone -background black -shadow $_SHADOW_SIZE_ \) +swap -background none -layers merge +repage "$_target_file_" \ - && magick convert "$_target_file_" -bordercolor $_BG_COLOR_ -border $_BG_SIZE_ "$_target_file_" - check - - magick convert "$_target_file_" -gravity North -background $_BG_COLOR_ -splice 0x$(( $_BG_SIZE_ / 2 )) "$_target_file_" - check - - magick convert "$_target_file_" -profile /usr/share/color/icc/colord/sRGB.icc "$_target_file_" - check -} - -function summary() { - _runtime_job_=$(($2-$1)) - hours=$((_runtime_job_ / 3600)); minutes=$(( (_runtime_job_ % 3600) / 60 )); seconds=$(( (_runtime_job_ % 3600) % 60 )) - - if [[ $3 != "failed" ]]; then - xclip -selection clipboard -t image/png -i $_target_file_ && notify-send -u normal -t 3000 "Awesome-Maim: $_target_file_ Copied" - fi -} - -function main() { - _start_job_=$(date +%Y.%m.%d-%H.%M.%S) - - maim -u -b 3 -m 5 -s ~/Pictures/Screenshots/$_start_job_.png> /dev/null 2>&1 - check - - get_latest_img - - convert - - mv $_LATEST_IMAGE_ ~/Pictures/Screenshots/Original/ - notify-send -i ~/Pictures/Screenshots/Original/$_start_job_.png "Screenshot Taken" "saved to ~/Pictures/Screenshots" - _end_job_=$(date +%s) -} - - -if [[ ! -d "$_SCREENSHOT_DIR_" || ! -d "$_ORIGINAL_DIR_" ]]; then - mkdir -p "$_SCREENSHOT_DIR_" - mkdir -p "$_ORIGINAL_DIR_" + Example: + ./screensht area + ./screensht full + " +elif [ "$1" = 'full' ]; +then + msg="Full screenshot saved and copied to clipboard!" + shot 'maim -u -m 5' "${msg}" +elif [ "$1" = 'area' ]; +then + msg='Area screenshot saved and copied to clipboard!' + shot 'maim -u -b 2 -m 5 -s' "${msg}" fi -clear -main diff --git a/config/awesome/configuration/autostart.lua b/config/awesome/configuration/autostart.lua index af4a994..8c09df4 100644 --- a/config/awesome/configuration/autostart.lua +++ b/config/awesome/configuration/autostart.lua @@ -10,9 +10,14 @@ local function run_once(cmd) findme, cmd), false) end --- picom +-- music +run_once("mpd") +run_once("mpDris2") -run_once("picom --experimental-backends --config " .. - gears.filesystem.get_configuration_dir() .. "theme/picom.conf") +-- picom +run_once("picom --experimental-backends --config " .. theme_dir .. "picom.conf") + +-- auth +run_once("/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1") return autostart \ No newline at end of file diff --git a/config/awesome/configuration/bling.lua b/config/awesome/configuration/bling.lua deleted file mode 100644 index 0793a5e..0000000 --- a/config/awesome/configuration/bling.lua +++ /dev/null @@ -1,51 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local beautiful = require("beautiful") -local bling = require("module.bling") - -bling.module.flash_focus.enable() - --- Set Tile Wallpaper --- bling.module.tiled_wallpaper("", s, { --- fg = beautiful.lighter_bg, --- bg = beautiful.xbackground, --- offset_y = 6, --- offset_x = 18, --- font = "Iosevka", --- font_size = 17, --- padding = 70, --- zickzack = true --- }) - --- Enable Tag Preview Module from Bling -bling.widget.tag_preview.enable { - show_client_content = false, - placement_fn = function(c) - awful.placement.left(c, { - margins = { - left = beautiful.wibar_width + 11 - } - }) - end, - scale = 0.15, - honor_padding = true, - honor_workarea = false, - background_widget = wibox.widget { - bg = beautiful.xbackground, - widget = wibox.widget.background - } -} - --- Enable Task Preview Module from Bling -bling.widget.task_preview.enable { - placement_fn = function(c) - awful.placement.top_left(c, { - margins = { - top = 10, - left = beautiful.wibar_width + 11 - } - }) - end -} - -require('ui.widgets.window_switcher').enable() diff --git a/config/awesome/configuration/desktop.lua b/config/awesome/configuration/desktop.lua deleted file mode 100644 index f1f9a24..0000000 --- a/config/awesome/configuration/desktop.lua +++ /dev/null @@ -1,35 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local naughty = require("naughty") -local awful = require("awful") -require("awful.autofocus") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Check if awesome encountered an error during startup and fell back to --- another config (This code will only ever execute for the fallback config) -naughty.connect_signal("request::display_error", function(message, startup) - naughty.notification { - urgency = "critical", - title = "Oops, an error happened" .. - (startup and " during startup!" or "!"), - message = message - } -end) - --- set wallpapers -awful.screen.connect_for_each_screen(function(s) - gears.wallpaper.maximized(beautiful.wallpaper, s, false, nil) - -end) - --- Screen Padding and Tags -screen.connect_signal("request::desktop_decoration", function(s) - -- Screen padding - screen[s].padding = {left = 0, right = 0, top = 0, bottom = 0} - -- Each screen has its own tag table. - awful.tag({"1", "2", "3", "4", "5"}, s, awful.layout.layouts[1]) -end) - diff --git a/config/awesome/configuration/extras.lua b/config/awesome/configuration/extras.lua new file mode 100644 index 0000000..86245ab --- /dev/null +++ b/config/awesome/configuration/extras.lua @@ -0,0 +1,96 @@ +-- Standard awesome library +local awful = require("awful") +require("awful.autofocus") +local gears = require("gears") +local gfs = gears.filesystem +local naughty = require("naughty") +local wibox = require("wibox") + +-- Theme handling library +local beautiful = require("beautiful") + + +-- Check if awesome encountered an error during startup and fell back to +-- another config (This code will only ever execute for the fallback config) +naughty.connect_signal("request::display_error", function(message, startup) + naughty.notification { + urgency = "critical", + title = "Oops, an error happened" .. + (startup and " during startup!" or "!"), + message = message + } +end) + +client.connect_signal("request::manage", function(c) + -- Add missing icon to client + if not c.icon then + local icon = gears.surface(beautiful.awesome_logo) + c.icon = icon._native + icon:finish() + end + + -- Set the windows at the slave, + if awesome.startup and not c.size_hints.user_position and + not c.size_hints.program_position then + -- Prevent clients from being unreachable after screen count changes. + awful.placement.no_offscreen(c) + end +end) + +-- Enable sloppy focus, so that focus follows mouse. +client.connect_signal("mouse::enter", function(c) + c:emit_signal("request::activate", "mouse_enter", {raise = false}) +end) + +client.connect_signal("focus", + function(c) c.border_color = beautiful.border_focus end) + +client.connect_signal("unfocus", + function(c) c.border_color = beautiful.border_normal end) + + +-- Hide all windows when a splash is shown +awesome.connect_signal("widgets::splash::visibility", function(vis) + local t = screen.primary.selected_tag + if vis then + for idx, c in ipairs(t:clients()) do c.hidden = true end + else + for idx, c in ipairs(t:clients()) do c.hidden = false end + end +end) + + +--Bling +---------- + +local bling = require("module.bling") + +bling.module.flash_focus.enable() + +-- Tag Preview +bling.widget.tag_preview.enable { + show_client_content = false, + placement_fn = function(c) + awful.placement.top_left(c, { + margins = { + top = 99, + left = beautiful.wibar_width + 55 + } + }) + end, + scale = 0.15, + honor_padding = true, + honor_workarea = false, + background_widget = wibox.widget { + -- image = beautiful.wallpaper, + -- horizontal_fit_policy = "fit", + -- vertical_fit_policy = "fit", + -- widget = wibox.widget.imagebox + bg = beautiful.wibar_bg, + widget = wibox.container.bg + } +} + +require('ui.widgets.window_switcher').enable() + + diff --git a/config/awesome/configuration/init.lua b/config/awesome/configuration/init.lua index 4201abb..7eac3a4 100644 --- a/config/awesome/configuration/init.lua +++ b/config/awesome/configuration/init.lua @@ -1,6 +1,86 @@ -require("configuration.bling") +-- Standard awesome library +local awful = require("awful") +local gears = require("gears") +local gfs = gears.filesystem +local wibox = require("wibox") + +-- Theme handling library +local beautiful = require("beautiful") + +-- Helpers +local helpers = require("helpers") + +-- Bling Module +local bling = require("module.bling") + +-- Layout Machi +local machi = require("module.layout-machi") +beautiful.layout_machi = machi.get_icon() + +-- This is to slave windows' positions in floating layout +require("module.savefloats") + +-- Better mouse resizing on tiled +require("module.better-resize") + + +-- Desktop +------------- + +-- Custom Layouts +local mstab = bling.layout.mstab +local centered = bling.layout.centered +local horizontal = bling.layout.horizontal +local equal = bling.layout.equalarea +local deck = bling.layout.deck + +machi.editor.nested_layouts = { + ["0"] = deck, + ["1"] = awful.layout.suit.spiral, + ["2"] = awful.layout.suit.fair, + ["3"] = awful.layout.suit.fair.horizontal +} + +-- Set the layouts +tag.connect_signal("request::default_layouts", function() + awful.layout.append_default_layouts({ + awful.layout.suit.tile, awful.layout.suit.floating, centered, mstab, + horizontal, machi.default_layout, equal, deck + }) +end) + +-- Screen Padding and Tags +screen.connect_signal("request::desktop_decoration", function(s) + -- Screen padding + screen[s].padding = {left = dpi(40), right = dpi(15), top = dpi(15), bottom = dpi(15)} + -- Each screen has its own tag table. + awful.tag({"1", "2", "3", "4", "5"}, s, awful.layout.layouts[1]) +end) + +-- Wallpapers +-- set wallpapers +awful.screen.connect_for_each_screen(function(s) + -- gears.wallpaper.maximized(beautiful.wallpaper, s, false, nil) + gears.wallpaper.set(beautiful.xcolor8) +end) + +-- Set Tile Wallpaper +-- bling.module.tiled_wallpaper("", s, { +-- fg = beautiful.lighter_bg, +-- bg = beautiful.xbackground, +-- offset_y = 6, +-- offset_x = 18, +-- font = "Iosevka", +-- font_size = 17, +-- padding = 70, +-- zickzack = true +-- }) + + +-- Stuff +----------- + require("configuration.keys") require("configuration.ruled") -require("configuration.window") -require("configuration.desktop") +require("configuration.extras") require("configuration.menu") diff --git a/config/awesome/configuration/keys.lua b/config/awesome/configuration/keys.lua index 6942f31..fe5ce38 100644 --- a/config/awesome/configuration/keys.lua +++ b/config/awesome/configuration/keys.lua @@ -16,6 +16,7 @@ local naughty = require("naughty") -- Bling local bling = require("module.bling") +local playerctl = bling.signal.playerctl.lib() -- Machi local machi = require("module.layout-machi") @@ -25,7 +26,7 @@ local helpers = require("helpers") -- Default modkey. modkey = "Mod4" -altkey = "Mod1" +alt = "Mod1" ctrl = "Control" shift = "Shift" @@ -40,31 +41,34 @@ awful.keyboard.append_global_keybindings({ end, {description = "open applications menu", group = "launcher"}), awful.key({modkey, shift}, "d", function() - dash_toggle() + dashboard_toggle() end, {description = "toggle dashboard", group = "launcher"}), awful.key({modkey}, "f", function() - awful.spawn(filemanager) + awful.spawn(file_manager) end, {description = "open file manager", group = "launcher"}), awful.key({modkey}, "w", function() awful.spawn.with_shell(browser) end, {description = "open web browser", group = "launcher"}), - + awful.key({modkey}, "x", function() + awful.spawn.with_shell("xcolor-pick") + end, + {description = "open color-picker", group = "launcher"}) }) -- Client and Tabs Bindings awful.keyboard.append_global_keybindings({ - awful.key({altkey}, "a", function() + awful.key({alt}, "a", function() bling.module.tabbed.pick_with_dmenu() end, {description = "pick client to add to tab group", group = "tabs"}), - awful.key({altkey}, "s", function() + awful.key({alt}, "s", function() bling.module.tabbed.iter() end, {description = "iterate through tabbing group", group = "tabs"}), - awful.key({altkey}, "d", function() + awful.key({alt}, "d", function() bling.module.tabbed.pop() end, {description = "remove focused client from tabbing group",group = "tabs"}), @@ -107,73 +111,82 @@ awful.keyboard.append_global_keybindings({ awful.key({modkey}, "u", awful.client.urgent.jumpto, {description = "jump to urgent client", group = "client"}), - awful.key({altkey}, "Tab", function() + awful.key({alt}, "Tab", function() awesome.emit_signal("bling::window_switcher::turn_on") end, {description = "window switcher", group = "client"}) }) --- Awesomewm +-- Hotkeys awful.keyboard.append_global_keybindings({ -- Brightness Control awful.key({}, "XF86MonBrightnessUp", function() awful.spawn("brightnessctl set 5%+ -q") end, - {description = "increase brightness", group = "awesome"}), + {description = "increase brightness", group = "hotkeys"}), awful.key({}, "XF86MonBrightnessDown", function() awful.spawn("brightnessctl set 5%- -q") end, - {description = "decrease brightness", group = "awesome"}), + {description = "decrease brightness", group = "hotkeys"}), -- Volume control awful.key({}, "XF86AudioRaiseVolume", function() - awful.spawn("amixer -D pulse set Master 5%+") + helpers.volume_control(5) end, - {description = "increase volume", group = "awesome"}), + {description = "increase volume", group = "hotkeys"}), awful.key({}, "XF86AudioLowerVolume", function() - awful.spawn("amixer -D pulse set Master 5%-") + helpers.volume_control(-5) end, - {description = "decrease volume", group = "awesome"}), + {description = "decrease volume", group = "hotkeys"}), awful.key({}, "XF86AudioMute", function() - awful.spawn("amixer -D pulse set Master 1+ toggle") + helpers.volume_control(0) end, - {description = "mute volume", group = "awesome"}), + {description = "mute volume", group = "hotkeys"}), - -- Media Control + -- Music awful.key({}, "XF86AudioPlay", function() - awful.spawn("playerctl play-pause") + playerctl:play_pause() end, - {description = "toggle playerctl", group = "awesome"}), + {description = "toggle music", group = "hotkeys"}), + awful.key({}, "XF86AudioPrev", function() - awful.spawn("playerctl previous") + playerctl:previous() end, - {description = "playerctl previous", group = "awesome"}), + {description = "previous music", group = "hotkeys"}), + awful.key({}, "XF86AudioNext", function() - awful.spawn("playerctl next") + playerctl:next() end, - {description = "playerctl next", group = "awesome"}), + {description = "next music", group = "hotkeys"}), -- Screenshots - awful.key({}, "Print", function() - awful.spawn.with_shell("screensht") + awful.key({}, "Print", function() + awful.spawn.with_shell("screensht full") end, - {description = "take a screenshot", group = "awesome"}), + {description = "take a full screenshot", group = "hotkeys"}), + + awful.key({alt}, "Print", function() + awful.spawn.with_shell("screensht area") + end, + {description = "take a area screenshot", group = "hotkeys"}), -- Lockscreen - awful.key({modkey}, "x", function() - lock_screen_show() + awful.key({modkey, ctrl}, "l", function() + lock_screen_show() end, - {description = "lock screen", group = "awesome"}), + {description = "lock screen", group = "hotkeys"}) +}) - -- Awesome stuff - awful.key({modkey}, "F1", +-- Awesome stuff +awful.keyboard.append_global_keybindings({ + awful.key({modkey}, "F1", hotkeys_popup.show_help, {description = "show help", group = "awesome"}), - awful.key({modkey, "Control"}, "r", + awful.key({modkey, ctrl}, "r", awesome.restart, {description = "reload awesome", group = "awesome"}), - awful.key({modkey, "Shift"}, "q", + awful.key({modkey, ctrl}, "q", awesome.quit, {description = "quit awesome", group = "awesome"}) }) @@ -237,10 +250,10 @@ awful.keyboard.append_global_keybindings({ {description = "select previous layout", group = "layout"}), -- Tag - awful.key({ modkey, altkey}, "Left", + awful.key({ modkey, alt}, "Left", awful.tag.viewprev, {description = "view previous", group = "tag"}), - awful.key({ modkey, altkey}, "Right", + awful.key({ modkey, alt}, "Right", awful.tag.viewnext, {description = "view next", group = "tag"}), awful.key({ modkey}, "Escape", @@ -394,15 +407,6 @@ awful.keyboard.append_global_keybindings({ if tag then client.focus:toggle_tag(tag) end end end - }, awful.key { - modifiers = {modkey}, - keygroup = "numpad", - description = "select layout directly", - group = "layout", - on_press = function(index) - local t = awful.screen.focused().selected_tag - if t then t.layout = t.layouts[index] or t.layout end - end } }) @@ -419,9 +423,9 @@ awful.mouse.append_global_mousebindings({ end end), - -- Right click + -- Middle click awful.button({}, 2, function() - dash_toggle() + dashboard_toggle() end), -- Right click @@ -451,4 +455,4 @@ client.connect_signal("request::default_mousebindings", function() end) }) end) --- EOF ------------------------------------------------------------------------ + diff --git a/config/awesome/configuration/menu.lua b/config/awesome/configuration/menu.lua index 9d27946..6c816b9 100644 --- a/config/awesome/configuration/menu.lua +++ b/config/awesome/configuration/menu.lua @@ -9,6 +9,8 @@ awful.screen.connect_for_each_screen(function(s) -- Submenu awesomemenu = { {"Hotkeys", function() hotkeys_popup.show_help(nil, awful.screen.focused()) end}, + {"Manual", terminal .. " -e man awesome"}, + {"Edit Config", editor .. " " .. awesome.conffile}, {"Restart", awesome.restart}, {"Quit", function() awesome.quit() end} } @@ -27,11 +29,11 @@ awful.screen.connect_for_each_screen(function(s) -- Mainmenu mymainmenu = awful.menu({ items = { - {"Terminal", terminal, beautiful.awesome_logo}, - {"Code Editor", vscode}, - {"File Manager", filemanager}, - {"Web Browser", browser}, - {"Discord", discord}, + {"Terminal", function() awful.spawn.with_shell(terminal) end, beautiful.awesome_logo}, + {"Code Editor", function() awful.spawn.with_shell(vscode) end}, + {"File Manager", function() awful.spawn.with_shell(file_manager) end}, + {"Web Browser", function() awful.spawn.with_shell(browser) end}, + {"Music", function() awful.spawn.with_shell(music_client) end}, {"AwesomeWM", awesomemenu}, {"Power Menu", powermenu} } diff --git a/config/awesome/configuration/ruled.lua b/config/awesome/configuration/ruled.lua index bdc68d4..6a5f943 100644 --- a/config/awesome/configuration/ruled.lua +++ b/config/awesome/configuration/ruled.lua @@ -1,7 +1,23 @@ +-- Standard awesome library +local gears = require("gears") local awful = require("awful") + +-- Theme handling library local beautiful = require("beautiful") + +-- Notification handling library +local naughty = require("naughty") + +-- Ruled local ruled = require("ruled") +-- Helpers +local helpers = require("helpers") + +-- Get screen geometry +local screen_width = awful.screen.focused().geometry.width +local screen_height = awful.screen.focused().geometry.height + ruled.client.connect_signal("request::rules", function() -- Global @@ -13,11 +29,12 @@ ruled.client.connect_signal("request::rules", function() raise = true, size_hints_honor = false, screen = awful.screen.preferred, + titlebars_enabled = beautiful.titlebar_enabled, placement = awful.placement.no_overlap+awful.placement.no_offscreen } } - -- tasklist order + -- Tasklist order ruled.client.append_rule { id = "tasklist_order", rule = {}, @@ -25,58 +42,135 @@ ruled.client.connect_signal("request::rules", function() callback = awful.client.setslave } - -- Float em - ruled.client.append_rule { - id = "floating", - rule_any = { - class = {"Arandr", "Blueman-manager", "Sxiv", "fzfmenu"}, - role = { - "pop-up" -- e.g. Google Chrome's (detached) Developer Tools. - }, - name = {"Friends List", "Steam - News"}, - instance = {"spad", "discord", "music"} - }, - properties = {floating = true, placement = awful.placement.centered} - } - - -- Borders - ruled.client.append_rule { - id = "borders", - rule_any = {type = {"normal", "dialog"}}, - except_any = { - role = {"Popup"}, - type = {"splash"}, - name = {"^discord.com is sharing your screen.$"} - }, - properties = { - border_width = beautiful.border_width, - border_color = beautiful.border_normal - } - } - - -- Center Placement - ruled.client.append_rule { - id = "center_placement", - rule_any = { - type = {"dialog"}, - class = {"Steam", "discord", "markdown_input"}, - instance = {"markdown_input"}, - role = {"GtkFileChooserDialog", "conversation"} - }, - properties = {placement = awful.placement.center} - } - -- Titlebar rules ruled.client.append_rule { id = "titlebars", - rule_any = {type = {"normal", "dialog"}}, - except_any = { - class = {"Steam", "zoom", "jetbrains-studio", "chat", "Org.gnome.Nautilus", "Firefox", "Google-chrome", "Brave-browser"}, - type = {"splash"}, - instance = {"onboard"}, - name = {"^discord.com is sharing your screen.$"} + rule_any = { + class = { + "discord", + "Spotify", + "firefox", + "Org.gnome.Nautilus" + }, + type = { + "splash" + }, + name = { + "^discord.com is sharing your screen.$" -- Discord (running in browser) screen sharing popup + } }, - properties = {titlebars_enabled = true} + properties = { + titlebars_enabled = false + } + } + + -- Float + ruled.client.append_rule { + id = "floating", + rule_any = { + instance = { + "Devtools", -- Firefox devtools + }, + class = { + "Lxappearance", + "Nm-connection-editor", + }, + name = { + "Event Tester", -- xev + }, + role = { + "AlarmWindow", + "pop-up", + "GtkFileChooserDialog", + "conversation", + }, + type = { + "dialog", + } + }, + properties = { floating = true, placement = helpers.centered_client_placement } + } + + -- Centered + ruled.client.append_rule { + id = "centered", + rule_any = { + type = { + "dialog", + }, + class = { + -- "discord", + }, + role = { + "GtkFileChooserDialog", + "conversation", + } + }, + properties = { placement = helpers.centered_client_placement }, + } + + -- Music clients (usually a terminal running ncmpcpp) + ruled.client.append_rule { + rule_any = { + class = { + "music" + }, + instance = { + "music" + } + }, + properties = { + floating = true, + width = screen_width * 0.25, + height = screen_height * 0.4, + placement = helpers.centered_client_placement + } + } + + -- Image viewers + ruled.client.append_rule { + rule_any = { + class = { + "feh", + "imv" + } + }, + properties = { + floating = true, + width = screen_width * 0.7, + height = screen_height * 0.75 + }, + callback = function (c) + awful.placement.centered(c,{honor_padding = true, honor_workarea=true}) + end + } + + -- Mpv + ruled.client.append_rule { + rule = { class = "mpv" }, + properties = {}, + callback = function (c) + -- make it floating, ontop and move it out of the way if the current tag is maximized + if awful.layout.get(awful.screen.focused()) == awful.layout.suit.floating then + c.floating = true + c.ontop = true + c.width = screen_width * 0.30 + c.height = screen_height * 0.35 + awful.placement.bottom_right(c, { + honor_padding = true, + honor_workarea = true, + margins = { bottom = beautiful.useless_gap * 2, right = beautiful.useless_gap * 2 } + }) + awful.titlebar.hide(c, beautiful.titlebar_pos) + end + + -- restore `ontop` after fullscreen is disabled + c:connect_signal("property::fullscreen", function () + if not c.fullscreen then + c.ontop = true + end + end) + end } end) diff --git a/config/awesome/configuration/window.lua b/config/awesome/configuration/window.lua deleted file mode 100644 index ce1eac6..0000000 --- a/config/awesome/configuration/window.lua +++ /dev/null @@ -1,170 +0,0 @@ -local awful = require("awful") -local gears = require("gears") -local gfs = gears.filesystem -local wibox = require("wibox") -local beautiful = require("beautiful") -local dpi = require("beautiful.xresources").apply_dpi -local helpers = require("helpers") - --- Bling Module -local bling = require("module.bling") - --- Layout Machi -local machi = require("module.layout-machi") -beautiful.layout_machi = machi.get_icon() - --- This is to slave windows' positions in floating layout -require("module.savefloats") - --- Better mouse resizing on tiled -require("module.better-resize") - -client.connect_signal("request::manage", function(c) - if not c.icon then - local i = gears.surface(gfs.get_configuration_dir() .. - "theme/assets/icons/awesome.png") - c.icon = i._native - end - - -- Set the windows at the slave, - if awesome.startup and not c.size_hints.user_position and - not c.size_hints.program_position then - -- Prevent clients from being unreachable after screen count changes. - awful.placement.no_offscreen(c) - end -end) - --- Enable sloppy focus, so that focus follows mouse. -client.connect_signal("mouse::enter", function(c) - c:emit_signal("request::activate", "mouse_enter", {raise = false}) -end) - -client.connect_signal("focus", - function(c) c.border_color = beautiful.border_focus end) - -client.connect_signal("unfocus", - function(c) c.border_color = beautiful.border_normal end) - --- Custom Layouts ------------------------------------------------------------- - -local mstab = bling.layout.mstab -local centered = bling.layout.centered -local horizontal = bling.layout.horizontal -local equal = bling.layout.equalarea -local deck = bling.layout.deck - -machi.editor.nested_layouts = { - ["0"] = deck, - ["1"] = awful.layout.suit.spiral, - ["2"] = awful.layout.suit.fair, - ["3"] = awful.layout.suit.fair.horizontal -} - --- Set the layouts - -tag.connect_signal("request::default_layouts", function() - awful.layout.append_default_layouts({ - awful.layout.suit.tile, awful.layout.suit.floating, centered, mstab, - horizontal, machi.default_layout, equal, deck - }) -end) - --- Layout List Widget --------------------------------------------------------- - --- List -local ll = awful.widget.layoutlist { - source = awful.widget.layoutlist.source.default_layouts, -- DOC_HIDE - spacing = dpi(24), - base_layout = wibox.widget { - spacing = dpi(24), - forced_num_cols = 4, - layout = wibox.layout.grid.vertical - }, - widget_template = { - { - { - id = "icon_role", - forced_height = dpi(68), - forced_width = dpi(68), - widget = wibox.widget.imagebox - }, - margins = dpi(24), - widget = wibox.container.margin - }, - id = "background_role", - forced_width = dpi(68), - forced_height = dpi(68), - widget = wibox.container.background - } -} - --- Popup -local layout_popup = awful.popup { - widget = wibox.widget { - {ll, margins = dpi(24), widget = wibox.container.margin}, - bg = beautiful.xbackground, - shape = helpers.rrect(beautiful.border_radius), - border_color = beautiful.widget_border_color, - border_width = beautiful.widget_border_width, - widget = wibox.container.background - }, - placement = awful.placement.centered, - ontop = true, - visible = false, - bg = beautiful.xbackground .. "00" -} - --- Key Bindings for Widget ---------------------------------------------------- - -function gears.table.iterate_value(t, value, step_size, filter, start_at) - local k = gears.table.hasitem(t, value, true, start_at) - if not k then return end - - step_size = step_size or 1 - local new_key = gears.math.cycle(#t, k + step_size) - - if filter and not filter(t[new_key]) then - for i = 1, #t do - local k2 = gears.math.cycle(#t, new_key + i) - if filter(t[k2]) then return t[k2], k2 end - end - return - end - - return t[new_key], new_key -end - -awful.keygrabber { - start_callback = function() layout_popup.visible = true end, - stop_callback = function() layout_popup.visible = false end, - export_keybindings = true, - stop_event = "release", - stop_key = {"Escape", "Super_L", "Super_R", "Mod4"}, - keybindings = { - { - {modkey, "Shift"}, " ", function() - awful.layout.set(gears.table.iterate_value(ll.layouts, - ll.current_layout, -1), - nil) - end - }, { - {modkey}, " ", function() - awful.layout.set(gears.table.iterate_value(ll.layouts, - ll.current_layout, 1), - nil) - end - } - } -} - --- Hide all windows when a splash is shown -awesome.connect_signal("widgets::splash::visibility", function(vis) - local t = screen.primary.selected_tag - if vis then - for idx, c in ipairs(t:clients()) do c.hidden = true end - else - for idx, c in ipairs(t:clients()) do c.hidden = false end - end -end) - --- EOF ------------------------------------------------------------------------ diff --git a/config/awesome/helpers.lua b/config/awesome/helpers.lua index af15179..253e953 100644 --- a/config/awesome/helpers.lua +++ b/config/awesome/helpers.lua @@ -473,6 +473,12 @@ function helpers.float_and_resize(c, width, height) c:raise() end +function helpers.centered_client_placement(c) + return gears.timer.delayed_call(function () + awful.placement.centered(c, {honor_padding = true, honor_workarea=true}) + end) +end + -- Useful for periodically checking the output of a command that -- requires internet access. -- Ensures that `command` will be run EXACTLY once during the desired @@ -544,7 +550,12 @@ function helpers.music_control(state) awful.spawn.with_shell(cmd) end +function helpers.send_key(c, key) + awful.spawn.with_shell("xdotool key --window "..tostring(c.window).." "..key) +end + +function helpers.send_key_sequence(c, seq) + awful.spawn.with_shell("xdotool type --delay 5 --window "..tostring(c.window).." "..seq) +end return helpers - --- EOF ------------------------------------------------------------------------ diff --git a/config/awesome/module/bling/AUTHORS.md b/config/awesome/module/bling/AUTHORS.md index d9c6d2d..471cad5 100644 --- a/config/awesome/module/bling/AUTHORS.md +++ b/config/awesome/module/bling/AUTHORS.md @@ -7,3 +7,4 @@ The following developers have contributed major code to bling: * [HumblePresent](https://github.com/HumblePresent) * [Kasper24](https://github.com/Kasper24) * [undefinedDarkness](https://github.com/undefinedDarkness) + * [eylles](https://github.com/eylles) diff --git a/config/awesome/module/bling/layout/centered.lua b/config/awesome/module/bling/layout/centered.lua index 4e1ad24..7929dd8 100644 --- a/config/awesome/module/bling/layout/centered.lua +++ b/config/awesome/module/bling/layout/centered.lua @@ -8,37 +8,27 @@ mylayout.name = "centered" function mylayout.arrange(p) local area = p.workarea local t = p.tag or screen[p.screen].selected_tag - local mwfact = t.master_width_factor local nmaster = math.min(t.master_count, #p.clients) local nslaves = #p.clients - nmaster - local master_area_width = area.width * mwfact - local slave_area_width = area.width - master_area_width - local master_area_x = area.x + 0.5 * slave_area_width + local master_area_width = area.width * t.master_width_factor + if t.master_count == 0 then master_area_width = 0 end + local slave_width = 0.5 * (area.width - master_area_width) + local master_area_x = area.x + slave_width - local number_of_left_sided_slaves = math.floor(nslaves / 2) - local number_of_right_sided_slaves = nslaves - number_of_left_sided_slaves - local left_iterator = 0 - local right_iterator = 0 - -- Special case: no maters -> rrelapse into awesomes fair layout - if t.master_count == 0 then - awful.layout.suit.fair.arrange(p) - return - end - - -- Special case: one slave -> relapse into awesomes masterstack tile layout - if nslaves == 1 then - awful.layout.suit.tile.right.arrange(p) - return - end - - -- Special case: no slaves -> fullscreen master area - if nslaves < 1 then - master_area_width = area.width + -- Special case: few slaves -> make masters take more space - unless requested otherwise! + if nslaves < 2 and t.master_fill_policy ~= "master_width_factor" then master_area_x = area.x + + if nslaves == 1 then + slave_width = area.width - master_area_width + else + master_area_width = area.width + end end + -- iterate through masters for idx = 1, nmaster do local c = p.clients[idx] @@ -52,8 +42,14 @@ function mylayout.arrange(p) p.geometries[c] = g end + -- iterate through slaves - for idx = 1, nslaves do -- idx=nmaster+1,#p.clients do + local number_of_left_sided_slaves = math.floor(nslaves / 2) + local number_of_right_sided_slaves = nslaves - number_of_left_sided_slaves + local left_iterator = 0 + local right_iterator = 0 + + for idx = 1, nslaves do local c = p.clients[idx + nmaster] local g if idx % 2 == 0 then @@ -62,17 +58,17 @@ function mylayout.arrange(p) y = area.y + left_iterator * (area.height / number_of_left_sided_slaves), - width = slave_area_width / 2, + width = slave_width, height = area.height / number_of_left_sided_slaves, } left_iterator = left_iterator + 1 else g = { - x = area.x + master_area_width + slave_area_width / 2, + x = master_area_x + master_area_width, y = area.y + right_iterator * (area.height / number_of_right_sided_slaves), - width = slave_area_width / 2, + width = slave_width, height = area.height / number_of_right_sided_slaves, } right_iterator = right_iterator + 1 diff --git a/config/awesome/module/bling/layout/mstab.lua b/config/awesome/module/bling/layout/mstab.lua index 639275f..93ceb0e 100644 --- a/config/awesome/module/bling/layout/mstab.lua +++ b/config/awesome/module/bling/layout/mstab.lua @@ -7,6 +7,7 @@ local mylayout = {} mylayout.name = "mstab" +local tabbar_disable = beautiful.mstab_bar_disable or false local tabbar_ontop = beautiful.mstab_bar_ontop or false local tabbar_padding = beautiful.mstab_bar_padding or "default" local border_radius = beautiful.mstab_border_radius @@ -193,16 +194,18 @@ function mylayout.arrange(p) local tabbar_width_change = 0 local tabbar_y_change = 0 local tabbar_x_change = 0 - if tabbar_position == "top" then - tabbar_size_change = tabbar_size + tabbar_padding - tabbar_y_change = tabbar_size + tabbar_padding - elseif tabbar_position == "bottom" then - tabbar_size_change = tabbar_size + tabbar_padding - elseif tabbar_position == "left" then - tabbar_width_change = tabbar_size + tabbar_padding - tabbar_x_change = tabbar_size + tabbar_padding - elseif tabbar_position == "right" then - tabbar_width_change = tabbar_size + tabbar_padding + if not tabbar_disable then + if tabbar_position == "top" then + tabbar_size_change = tabbar_size + tabbar_padding + tabbar_y_change = tabbar_size + tabbar_padding + elseif tabbar_position == "bottom" then + tabbar_size_change = tabbar_size + tabbar_padding + elseif tabbar_position == "left" then + tabbar_width_change = tabbar_size + tabbar_padding + tabbar_x_change = tabbar_size + tabbar_padding + elseif tabbar_position == "right" then + tabbar_width_change = tabbar_size + tabbar_padding + end end -- Iterate through slaves @@ -231,14 +234,16 @@ function mylayout.arrange(p) p.geometries[c] = g end - update_tabbar( - slave_clients, - t, - t.top_idx, - area, - master_area_width, - slave_area_width - ) + if not tabbar_disable then + update_tabbar( + slave_clients, + t, + t.top_idx, + area, + master_area_width, + slave_area_width + ) + end end return mylayout diff --git a/config/awesome/module/bling/module/flash_focus.lua b/config/awesome/module/bling/module/flash_focus.lua index 2fe3f47..246f4a3 100644 --- a/config/awesome/module/bling/module/flash_focus.lua +++ b/config/awesome/module/bling/module/flash_focus.lua @@ -5,7 +5,7 @@ local op = beautiful.flash_focus_start_opacity or 0.6 local stp = beautiful.flash_focus_step or 0.01 local flashfocus = function(c) - if c then + if c and #c.screen.clients > 1 then c.opacity = op local q = op local g = gears.timer({ diff --git a/config/awesome/module/bling/module/scratchpad.lua b/config/awesome/module/bling/module/scratchpad.lua index 2b8f639..6ef011f 100644 --- a/config/awesome/module/bling/module/scratchpad.lua +++ b/config/awesome/module/bling/module/scratchpad.lua @@ -1,16 +1,111 @@ local awful = require("awful") local gears = require("gears") local naughty = require("naughty") - -local ruled -if awesome.version ~= "v4.3" then - ruled = require("ruled") -end - local helpers = require(tostring(...):match(".*bling") .. ".helpers") +local capi = { awesome = awesome, client = client } +local ruled = capi.awesome.version ~= "v4.3" and require("ruled") or nil +local pairs = pairs local Scratchpad = { mt = {} } +--- Called when the turn off animation has ended +local function on_animate_turn_off_end(self, tag) + -- When toggling off a scratchpad that's present on multiple tags + -- depsite still being unminizmied on the other tags it will become invisible + -- as it's position could be outside the screen from the animation + self.client:geometry({ + x = self.geometry.x + self.client.screen.geometry.x, + y = self.geometry.y + self.client.screen.geometry.y, + width = self.geometry.width, + height = self.geometry.height, + }) + + helpers.client.turn_off(self.client, tag) + + self.turning_off = false + + self:emit_signal("turn_off", self.client) +end + +--- The turn off animation +local function animate_turn_off(self, anim, axis) + self.screen_on_toggled_scratchpad = self.client.screen + self.tag_on_toggled_scratchpad = self.screen_on_toggled_scratchpad.selected_tag + + if self.client.floating == false then + -- Save the client geometry before floating it + local non_floating_x = self.client.x + local non_floating_y = self.client.y + local non_floating_width = self.client.width + local non_floating_height = self.client.height + + -- Can't animate non floating clients + self.client.floating = true + + -- Set the client geometry back to what it was before floating it + self.client:geometry({ + x = non_floating_x, + y = non_floating_y, + width = non_floating_width, + height = non_floating_height, + }) + end + + if axis == "x" then + anim.pos = self.client.x + else + anim.pos = self.client.y + end + + anim:set(anim:initial()) +end + +-- Handles changing tag mid animation +local function abort_if_tag_was_switched(self) + -- Check for the following scenerio: + -- Toggle on scratchpad at tag 1 + -- Toggle on scratchpad at tag 2 + -- Toggle off scratchpad at tag 1 + -- Switch to tag 2 + -- Outcome: The client will remain on tag 1 and will instead be removed from tag 2 + if (self.turning_off) and (self.screen_on_toggled_scratchpad and + self.screen_on_toggled_scratchpad.selected_tag) ~= self.tag_on_toggled_scratchpad + then + if self.rubato.x then + self.rubato.x:abort() + end + if self.rubato.y then + self.rubato.y:abort() + end + on_animate_turn_off_end(self, self.tag_on_toggled_scratchpad) + self.screen_on_toggled_scratchpad.selected_tag = nil + self.tag_on_toggled_scratchpad = nil + end +end + +--- The turn on animation +local function animate_turn_on(self, anim, axis) + -- Check for the following scenerio: + -- Toggle on scratchpad at tag 1 + -- Toggle on scratchpad at tag 2 + -- The animation will instantly end + -- as the timer pos is already at the on position + -- from toggling on the scratchpad at tag 1 + if axis == "x" and anim.pos == self.geometry.x then + anim.pos = anim:initial() + else + if anim.pos == self.geometry.y then + anim.pos = anim:initial() + end + end + + if axis == "x" then + anim:set(self.geometry.x) + else + anim:set(self.geometry.y) + end +end + --- Creates a new scratchpad object based on the argument -- -- @param args A table of possible arguments @@ -25,10 +120,40 @@ function Scratchpad:new(args) end args.rubato = args.rubato or {} - args.in_anim = false - local ret = gears.object({}) + + local ret = gears.object{} gears.table.crush(ret, Scratchpad) gears.table.crush(ret, args) + + if ret.rubato.x then + ret.rubato.x:subscribe(function(pos) + if ret.client and ret.client.valid then + ret.client.x = pos + end + abort_if_tag_was_switched(ret) + end) + + ret.rubato.x.ended:subscribe(function() + if ((ret.rubato.y and ret.rubato.y.state == false) or (ret.rubato.y == nil)) and ret.turning_off == true then + on_animate_turn_off_end(ret) + end + end) + end + if ret.rubato.y then + ret.rubato.y:subscribe(function(pos) + if ret.client and ret.client.valid then + ret.client.y = pos + end + abort_if_tag_was_switched(ret) + end) + + ret.rubato.y.ended:subscribe(function() + if ((ret.rubato.x and ret.rubato.x.state == false) or (ret.rubato.x == nil)) and ret.turning_off == true then + on_animate_turn_off_end(ret) + end + end) + end + return ret end @@ -56,6 +181,7 @@ function Scratchpad:apply(c) width = self.geometry.width, height = self.geometry.height, }) + if self.autoclose then c:connect_signal("unfocus", function(c1) c1.sticky = false -- client won't turn off if sticky @@ -64,82 +190,48 @@ function Scratchpad:apply(c) end end ---- The turn on animation -local function animate_turn_on(self, c, anim, axis) - -- Check for the following scenerio: - -- Toggle on scratchpad at tag 1 - -- Toggle on scratchpad at tag 2 - -- The animation will instantly end - -- as the timer pos is already at the on position - -- from toggling on the scratchpad at tag 1 - if axis == "x" and anim.pos == self.geometry.x then - anim.pos = anim:initial() - else - if anim.pos == self.geometry.y then - anim.pos = anim:initial() - end - end - - anim:subscribe(function(pos) - if c and c.valid then - if axis == "x" then - c.x = pos - else - c.y = pos - end - end - self.in_anim = true - end) - - if axis == "x" then - anim:set(self.geometry.x) - else - anim:set(self.geometry.y) - end - - anim.ended:subscribe(function() - self.in_anim = false - anim:unsubscribe() - anim.ended:unsubscribe() - end) -end - --- Turns the scratchpad on function Scratchpad:turn_on() - local c = self:find()[1] + self.client = self:find()[1] + local anim_x = self.rubato.x local anim_y = self.rubato.y - if c and not self.in_anim and c.first_tag and c.first_tag.selected then - c:raise() - client.focus = c + local in_anim = false + if (anim_x and anim_x.state == true) or (anim_y and anim_y.state == true) then + in_anim = true + end + + if self.client and not in_anim and self.client.first_tag and self.client.first_tag.selected then + self.client:raise() + capi.client.focus = self.client return end - if c and not self.in_anim then + if self.client and not in_anim then -- if a client was found, turn it on if self.reapply then - self:apply(c) + self:apply(self.client) end -- c.sticky was set to false in turn_off so it has to be reapplied anyway - c.sticky = self.sticky + self.client.sticky = self.sticky if anim_x then - animate_turn_on(self, c, anim_x, "x") + animate_turn_on(self, anim_x, "x") end if anim_y then - animate_turn_on(self, c, anim_y, "y") + animate_turn_on(self, anim_y, "y") end - helpers.client.turn_on(c) - self:emit_signal("turn_on", c) + helpers.client.turn_on(self.client) + self:emit_signal("turn_on", self.client) return end - if not c then + if not self.client then -- if no client was found, spawn one, find the corresponding window, -- apply the properties only once (until the next closing) local pid = awful.spawn.with_shell(self.command) - if awesome.version ~= "v4.3" then + if capi.awesome.version ~= "v4.3" then ruled.client.append_rule({ id = "scratchpad", rule = self.rule, @@ -159,6 +251,8 @@ function Scratchpad:turn_on() autostart = true, single_shot = true, callback = function() + self.client = c + self:apply(c) c.hidden = false c.minimized = false @@ -166,10 +260,10 @@ function Scratchpad:turn_on() c:activate({}) if anim_x then - animate_turn_on(self, c, anim_x, "x") + animate_turn_on(self, anim_x, "x") end if anim_y then - animate_turn_on(self, c, anim_y, "y") + animate_turn_on(self, anim_y, "y") end self:emit_signal("inital_apply", c) @@ -189,12 +283,14 @@ function Scratchpad:turn_on() else local function inital_apply(c1) if helpers.client.is_child_of(c1, pid) then + self.client = c1 + self:apply(c1) if anim_x then - animate_turn_on(self, c1, anim_x, "x") + animate_turn_on(self, anim_x, "x") end if anim_y then - animate_turn_on(self, c1, anim_y, "y") + animate_turn_on(self, anim_y, "y") end self:emit_signal("inital_apply", c1) client.disconnect_signal("manage", inital_apply) @@ -205,111 +301,32 @@ function Scratchpad:turn_on() end end ---- Called when the turn off animation has ended -local function on_animate_turn_off_end(self, c, anim, tag, turn_off_on_end) - anim:unsubscribe() - anim.ended:unsubscribe() - - if turn_off_on_end then - -- When toggling off a scratchpad that's present on multiple tags - -- depsite still being unminizmied on the other tags it will become invisible - -- as it's position could be outside the screen from the animation - c:geometry({ - x = self.geometry.x + c.screen.geometry.x, - y = self.geometry.y + c.screen.geometry.y, - width = self.geometry.width, - height = self.geometry.height, - }) - helpers.client.turn_off(c, tag) - - self:emit_signal("turn_off", c) - - self.in_anim = false - end -end - ---- The turn off animation -local function animate_turn_off(self, c, anim, axis, turn_off_on_end) - local screen_on_toggled_scratchpad = c.screen - local tag_on_toggled_scratchpad = screen_on_toggled_scratchpad.selected_tag - - if c.floating == false then - -- Save the client geometry before floating it - local non_floating_x = c.x - local non_floating_y = c.y - local non_floating_width = c.width - local non_floating_height = c.height - - -- Can't animate non floating clients - c.floating = true - - -- Set the client geometry back to what it was before floating it - c:geometry({ - x = non_floating_x, - y = non_floating_y, - width = non_floating_width, - height = non_floating_height, - }) - end - - - if axis == "x" then - anim.pos = c.x - else - anim.pos = c.y - end - - anim:subscribe(function(pos) - if c and c.valid then - if axis == "x" then - c.x = pos - else - c.y = pos - end - end - self.in_anim = true - - -- Handles changing tag mid animation - -- Check for the following scenerio: - -- Toggle on scratchpad at tag 1 - -- Toggle on scratchpad at tag 2 - -- Toggle off scratchpad at tag 1 - -- Switch to tag 2 - -- Outcome: The client will remain on tag 1 and will instead be removed from tag 2 - if screen_on_toggled_scratchpad.selected_tag ~= tag_on_toggled_scratchpad then - on_animate_turn_off_end(self, c, anim, tag_on_toggled_scratchpad, true) - end - end) - - anim:set(anim:initial()) - - anim.ended:subscribe(function() - on_animate_turn_off_end(self, c, anim, nil, turn_off_on_end) - end) -end - --- Turns the scratchpad off function Scratchpad:turn_off() - local c = self:find()[1] - if c and not self.in_anim then - -- Get the tweens - local anim_x = self.rubato.x - local anim_y = self.rubato.y + self.client = self:find()[1] - local anim_x_duration = (anim_x and anim_x.duration) or 0 - local anim_y_duration = (anim_y and anim_y.duration) or 0 + -- Get the tweens + local anim_x = self.rubato.x + local anim_y = self.rubato.y - local turn_off_on_end = (anim_x_duration >= anim_y_duration) and true or false + local in_anim = false + if (anim_x and anim_x.state == true) or (anim_y and anim_y.state == true) then + in_anim = true + end + + if self.client and not in_anim then if anim_x then - animate_turn_off(self, c, anim_x, "x", turn_off_on_end) + self.turning_off = true + animate_turn_off(self, anim_x, "x") end if anim_y then - animate_turn_off(self, c, anim_y, "y", not turn_off_on_end) + self.turning_off = true + animate_turn_off(self, anim_y, "y") end if not anim_x and not anim_y then - helpers.client.turn_off(c) - self:emit_signal("turn_off", c) + helpers.client.turn_off(self.client) + self:emit_signal("turn_off", self.client) end end end @@ -335,8 +352,8 @@ function Scratchpad:toggle() end end else - is_turn_off = client.focus - and awful.rules.match(client.focus, self.rule) + is_turn_off = capi.client.focus + and awful.rules.match(capi.client.focus, self.rule) end if is_turn_off then diff --git a/config/awesome/module/bling/module/wallpaper.lua b/config/awesome/module/bling/module/wallpaper.lua index b8344ff..1252bee 100644 --- a/config/awesome/module/bling/module/wallpaper.lua +++ b/config/awesome/module/bling/module/wallpaper.lua @@ -53,36 +53,37 @@ function apply(wallpaper_object, args) args.offset = args.offset or { x = 0, y = 0 } args.scale = args.scale or 1 local positions = { - ["centered"] = function() + ["centered"] = function(s) gears.wallpaper.centered( wallpaper_object, - args.screen, + s, args.background, args.scale ) end, - ["tiled"] = function() - gears.wallpaper.tiled(wallpaper_object, args.screen, args.offset) + ["tiled"] = function(s) + gears.wallpaper.tiled(wallpaper_object, s, args.offset) end, - ["maximized"] = function() + ["maximized"] = function(s) gears.wallpaper.maximized( wallpaper_object, - args.screen, + s, args.ignore_aspect, args.offset ) end, - ["fit"] = function() - gears.wallpaper.fit(wallpaper_object, args.screen, args.background) + ["fit"] = function(s) + gears.wallpaper.fit(wallpaper_object, s, args.background) end, } + local call_func = nil if type(wallpaper_object) == "string" and gears.filesystem.file_readable(wallpaper_object) then -- path of an image file, we use a position function local p = args.position or "centered" - positions[p]() + call_func = positions[p] elseif type(wallpaper_object) == "function" then -- function wallpaper_object(args) @@ -91,10 +92,13 @@ function apply(wallpaper_object, args) and args.position then -- if the user sets a position function, wallpaper_object should be a cairo surface - positions[args.position]() + call_func = positions[args.position] else gears.wallpaper.set(wallpaper_object) end + if call_func then + call_func(args.screen) + end end --- Converts `args.wallpaper` to a list of `wallpaper_objects` readable by `apply` function). @@ -154,7 +158,15 @@ local simple_index = 0 function setters.simple(args) local wallpapers = prepare_list(args) simple_index = (simple_index % #wallpapers) + 1 - apply(wallpapers[simple_index], args) + if type(args.screen) == 'table' then + for _,v in ipairs(args.screen) do + args.screen = v + apply(wallpapers[simple_index], args) + args.screen = nil + end + else + apply(wallpapers[simple_index], args) + end end --- Set a random wallpaper from a list. @@ -164,7 +176,15 @@ end -- @see prepare_list function setters.random(args) local wallpapers = prepare_list(args) - apply(wallpapers[math.random(#wallpapers)], args) + if type(args.screen) == 'table' then + for _,v in ipairs(args.screen) do + args.screen = v + apply(wallpapers[math.random(#wallpapers)], args) + args.screen = nil + end + else + apply(wallpapers[math.random(#wallpapers)], args) + end end local simple_schedule_object = nil @@ -310,7 +330,10 @@ function setup(args) config.set_function = config.set_function or (config.wallpaper and setters.simple or setters.awesome_wallpaper) local function set_wallpaper(s) - config.screen = s or config.screen + if type(config.screen) ~= 'table' then + if config.screen and s and config.screen ~= s then return end + config.screen = s or config.screen + end config.set_function(config) end diff --git a/config/awesome/module/bling/module/window_swallowing.lua b/config/awesome/module/bling/module/window_swallowing.lua index 368541b..60950aa 100644 --- a/config/awesome/module/bling/module/window_swallowing.lua +++ b/config/awesome/module/bling/module/window_swallowing.lua @@ -11,53 +11,93 @@ local helpers = require(tostring(...):match(".*bling") .. ".helpers") local window_swallowing_activated = false -- you might want to add or remove applications here -local dont_swallow_classname_list = beautiful.dont_swallow_classname_list +local parent_filter_list = beautiful.parent_filter_list + or beautiful.dont_swallow_classname_list or { "firefox", "Gimp", "Google-chrome" } -local activate_dont_swallow_filter = beautiful.dont_swallow_filter_activated - or true +local child_filter_list = beautiful.child_filter_list + or beautiful.dont_swallow_classname_list or { } --- checks if client classname matches with any entry of the dont-swallow-list -local function check_if_swallow(c) - if not activate_dont_swallow_filter then - return true - end - for _, classname in ipairs(dont_swallow_classname_list) do - if classname == c.class then - return false +-- for boolean values the or chain way to set the values breaks with 2 vars +-- and always defaults to true so i had to do this to se the right value... +local swallowing_filter = true +local filter_vars = { beautiful.swallowing_filter, beautiful.dont_swallow_filter_activated } +for _, var in pairs(filter_vars) do + swallowing_filter = var +end + +-- check if element exist in table +-- returns true if it is +local function is_in_table(element, table) + local res = false + for _, value in pairs(table) do + if element:match(value) then + res = true + break end end - return true + return res end +-- if the swallowing filter is active checks the child and parent classes +-- against their filters +local function check_swallow(parent, child) + local res = true + if swallowing_filter then + local prnt = not is_in_table(parent, parent_filter_list) + local chld = not is_in_table(child, child_filter_list) + res = ( prnt and chld ) + end + return res +end + +-- async function to get the parent's pid +-- recieves a child process pid and a callback function +-- parent_pid in format "init(1)---ancestorA(pidA)---ancestorB(pidB)...---process(pid)" +function get_parent_pid(child_ppid, callback) + local ppid_cmd = string.format("pstree -A -p -s %s", child_ppid) + awful.spawn.easy_async(ppid_cmd, function(stdout, stderr, reason, exit_code) + -- primitive error checking + if stderr and stderr ~= "" then + callback(stderr) + return + end + local ppid = stdout + callback(nil, ppid) + end) +end + + -- the function that will be connected to / disconnected from the spawn client signal local function manage_clientspawn(c) -- get the last focused window to check if it is a parent window local parent_client = awful.client.focus.history.get(c.screen, 1) if not parent_client then return + elseif parent_client.type == "dialog" or parent_client.type == "splash" then + return end - -- io.popen is normally discouraged. Should probably be changed - local handle = io.popen( - [[pstree -T -p -a -s ]] - .. tostring(c.pid) - .. [[ | sed '2q;d' | grep -o '[0-9]*$' | tr -d '\n']] - ) - local parent_pid = handle:read("*a") - handle:close() - + get_parent_pid(c.pid, function(err, ppid) + if err then + return + end + parent_pid = ppid if - (tostring(parent_pid) == tostring(parent_client.pid)) - and check_if_swallow(c) + -- will search for "(parent_client.pid)" inside the parent_pid string + ( tostring(parent_pid):find("("..tostring(parent_client.pid)..")") ) + and check_swallow(parent_client.class, c.class) then c:connect_signal("unmanage", function() - helpers.client.turn_on(parent_client) - helpers.client.sync(parent_client, c) + if parent_client then + helpers.client.turn_on(parent_client) + helpers.client.sync(parent_client, c) + end end) helpers.client.sync(c, parent_client) helpers.client.turn_off(parent_client) end + end) end -- without the following functions that module would be autoloaded by require("bling") diff --git a/config/awesome/module/bling/theme-var-template.lua b/config/awesome/module/bling/theme-var-template.lua index 421d37c..13d0f5a 100644 --- a/config/awesome/module/bling/theme-var-template.lua +++ b/config/awesome/module/bling/theme-var-template.lua @@ -42,6 +42,7 @@ theme.tabbar_bg_normal_inactive = nil -- background color of unfocused clients o theme.tabbar_fg_normal_inactive = nil -- foreground color of unfocused clients on the tabbar when inactive -- mstab +theme.mstab_bar_disable = false -- disable the tabbar theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients theme.mstab_dont_resize_slaves = false -- whether the tabbed stack windows should be smaller than the -- currently focused stack window (set it to true if you use diff --git a/config/awesome/module/bling/widget/app_launcher/init.lua b/config/awesome/module/bling/widget/app_launcher/init.lua index 7eeaf17..b74c2ab 100644 --- a/config/awesome/module/bling/widget/app_launcher/init.lua +++ b/config/awesome/module/bling/widget/app_launcher/init.lua @@ -281,8 +281,8 @@ local function search(self, text) text = text:gsub( "%W", "" ) -- Check if there's a match by the app name or app command - if string.find(entry.name, case_insensitive_pattern(text)) ~= nil or - self.search_commands and string.find(entry.commandline, case_insensitive_pattern(text)) ~= nil + if string.find(entry.name:lower(), text:lower(), 1, true) ~= nil or + self.search_commands and string.find(entry.commandline, text:lower(), 1, true) ~= nil then table.insert(self._private.matched_entries, { name = entry.name, @@ -498,7 +498,6 @@ local function scroll_right(self) local rows, columns = self._private.grid:get_dimension() local pos = self._private.grid:get_widget_position(self._private.active_widget) local is_less_than_max_column = pos.col < columns - local is_less_than_max_page = self._private.current_page < self._private.pages_count -- Check if we can scroll down the app list if is_less_than_max_column then @@ -773,6 +772,7 @@ local function new(args) args.icon_theme = args.icon_theme or nil args.icons_size = args.icons_size or nil + args.type = args.type or "dock" args.show_on_focused_screen = args.show_on_focused_screen == nil and true or args.show_on_focused_screen args.screen = args.screen or capi.screen.primary args.placement = args.placement or awful.placement.centered @@ -919,7 +919,7 @@ local function new(args) } ret._private.widget = awful.popup { - type = "dock", + type = args.type, visible = false, ontop = true, placement = ret.placement, diff --git a/config/awesome/module/layout-machi/layout.lua b/config/awesome/module/layout-machi/layout.lua index b8cc215..d1ff077 100644 --- a/config/awesome/module/layout-machi/layout.lua +++ b/config/awesome/module/layout-machi/layout.lua @@ -182,6 +182,7 @@ function module.create(args_or_name, editor, default_cmd) end local function get_instance_data(screen, tag) + if screen == nil then return end local workarea = screen.workarea local instance = get_instance_(tag) local cmd = instance.cmd or module.global_default_cmd diff --git a/config/awesome/module/overflow.lua b/config/awesome/module/overflow.lua deleted file mode 100644 index 83b21eb..0000000 --- a/config/awesome/module/overflow.lua +++ /dev/null @@ -1,627 +0,0 @@ ---------------------------------------------------------------------------- --- A layout that allows its children to take more space than what's available --- in the surrounding container. If the content does exceed the available --- size, a scrollbar is added and scrolling behavior enabled. --- ---@DOC_wibox_layout_defaults_overflow_EXAMPLE@ --- @author Lucas Schwiderski --- @copyright 2021 Lucas Schwiderski --- @layoutmod wibox.layout.overflow ---------------------------------------------------------------------------- - -local base = require('wibox.widget.base') -local fixed = require('wibox.layout.fixed') -local separator = require('wibox.widget.separator') -local gtable = require('gears.table') -local gshape = require('gears.shape') -local gobject = require('gears.object') -local mousegrabber = mousegrabber - -local overflow = { mt = {} } - --- Determine the required space to draw the layout's children and, if necessary, --- the scrollbar. -function overflow:fit(context, orig_width, orig_height) - local widgets = self._private.widgets - local num_widgets = #widgets - if num_widgets < 1 then - return 0, 0 - end - - local width, height = orig_width, orig_height - local scrollbar_width = self._private.scrollbar_width - local scrollbar_enabled = self._private.scrollbar_enabled - local used_in_dir, used_max = 0, 0 - local is_y = self._private.dir == "y" - local avail_in_dir = is_y and orig_height or orig_width - - -- Set the direction covered by scrolling to the maximum value - -- to allow widgets to take as much space as they want. - if is_y then - height = math.huge - else - width = math.huge - end - - -- First, determine widget sizes. - -- Only when the content doesn't fit and needs scrolling should - -- we reduce content size to make space for a scrollbar. - for _, widget in pairs(widgets) do - local w, h = base.fit_widget(self, context, widget, width, height) - - if is_y then - used_max = math.max(used_max, w) - used_in_dir = used_in_dir + h - else - used_in_dir = used_in_dir + w - used_max = math.max(used_max, h) - end - end - - local spacing = self._private.spacing * (num_widgets - 1) - used_in_dir = used_in_dir + spacing - - local need_scrollbar = used_in_dir > avail_in_dir and scrollbar_enabled - - -- If the direction perpendicular to scrolling (e.g. width in vertical - -- scrolling) is not fully covered by any of the widgets, we can add our - -- scrollbar width to that value. Otherwise widget size will be reduced - -- during `layout` to make space for the scrollbar. - if need_scrollbar - and ( - (is_y and used_max < orig_width) - or (not is_y and used_max < orig_height) - ) then - used_max = used_max + scrollbar_width - end - - if is_y then - return used_max, used_in_dir - else - return used_in_dir, used_max - end -end - --- Layout children, scrollbar and spacing widgets. --- Only those widgets that are currently visible will be placed. -function overflow:layout(context, orig_width, orig_height) - local result = {} - local is_y = self._private.dir == "y" - local widgets = self._private.widgets - local avail_in_dir = is_y and orig_height or orig_width - local scrollbar_width = self._private.scrollbar_width - local scrollbar_enabled = self._private.scrollbar_enabled - local scrollbar_position = self._private.scrollbar_position - local width, height = orig_width, orig_height - local widget_x, widget_y = 0, 0 - local used_in_dir, used_max = 0, 0 - - -- Set the direction covered by scrolling to the maximum value - -- to allow widgets to take as much space as they want. - if is_y then - height = math.huge - else - width = math.huge - end - - -- First, determine widget sizes. - -- Only when the content doesn't fit and needs scrolling should - -- we reduce content size to make space for a scrollbar. - for _, widget in pairs(widgets) do - local w, h = base.fit_widget(self, context, widget, width, height) - - if is_y then - used_max = math.max(used_max, w) - used_in_dir = used_in_dir + h - else - used_in_dir = used_in_dir + w - used_max = math.max(used_max, h) - end - end - - used_in_dir = used_in_dir + self._private.spacing * (#widgets-1) - - -- Save size for scrolling behavior - self._private.avail_in_dir = avail_in_dir - self._private.used_in_dir = used_in_dir - - local need_scrollbar = used_in_dir > avail_in_dir and scrollbar_enabled - - local scroll_position = self._private.position - - if need_scrollbar then - local scrollbar_widget = self._private.scrollbar_widget - local bar_x, bar_y = 0, 0 - local bar_w, bar_h - -- The percentage of how much of the content can be visible within - -- the available space - local visible_percent = avail_in_dir / used_in_dir - -- Make scrollbar length reflect `visible_percent` - -- TODO: Apply a default minimum length - local bar_length = math.floor(visible_percent * avail_in_dir) - local bar_pos = (avail_in_dir - bar_length) * self._private.position - - if is_y then - bar_w, bar_h = base.fit_widget(self, context, scrollbar_widget, scrollbar_width, bar_length) - bar_y = bar_pos - - if scrollbar_position == "left" then - widget_x = widget_x + bar_w - elseif scrollbar_position == "right" then - bar_x = orig_width - bar_w - end - - self._private.bar_length = bar_h - - width = width - bar_w - else - bar_w, bar_h = base.fit_widget(self, context, scrollbar_widget, bar_length, scrollbar_width) - bar_x = bar_pos - - if scrollbar_position == "top" then - widget_y = widget_y + bar_h - elseif scrollbar_position == "bottom" then - bar_y = orig_height - bar_h - end - - self._private.bar_length = bar_w - - height = height - bar_h - end - - table.insert(result, base.place_widget_at( - scrollbar_widget, - math.floor(bar_x), - math.floor(bar_y), - math.floor(bar_w), - math.floor(bar_h) - )) - end - - local pos, spacing = 0, self._private.spacing - local interval = used_in_dir - avail_in_dir - - local spacing_widget = self._private.spacing_widget - if spacing_widget then - if is_y then - local _ - _, spacing = base.fit_widget(self, context, spacing_widget, width, spacing) - else - spacing = base.fit_widget(self, context, spacing_widget, spacing, height) - end - end - - for i, w in pairs(widgets) do - local content_x, content_y - local content_w, content_h = base.fit_widget(self, context, w, width, height) - - -- When scrolling down, the content itself moves up -> substract - local scrolled_pos = pos - (scroll_position * interval) - - -- Stop processing completely once we're passed the visible portion - if scrolled_pos > avail_in_dir then - break - end - - if is_y then - content_x, content_y = widget_x, scrolled_pos - pos = pos + content_h + spacing - - if self._private.fill_space then - content_w = width - end - else - content_x, content_y = scrolled_pos, widget_y - pos = pos + content_w + spacing - - if self._private.fill_space then - content_h = height - end - end - - local is_in_view = is_y - and (scrolled_pos + content_h > 0) - or (scrolled_pos + content_w > 0) - - if is_in_view then - -- Add the spacing widget, but not before the first widget - if i > 1 and spacing_widget then - table.insert(result, base.place_widget_at( - spacing_widget, - -- The way how spacing is added for regular widgets - -- and the `spacing_widget` is disconnected: - -- The offset for regular widgets is added to `pos` one - -- iteration _before_ the one where the widget is actually - -- placed. - -- Because of that, the placement for the spacing widget - -- needs to substract that offset to be placed right after - -- the previous regular widget. - math.floor(is_y and content_x or (content_x - spacing)), - math.floor(is_y and (content_y - spacing) or content_y), - math.floor(is_y and content_w or spacing), - math.floor(is_y and spacing or content_h) - )) - end - - table.insert(result, base.place_widget_at( - w, - math.floor(content_x), - math.floor(content_y), - math.floor(content_w), - math.floor(content_h) - )) - end - end - - return result -end - -function overflow:before_draw_children(_, cr, width, height) - -- Clip drawing for children to the space we're allowed to draw in - cr:rectangle(0, 0, width, height) - cr:clip() -end - - ---- The amount of units to advance per scroll event. --- This affects calls to `scroll` and the default mouse wheel handler. --- --- The default is `10`. --- --- @property step --- @tparam number step The step size. --- @see set_step - ---- Set the step size. --- --- @method overflow:set_step --- @tparam number step The step size. --- @see step -function overflow:set_step(step) - self._private.step = step - -- We don't need to emit enything here, since changing step only really - -- takes effect the next time the user scrolls -end - - ---- Scroll the layout's content by `amount * step`. --- A positive amount scroll down/right, a negative amount scrolls up/left. --- --- @method overflow:scroll --- @tparam number amount The amount to scroll by. --- @emits property::overflow::position --- @emitstparam property::overflow::position number position The new position. --- @emits widget::layout_changed --- @emits widget::redraw_needed --- @see step -function overflow:scroll(amount) - if amount == 0 then - return - end - local interval = self._private.used_in_dir - local delta = self._private.step / interval - - local pos = self._private.position + (delta * amount) - self:set_position(pos) -end - - ---- The scroll position. --- The position is represented as a fraction from `0` to `1`. --- --- @property position --- @tparam number position The position. --- @propemits true false --- @see set_position - ---- Set the current scroll position. --- --- @method overflow:set_position --- @tparam number position The new position. --- @propemits true false --- @emits widget::layout_changed --- @emits widget::redraw_needed --- @see position -function overflow:set_position(pos) - local current = self._private.position - local interval = self._private.used_in_dir - self._private.avail_in_dir - if current == pos - -- the content takes less space than what is available, i.e. everything - -- is already visible - or interval <= 0 - -- the position is out of range - or (current <= 0 and pos < 0) - or (current >= 1 and pos > 1) then - return - end - - self._private.position = math.min(1, math.max(pos, 0)) - - self:emit_signal("widget::layout_changed") - self:emit_signal("property::position", pos) -end - - ---- Get the current scroll position. --- --- @method overflow:get_position --- @treturn number position The current position. --- @see position -function overflow:get_position() - return self._private.position -end - - ---- The scrollbar width. --- For horizontal scrollbars, this is the scrollbar height --- --- The default is `5`. --- ---@DOC_wibox_layout_overflow_scrollbar_width_EXAMPLE@ --- --- @property scrollbar_width --- @tparam number scrollbar_width The scrollbar width. --- @propemits true false --- @see set_scrollbar_width - ---- Set the scrollbar width. --- --- @method overflow:set_scrollbar_width --- @tparam number scrollbar_width The new scrollbar width. --- @propemits true false --- @emits widget::layout_changed --- @emits widget::redraw_needed --- @see scrollbar_width -function overflow:set_scrollbar_width(width) - if self._private.scrollbar_width == width then - return - end - - self._private.scrollbar_width = width - - self:emit_signal("widget::layout_changed") - self:emit_signal("property::scrollbar_width", width) -end - - ---- The scrollbar position. --- --- For horizontal scrollbars, this can be `"top"` or `"bottom"`, --- for vertical scrollbars this can be `"left"` or `"right"`. --- The default is `"left"`/`"bottom"`. --- ---@DOC_wibox_layout_overflow_scrollbar_position_EXAMPLE@ --- --- @property scrollbar_position --- @tparam string scrollbar_position The scrollbar position. --- @propemits true false --- @see set_scrollbar_position - ---- Set the scrollbar position. --- --- @method overflow:set_scrollbar_position --- @tparam string scrollbar_position The new scrollbar position. --- @propemits true false --- @emits widget::layout_changed --- @emits widget::redraw_needed --- @see scrollbar_position -function overflow:set_scrollbar_position(position) - if self._private.scrollbar_position == position then - return - end - - self._private.scrollbar_position = position - - self:emit_signal("widget::layout_changed") - self:emit_signal("property::scrollbar_position", position) -end - - ---- The scrollbar visibility. --- If this is set to `false`, no scrollbar will be rendered, even if the layout's --- content overflows. Mouse wheel scrolling will work regardless. --- --- The default is `true`. --- --- @property scrollbar_enabled --- @tparam boolean scrollbar_enabled The scrollbar visibility. --- @propemits true false --- @see set_scrollbar_enabled - ---- Enable or disable the scrollbar visibility. --- --- @method overflow:set_scrollbar_enabled --- @tparam boolean scrollbar_enabled The new scrollbar visibility. --- @propemits true false --- @emits widget::layout_changed --- @emits widget::redraw_needed --- @see scrollbar_enabled -function overflow:set_scrollbar_enabled(enabled) - if self._private.scrollbar_enabled == enabled then - return - end - - self._private.scrollbar_enabled = enabled - - self:emit_signal("widget::layout_changed") - self:emit_signal("property::scrollbar_enabled", enabled) -end - --- Wraps a callback function for `mousegrabber` that is capable of --- updating the scroll position. -local function build_grabber(container) - local is_y = container._private.dir == "y" - local bar_interval = container._private.avail_in_dir - container._private.bar_length - local start_pos = container._private.position * bar_interval - local coords = mouse.coords() - local start = is_y and coords.y or coords.x - - return function(mouse) - if not mouse.buttons[1] then - return false - end - - local pos = is_y and mouse.y or mouse.x - container:set_position((start_pos + (pos - start)) / bar_interval) - - return true - end -end - --- Applies a mouse button signal using `build_grabber` to a scrollbar widget. -local function apply_scrollbar_mouse_signal(container, w) - w:connect_signal('button::press', function(_, _, _, button_id) - if button_id ~= 1 then - return - end - mousegrabber.run(build_grabber(container), "fleur") - end) -end - - ---- The scrollbar widget. --- This widget is rendered as the scrollbar element. --- --- The default is `awful.widget.separator{ shape = gears.shape.rectangle }`. --- ---@DOC_wibox_layout_overflow_scrollbar_widget_EXAMPLE@ --- --- @property scrollbar_widget --- @tparam widget scrollbar_widget The scrollbar widget. --- @propemits true false --- @see set_scrollbar_widget - ---- Set the scrollbar widget. --- --- This will also apply the mouse button handler. --- --- @method overflow:set_scrollbar_widget --- @tparam widget scrollbar_widget The new scrollbar widget. --- @propemits true false --- @emits widget::layout_changed --- @see scrollbar_widget -function overflow:set_scrollbar_widget(widget) - local w = base.make_widget_from_value(widget) - - apply_scrollbar_mouse_signal(self, w) - - self._private.scrollbar_widget = w - - self:emit_signal("widget::layout_changed") - self:emit_signal("property::scrollbar_widget", widget) -end - -local function new(dir, ...) - local ret = fixed[dir](...) - - gtable.crush(ret, overflow, true) - ret.widget_name = gobject.modulename(2) - - -- Manually set the position here. We don't know the bounding size yet. - ret._private.position = 0 - - -- Apply defaults. Bypass setters to avoid signals. - ret._private.step = 10 - ret._private.fill_space = true - ret._private.scrollbar_width = 5 - ret._private.scrollbar_enabled = true - ret._private.scrollbar_position = dir == "vertical" and "right" or "bottom" - - local scrollbar_widget = separator({ shape = gshape.rectangle }) - apply_scrollbar_mouse_signal(ret, scrollbar_widget) - ret._private.scrollbar_widget = scrollbar_widget - - ret:connect_signal('button::press', function(self, _, _, button) - if button == 4 then - if self.scroll_speed == nil or self.scroll_speed <= 0 then - self:scroll(-1) - else - self:scroll(-1 * self.scroll_speed) - end - elseif button == 5 then - if self.scroll_speed == nil or self.scroll_speed <= 0 then - self:scroll(1) - else - self:scroll(1 * self.scroll_speed) - end - end - end) - - return ret -end - - ---- Returns a new horizontal overflow layout. --- Child widgets are placed similar to `wibox.layout.fixed`, except that --- they may take as much width as they want. If the total width of all child --- widgets exceeds the width available whithin the layout's outer container --- a scrollbar will be added and scrolling behavior enabled. --- @tparam widget ... Widgets that should be added to the layout. --- @constructorfct wibox.layout.overflow.horizontal -function overflow.horizontal(...) - return new("horizontal", ...) -end - - ---- Returns a new vertical overflow layout. --- Child widgets are placed similar to `wibox.layout.fixed`, except that --- they may take as much height as they want. If the total height of all child --- widgets exceeds the height available whithin the layout's outer container --- a scrollbar will be added and scrolling behavior enabled. --- @tparam widget ... Widgets that should be added to the layout. --- @constructorfct wibox.layout.fixed.horizontal -function overflow.vertical(...) - return new("vertical", ...) -end - - ---- Add spacing between each layout widgets. --- --- This behaves just like in `wibox.layout.fixed`: --- ---@DOC_wibox_layout_fixed_spacing_EXAMPLE@ --- --- @property spacing --- @tparam number spacing Spacing between widgets. --- @propemits true false --- @see wibox.layout.fixed - - ---- The widget used to fill the spacing between the layout elements. --- By default, no widget is used. --- --- This behaves just like in `wibox.layout.fixed`: --- ---@DOC_wibox_layout_fixed_spacing_widget_EXAMPLE@ --- --- @property spacing_widget --- @tparam widget spacing_widget --- @propemits true false --- @see wibox.layout.fixed - - ---- Set the layout's fill_space property. --- --- If this property is `true`, widgets --- take all space in the non-scrolling directing (e.g. `width` for vertical --- scrolling). If `false`, they will only take as much as they need for their --- content. --- --- The default is `true`. --- ---@DOC_wibox_layout_overflow_fill_space_EXAMPLE@ --- --- @property fill_space --- @tparam boolean fill_space --- @propemits true false - - ---@DOC_fixed_COMMON@ - ---@DOC_widget_COMMON@ - ---@DOC_object_COMMON@ - -return setmetatable(overflow, overflow.mt) - --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/config/awesome/module/rubato/README.md b/config/awesome/module/rubato/README.md index 1430da6..fcc530e 100644 --- a/config/awesome/module/rubato/README.md +++ b/config/awesome/module/rubato/README.md @@ -13,7 +13,8 @@ Basically like [awestore](https://github.com/K4rakara/awestore) but not really. Join the cool curve crew - +

Background and Explanation

@@ -210,82 +211,127 @@ In practice, creating your own easing would look like this: 1. Go to [easings.net](https://easings.net) -For the sake of this tutorial, we'll do an extremely complex easing, "ease in elastic" +For the sake of this tutorial, we'll do an extremely complex (hellish? easing, "ease in elastic" +For the sake of this tutorial, we'll do both an easy easing and a complex one. The easy easing will +be the beautifully simple and quite frankly obvious quadratic. The much worse easing will be "ease +in elastic." 2. Find the necessary information -**Important:** You should really use sagemath or Wolfram Mathematica to get as exact of a derivative -as you can. Wolfram Alpha doesn't cut it. I personally used sagemath because it's actually free, -which is pretty cool. To take that one step further, I'd suggest using jupyter notebook in tandem -with sagemath because if you run `%display latex` you get a super good looking output. If you can't -use jupyter (or don't want to), `%display ascii_art` is a pretty cool alternative. +For quadratic we already know the function: `y=x^2`. I don't even need to use latex it's that easy. + +For ease in elastic, we use the function given [here](https://easings.net/#easeInElastic): -The initial function, given by [easings.net](https://easings.net), is as follows: +3. Take the derivative + +Quadratic: `y=2x`, easy as that. + +**Important:** Look. Computers aren't the greatest at indefinite mathematics. As such, it's +possible that, like myself, you will have a hard time getting the correct derivative if it's as +complicated as these here. Don't be discouraged, however! Sagemath (making sure not to factor +anything) could correctly do out this math, even if I had a bit of a scare realizing that when I +was factoring it I was just being saved by `override_simulate` being accidentally set to true. + +Anyways, use sagemath and jupyter notebook. I don't know if all sagemaths come with it +preinstalled, but nix makes it so easy that all I have to do is `sage -n jupyter` and it'll open it +right up. `%display latex` in jupiter makes it look pretty, whereas `%display ascii_art` will make +it look *presentable* in tui sagemath. + The derivative (via sagemath) is as follows: - -First we double check that `f'(0)=0`, which in this case it is not. + + +4. Double check that `f'(0)=0` + +Quadratic: `2*0 = 0` so we're good + +Ease in elastic not so much, however: + +We'll subtract this value from `f(x)` so that our new `f(x)`, let's say `f_2(x)` has a point at +(0, 0). -so now we subtract `f'(0)` from `f'(x)` and get a pretty messy function, let's say `f_2(x)`. -Regrettably, we're about to mess up that function a little more. Next we check that `f_2(1)=1`. In -this case, once again, it doesn't. We get - +5. Double check that `f_2(1)=1` -So now we divide our `f(x)` by `f(1)`, to get our final function, `f_e(x)` (easing function) (I am -so good at naming these kinds of things) - +Quadratic: No, actually. This means we have to do a wee bit of work: `f(1)=2`, so to counteract this, +we'll create a new (and final) function that we can call `f_e` (easing function) by dividing `f(x)` +by `f(1)`. In practice this looks like this: -Great... This is going to be a treat to write as lua... Anyways, our final step is to find the -definite integral from 0 to 1 of our `f(x)`, which is this - +``` +f(1)=2, f(x)/f(1) = 2x / 2 = x, f_e(x)=x +``` -Now I'm sure that looks pretty daunting. However, these functions are kinda stupidly easy to find -with sagemath. You basically only have to run these commands: +Easy as that! + +Or so you thought. Now let's check the same for ease in elastic: + + + +Hence the need for sagemath. Once we divide the two we get our final easing function, this: + + + +What on god's green earth is that. Well whatever, at least it works (?). + +6. Finally, we get the definite integral from 0 to 1 of our `f(x)` + +For `f(x)=x` we can do that in our heads, it's just `1/2`. + +For ease in elastic not so much. You can do this with sagemath and eventually get this: + + + +So this all looked pretty daunting probably, and to be honest it took me hours of either not using +sage (I tried with wolfram alpha for a good hour) or using sage incorrectly (it took three months +to realize that this entire section of the readme was wrong and that using `factor` made it +incorrect), but now that I have this easy little code snippet you can use for sage it shouldn't be +as much of a hastle for you. ```python from sage.symbolic.integration.integral import definite_integral function('f') -f(x)=factor(derivative('''your function goes here''', x)) -f(x)=factor(f(x)-f(0)) -f(x)=factor(f(x)/f(1)) +f(x)='''your function goes here''' +f(x)=derivative(f(x), x) +f(x)=f(x)-f(0) +f(x)=f(x)/f(1) print(f(x)) # easing print(definite_integral(f(x), x, 0, 1)) # F ``` -which will tell you all you need to know. +So the thing with using `factor` is that, while on some weird other version of sage I was geting a +bunch of 0.49999s which wouldn't round to .5, the result was straight up wrong. So I advise against +it, and if you can't do the derivative then sucks to suck I guess (just lmk in an issue or +something and I'll try my very best). -It's important to use the `factor(...)` thing because otherwise you may end up with decimals, which -really should be avoided if possible. When I didn't do factor, there were 0.499999s which makes it -decently less accurate and substantially more complicated. +4. Now we just have to translate this into an actual lua table. -4. Now we just have to translate this into an actual lua table. You might want to be careful about - not doing more operations than necessary but honestly it probably doesn't much matter. +Quadratic, as usual, is easy. +```lua +local quadratic = { + F = 1/2 -- F = 1/2 + easing = function(t) return t end -- f(x) = x +} +``` + +Ease in elastic, as usual, is not. At one point I had the willpower to try and optimize operations, +but I really don't want to simplify those equations and I can't trust `factor`, so for now it stays +as is. If it irks you, make a pull request and save us both. ```lua ---all the constants are calculated only once -local cs = { - c1 = 6 * math.pi - 3 * math.sqrt(3) * math.log(2), - c2 = math.sqrt(3) * math.pi, - c3 = 6 * math.sqrt(3) * math.log(2), - c4 = 6 * math.pi - 6147 * math.sqrt(3) * math.log(2), - c5 = 46 * math.pi / 6 -} - -bouncy = { - F = (20 * math.pi - (10 * math.log(2) - 2049) * math.sqrt(3)) / - (20 * math.pi - 20490 * math.sqrt(3) * math.log(2)), - easing = function(t) - --both of these values are reused - local c1 = (20 * t * math.pi) / 3 - cs.c5 - local c2 = math.pow(2, 10 * t + 1) --in the 2^{10x+2} I factored out the 2 to calculate this once - - return (cs.c1 + cs.c2 * c2 * math.cos(c1) + cs.c3 * c2 * math.sin(c1)) / cs.c4 - end +local bouncy = { + F = (20*math.sqrt(3)*math.pi-30*math.log(2)-6147) / + (10*(2*math.sqrt(3)*math.pi-6147*math.log(2))), + easing = function(t) return +(4096*math.pi*math.pow(2, 10*t-10)*math.cos(20/3*math.pi*t-43/6*math.pi) ++6144*math.pow(2, 10*t-10)*math.log(2)*math.sin(20/3*math.pi*t-43/6*math.pi) ++2*math.sqrt(3)*math.pi-3*math.log(2)) / +(2*math.pi*math.sqrt(3)-6147*math.log(2)) + end } +-- how it would actually look in a timed object timed = rubato.timed { intro = 0, --we'll use this as an outro, since it's weird as an intro outro = 0.7, @@ -350,3 +396,5 @@ about in the first place. Plus, it'll be the first of my projects without garbag - [ ] only apply corrective coefficient to plateau - [ ] Do `prop_intro` more intelligently so it doesn't have to do so many comparisons - [ ] Make things like `abort` more useful + - [ ] Merge that pr by @Kasper so instant works + - [ ] Add a manager (this proceeds the above todo thing) diff --git a/config/awesome/module/rubato/easing.lua b/config/awesome/module/rubato/easing.lua index d482228..43a54ee 100644 --- a/config/awesome/module/rubato/easing.lua +++ b/config/awesome/module/rubato/easing.lua @@ -25,18 +25,19 @@ local b_cs = { c5 = 46 * math.pi / 6 } ---the bouncy one as seen in the readme +-- Okay look. It works. It's not terribly slow because computers can do math +-- quick. The other one decidedly does not work (thanks sagemath, I trusted +-- you...) so this will have to do. I may try to fix it up at some point, I may +-- just leave it be and laugh to myself whenever I see this. As they say, if +-- As they say, if you want something fixed that badly, make a pull request lol local bouncy = { - F = (20 * math.pi - (10 * math.log(2) - 2049) * math.sqrt(3)) / - (20 * math.pi - 20490 * math.sqrt(3) * math.log(2)), - easing = function(t) - --short circuit - if t == 0 then return 0 end - if t == 1 then return 1 end - - local c1 = (20 * t * math.pi) / 3 - b_cs.c5 - local c2 = math.pow(2, 10 * t + 1) - return (b_cs.c1 + b_cs.c2 * c2 * math.cos(c1) + b_cs.c3 * c2 * math.sin(c1)) / b_cs.c4 + F = (20*math.sqrt(3)*math.pi-30*math.log(2)-6147) / + (10*(2*math.sqrt(3)*math.pi-6147*math.log(2))), + easing = function(t) return +(4096*math.pi*math.pow(2, 10*t-10)*math.cos(20/3*math.pi*t-43/6*math.pi) ++6144*math.pow(2, 10*t-10)*math.log(2)*math.sin(20/3*math.pi*t-43/6*math.pi) ++2*math.sqrt(3)*math.pi-3*math.log(2)) / +(2*math.pi*math.sqrt(3)-6147*math.log(2)) end } diff --git a/config/awesome/module/rubato/timed.lua b/config/awesome/module/rubato/timed.lua index e4f26b6..5d14735 100644 --- a/config/awesome/module/rubato/timed.lua +++ b/config/awesome/module/rubato/timed.lua @@ -44,11 +44,12 @@ local function simulate_easing(pos, duration, intro, intro_e, outro, outro_e, m, local ps_pos = pos local dx + -- Key for cacheing results - local key = string.format("%f %f %f %s %f %s %s %s", + local key = string.format("%f %f %f %s %f %s %f %f", pos, duration, - intro, intro_e, - outro, outro_e, + intro, tostring(intro_e), + outro, tostring(outro_e), m, b) -- Short circuits if it's already done the calculation @@ -106,22 +107,24 @@ local function timed(args) obj.easing_inter = args.easing_inter or obj.easing --dev interface changes - obj.log = args.log or false + obj.log = args.log or function() end obj.awestore_compat = args.awestore_compat or false --animation logic changes - obj.override_simulate = args.override_simulate or true - obj.rapid_set = args.rapid_set ~= nil and args.rapid_set or obj.awestore_compat - - obj.rate = args.rate or RUBATO_DEF_RATE or 30 - obj.override_dt = args.override_dt or RUBATO_OVERRIDE_DT or true + obj.override_simulate = args.override_simulate or false + --[[ rapid_set is allowed by awestore but I don't like it, so it's bound to awestore_compat if not explicitly set + override_dt doesn't work well with big animations or scratchpads (blame awesome not me) (probably) so that too is + is tied to awestore_compat if not explicitly set, then to the default value ]] + obj.rapid_set = args.rapid_set == nil and obj.awestore_compat or args.rapid_set + obj.override_dt = args.override_dt == nil and (not obj.awestore_compat and RUBATO_OVERRIDE_DT) or args.override_dt -- hidden properties obj._props = { - target = obj.pos + target = obj.pos, + rate = args.rate or RUBATO_DEF_RATE } - -- annoying awestore compatibility + -- awestore compatibility if obj.awestore_compat then obj._initial = obj.pos obj._last = 0 @@ -134,37 +137,39 @@ local function timed(args) end - --TODO: fix double pos thing - -- Variables used in calculation - local time = 0 - local dt = 1 / obj.rate - local dx = 0 - local m - local b - local is_inter --whether or not it's in an intermittent state + -- Variables used in calculation, defined once bcz less operations + local time = 0 -- current time + local dt = 1 / obj._props.rate -- change in time + local dx = 0 -- value of slope at current time + local m -- slope + local b -- y-intercept + local is_inter --whether or not it's in an intermittent state - local last_frame_time = 0 --the time before the last frame - local raw_dt = dt + local last_frame_time --the time at the last frame + local frame_time = dt --duration of the last frame (placeholder) -- Variables used in simulation - local ps_pos - local coef - + local ps_pos -- pseudoposition + local coef -- corrective coefficient TODO: apply to plateau -- The timer that does all the animating - local timer = gears.timer() + local timer = gears.timer { timeout = dt } timer:connect_signal("timeout", function() -- Find the correct dt if it's not already correct - if (obj.override_dt) then - dt = os.clock() - last_frame_time + if (obj.override_dt and last_frame_time) then + frame_time = os.clock() - last_frame_time - if (raw_dt < dt) then timer.timeout = dt - else dt = raw_dt end - - last_frame_time = os.clock() + --[[ if frame time is bigger than dt, we must readjust dt by the difference + between dt and the last frame. Basically, dt + (frame_time - dt) which just + results in frame_time ]] + if (frame_time > timer.timeout) then dt = frame_time + else dt = timer.timeout end end + -- for the next timeout event + if (obj.override_dt) then last_frame_time = os.clock() end + --increment time time = time + dt @@ -181,7 +186,7 @@ local function timed(args) obj.pos = obj.pos + dx * dt * coef --sets up when to stop by time - --weirdness is to try to get closest to duration + --weirdness is to try to get as close to duration as possible if obj.duration - time < dt / 2 then obj.pos = obj._props.target --snaps to target in case of small error time = obj.duration --snaps time to duration @@ -192,7 +197,7 @@ local function timed(args) --run subscribed in functions obj:fire(obj.pos, time, dx) - -- awestore compatibility.... + -- awestore compatibility... if obj.awestore_compat then obj.ended:fire(obj.pos, time, dx) end --otherwise it just fires normally @@ -203,19 +208,18 @@ local function timed(args) -- Set target and begin interpolation local function set(target_new) - --disallow setting it twice (because it makes it go wonky) + --disallow setting it twice (because it makes it go wonky sometimes) if not obj.rapid_set and obj._props.target == target_new then return end --animation values - obj._props.target = target_new --sets target - time = 0 --resets time - coef = 1 --resets coefficient + obj._props.target = target_new --sets target + time = 0 --resets time + coef = 1 --resets coefficient --rate stuff - dt = 1 / obj.rate - raw_dt = dt - last_frame_time = os.clock() - timer.timeout = dt + --both of these values would ideally be timer.timeout so that's their default + dt, frame_time = timer.timeout, timer.timeout + last_frame_time = nil --is given a value after the first frame -- does annoying awestore compatibility if obj.awestore_compat then @@ -223,6 +227,7 @@ local function timed(args) obj.started:fire(obj.pos, time, dx) end + -- if it's already started, reflect that in is_inter is_inter = timer.started --set initial position if interrupting another animation @@ -238,7 +243,9 @@ local function timed(args) b) --if it will make a mistake (or override_simulate is true), fix it - if obj.override_simulate or b / math.abs(b) ~= m / math.abs(m) then + --it should only make a mistake when switching direction + --b ~= zero protection so that I won't get any NaNs (because NaN ~= NaN) + if obj.override_simulate or (b ~= 0 and b / math.abs(b) ~= m / math.abs(m)) then ps_pos = simulate_easing(obj.pos, obj.duration, (is_inter and obj.inter or obj.intro) * (obj.prop_intro and obj.duration or 1), is_inter and obj.easing_inter.easing or obj.easing.easing, @@ -248,7 +255,7 @@ local function timed(args) --get coefficient by calculating ratio of theoretical range : experimental range coef = (obj.pos - obj._props.target) / (obj.pos - ps_pos) - if coef ~= coef then coef = 1 end --check for div by 0 resulting in nan + if coef ~= coef then coef = 1 end --check for div by 0 resulting in NaN end if not timer.started then timer:start() end @@ -268,8 +275,7 @@ local function timed(args) b = nil is_inter = false coef = 1 - dt = 1 / obj.rate - timer.timeout = dt + dt = timer.timeout end -- Effectively pauses the timer @@ -282,7 +288,6 @@ local function timed(args) obj.subscribe_callback = function(func) func(obj.pos, time, dt) end if args.subscribed ~= nil then obj:subscribe(args.subscribed) end - -- Metatable for cooler api local mt = {} function mt:__index(key) @@ -302,6 +307,11 @@ local function timed(args) -- Changing target should call set elseif key == "target" then set(value) --set target + -- Changing rate should also update timeout + elseif key == "rate" then + self._props.rate = value + timer.timeout = 1 / value + -- If it's in _props set it there elseif self._props[key] ~= nil then self._props[key] = value diff --git a/config/awesome/module/wallpaper.lua b/config/awesome/module/wallpaper.lua deleted file mode 100644 index b18f1fd..0000000 --- a/config/awesome/module/wallpaper.lua +++ /dev/null @@ -1,78 +0,0 @@ --- Credits to https://github.com/WillPower3309/awesome-widgets/blob/master/wallpaper-blur.lua --- @author William McKinnon --- I tried implementing this with `gears.wallpaper` but the latency was just too much, so feh is preferable here -local awful = require("awful") -local gears = require("gears") -local naughty = require("naughty") -local beautiful = require("beautiful") - -local blurred = false; - -local wallpaper = beautiful.wallpaper -local blurredWallpaper = beautiful.wallpaper_blur - -awful.spawn.with_shell("feh --bg-fill " .. wallpaper) - -local function exists(file) - local ok, err, code = os.rename(file, file) - if not ok then if code == 13 then return true end end - return ok, err -end - -if not exists(blurredWallpaper) then - naughty.notify({ - preset = naughty.config.presets.normal, - title = 'Wallpaper', - text = 'Generating blurred wallpaper...' - }) - - -- uses image magick to create a blurred version of the wallpaper - awful.spawn.with_shell( - "convert -filter Gaussian -blur 0x20 " .. wallpaper .. " " .. - blurredWallpaper) - - naughty.notify({ - preset = naughty.config.presets.normal, - title = 'Wallpaper', - text = 'Blurred wallpaper generated!' - }) -end - --- changes to blurred wallpaper -local function blur() - if not blurred then - awful.spawn.with_shell("feh --bg-fill " .. blurredWallpaper) - blurred = true - end -end - --- changes to normal wallpaper -local function unblur() - if blurred then - awful.spawn.with_shell("feh --bg-fill " .. wallpaper) - blurred = false - end -end - --- blur / unblur on tag change -tag.connect_signal('property::selected', function(t) - -- if tag has clients - for _ in pairs(t:clients()) do - blur() - return - end - -- if tag has no clients - unblur() -end) - --- check if wallpaper should be blurred on client open -client.connect_signal("manage", function(c) blur() end) - --- check if wallpaper should be unblurred on client close -client.connect_signal("unmanage", function(c) - local t = awful.screen.focused().selected_tag - -- check if any open clients - for _ in pairs(t:clients()) do return end - -- unblur if no open clients - unblur() -end) diff --git a/config/awesome/module/window_switcher.lua b/config/awesome/module/window_switcher.lua deleted file mode 100644 index af7fe54..0000000 --- a/config/awesome/module/window_switcher.lua +++ /dev/null @@ -1,392 +0,0 @@ -local cairo = require("lgi").cairo -local awful = require("awful") -local gears = require("gears") -local wibox = require("wibox") -local beautiful = require("beautiful") -local helpers = require("helpers") - -local dpi = beautiful.xresources.apply_dpi - -local window_switcher_first_client -- The client that was focused when the window_switcher was activated -local window_switcher_minimized_clients = {} -- The clients that were minimized when the window switcher was activated -local window_switcher_grabber - -local get_num_clients = function(s) - local minimized_clients_in_tag = 0 - local matcher = function(c) - return awful.rules.match(c, { - minimized = true, - skip_taskbar = false, - hidden = false, - first_tag = s.selected_tag - }) - end - for c in awful.client.iterate(matcher) do - minimized_clients_in_tag = minimized_clients_in_tag + 1 - end - return minimized_clients_in_tag + #s.clients -end - -local window_switcher_hide = function() - -- Add currently focused client to history - if client.focus then - local window_switcher_last_client = client.focus - awful.client.focus.history.add(window_switcher_last_client) - -- Raise client that was focused originally - -- Then raise last focused client - if window_switcher_first_client and window_switcher_first_client.valid then - window_switcher_first_client:raise() - window_switcher_last_client:raise() - end - end - - -- Minimize originally minimized clients - local s = awful.screen.focused() - local clients = s.selected_tag:clients() - for _, c in pairs(window_switcher_minimized_clients) do - if c and c.valid and not (client.focus and client.focus == c) then - c.minimized = true - end - end - -- Reset helper table - window_switcher_minimized_clients = {} - - -- Resume recording focus history - awful.client.focus.history.enable_tracking() - -- Stop and hide window_switcher - awful.keygrabber.stop(window_switcher_grabber) - s.window_switcher_box.visible = false -end - -local function draw_widget(s, type, client_width, client_height, client_margin, - background, border_radius, border_width, - border_color, text_font, font_icons, font_icons_font, - mouse_keys) - local set_icon = function(item, c) - local i = font_icons[c.class] or font_icons['_'] - item:get_children_by_id('text_icon')[1].markup = - "" .. i.symbol .. "" - end - - local update_thumbnail = function(self, c) - local content = gears.surface(c.content) - local cr = cairo.Context(content) - local x, y, w, h = cr:clip_extents() - local 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() - self:get_children_by_id('thumbnail')[1].image = gears.surface.load(img) - end - - local icon_widget = function() - if (font_icons) ~= nil then - return { - widget = wibox.widget.textbox, - id = 'text_icon', - font = font_icons_font, - forced_width = dpi(50), - align = "center", - valign = "center" - } - else - return { - awful.widget.clienticon, - margins = 5, - forced_width = dpi(50), - widget = wibox.container.margin - } - end - end - - local tasklist_widget = function() - if type == "text" then - return awful.widget.tasklist { - screen = s, - filter = awful.widget.tasklist.filter.currenttags, - buttons = mouse_keys, - style = {font = text_font}, - layout = {layout = wibox.layout.fixed.vertical}, - widget_template = { - widget = wibox.container.background, - id = "bg_role", - forced_height = item_height, - create_callback = function(self, c, _, __) - set_icon(self, c) - c:connect_signal("property::class", - function() - set_icon(self, c) - end) - end, - { - layout = wibox.layout.fixed.horizontal, - icon_widget(), - { - { - widget = wibox.widget.textbox, - id = 'text_role', - align = "center" - }, - widget = wibox.container.margin, - left = dpi(6), - right = dpi(14), - -- Add margins to top and bottom in order to force the - -- text to be on a single line, if needed. Might need - -- to adjust them according to font size. - top = dpi(14), - bottom = dpi(14) - } - } - } - } - else - return awful.widget.tasklist { - screen = s, - filter = awful.widget.tasklist.filter.currenttags, - buttons = mouse_keys, - style = {font = text_font}, - layout = {layout = wibox.layout.flex.horizontal}, - widget_template = { - widget = wibox.container.background, - id = "bg_role", - forced_width = client_width, - forced_height = client_height, - create_callback = function(self, c, _, __) - if (font_icons) ~= nil then - set_icon(self, c) - c:connect_signal("property::class", - function() - set_icon(self, c) - end) - end - update_thumbnail(self, c) - end, - update_callback = function(self, c, _, __) - if (font_icons) ~= nil then - set_icon(self, c) - c:connect_signal("property::class", - function() - set_icon(self, c) - end) - end - update_thumbnail(self, c) - end, - { - layout = wibox.layout.flex.vertical, - { - widget = wibox.container.margin, - left = dpi(6), - right = dpi(14), - -- Add margins to top and bottom in order to force the - -- text to be on a single line, if needed. Might need - -- to adjust them according to font size. - top = dpi(14), - bottom = dpi(14), - { - widget = wibox.widget.imagebox, - id = 'thumbnail', - resize = true, - horizontal_fit_policy = "fit", - vertical_fit_policy = "fit" - } - }, - { - layout = wibox.layout.fixed.horizontal, - icon_widget(), - { - widget = wibox.container.margin, - left = dpi(6), - right = dpi(14), - -- Add margins to top and bottom in order to force the - -- text to be on a single line, if needed. Might need - -- to adjust them according to font size. - top = dpi(14), - bottom = dpi(14), - { - widget = wibox.widget.textbox, - id = 'text_role', - align = "center" - } - } - } - } - } - } - end - end - - s.window_switcher_tasklist = tasklist_widget() - - s.window_switcher_box = awful.popup({ - type = "dropdown_menu", - visible = false, - ontop = true, - screen = s, - bg = "#00000000", - widget = { - { - s.window_switcher_tasklist, - margins = client_margin, - widget = wibox.container.margin - }, - bg = background, - shape_border_color = border_color, - shape_border_width = border_width, - shape = helpers.rrect(border_radius), - widget = wibox.container.background - } - }) - - -- Center window switcher whenever its height changes - s.window_switcher_box:connect_signal("property::width", function() - awful.placement.centered(s.window_switcher_box, - {honor_workarea = true, honor_padding = true}) - if s.window_switcher_box.visible and get_num_clients(s) == 0 then - window_switcher_hide() - end - end) - s.window_switcher_box:connect_signal("property::height", function() - awful.placement.centered(s.window_switcher_box, - {honor_workarea = true, honor_padding = true}) - if s.window_switcher_box.visible and get_num_clients(s) == 0 then - window_switcher_hide() - end - end) -end - -local enable = function(opts) - local opts = opts or {} - - local type = opts.type or "thumbnail" - local client_width - if type == "thumbnail" then - client_width = opts.client_width or dpi(150) - else - client_width = opts.client_width or dpi(500) - end - local client_height = opts.client_height or dpi(250) - local client_margin = opts.client_margin or dpi(10) - local background = beautiful.window_switcher_widget_bg or "#000000" - local border_radius = beautiful.window_switcher_widget_border_radius or - dpi(0) - local border_width = beautiful.window_switcher_widget_border_width or dpi(0) - local border_color = beautiful.window_switcher_widget_border_color or - "#ffffff" - local text_font = opts.text_font or beautiful.font - local font_icons = opts.font_icons or nil - local font_icons_font = opts.font_icons_font or beautiful.font - - local hide_window_switcher_key = opts.hide_window_switcher_key or 'Escape' - - local select_client_key = opts.select_client_key or 1 - local minimize_key = opts.minimize_key or 'n' - local unminimize_key = opts.unminimize_key or 'N' - local kill_client_key = opts.kill_client_key or 'q' - - local cycle_key = opts.cycle_key or 'Tab' - - local previous_key = opts.previous_key or 'Left' - local next_key = opts.next_key or 'Right' - - local vim_previous_key = opts.vim_previous_key or 'h' - local vim_next_key = opts.vim_next_key or 'l' - - local scroll_previous_key = opts.scroll_previous_key or 4 - local scroll_next_key = opts.scroll_next_key or 5 - - local mouse_keys = gears.table.join(awful.button { - modifiers = {"Any"}, - button = select_client_key, - on_press = function(c) client.focus = c end - }, awful.button { - modifiers = {"Any"}, - button = scroll_previous_key, - on_press = function() awful.client.focus.byidx(-1) end - }, awful.button { - modifiers = {"Any"}, - button = scroll_next_key, - on_press = function() awful.client.focus.byidx(1) end - }) - - local keyboard_keys = { - [hide_window_switcher_key] = window_switcher_hide, - - [minimize_key] = function() - if client.focus then client.focus.minimized = true end - end, - [unminimize_key] = function() - if awful.client.restore() then - client.focus = awful.client.restore() - end - end, - [kill_client_key] = function() - if client.focus then client.focus:kill() end - end, - - [cycle_key] = function() awful.client.focus.byidx(1) end, - - [previous_key] = function() awful.client.focus.byidx(1) end, - [next_key] = function() awful.client.focus.byidx(-1) end, - - [vim_previous_key] = function() awful.client.focus.byidx(1) end, - [vim_next_key] = function() awful.client.focus.byidx(-1) end - } - - awesome.connect_signal("module::window_switcher::visibility", function(s) - local number_of_clients = get_num_clients(s) - if number_of_clients == 0 then return end - - -- Store client that is focused in a variable - window_switcher_first_client = client.focus - - -- Stop recording focus history - awful.client.focus.history.disable_tracking() - - -- Go to previously focused client (in the tag) - awful.client.focus.history.previous() - - -- Track minimized clients - -- Unminimize them - -- Lower them so that they are always below other - -- originally unminimized windows - local clients = s.selected_tag:clients() - for _, c in pairs(clients) do - if c.minimized then - table.insert(window_switcher_minimized_clients, c) - c.minimized = false - c:lower() - end - end - - -- Start the keygrabber - window_switcher_grabber = awful.keygrabber.run( - function(_, key, event) - if event == "release" then - -- Hide if the modifier was released - -- We try to match Super or Alt or Control since we do not know which keybind is - -- used to activate the window switcher (the keybind is set by the user in keys.lua) - if key:match("Super") or key:match("Alt") or - key:match("Control") then - window_switcher_hide() - end - -- Do nothing - return - end - - -- Run function attached to key, if it exists - if keyboard_keys[key] then keyboard_keys[key]() end - end) - - gears.timer.delayed_call(function() - -- Finally make the window switcher wibox visible after - -- a small delay, to allow the popup size to update - draw_widget(s, type, client_width, client_height, client_margin, - background, border_radius, border_width, border_color, - text_font, font_icons, font_icons_font, mouse_keys) - s.window_switcher_box.visible = true - end) - end) -end - -return {enable = enable} diff --git a/config/awesome/rc.lua b/config/awesome/rc.lua index f5efdd7..8870405 100644 --- a/config/awesome/rc.lua +++ b/config/awesome/rc.lua @@ -1,12 +1,13 @@ +pcall(require, "luarocks.loader") --[[ _____ __ _ __ _____ _____ _____ _______ _____ | | | | | ___| ___| | | ___| | - | | | | ___|___ | | | | | | ___| |__|__|_______|_____|_____|_____|__|_|__|_____| - + ~ AestheticArch ~ + rxyhn --]] -pcall(require, "luarocks.loader") -- Standard awesome library local gfs = require("gears.filesystem") @@ -14,17 +15,18 @@ local awful = require("awful") -- Theme handling library local beautiful = require("beautiful") +theme_dir = gfs.get_configuration_dir() .. "theme/" +dpi = beautiful.xresources.apply_dpi beautiful.init(gfs.get_configuration_dir() .. "theme/theme.lua") -- Default Applications terminal = "alacritty" -browser = "firefox" -filemanager = "nautilus" +editor = terminal .. " -e " .. os.getenv("EDITOR") vscode = "code" -editor = os.getenv("EDITOR") or "nvim" -editor_cmd = terminal .. " -e " .. editor -discord = "discord" -launcher = "rofi -show drun" +browser = "firefox" +launcher = "rofi -show drun -theme " .. theme_dir .. "rofi.rasi" +file_manager = "nautilus" +music_client = terminal .. " --class music -e ncmpcpp" -- Weather API openweathermap_key = "" -- API Key @@ -49,4 +51,3 @@ require("ui") collectgarbage("setpause", 110) collectgarbage("setstepmul", 1000) --- EOF ------------------------------------------------------------------------ diff --git a/config/awesome/signal/playerctl.lua b/config/awesome/signal/playerctl.lua index 709b954..330058b 100644 --- a/config/awesome/signal/playerctl.lua +++ b/config/awesome/signal/playerctl.lua @@ -6,6 +6,11 @@ local playerctl = require("module.bling").signal.playerctl.lib() playerctl:connect_signal("metadata", function(_, title, artist, album_path, album, new, player_name) if new == true then - naughty.notify({title = title, text = artist, image = album_path}) + naughty.notify ({ + app_name = 'Music', + title = title, + text = artist, + image = album_path + }) end end) diff --git a/config/awesome/signal/volume.lua b/config/awesome/signal/volume.lua index dbe8e86..c8478cb 100644 --- a/config/awesome/signal/volume.lua +++ b/config/awesome/signal/volume.lua @@ -12,7 +12,9 @@ local function emit_volume_info() -- In the output of `pacmd list-sinks`, lines +7 and +11 after "* index:" -- contain the volume level and muted state respectively -- This is why we are using `awk` to print them. - awful.spawn.easy_async_with_shell("pacmd list-sinks | awk '/\\* index: /{nr[NR+7];nr[NR+11]}; NR in nr'", function(stdout) + awful.spawn.easy_async_with_shell( + "pacmd list-sinks | awk '/\\* index: /{nr[NR+7];nr[NR+11]}; NR in nr'", + function(stdout) local volume = stdout:match('(%d+)%% /') local muted = stdout:match('muted:(%s+)[yes]') local muted_int = muted and 1 or 0 @@ -42,12 +44,12 @@ local volume_script = [[ -- Kill old pactl subscribe processes -awful.spawn.easy_async({"pkill", "--full", "--uid", os.getenv("USER"), "^pactl subscribe"}, function () +awful.spawn.easy_async({ + "pkill", "--full", "--uid", os.getenv("USER"), "^pactl subscribe" +}, function () -- Run emit_volume_info() with each line printed awful.spawn.with_line_callback(volume_script, { - stdout = function(line) - emit_volume_info() - end + stdout = function(line) emit_volume_info() end }) end) diff --git a/config/awesome/theme/assets/icons/brightness.svg b/config/awesome/theme/assets/icons/brightness.svg new file mode 100644 index 0000000..862549e --- /dev/null +++ b/config/awesome/theme/assets/icons/brightness.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/config/awesome/theme/assets/icons/volume.svg b/config/awesome/theme/assets/icons/volume.svg new file mode 100644 index 0000000..7a59aa1 --- /dev/null +++ b/config/awesome/theme/assets/icons/volume.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/config/awesome/theme/picom.conf b/config/awesome/theme/picom.conf index 965e44c..78cd247 100644 --- a/config/awesome/theme/picom.conf +++ b/config/awesome/theme/picom.conf @@ -1,14 +1,15 @@ # Shadows -shadow = true; -shadow-radius = 20; -shadow-spread = 10; -shadow-offset-x = -20; -shadow-offset-y = -20; -shadow-opacity = 1.8; +shadow = true; +shadow-radius = 14; +shadow-opacity = 0.50; +shadow-offset-x = -14; +shadow-offset-y = -14; + shadow-exclude = [ - "class_g = 'Synapse'", "class_g = 'slop'", + "window_type = 'menu'", + "window_type = 'desktop'", "_GTK_FRAME_EXTENTS@:c", "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'" ]; @@ -19,34 +20,26 @@ shadow-exclude = [ fading = true; fade-in-step = 0.03; fade-out-step = 0.03; -fade-delta = 2; +fade-delta = 3; -no-fading-destroyed-argb = true; +no-fading-openclose = false +no-fading-destroyed-argb = true - -# Corners - -# corner-radius = 3 -rounded-corners-exclude = [ - "name *= 'screenkey'", - "window_type = 'dock'", - "window_type = 'desktop'" +fade-exclude = [ + "!window_type = 'dropdown_menu'" ]; - # Background-Blurring -# blur-kern = "3x3box"; +blur-kern = "11x11gaussian"; blur-method = "dual_kawase"; -blur-strength = 3; +blur-strength = 3.0; blur-background = false; -blur-background-frame = false; -blur-background-fixed = false; +blur-background-frame = true; +blur-background-fixed = true; + blur-background-exclude = [ - "! name~=''", - "name *= 'rofi'", - "class_g = 'slop'", - # "window_type = 'dock'", + "!window_type = 'splash'", "window_type = 'desktop'", "_GTK_FRAME_EXTENTS@:c", "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'" @@ -57,26 +50,31 @@ blur-background-exclude = [ backend = "glx"; vsync = true; +daemon = false; +dbus = false; +mark-wmwin-focused = true; +mark-ovredir-focused = true; detect-rounded-corners = true; detect-client-opacity = true; refresh-rate = 0; detect-transient = true; glx-no-stencil = true; use-damage = true; +resize-damage = 1; xrender-sync-fence = true; glx-use-copysubbuffer-mesa = false; +transparent-clipping = false; wintypes: { normal = { fade = true; full-shadow = true; }; - tooltip = { fade = true; }; - menu = { fade = true; }; popup_menu = { fade = true; full-shadow = true; }; - dropdown_menu = { fade = true; }; - utility = { fade = true; }; - dialog = { fade = true; }; - notify = { fade = true; }; - unknown = { fade = true; }; notification = { full-shadow = true; }; - # dock = { shadow = false; }; + dropdown_menu = { fade = true; full-shadow = true; }; + tooltip = { fade = true; shadow = false; focus = true; }; + menu = { fade = true; full-shadow = true; }; + utility = { fade = true; full-shadow = true; }; + toolbar = {full-shadow = true;}; + dialog = { fade = true; full-shadow = true; }; + dock = { fade = true; full-shadow = true;}; }; diff --git a/config/rofi/config.rasi b/config/awesome/theme/rofi.rasi similarity index 65% rename from config/rofi/config.rasi rename to config/awesome/theme/rofi.rasi index 9bd4f20..21ae17a 100644 --- a/config/rofi/config.rasi +++ b/config/awesome/theme/rofi.rasi @@ -1,8 +1,8 @@ configuration { - modi: "drun"; + modi: "drun"; display-drun: "Apps"; drun-display-format: "{name}"; - font: "Iosevka 9"; + font: "Iosevka 8"; show-icons: true; icon-theme: "Papirus"; } @@ -13,30 +13,30 @@ configuration { bg: #061115; fg: #d9d7d6; accent: #1c252c; - darker-bg: #0A1419; + darkerAccent: #162026; active: #484e5b; - rad: 10px; + rad: 12px; background-color: @bg; text-color: @fg; } window { - transparency: "real"; - text-color: @fg; - location: center; - x-offset: 0; - y-offset: 0; - width: 30%; - border-radius: 10px; + transparency: "real"; + height: 94%; + width: 22%; + location: west; + x-offset: 7%; + y-offset: 0%; + border-radius: @rad; } inputbar { children: [ textbox, entry ]; expand: false; - margin: 20px 20px 0; + margin: 20px 20px 0 20px; border-radius: @rad; - background-color: @darker-bg; + background-color: @darkerAccent; } textbox { @@ -51,20 +51,19 @@ textbox { font: "Material Icons 17"; } - entry{ expand: true; padding: 2%; placeholder: "Search"; border-radius: @rad; - background-color: @darker-bg; + background-color: @darkerAccent; } listview { - columns: 3; - lines: 3; + columns: 2; + lines: 2; cycle: false; - margin: 1em; + margin: 20px; } element { @@ -78,11 +77,11 @@ element-text, element-icon { background-color: inherit; } -element-icon { size: 36px; } +element-icon { size: 48px; } listview, element, element selected, element-text, element-icon { cursor: pointer; } element selected { - background-color: @darker-bg; + background-color: @darkerAccent; text-color: @fg; - border-radius: 5px; + border-radius: @rad; } diff --git a/config/awesome/theme/theme.lua b/config/awesome/theme/theme.lua index 1e3879a..bda6cc0 100644 --- a/config/awesome/theme/theme.lua +++ b/config/awesome/theme/theme.lua @@ -9,6 +9,8 @@ local theme_assets = require("beautiful.theme_assets") local xresources = require("beautiful.xresources") local xrdb = xresources.get_current_theme() local dpi = xresources.apply_dpi + +-- Helpers local helpers = require("helpers") @@ -16,27 +18,27 @@ local helpers = require("helpers") ---------- -- Load ~/.Xresources colors -theme.xbackground = xrdb.background -theme.xforeground = xrdb.foreground -theme.xcolor0 = xrdb.color0 -theme.xcolor1 = xrdb.color1 -theme.xcolor2 = xrdb.color2 -theme.xcolor3 = xrdb.color3 -theme.xcolor4 = xrdb.color4 -theme.xcolor5 = xrdb.color5 -theme.xcolor6 = xrdb.color6 -theme.xcolor7 = xrdb.color7 -theme.xcolor8 = xrdb.color8 -theme.xcolor9 = xrdb.color9 -theme.xcolor10 = xrdb.color10 -theme.xcolor11 = xrdb.color11 -theme.xcolor12 = xrdb.color12 -theme.xcolor13 = xrdb.color13 -theme.xcolor14 = xrdb.color14 -theme.xcolor15 = xrdb.color15 +theme.xbackground = xrdb.background +theme.xforeground = xrdb.foreground +theme.xcolor0 = xrdb.color0 +theme.xcolor1 = xrdb.color1 +theme.xcolor2 = xrdb.color2 +theme.xcolor3 = xrdb.color3 +theme.xcolor4 = xrdb.color4 +theme.xcolor5 = xrdb.color5 +theme.xcolor6 = xrdb.color6 +theme.xcolor7 = xrdb.color7 +theme.xcolor8 = xrdb.color8 +theme.xcolor9 = xrdb.color9 +theme.xcolor10 = xrdb.color10 +theme.xcolor11 = xrdb.color11 +theme.xcolor12 = xrdb.color12 +theme.xcolor13 = xrdb.color13 +theme.xcolor14 = xrdb.color14 +theme.xcolor15 = xrdb.color15 theme.darker_bg = "#0a1419" theme.lighter_bg = "#162026" -theme.dash_fg = "#666c79" +theme.dashboard_fg = "#666c79" theme.transparent = "#00000000" -- PFP @@ -50,6 +52,8 @@ theme.awesome_logo = gears.surface.load_uncached(gfs.get_configuration_dir() .. -- Notifications icon theme.notification_icon = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/notification.png") +theme.volume_icon = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/volume.svg") +theme.brightness_icon = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/brightness.svg") -- Fonts theme.font_name = "Iosevka " @@ -61,95 +65,84 @@ theme.font_taglist = theme.icon_font_name .. "13" -- Background Colors theme.bg_dark = theme.darker_bg theme.bg_normal = theme.xbackground -theme.bg_focus = theme.xcolor0 -theme.bg_urgent = theme.xcolor8 -theme.bg_minimize = theme.xcolor8 +theme.bg_focus = theme.xbackground +theme.bg_urgent = theme.xbackground +theme.bg_minimize = theme.xbackground +theme.bg_secondary = theme.darker_bg +theme.bg_accent = theme.lighter_bg -- Foreground Colors theme.fg_normal = theme.xforeground -theme.fg_focus = theme.xcolor4 -theme.fg_urgent = theme.xcolor3 -theme.fg_minimize = theme.xcolor8 -theme.button_close = theme.xcolor1 +theme.fg_focus = theme.xforeground +theme.fg_urgent = theme.xcolor1 +theme.fg_minimize = theme.xcolor0 -- Borders theme.border_width = dpi(0) -theme.oof_border_width = theme.border_width +theme.oof_border_width = dpi(0) theme.border_normal = theme.darker_bg theme.border_focus = theme.darker_bg -theme.border_radius = dpi(10) -theme.client_radius = dpi(12) theme.widget_border_width = dpi(2) -theme.widget_border_color = theme.lighter_bg +theme.widget_border_color = theme.darker_bg + +-- Radius +theme.border_radius = dpi(12) +theme.client_radius = dpi(10) +theme.dashboard_radius = dpi(10) +theme.bar_radius = dpi(10) -- Taglist --- Generate taglist squares: local taglist_square_size = dpi(0) theme.taglist_squares_sel = theme_assets.taglist_squares_sel(taglist_square_size, theme.fg_normal) theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(taglist_square_size, theme.fg_normal) theme.taglist_font = theme.font_taglist theme.taglist_bg = theme.wibar_bg + theme.taglist_bg_focus = theme.lighter_bg theme.taglist_fg_focus = theme.xcolor3 + theme.taglist_bg_urgent = theme.wibar_bg theme.taglist_fg_urgent = theme.xcolor6 + theme.taglist_bg_occupied = theme.wibar_bg theme.taglist_fg_occupied = theme.xcolor6 + theme.taglist_bg_empty = theme.wibar_bg theme.taglist_fg_empty = theme.xcolor8 + theme.taglist_bg_volatile = transparent theme.taglist_fg_volatile = theme.xcolor11 + theme.taglist_disable_icon = true -theme.taglist_shape_focus = helpers.rrect(theme.border_radius / 2) -theme.taglist_shape_empty = helpers.rrect(theme.border_radius / 2) -theme.taglist_shape = helpers.rrect(theme.border_radius / 2) -theme.taglist_shape_urgent = helpers.rrect(theme.border_radius / 2) -theme.taglist_shape_volatile = helpers.rrect(theme.border_radius / 2) - --- Tasklist -theme.tasklist_font = theme.font -theme.tasklist_plain_task_name = true -theme.tasklist_bg_focus = theme.lighter_bg -theme.tasklist_fg_focus = theme.xcolor6 -theme.tasklist_bg_minimize = theme.xcolor0 .. 55 -theme.tasklist_fg_minimize = theme.xforeground .. 55 -theme.tasklist_bg_normal = theme.darker_bg -theme.tasklist_fg_normal = theme.xforeground -theme.tasklist_disable_task_name = false -theme.tasklist_disable_icon = true -theme.tasklist_bg_urgent = theme.xcolor0 -theme.tasklist_fg_urgent = theme.xcolor1 -theme.tasklist_align = "center" +theme.taglist_shape_focus = helpers.rrect(theme.bar_radius) +theme.taglist_shape_empty = helpers.rrect(theme.bar_radius) +theme.taglist_shape = helpers.rrect(theme.bar_radius) +theme.taglist_shape_urgent = helpers.rrect(theme.bar_radius) +theme.taglist_shape_volatile = helpers.rrect(theme.bar_radius) -- Titlebars -theme.titlebars_enabled = true +theme.titlebar_enabled = true theme.titlebar_size = dpi(45) theme.titlebar_unfocused = theme.xcolor0 -- Pop up notifications -theme.pop_size = dpi(180) +theme.pop_size = dpi(200) theme.pop_bg = theme.xbackground theme.pop_bar_bg = theme.xcolor0 theme.pop_vol_color = theme.xcolor4 -theme.pop_brightness_color = theme.xcolor3 +theme.pop_brightness_color = theme.xcolor5 theme.pop_fg = theme.xforeground -theme.pop_border_radius = dpi(6) +theme.pop_border_radius = theme.border_radius -- Tooltip -theme.tooltip_height = dpi(490) -theme.tooltip_width = dpi(310) -theme.tooltip_bg = theme.xbackground -theme.tooltip_box_bg = theme.bg_secondary -theme.tooltip_fg = theme.xforeground -theme.tooltip_box_fg = theme.xcolor8 -theme.tooltip_margin = dpi(15) -theme.tooltip_box_margin = dpi(10) +theme.tooltip_bg = theme.xbackground +theme.tooltip_height = dpi(245) +theme.tooltip_width = dpi(200) theme.tooltip_gap = dpi(10) -theme.tooltip_border_radius = dpi(6) -theme.tooltip_box_border_radius = dpi(3) -theme.tooltip_border_width = dpi(0) -theme.tooltip_border_color = theme.xcolor0 +theme.tooltip_box_margin = dpi(10) +theme.tooltip_border_radius = theme.border_radius +theme.tooltip_box_border_radius = theme.bar_radius -- Edge snap theme.snap_bg = theme.xcolor8 @@ -159,18 +152,16 @@ theme.snap_shape = helpers.rrect(0) theme.prompt_bg = transparent theme.prompt_fg = theme.xforeground --- Dashboard -theme.dash_width = dpi(300) -theme.dash_box_bg = theme.lighter_bg -theme.dash_box_fg = theme.dash_fg +-- dashboard +theme.dashboard_width = dpi(300) +theme.dashboard_box_bg = theme.lighter_bg +theme.dashboard_box_fg = theme.dashboard_fg --- Tooltips -theme.tooltip_bg = theme.xbackground -theme.tooltip_fg = theme.xforeground -theme.tooltip_font = theme.font_name .. "10" -theme.tooltip_border_width = 0 -theme.tooltip_opacity = 1 -theme.tooltip_align = "top" +-- Playerctl +theme.playerctl_ignore = {"firefox", "qutebrowser", "chromium", "brave"} +theme.playerctl_player = {"spotify", "mpd", "%any"} +theme.playerctl_update_on_activity = true +theme.playerctl_position_update_interval = 1 -- Menu theme.menu_height = dpi(30) @@ -186,15 +177,18 @@ theme.menu_submenu = "» " theme.menu_submenu_icon = nil -- Hotkeys Pop Up -theme.hotkeys_font = theme.font -theme.hotkeys_border_color = theme.lighter_bg -theme.hotkeys_group_margin = dpi(40) -theme.hotkeys_shape = helpers.rrect(5) +theme.hotkeys_bg = theme.xbackground +theme.hotkeys_fg = theme.xforeground +theme.hotkeys_modifiers_fg = theme.xforeground +theme.hotkeys_font = theme.font_name .. "10" +theme.hotkeys_description_font = theme.font_name .. "9" +theme.hotkeys_shape = helpers.rrect(theme.border_radius) +theme.hotkeys_group_margin = dpi(30) -- Layout List theme.layoutlist_border_color = theme.lighter_bg theme.layoutlist_border_width = theme.border_width -theme.layoutlist_shape_selected = helpers.rrect(3) +theme.layoutlist_shape_selected = helpers.rrect(dpi(10)) theme.layoutlist_bg_selected = theme.lighter_bg -- Recolor Layout icons: @@ -204,24 +198,20 @@ theme = theme_assets.recolor_layout(theme, theme.xforeground) theme.useless_gap = dpi(5) -- Wibar -theme.wibar_height = (dpi(42) + theme.widget_border_width) * 0 -theme.wibar_width = dpi(42) + theme.widget_border_width -theme.wibar_margin = dpi(15) -theme.wibar_spacing = dpi(15) +theme.wibar_width = dpi(45) theme.wibar_bg = theme.xbackground -theme.wibar_bg_secondary = theme.lighter_bg theme.wibar_position = "left" -- Tabs theme.mstab_bar_height = dpi(60) theme.mstab_bar_padding = dpi(0) -theme.mstab_border_radius = dpi(6) +theme.mstab_border_radius = theme.border_radius theme.tabbar_disable = true theme.tabbar_style = "modern" -theme.tabbar_bg_focus = theme.xbackground -theme.tabbar_bg_normal = theme.xcolor0 -theme.tabbar_fg_focus = theme.xcolor0 -theme.tabbar_fg_normal = theme.xcolor15 +theme.tabbar_bg_focus = theme.lighter_bg +theme.tabbar_bg_normal = theme.darker_bg +theme.tabbar_fg_focus = theme.xforeground +theme.tabbar_fg_normal = theme.xcolor0 theme.tabbar_position = "bottom" theme.tabbar_AA_radius = 0 theme.tabbar_size = 40 @@ -238,26 +228,27 @@ theme.dont_swallow_classname_list = { } -- Layout Machi -theme.machi_switcher_border_color = theme.lighter_bg +theme.machi_switcher_border_color = theme.darker_bg theme.machi_switcher_border_opacity = 0.25 -theme.machi_editor_border_color = theme.lighter_bg +theme.machi_editor_border_color = theme.darker_bg theme.machi_editor_border_opacity = 0.25 theme.machi_editor_active_opacity = 0.25 -- Tag Preview -theme.tag_preview_widget_border_radius = theme.border_radius / 2 -theme.tag_preview_client_border_radius = theme.border_radius / 2 +theme.tag_preview_client_border_radius = dpi(6) theme.tag_preview_client_opacity = 0.1 theme.tag_preview_client_bg = theme.xbackground -theme.tag_preview_client_border_color = theme.lighter_bg +theme.tag_preview_client_border_color = theme.darker_bg theme.tag_preview_client_border_width = theme.widget_border_width + +theme.tag_preview_widget_border_radius = theme.border_radius theme.tag_preview_widget_bg = theme.xbackground theme.tag_preview_widget_border_color = theme.widget_border_color theme.tag_preview_widget_border_width = theme.widget_border_width * 0 theme.tag_preview_widget_margin = dpi(10) -- Task Preview -theme.task_preview_widget_border_radius = theme.border_radius / 2 +theme.task_preview_widget_border_radius = dpi(10) theme.task_preview_widget_bg = theme.xbackground theme.task_preview_widget_border_color = theme.widget_border_color theme.task_preview_widget_border_width = theme.widget_border_width * 0 diff --git a/config/awesome/ui/widgets/analog_clock.lua b/config/awesome/ui/widgets/analog_clock.lua index d15c74a..886c256 100644 --- a/config/awesome/ui/widgets/analog_clock.lua +++ b/config/awesome/ui/widgets/analog_clock.lua @@ -11,6 +11,7 @@ local cairo = require("lgi").cairo -- Analog clock ------------------ +-- Stolen from No37 local function create_minute_pointer(minute) local img = cairo.ImageSurface(cairo.Format.ARGB32, 1000, 1000) diff --git a/config/mpd/mpd.conf b/config/mpd/mpd.conf new file mode 100644 index 0000000..70aa652 --- /dev/null +++ b/config/mpd/mpd.conf @@ -0,0 +1,41 @@ +music_directory "~/Music" +playlist_directory "~/.config/mpd/playlists" +db_file "~/.config/mpd/database" +log_file "~/.config/mpd/log" +bind_to_address "127.0.0.1" + +audio_output { + type "alsa" + name "ALSA [Bit-perfect]" + device "hw:1,0" + auto_channels "no" + auto_format "no" + auto_resample "no" + dop "yes" + mixer_type "none" + replay_gain_handler "none" + buffer_time "100000" +} + +audio_output { + type "pulse" + name "PulseAudio" + buffer_time "100000" +} + +audio_output { + type "fifo" + name "Visualizer" + format "44100:16:2" + path "/tmp/mpd.fifo" +} + +audio_output { + type "httpd" + name "lossless" + encoder "flac" + port "8000" + max_client "8" + mixer_type "software" + format "44100:16:2" +} diff --git a/config/ncmpcpp/bindings b/config/ncmpcpp/bindings new file mode 100644 index 0000000..a911222 --- /dev/null +++ b/config/ncmpcpp/bindings @@ -0,0 +1,392 @@ +#def_key "mouse" +# mouse_event +# +def_key "k" + scroll_up +# +#def_key "shift-up" +# select_item +# scroll_up +# +def_key "j" + scroll_down +# +#def_key "shift-down" +# select_item +# scroll_down +# +#def_key "[" +# scroll_up_album +# +#def_key "]" +# scroll_down_album +# +#def_key "{" +# scroll_up_artist +# +#def_key "}" +# scroll_down_artist +# +#def_key "page_up" +# page_up +# +#def_key "page_down" +# page_down +# +#def_key "home" +# move_home +# +#def_key "end" +# move_end +# +#def_key "insert" +# select_item +# +#def_key "enter" +# enter_directory +# +#def_key "enter" +# toggle_output +# +#def_key "enter" +# run_action +# +#def_key "enter" +# play_item +# +#def_key "space" +# add_item_to_playlist +# +#def_key "space" +# toggle_lyrics_update_on_song_change +# +#def_key "space" +# toggle_visualization_type +# +#def_key "delete" +# delete_playlist_items +# +#def_key "delete" +# delete_browser_items +# +#def_key "delete" +# delete_stored_playlist +# +def_key "l" + next_column +# +#def_key "right" +# slave_screen +# +#def_key "right" +# volume_up +# +#def_key "+" +# volume_up +# +def_key "h" + previous_column +# +#def_key "left" +# master_screen +# +#def_key "left" +# volume_down +# +#def_key "=" +# volume_down +# +#def_key ":" +# execute_command +# +#def_key "tab" +# next_screen +# +#def_key "shift-tab" +# previous_screen +# +#def_key "f1" +# show_help +# +#def_key "1" +# show_playlist +# +#def_key "2" +# show_browser +# +#def_key "2" +# change_browse_mode +# +#def_key "3" +# show_search_engine +# +#def_key "3" +# reset_search_engine +# +#def_key "4" +# show_media_library +# +#def_key "4" +# toggle_media_library_columns_mode +# +#def_key "5" +# show_playlist_editor +# +#def_key "6" +# show_tag_editor +# +#def_key "7" +# show_outputs +# +#def_key "8" +# show_visualizer +# +#def_key "-" +# show_clock +# +#def_key "@" +# show_server_info +# +#def_key "s" +# stop +# +#def_key "p" +# pause +# +#def_key ">" +# next +# +#def_key "<" +# previous +# +#def_key "ctrl-h" +# jump_to_parent_directory +# +#def_key "ctrl-h" +# replay_song +# +#def_key "backspace" +# jump_to_parent_directory +# +#def_key "backspace" +# replay_song +# +#def_key "f" +# seek_forward +# +#def_key "b" +# seek_backward +# +#def_key "r" +# toggle_repeat +# +#def_key "z" +# toggle_random +# +#def_key "y" +# save_tag_changes +# +#def_key "y" +# start_searching +# +#def_key "y" +# toggle_single +# +#def_key "R" +# toggle_consume +# +#def_key "Y" +# toggle_replay_gain_mode +# +#def_key "T" +# toggle_add_mode +# +#def_key "|" +# toggle_mouse +# +#def_key "#" +# toggle_bitrate_visibility +# +#def_key "Z" +# shuffle +# +#def_key "x" +# toggle_crossfade +# +#def_key "X" +# set_crossfade +# +#def_key "u" +# update_database +# +#def_key "ctrl-s" +# sort_playlist +# +#def_key "ctrl-s" +# toggle_browser_sort_mode +# +#def_key "ctrl-s" +# toggle_media_library_sort_mode +# +#def_key "ctrl-r" +# reverse_playlist +# +#def_key "ctrl-f" +# apply_filter +# +#def_key "ctrl-_" +# select_found_items +# +#def_key "/" +# find +# +#def_key "/" +# find_item_forward +# +#def_key "?" +# find +# +#def_key "?" +# find_item_backward +# +#def_key "." +# next_found_item +# +#def_key "," +# previous_found_item +# +#def_key "w" +# toggle_find_mode +# +#def_key "e" +# edit_song +# +#def_key "e" +# edit_library_tag +# +#def_key "e" +# edit_library_album +# +#def_key "e" +# edit_directory_name +# +#def_key "e" +# edit_playlist_name +# +#def_key "e" +# edit_lyrics +# +#def_key "i" +# show_song_info +# +#def_key "I" +# show_artist_info +# +#def_key "g" +# jump_to_position_in_song +# +def_key "L" + show_lyrics +# +#def_key "ctrl-v" +# select_range +# +#def_key "v" +# reverse_selection +# +#def_key "V" +# remove_selection +# +#def_key "B" +# select_album +# +#def_key "a" +# add_selected_items +# +#def_key "c" +# clear_playlist +# +#def_key "c" +# clear_main_playlist +# +#def_key "C" +# crop_playlist +# +#def_key "C" +# crop_main_playlist +# +#def_key "m" +# move_sort_order_up +# +#def_key "m" +# move_selected_items_up +# +#def_key "n" +# move_sort_order_down +# +#def_key "n" +# move_selected_items_down +# +#def_key "M" +# move_selected_items_to +# +#def_key "A" +# add +# +#def_key "S" +# save_playlist +# +#def_key "o" +# jump_to_playing_song +# +#def_key "G" +# jump_to_browser +# +#def_key "G" +# jump_to_playlist_editor +# +#def_key "~" +# jump_to_media_library +# +#def_key "E" +# jump_to_tag_editor +# +#def_key "U" +# toggle_playing_song_centering +# +#def_key "P" +# toggle_display_mode +# +#def_key "\\" +# toggle_interface +# +#def_key "!" +# toggle_separators_between_albums +# +#def_key "L" +# toggle_lyrics_fetcher +# +#def_key "F" +# fetch_lyrics_in_background +# +#def_key "alt-l" +# toggle_fetching_lyrics_in_background +# +#def_key "ctrl-l" +# toggle_screen_lock +# +#def_key "`" +# toggle_library_tag_type +# +#def_key "`" +# refetch_lyrics +# +#def_key "`" +# add_random_items +# +#def_key "ctrl-p" +# set_selected_items_priority +# +#def_key "q" +# quit +# diff --git a/config/ncmpcpp/config b/config/ncmpcpp/config new file mode 100644 index 0000000..5c977e1 --- /dev/null +++ b/config/ncmpcpp/config @@ -0,0 +1,70 @@ +# DIRECTORY +# --- +ncmpcpp_directory = ~/.config/ncmpcpp +lyrics_directory = ~/.config/ncmpcpp/lyrics +mpd_music_dir = ~/Music + +# GENERAL +# --- +external_editor = nvim +message_delay_time = 1 +playlist_disable_highlight_delay = 2 +autocenter_mode = "yes" +centered_cursor = "yes" +ignore_leading_the = "yes" +allow_for_physical_item_deletion = "no" +connected_message_on_startup = "yes" +cyclic_scrolling = "yes" +mouse_support = "yes" +mouse_list_scroll_whole_page = "yes" +lines_scrolled = "1" +playlist_shorten_total_times = "yes" +playlist_display_mode = "columns" +browser_display_mode = "columns" +search_engine_display_mode = "columns" +playlist_editor_display_mode = "columns" +user_interface = "classic" +follow_now_playing_lyrics = "yes" +display_bitrate = "no" +startup_screen = "playlist" + +# VISUALIZER +# --- +visualizer_data_source = "/tmp/mpd.fifo" +visualizer_output_name = "Visualizer" +visualizer_in_stereo = "no" +visualizer_sync_interval = "30" +visualizer_type = "ellipse" +visualizer_fps = "60" +visualizer_look = ●▮ +visualizer_color = "33,39,63,75,81,99,117,153,189" + +# PROGRESS BAR +# --- +progressbar_look = " " +progressbar_color = "black" +progressbar_elapsed_color = "yellow" + +# COLORS +# --- +main_window_color = "blue" +color1 = "white" +color2 = "blue" + +# UI VISIBILITY +# --- +header_visibility = "no" +statusbar_visibility = "no" +titles_visibility = "no" + +# UI APPEARANCE +# --- +now_playing_prefix = "$b$8$7 " +now_playing_suffix = " $/b$8" +current_item_prefix = "$b$7$/b$3 " +current_item_suffix = " $8" +song_status_format= "$7%t" +song_list_format = "$8%a - %t$R %l" +song_columns_list_format = "(53)[white]{tr} (45)[blue]{a}" +song_library_format = {{%a - %t} (%b)}|{%f} +song_window_title_format = "Music"