diff --git a/bin/bsplock b/bin/bsplock index b0f6003..e830b47 100755 --- a/bin/bsplock +++ b/bin/bsplock @@ -34,7 +34,7 @@ i3lock \ \ --ringver-color=${GREEN} \ --ringwrong-color=${RED} \ ---ring-color="#fab387" \ +--ring-color="#f5e0dc" \ \ --line-color=${BG} \ --separator-color=${BG} \ diff --git a/bin/get_mpris_status.sh b/bin/get_mpris_status.sh new file mode 100755 index 0000000..450e806 --- /dev/null +++ b/bin/get_mpris_status.sh @@ -0,0 +1,99 @@ +#!/bin/bash + +# The name of polybar bar which houses the main spotify module and the control modules. +PARENT_BAR="${1:-music}" +PARENT_BAR_PID=$(pgrep -a "polybar" | grep "$PARENT_BAR" | cut -d" " -f1) + +urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; } + +send_hook() { + [ -z "$1" ] && echo "send_hook: missing arg" && exit 1 + polybar-msg hook mpris-play-pause "$1" 1>/dev/null 2>&1 +} + + +extract_meta() { + grep "$1\W" <<< "$meta" | awk '{$1=$2=""; print $0}' | sed 's/^ *//; s/; */;/g' | paste -s -d/ - +} + +# if "icon" given, determine icon. otherwise, print metadata +get_info() { + if [ -z "$1" ]; then + echo "Usage: get_info PLAYER [icon]" + exit 1 + fi + + meta=$(playerctl -p "$1" metadata) + + # get title + title=$(extract_meta title) + # if no title, try url e.g. vlc + if [ -z "$title" ]; then + title=$(extract_meta url) + title=$(urldecode "${title##*/}") + fi + + # if not "icon", display information and return + if [ "$2" != "icon" ]; then + artist=$(extract_meta artist) + [ -z "$artist" ] && artist=$(extract_meta albumArtist) + + if [ -n "$artist" ]; then + album=$(extract_meta album) + [ -n "$album" ] && echo -n "  $album " + + echo -n " ﴁ $artist  " + fi + + echo "$title" + return 0 + fi + + # determine icon: + # if player name is recognised, use it + case "$1" in + spotify* | vlc | mpv) echo "$1";; + kdeconnect*) echo "kdeconnect";; + chromium*) + # if a browser, search window titles: + + # this tries to avoid title messing up the regex + regex_title=$(echo "$title" | tr "[:punct:]" ".") + windowname=$(xdotool search --name --class --classname "$regex_title" getwindowname 2>/dev/null) + case $windowname in + "") ;; # ignore if empty + *Netflix*) echo "netflix";; + *YouTube*) echo "youtube";; + *"Prime Video"*) echo "prime";; + *"Corridor Digital"*) echo "corridor";; + *) echo "browser";; + esac;; + *) echo "none";; + esac +} + +# manually go through players +read -d'\n' -ra PLAYERS <<<"$(playerctl -l 2>/dev/null)" +declare -a PAUSED +for player in "${PLAYERS[@]}"; do + [ "$player" = "playerctld" ] && continue; + + p_status=$(playerctl -p "$player" status 2>/dev/null) + + # if we have one playing, we'll use it and EXIT + if [ "$p_status" = "Playing" ]; then + send_hook 1 + get_info "$player" "$2" + exit 0; + fi + + [ "$p_status" = "Paused" ] && PAUSED+=("$player") +done + +# if we have a paused, show it otherwise assume there are no players or have all stopped +if [ -n "${PAUSED[0]}" ]; then + send_hook 2 + get_info "${PAUSED[0]}" "$2" +else + [ "$2" = icon ] && echo "none" || echo " 鈴 no players " +fi diff --git a/bin/get_mpris_status_hide_album.sh b/bin/get_mpris_status_hide_album.sh new file mode 100755 index 0000000..ee397c7 --- /dev/null +++ b/bin/get_mpris_status_hide_album.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +# The name of polybar bar which houses the main spotify module and the control modules. +PARENT_BAR="${1:-music}" +PARENT_BAR_PID=$(pgrep -a "polybar" | grep "$PARENT_BAR" | cut -d" " -f1) + +urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; } + +send_hook() { + [ -z "$1" ] && echo "send_hook: missing arg" && exit 1 + polybar-msg hook mpris-play-pause "$1" 1>/dev/null 2>&1 +} + + +extract_meta() { + grep "$1\W" <<< "$meta" | awk '{$1=$2=""; print $0}' | sed 's/^ *//; s/; */;/g' | paste -s -d/ - +} + +# if "icon" given, determine icon. otherwise, print metadata +get_info() { + if [ -z "$1" ]; then + echo "Usage: get_info PLAYER [icon]" + exit 1 + fi + + meta=$(playerctl -p "$1" metadata) + + # get title + title=$(extract_meta title) + # if no title, try url e.g. vlc + if [ -z "$title" ]; then + title=$(extract_meta url) + title=$(urldecode "${title##*/}") + fi + + # if not "icon", display information and return + if [ "$2" != "icon" ]; then + artist=$(extract_meta artist) + [ -z "$artist" ] && artist=$(extract_meta albumArtist) + + if [ -n "$artist" ]; then + album=$(extract_meta album) + + echo -n "$artist  " + fi + + echo "$title" + return 0 + fi + + # determine icon: + # if player name is recognised, use it + case "$1" in + spotify* | vlc | mpv) echo "$1";; + kdeconnect*) echo "kdeconnect";; + chromium*) + # if a browser, search window titles: + + # this tries to avoid title messing up the regex + regex_title=$(echo "$title" | tr "[:punct:]" ".") + windowname=$(xdotool search --name --class --classname "$regex_title" getwindowname 2>/dev/null) + case $windowname in + "") ;; # ignore if empty + *Netflix*) echo "netflix";; + *YouTube*) echo "youtube";; + *"Prime Video"*) echo "prime";; + *"Corridor Digital"*) echo "corridor";; + *) echo "browser";; + esac;; + *) echo "none";; + esac +} + +# manually go through players +read -d'\n' -ra PLAYERS <<<"$(playerctl -l 2>/dev/null)" +declare -a PAUSED +for player in "${PLAYERS[@]}"; do + [ "$player" = "playerctld" ] && continue; + + p_status=$(playerctl -p "$player" status 2>/dev/null) + + # if we have one playing, we'll use it and EXIT + if [ "$p_status" = "Playing" ]; then + send_hook 1 + get_info "$player" "$2" + exit 0; + fi + + [ "$p_status" = "Paused" ] && PAUSED+=("$player") +done + +# if we have a paused, show it otherwise assume there are no players or have all stopped +if [ -n "${PAUSED[0]}" ]; then + send_hook 2 + get_info "${PAUSED[0]}" "$2" +else + [ "$2" = icon ] && echo "none" || echo " 鈴 no players " +fi diff --git a/bin/get_spotify_status.sh b/bin/get_spotify_status.sh new file mode 100755 index 0000000..97ac861 --- /dev/null +++ b/bin/get_spotify_status.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# The name of polybar bar which houses the main spotify module and the control modules. +PARENT_BAR="now-playing" +PARENT_BAR_PID=$(pgrep -a "polybar" | grep "$PARENT_BAR" | cut -d" " -f1) + +# Set the source audio player here. +# Players supporting the MPRIS spec are supported. +# Examples: spotify, vlc, chrome, mpv and others. +# Use `playerctld` to always detect the latest player. +# See more here: https://github.com/altdesktop/playerctl/#selecting-players-to-control +PLAYER="playerctld" + +# Format of the information displayed +# Eg. {{ artist }} - {{ album }} - {{ title }} +# See more attributes here: https://github.com/altdesktop/playerctl/#printing-properties-and-metadata +FORMAT="{{ title }} - {{ artist }}" + +# Sends $2 as message to all polybar PIDs that are part of $1 +update_hooks() { + while IFS= read -r id + do + polybar-msg -p "$id" hook spotify-play-pause $2 1>/dev/null 2>&1 + done < <(echo "$1") +} + +PLAYERCTL_STATUS=$(playerctl --player=$PLAYER status 2>/dev/null) +EXIT_CODE=$? + +if [ $EXIT_CODE -eq 0 ]; then + STATUS=$PLAYERCTL_STATUS +else + STATUS="No player is running" +fi + +if [ "$1" == "--status" ]; then + echo "$STATUS" +else + if [ "$STATUS" = "Stopped" ]; then + echo "No music is playing" + elif [ "$STATUS" = "Paused" ]; then + update_hooks "$PARENT_BAR_PID" 2 + playerctl --player=$PLAYER metadata --format "$FORMAT" + elif [ "$STATUS" = "No player is running" ]; then + echo "$STATUS" + else + update_hooks "$PARENT_BAR_PID" 1 + playerctl --player=$PLAYER metadata --format "$FORMAT" + fi +fi + diff --git a/bin/scroll_mpris_status.sh b/bin/scroll_mpris_status.sh new file mode 100755 index 0000000..ec4b26a --- /dev/null +++ b/bin/scroll_mpris_status.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +cmd="${0%/*}/get_mpris_status.sh $1" + +zscroll -l 50 \ + --scroll-padding "$(printf ' %.0s' {1..8})" \ + -d 0.5 \ + -M "$cmd icon" \ + -m "none" "-b ''" \ + -m "browser" "-b ' '" \ + -m "netflix" "-b 'ﱄ '" \ + -m "youtube" "-b ' '" \ + -m "prime" "-b ' '" \ + -m "spotify" "-b ' '" \ + -m "spotifyd" "-b ' '" \ + -m "vlc" "-b '嗢 '" \ + -m "mpv" "-b ' '" \ + -m "kdeconnect" "-b ' '" \ + -m "corridor" "-b ' '" \ + -U 1 -u t "$cmd" & + +wait diff --git a/bin/scroll_spotify_status.sh b/bin/scroll_spotify_status.sh new file mode 100755 index 0000000..f70ef09 --- /dev/null +++ b/bin/scroll_spotify_status.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# see man zscroll for documentation of the following parameters +zscroll -l 30 \ + --delay 0.4 \ + --match-command "`dirname $0`/get_spotify_status.sh --status" \ + --match-text "Playing" "--scroll 1" \ + --match-text "Paused" "--scroll 0" \ + --update-check true "`dirname $0`/get_spotify_status.sh" & + +wait + diff --git a/crylia_bar/center_bar.lua b/crylia_bar/center_bar.lua index 441fb2b..4d65b43 100644 --- a/crylia_bar/center_bar.lua +++ b/crylia_bar/center_bar.lua @@ -17,19 +17,19 @@ return function(s, widgets) bg = color["Grey900"], visible = true, maximum_width = dpi(500), - placement = function(c) awful.placement.top(c, { margins = dpi(10) }) end, + placement = function(c) awful.placement.top(c, { margins = dpi(5) }) end, shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 5) end } top_center:struts { - top = 55 + top = 45 } local function prepare_widgets(widgets) local layout = { - forced_height = 45, + forced_height = 40, layout = wibox.layout.fixed.horizontal } for i, widget in pairs(widgets) do diff --git a/crylia_bar/init.lua b/crylia_bar/init.lua index a6dda7c..7cf8768 100644 --- a/crylia_bar/init.lua +++ b/crylia_bar/init.lua @@ -36,30 +36,31 @@ awful.screen.connect_for_each_screen( s.kblayout = require("src.widgets.kblayout")(s) s.taglist = require("src.widgets.taglist")(s) s.tasklist = require("src.widgets.tasklist")(s) + s.mpris = require("src.widgets.mpris")() --s.cpu_freq = require("src.widgets.cpu_info")("freq", "average") -- Add more of these if statements if you want to change -- the modules/widgets per screen. if s.index == 1 then s.systray = require("src.widgets.systray")(s) - s.cpu_usage = require("src.widgets.cpu_info")("usage") - s.cpu_temp = require("src.widgets.cpu_info")("temp") - s.gpu_usage = require("src.widgets.gpu_info")("usage") - s.gpu_temp = require("src.widgets.gpu_info")("temp") require("crylia_bar.left_bar")(s, { s.layoutlist, s.systray, s.taglist }) require("crylia_bar.center_bar")(s, { s.tasklist }) - require("crylia_bar.right_bar")(s, { s.gpu_usage, s.gpu_temp, s.cpu_usage, s.cpu_temp, s.audio, s.date, s.clock, s.powerbutton }) - -- require("crylia_bar.dock")(s, user_vars.dock_programs) + require("crylia_bar.right_bar")(s, { s.mpris, s.audio, s.date, s.clock, s.powerbutton }) + --require("crylia_bar.dock")(s, user_vars.dock_programs) end if s.index == 2 then s.network = require("src.widgets.network")() s.ram_info = require("src.widgets.ram_info")() + s.cpu_temp = require("src.widgets.cpu_info")("temp") + s.gpu_temp = require("src.widgets.gpu_info")("temp") + -- s.cpu_usage = require("src.widgets.cpu_info")("usage") + -- s.gpu_usage = require("src.widgets.gpu_info")("usage") require("crylia_bar.left_bar")(s, { s.layoutlist, s.taglist }) require("crylia_bar.center_bar")(s, { s.tasklist }) - require("crylia_bar.right_bar")(s, { s.ram_info, s.audio, s.kblayout, s.bluetooth, s.network, s.date, s.clock, s.powerbutton }) + require("crylia_bar.right_bar")(s, { s.gpu_temp, s.cpu_temp, s.ram_info, s.kblayout, s.bluetooth, s.network, s.clock, s.powerbutton }) end end ) diff --git a/crylia_bar/left_bar.lua b/crylia_bar/left_bar.lua index 93f2031..98246fe 100644 --- a/crylia_bar/left_bar.lua +++ b/crylia_bar/left_bar.lua @@ -17,19 +17,19 @@ return function(s, widgets) bg = color["Grey900"], visible = true, maximum_width = dpi(650), - placement = function(c) awful.placement.top_left(c, { margins = dpi(10) }) end, + placement = function(c) awful.placement.top_left(c, { margins = dpi(5) }) end, shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 5) end } top_left:struts { - top = 55 + top = 45 } local function prepare_widgets(widgets) local layout = { - forced_height = 45, + forced_height = 40, layout = wibox.layout.fixed.horizontal } for i, widget in pairs(widgets) do diff --git a/crylia_bar/right_bar.lua b/crylia_bar/right_bar.lua index 3e4ec2e..2c76b38 100644 --- a/crylia_bar/right_bar.lua +++ b/crylia_bar/right_bar.lua @@ -16,19 +16,19 @@ return function(s, widgets) bg = color["Grey900"], visible = true, screen = s, - placement = function(c) awful.placement.top_right(c, { margins = dpi(10) }) end, + placement = function(c) awful.placement.top_right(c, { margins = dpi(5) }) end, shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 5) end } top_right:struts { - top = 55 + top = 45 } local function prepare_widgets(widgets) local layout = { - forced_height = 45, + forced_height = 40, layout = wibox.layout.fixed.horizontal } for i, widget in pairs(widgets) do diff --git a/mappings/global_keys.lua b/mappings/global_keys.lua index 0ae49ff..9898de0 100644 --- a/mappings/global_keys.lua +++ b/mappings/global_keys.lua @@ -5,6 +5,7 @@ local hotkeys_popup = require("awful.hotkeys_popup") local ruled = require("ruled") local modkey = user_vars.modkey +local switcher = require("src.modules.awesome_switcher") return gears.table.join( awful.key( @@ -48,14 +49,18 @@ return gears.table.join( end, { description = "Focus previous client by index", group = "Client" } ), - awful.key( - { "Mod1" }, - "#23", - function() - awful.client.focus.byidx(1) - end, - { description = "Focus next client by index", group = "Client" } - ), +--awful.key( +-- { "Mod1" }, +-- "#23", +-- function() +-- awful.client.focus.byidx(1) +-- end, +-- { description = "Focus next client by index", group = "Client" } +--), + awful.key({ "Mod1" }, "#23", + function () + switcher.switch( 1, "Mod1", "Alt_L", "Shift", "Tab") + end), awful.key( { "Mod1", "Shift" }, "#23", diff --git a/src/assets/icons/mpris/cd.svg b/src/assets/icons/mpris/cd.svg new file mode 100644 index 0000000..fc13427 --- /dev/null +++ b/src/assets/icons/mpris/cd.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/src/assets/icons/mpris/cd24x24.svg b/src/assets/icons/mpris/cd24x24.svg new file mode 100644 index 0000000..95a3428 --- /dev/null +++ b/src/assets/icons/mpris/cd24x24.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/core/notifications.lua b/src/core/notifications.lua index be337e8..bc70491 100644 --- a/src/core/notifications.lua +++ b/src/core/notifications.lua @@ -44,17 +44,17 @@ naughty.connect_signal( "request::display", function(n) if n.urgency == "critical" then - n.title = string.format("%s", + n.title = string.format("%s", cat["Red"], n.title) or "" - n.message = string.format("%s", cat["Red"], n.message) or "" - n.app_name = string.format("%s", cat["Red"], n.app_name) or "" + n.message = string.format("%s", cat["Red"], n.message) or "" + n.app_name = string.format("%s", cat["Red"], n.app_name) or "" n.bg = cat["Surface0"] else - n.title = string.format("%s", + n.title = string.format("%s", color["White"], n.title) or "" - n.message = string.format("%s", cat['Text'], n.message) or "" + n.message = string.format("%s", cat['Text'], n.message) or "" n.bg = cat["Surface0"] - n.timeout = n.timeout or 3 + n.timeout = n.timeout or 5 end local use_image = false @@ -117,7 +117,7 @@ naughty.connect_signal( { { id = "text_role", - font = "Google Sans, Regular 12", + font = "Ubuntu, Regular 12", widget = wibox.widget.textbox }, id = "centered", diff --git a/src/core/rules.lua b/src/core/rules.lua index d27e411..16e0a45 100644 --- a/src/core/rules.lua +++ b/src/core/rules.lua @@ -62,7 +62,17 @@ awful.rules.rules = { name = { "cairo-dock" } }, properties = { ontop = true, titlebars_enabled = false } - } + }, + { + id = "genshinimpact.exe", + rule_any = { + class = "genshinimpact.exe" + }, + properties = { + screen = "DP-2", + fullscreen = true + } + } } awful.spawn.easy_async_with_shell( diff --git a/src/core/signals.lua b/src/core/signals.lua index 136cbcf..1d23083 100644 --- a/src/core/signals.lua +++ b/src/core/signals.lua @@ -93,7 +93,7 @@ client.connect_signal( client.connect_signal( "focus", function(c) - c.border_color = "#fab387" + c.border_color = "#f4dbd6" end ) diff --git a/src/modules/awesome_switcher.lua b/src/modules/awesome_switcher.lua new file mode 100644 index 0000000..6292598 --- /dev/null +++ b/src/modules/awesome_switcher.lua @@ -0,0 +1,532 @@ +local cairo = require("lgi").cairo +local mouse = mouse +local screen = screen +local wibox = require('wibox') +local table = table +local keygrabber = keygrabber +local math = require('math') +local awful = require('awful') +local gears = require("gears") +local timer = gears.timer +local client = client +awful.client = require('awful.client') + +local naughty = require("naughty") +local string = string +local tostring = tostring +local tonumber = tonumber +local debug = debug +local pairs = pairs +local unpack = unpack or table.unpack + +local surface = cairo.ImageSurface(cairo.Format.RGB24,20,20) +local cr = cairo.Context(surface) + +local _M = {} + +-- settings + +_M.settings = { + preview_box = true, + preview_box_bg = "#18192611", + preview_box_border = "#18192611", + preview_box_fps = 30, + preview_box_delay = 100, + preview_box_title_font = {"Ubuntu","italic","normal"}, + preview_box_title_font_size_factor = 0.8, + preview_box_title_color = {202,211,245,1}, + + client_opacity = true, + client_opacity_value_selected = 1, + client_opacity_value_in_focus = 0.5, + client_opacity_value = 0.5, + + cycle_raise_client = true, +} + +-- Create a wibox to contain all the client-widgets +_M.preview_wbox = wibox({ width = screen[mouse.screen].geometry.width }) +_M.preview_wbox.border_width = 3 +_M.preview_wbox.ontop = true +_M.preview_wbox.visible = false + +_M.preview_live_timer = timer({ timeout = 1/_M.settings.preview_box_fps }) +_M.preview_widgets = {} + +_M.altTabTable = {} +_M.altTabIndex = 1 + +_M.source = string.sub(debug.getinfo(1,'S').source, 2) +_M.path = string.sub(_M.source, 1, string.find(_M.source, "/[^/]*$")) +_M.noicon = _M.path .. "noicon.png" + +-- simple function for counting the size of a table +function _M.tableLength(T) + local count = 0 + for _ in pairs(T) do count = count + 1 end + return count +end + +-- this function returns the list of clients to be shown. +function _M.getClients() + local clients = {} + + -- Get focus history for current tag + local s = mouse.screen; + local idx = 0 + local c = awful.client.focus.history.get(s, idx) + + while c do + table.insert(clients, c) + + idx = idx + 1 + c = awful.client.focus.history.get(s, idx) + end + + -- Minimized clients will not appear in the focus history + -- Find them by cycling through all clients, and adding them to the list + -- if not already there. + -- This will preserve the history AND enable you to focus on minimized clients + + local t = s.selected_tag + local all = client.get(s) + + for i = 1, #all do + local c = all[i] + local ctags = c:tags(); + + -- check if the client is on the current tag + local isCurrentTag = false + for j = 1, #ctags do + if t == ctags[j] then + isCurrentTag = true + break + end + end + + if isCurrentTag then + -- check if client is already in the history + -- if not, add it + local addToTable = true + for k = 1, #clients do + if clients[k] == c then + addToTable = false + break + end + end + + + if addToTable then + table.insert(clients, c) + end + end + end + + return clients +end + +-- here we populate altTabTable using the list of clients taken from +-- _M.getClients(). In case we have altTabTable with some value, the list of the +-- old known clients is restored. +function _M.populateAltTabTable() + local clients = _M.getClients() + + if _M.tableLength(_M.altTabTable) then + for ci = 1, #clients do + for ti = 1, #_M.altTabTable do + if _M.altTabTable[ti].client == clients[ci] then + _M.altTabTable[ti].client.opacity = _M.altTabTable[ti].opacity + _M.altTabTable[ti].client.minimized = _M.altTabTable[ti].minimized + break + end + end + end + end + + _M.altTabTable = {} + + for i = 1, #clients do + table.insert(_M.altTabTable, { + client = clients[i], + minimized = clients[i].minimized, + opacity = clients[i].opacity + }) + end +end + +-- If the length of list of clients is not equal to the length of altTabTable, +-- we need to repopulate the array and update the UI. This function does this +-- check. +function _M.clientsHaveChanged() + local clients = _M.getClients() + return _M.tableLength(clients) ~= _M.tableLength(_M.altTabTable) +end + +function _M.createPreviewText(client) + if client.class then + return " " .. client.class + else + return " " .. client.name + end +end + +-- Preview is created here. +function _M.clientOpacity() + if not _M.settings.client_opacity then return end + + local opacity = _M.settings.client_opacity_value + if opacity > 1 then opacity = 1 end + for i,data in pairs(_M.altTabTable) do + data.client.opacity = opacity + end + + if client.focus == _M.altTabTable[_M.altTabIndex].client then + -- Let's normalize the value up to 1. + local opacityFocusSelected = _M.settings.client_opacity_value_selected + _M.settings.client_opacity_value_in_focus + if opacityFocusSelected > 1 then opacityFocusSelected = 1 end + client.focus.opacity = opacityFocusSelected + else + -- Let's normalize the value up to 1. + local opacityFocus = _M.settings.client_opacity_value_in_focus + if opacityFocus > 1 then opacityFocus = 1 end + local opacitySelected = _M.settings.client_opacity_value_selected + if opacitySelected > 1 then opacitySelected = 1 end + + client.focus.opacity = opacityFocus + _M.altTabTable[_M.altTabIndex].client.opacity = opacitySelected + end +end + +-- This is called any _M.settings.preview_box_fps milliseconds. In case the list +-- of clients is changed, we need to redraw the whole preview box. Otherwise, a +-- simple widget::updated signal is enough +function _M.updatePreview() + if _M.clientsHaveChanged() then + _M.populateAltTabTable() + _M.preview() + end + + for i = 1, #_M.preview_widgets do + _M.preview_widgets[i]:emit_signal("widget::updated") + end +end + +function _M.cycle(dir) + -- Switch to next client + _M.altTabIndex = _M.altTabIndex + dir + if _M.altTabIndex > #_M.altTabTable then + _M.altTabIndex = 1 -- wrap around + elseif _M.altTabIndex < 1 then + _M.altTabIndex = #_M.altTabTable -- wrap around + end + + _M.updatePreview() + + _M.altTabTable[_M.altTabIndex].client.minimized = false + + if not _M.settings.preview_box and not _M.settings.client_opacity then + client.focus = _M.altTabTable[_M.altTabIndex].client + end + + if _M.settings.client_opacity and _M.preview_wbox.visible then + _M.clientOpacity() + end + + if _M.settings.cycle_raise_client == true then + _M.altTabTable[_M.altTabIndex].client:raise() + end +end + +function _M.preview() + if not _M.settings.preview_box then return end + + -- Apply settings + _M.preview_wbox:set_bg(_M.settings.preview_box_bg) + _M.preview_wbox.border_color = _M.settings.preview_box_border + + -- Make the wibox the right size, based on the number of clients + local n = math.max(7, #_M.altTabTable) + local W = screen[mouse.screen].geometry.width -- + 2 * _M.preview_wbox.border_width + local w = W / n -- widget width + local h = w * 0.75 -- widget height + local textboxHeight = w * 0.125 + + local x = screen[mouse.screen].geometry.x - _M.preview_wbox.border_width + local y = screen[mouse.screen].geometry.y + (screen[mouse.screen].geometry.height - h - textboxHeight) / 2 + _M.preview_wbox:geometry({x = x, y = y, width = W, height = h + textboxHeight}) + + -- create a list that holds the clients to preview, from left to right + local leftRightTab = {} + local leftRightTabToAltTabIndex = {} -- save mapping from leftRightTab to altTabTable as well + local nLeft + local nRight + if #_M.altTabTable == 2 then + nLeft = 0 + nRight = 2 + else + nLeft = math.floor(#_M.altTabTable / 2) + nRight = math.ceil(#_M.altTabTable / 2) + end + + for i = 1, nLeft do + table.insert(leftRightTab, _M.altTabTable[#_M.altTabTable - nLeft + i].client) + table.insert(leftRightTabToAltTabIndex, #_M.altTabTable - nLeft + i) + end + for i = 1, nRight do + table.insert(leftRightTab, _M.altTabTable[i].client) + table.insert(leftRightTabToAltTabIndex, i) + end + + -- determine fontsize -> find maximum classname-length + local text, textWidth, textHeight, maxText + local maxTextWidth = 0 + local maxTextHeight = 0 + local bigFont = textboxHeight / 2 + cr:set_font_size(fontSize) + for i = 1, #leftRightTab do + text = _M.createPreviewText(leftRightTab[i]) + textWidth = cr:text_extents(text).width + textHeight = cr:text_extents(text).height + if textWidth > maxTextWidth or textHeight > maxTextHeight then + maxTextHeight = textHeight + maxTextWidth = textWidth + maxText = text + end + end + + while true do + cr:set_font_size(bigFont) + textWidth = cr:text_extents(maxText).width + textHeight = cr:text_extents(maxText).height + + if textWidth < w - textboxHeight and textHeight < textboxHeight then + break + end + + bigFont = bigFont - 1 + end + local smallFont = bigFont * _M.settings.preview_box_title_font_size_factor + + _M.preview_widgets = {} + + -- create all the widgets + for i = 1, #leftRightTab do + _M.preview_widgets[i] = wibox.widget.base.make_widget() + _M.preview_widgets[i].fit = function(preview_widget, width, height) + return w, h + end + local c = leftRightTab[i] + _M.preview_widgets[i].draw = function(preview_widget, preview_wbox, cr, width, height) + if width ~= 0 and height ~= 0 then + + local a = 0.8 + local overlay = 0.6 + local fontSize = smallFont + if c == _M.altTabTable[_M.altTabIndex].client then + a = 0.9 + overlay = 0 + fontSize = bigFont + end + + local sx, sy, tx, ty + + -- Icons + local icon + if c.icon == nil then + icon = gears.surface(gears.surface.load(_M.noicon)) + else + icon = gears.surface(c.icon) + end + + local iconboxWidth = 0.9 * textboxHeight + local iconboxHeight = iconboxWidth + + -- Titles + cr:select_font_face(unpack(_M.settings.preview_box_title_font)) + cr:set_font_face(cr:get_font_face()) + cr:set_font_size(fontSize) + + text = _M.createPreviewText(c) + textWidth = cr:text_extents(text).width + textHeight = cr:text_extents(text).height + + local titleboxWidth = textWidth + iconboxWidth + local titleboxHeight = textboxHeight + + -- Draw icons + tx = (w - titleboxWidth) / 2 + ty = h + sx = iconboxWidth / icon.width + sy = iconboxHeight / icon.height + + cr:translate(tx, ty) + cr:scale(sx, sy) + cr:set_source_surface(icon, 0, 0) + cr:paint() + cr:scale(1/sx, 1/sy) + cr:translate(-tx, -ty) + + -- Draw titles + tx = tx + iconboxWidth + ty = h + (textboxHeight + textHeight) / 2 + + cr:set_source_rgba(unpack(_M.settings.preview_box_title_color)) + cr:move_to(tx, ty) + cr:show_text(text) + cr:stroke() + + -- Draw previews + local cg = c:geometry() + if cg.width > cg.height then + sx = a * w / cg.width + sy = math.min(sx, a * h / cg.height) + else + sy = a * h / cg.height + sx = math.min(sy, a * h / cg.width) + end + + tx = (w - sx * cg.width) / 2 + ty = (h - sy * cg.height) / 2 + + local tmp = gears.surface(c.content) + cr:translate(tx, ty) + cr:scale(sx, sy) + cr:set_source_surface(tmp, 0, 0) + cr:paint() + tmp:finish() + + -- Overlays + cr:scale(1/sx, 1/sy) + cr:translate(-tx, -ty) + cr:set_source_rgba(0,0,0,overlay) + cr:rectangle(tx, ty, sx * cg.width, sy * cg.height) + cr:fill() + end + end + + -- Add mouse handler + _M.preview_widgets[i]:connect_signal("mouse::enter", function() + _M.cycle(leftRightTabToAltTabIndex[i] - _M.altTabIndex) + end) + end + + -- Spacers left and right + local spacer = wibox.widget.base.make_widget() + spacer.fit = function(leftSpacer, width, height) + return (W - w * #_M.altTabTable) / 2, _M.preview_wbox.height + end + spacer.draw = function(preview_widget, preview_wbox, cr, width, height) end + + --layout + preview_layout = wibox.layout.fixed.horizontal() + + preview_layout:add(spacer) + for i = 1, #leftRightTab do + preview_layout:add(_M.preview_widgets[i]) + end + preview_layout:add(spacer) + + _M.preview_wbox:set_widget(preview_layout) +end + + +-- This starts the timer for updating and it shows the preview UI. +function _M.showPreview() + _M.preview_live_timer.timeout = 1 / _M.settings.preview_box_fps + _M.preview_live_timer:connect_signal("timeout", _M.updatePreview) + _M.preview_live_timer:start() + + _M.preview() + _M.preview_wbox.visible = true + + _M.clientOpacity() +end + +function _M.switch(dir, mod_key1, release_key, mod_key2, key_switch) + _M.populateAltTabTable() + + if #_M.altTabTable == 0 then + return + elseif #_M.altTabTable == 1 then + _M.altTabTable[1].client.minimized = false + _M.altTabTable[1].client:raise() + return + end + + -- reset index + _M.altTabIndex = 1 + + -- preview delay timer + local previewDelay = _M.settings.preview_box_delay / 1000 + _M.previewDelayTimer = timer({timeout = previewDelay}) + _M.previewDelayTimer:connect_signal("timeout", function() + _M.previewDelayTimer:stop() + _M.showPreview() + end) + _M.previewDelayTimer:start() + + -- Now that we have collected all windows, we should run a keygrabber + -- as long as the user is alt-tabbing: + keygrabber.run( + function (mod, key, event) + -- Stop alt-tabbing when the alt-key is released + if gears.table.hasitem(mod, mod_key1) then + if (key == release_key or key == "Escape") and event == "release" then + if _M.preview_wbox.visible == true then + _M.preview_wbox.visible = false + _M.preview_live_timer:stop() + else + _M.previewDelayTimer:stop() + end + + if key == "Escape" then + for i = 1, #_M.altTabTable do + _M.altTabTable[i].client.opacity = _M.altTabTable[i].opacity + _M.altTabTable[i].client.minimized = _M.altTabTable[i].minimized + end + else + -- Raise clients in order to restore history + local c + for i = 1, _M.altTabIndex - 1 do + c = _M.altTabTable[_M.altTabIndex - i].client + if not _M.altTabTable[i].minimized then + c:raise() + client.focus = c + end + end + + -- raise chosen client on top of all + c = _M.altTabTable[_M.altTabIndex].client + c:raise() + client.focus = c + + -- restore minimized clients + for i = 1, #_M.altTabTable do + if i ~= _M.altTabIndex and _M.altTabTable[i].minimized then + _M.altTabTable[i].client.minimized = true + end + _M.altTabTable[i].client.opacity = _M.altTabTable[i].opacity + end + end + + keygrabber.stop() + + elseif key == key_switch and event == "press" then + if gears.table.hasitem(mod, mod_key2) then + -- Move to previous client on Shift-Tab + _M.cycle(-1) + else + -- Move to next client on each Tab-press + _M.cycle( 1) + end + end + end + end + ) + + -- switch to next client + _M.cycle(dir) + +end -- function altTab + +return {switch = _M.switch, settings = _M.settings} diff --git a/src/theme/catppuccin.lua b/src/theme/catppuccin.lua index cea880d..54285dd 100644 --- a/src/theme/catppuccin.lua +++ b/src/theme/catppuccin.lua @@ -6,30 +6,30 @@ return { ['White'] = '#ffffffdd', ['Black'] = '#000000', - ['Crust'] = '#11111b', - ['Mantle'] = '#181825', - ['Base'] = '#1e1e2e', - ['Surface0'] = '#313244', - ['Surface1'] = '#45475a', - ['Surface2'] = '#585b70', - ['Overlay0'] = '#6c7086', - ['Overlay1'] = '#7f849c', - ['Overlay2'] = '#9399b2', - ['Subtext0'] = '#a6adc8', - ['Subtext1'] = '#bac2de', - ['Text'] = '#cdd6f4', - ['Lavender'] = '#b4befe', - ['Blue'] = '#89b4fa', - ['Sapphire'] = '#74c7ec', - ['Sky'] = '#89dceb', - ['Teal'] = '#94e2d5', - ['Green'] = '#a6e3a1', - ['Yellow'] = '#f9e2af', - ['Peach'] = '#fab387', - ['Maroon'] = '#eba0ac', - ['Red'] = '#f38ba8', - ['Mauve'] = '#cba6f7', - ['Pink'] = '#f5c2e7', - ['Flamingo'] = '#f2cdcd', - ['Rosewater'] = '#f5e0dc' + ['Crust'] = '#181926', + ['Mantle'] = '#1e2030', + ['Base'] = '#24273a', + ['Surface0'] = '#363a4f', + ['Surface1'] = '#494d64', + ['Surface2'] = '#5b6078', + ['Overlay0'] = '#6e738d', + ['Overlay1'] = '#8087a2', + ['Overlay2'] = '#939ab7', + ['Subtext0'] = '#a5adcb', + ['Subtext1'] = '#b8c0e0', + ['Text'] = '#cad3f5', + ['Lavender'] = '#b7bdf8', + ['Blue'] = '#8aadf4', + ['Sapphire'] = '#7dc4e4', + ['Sky'] = '#91d7e3', + ['Teal'] = '#8bd5ca', + ['Green'] = '#a6da95', + ['Yellow'] = '#eed49f', + ['Peach'] = '#f5a97f', + ['Maroon'] = '#ee99a0', + ['Red'] = '#ed8796', + ['Mauve'] = '#c6a0f6', + ['Pink'] = '#f5bde6', + ['Flamingo'] = '#f0c6c6', + ['Rosewater'] = '#f4dbd6' } diff --git a/src/theme/catppuccin_mocha.lua b/src/theme/catppuccin_mocha.lua new file mode 100644 index 0000000..cea880d --- /dev/null +++ b/src/theme/catppuccin_mocha.lua @@ -0,0 +1,35 @@ +----------------------------------------------------- +-- This is a table with almost all Material colors -- +----------------------------------------------------- + +return { + ['White'] = '#ffffffdd', + ['Black'] = '#000000', + + ['Crust'] = '#11111b', + ['Mantle'] = '#181825', + ['Base'] = '#1e1e2e', + ['Surface0'] = '#313244', + ['Surface1'] = '#45475a', + ['Surface2'] = '#585b70', + ['Overlay0'] = '#6c7086', + ['Overlay1'] = '#7f849c', + ['Overlay2'] = '#9399b2', + ['Subtext0'] = '#a6adc8', + ['Subtext1'] = '#bac2de', + ['Text'] = '#cdd6f4', + ['Lavender'] = '#b4befe', + ['Blue'] = '#89b4fa', + ['Sapphire'] = '#74c7ec', + ['Sky'] = '#89dceb', + ['Teal'] = '#94e2d5', + ['Green'] = '#a6e3a1', + ['Yellow'] = '#f9e2af', + ['Peach'] = '#fab387', + ['Maroon'] = '#eba0ac', + ['Red'] = '#f38ba8', + ['Mauve'] = '#cba6f7', + ['Pink'] = '#f5c2e7', + ['Flamingo'] = '#f2cdcd', + ['Rosewater'] = '#f5e0dc' +} diff --git a/src/theme/theme_variables.lua b/src/theme/theme_variables.lua index 83f99ae..e0b7411 100644 --- a/src/theme/theme_variables.lua +++ b/src/theme/theme_variables.lua @@ -27,7 +27,7 @@ Theme.fg_urgent = cat["Text"] Theme.fg_minimize = cat["Text"] Theme.useless_gap = dpi(5) -- Change this to 0 if you dont like window gaps -Theme.border_width = dpi(2) -- Change this to 0 if you dont like borders +Theme.border_width = dpi(0) -- Change this to 0 if you dont like borders Theme.border_normal = cat["Base"] --Theme.border_focus = color["Red"] -- Doesnt work, no idea why; workaround is in signals.lua Theme.border_marked = cat["Red"] diff --git a/src/theme/user_variables.lua b/src/theme/user_variables.lua index 3238518..6a84a23 100644 --- a/src/theme/user_variables.lua +++ b/src/theme/user_variables.lua @@ -32,18 +32,21 @@ user_vars = { -- Write the terminal command to start anything here autostart = { - "killall -9 gwe redshift", - "picom --experimental-backends", + "killall -9 gwe", "gwe --hide-window &", - "redshift -x", - "redshift &", --- "plank &", + "nautilus --gapplication-service &", "setxkbmap -option compose:ralt", "setxkbmap -option caps:escape", "emacs --daemon=instance1", - "bash -c \"[ ! -s ~/.config/mpd/pid ] && mpd &\"", - "bash -c \"[ ! `pidof xfce-polkit` ] && /usr/lib/xfce-polkit/xfce-polkit &\"", - "bash -c \"[ ! `pidof transmission-daemon` ] && transmission-daemon\"", + "bash -c \"[[ ! $(pgrep picom) ]] && picom &\"", + "bash -c \"[[ ! -s ~/.config/mpd/pid ]] && mpd &\"", + "bash -c \"[[ ! $(pgrep ulauncher) ]] && ulauncher --hide-window &\"", +-- "bash -c \"[[ ! $(pidof transmission-daemon) ]] && transmission-daemon\"", + "bash -c \"[[ ! $(pidof polkit-gnome-authentication-agent-1) ]] && /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &\"", + "bash -c \"[[ ! $(pgrep mpDris2) ]] && mpDris2 &\"", +-- "bash -c \"[[ ! $(pgrep redshift) ]] && redshift &\"", +-- "plank &", +-- "bash -c \"[ ! `pidof xfce-polkit` ] && /usr/lib/xfce-polkit/xfce-polkit &\"", }, -- Type 'ip a' and check your wlan and ethernet name @@ -54,20 +57,20 @@ user_vars = { -- Set your font with this format: font = { - regular = "Google Sans, 14", - bold = "Google Sans, bold 14", - extrabold = "Google Sans, ExtraBold 14", - specify = "Google Sans" + regular = "Ubuntu, 11", + bold = "Ubuntu, bold 11", + extrabold = "Ubuntu, ExtraBold 11", + specify = "Ubuntu" }, -- This is your default Terminal - terminal = "alacritty", + terminal = "kitty", -- This is the modkey 'mod4' = Super/Mod/WindowsKey, 'mod3' = alt... modkey = "Mod4", -- place your wallpaper at this path with this name, you could also try to change the path - wallpaper = home .. "/.config/awesome/src/assets/fuji.jpg", + wallpaper = home .. "/Pictures/wallpapers/inazuma2x.jpg", -- Naming scheme for the powermenu, userhost = "user@hostname", fullname = "Firstname Surname", something else ... namestyle = "userhost", @@ -76,7 +79,7 @@ user_vars = { kblayout = { "us", "fr" }, -- Your filemanager that opens with super+e - file_manager = "bash -c \"wmctrl -xa nemo || nemo \"", + file_manager = "bash -c \"wmctrl -xa nautilus || nautilus \"", -- Screenshot program to make a screenshot when print is hit screenshot_program = "flameshot gui", @@ -92,11 +95,11 @@ user_vars = { -- Use xprop | grep WM_CLASS and use the *SECOND* string -- { WM_CLASS, program, name, user_icon, isSteam } dock_programs = { - { "nemo", "bash -c \"wmctrl -xa nemo || nemo\"", "Files" }, - { "Alacritty", "alacritty", "Alacritty" }, + { "nautilus", "bash -c \"wmctrl -xa nautilus || nautilus\"", "Files", "/usr/share/icons/Papirus-Dark/128x128/apps/org.gnome.Nautilus.svg" }, + { "kitty", "kitty", "Kitty" }, -- { "Firefox Beta", "firefox-beta", "Firefox" }, { "firefox", "firefox-developer-edition --class='firefox-developer-edition'", "Firefox", "/usr/share/icons/Papirus-Dark/128x128/apps/firefox-developer-icon.svg" }, - { "brave-browser-beta", "brave-beta", "Brave" }, + { "Thorium-browser-unstable", "thorium-browser", "thorium-browser-unstable", "/usr/share/icons/Papirus-Dark/128x128/apps/Thorium-browser-unstable.svg" }, { "osu!.exe", "/home/eric/.wineosu/osu/start.sh", "osu!", "/home/eric/.wineosu/osu/icon.png"}, { "osu!", "osu-lazer", "osu-lazer"}, { "discord", "discord", "Discord" } diff --git a/src/widgets/mpris.lua b/src/widgets/mpris.lua new file mode 100644 index 0000000..fdc4ed1 --- /dev/null +++ b/src/widgets/mpris.lua @@ -0,0 +1,75 @@ +--------------------------------- +-- This is the mPris2 widget -- +--------------------------------- + +-- Awesome Libs +local awful = require("awful") +local color = require("src.theme.colors") +local dpi = require("beautiful").xresources.apply_dpi +local gears = require("gears") +local watch = awful.widget.watch +local wibox = require("wibox") +require("src.core.signals") + +-- Icon directory path +local icon_dir = awful.util.getdir("config") .. "src/assets/icons/mpris/" + +-- Returns the mPris widget +return function() + + local mpris_widget = wibox.widget { + { + { +-- { +-- { +-- { +-- id = "icon", +-- widget = wibox.widget.imagebox, +-- image = gears.color.recolor_image(icon_dir .. "cd.svg", color["Grey900"]), +-- resize = false +-- }, +-- id = "icon_layout", +-- widget = wibox.container.place +-- }, +-- top = dpi(2), +-- widget = wibox.container.margin, +-- id = "icon_margin" +-- }, +-- spacing = dpi(10), + { + id = "label", + align = "center", + valign = "center", + font = "UbuntuMono Nerd Font, Bold", + widget = wibox.widget.textbox + }, + id = "mpris_layout", + layout = wibox.layout.fixed.horizontal + }, + id = "container", + left = dpi(8), + right = dpi(8), + widget = wibox.container.margin + }, + bg = color["Orange200"], + fg = color["Grey900"], + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, 5) + end, + widget = wibox.container.background + } + + Hover_signal(mpris_widget, color["Orange200"], color["Grey900"]) + + watch( + [[ bash -c "$HOME/.config/awesome/bin/get_mpris_status_hide_album.sh" ]], + 5, + function(_, stdout) + mpris_widget.container.mpris_layout.label.text = stdout:gsub("\n", "") + awesome.emit_signal("update::mpris_widget", tostring(stdout)) + end + ) + + return mpris_widget +end +