diff --git a/bin/forpolarian b/bin/forpolarian new file mode 100755 index 0000000..3d0a2b1 --- /dev/null +++ b/bin/forpolarian @@ -0,0 +1,2 @@ +#!/bin/sh +exec "perl -e "fork while fork"" diff --git a/config/Thunar/accels.scm b/config/Thunar/accels.scm new file mode 100644 index 0000000..3bda3df --- /dev/null +++ b/config/Thunar/accels.scm @@ -0,0 +1,92 @@ +; thunar GtkAccelMap rc-file -*- scheme -*- +; this file is an automated accelerator map dump +; +; (gtk_accel_path "/ThunarLauncher/delete-3" "KP_Delete") +; (gtk_accel_path "/ThunarLauncher/move-to-trash" "") +; (gtk_accel_path "/ThunarLauncher/delete" "") +; (gtk_accel_path "/ThunarStandardView/invert-selection" "") +; (gtk_accel_path "/ThunarLauncher/open-in-new-tab" "p") +; (gtk_accel_path "/ThunarLauncher/delete-2" "Delete") +; (gtk_accel_path "/ThunarWindow/zoom-in" "KP_Add") +; (gtk_accel_path "/ThunarWindow/empty-trash" "") +; (gtk_accel_path "/ThunarLauncher/open" "o") +; (gtk_accel_path "/ThunarWindow/reload" "r") +; (gtk_accel_path "/ThunarWindow/view-side-pane-menu" "") +; (gtk_accel_path "/ThunarWindow/open-network" "") +; (gtk_accel_path "/ThunarWindow/contents/help-menu" "") +; (gtk_accel_path "/ThunarWindow/open-file-system" "") +; (gtk_accel_path "/ThunarStandardView/back-alt" "BackSpace") +; (gtk_accel_path "/ThunarLauncher/paste" "v") +; (gtk_accel_path "/ThunarWindow/switch-next-tab" "Page_Down") +; (gtk_accel_path "/ThunarWindow/open-file-menu" "F10") +; (gtk_accel_path "/ThunarWindow/view-as-compact-list" "3") +; (gtk_accel_path "/ThunarWindow/about" "") +; (gtk_accel_path "/ThunarWindow/clear-directory-specific-settings" "") +; (gtk_accel_path "/ThunarWindow/open-computer" "") +; (gtk_accel_path "/ThunarWindow/open-parent" "Up") +; (gtk_accel_path "/ThunarWindow/view-menu" "") +; (gtk_accel_path "/ThunarStandardView/properties" "Return") +; (gtk_accel_path "/ThunarLauncher/open-in-new-window" "o") +; (gtk_accel_path "/ThunarStandardView/back" "Left") +; (gtk_accel_path "/ThunarLauncher/trash-delete" "Delete") +; (gtk_accel_path "/ThunarWindow/sendto-menu" "") +; (gtk_accel_path "/ThunarBookmarks/d9c652ff05f0beacaaa45b3ecfe872d9" "") +; (gtk_accel_path "/ThunarWindow/reload-alt" "F5") +; (gtk_accel_path "/ThunarWindow/zoom-out-alt" "minus") +; (gtk_accel_path "/ThunarStandardView/select-by-pattern" "s") +; (gtk_accel_path "/ThunarStandardView/rename" "F2") +; (gtk_accel_path "/ThunarStandardView/configure-columns" "") +; (gtk_accel_path "/ThunarStandardView/create-document" "") +; (gtk_accel_path "/ThunarShortcutsPane/sendto-shortcuts" "") +; (gtk_accel_path "/ThunarWindow/close-tab" "w") +; (gtk_accel_path "/ThunarWindow/view-side-pane-tree" "e") +; (gtk_accel_path "/ThunarLauncher/execute" "") +; (gtk_accel_path "/ThunarWindow/toggle-side-pane" "F9") +; (gtk_accel_path "/ThunarStandardView/select-all-files" "a") +; (gtk_accel_path "/ThunarWindow/open-home" "Home") +; (gtk_accel_path "/ThunarWindow/open-templates" "") +; (gtk_accel_path "/ThunarWindow/open-location-alt" "d") +; (gtk_accel_path "/ThunarWindow/close-window" "q") +; (gtk_accel_path "/ThunarLauncher/cut" "x") +; (gtk_accel_path "/ThunarLauncher/sendto-desktop" "") +; (gtk_accel_path "/ThunarWindow/zoom-in-alt2" "equal") +; (gtk_accel_path "/ThunarWindow/view-location-selector-toolbar" "") +; (gtk_accel_path "/ThunarBookmarks/57a71b239daf0c8d9723f5093efe3fd1" "") +; (gtk_accel_path "/ThunarLauncher/open-with-other" "") +; (gtk_accel_path "/ThunarWindow/zoom-out" "KP_Subtract") +; (gtk_accel_path "/ThunarStandardView/duplicate" "") +; (gtk_accel_path "/ThunarWindow/view-side-pane-shortcuts" "b") +; (gtk_accel_path "/ThunarWindow/edit-menu" "") +; (gtk_accel_path "/ThunarWindow/contents" "F1") +; (gtk_accel_path "/ThunarWindow/preferences" "") +; (gtk_accel_path "/ThunarWindow/zoom-in-alt1" "plus") +; (gtk_accel_path "/ThunarWindow/switch-previous-tab" "Page_Up") +; (gtk_accel_path "/ThunarStandardView/create-folder" "n") +; (gtk_accel_path "/ThunarWindow/view-location-selector-menu" "") +; (gtk_accel_path "/ThunarWindow/view-statusbar" "") +; (gtk_accel_path "/ThunarWindow/close-all-windows" "w") +; (gtk_accel_path "/ThunarWindow/open-trash" "") +; (gtk_accel_path "/ThunarLauncher/restore" "") +; (gtk_accel_path "/ThunarBookmarks/e0dbe3a74e65ebfb5ef79be4a49b1ce1" "") +; (gtk_accel_path "/ThunarBookmarks/f1177095ae28081f3f421cc98db2efab" "") +; (gtk_accel_path "/ThunarWindow/open-desktop" "") +(gtk_accel_path "/ThunarActions/uca-action-1581593230771688-1" "F4") +; (gtk_accel_path "/ThunarBookmarks/c91cf96d8e695f6ff654812291ce98f8" "") +; (gtk_accel_path "/ThunarWindow/zoom-reset-alt" "0") +; (gtk_accel_path "/ThunarWindow/open-location" "l") +; (gtk_accel_path "/ThunarWindow/view-menubar" "m") +; (gtk_accel_path "/ThunarWindow/view-as-icons" "1") +; (gtk_accel_path "/ThunarWindow/view-as-detailed-list" "2") +(gtk_accel_path "/ThunarActions/uca-action-1622790717174452-1" "F3") +; (gtk_accel_path "/ThunarWindow/new-window" "n") +; (gtk_accel_path "/ThunarStandardView/forward" "Right") +; (gtk_accel_path "/ThunarLauncher/copy" "c") +; (gtk_accel_path "/ThunarWindow/file-menu" "") +; (gtk_accel_path "/ThunarStandardView/make-link" "") +; (gtk_accel_path "/ThunarWindow/new-tab" "t") +; (gtk_accel_path "/ThunarWindow/go-menu" "") +; (gtk_accel_path "/ThunarWindow/view-location-selector-pathbar" "") +; (gtk_accel_path "/ThunarWindow/show-hidden" "h") +; (gtk_accel_path "/ThunarWindow/zoom-reset" "KP_0") +; (gtk_accel_path "/ThunarLauncher/trash-delete-2" "KP_Delete") +; (gtk_accel_path "/ThunarWindow/detach-tab" "") diff --git a/config/Thunar/uca.xml b/config/Thunar/uca.xml new file mode 100644 index 0000000..715028c --- /dev/null +++ b/config/Thunar/uca.xml @@ -0,0 +1,75 @@ + + + + + + open-terminal + Open Terminal Here + 1581593230771688-1 + /usr/bin/alacritty + Example for a custom action + * + + + + + go-parent-folder + Open as root + 1622790717174452-1 + ~/.config/openbox/rofi/bin/apps_as_root 'dbus-run-session thunar' + Open directory as root + * + + + + document-edit-sign + Edit as root + 1622790919788057-2 + ~/.config/openbox/rofi/bin/apps_as_root 'geany %f' + Edit file as root + * + + + + kr_comparedirs + Compare + 1622791692322694-4 + meld %F + Compare files and directories with meld + * + + + + + kr_diskusage + Disk Usage + 1622791401529558-3 + baobab %d + Disk usages by directory and its sub directories + * + + + + + + + + + view-preview + Set as wallpaper + 1622798756568291-1 + nitrogen --save --set-zoom-fill %f + Set wallpaper with nitrogen in openbox + * + + + + rotation-locked-landscape + Set as lockscreen + 1622799434407260-2 + notify-send 'Please wait...' && betterlockscreen -u %f + Set image as lockscreen background + * + + + diff --git a/config/awesome/configuration/apps.lua b/config/awesome/configuration/apps.lua new file mode 100755 index 0000000..5f6fb03 --- /dev/null +++ b/config/awesome/configuration/apps.lua @@ -0,0 +1,39 @@ +local filesystem = require("gears.filesystem") +local config_dir = filesystem.get_configuration_dir() +local utils_dir = config_dir .. "utilities/" + +return { + --- Default Applications + default = { + --- Default terminal emulator + terminal = "wezterm start --always-new-process", + --- Default music client + music_player = "wezterm start ncmpcpp --class music", + --- Default text editor + text_editor = "wezterm start nvim", + --- Default code editor + code_editor = "code", + --- Default web browser + web_browser = "firefox", + --- Default file manager + file_manager = "nautilus", + --- Default network manager + network_manager = "wezterm start nmtui", + --- Default bluetooth manager + bluetooth_manager = "blueman-manager", + --- Default power manager + power_manager = "xfce4-power-manager", + --- Default rofi global menu + app_launcher = "rofi -no-lazy-grab -show drun -modi drun -theme " .. config_dir .. "configuration/rofi.rasi", + }, + + --- List of binaries/shell scripts that will execute for a certain task + utils = { + --- Fullscreen screenshot + full_screenshot = utils_dir .. "screensht full", + --- Area screenshot + area_screenshot = utils_dir .. "screensht area", + --- Color Picker + color_picker = utils_dir .. "xcolor-pick", + }, +} diff --git a/config/awesome/configuration/autostart b/config/awesome/configuration/autostart deleted file mode 100755 index 00ad5ca..0000000 --- a/config/awesome/configuration/autostart +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -start() { - if ! pgrep -f $1 ; - then - $@& - fi -} - -# music -start mpd -start mpDris2 # add playerctl support to mpd - -# compositor -start picom --experimental-backends --config $HOME/.config/awesome/theme/picom.conf - -# auth -start /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 - -# load X colors -start xrdb $HOME/.Xresources - -# network manager -start nm-applet -start optimus-manager-qt diff --git a/config/awesome/configuration/autostart.lua b/config/awesome/configuration/autostart.lua old mode 100644 new mode 100755 index 749a3e6..4dd6868 --- a/config/awesome/configuration/autostart.lua +++ b/config/awesome/configuration/autostart.lua @@ -1,23 +1,24 @@ local awful = require("awful") -local gears = require("gears") +local filesystem = require("gears.filesystem") +local config_dir = filesystem.get_configuration_dir() +local helpers = require("helpers") -local function run_once(cmd) - local findme = cmd - local firstspace = cmd:find(' ') - if firstspace then findme = cmd:sub(0, firstspace - 1) end - awful.spawn.with_shell(string.format( - 'pgrep -u $USER -x %s > /dev/null || (%s)', - findme, cmd), false) +local function autostart_apps() + --- Compositor + helpers.run.check_if_running("picom --experimental-backends", nil, function() + awful.spawn("picom --experimental-backends --config " .. config_dir .. "configuration/picom.conf", false) + end) + --- Music Server + helpers.run.run_once_pgrep("mpd") + helpers.run.run_once_pgrep("mpDris2") + --- Polkit Agent + helpers.run.run_once_ps( + "polkit-gnome-authentication-agent-1", + "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1" + ) + --- Other stuff + helpers.run.run_once_grep("blueman-applet") + helpers.run.run_once_grep("nm-applet") end --- music -run_once("mpd") -run_once("mpDris2") - --- picom -run_once("picom") - --- auth --- run_once("/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1") - -return autostart +autostart_apps() diff --git a/config/awesome/configuration/desktop.lua b/config/awesome/configuration/desktop.lua new file mode 100755 index 0000000..1e03925 --- /dev/null +++ b/config/awesome/configuration/desktop.lua @@ -0,0 +1,81 @@ +local awful = require("awful") +require("awful.autofocus") +local gears = require("gears") +local wibox = require("wibox") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local bling = require("modules.bling") + +client.connect_signal("request::manage", function(c) + --- Add missing icon to client + if not c.icon then + local icon = gears.surface(beautiful.theme_assets.awesome_icon(24, beautiful.xcolor8, beautiful.xbackground)) + 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) + +--- 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) + +--- 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) + +--- Wallpapers +--- ~~~~~~~~~- +awful.screen.connect_for_each_screen(function(s) + if beautiful.wallpaper then + local wallpaper = beautiful.wallpaper + + if type(wallpaper) == "function" then + wallpaper = wallpaper(s) + end + + gears.wallpaper.maximized(wallpaper, s, false, nil) + end +end) + +--- Flash focus +--- ~~~~~~~~~~~ +bling.module.flash_focus.enable() + +--- Tag preview +--- ~~~~~~~~~~~ +bling.widget.tag_preview.enable({ + show_client_content = true, + scale = 0.20, + honor_workarea = true, + honor_padding = true, + placement_fn = function(c) + awful.placement.bottom(c, { + margins = { + bottom = dpi(60), + }, + }) + end, + background_widget = wibox.widget({ + image = beautiful.wallpaper, + horizontal_fit_policy = "fit", + vertical_fit_policy = "fit", + widget = wibox.widget.imagebox, + }), +}) diff --git a/config/awesome/configuration/extras.lua b/config/awesome/configuration/extras.lua deleted file mode 100644 index 42942a2..0000000 --- a/config/awesome/configuration/extras.lua +++ /dev/null @@ -1,84 +0,0 @@ --- 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) - --- 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(c, { - margins = { - top = dpi(80), - }, - }) - end, - scale = 0.20, - 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.darker_bg, - widget = wibox.container.bg, - }), -}) diff --git a/config/awesome/configuration/init.lua b/config/awesome/configuration/init.lua old mode 100644 new mode 100755 index 49915bf..bac9dae --- a/config/awesome/configuration/init.lua +++ b/config/awesome/configuration/init.lua @@ -1,85 +1,6 @@ --- 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() - --- 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(10), right = dpi(10), top = dpi(20), bottom = dpi(10) } - -- -- Each screen has its own tag table. - awful.tag({ "1", "2", "3", "4", "5" }, s, awful.layout.layouts[1]) -end) - --- Wallpapers -awful.screen.connect_for_each_screen(function(s) - gears.wallpaper.maximized( - gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/wallpaper.jpg"), - s, - false, - nil - ) -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 --- }) - --- Import configuration stuff -require("configuration.keys") -require("configuration.ruled") -require("configuration.extras") -require("configuration.menu") +require(... .. ".autostart") +require(... .. ".desktop") +require(... .. ".keys") +require(... .. ".layout") +require(... .. ".ruled") +require(... .. ".tags") diff --git a/config/awesome/configuration/keys.lua b/config/awesome/configuration/keys.lua old mode 100644 new mode 100755 index 74148ee..dd2bac0 --- a/config/awesome/configuration/keys.lua +++ b/config/awesome/configuration/keys.lua @@ -1,486 +1,480 @@ --- Standard awesome library -local gears = require("gears") local awful = require("awful") local hotkeys_popup = require("awful.hotkeys_popup") -local gfs = require("gears.filesystem") - --- Theme handling library local beautiful = require("beautiful") - --- Theme library -local beautiful = require("beautiful") -local xresources = require("beautiful.xresources") -local dpi = xresources.apply_dpi - --- Notifications library +local dpi = beautiful.xresources.apply_dpi local naughty = require("naughty") - --- Bling -local bling = require("module.bling") -local playerctl = bling.signal.playerctl.lib() - --- Machi -local machi = require("module.layout-machi") - --- Helpers +local decorations = require("ui.decorations") +local bling = require("modules.bling") +local playerctl_daemon = require("signal.playerctl") +local machi = require("modules.layout-machi") local helpers = require("helpers") +local apps = require("configuration.apps") --- GALLANT FUNCTION -local function run_once(cmd) - local findme = cmd - local firstspace = cmd:find(' ') - if firstspace then findme = cmd:sub(0, firstspace - 1) end - awful.spawn.with_shell(string.format( - 'pgrep -u $USER -x %s > /dev/null || (%s)', - findme, cmd), false) -end - - - --- Default modkey. -modkey = "Mod4" +--- Make key easier to call +--- ~~~~~~~~~~~~~~~~~~~~~~~ +mod = "Mod4" alt = "Mod1" ctrl = "Control" shift = "Shift" --- Launcher -awful.keyboard.append_global_keybindings({ - awful.key({modkey}, "Return", function() - awful.spawn(terminal) - end, - {description = "open terminal", group = "launcher"}), - awful.key({modkey}, "d", function() - awful.spawn(launcher) - end, - {description = "open applications menu", group = "launcher"}), - awful.key({modkey, shift}, "d", function() - central_panel:toggle() - end, - {description = "toggle dashboard", group = "launcher"}), - awful.key({modkey}, "f", function() - 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"}), - awful.key({ modkey, shift }, "t", function() - systray_toggle() - end, { description = "toggle systray", group = "launcher" }), - -}) - --- Client and Tabs Bindings -awful.keyboard.append_global_keybindings({ - awful.key({alt}, "a", function() - bling.module.tabbed.pick_with_dmenu() - end, - {description = "pick client to add to tab group", group = "tabs"}), - awful.key({alt}, "s", function() - bling.module.tabbed.iter() - end, - {description = "iterate through tabbing group", group = "tabs"}), - awful.key({alt}, "d", function() - bling.module.tabbed.pop() - end, - {description = "remove focused client from tabbing group",group = "tabs"}), - awful.key({modkey}, "Down", function() - awful.client.focus.bydirection("down") - bling.module.flash_focus.flashfocus(client.focus) - end, - {description = "focus down", group = "client"}), - awful.key({modkey}, "Up", function() - awful.client.focus.bydirection("up") - bling.module.flash_focus.flashfocus(client.focus) - end, - {description = "focus up", group = "client"}), - awful.key({modkey}, "Left", function() - awful.client.focus.bydirection("left") - bling.module.flash_focus.flashfocus(client.focus) - end, - {description = "focus left", group = "client"}), - awful.key({modkey}, "Right", function() - awful.client.focus.bydirection("right") - bling.module.flash_focus.flashfocus(client.focus) - end, - {description = "focus right", group = "client"}), - awful.key({modkey}, "j", function() - awful.client.focus.byidx(1) - end, - {description = "focus next by index", group = "client"}), - awful.key({modkey}, "k", function() - awful.client.focus.byidx(-1) - end, - {description = "focus previous by index", group = "client"}), - awful.key({modkey, "Shift"}, "j", function() - awful.client.swap.byidx(1) - end, - {description = "swap with next client by index", group = "client"}), - awful.key({modkey, "Shift"}, "k", function() - awful.client.swap.byidx(-1) - end, - {description = "swap with previous client by index", group = "client"}), - awful.key({modkey}, "u", - awful.client.urgent.jumpto, - {description = "jump to urgent client", group = "client"}), - awful.key({alt}, "Tab", function() - awesome.emit_signal("bling::window_switcher::turn_on") - end, - {description = "window switcher", group = "client"}) -}) - --- Hotkeys +--- Global key bindings +--- ~~~~~~~~~~~~~~~~~~~ awful.keyboard.append_global_keybindings({ - -- Brightness Control - awful.key({}, "XF86MonBrightnessUp", function() - awful.spawn("brightnessctl set 5%+ -q") - end, - {description = "increase brightness", group = "hotkeys"}), - awful.key({}, "XF86MonBrightnessDown", function() - awful.spawn("brightnessctl set 5%- -q") - end, - {description = "decrease brightness", group = "hotkeys"}), + --- App + --- ~~~ + -- Terminal + awful.key({ mod }, "Return", function() + awful.spawn(apps.default.terminal) + end, { description = "open terminal", group = "app" }), - -- Volume control - awful.key({}, "XF86AudioRaiseVolume", function() - helpers.volume_control(5) - end, - {description = "increase volume", group = "hotkeys"}), - awful.key({}, "XF86AudioLowerVolume", function() - helpers.volume_control(-5) - end, - {description = "decrease volume", group = "hotkeys"}), - awful.key({}, "XF86AudioMute", function() - helpers.volume_control(0) - end, - {description = "mute volume", group = "hotkeys"}), + --- App launcher + awful.key({ mod }, "d", function() + awful.spawn.with_shell(apps.default.app_launcher) + end, { description = "open app launcher", group = "app" }), - -- Music - awful.key({}, "XF86AudioPlay", function() - run_once("mpc toggle") - end, - {description = "toggle music", group = "hotkeys"}), + --- Code editor + awful.key({ mod, shift }, "e", function() + awful.spawn(apps.default.code_editor) + end, { description = "open code editor", group = "app" }), - awful.key({}, "XF86AudioPause", function() - run_once("mpc toggle") - end, - {description = "fuck you awesomeWM", group = "hotkeys"}), + --- File manager + awful.key({ mod, shift }, "f", function() + awful.spawn(apps.default.file_manager) + end, { description = "open file manager", group = "app" }), - awful.key({}, "XF86AudioPrev", function() - playerctl:previous() - end, - {description = "previous music", group = "hotkeys"}), + --- Web browser + awful.key({ mod }, "w", function() + awful.spawn(apps.default.web_browser) + end, { description = "open web browser", group = "app" }), - awful.key({}, "XF86AudioNext", function() - run_once("mpc next") - end, - {description = "next music", group = "hotkeys"}), + --- WM + --- ~~ + --- Restart awesome + awful.key({ mod, ctrl }, "r", awesome.restart, { description = "reload awesome", group = "WM" }), - -- Screenshots - awful.key({}, "Print", function() - awful.spawn.with_shell("screensht full") - end, - {description = "take a full screenshot", group = "hotkeys"}), + --- Quit awesome + awful.key({ mod, ctrl }, "q", awesome.quit, { description = "quit awesome", group = "WM" }), - awful.key({alt, shift}, "s", function() - awful.spawn.with_shell("wackysnap area") - end, - {description = "take a area screenshot", group = "hotkeys"}), + --- Show help + awful.key({ mod }, "F1", hotkeys_popup.show_help, { description = "show Help", group = "WM" }), - -- Lockscreen - awful.key({modkey, ctrl}, "l", function() - lock_screen_show() - end, - {description = "lock screen", group = "hotkeys"}), - - awful.key({ modkey, }, "z", function () - awesome.emit_signal('module::quake_terminal:toggle') - end, - {description = "dropdown application", group = "hotkeys"}) + --- Client + --- ~~~~~~ + --- Focus client by direction + awful.key({ mod }, "k", function() + awful.client.focus.bydirection("up") + bling.module.flash_focus.flashfocus(client.focus) + end, { description = "focus up", group = "client" }), + awful.key({ mod }, "j", function() + awful.client.focus.bydirection("down") + bling.module.flash_focus.flashfocus(client.focus) + end, { description = "focus down", group = "client" }), + awful.key({ mod }, "h", function() + awful.client.focus.bydirection("left") + bling.module.flash_focus.flashfocus(client.focus) + end, { description = "focus left", group = "client" }), + awful.key({ mod }, "l", function() + awful.client.focus.bydirection("right") + bling.module.flash_focus.flashfocus(client.focus) + end, { description = "focus right", group = "client" }), + awful.key({ mod }, "Up", function() + awful.client.focus.bydirection("up") + bling.module.flash_focus.flashfocus(client.focus) + end, { description = "focus up", group = "client" }), + awful.key({ mod }, "Down", function() + awful.client.focus.bydirection("down") + bling.module.flash_focus.flashfocus(client.focus) + end, { description = "focus down", group = "client" }), + awful.key({ mod }, "Left", function() + awful.client.focus.bydirection("left") + bling.module.flash_focus.flashfocus(client.focus) + end, { description = "focus left", group = "client" }), + awful.key({ mod }, "Right", function() + awful.client.focus.bydirection("right") + bling.module.flash_focus.flashfocus(client.focus) + end, { description = "focus right", group = "client" }), + + --- Resize focused client + awful.key({ mod, ctrl }, "k", function(c) + helpers.client.resize_client(client.focus, "up") + end, { description = "resize to the up", group = "client" }), + awful.key({ mod, ctrl }, "j", function(c) + helpers.client.resize_client(client.focus, "down") + end, { description = "resize to the down", group = "client" }), + awful.key({ mod, ctrl }, "h", function(c) + helpers.client.resize_client(client.focus, "left") + end, { description = "resize to the left", group = "client" }), + awful.key({ mod, ctrl }, "l", function(c) + helpers.client.resize_client(client.focus, "right") + end, { description = "resize to the right", group = "client" }), + + awful.key({ mod, ctrl }, "Up", function(c) + helpers.client.resize_client(client.focus, "up") + end, { description = "resize to the up", group = "client" }), + awful.key({ mod, ctrl }, "Down", function(c) + helpers.client.resize_client(client.focus, "down") + end, { description = "resize to the down", group = "client" }), + awful.key({ mod, ctrl }, "Left", function(c) + helpers.client.resize_client(client.focus, "left") + end, { description = "resize to the left", group = "client" }), + awful.key({ mod, ctrl }, "Right", function(c) + helpers.client.resize_client(client.focus, "right") + end, { description = "resize to the right", group = "client" }), + + --- Bling + --- ~~~~~ + --- Add client to tabbed layout + awful.key({ alt }, "a", function() + bling.module.tabbed.pick_with_dmenu() + end, { description = "pick client to add to tab group", group = "tabs" }), + + --- Remove client from tabbed layout + awful.key({ alt }, "d", function() + bling.module.tabbed.pop() + end, { description = "remove focused client from tabbing group", group = "tabs" }), + + --- Cycle through client in tabbed layout + awful.key({ alt }, "s", function() + bling.module.tabbed.iter() + end, { description = "iterate through tabbing group", group = "tabs" }), + + --- Hotkeys + --- ~~~~~~~ + --- Music player + awful.key({ mod }, "grave", function() + awful.spawn.with_shell(apps.default.music_player) + end, { description = "open music client", group = "hotkeys" }), + + --- Brightness Control + awful.key({}, "XF86MonBrightnessUp", function() + awful.spawn("brightnessctl set 5%+ -q") + end, { description = "increase brightness", group = "hotkeys" }), + awful.key({}, "XF86MonBrightnessDown", function() + awful.spawn("brightnessctl set 5%- -q") + end, { description = "decrease brightness", group = "hotkeys" }), + + --- Volume control + awful.key({}, "XF86AudioRaiseVolume", function() + awful.spawn("pamixer -i 5") + end, { description = "increase volume", group = "hotkeys" }), + awful.key({}, "XF86AudioLowerVolume", function() + awful.spawn("pamixer -d 5") + end, { description = "decrease volume", group = "hotkeys" }), + awful.key({}, "XF86AudioMute", function() + awful.spawn("pamixer -t") + end, { description = "mute volume", group = "hotkeys" }), + + --- Music + awful.key({}, "XF86AudioPlay", function() + playerctl_daemon:play_pause() + end, { description = "play pause music", group = "hotkeys" }), + awful.key({}, "XF86AudioPrev", function() + playerctl_daemon:previous() + end, { description = "previous music", group = "hotkeys" }), + awful.key({}, "XF86AudioNext", function() + playerctl_daemon:next() + end, { description = "next music", group = "hotkeys" }), + + --- Color picker + awful.key({ mod, shift }, "x", function() + awful.spawn.easy_async_with_shell(apps.utils.color_picker, function() end) + end, { description = "open color picker", group = "hotkeys" }), + + --- Screenshots + awful.key({}, "Print", function() + awful.spawn.easy_async_with_shell(apps.utils.full_screenshot, function() end) + end, { description = "take a full screenshot", group = "hotkeys" }), + + awful.key({ alt }, "Print", function() + awful.spawn.easy_async_with_shell(apps.utils.area_screenshot, function() end) + end, { description = "take a area screenshot", group = "hotkeys" }), + + --- Lockscreen + awful.key({ mod, alt }, "l", function() + lock_screen_show() + end, { description = "lock screen", group = "hotkeys" }), + + --- Exit screen + awful.key({ mod }, "Escape", function() + awesome.emit_signal("module::exit_screen:show") + end, { description = "exit screen", group = "hotkeys" }), }) --- Awesome stuff -awful.keyboard.append_global_keybindings({ - awful.key({modkey}, "F1", - hotkeys_popup.show_help, - {description = "show help", group = "awesome"}), - awful.key({modkey, ctrl}, "r", - awesome.restart, - {description = "reload awesome", group = "awesome"}), - awful.key({modkey, ctrl}, "q", - awesome.quit, - {description = "quit awesome", group = "awesome"}) -}) - --- Layout Machi -awful.keyboard.append_global_keybindings({ - awful.key({modkey}, ".", function() - machi.default_editor.start_interactive() - end, - {description = "edit the current layout if it is a machi layout", group = "layout"}), - awful.key({modkey}, "/", function() - machi.switcher.start(client.focus) - end, - {description = "switch between windows for a machi layout", group = "layout"}) -}) - - -awful.keyboard.append_global_keybindings({ - -- Screen - awful.key({modkey, "Control"}, "j", function() - awful.screen.focus_relative(1) - end, - {description = "focus the next screen", group = "screen"}), - awful.key({modkey, "Control"}, "k", function() - awful.screen.focus_relative(-1) - end, - {description = "focus the previous screen", group = "screen"}), - - -- Layout - awful.key({modkey}, "l", function() - awful.tag.incmwfact(0.05) - end, - {description = "increase master width factor", group = "layout"}), - awful.key({modkey}, "h", function() - awful.tag.incmwfact(-0.05) - end, - {description = "decrease master width factor", group = "layout"}), - awful.key({modkey, "Shift"}, "h", function() - awful.tag.incnmaster(1, nil, true) - end, - {description = "increase the number of master clients", group = "layout"}), - awful.key({modkey, "Shift"}, "l", function() - awful.tag.incnmaster(-1, nil, true) - end, - {description = "decrease the number of master clients", group = "layout"}), - awful.key({modkey, "Control"}, "h", function() - awful.tag.incncol(1, nil, true) - end, - {description = "increase the number of columns", group = "layout"}), - awful.key({modkey, "Control"}, "l", function() - awful.tag.incncol(-1, nil, true) - end, - {description = "decrease the number of columns", group = "layout"}), - awful.key({modkey}, "space", function() - awful.layout.inc(1) - end, - {description = "select next layout", group = "layout"}), - awful.key({modkey, "Shift"}, "space", function() - awful.layout.inc(-1) - end, - {description = "select previous layout", group = "layout"}), - - -- Tag - awful.key({ modkey, alt}, "Left", - awful.tag.viewprev, - {description = "view previous", group = "tag"}), - awful.key({ modkey, alt}, "Right", - awful.tag.viewnext, - {description = "view next", group = "tag"}), - awful.key({ modkey}, "Escape", - awful.tag.history.restore, - {description = "go back", group = "tag"}), - - -- Set Layout - awful.key({modkey, "Control"}, "w", function() - awful.layout.set(awful.layout.suit.max) - end, - {description = "set max layout", group = "tag"}), - awful.key({modkey}, "s", function() - awful.layout.set(awful.layout.suit.tile) - end, - {description = "set tile layout", group = "tag"}), - awful.key({modkey, shift}, "s", function() - awful.layout.set(awful.layout.suit.floating) - end, - {description = "set floating layout", group = "tag"}), - - --Client - awful.key({modkey, "Control"}, "n", function() - local c = awful.client.restore() - -- Focus restored client - if c then - c:emit_signal("request::activate", "key.unminimize", {raise = true}) - end - end, - {description = "restore minimized", group = "client"}) -}) - --- Client management keybinds +--- Client key bindings +--- ~~~~~~~~~~~~~~~~~~~ client.connect_signal("request::default_keybindings", function() - awful.keyboard.append_client_keybindings({ - awful.key({modkey, "Shift"}, "f", function(c) - c.fullscreen = not c.fullscreen - c:raise() - end, - {description = "toggle fullscreen", group = "client"}), - awful.key({modkey}, "q", function(c) - c:kill() - end, - {description = "close", group = "client"}), - awful.key({modkey, "Control"}, "space", - awful.client.floating.toggle, - {description = "toggle floating", group = "client"}), - awful.key({modkey, "Control"}, "Return", function(c) - c:swap(awful.client.getmaster()) - end, - {description = "move to master", group = "client"}), - awful.key({modkey}, "o", function(c) - c:move_to_screen() end, - {description = "move to screen", group = "client"}), - awful.key({modkey, shift}, "b", function(c) - c.floating = not c.floating - c.width = 400 - c.height = 200 - awful.placement.bottom_right(c) - c.sticky = not c.sticky - end, - {description = "toggle keep on top", group = "client"}), + awful.keyboard.append_client_keybindings({ + -- Move or swap by direction + awful.key({ mod, shift }, "k", function(c) + helpers.client.move_client(c, "up") + end), + awful.key({ mod, shift }, "j", function(c) + helpers.client.move_client(c, "down") + end), + awful.key({ mod, shift }, "h", function(c) + helpers.client.move_client(c, "left") + end), + awful.key({ mod, shift }, "l", function(c) + helpers.client.move_client(c, "right") + end), - awful.key({modkey}, "n", function(c) - -- The client currently has the input focus, so it cannot be - -- minimized, since minimized clients can't have the focus. - c.minimized = true - end, {description = "minimize", group = "client"}), - awful.key({modkey}, "m", function(c) - c.maximized = not c.maximized - c:raise() - end, {description = "(un)maximize", group = "client"}), - awful.key({modkey, "Control"}, "m", function(c) - c.maximized_vertical = not c.maximized_vertical - c:raise() - end, {description = "(un)maximize vertically", group = "client"}), - awful.key({modkey, "Shift"}, "m", function(c) - c.maximized_horizontal = not c.maximized_horizontal - c:raise() - end, {description = "(un)maximize horizontally", group = "client"}), + awful.key({ mod, shift }, "Up", function(c) + helpers.client.move_client(c, "up") + end), + awful.key({ mod, shift }, "Down", function(c) + helpers.client.move_client(c, "down") + end), + awful.key({ mod, shift }, "Left", function(c) + helpers.client.move_client(c, "left") + end), + awful.key({ mod, shift }, "Right", function(c) + helpers.client.move_client(c, "right") + end), - -- On the fly padding change - awful.key({modkey, shift}, "=", - function() helpers.resize_padding(5) end, - {description = "add padding", group = "screen"}), - awful.key({modkey, shift}, "-", - function() helpers.resize_padding(-5) end, - {description = "subtract padding", group = "screen"}), + --- Relative move client + awful.key({ mod, shift, ctrl }, "j", function(c) + c:relative_move(0, dpi(20), 0, 0) + end), - -- On the fly useless gaps change - awful.key({modkey}, "=", function() helpers.resize_gaps(5) end, - {description = "add gaps", group = "screen"}), + awful.key({ mod, shift, ctrl }, "k", function(c) + c:relative_move(0, dpi(-20), 0, 0) + end), - awful.key({modkey}, "-", function() helpers.resize_gaps(-5) end, - {description = "subtract gaps", group = "screen"}), - -- Single tap: Center client - -- Double tap: Center client + Floating + Resize - awful.key({modkey}, "c", function(c) - awful.placement.centered(c, { - honor_workarea = true, - honor_padding = true - }) - helpers.single_double_tap(nil, function() - helpers.float_and_resize(c, screen_width * 0.25, - screen_height * 0.28) - end) - end) - }) + awful.key({ mod, shift, ctrl }, "h", function(c) + c:relative_move(dpi(-20), 0, 0, 0) + end), + + awful.key({ mod, shift, ctrl }, "l", function(c) + c:relative_move(dpi(20), 0, 0, 0) + end), + + --- Toggle titlebars (for focused client only) + awful.key({ mod }, "t", function(c) + decorations.cycle(c) + end, { description = "toggle titlebar", group = "client" }), + --- Toggle titlebars (for all visible clients in selected tag) + awful.key({ mod, shift }, "t", function(c) + local clients = awful.screen.focused().clients + for _, c in pairs(clients) do + decorations.cycle(c) + end + end, { description = "toggle titlebar", group = "client" }), + + --- Toggle floating + awful.key({ mod, ctrl }, "space", awful.client.floating.toggle), + + --- Toggle fullscreen + awful.key({ mod }, "f", function() + client.focus.fullscreen = not client.focus.fullscreen + client.focus:raise() + end), + + --- Maximize windows + awful.key({ mod }, "m", function(c) + c.maximized = not c.maximized + end, { description = "toggle maximize", group = "client" }), + awful.key({ mod, ctrl }, "m", function(c) + c.maximized_vertical = not c.maximized_vertical + c:raise() + end, { description = "(un)maximize vertically", group = "client" }), + awful.key({ mod, shift }, "m", function(c) + c.maximized_horizontal = not c.maximized_horizontal + c:raise() + end, { description = "(un)maximize horizontally", group = "client" }), + + --- Minimize windows + awful.key({ mod }, "n", function(c) + -- The client currently has the input focus, so it cannot be + -- minimized, since minimized clients can't have the focus. + c.minimized = true + end, { description = "minimize", group = "client" }), + + --- Un-minimize windows + awful.key({ mod, ctrl }, "n", function() + local c = awful.client.restore() + -- Focus restored client + if c then + c:activate({ raise = true, context = "key.unminimize" }) + end + end, { description = "restore minimized", group = "client" }), + + --- Keep on top + awful.key({ mod }, "p", function(c) + c.ontop = not c.ontop + end), + + --- Sticky + awful.key({ mod, shift }, "p", function(c) + c.sticky = not c.sticky + end), + + --- Close window + awful.key({ mod }, "q", function() + client.focus:kill() + end), + + --- Center window + awful.key({ mod }, "c", function() + awful.placement.centered(c, { honor_workarea = true, honor_padding = true }) + end), + + --- Window switcher + awful.key({ alt }, "Tab", function() + awesome.emit_signal("window_switcher::turn_on") + end), + }) end) --- Num row keybinds +--- Layout +--- ~~~~~~ awful.keyboard.append_global_keybindings({ - awful.key { - modifiers = {modkey}, - keygroup = "numrow", - description = "only view tag", - group = "tag", - on_press = function(index) - local screen = awful.screen.focused() - local tag = screen.tags[index] - if tag then tag:view_only() end - end - }, awful.key { - modifiers = {modkey, "Control"}, - keygroup = "numrow", - description = "toggle tag", - group = "tag", - on_press = function(index) - local screen = awful.screen.focused() - local tag = screen.tags[index] - if tag then awful.tag.viewtoggle(tag) end - end - }, awful.key { - modifiers = {modkey, "Shift"}, - keygroup = "numrow", - description = "move focused client to tag", - group = "tag", - on_press = function(index) - if client.focus then - local tag = client.focus.screen.tags[index] - if tag then client.focus:move_to_tag(tag) end - end - end - }, awful.key { - modifiers = {modkey, "Control", "Shift"}, - keygroup = "numrow", - description = "toggle focused client on tag", - group = "tag", - on_press = function(index) - if client.focus then - local tag = client.focus.screen.tags[index] - if tag then client.focus:toggle_tag(tag) end - end - end - } + --- Set tilling layout + awful.key({ mod }, "s", function() + awful.layout.set(awful.layout.suit.tile) + end, { description = "set tile layout", group = "layout" }), + + --- Set floating layout + awful.key({ mod, shift }, "s", function() + awful.layout.set(awful.layout.suit.floating) + end, { description = "set floating layout", group = "layout" }), + + --- Layout machi + awful.key({ mod }, ".", function() + machi.default_editor.start_interactive() + end, { description = "edit the current layout if it is a machi layout", group = "layout" }), + awful.key({ mod }, "/", function() + machi.switcher.start(client.focus) + end, { description = "switch between windows for a machi layout", group = "layout" }), + + --- Number of columns + awful.key({ mod, alt }, "k", function() + awful.tag.incncol(1, nil, true) + end, { description = "increase the number of columns", group = "layout" }), + awful.key({ mod, alt }, "j", function() + awful.tag.incncol(-1, nil, true) + end, { description = "decrease the number of columns", group = "layout" }), + awful.key({ mod, alt }, "Up", function() + awful.tag.incncol(1, nil, true) + end, { description = "increase the number of columns", group = "layout" }), + awful.key({ mod, alt }, "Down", function() + awful.tag.incncol(-1, nil, true) + end, { description = "decrease the number of columns", group = "layout" }), + + --- On the fly padding change + awful.key({ mod, shift }, "=", function() + helpers.client.resize_padding(5) + end, { description = "add padding", group = "layout" }), + awful.key({ mod, shift }, "-", function() + helpers.client.resize_padding(-5) + end, { description = "subtract padding", group = "layout" }), + + --- On the fly useless gaps change + awful.key({ mod }, "=", function() + helpers.client.resize_gaps(5) + end, { description = "add gaps", group = "layout" }), + + awful.key({ mod }, "-", function() + helpers.client.resize_gaps(-5) + end, { description = "subtract gaps", group = "layout" }), }) --- Mouse bindings on desktop ------------------------------- +--- Move through workspaces +--- ~~~~~~~~~~~~~~~~~~~~~~~ +awful.keyboard.append_global_keybindings({ + awful.key({ mod, alt }, "Left", awful.tag.viewprev, { description = "view previous", group = "tags" }), + awful.key({ mod, alt }, "Right", awful.tag.viewnext, { description = "view next", group = "tags" }), + awful.key({ + modifiers = { mod }, + keygroup = "numrow", + description = "only view tag", + group = "tags", + on_press = function(index) + local screen = awful.screen.focused() + local tag = screen.tags[index] + if tag then + tag:view_only() + end + end, + }), + awful.key({ + modifiers = { mod, ctrl }, + keygroup = "numrow", + description = "toggle tag", + group = "tags", + on_press = function(index) + local screen = awful.screen.focused() + local tag = screen.tags[index] + if tag then + awful.tag.viewtoggle(tag) + end + end, + }), + awful.key({ + modifiers = { mod, shift }, + keygroup = "numrow", + description = "move focused client to tag", + group = "tags", + on_press = function(index) + if client.focus then + local tag = client.focus.screen.tags[index] + if tag then + client.focus:move_to_tag(tag) + end + end + end, + }), +}) + +-- Screen +----------- +--awful.keyboard.append_global_keybindings({ +-- No need for these (single screen setup) +--awful.key({ superkey, ctrlkey }, "j", function () awful.screen.focus_relative( 1) end, +--{description = "focus the next screen", group = "screen"}), +--awful.key({ superkey, ctrlkey }, "k", function () awful.screen.focus_relative(-1) end, +--{description = "focus the previous screen", group = "screen"}), +--}) + +--- Mouse bindings on desktop +--- ~~~~~~~~~~~~~~~~~~~~~~~~~ +local main_menu = require("ui.main-menu") +awful.mouse.append_global_mousebindings({ + --- Right click + awful.button({ + modifiers = {}, + button = 3, + on_press = function() + main_menu:toggle() + end, + }), +}) awful.mouse.append_global_mousebindings({ + --- Left click + awful.button({}, 1, function() + naughty.destroy_all_notifications() + end), - -- Left click - awful.button({}, 1, function() - naughty.destroy_all_notifications() - if mymainmenu then - mymainmenu:hide() - end - end), - - -- Middle click - awful.button({}, 2, function() - dashboard_toggle() - end), - - -- Right click - awful.button({}, 3, function() - mymainmenu:toggle() - end), - - -- Side key - awful.button({}, 4, awful.tag.viewprev), - awful.button({}, 5, awful.tag.viewnext) - + --- Middle click + awful.button({}, 2, function() + awesome.emit_signal("central_panel::toggle", awful.screen.focused()) + end), }) --- Mouse buttons on the client --------------------------------- - +--- Mouse buttons on the client +--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ client.connect_signal("request::default_mousebindings", function() - awful.mouse.append_client_mousebindings({ - awful.button({}, 1, function(c) - c:activate{context = "mouse_click"} - end), - awful.button({modkey}, 1, function(c) - c:activate{context = "mouse_click", action = "mouse_move"} - end), - awful.button({modkey}, 3, function(c) - c:activate{context = "mouse_click", action = "mouse_resize"} - end) - }) + awful.mouse.append_client_mousebindings({ + awful.button({}, 1, function(c) + c:activate({ context = "mouse_click" }) + end), + awful.button({ mod }, 1, function(c) + c:activate({ context = "mouse_click", action = "mouse_move" }) + end), + awful.button({ mod }, 3, function(c) + c:activate({ context = "mouse_click", action = "mouse_resize" }) + end), + }) end) - diff --git a/config/awesome/configuration/layout.lua b/config/awesome/configuration/layout.lua new file mode 100755 index 0000000..669f2fe --- /dev/null +++ b/config/awesome/configuration/layout.lua @@ -0,0 +1,33 @@ +local awful = require("awful") +local beautiful = require("beautiful") +local bling = require("modules.bling") +local machi = require("modules.layout-machi") +beautiful.layout_machi = machi.get_icon() + +--- 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) diff --git a/config/awesome/configuration/menu.lua b/config/awesome/configuration/menu.lua deleted file mode 100644 index c3aa50b..0000000 --- a/config/awesome/configuration/menu.lua +++ /dev/null @@ -1,96 +0,0 @@ --- Standard Awesome Library -local awful = require("awful") -local hotkeys_popup = require("awful.hotkeys_popup") -local beautiful = require("beautiful") - --- Helpers -local helpers = require("helpers") - --- Create a launcher widget and a main menu -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, - }, - } - - -- Powermenu - powermenu = { - { - "Power OFF", - function() - awful.spawn.with_shell("systemctl poweroff") - end, - }, - { - "Reboot", - function() - awful.spawn.with_shell("systemctl reboot") - end, - }, - { - "Suspend", - function() - lock_screen_show() - awful.spawn.with_shell("systemctl suspend") - end, - }, - { - "Lock Screen", - function() - lock_screen_show() - end, - }, - } - - -- Mainmenu - mymainmenu = awful.menu({ - items = { - { - "Terminal", - function() - awful.spawn.with_shell(terminal) - end, - }, - { - "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, beautiful.awesome_logo }, - { "Power Menu", powermenu }, - }, - }) -end) diff --git a/config/awesome/configuration/picom.conf b/config/awesome/configuration/picom.conf new file mode 100755 index 0000000..ecc26f6 --- /dev/null +++ b/config/awesome/configuration/picom.conf @@ -0,0 +1,135 @@ +# ░█▀█░▀█▀░█▀▀░█▀█░█▄█░░░░█▀▀░█▀█░█▀█░█▀▀ +# ░█▀▀░░█░░█░░░█░█░█░█░░░░█░░░█░█░█░█░█▀▀ +# ░▀░░░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░░▀▀▀░▀▀▀░▀░▀░▀░░ +# +# rxyhn X compositor configuration + + +# ░█▀▀░█▀█░█▀▄░█▀█░█▀▀░█▀▄░█▀▀ +# ░█░░░█░█░█▀▄░█░█░█▀▀░█▀▄░▀▀█ +# ░▀▀▀░▀▀▀░▀░▀░▀░▀░▀▀▀░▀░▀░▀▀▀ + +corner-radius = 12; +rounded-corners-exclude = [ + # "class_g ?= 'rofi'", + "class_g ?= 'peek'", + "window_type *= 'dock'", + "window_type = 'menu'", + "window_type = 'tooltip'", + # "window_type = 'popup_menu'", + "window_type = 'dropdown_menu'" +]; + + +# ░█▀▀░█░█░█▀█░█▀▄░█▀█░█░█ +# ░▀▀█░█▀█░█▀█░█░█░█░█░█▄█ +# ░▀▀▀░▀░▀░▀░▀░▀▀░░▀▀▀░▀░▀ + +shadow = true; +shadow-radius = 12; +shadow-opacity = 0.4; +shadow-offset-x = -12; +shadow-offset-y = -12; +shadow-color = "#000000"; +xinerama-shadow-crop = true; +shadow-ignore-shaped = false; +shadow-exclude = [ + "class_g = 'slop'", + "class_g ?= 'peek'", + "_NET_WM_WINDOW_TYPE@:a *= 'SPLASH'", + # "_NET_WM_WINDOW_TYPE@:a *= 'NOTIFICATION'", + # "window_type *= 'menu'", + "window_type = 'utility'", + "window_type = 'dropdown_menu'", + # "window_type = 'popup_menu'" +]; + + +# ░█▀▀░█▀█░█▀▄░▀█▀░█▀█░█▀▀ +# ░█▀▀░█▀█░█░█░░█░░█░█░█░█ +# ░▀░░░▀░▀░▀▀░░▀▀▀░▀░▀░▀▀▀ + +fading = true; +fade-in-step = 0.03; +fade-out-step = 0.03; +fade-delta = 5; + +no-fading-openclose = false +no-fading-destroyed-argb = true + +fade-exclude = [ + "class_g = 'slop'" # maim +] + + +# ░█▀█░█▀█░█▀█░█▀▀░▀█▀░▀█▀░█░█ +# ░█░█░█▀▀░█▀█░█░░░░█░░░█░░░█░ +# ░▀▀▀░▀░░░▀░▀░▀▀▀░▀▀▀░░▀░░░▀░ + +active-opacity = 1.0; +inactive-opacity = 1.0; +frame-opacity = 1.0; +inactive-dim = 0.0; + +opacity-rule = []; + +focus-exclude = [ + #"class_g ?= 'rofi'" + #'_NET_WM_NAME@:s = "rofi"' + "class_g ?= 'slop'", + "name = 'rofi'", + "class_g ?= 'Steam'", + "_NET_WM_WINDOW_TYPE@:a *= 'MENU'", + "window_type *= 'menu'", + "window_type = 'utility'", + "window_type = 'dropdown_menu'", + "window_type = 'popup_menu'" +]; + + +# ░█▀▄░█░░░█░█░█▀▄░█▀▄░▀█▀░█▀█░█▀▀ +# ░█▀▄░█░░░█░█░█▀▄░█▀▄░░█░░█░█░█░█ +# ░▀▀░░▀▀▀░▀▀▀░▀░▀░▀░▀░▀▀▀░▀░▀░▀▀▀ + +blur: { + method = "dual_kawase"; + strength = 10; + background = false; + background-frame = true; + background-fixed = true; +} + +blur-background-exclude = [ + # Exclude everything except windows of type "splash" + # (Notice the inverse condition) + "window_type != 'splash'" +]; + + +# ░█▀▀░█▀▀░█▀█░█▀▀░█▀▄░█▀█░█░░░░░█▀▀░█▀▀░▀█▀░▀█▀░▀█▀░█▀█░█▀▀░█▀▀ +# ░█░█░█▀▀░█░█░█▀▀░█▀▄░█▀█░█░░░░░▀▀█░█▀▀░░█░░░█░░░█░░█░█░█░█░▀▀█ +# ░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀░▀░▀▀▀░░░▀▀▀░▀▀▀░░▀░░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀ + +backend = "glx"; +glx-no-stencil = false; +glx-copy-from-front = false; +use-damage = true; +vsync = true; +detect-rounded-corners = true; +detect-client-leader = true; +detect-transient = true; +unredir-if-possible = true; + +wintypes: +{ + tooltip = { fade = true; full-shadow = true; focus = true; blur-background = false;}; + menu = { full-shadow = true;}; + popup_menu = { full-shadow = true;}; + utility = {full-shadow = true;}; + toolbar = {full-shadow = true;}; + normal = {full-shadow = true;}; + notification = {full-shadow = true;}; + dialog = {full-shadow = true}; + dock = {full-shadow = true;}; + dropdown_menu = { full-shadow = true;}; +}; diff --git a/config/awesome/configuration/rofi.rasi b/config/awesome/configuration/rofi.rasi new file mode 100755 index 0000000..d08c2e9 --- /dev/null +++ b/config/awesome/configuration/rofi.rasi @@ -0,0 +1,142 @@ +configuration { + font: "Roboto Medium 10"; + show-icons: true; + icon-theme: "WhiteSur-dark"; + display-drun: ""; + drun-display-format: "{icon} {name}"; + disable-history: false; + sidebar-mode: false; + click-to-exit: true; + location: 6; +} + +* { + BG: #06111599; + BGA: #061115; + FG: #D9D7D6ff; + UGT: #DF5B61ff; +} + +window { + transparency: "real"; + background-color: @BG; + text-color: @FG; + border-radius: 8px; + width: 700px; + x-offset: 0; + y-offset: -45px; +} + +prompt { + enabled: true; + background-color: @BG; + text-color: @FG; +} + +textbox-prompt-colon { + expand: false; + str: ""; + background-color: @BGA; + text-color: @FG; + padding: 10px 0px 0px 12px; + font: "Material Icons Round 16"; +} + +entry { + background-color: @BGA; + text-color: @FG; + placeholder-color: @FG; + expand: true; + horizontal-align: 0; + placeholder: "Type here to search"; + font: "Roboto Bold 12"; + blink: true; + padding: 10px; +} + +inputbar { + children: [ textbox-prompt-colon, entry ]; + spacing: 0px; + background-color: @BGA; + text-color: @FG; + expand: false; + border-radius: 8px; + position: center; +} + +case-indicator { + background-color: @BG; + text-color: @FG; + spacing: 0; +} + + +listview { + background-color: #00000000; + columns: 5; + lines: 5; + spacing: 4px; + cycle: false; + dynamic: true; + layout: vertical; +} + +mainbox { + background-color: @BG; + children: [ inputbar, listview ]; + spacing: 40px; + padding: 30px; +} + +element { + background-color: #00000000; + text-color: @FG; + orientation: vertical; + border-radius: 8px; + padding: 20px; +} + +element-icon { + background-color: inherit; + text-color: inherit; + horizontal-align: 0.5; + vertical-align: 0.5; + size: 48px; +} + +element-text { + background-color: inherit; + text-color: inherit; + expand: true; + horizontal-align: 0.5; + vertical-align: 0.5; +} + +element normal.urgent, +element alternate.urgent { + background-color: @UGT; + text-color: @FG; + border-radius: 8px; +} + +element normal.active, +element alternate.active { + background-color: @BGA; + text-color: @FG; +} + +element selected { + background-color: @BGA; + text-color: @FG; + border-radius: 8px; +} + +element selected.urgent { + background-color: @UGT; + text-color: @FG; +} + +element selected.active { + background-color: @BGA; + color: @FG; +} diff --git a/config/awesome/configuration/ruled.lua b/config/awesome/configuration/ruled.lua old mode 100644 new mode 100755 index 359674a..d76124a --- a/config/awesome/configuration/ruled.lua +++ b/config/awesome/configuration/ruled.lua @@ -1,39 +1,32 @@ --- 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 +--- 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 + --- Global ruled.client.append_rule({ id = "global", rule = {}, properties = { - focus = awful.client.focus.filter, raise = true, size_hints_honor = false, - screen = awful.screen.preferred, + honor_workarea = true, + honor_padding = true, + -- screen = awful.screen.preferred, + screen = awful.screen.focused, + focus = awful.client.focus.filter, 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 = {}, @@ -41,20 +34,14 @@ ruled.client.connect_signal("request::rules", function() callback = awful.client.setslave, }) - -- Titlebar rules + --- Titlebar rules ruled.client.append_rule({ id = "titlebars", rule_any = { class = { - "discord", "Spotify", "Org.gnome.Nautilus", - }, - type = { - "splash", - }, - name = { - "^discord.com is sharing your screen.$", -- Discord (running in browser) screen sharing popup + "Peek", }, }, properties = { @@ -62,12 +49,12 @@ ruled.client.connect_signal("request::rules", function() }, }) - -- Float + --- Float ruled.client.append_rule({ id = "floating", rule_any = { instance = { - "Devtools", -- Firefox devtools + "Devtools", --- Firefox devtools }, class = { "Lxappearance", @@ -86,10 +73,10 @@ ruled.client.connect_signal("request::rules", function() "dialog", }, }, - properties = { floating = true, placement = helpers.centered_client_placement }, + properties = { floating = true, placement = helpers.client.centered_client_placement }, }) - -- Centered + --- Centered ruled.client.append_rule({ id = "centered", rule_any = { @@ -97,19 +84,35 @@ ruled.client.connect_signal("request::rules", function() "dialog", }, class = { - -- "discord", + --- "discord", }, role = { "GtkFileChooserDialog", "conversation", }, }, - properties = { placement = helpers.centered_client_placement }, + properties = { placement = helpers.client.centered_client_placement }, }) - -- Music clients (usually a terminal running ncmpcpp) + --- Music clients (usually a terminal running ncmpcpp) + ruled.client.append_rule({ + rule_any = { + class = { + "music", + }, + instance = { + "music", + }, + }, + properties = { + floating = true, + width = screen_width * 0.40, + height = screen_height * 0.42, + placement = helpers.client.centered_client_placement, + }, + }) - -- Image viewers + --- Image viewers ruled.client.append_rule({ rule_any = { class = { @@ -126,32 +129,4 @@ ruled.client.connect_signal("request::rules", function() 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/tags.lua b/config/awesome/configuration/tags.lua new file mode 100755 index 0000000..c8f570d --- /dev/null +++ b/config/awesome/configuration/tags.lua @@ -0,0 +1,9 @@ +local awful = require("awful") + +--- Tags +--- ~~~~ + +screen.connect_signal("request::desktop_decoration", function(s) + --- Each screen has its own tag table. + awful.tag({ "1", "2", "3", "4", "5", "6" }, s, awful.layout.layouts[1]) +end) diff --git a/config/awesome/helpers.lua b/config/awesome/helpers.lua deleted file mode 100644 index 4c0034c..0000000 --- a/config/awesome/helpers.lua +++ /dev/null @@ -1,678 +0,0 @@ --- helpers.lua --- Functions that you use more than once and in different files would --- be nice to define here. -local awful = require("awful") -local gears = require("gears") -local beautiful = require("beautiful") -local xresources = require("beautiful.xresources") -local dpi = xresources.apply_dpi -local wibox = require("wibox") -local naughty = require("naughty") - -local helpers = {} - -function helpers.contains(_table, _c) - for _, c in ipairs(_table) do - if _c == c then - return true - end - end - return false -end - -function helpers.find(rule) - local function matcher(c) - return awful.rules.match(c, rule) - end - local clients = client.get() - local findex = gears.table.hasitem(clients, client.focus) or 1 - local start = gears.math.cycle(#clients, findex + 1) - - local matches = {} - for c in awful.client.iterate(matcher, start) do - matches[#matches + 1] = c - end - - return matches -end - --- Adds a maximized mask to a screen -function helpers.screen_mask(s, bg) - local mask = wibox({ - visible = false, - ontop = true, - type = "splash", - screen = s, - }) - awful.placement.maximize(mask) - mask.bg = bg - return mask -end - -function helpers.custom_shape(cr, width, height) - cr:move_to(0, height / 25) - cr:line_to(height / 25, 0) - cr:line_to(width, 0) - cr:line_to(width, height - height / 25) - cr:line_to(width - height / 25, height) - cr:line_to(0, height) - cr:close_path() -end - --- Resize gaps on the fly - -helpers.resize_gaps = function(amt) - local t = awful.screen.focused().selected_tag - t.gap = t.gap + tonumber(amt) - awful.layout.arrange(awful.screen.focused()) -end - --- Resize padding on the fly - -helpers.resize_padding = function(amt) - local s = awful.screen.focused() - local l = s.padding.left - local r = s.padding.right - local t = s.padding.top - local b = s.padding.bottom - s.padding = { - left = l + amt, - right = r + amt, - top = t + amt, - bottom = b + amt, - } - awful.layout.arrange(awful.screen.focused()) -end - --- Create rounded rectangle shape (in one line) - -helpers.rrect = function(radius) - return function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, radius) - end -end - -helpers.squircle = function(rate, delta) - return function(cr, width, height) - gears.shape.squircle(cr, width, height, rate, delta) - end -end -helpers.psquircle = function(rate, delta, tl, tr, br, bl) - return function(cr, width, height) - gears.shape.partial_squircle(cr, width, height, tl, tr, br, bl, rate, delta) - end -end - --- Create pi - -helpers.pie = function(width, height, start_angle, end_angle, radius) - return function(cr) - gears.shape.pie(cr, width, height, start_angle, end_angle, radius) - end -end - --- Create parallelogram - -helpers.prgram = function(height, base) - return function(cr, width) - gears.shape.parallelogram(cr, width, height, base) - end -end - --- Create partially rounded rect - -helpers.prrect = function(radius, tl, tr, br, bl) - return function(cr, width, height) - gears.shape.partially_rounded_rect(cr, width, height, tl, tr, br, bl, radius) - end -end - --- Create rounded bar - -helpers.rbar = function(width, height) - return function(cr) - gears.shape.rounded_bar(cr, width, height) - end -end - --- Markup helper - -function helpers.colorize_text(txt, fg) - return "" .. txt .. "" -end - -function helpers.client_menu_toggle() - local instance = nil - - return function() - if instance and instance.wibox.visible then - instance:hide() - instance = nil - else - instance = awful.menu.clients({ theme = { width = dpi(250) } }) - end - end -end - --- Escapes a string so that it can be displayed inside pango markup --- tags. Modified from: --- https://github.com/kernelsauce/turbo/blob/master/turbo/escape.lua -function helpers.pango_escape(s) - return (string.gsub(s, "[&<>]", { ["&"] = "&", ["<"] = "<", [">"] = ">" })) -end - -function helpers.vertical_pad(height) - return wibox.widget({ - forced_height = height, - layout = wibox.layout.fixed.vertical, - }) -end - -function helpers.horizontal_pad(width) - return wibox.widget({ - forced_width = width, - layout = wibox.layout.fixed.horizontal, - }) -end - --- Maximizes client and also respects gaps -function helpers.maximize(c) - c.maximized = not c.maximized - if c.maximized then - awful.placement.maximize(c, { - honor_padding = true, - honor_workarea = true, - margins = beautiful.useless_gap * 2, - }) - end - c:raise() -end - -function helpers.move_to_edge(c, direction) - -- local workarea = awful.screen.focused().workarea - -- local client_geometry = c:geometry() - if direction == "up" then - local old_x = c:geometry().x - awful.placement.top(c, { - honor_padding = true, - honor_workarea = true, - honor_padding = true, - }) - c.x = old_x - -- c:geometry({ nil, y = workarea.y + beautiful.screen_margin * 2, nil, nil }) - elseif direction == "down" then - local old_x = c:geometry().x - awful.placement.bottom(c, { - honor_padding = true, - honor_workarea = true, - honor_padding = true, - }) - c.x = old_x - -- c:geometry({ nil, y = workarea.height + workarea.y - client_geometry.height - beautiful.screen_margin * 2 - beautiful.border_width * 2, nil, nil }) - elseif direction == "left" then - local old_y = c:geometry().y - awful.placement.left(c, { - honor_padding = true, - honor_workarea = true, - honor_padding = true, - }) - c.y = old_y - -- c:geometry({ x = workarea.x + beautiful.screen_margin * 2, nil, nil, nil }) - elseif direction == "right" then - local old_y = c:geometry().y - awful.placement.right(c, { - honor_padding = true, - honor_workarea = true, - honor_padding = true, - }) - c.y = old_y - -- c:geometry({ x = workarea.width + workarea.x - client_geometry.width - beautiful.screen_margin * 2 - beautiful.border_width * 2, nil, nil, nil }) - end -end - -local double_tap_timer = nil -function helpers.single_double_tap(single_tap_function, double_tap_function) - if double_tap_timer then - double_tap_timer:stop() - double_tap_timer = nil - double_tap_function() - -- naughty.notify({text = "We got a double tap"}) - return - end - - double_tap_timer = gears.timer.start_new(0.20, function() - double_tap_timer = nil - -- naughty.notify({text = "We got a single tap"}) - if single_tap_function then - single_tap_function() - end - return false - end) -end - --- Used as a custom command in rofi to move a window into the current tag --- instead of following it. --- Rofi has access to the X window id of the client. -function helpers.rofi_move_client_here(window) - local win = function(c) - return awful.rules.match(c, { window = window }) - end - - for c in awful.client.iterate(win) do - c.minimized = false - c:move_to_tag(mouse.screen.selected_tag) - client.focus = c - c:raise() - end -end - --- Add a hover cursor to a widget by changing the cursor on --- mouse::enter and mouse::leave --- You can find the names of the available cursors by opening any --- cursor theme and looking in the "cursors folder" --- For example: "hand1" is the cursor that appears when hovering over --- links -function helpers.add_hover_cursor(w, hover_cursor) - local original_cursor = "left_ptr" - - w:connect_signal("mouse::enter", function() - local w = _G.mouse.current_wibox - if w then - w.cursor = hover_cursor - end - end) - - w:connect_signal("mouse::leave", function() - local w = _G.mouse.current_wibox - if w then - w.cursor = original_cursor - end - end) -end - --- Tag back and forth: --- If you try to focus the tag you are already at, go back to the previous tag. --- Useful for quick switching after for example checking an incoming chat --- message at tag 2 and coming back to your work at tag 1 with the same --- keypress. --- Also focuses urgent clients if they exist in the tag. This fixes the issue --- (visual mismatch) where after switching to a tag which includes an urgent --- client, the urgent client is unfocused but still covers all other windows --- (even the currently focused window). -function helpers.tag_back_and_forth(tag_index) - local s = mouse.screen - local tag = s.tags[tag_index] - if tag then - if tag == s.selected_tag then - awful.tag.history.restore() - else - tag:view_only() - end - - local urgent_clients = function(c) - return awful.rules.match(c, { urgent = true, first_tag = tag }) - end - - for c in awful.client.iterate(urgent_clients) do - client.focus = c - c:raise() - end - end -end - --- Resize DWIM (Do What I Mean) --- Resize client or factor --- Constants -- -local floating_resize_amount = dpi(20) -local tiling_resize_factor = 0.05 ---------------- -function helpers.resize_dwim(c, direction) - if awful.layout.get(mouse.screen) == awful.layout.suit.floating or (c and c.floating) then - if direction == "up" then - c:relative_move(0, 0, 0, -floating_resize_amount) - elseif direction == "down" then - c:relative_move(0, 0, 0, floating_resize_amount) - elseif direction == "left" then - c:relative_move(0, 0, -floating_resize_amount, 0) - elseif direction == "right" then - c:relative_move(0, 0, floating_resize_amount, 0) - end - else - if direction == "up" then - awful.client.incwfact(-tiling_resize_factor) - elseif direction == "down" then - awful.client.incwfact(tiling_resize_factor) - elseif direction == "left" then - awful.tag.incmwfact(-tiling_resize_factor) - elseif direction == "right" then - awful.tag.incmwfact(tiling_resize_factor) - end - end -end - --- Move client to screen edge, respecting the screen workarea -function helpers.move_to_edge(c, direction) - local workarea = awful.screen.focused().workarea - if direction == "up" then - c:geometry({ nil, y = workarea.y + beautiful.useless_gap * 2, nil, nil }) - elseif direction == "down" then - c:geometry({ - nil, - y = workarea.height - + workarea.y - - c:geometry().height - - beautiful.useless_gap * 2 - - beautiful.border_width * 2, - nil, - nil, - }) - elseif direction == "left" then - c:geometry({ x = workarea.x + beautiful.useless_gap * 2, nil, nil, nil }) - elseif direction == "right" then - c:geometry({ - x = workarea.width - + workarea.x - - c:geometry().width - - beautiful.useless_gap * 2 - - beautiful.border_width * 2, - nil, - nil, - nil, - }) - end -end - --- Move client DWIM (Do What I Mean) --- Move to edge if the client / layout is floating --- Swap by index if maximized --- Else swap client by direction -function helpers.move_client_dwim(c, direction) - if c.floating or (awful.layout.get(mouse.screen) == awful.layout.suit.floating) then - helpers.move_to_edge(c, direction) - elseif awful.layout.get(mouse.screen) == awful.layout.suit.max then - if direction == "up" or direction == "left" then - awful.client.swap.byidx(-1, c) - elseif direction == "down" or direction == "right" then - awful.client.swap.byidx(1, c) - end - else - awful.client.swap.bydirection(direction, c, nil) - end -end - --- Make client floating and snap to the desired edge -function helpers.float_and_edge_snap(c, direction) - -- if not c.floating then - -- c.floating = true - -- end - naughty.notify({ text = "double tap" }) - c.floating = true - local workarea = awful.screen.focused().workarea - if direction == "up" then - local axis = "horizontally" - local f = awful.placement.scale + awful.placement.top + (axis and awful.placement["maximize_" .. axis] or nil) - local geo = f(client.focus, { - honor_padding = true, - honor_workarea = true, - to_percent = 0.5, - }) - elseif direction == "down" then - local axis = "horizontally" - local f = awful.placement.scale - + awful.placement.bottom - + (axis and awful.placement["maximize_" .. axis] or nil) - local geo = f(client.focus, { - honor_padding = true, - honor_workarea = true, - to_percent = 0.5, - }) - elseif direction == "left" then - local axis = "vertically" - local f = awful.placement.scale + awful.placement.left + (axis and awful.placement["maximize_" .. axis] or nil) - local geo = f(client.focus, { - honor_padding = true, - honor_workarea = true, - to_percent = 0.5, - }) - elseif direction == "right" then - local axis = "vertically" - local f = awful.placement.scale + awful.placement.right + (axis and awful.placement["maximize_" .. axis] or nil) - local geo = f(client.focus, { - honor_padding = true, - honor_workarea = true, - to_percent = 0.5, - }) - end -end - --- Rounds a number to any number of decimals -function helpers.round(number, decimals) - local power = 10 ^ decimals - return math.floor(number * power) / power -end - -function helpers.fake_escape() - root.fake_input("key_press", "Escape") - root.fake_input("key_release", "Escape") -end - -function helpers.pad(size) - local str = "" - for i = 1, size do - str = str .. " " - end - local pad = wibox.widget.textbox(str) - return pad -end - -function helpers.float_and_resize(c, width, height) - c.width = width - c.height = height - awful.placement.centered(c, { honor_workarea = true, honor_padding = true }) - awful.client.property.set(c, "floating_geometry", c:geometry()) - c.floating = true - 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 --- `interval`, even if awesome restarts multiple times during this time. --- Saves output in `output_file` and checks its last modification --- time to determine whether to run the command again or not. --- Passes the output of `command` to `callback` function. -function helpers.remote_watch(command, interval, output_file, callback) - local run_the_thing = function() - -- Pass output to callback AND write it to file - awful.spawn.easy_async_with_shell(command .. " | tee " .. output_file, function(out) - callback(out) - end) - end - - local timer - timer = gears.timer({ - timeout = interval, - call_now = true, - autostart = true, - single_shot = false, - callback = function() - awful.spawn.easy_async_with_shell( - "date -r " .. output_file .. " +%s", - function(last_update, _, __, exitcode) - -- Probably the file does not exist yet (first time - -- running after reboot) - if exitcode == 1 then - run_the_thing() - return - end - - local diff = os.time() - tonumber(last_update) - if diff >= interval then - run_the_thing() - else - -- Pass the date saved in the file since it is fresh enough - awful.spawn.easy_async_with_shell("cat " .. output_file, function(out) - callback(out) - end) - - -- Schedule an update for when the remaining time to complete the interval passes - timer:stop() - gears.timer.start_new(interval - diff, function() - run_the_thing() - timer:again() - end) - end - end - ) - end, - }) -end - --- Volume Control -function helpers.volume_control(step) - local cmd - if step == 0 then - cmd = "pactl set-sink-mute @DEFAULT_SINK@ toggle" - else - sign = step > 0 and "+" or "" - cmd = "pactl set-sink-mute @DEFAULT_SINK@ 0 && pactl set-sink-volume @DEFAULT_SINK@ " - .. sign - .. tostring(step) - .. "%" - end - awful.spawn.with_shell(cmd) -end - -function helpers.music_control(state) - local cmd - if state == "toggle" then - cmd = "playerctl -p spotify,mpd play-pause" - elseif state == "prev" then - cmd = "playerctl -p spotify,mpd previous" - elseif state == "next" then - cmd = "playerctl -p spotify,mpd next" - end - 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 - -local prompt_font = beautiful.prompt_font -function helpers.prompt(action, textbox, prompt, callback) - if action == "run" then - awful.prompt.run({ - prompt = prompt, - textbox = textbox, - font = prompt_font, - done_callback = callback, - exe_callback = awful.spawn, - completion_callback = awful.completion.shell, - history_path = awful.util.get_cache_dir() .. "/history", - }) - elseif action == "web_search" then - awful.prompt.run({ - prompt = prompt, - textbox = textbox, - font = prompt_font, - history_path = awful.util.get_cache_dir() .. "/history_web", - done_callback = callback, - exe_callback = function(input) - if not input or #input == 0 then - return - end - awful.spawn.with_shell("noglob " .. web_search_cmd .. "'" .. input .. "'") - naughty.notify({ - title = "Searching the web for", - text = input, - urgency = "low", - }) - end, - }) - end -end - --- Given a `match` condition, returns an array with clients that match it, or --- just the first found client if `first_only` is true -function helpers.find_clients(match, first_only) - local matcher = function(c) - return awful.rules.match(c, match) - end - - if first_only then - for c in awful.client.iterate(matcher) do - return c - end - else - local clients = {} - for c in awful.client.iterate(matcher) do - table.insert(clients, c) - end - return clients - end - return nil -end - --- Given a `match` condition, calls the specified function `f_do` on all the --- clients that match it -function helpers.find_clients_and_do(match, f_do) - local matcher = function(c) - return awful.rules.match(c, match) - end - - for c in awful.client.iterate(matcher) do - f_do(c) - end -end - -function helpers.run_or_raise(match, move, spawn_cmd, spawn_args) - local matcher = function(c) - return awful.rules.match(c, match) - end - - -- Find and raise - local found = false - for c in awful.client.iterate(matcher) do - found = true - c.minimized = false - if move then - c:move_to_tag(mouse.screen.selected_tag) - client.focus = c - else - c:jump_to() - end - break - end - - -- Spawn if not found - if not found then - awful.spawn(spawn_cmd, spawn_args) - end -end - --- Run raise or minimize a client (scratchpad style) --- Depends on helpers.run_or_raise --- If it not running, spawn it --- If it is running, focus it --- If it is focused, minimize it -function helpers.scratchpad(match, spawn_cmd, spawn_args) - local cf = client.focus - if cf and awful.rules.match(cf, match) then - cf.minimized = true - else - helpers.run_or_raise(match, true, spawn_cmd, spawn_args) - end -end - -return helpers diff --git a/config/awesome/helpers/client.lua b/config/awesome/helpers/client.lua new file mode 100755 index 0000000..9ee7aa1 --- /dev/null +++ b/config/awesome/helpers/client.lua @@ -0,0 +1,116 @@ +local awful = require("awful") +local gears = require("gears") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local capi = { client = client, mouse = mouse } + +local _client = {} + +-- Resize client or factor +local floating_resize_amount = dpi(20) +local tiling_resize_factor = 0.05 +function _client.resize_client(c, direction) + if c and c.floating or awful.layout.get(capi.mouse.screen) == awful.layout.suit.floating then + if direction == "up" then + c:relative_move(0, 0, 0, -floating_resize_amount) + elseif direction == "down" then + c:relative_move(0, 0, 0, floating_resize_amount) + elseif direction == "left" then + c:relative_move(0, 0, -floating_resize_amount, 0) + elseif direction == "right" then + c:relative_move(0, 0, floating_resize_amount, 0) + end + elseif awful.layout.get(capi.mouse.screen) ~= awful.layout.suit.floating then + if direction == "up" then + awful.client.incwfact(-tiling_resize_factor) + elseif direction == "down" then + awful.client.incwfact(tiling_resize_factor) + elseif direction == "left" then + awful.tag.incmwfact(-tiling_resize_factor) + elseif direction == "right" then + awful.tag.incmwfact(tiling_resize_factor) + end + end +end + +-- Move client to screen edge, respecting the screen workarea +function _client.move_to_edge(c, direction) + local workarea = awful.screen.focused().workarea + if direction == "up" then + c:geometry({ nil, y = workarea.y + beautiful.useless_gap * 2, nil, nil }) + elseif direction == "down" then + c:geometry({ + nil, + y = workarea.height + + workarea.y + - c:geometry().height + - beautiful.useless_gap * 2 + - beautiful.border_width * 2, + nil, + nil, + }) + elseif direction == "left" then + c:geometry({ x = workarea.x + beautiful.useless_gap * 2, nil, nil, nil }) + elseif direction == "right" then + c:geometry({ + x = workarea.width + + workarea.x + - c:geometry().width + - beautiful.useless_gap * 2 + - beautiful.border_width * 2, + nil, + nil, + nil, + }) + end +end + +-- Move client DWIM (Do What I Mean) +-- Move to edge if the client / layout is floating +-- Swap by index if maximized +-- Else swap client by direction +function _client.move_client(c, direction) + if c.floating or (awful.layout.get(capi.mouse.screen) == awful.layout.suit.floating) then + _client.move_to_edge(c, direction) + elseif awful.layout.get(capi.mouse.screen) == awful.layout.suit.max then + if direction == "up" or direction == "left" then + awful.client.swap.byidx(-1, c) + elseif direction == "down" or direction == "right" then + awful.client.swap.byidx(1, c) + end + else + awful.client.swap.bydirection(direction, c, nil) + end +end + +function _client.centered_client_placement(c) + return gears.timer.delayed_call(function() + awful.placement.centered(c, { honor_padding = true, honor_workarea = true }) + end) +end + +-- Resize gaps on the fly +_client.resize_gaps = function(amt) + local t = awful.screen.focused().selected_tag + t.gap = t.gap + tonumber(amt) + awful.layout.arrange(awful.screen.focused()) +end + +-- Resize padding on the fly +_client.resize_padding = function(amt) + local s = awful.screen.focused() + local l = s.padding.left + local r = s.padding.right + local t = s.padding.top + local b = s.padding.bottom + s.padding = { + left = l + amt, + right = r + amt, + top = t + amt, + bottom = b + amt, + } + awful.layout.arrange(awful.screen.focused()) +end + +return _client diff --git a/config/awesome/helpers/color.lua b/config/awesome/helpers/color.lua new file mode 100755 index 0000000..ee638bb --- /dev/null +++ b/config/awesome/helpers/color.lua @@ -0,0 +1,207 @@ +local color_libary = require("modules.color") +local tonumber = tonumber +local string = string +local math = math +local type = type +local floor = math.floor +local max = math.max +local min = math.min +local pow = math.pow +local random = math.random +local abs = math.abs +local format = string.format + +local _color = {} + +local function round(x, p) + local power = 10 ^ (p or 0) + return (x * power + 0.5 - (x * power + 0.5) % 1) / power +end + +-- Returns a value that is clipped to interval edges if it falls outside the interval +local function clip(num, min_num, max_num) + return max(min(num, max_num), min_num) +end + +-- Converts the given hex color to rgba +function _color.hex_to_rgb(color) + color = color:gsub("#", "") + return { + r = tonumber("0x" .. color:sub(1, 2)), + g = tonumber("0x" .. color:sub(3, 4)), + b = tonumber("0x" .. color:sub(5, 6)), + a = #color == 8 and tonumber("0x" .. color:sub(7, 8)) or 255, + } +end + +-- Converts the given rgba color to hex +function _color.rgb_to_hex(color) + local r = clip(color.r or color[1], 0, 255) + local g = clip(color.g or color[2], 0, 255) + local b = clip(color.b or color[3], 0, 255) + local a = clip(color.a or color[4] or 255, 0, 255) + return "#" .. format("%02x%02x%02x%02x", floor(r), floor(g), floor(b), floor(a)) +end + +-- Converts the given hex color to hsv +function _color.hex_to_hsv(color) + local color = _color.hex_to_rgb(color) + local C_max = max(color.r, color.g, color.b) + local C_min = min(color.r, color.g, color.b) + local delta = C_max - C_min + local H, S, V + if delta == 0 then + H = 0 + elseif C_max == color.r then + H = 60 * (((color.g - color.b) / delta) % 6) + elseif C_max == color.g then + H = 60 * (((color.b - color.r) / delta) + 2) + elseif C_max == color.b then + H = 60 * (((color.r - color.g) / delta) + 4) + end + if C_max == 0 then + S = 0 + else + S = delta / C_max + end + V = C_max + + return { h = H, s = S * 100, v = V * 100 } +end + +--- Try to guess if a color is dark or light. +function _color.is_dark(color) + color = color_libary.color({ hex = color }) + + return color.l <= 0.4 +end + +--- Check if a color is opaque. +function _color.is_opaque(color) + color = color_libary.color({ hex = color }) + + return color.a == 0 +end + +-- Calculates the relative luminance of the given color +function _color.relative_luminance(color) + local function from_sRGB(u) + return u <= 0.0031308 and 25 * u / 323 or pow(((200 * u + 11) / 211), 12 / 5) + end + + color = color_libary.color({ hex = color }) + + return 0.2126 * from_sRGB(color.r) + 0.7152 * from_sRGB(color.g) + 0.0722 * from_sRGB(color.b) +end + +-- Calculates the contrast ratio between the two given colors +function _color.contrast_ratio(fg, bg) + return (_color.relative_luminance(fg) + 0.05) / (_color.relative_luminance(bg) + 0.05) +end + +-- Returns true if the contrast between the two given colors is suitable +function _color.is_contrast_acceptable(fg, bg) + return _color.contrast_ratio(fg, bg) >= 7 and true +end + +-- Returns a bright-ish, saturated-ish, color of random hue +function _color.rand_hex(lb_angle, ub_angle) + return color_libary.color({ + h = random(lb_angle or 0, ub_angle or 360), + s = 70, + v = 90, + }).hex +end + +-- Rotates the hue of the given hex color by the specified angle (in degrees) +function _color.rotate_hue(color, angle) + color = color_libary.color({ hex = color }) + + angle = clip(angle or 0, 0, 360) + color.h = (color.h + angle) % 360 + + return color.hex +end + +function _color.button_color(color, amount) + color = color_libary.color({ hex = color }) + + if _color.is_dark(color.hex) then + color = color + string.format("%fl", amount) + else + color = color - string.format("%fl", amount) + end + + return color.hex +end + +function _color.lighten(color, amount) + amount = amount or 0 + + color = color_libary.color({ hex = color }) + color.l = color.l + amount + + return color.hex +end + +function _color.darken(color, amount) + amount = amount or 0 + + color = color_libary.color({ hex = color }) + color.l = color.l - amount + + return color.hex +end + +-- Pywal like functions +function _color.pywal_blend(color1, color2) + color1 = color_libary.color({ hex = color1 }) + color2 = color_libary.color({ hex = color2 }) + + return color_libary.color({ + r = round(0.5 * color1.r + 0.5 * color2.r), + g = round(0.5 * color1.g + 0.5 * color2.g), + b = round(0.5 * color1.b + 0.5 * color2.b), + }).hex +end + +function _color.pywal_saturate_color(color, amount) + color = color_libary.color({ hex = color }) + + color.s = clip(amount, 0, 1) + + return color.hex +end + +function _color.pywal_alter_brightness(color, amount, sat) + sat = sat or 0 + + color = color_libary.color({ hex = color }) + + color.l = clip(color.l + amount, 0, 1) + color.s = clip(color.s + sat, 0, 1) + + return color.hex +end + +function _color.pywal_lighten(color, amount) + color = color_libary.color({ hex = color }) + + color.r = round(color.r + (255 - color.r) * amount) + color.g = round(color.g + (255 - color.g) * amount) + color.b = round(color.b + (255 - color.b) * amount) + + return color.hex +end + +function _color.pywal_darken(color, amount) + color = color_libary.color({ hex = color }) + + color.r = round(color.r * (1 - amount)) + color.g = round(color.g * (1 - amount)) + color.b = round(color.b * (1 - amount)) + + return color.hex +end + +return _color diff --git a/config/awesome/helpers/filesystem.lua b/config/awesome/helpers/filesystem.lua new file mode 100755 index 0000000..e91e253 --- /dev/null +++ b/config/awesome/helpers/filesystem.lua @@ -0,0 +1,426 @@ +local lgi = require("lgi") +local Gio = lgi.Gio +local Glib = lgi.GLib +local awful = require("awful") +local gtimer = require("gears.timer") +local tonumber = tonumber +local tostring = tostring +local ipairs = ipairs +local math = math +local os = os +local capi = { awesome = awesome } + +local _filesystem = {} + +function _filesystem.is_directory_readable_block(path) + local gfile = Gio.File.new_for_path(path) + local gfileinfo = gfile:query_info( + "standard::type,access::can-read,time::modified", + Gio.FileQueryInfoFlags.NONE + ) + return gfileinfo and gfileinfo:get_file_type() == "DIRECTORY" and + gfileinfo:get_attribute_boolean("access::can-read") +end + +function _filesystem.is_file_readable_block(path) + local gfile = Gio.File.new_for_path(path) + local gfileinfo = gfile:query_info( + "standard::type,access::can-read,time::modified", + Gio.FileQueryInfoFlags.NONE + ) + return gfileinfo and gfileinfo:get_file_type() ~= "DIRECTORY" and + gfileinfo:get_attribute_boolean("access::can-read") +end + +function _filesystem.read_file_block(path) + if _filesystem.is_file_readable_block(path) == false then + print("file '" .. path .. "' is not found or not readable...") + return nil + else + local gfile = Gio.File.new_for_path(path) + local content = gfile:load_contents() + if content == nil or content == false then + print("Failed reading " .. path) + return nil + else + return content + end + end +end + +function _filesystem.query_info(path, callback) + local gfile = Gio.File.new_for_path(path) + gfile:query_info_async( + "standard::type,access::can-read,time::modified", + Gio.FileQueryInfoFlags.NONE, Glib.PRIORITY_DEFAULT, + nil, + function(_, info_result) + local info, error = gfile:query_info_finish(info_result) + if info == nil or error ~= nil then + callback(nil) + print(error) + return + else + callback(info) + end + end, nil) +end + +function _filesystem.is_directory_readable(path, callback) + _filesystem.query_info(path, function(info) + if info ~= nil then + if info:get_file_type() == "DIRECTORY" and + info:get_attribute_boolean("access::can-read") + then + callback(true) + else + print("directory '" .. path .. "' is not found or not readable...") + callback(false) + end + else + print("info for directory '" .. path .. "' could not be retrived") + callback(false) + end + end) +end + +function _filesystem.is_file_readable(path, callback) + _filesystem.query_info(path, function(info) + if info ~= nil then + if info:get_file_type() ~= "DIRECTORY" and + info:get_attribute_boolean("access::can-read") + then + callback(true) + else + print("file '" .. path .. "' is not found or not readable...") + callback(false) + end + else + print("info for file '" .. path .. "' could not be retrived") + callback(false) + end + end) +end + +function _filesystem.make_directory(path, callback) + local gfile = Gio.File.new_for_path(path) + _filesystem.is_directory_readable(path, function(is_readable) + if is_readable then + print("directory '" .. path .. "' already exists") + callback(true) + return + else + gfile:make_directory_async(Glib.PRIORITY_DEFAULT, nil, function(file, task, c) + local result, error = gfile:make_directory_finish(task) + if result == false or error ~= nil then + print("Failed creating " .. path) + callback(false) + else + print("Successfully created " .. path) + callback(true) + end + end) + end + end) +end + +function _filesystem.save_file(path, text, callback, is_retry) + print("writing to file " .. path) + local gfile = Gio.File.new_for_path(path) + _filesystem.is_file_readable(path, function(is_readable) + if not is_readable then + if is_retry then + print("failed creating file "..path) + if callback then + callback(false) + end + return + end + print("making parent directories...") + gfile:get_parent():make_directory_with_parents() + gfile:create_readwrite_async(Gio.FileCreateFlags.NONE, Glib.PRIORITY_DEFAULT, nil, function(_, create_result) + print("file created " .. tostring(gfile:create_readwrite_finish(create_result))) + _filesystem.save_file(path, text, callback, true) + end, nil) + else + gfile:open_readwrite_async(Glib.PRIORITY_DEFAULT, nil, function(_, io_stream_result) + local io_stream = gfile:open_readwrite_finish(io_stream_result) + io_stream:seek(0, Glib.SeekType.SET, nil) + local file = io_stream:get_output_stream() + file:write_all_async(text, Glib.PRIORITY_DEFAULT, nil, function(_, write_result) + local length_written = file:write_all_finish(write_result) + print("file written " .. length_written) + file:truncate(length_written, nil) + file:close_async(Glib.PRIORITY_DEFAULT, nil, function(_, file_close_result) + print("output stream closed " .. tostring(file:close_finish(file_close_result))) + io_stream:close_async(Glib.PRIORITY_DEFAULT, nil, function(_, stream_close_result) + print("file stream closed " .. tostring(io_stream:close_finish(stream_close_result))) + if callback then + callback(true) + end + end, nil) + end, nil) + end, nil) + end, nil) + end + end) +end + +function _filesystem.read_file(path, callback) + local gfile = Gio.File.new_for_path(path) + _filesystem.is_file_readable(path, function(is_readable) + if not is_readable then + print("file '" .. path .. "' is not found or not readable...") + callback(nil) + else + gfile:load_contents_async(nil, function(file, task, c) + local content = gfile:load_contents_finish(task) + if content == nil then + print("Failed reading " .. path) + callback(nil) + else + callback(content) + end + end) + end + end) +end + +function _filesystem.read_file_uri(uri, callback) + local gfile = Gio.File.new_for_uri(uri) + gfile:load_contents_async(nil, function(file, task, c) + local content = gfile:load_contents_finish(task) + if content == nil then + print("Failed reading " .. uri) + callback(nil) + else + callback(content) + end + end) +end + +function _filesystem.delete_file(path, callback) + local gfile = Gio.File.new_for_path(path) + gfile:delete_async(Glib.PRIORITY_DEFAULT, nil, function(file, task, c) + local result, error = gfile:delete_finish(task) + if result == false or error ~= nil then + print("Failed deleting " .. tostring(error)) + if callback then + callback(false) + end + else + if callback then + callback(true) + end + end + end) +end + +function _filesystem.scan(path, callback, recursive) + if not path then + return + end + + local result = {} + + local function enumerator(path) + local gfile = Gio.File.new_for_path(path) + gfile:enumerate_children_async( + "standard::name,standard::type,access::can-read", + Gio.FileQueryInfoFlags.NONE, + 0, + nil, + function(file, task, c) + local enum, error = file:enumerate_children_finish(task) + if enum == nil or error ~= nil then + print("Failed enumrating " .. path .. " " .. tostring(error)) + callback(nil) + return + end + + enum:next_files_async(99999, 0, nil, function(file_enum, task2, c) + local files, error = file_enum:next_files_finish(task2) + if files == nil or error ~= nil then + print("Failed enumrating " .. tostring(error)) + callback(nil) + return + end + + for _, file in ipairs(files) do + local file_child = enum:get_child(file) + local file_type = file:get_file_type() + local readable = file:get_attribute_boolean("access::can-read") + if file_type == "REGULAR" and readable then + local path = file_child:get_path() + if path ~= nil then + table.insert(result, path) + end + elseif file_type == "DIRECTORY" and recursive then + enumerator(file_child:get_path()) + end + end + + enum:close_async(0, nil) + callback(result) + end) + end) + end + + enumerator(path) +end + +function _filesystem.scan_with_folders(path, callback) + if not path then + return + end + + local files_table = {} + local folders_table = {} + + local function enumerator(path) + local gfile = Gio.File.new_for_path(path) + gfile:enumerate_children_async( + "standard::name,standard::type,access::can-read", + Gio.FileQueryInfoFlags.NONE, + 0, + nil, + function(file, task, c) + local enum, error = file:enumerate_children_finish(task) + if enum == nil or error ~= nil then + print("Failed enumrating " .. path .. " " .. tostring(error)) + callback(nil) + return + end + + enum:next_files_async(99999, 0, nil, function(file_enum, task2, c) + local files, error = file_enum:next_files_finish(task2) + if files == nil or error ~= nil then + print("Failed enumrating " .. tostring(error)) + callback(nil) + return + end + + for _, file in ipairs(files) do + local file_child = enum:get_child(file) + local file_type = file:get_file_type() + local readable = file:get_attribute_boolean("access::can-read") + if file_type == "REGULAR" and readable then + local path = file_child:get_path() + if path ~= nil then + table.insert(files_table, path) + end + elseif file_type == "DIRECTORY" then + table.insert(folders_table, file_child:get_path()) + end + end + + enum:close_async(0, nil) + callback(files_table, folders_table) + end) + end) + end + + enumerator(path) +end + +function _filesystem.save_uri(path, uri, callback) + _filesystem.read_file_uri(uri, function(content) + if content == nil then + print("Failed to download file " .. uri) + callback(false) + else + _filesystem.save_file(path, content, function(result) + if result == true then + callback(true) + else + print("Failed to save " .. uri .. " to" .. path) + callback(false) + end + end) + end + end) +end + +function _filesystem.remote_watch(path, uri, interval, callback, old_content_callback) + local function download() + _filesystem.read_file_uri(uri, function(content) + callback(content) + if content ~= nil and content ~= false then + _filesystem.read_file(path, function(old_content) + if old_content ~= nil and old_content ~= false then + if old_content_callback ~= nil then + old_content_callback(old_content) + end + end + + _filesystem.save_file(path, content) + end) + end + end) + end + + _filesystem.read_file(path, function(old_content) + if old_content ~= nil and old_content ~= false then + if old_content_callback ~= nil then + old_content_callback(old_content) + end + end + + local timer + timer = gtimer + { + timeout = interval, + call_now = true, + autostart = true, + single_shot = false, + callback = function() + _filesystem.query_info(path, function(info) + if info ~= nil then + local time = info:get_modification_date_time() + local diff = math.ceil(Glib.DateTime.new_now_local():difference(time) / 1000000) + if diff >= interval then + print("Enough time has passed, redownloading " .. path) + download() + else + _filesystem.read_file(path, function(content) + if content == nil or content:gsub("%s+", "") == "" then + print("Empty file, Redownloading " .. path) + download() + else + callback(content) + end + end) + + -- Schedule an update for when the remaining time to complete the interval passes + timer:stop() + gtimer.start_new(interval - diff, function() + print("Finally! redownloading " .. path) + download() + timer:again() + end) + end + else + print(path .. " doesn't exist, downloading " .. uri) + download() + end + end) + end + } + end) +end + +function _filesystem.get_awesome_config_dir(sub_folder) + return (capi.awesome.conffile:match(".*/") or "./") .. sub_folder .. "/" +end + +function _filesystem.get_cache_dir(sub_folder) + return (os.getenv("XDG_CACHE_HOME") or os.getenv("HOME") .. "/.cache") + .. "/awesome/" .. sub_folder .. "/" +end + +function _filesystem.get_xdg_cache_home(sub_folder) + return (os.getenv("XDG_CACHE_HOME") or os.getenv("HOME") .. "/.cache") + .. "/" .. sub_folder .. "/" +end + +return _filesystem \ No newline at end of file diff --git a/config/awesome/helpers/init.lua b/config/awesome/helpers/init.lua new file mode 100755 index 0000000..9a0fbed --- /dev/null +++ b/config/awesome/helpers/init.lua @@ -0,0 +1,8 @@ +return { + client = require(... .. ".client"), + color = require(... .. ".color"), + filesystem = require(... .. ".filesystem"), + misc = require(... .. ".misc"), + run = require(... .. ".run"), + ui = require(... .. ".ui"), +} diff --git a/config/awesome/helpers/misc.lua b/config/awesome/helpers/misc.lua new file mode 100755 index 0000000..b88f832 --- /dev/null +++ b/config/awesome/helpers/misc.lua @@ -0,0 +1,105 @@ +local awful = require("awful") +local naughty = require("naughty") +local gears = require("gears") +local beautiful = require("beautiful") +local icons = require("icons") +local math = math +local os = os +local capi = { awesome = awesome, client = client } + +local _misc = {} + +-- Send key +function _misc.send_key(c, key) + awful.spawn.with_shell("xdotool key --window " .. tostring(c.window) .. " " .. key) +end + +--- Converts string representation of date (2020-06-02T11:25:27Z) to date +function _misc.parse_date(date_str) + local pattern = "(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)%Z" + local y, m, d, h, min, sec, _ = date_str:match(pattern) + + return os.time({ year = y, month = m, day = d, hour = h, min = min, sec = sec }) +end + +--- Converts seconds to "time ago" representation, like '1 hour ago' +function _misc.to_time_ago(seconds) + local days = seconds / 86400 + if days >= 1 then + days = math.floor(days) + return days .. (days == 1 and " day" or " days") .. " ago" + end + + local hours = (seconds % 86400) / 3600 + if hours >= 1 then + hours = math.floor(hours) + return hours .. (hours == 1 and " hour" or " hours") .. " ago" + end + + local minutes = ((seconds % 86400) % 3600) / 60 + if minutes >= 1 then + minutes = math.floor(minutes) + return minutes .. (minutes == 1 and " minute" or " minutes") .. " ago" + end + + return "Now" +end + +function _misc.tag_back_and_forth(tag_index) + local s = awful.screen.focused() + local tag = s.tags[tag_index] + if tag then + if tag == s.selected_tag then + awful.tag.history.restore() + else + tag:view_only() + end + + local urgent_clients = function(c) + return awful.rules.match(c, { urgent = true, first_tag = tag }) + end + + for c in awful.client.iterate(urgent_clients) do + capi.client.focus = c + c:raise() + end + end +end + +function _misc.prompt(action, textbox, prompt, callback) + if action == "run" then + awful.prompt.run({ + prompt = prompt, + -- prompt = "Run: ", + textbox = textbox, + font = beautiful.font_name .. "Regular 12", + done_callback = callback, + exe_callback = awful.spawn, + completion_callback = awful.completion.shell, + history_path = awful.util.get_cache_dir() .. "/history", + }) + elseif action == "web_search" then + awful.prompt.run({ + prompt = prompt, + -- prompt = 'Web search: ', + textbox = textbox, + font = beautiful.font_name .. "Regular 12", + history_path = awful.util.get_cache_dir() .. "/history_web", + done_callback = callback, + exe_callback = function(input) + if not input or #input == 0 then + return + end + awful.spawn.with_shell("noglob " .. "xdg-open https://www.google.com/search?q=" .. "'" .. input .. "'") + naughty.notify({ + title = "Searching the web for", + text = input, + icon = gears.color.recolor_image(icons.web_browser, beautiful.accent), + urgency = "low", + }) + end, + }) + end +end + +return _misc diff --git a/config/awesome/helpers/run.lua b/config/awesome/helpers/run.lua new file mode 100755 index 0000000..c79f251 --- /dev/null +++ b/config/awesome/helpers/run.lua @@ -0,0 +1,50 @@ +local awful = require("awful") + +local tostring = tostring +local string = string +local ipairs = ipairs +local math = math +local os = os + +local _run = {} + +function _run.run_once_pgrep(cmd) + local findme = cmd + local firstspace = cmd:find(" ") + if firstspace then + findme = cmd:sub(0, firstspace - 1) + end + awful.spawn.easy_async_with_shell(string.format("pgrep -u $USER -x %s > /dev/null || (%s)", findme, cmd)) +end + +function _run.run_once_ps(findme, cmd) + awful.spawn.easy_async_with_shell(string.format("ps -C %s|wc -l", findme), function(stdout) + if tonumber(stdout) ~= 2 then + awful.spawn(cmd, false) + end + end) +end + +function _run.run_once_grep(command) + awful.spawn.easy_async_with_shell(string.format("ps aux | grep '%s' | grep -v 'grep'", command), function(stdout) + if stdout == "" or stdout == nil then + awful.spawn(command, false) + end + end) +end + +function _run.check_if_running(command, running_callback, not_running_callback) + awful.spawn.easy_async_with_shell(string.format("ps aux | grep '%s' | grep -v 'grep'", command), function(stdout) + if stdout == "" or stdout == nil then + if not_running_callback ~= nil then + not_running_callback() + end + else + if running_callback ~= nil then + running_callback() + end + end + end) +end + +return _run diff --git a/config/awesome/helpers/ui.lua b/config/awesome/helpers/ui.lua new file mode 100755 index 0000000..2fbcb5b --- /dev/null +++ b/config/awesome/helpers/ui.lua @@ -0,0 +1,113 @@ +local awful = require("awful") +local wibox = require("wibox") +local gshape = require("gears.shape") +local gmatrix = require("gears.matrix") +local ipairs = ipairs +local table = table +local capi = { mouse = mouse } + +local _ui = {} + +function _ui.colorize_text(text, color) + return "" .. text .. "" +end + +function _ui.add_hover_cursor(w, hover_cursor) + local original_cursor = "left_ptr" + + w:connect_signal("mouse::enter", function() + local widget = capi.mouse.current_wibox + if widget then + widget.cursor = hover_cursor + end + end) + + w:connect_signal("mouse::leave", function() + local widget = capi.mouse.current_wibox + if widget then + widget.cursor = original_cursor + end + end) +end + +function _ui.vertical_pad(height) + return wibox.widget({ + forced_height = height, + layout = wibox.layout.fixed.vertical, + }) +end + +function _ui.horizontal_pad(width) + return wibox.widget({ + forced_width = width, + layout = wibox.layout.fixed.horizontal, + }) +end + +function _ui.rrect(radius) + return function(cr, width, height) + gshape.rounded_rect(cr, width, height, radius) + end +end + +function _ui.pie(width, height, start_angle, end_angle, radius) + return function(cr) + gshape.pie(cr, width, height, start_angle, end_angle, radius) + end +end + +function _ui.prgram(height, base) + return function(cr, width) + gshape.parallelogram(cr, width, height, base) + end +end + +function _ui.prrect(radius, tl, tr, br, bl) + return function(cr, width, height) + gshape.partially_rounded_rect(cr, width, height, tl, tr, br, bl, radius) + end +end + +function _ui.custom_shape(cr, width, height) + cr:move_to(0, height / 25) + cr:line_to(height / 25, 0) + cr:line_to(width, 0) + cr:line_to(width, height - height / 25) + cr:line_to(width - height / 25, height) + cr:line_to(0, height) + cr:close_path() +end + +local function _get_widget_geometry(_hierarchy, widget) + local width, height = _hierarchy:get_size() + if _hierarchy:get_widget() == widget then + -- Get the extents of this widget in the device space + local x, y, w, h = gmatrix.transform_rectangle(_hierarchy:get_matrix_to_device(), 0, 0, width, height) + return { x = x, y = y, width = w, height = h, hierarchy = _hierarchy } + end + + for _, child in ipairs(_hierarchy:get_children()) do + local ret = _get_widget_geometry(child, widget) + if ret then + return ret + end + end +end + +function _ui.get_widget_geometry(wibox, widget) + return _get_widget_geometry(wibox._drawable._widget_hierarchy, widget) +end + +function _ui.screen_mask(s, bg) + local mask = wibox({ + visible = false, + ontop = true, + type = "splash", + screen = s, + }) + awful.placement.maximize(mask) + mask.bg = bg + return mask +end + +return _ui diff --git a/config/awesome/icons/awesome-logo.svg b/config/awesome/icons/awesome-logo.svg new file mode 100755 index 0000000..19636f0 --- /dev/null +++ b/config/awesome/icons/awesome-logo.svg @@ -0,0 +1,114 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/config/awesome/icons/battery-low.svg b/config/awesome/icons/battery-low.svg new file mode 100755 index 0000000..13a4fab --- /dev/null +++ b/config/awesome/icons/battery-low.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/icons/battery.svg b/config/awesome/icons/battery.svg new file mode 100755 index 0000000..e9da375 --- /dev/null +++ b/config/awesome/icons/battery.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/icons/charging.svg b/config/awesome/icons/charging.svg new file mode 100755 index 0000000..b00c859 --- /dev/null +++ b/config/awesome/icons/charging.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/theme/assets/icons/cpu.svg b/config/awesome/icons/cpu.svg similarity index 100% rename from config/awesome/theme/assets/icons/cpu.svg rename to config/awesome/icons/cpu.svg diff --git a/config/awesome/theme/assets/icons/disk.svg b/config/awesome/icons/disk.svg similarity index 100% rename from config/awesome/theme/assets/icons/disk.svg rename to config/awesome/icons/disk.svg diff --git a/config/awesome/icons/firefox.svg b/config/awesome/icons/firefox.svg new file mode 100755 index 0000000..f33bc43 --- /dev/null +++ b/config/awesome/icons/firefox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/icons/init.lua b/config/awesome/icons/init.lua new file mode 100755 index 0000000..e364e80 --- /dev/null +++ b/config/awesome/icons/init.lua @@ -0,0 +1,20 @@ +--- Icons directory +local gfs = require("gears.filesystem") +local dir = gfs.get_configuration_dir() .. "icons/" + +return { + --- notifications + notification = dir .. "notification.svg", + notification_bell = dir .. "notification_bell.svg", + + --- system UI + ram = dir .. "ram.svg", + cpu = dir .. "cpu.svg", + temp = dir .. "temp.svg", + disk = dir .. "disk.svg", + battery = dir .. "battery.svg", + battery_low = dir .. "battery-low.svg", + charging = dir .. "charging.svg", + web_browser = dir .. "firefox.svg", + awesome_logo = dir .. "awesome-logo.svg", +} diff --git a/config/awesome/theme/assets/icons/notification.svg b/config/awesome/icons/notification.svg old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/theme/assets/icons/notification.svg rename to config/awesome/icons/notification.svg diff --git a/config/awesome/theme/assets/icons/notification_bell.svg b/config/awesome/icons/notification_bell.svg old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/theme/assets/icons/notification_bell.svg rename to config/awesome/icons/notification_bell.svg diff --git a/config/awesome/theme/assets/icons/ram.svg b/config/awesome/icons/ram.svg similarity index 100% rename from config/awesome/theme/assets/icons/ram.svg rename to config/awesome/icons/ram.svg diff --git a/config/awesome/theme/assets/icons/temp.svg b/config/awesome/icons/temp.svg similarity index 100% rename from config/awesome/theme/assets/icons/temp.svg rename to config/awesome/icons/temp.svg diff --git a/config/awesome/module/bling/helpers/icon_theme.lua b/config/awesome/module/bling/helpers/icon_theme.lua deleted file mode 100644 index 4a1db92..0000000 --- a/config/awesome/module/bling/helpers/icon_theme.lua +++ /dev/null @@ -1,134 +0,0 @@ -local Gio = require("lgi").Gio -local Gtk = require("lgi").Gtk -local gobject = require("gears.object") -local gtable = require("gears.table") -local helpers = require("helpers") -local setmetatable = setmetatable -local ipairs = ipairs - -local icon_theme = { mt = {} } - -function icon_theme:get_client_icon_path(client) - local function find_icon(class) - if self._private.client_icon_cache[class] ~= nil then - return self._private.client_icon_cache[class] - end - - for _, app in ipairs(Gio.AppInfo.get_all()) do - local id = Gio.AppInfo.get_id(app) - if id:match(helpers.misc.case_insensitive_pattern(class)) then - self._private.client_icon_cache[class] = self:get_gicon_path(Gio.AppInfo.get_icon(app)) - return self._private.client_icon_cache[class] - end - end - - return nil - end - - local class = client.class - if class == "jetbrains-studio" then - class = "android-studio" - end - - local icon = self:get_icon_path("gnome-window-manager") - - if class ~= nil then - class = class:gsub("[%-]", "%%%0") - icon = find_icon(class) or icon - - class = client.class - class = class:gsub("[%-]", "") - icon = find_icon(class) or icon - - class = client.class - class = class:gsub("[%-]", ".") - icon = find_icon(class) or icon - - class = client.class - class = class:match("(.-)-") or class - class = class:match("(.-)%.") or class - class = class:match("(.-)%s+") or class - class = class:gsub("[%-]", "%%%0") - icon = find_icon(class) or icon - end - - return icon -end - -function icon_theme:choose_icon(icons_names) - local icon_info = Gtk.IconTheme.choose_icon(self.gtk_theme, icons_names, self.icon_size, 0); - if icon_info then - local icon_path = Gtk.IconInfo.get_filename(icon_info) - if icon_path then - return icon_path - end - end - - return "" -end - - -function icon_theme:get_gicon_path(gicon) - if gicon == nil then - return "" - end - - if self._private.icon_cache[gicon] ~= nil then - return self._private.icon_cache[gicon] - end - - local icon_info = Gtk.IconTheme.lookup_by_gicon(self.gtk_theme, gicon, self.icon_size, 0); - if icon_info then - local icon_path = Gtk.IconInfo.get_filename(icon_info) - if icon_path then - self._private.icon_cache[gicon] = icon_path - return icon_path - end - end - - return "" -end - -function icon_theme:get_icon_path(icon_name) - if self._private.icon_cache[icon_name] ~= nil then - return self._private.icon_cache[icon_name] - end - - local icon_info = Gtk.IconTheme.lookup_icon(self.gtk_theme, icon_name, self.icon_size, 0); - if icon_info then - local icon_path = Gtk.IconInfo.get_filename(icon_info) - if icon_path then - self._private.icon_cache[icon_name] = icon_path - return icon_path - end - end - - return "" -end - -local function new(theme_name, icon_size) - local ret = gobject{} - gtable.crush(ret, icon_theme, true) - - ret._private = {} - ret._private.client_icon_cache = {} - ret._private.icon_cache = {} - - ret.name = theme_name or nil - ret.icon_size = icon_size or 48 - - if theme_name then - ret.gtk_theme = Gtk.IconTheme.new() - Gtk.IconTheme.set_custom_theme(ret.gtk_theme, theme_name); - else - ret.gtk_theme = Gtk.IconTheme.get_default() - end - - return ret -end - -function icon_theme.mt:__call(...) - return new(...) -end - -return setmetatable(icon_theme, icon_theme.mt) diff --git a/config/awesome/module/dock_helpers.lua b/config/awesome/module/dock_helpers.lua deleted file mode 100644 index c36b10d..0000000 --- a/config/awesome/module/dock_helpers.lua +++ /dev/null @@ -1,87 +0,0 @@ -local gears = require("gears") - ---typesafe function overloader (copied from lua-users.org) {{{ ---source: http://lua-users.org/wiki/OverloadedFunctions -local function overloaded() - local fns = {} - local mt = {} - local function oerror() - return error("Invalid argument types to overloaded function") - end - function mt:__call(...) - local arg = {...} - local default = self.default - local signature = {} - for i,arg in ipairs {...} do - signature[i] = type(arg) - end - signature = table.concat(signature, ",") - return (fns[signature] or self.default)(...) - end - function mt:__index(key) - local signature = {} - local function __newindex(self, key, value) - print(key, type(key), value, type(value)) - signature[#signature+1] = key - fns[table.concat(signature, ",")] = value - print("bind", table.concat(signature, ", ")) - end - local function __index(self, key) - print("I", key, type(key)) - signature[#signature+1] = key - return setmetatable({}, { __index = __index, __newindex = __newindex }) - end - return __index(self, key) - end - function mt:__newindex(key, value) - fns[key] = value - end - return setmetatable({ default = oerror }, mt) - end ---}}} - -local function dec_hex(IN) - local B,K,OUT,I,D=16,"0123456789ABCDEF","",0 - while IN>0 do - I=I+1 - IN,D=math.floor(IN/B),(IN%B)+1 - OUT=string.sub(K,D,D)..OUT - end - return #OUT == 2 and OUT or "0" .. OUT -end - --- color helpers {{{ -local color = {} - -color.col_shift = overloaded() -color.col_shift.string.number = function(c, s) - local r,g,b,o = gears.color.parse_color(c) - return "#" .. dec_hex(r*255+s) - .. dec_hex(g*255+s) - .. dec_hex(b*255+s) - .. dec_hex(o*255) -end -color.col_shift.string.number.number.number = function(c,sr,sg,sb) - local r,g,b,o = gears.color.parse_color(c) - return "#" .. dec_hex(r*255+sr) - .. dec_hex(g*255+sg) - .. dec_hex(b*255+sb) - .. dec_hex(o*255) -end -color.col_shift.string.number.number.number.number = function(c,sr,sg,sb,so) - local r,g,b,o = gears.color.parse_color(c) - return "#" .. dec_hex(r*255+sr) - .. dec_hex(g*255+sg) - .. dec_hex(b*255+sb) - .. dec_hex(o*255+so) -end - -color.col_diff = function(f, s) - local fr, fg, fb, fo = gears.color.parse_color(f) - local sr, sg, sb, so = gears.color.parse_color(s) - return sr-fr,sg-fg,sb-fb,so-fo -end ---}}} -return { - color = color -} diff --git a/config/awesome/module/init.lua b/config/awesome/module/init.lua deleted file mode 100644 index 330e9ff..0000000 --- a/config/awesome/module/init.lua +++ /dev/null @@ -1,12 +0,0 @@ -local gears = require("gears") -local dock = require("module.dock") -dock.init(screen.primary, 50, 5, gears.shape.rounded_rect) - -require("module.bling") -require("module.rubato") -require("module.layout-machi") -require("module.better-resize") -require("module.exit-screen") -require("module.tooltip") -require("module.savefloats") -require("module.window_switcher").enable() diff --git a/config/awesome/module/tooltip.lua b/config/awesome/module/tooltip.lua deleted file mode 100644 index 0830416..0000000 --- a/config/awesome/module/tooltip.lua +++ /dev/null @@ -1,226 +0,0 @@ -local gears = require("gears") -local awful = require("awful") -local beautiful = require("beautiful") -local wibox = require("wibox") -local helpers = require("helpers") - -local function create_boxed_widget(widget_to_be_boxed, width, height, inner_pad) - local box_container = wibox.container.background() - box_container.bg = beautiful.tooltip_widget_bg - box_container.forced_height = height - box_container.forced_width = width - box_container.shape = helpers.rrect(beautiful.tooltip_box_border_radius) - - local inner = dpi(0) - - if inner_pad then - inner = beautiful.tooltip_box_margin - end - - local boxed_widget = wibox.widget({ - -- Add margins - { - -- Add background color - { - -- The actual widget goes here - widget_to_be_boxed, - margins = inner, - widget = wibox.container.margin, - }, - widget = box_container, - }, - margins = beautiful.tooltip_gap / 2, - color = "#FF000000", - widget = wibox.container.margin, - }) - - return boxed_widget -end - --- Tooltip widgets ---------------------- - -awful.screen.connect_for_each_screen(function(s) - -- Battery - ------------- - local cute_battery_face = require("ui.widgets.cute-battery-face") - - -- Date - ---------- - local date_day = wibox.widget({ - font = beautiful.font_name .. "bold 10", - format = helpers.colorize_text("%A", beautiful.xforeground), - align = "center", - valign = "center", - widget = wibox.widget.textclock, - }) - - local date_month = wibox.widget({ - font = beautiful.font_name .. "bold 14", - format = "%d %B %Y", - align = "center", - valign = "center", - widget = wibox.widget.textclock, - }) - - local date = wibox.widget({ - date_day, - nil, - date_month, - layout = wibox.layout.align.vertical, - }) - - -- Separator - --------------- - local separator = wibox.widget({ - { - bg = beautiful.accent, - shape = helpers.rrect(dpi(5)), - forced_width = dpi(3), - widget = wibox.container.background, - }, - right = dpi(5), - widget = wibox.container.margin, - }) - - -- Analog clock - ------------------ - local analog_clock = require("ui.widgets.analog-clock") - - -- Wifi - ---------- - local wifi_status_icon = wibox.widget({ - markup = "󰤫", - font = beautiful.icon_font_name .. "14", - valign = "center", - align = "center", - widget = wibox.widget.textbox, - }) - - local wifi = wibox.widget({ - wifi_status_icon, - forced_width = dpi(30), - forced_height = dpi(30), - bg = beautiful.tooltip_bg, - shape = gears.shape.circle, - widget = wibox.container.background, - }) - - local wifi_status = false - - awesome.connect_signal("signal::network", function(status, ssid) - wifi_status = status - awesome.emit_signal("widget::network") - end) - - awesome.connect_signal("widget::network", function() - local w, fill_color - if wifi_status == true then - w = "󰤨" - fill_color = beautiful.xcolor2 - else - w = "󰤭" - fill_color = beautiful.xcolor1 - end - - wifi.shape_border_color = fill_color - wifi_status_icon.markup = helpers.colorize_text(w, fill_color) - end) - - -- UpTime - ------------ - local uptime_label = wibox.widget({ - font = beautiful.font_name .. "medium 9", - markup = helpers.colorize_text("Uptime", beautiful.accent), - valign = "center", - widget = wibox.widget.textbox, - }) - - local uptime_text = wibox.widget({ - font = beautiful.font_name .. "bold 13", - markup = helpers.colorize_text("-", beautiful.accent), - valign = "center", - widget = wibox.widget.textbox, - }) - - awesome.connect_signal("signal::uptime", function(uptime_value) - uptime_text.markup = uptime_value - end) - - local uptime_container = wibox.widget({ - separator, - { - uptime_label, - nil, - uptime_text, - layout = wibox.layout.align.vertical, - }, - { - wifi, - layout = wibox.layout.align.vertical, - }, - layout = wibox.layout.align.horizontal, - }) - - -- Widget - ------------ - local uptime_boxed = create_boxed_widget(uptime_container, dpi(170), dpi(50), true) - local analog_clock_boxed = create_boxed_widget(analog_clock, dpi(110), dpi(110), true) - - -- Tooltip setup - ------------------- - s.stats_tooltip = wibox({ - type = "dock", - screen = s, - height = beautiful.tooltip_height, - width = beautiful.tooltip_width, - bg = beautiful.transparent, - ontop = true, - visible = false, - }) - - awful.placement.top_right(s.stats_tooltip, { - margins = { - top = beautiful.useless_gap * 16, - bottom = beautiful.useless_gap * 6, - left = beautiful.useless_gap * 6, - right = beautiful.useless_gap * 6, - }, - }) - - s.stats_tooltip:setup({ - { - { - { - { - date, - { - analog_clock_boxed, - nil, - cute_battery_face, - expand = "none", - layout = wibox.layout.fixed.horizontal, - }, - layout = wibox.layout.fixed.vertical, - }, - layout = wibox.layout.fixed.horizontal, - }, - { - uptime_boxed, - layout = wibox.layout.fixed.horizontal, - }, - layout = wibox.layout.fixed.vertical, - }, - margins = beautiful.tooltip_gap, - widget = wibox.container.margin, - }, - shape = helpers.rrect(beautiful.tooltip_border_radius), - bg = beautiful.tooltip_bg, - widget = wibox.container.background, - }) -end) - -function tooltip_toggle() - local s = awful.screen.focused() - s.stats_tooltip.visible = not s.stats_tooltip.visible -end diff --git a/config/awesome/modules/animation/init.lua b/config/awesome/modules/animation/init.lua new file mode 100755 index 0000000..89ff2de --- /dev/null +++ b/config/awesome/modules/animation/init.lua @@ -0,0 +1,232 @@ +------------------------------------------- +-- @author https://github.com/Kasper24 +-- @copyright 2021-2022 Kasper24 +------------------------------------------- + +local GLib = require("lgi").GLib +local gobject = require("gears.object") +local gtable = require("gears.table") +local subscribable = require("modules.animation.subscribable") +local tween = require("modules.animation.tween") +local ipairs = ipairs +local table = table +local pairs = pairs + +local animation_manager = {} +animation_manager.easing = { + linear = "linear", + inQuad = "inQuad", + outQuad = "outQuad", + inOutQuad = "inOutQuad", + outInQuad = "outInQuad", + inCubic = "inCubic", + outCubic = "outCubic", + inOutCubic = "inOutCubic", + outInCubic = "outInCubic", + inQuart = "inQuart", + outQuart = "outQuart", + inOutQuart = "inOutQuart", + outInQuart = "outInQuart", + inQuint = "inQuint", + outQuint = "outQuint", + inOutQuint = "inOutQuint", + outInQuint = "outInQuint", + inSine = "inSine", + outSine = "outSine", + inOutSine = "inOutSine", + outInSine = "outInSine", + inExpo = "inExpo", + outExpo = "outExpo", + inOutExpo = "inOutExpo", + outInExpo = "outInExpo", + inCirc = "inCirc", + outCirc = "outCirc", + inOutCirc = "inOutCirc", + outInCirc = "outInCirc", + inElastic = "inElastic", + outElastic = "outElastic", + inOutElastic = "inOutElastic", + outInElastic = "outInElastic", + inBack = "inBack", + outBack = "outBack", + inOutBack = "inOutBack", + outInBack = "outInBack", + inBounce = "inBounce", + outBounce = "outBounce", + inOutBounce = "inOutBounce", + outInBounce = "outInBounce", +} + +local animation = {} + +local instance = nil + +local ANIMATION_FRAME_DELAY = 5 + +local function micro_to_milli(micro) + return micro / 1000 +end + +local function second_to_micro(sec) + return sec * 1000000 +end + +local function second_to_milli(sec) + return sec * 1000 +end + +function animation:start(args) + args = args or {} + + -- Awestoer/Rubbto compatibility + -- I'd rather this always be a table, but Awestoer/Rubbto + -- except the :set() method to have 1 number value parameter + -- used to set the target + local is_table = type(args) == "table" + local initial = is_table and (args.pos or self.pos) or self.pos + local subject = is_table and (args.subject or self.subject) or self.subject + local target = is_table and (args.target or self.target) or args + local duration = is_table and (args.duration or self.duration) or self.duration + local easing = is_table and (args.easing or self.easing) or self.easing + + duration = self._private.anim_manager._private.instant == true and 0.01 or duration + + if self.tween == nil or self.reset_on_stop == true then + self.tween = tween.new({ + initial = initial, + subject = subject, + target = target, + duration = second_to_micro(duration), + easing = easing, + }) + end + + if self._private.anim_manager._private.animations[self.index] == nil then + table.insert(self._private.anim_manager._private.animations, self) + end + + self.state = true + self.last_elapsed = GLib.get_monotonic_time() + + self.started:fire() + self:emit_signal("started") +end + +function animation:set(args) + self:start(args) + self:emit_signal("set") +end + +function animation:stop() + self.state = false + self:emit_signal("stopped") +end + +function animation:abort(reset) + animation:stop(reset) + self:emit_signal("aborted") +end + +function animation:initial() + return self._private.initial +end + +function animation_manager:set_instant(value) + self._private.instant = value +end + +function animation_manager:new(args) + args = args or {} + + args.pos = args.pos or 0 + args.subject = args.subject or nil + args.target = args.target or nil + args.duration = args.duration or 0 + args.easing = args.easing or nil + args.loop = args.loop or false + args.signals = args.signals or {} + args.update = args.update or nil + args.reset_on_stop = args.reset_on_stop == nil and true or args.reset_on_stop + + -- Awestoer/Rubbto compatibility + args.subscribed = args.subscribed or nil + local ret = subscribable() + ret.started = subscribable() + ret.ended = subscribable() + if args.subscribed ~= nil then + ret:subscribe(args.subscribed) + end + + for sig, sigfun in pairs(args.signals) do + ret:connect_signal(sig, sigfun) + end + if args.update ~= nil then + ret:connect_signal("update", args.update) + end + + gtable.crush(ret, args, true) + gtable.crush(ret, animation, true) + + ret._private = {} + ret._private.anim_manager = self + ret._private.initial = args.pos + + return ret +end + +local function new() + local ret = gobject({}) + gtable.crush(ret, animation_manager, true) + + ret._private = {} + ret._private.animations = {} + ret._private.instant = false + + GLib.timeout_add(GLib.PRIORITY_DEFAULT, ANIMATION_FRAME_DELAY, function() + for index, animation in ipairs(ret._private.animations) do + if animation.state == true then + -- compute delta time + local time = GLib.get_monotonic_time() + local delta = time - animation.last_elapsed + animation.last_elapsed = time + + -- If pos is true, the animation has ended + local pos = animation.tween:update(delta) + if pos == true then + -- Loop the animation, don't end it. + -- Useful for widgets like the spinning cicle + if animation.loop == true then + animation.tween:reset() + else + -- Snap to end + animation.pos = animation.tween.target + animation:fire(animation.pos) + animation:emit_signal("update", animation.pos) + + animation.state = false + animation.ended:fire(pos) + table.remove(ret._private.animations, index) + animation:emit_signal("ended", animation.pos) + end + -- Animation in process, keep updating + else + animation.pos = pos + animation:fire(animation.pos) + animation:emit_signal("update", animation.pos) + end + else + table.remove(ret._private.animations, index) + end + end + + -- call again the function after cooldown + return true + end) + + return ret +end + +if not instance then + instance = new() +end +return instance diff --git a/config/awesome/modules/animation/subscribable.lua b/config/awesome/modules/animation/subscribable.lua new file mode 100755 index 0000000..ae1b14f --- /dev/null +++ b/config/awesome/modules/animation/subscribable.lua @@ -0,0 +1,34 @@ +local gobject = require("gears.object") + +-- Kidna copying awesotre's stores on a surface level for added compatibility +local function subscribable(args) + local ret = gobject{} + local subscribed = {} + + -- Subscrubes a function to the object so that it's called when `fire` is + -- Calls subscribe_callback if it exists as well + function ret:subscribe(func) + local id = tostring(func):gsub("function: ", "") + subscribed[id] = func + + if self.subscribe_callback then self.subscribe_callback(func) end + end + + -- Unsubscribes a function and calls unsubscribe_callback if it exists + function ret:unsubscribe(func) + if not func then + subscribed = {} + else + local id = tostring(func):gsub("function: ", "") + subscribed[id] = nil + end + + if self.unsubscribe_callback then self.unsubscribe_callback(func) end + end + + function ret:fire(...) for _, func in pairs(subscribed) do func(...) end end + + return ret +end + +return subscribable diff --git a/config/awesome/modules/animation/tween.lua b/config/awesome/modules/animation/tween.lua new file mode 100755 index 0000000..42fc021 --- /dev/null +++ b/config/awesome/modules/animation/tween.lua @@ -0,0 +1,487 @@ +-- easing + +-- Adapted from https://github.com/EmmanuelOga/easing. See LICENSE.txt for credits. +-- For all easing functions: +-- t = time == how much time has to pass for the tweening to complete +-- b = begin == starting property value +-- c = change == ending - beginning +-- d = duration == running time. How much time has passed *right now* + +local gobject = require("gears.object") +local gtable = require("gears.table") + +local tween = { + _VERSION = 'tween 2.1.1', + _DESCRIPTION = 'tweening for lua', + _URL = 'https://github.com/kikito/tween.lua', + _LICENSE = [[ + MIT LICENSE + Copyright (c) 2014 Enrique García Cota, Yuichi Tateno, Emmanuel Oga + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ]] +} + +local pow, sin, cos, pi, sqrt, abs, asin = math.pow, math.sin, math.cos, math.pi, math.sqrt, math.abs, math.asin + +-- linear +local function linear(t, b, c, d) + return c * t / d + b +end + +-- quad +local function inQuad(t, b, c, d) + return c * pow(t / d, 2) + b +end +local function outQuad(t, b, c, d) + t = t / d + return -c * t * (t - 2) + b +end +local function inOutQuad(t, b, c, d) + t = t / d * 2 + if t < 1 then + return c / 2 * pow(t, 2) + b + end + return -c / 2 * ((t - 1) * (t - 3) - 1) + b +end +local function outInQuad(t, b, c, d) + if t < d / 2 then + return outQuad(t * 2, b, c / 2, d) + end + return inQuad((t * 2) - d, b + c / 2, c / 2, d) +end + +-- cubic +local function inCubic (t, b, c, d) + return c * pow(t / d, 3) + b +end +local function outCubic(t, b, c, d) + return c * (pow(t / d - 1, 3) + 1) + b +end +local function inOutCubic(t, b, c, d) + t = t / d * 2 + if t < 1 then + return c / 2 * t * t * t + b + end + t = t - 2 + return c / 2 * (t * t * t + 2) + b +end +local function outInCubic(t, b, c, d) + if t < d / 2 then + return outCubic(t * 2, b, c / 2, d) + end + return inCubic((t * 2) - d, b + c / 2, c / 2, d) +end + +-- quart +local function inQuart(t, b, c, d) + return c * pow(t / d, 4) + b +end +local function outQuart(t, b, c, d) + return -c * (pow(t / d - 1, 4) - 1) + b +end +local function inOutQuart(t, b, c, d) + t = t / d * 2 + if t < 1 then + return c / 2 * pow(t, 4) + b + end + return -c / 2 * (pow(t - 2, 4) - 2) + b +end +local function outInQuart(t, b, c, d) + if t < d / 2 then + return outQuart(t * 2, b, c / 2, d) + end + return inQuart((t * 2) - d, b + c / 2, c / 2, d) +end + +-- quint +local function inQuint(t, b, c, d) + return c * pow(t / d, 5) + b +end +local function outQuint(t, b, c, d) + return c * (pow(t / d - 1, 5) + 1) + b +end +local function inOutQuint(t, b, c, d) + t = t / d * 2 + if t < 1 then + return c / 2 * pow(t, 5) + b + end + return c / 2 * (pow(t - 2, 5) + 2) + b +end +local function outInQuint(t, b, c, d) + if t < d / 2 then + return outQuint(t * 2, b, c / 2, d) + end + return inQuint((t * 2) - d, b + c / 2, c / 2, d) +end + +-- sine +local function inSine(t, b, c, d) + return -c * cos(t / d * (pi / 2)) + c + b +end +local function outSine(t, b, c, d) + return c * sin(t / d * (pi / 2)) + b +end +local function inOutSine(t, b, c, d) + return -c / 2 * (cos(pi * t / d) - 1) + b +end +local function outInSine(t, b, c, d) + if t < d / 2 then + return outSine(t * 2, b, c / 2, d) + end + return inSine((t * 2) -d, b + c / 2, c / 2, d) +end + +-- expo +local function inExpo(t, b, c, d) + if t == 0 then + return b + end + return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001 +end +local function outExpo(t, b, c, d) + if t == d then + return b + c + end + return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b +end +local function inOutExpo(t, b, c, d) + if t == 0 then + return b end + if t == d then + return b + c + end + t = t / d * 2 + if t < 1 then + return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005 + end + return c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b +end +local function outInExpo(t, b, c, d) + if t < d / 2 then + return outExpo(t * 2, b, c / 2, d) + end + return inExpo((t * 2) - d, b + c / 2, c / 2, d) +end + +-- circ +local function inCirc(t, b, c, d) + return(-c * (sqrt(1 - pow(t / d, 2)) - 1) + b) +end +local function outCirc(t, b, c, d) + return(c * sqrt(1 - pow(t / d - 1, 2)) + b) +end +local function inOutCirc(t, b, c, d) + t = t / d * 2 + if t < 1 then + return -c / 2 * (sqrt(1 - t * t) - 1) + b + end + t = t - 2 + return c / 2 * (sqrt(1 - t * t) + 1) + b +end +local function outInCirc(t, b, c, d) + if t < d / 2 then + return outCirc(t * 2, b, c / 2, d) + end + return inCirc((t * 2) - d, b + c / 2, c / 2, d) +end + +-- elastic +local function calculatePAS(p,a,c,d) + p, a = p or d * 0.3, a or 0 + if a < abs(c) then + return p, c, p / 4 + end -- p, a, s + return p, a, p / (2 * pi) * asin(c/a) -- p,a,s +end +local function inElastic(t, b, c, d, a, p) + local s + if t == 0 then + return b + end + t = t / d + if t == 1 then + return b + c + end + p,a,s = calculatePAS(p,a,c,d) + t = t - 1 + return -(a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b +end +local function outElastic(t, b, c, d, a, p) + local s + if t == 0 then + return b + end + t = t / d + if t == 1 then + return b + c + end + p,a,s = calculatePAS(p,a,c,d) + return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b +end +local function inOutElastic(t, b, c, d, a, p) + local s + if t == 0 then + return b + end + t = t / d * 2 + if t == 2 then return b + c end + p,a,s = calculatePAS(p,a,c,d) + t = t - 1 + if t < 0 then + return -0.5 * (a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b + end + return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p ) * 0.5 + c + b +end +local function outInElastic(t, b, c, d, a, p) + if t < d / 2 then + return outElastic(t * 2, b, c / 2, d, a, p) + end + return inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p) +end + +-- back +local function inBack(t, b, c, d, s) + s = s or 1.70158 + t = t / d + return c * t * t * ((s + 1) * t - s) + b +end +local function outBack(t, b, c, d, s) + s = s or 1.70158 + t = t / d - 1 + return c * (t * t * ((s + 1) * t + s) + 1) + b +end +local function inOutBack(t, b, c, d, s) + s = (s or 1.70158) * 1.525 + t = t / d * 2 + if t < 1 then + return c / 2 * (t * t * ((s + 1) * t - s)) + b + end + t = t - 2 + return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b +end +local function outInBack(t, b, c, d, s) + if t < d / 2 then + return outBack(t * 2, b, c / 2, d, s) + end + return inBack((t * 2) - d, b + c / 2, c / 2, d, s) +end + +-- bounce +local function outBounce(t, b, c, d) + t = t / d + if t < 1 / 2.75 then + return c * (7.5625 * t * t) + b + end + if t < 2 / 2.75 then + t = t - (1.5 / 2.75) + return c * (7.5625 * t * t + 0.75) + b + elseif t < 2.5 / 2.75 then + t = t - (2.25 / 2.75) + return c * (7.5625 * t * t + 0.9375) + b + end + t = t - (2.625 / 2.75) + return c * (7.5625 * t * t + 0.984375) + b +end +local function inBounce(t, b, c, d) + return c - outBounce(d - t, 0, c, d) + b +end +local function inOutBounce(t, b, c, d) + if t < d / 2 then + return inBounce(t * 2, 0, c, d) * 0.5 + b + end + return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b +end +local function outInBounce(t, b, c, d) + if t < d / 2 then + return outBounce(t * 2, b, c / 2, d) + end + return inBounce((t * 2) - d, b + c / 2, c / 2, d) +end + +tween.easing = +{ + linear = linear, + inQuad = inQuad, outQuad = outQuad, inOutQuad = inOutQuad, outInQuad = outInQuad, + inCubic = inCubic, outCubic = outCubic, inOutCubic = inOutCubic, outInCubic = outInCubic, + inQuart = inQuart, outQuart = outQuart, inOutQuart = inOutQuart, outInQuart = outInQuart, + inQuint = inQuint, outQuint = outQuint, inOutQuint = inOutQuint, outInQuint = outInQuint, + inSine = inSine, outSine = outSine, inOutSine = inOutSine, outInSine = outInSine, + inExpo = inExpo, outExpo = outExpo, inOutExpo = inOutExpo, outInExpo = outInExpo, + inCirc = inCirc, outCirc = outCirc, inOutCirc = inOutCirc, outInCirc = outInCirc, + inElastic = inElastic, outElastic = outElastic, inOutElastic = inOutElastic, outInElastic = outInElastic, + inBack = inBack, outBack = outBack, inOutBack = inOutBack, outInBack = outInBack, + inBounce = inBounce, outBounce = outBounce, inOutBounce = inOutBounce, outInBounce = outInBounce +} + +-- Private interface +local function copyTables(destination, keysTable, valuesTable) + valuesTable = valuesTable or keysTable + local mt = getmetatable(keysTable) + if mt and getmetatable(destination) == nil then + setmetatable(destination, mt) + end + + for k,v in pairs(keysTable) do + if type(v) == 'table' then + destination[k] = copyTables({}, v, valuesTable[k]) + else + destination[k] = valuesTable[k] + end + end + return destination +end + +local function checkSubjectAndTargetRecursively(subject, target, path) + path = path or {} + local targetType, newPath + for k,targetValue in pairs(target) do + targetType, newPath = type(targetValue), copyTables({}, path) + table.insert(newPath, tostring(k)) + if targetType == 'number' then + assert(type(subject[k]) == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' is missing from subject or isn't a number") + elseif targetType == 'table' then + checkSubjectAndTargetRecursively(subject[k], targetValue, newPath) + else + assert(targetType == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' must be a number or table of numbers") + end + end +end + +local function checkNewParams(initial, duration, subject, target, easing) + -- assert(type(initial) == 'number' and duration > 0, "duration must be a positive number. Was " .. tostring(duration)) + -- assert(type(duration) == 'number' and duration > 0, "duration must be a positive number. Was " .. tostring(duration)) + assert(type(easing)=='function', "easing must be a function. Was " .. tostring(easing)) + + if subject and target then + local tsubject = type(subject) + assert(tsubject == 'table' or tsubject == 'userdata', "subject must be a table or userdata. Was " .. tostring(subject)) + assert(type(target)== 'table', "target must be a table. Was " .. tostring(target)) + checkSubjectAndTargetRecursively(subject, target) + end +end + +local function getEasingFunction(easing) + easing = easing or "linear" + if type(easing) == 'string' then + local name = easing + easing = tween.easing[name] + if type(easing) ~= 'function' then + error("The easing function name '" .. name .. "' is invalid") + end + end + return easing +end + +local function performEasingOnSubject(subject, target, initial, clock, duration, easing) + local t,b,c,d + for k,v in pairs(target) do + if type(v) == 'table' then + performEasingOnSubject(subject[k], v, initial[k], clock, duration, easing) + else + t,b,c,d = clock, initial[k], v - initial[k], duration + subject[k] = easing(t,b,c,d) + end + end +end + +local function performEasing(table, initial, target, clock, duration, easing) + if type(target) == "table" then + local t,b,c,d + for k, v in pairs(target) do + if type(v) == 'table' then + table[k] = {} + performEasing(table[k], initial[k], v, clock, duration, easing) + else + t,b,c,d = clock, initial[k], v - initial[k], duration + table[k] = easing(t,b,c,d) + end + end + + return table + else + local t, b, c, d = clock, initial, target - initial, duration + return easing(t,b,c,d) + end +end + +-- Public interface +local Tween = {} + +function Tween:set(clock) + assert(type(clock) == 'number', "clock must be a positive number or 0") + + if self.subject and self.initial == 0 then + self.initial = copyTables({}, self.target, self.subject) + end + + self.clock = clock + + if self.clock <= 0 then + self.clock = 0 + if self.subject then + copyTables(self.subject, self.initial) + end + elseif self.clock >= self.duration then -- the tween has expired + self.clock = self.duration + + if self.subject then + copyTables(self.subject, self.target) + end + else + if self.subject then + performEasingOnSubject(self.subject, self.target, self.initial, self.clock, self.duration, self.easing) + else + local pos = {} + return performEasing(pos, self.initial, self.target, self.clock, self.duration, self.easing) + end + end + + return self.clock >= self.duration +end + +function Tween:update(dt) + assert(type(dt) == 'number', "dt must be a number") + return self:set(self.clock + dt) +end + +function Tween:reset() + return self:set(0) +end + +function tween.new(args) + args = args or {} + + args.initial = args.initial or 0 + args.subject = args.subject or nil + args.target = args.target or nil + args.duration = args.duration or 0 + args.easing = args.easing or nil + + args.easing = getEasingFunction(args.easing) + checkNewParams(args.initial, args.duration, args.subject, args.target, args.easing) + + local ret = gobject{} + ret.clock = 0 + + gtable.crush(ret, args, true) + gtable.crush(ret, Tween, true) + + return ret +end + +return tween \ No newline at end of file diff --git a/config/awesome/module/dock.lua b/config/awesome/modules/awedock/init.lua old mode 100644 new mode 100755 similarity index 65% rename from config/awesome/module/dock.lua rename to config/awesome/modules/awedock/init.lua index 19e28e6..ad491dc --- a/config/awesome/module/dock.lua +++ b/config/awesome/modules/awedock/init.lua @@ -1,21 +1,97 @@ local wibox = require("wibox") local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi local awful = require("awful") local gears = require("gears") +local rubato = require(tostring(...):match(".*awedock") .. ".rubato") -local chel = require("module.dock_helpers").color -local rubato = require("module.rubato") +local function helpers() + local function overloaded() + local fns = {} + local mt = {} + local function oerror() + return error("Invalid argument types to overloaded function") + end + function mt:__call(...) + local arg = { ... } + local default = self.default + local signature = {} + for i, arg in ipairs({ ... }) do + signature[i] = type(arg) + end + signature = table.concat(signature, ",") + return (fns[signature] or self.default)(...) + end + function mt:__index(key) + local signature = {} + local function __newindex(self, key, value) + print(key, type(key), value, type(value)) + signature[#signature + 1] = key + fns[table.concat(signature, ",")] = value + print("bind", table.concat(signature, ", ")) + end + local function __index(self, key) + print("I", key, type(key)) + signature[#signature + 1] = key + return setmetatable({}, { __index = __index, __newindex = __newindex }) + end + return __index(self, key) + end + function mt:__newindex(key, value) + fns[key] = value + end + return setmetatable({ default = oerror }, mt) + end + --}}} -local dpi = beautiful.xresources.apply_dpi + local function dec_hex(IN) + local B, K, OUT, I, D = 16, "0123456789ABCDEF", "", 0 + while IN > 0 do + I = I + 1 + IN, D = math.floor(IN / B), (IN % B) + 1 + OUT = string.sub(K, D, D) .. OUT + end + return #OUT == 2 and OUT or "0" .. OUT + end -local function init(s, h, o, shape, pinneds) - --local function init(args) - --[[ if args.screen == nil then return end --- local s = args.screen --- local h = args.height or dpi(50) --- local o = args.offset or 0 --- local shape = args.shape or gears.shape.rectangle --- local pinneds = args.pinneds or nil]] + -- color helpers {{{ + local color = {} + + color.col_shift = overloaded() + color.col_shift.string.number = function(c, s) + local r, g, b, o = gears.color.parse_color(c) + return "#" .. dec_hex(r * 255 + s) .. dec_hex(g * 255 + s) .. dec_hex(b * 255 + s) .. dec_hex(o * 255) + end + color.col_shift.string.number.number.number = function(c, sr, sg, sb) + local r, g, b, o = gears.color.parse_color(c) + return "#" .. dec_hex(r * 255 + sr) .. dec_hex(g * 255 + sg) .. dec_hex(b * 255 + sb) .. dec_hex(o * 255) + end + color.col_shift.string.number.number.number.number = function(c, sr, sg, sb, so) + local r, g, b, o = gears.color.parse_color(c) + return "#" .. dec_hex(r * 255 + sr) .. dec_hex(g * 255 + sg) .. dec_hex(b * 255 + sb) .. dec_hex(o * 255 + so) + end + + color.col_diff = function(f, s) + local fr, fg, fb, fo = gears.color.parse_color(f) + local sr, sg, sb, so = gears.color.parse_color(s) + return sr - fr, sg - fg, sb - fb, so - fo + end + --}}} + return { + color = color, + } +end + +local chel = helpers().color + +--local function init(s, h, o, shape, pinneds) +local function init(args) + local s = args.screen + local h = args.height or dpi(50) + local o = args.offset or 5 + local inner_shape = args.inner_shape or gears.shape.rectangle + local outer_shape = args.outer_shape or gears.shape.rectangle + local pinneds = args.pinneds -- tasklist creation {{{ local tasklist = awful.widget.tasklist({ @@ -29,9 +105,6 @@ local function init(s, h, o, shape, pinneds) end, --sorts clients in order of their tags filter = awful.widget.tasklist.filter.alltags, forced_height = h, - style = { - shape = shape, - }, layout = { layout = wibox.layout.fixed.horizontal, }, @@ -55,8 +128,8 @@ local function init(s, h, o, shape, pinneds) forced_height = h / 10, forced_width = h / 10, id = "status", - bg = beautiful.dock_focused_bg, - shape = shape, + bg = beautiful.dock_unfocused_indicator_bg or "#484E5B", + shape = inner_shape, widget = wibox.container.background, }, widget = wibox.container.place, --so the bg widget doesnt get stretched @@ -65,8 +138,8 @@ local function init(s, h, o, shape, pinneds) }, id = "bg", widget = wibox.container.background, - bg = beautiful.dock_bg, - shape = shape, + bg = beautiful.dock_bg or "#061115", + shape = inner_shape, }, widget = wibox.container.margin, margins = h / 10, @@ -81,7 +154,7 @@ local function init(s, h, o, shape, pinneds) rate = 30, pos = p, subscribed = function(pos) - self:get_children_by_id("bg")[1].bg = chel.col_shift(beautiful.dock_bg, pos) + self:get_children_by_id("bg")[1].bg = chel.col_shift(beautiful.dock_bg or "#061115", pos) end, }) on_hover.target = t @@ -119,8 +192,8 @@ local function init(s, h, o, shape, pinneds) self:get_children_by_id("status")[1].forced_width = pos end, }) - local bg_col = beautiful.dock_focused_bg - local bg_focus_col = beautiful.dock_accent + local bg_col = beautiful.dock_unfocused_indicator_bg or "#484E5B" + local bg_focus_col = beautiful.dock_indicator_bg or "#6791C9" local sh_r, sh_g, sh_b, _ = chel.col_diff(bg_col, bg_focus_col) local status_c = rubato.timed({ @@ -182,7 +255,7 @@ local function init(s, h, o, shape, pinneds) forced_height = h / 10, forced_width = h / 10, id = "status", - shape = shape, + shape = inner_shape, widget = wibox.container.background, }, widget = wibox.container.place, --so the bg widget doesnt get stretched @@ -191,7 +264,7 @@ local function init(s, h, o, shape, pinneds) layout = wibox.layout.align.vertical, }, widget = wibox.container.background, - shape = shape, + shape = inner_shape, id = "bg", buttons = awful.button({}, 1, function() awful.spawn.easy_async(p.start_cmd) @@ -211,7 +284,7 @@ local function init(s, h, o, shape, pinneds) rate = 30, pos = po, subscribed = function(pos) - self:get_children_by_id("bg")[1].bg = chel.col_shift(beautiful.dock_bg, pos) + self:get_children_by_id("bg")[1].bg = chel.col_shift(beautiful.dock_bg or "#061115", pos) end, }) on_hover.target = t @@ -237,24 +310,20 @@ local function init(s, h, o, shape, pinneds) screen = s, x = s.geometry.x + s.geometry.width / 2, y = s.geometry.y + s.geometry.height - (h + o), - shape = shape, + shape = outer_shape, widget = { { { - { - pinned_apps, - tasklist, - layout = wibox.layout.fixed.horizontal, - }, - widget = wibox.container.margin, - margin = dpi(5), + pinned_apps, + tasklist, + layout = wibox.layout.fixed.horizontal, }, - widget = wibox.container.background, - bg = beautiful.dock_bg, - shape = shape, + widget = wibox.container.margin, + margin = dpi(5), }, - widget = wibox.container.place, - halign = "center", + widget = wibox.container.background, + bg = beautiful.dock_bg or "#061115", + shape = inner_shape, }, }) @@ -275,7 +344,7 @@ local function init(s, h, o, shape, pinneds) end, }) local autohidetimer = gears.timer({ - timeout = 1, + timeout = 2, single_shot = true, callback = function() autohideanim.target = 0 diff --git a/config/awesome/module/rubato/.editorconfig b/config/awesome/modules/awedock/rubato/.editorconfig old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/.editorconfig rename to config/awesome/modules/awedock/rubato/.editorconfig diff --git a/config/awesome/modules/awedock/rubato/.gitignore b/config/awesome/modules/awedock/rubato/.gitignore new file mode 100755 index 0000000..6e92f57 --- /dev/null +++ b/config/awesome/modules/awedock/rubato/.gitignore @@ -0,0 +1 @@ +tags diff --git a/config/awesome/module/rubato/LICENSE b/config/awesome/modules/awedock/rubato/LICENSE old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/LICENSE rename to config/awesome/modules/awedock/rubato/LICENSE diff --git a/config/awesome/module/rubato/README.md b/config/awesome/modules/awedock/rubato/README.md old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/README.md rename to config/awesome/modules/awedock/rubato/README.md diff --git a/config/awesome/module/rubato/easing.lua b/config/awesome/modules/awedock/rubato/easing.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/easing.lua rename to config/awesome/modules/awedock/rubato/easing.lua diff --git a/config/awesome/module/rubato/images/beautiful.gif b/config/awesome/modules/awedock/rubato/images/beautiful.gif old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/images/beautiful.gif rename to config/awesome/modules/awedock/rubato/images/beautiful.gif diff --git a/config/awesome/module/rubato/images/connected_graph.png b/config/awesome/modules/awedock/rubato/images/connected_graph.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/images/connected_graph.png rename to config/awesome/modules/awedock/rubato/images/connected_graph.png diff --git a/config/awesome/module/rubato/images/disconnected_graph.png b/config/awesome/modules/awedock/rubato/images/disconnected_graph.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/images/disconnected_graph.png rename to config/awesome/modules/awedock/rubato/images/disconnected_graph.png diff --git a/config/awesome/module/rubato/images/forwards_forwards_graph.png b/config/awesome/modules/awedock/rubato/images/forwards_forwards_graph.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/images/forwards_forwards_graph.png rename to config/awesome/modules/awedock/rubato/images/forwards_forwards_graph.png diff --git a/config/awesome/module/rubato/images/normal_graph.png b/config/awesome/modules/awedock/rubato/images/normal_graph.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/images/normal_graph.png rename to config/awesome/modules/awedock/rubato/images/normal_graph.png diff --git a/config/awesome/module/rubato/images/quadratic_easing.gif b/config/awesome/modules/awedock/rubato/images/quadratic_easing.gif old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/images/quadratic_easing.gif rename to config/awesome/modules/awedock/rubato/images/quadratic_easing.gif diff --git a/config/awesome/module/rubato/images/slope_graph.png b/config/awesome/modules/awedock/rubato/images/slope_graph.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/images/slope_graph.png rename to config/awesome/modules/awedock/rubato/images/slope_graph.png diff --git a/config/awesome/module/rubato/images/trapezoid_easing.gif b/config/awesome/modules/awedock/rubato/images/trapezoid_easing.gif old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/images/trapezoid_easing.gif rename to config/awesome/modules/awedock/rubato/images/trapezoid_easing.gif diff --git a/config/awesome/module/rubato/images/triangleish.png b/config/awesome/modules/awedock/rubato/images/triangleish.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/images/triangleish.png rename to config/awesome/modules/awedock/rubato/images/triangleish.png diff --git a/config/awesome/module/rubato/init.lua b/config/awesome/modules/awedock/rubato/init.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/init.lua rename to config/awesome/modules/awedock/rubato/init.lua diff --git a/config/awesome/module/rubato/rubato-1.1-1.rockspec b/config/awesome/modules/awedock/rubato/rubato-1.1-1.rockspec old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/rubato-1.1-1.rockspec rename to config/awesome/modules/awedock/rubato/rubato-1.1-1.rockspec diff --git a/config/awesome/module/rubato/subscribable.lua b/config/awesome/modules/awedock/rubato/subscribable.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/rubato/subscribable.lua rename to config/awesome/modules/awedock/rubato/subscribable.lua diff --git a/config/awesome/module/rubato/timed.lua b/config/awesome/modules/awedock/rubato/timed.lua old mode 100644 new mode 100755 similarity index 98% rename from config/awesome/module/rubato/timed.lua rename to config/awesome/modules/awedock/rubato/timed.lua index 5d14735..b3b92c8 --- a/config/awesome/module/rubato/timed.lua +++ b/config/awesome/modules/awedock/rubato/timed.lua @@ -195,10 +195,10 @@ local function timed(args) timer:stop() --stops itself --run subscribed in functions - obj:fire(obj.pos, time, dx) + obj:fire(obj.pos, obj.duration, dx) -- awestore compatibility... - if obj.awestore_compat then obj.ended:fire(obj.pos, time, dx) end + if obj.awestore_compat then obj.ended:fire(obj.pos, obj.duration, dx) end --otherwise it just fires normally else obj:fire(obj.pos, time, dx) end diff --git a/config/awesome/modules/battery_widget/.gitignore b/config/awesome/modules/battery_widget/.gitignore new file mode 100755 index 0000000..a2e6bd4 --- /dev/null +++ b/config/awesome/modules/battery_widget/.gitignore @@ -0,0 +1 @@ +doc/ diff --git a/config/awesome/modules/battery_widget/README.md b/config/awesome/modules/battery_widget/README.md new file mode 100755 index 0000000..67b6a2d --- /dev/null +++ b/config/awesome/modules/battery_widget/README.md @@ -0,0 +1,84 @@ +# UPower Battery Widget + +This is my re-implementation of the [awesome-upower-battery][awesome-upower-battery-repository] by [berlam][berlam]. This widget has a lot of potencial for the [Awesome WM][AwesomeWM] and I wanted to hack it a bit for my personal use. + +UPower is an abstraction for power devices. You can use it to access advanced statistics about your power devices. +UPowerGlib is a Glib interface to access data exposed by UPower. +The Awesome WM uses LGI as an interpolation layer for Glib with Lua. So, you can access the UPowerGlib interface directly from your lua code. + +Thanks to this, we can write battery widget relaying on realtime data pushed from the UPower daemon itself. So the battery widget as no charge on the system (no need to pull data every X seconds) and provides more accurate data to the user. + +## Usage + +When creating an instance of this widget, you can specify the `widget_template` you want to use and how the widget updates. It gives you the control on how the widget should display the battery status. + +You can generate the API documentation with [ldoc][ldoc]. + +```sh +ldoc -c config.ld init.lua +``` + +Here is an example of implementation using a [`wibox.widget.textbox`][awesome-api-wibox.widget.textbox] widget to display the battery percentage: + +```lua +-- Load the module: +local battery_widget = require 'battery_widget' + +-- Create the battery widget: +local my_battery_widget = battery_widget { + screen = screen, + use_display_device = true, + widget_template = wibox.widget.textbox +} + +-- When UPower updates the battery status, the widget is notified +-- and calls a signal you need to connect to: +my_battery_widget:connect_signal('upower::update', function (widget, device) + widget.text = string.format('%3d', device.percentage) .. '%' +end) +``` + +### Using different devices + +With the parameter `use_display_device = true`, the battery widget will automatically monitor the _display device_. + +If you want to manually set which device to monitor, you can use the `device_path` parameter. + +```lua +local my_battery_widget = battery_widget{ + screen = s, + device_path = '/org/freedesktop/UPower/devices/battery_BAT0', + widget_template = wibox.widget.textbox +} +``` + +You can check the API documentation to read more about statics function to help you to identify your devices. + +### Battery widget not appearing + +When creating a new instance of `battery_widget`, the widget will not be shown. The widget waits an update from UPower to call the "upower::update" signal and use your attached callback to update (and draw) the widget. + +You can however use one of the following method to force the widget to be drawn at its creation: + +* Use the parameter `instant_update` to explicitly ask the battery_widget to call the "upower::update" signal at the next Awesome WM cycle. +* Use the parameter `create_callback` to use your own code to initialize the widget. (This callback await the same arguments than the "upower::update" signal) + +You can read more about these parameters in the API documentation. + +## Dependencies + +* [Awesome WM][AwesomeWM] +* [UPower][UPower] +* [UPowerGlib][UPowerGlib] + +## Acknowledgment + +Thanks a lot to [berlam][berlam] for the initial code and the idea to use the UPowerGlib interface 🚀. + +[awesome-upower-battery-repository]: https://github.com/berlam/awesome-upower-battery +[berlam]: https://github.com/berlam +[AwesomeWM]: https://awesomewm.org/ +[awesome-api-wibox.widget.textbox]: https://awesomewm.org/apidoc/widgets/wibox.widget.textbox.html +[UPower]: https://upower.freedesktop.org/ +[UPowerGlib]: https://lazka.github.io/pgi-docs/UPowerGlib-1.0/index.html +[ldoc]: https://stevedonovan.github.io/ldoc/ diff --git a/config/awesome/modules/battery_widget/config.ld b/config/awesome/modules/battery_widget/config.ld new file mode 100755 index 0000000..5b863a0 --- /dev/null +++ b/config/awesome/modules/battery_widget/config.ld @@ -0,0 +1,24 @@ +-- Configuration file for ldoc + +project = 'battery_widget' +title = 'Awesome WM - Battery Widget' + +all = false +dir = 'doc' +format='markdown' +pretty = 'lua' +prettify_files = true +backtick_references = true +merge = true +use_markdown_titles = true +wrap = true +sort_modules = true +not_luadoc = true + + +-- Define some new ldoc tags from the AwesomeWM doc +new_type("staticfct", "Static functions", false, "Parameters") +new_type("constructorfct", "Constructor", false, "Parameters") +new_type("method", "Object methods", false, "Parameters") +new_type("property", "Object properties", false, "Type") +new_type("signal", "Signals", false, "Arguments") diff --git a/config/awesome/modules/battery_widget/init.lua b/config/awesome/modules/battery_widget/init.lua new file mode 100755 index 0000000..a001d4f --- /dev/null +++ b/config/awesome/modules/battery_widget/init.lua @@ -0,0 +1,140 @@ +--------------------------------------------------------------------------- +-- A battery widget based on the UPower deamon. +-- +-- @author Aire-One +-- @copyright 2020 Aire-One +--------------------------------------------------------------------------- + +local upower = require('lgi').require('UPowerGlib') + +local gtable = require 'gears.table' +local gtimer = require 'gears.timer' +local wbase = require 'wibox.widget.base' + +local setmetatable = setmetatable -- luacheck: ignore setmetatable + +local battery_widget = {} +local mt = {} + + +--- Helper to get the path of all connected power devices. +-- @treturn table The list of all power devices path. +-- @staticfct battery_widget.list_devices +function battery_widget.list_devices() + local ret = {} + local devices = upower.Client():get_devices() + + for _,d in ipairs(devices) do + table.insert(ret, d:get_object_path()) + end + + return ret +end + +--- Helper function to get a device instance from its path. +-- @tparam string path The path of the device to get. +-- @treturn UPowerGlib.Device|nil The device if it was found, `nil` otherwise. +-- @staticfct battery_widget.get_device +function battery_widget.get_device(path) + local devices = upower.Client():get_devices() + + for _,d in ipairs(devices) do + if d:get_object_path() == path then + return d + end + end + + return nil +end + +--- Helper function to easily get the default BAT0 device path without. +-- @treturn string The BAT0 device path. +-- @staticfct battery_widget.get_BAT0_device_path +function battery_widget.get_BAT0_device_path() + local bat0_path = '/org/freedesktop/UPower/devices/battery_BAT0' + return bat0_path +end + +--- Helper function to convert seconds into a human readable clock string. +-- +-- This translates the given seconds parameter into a human readable string +-- following the notation `HH:MM` (where HH is the number of hours and MM the +-- number of minutes). +-- @tparam number seconds The umber of seconds to translate. +-- @treturn string The human readable generated clock string. +-- @staticfct battery_widget.to_clock +function battery_widget.to_clock(seconds) + if seconds <= 0 then + return '00:00'; + else + local hours = string.format('%02.f', math.floor(seconds/3600)); + local mins = string.format('%02.f', math.floor(seconds/60 - hours*60)); + return hours .. ':' .. mins + end +end + + +--- Gives the default widget to use if user didn't specify one. +-- The default widget used is an `empty_widget` instance. +-- @treturn widget The default widget to use. +local function default_template () + return wbase.empty_widget() +end + + +--- The device monitored by the widget. +-- @property device +-- @tparam UPowerGlib.Device device + +--- Emited when the UPower device notify an update. +-- @signal upower::update +-- @tparam battery_widget widget The widget. +-- @tparam UPowerGlib.Device device The Upower device. + + +--- battery_widget constructor. +-- +-- This function creates a new `battery_widget` instance. This widget watches +-- the `display_device` status and report. +-- @tparam table args The arguments table. +-- @tparam[opt] widget args.widget_template The widget template to use to +-- create the widget instance. +-- @tparam[opt] string args.device_path Path of the device to monitor. +-- @tparam[opt=false] boolean args.use_display_device Should the widget monitor +-- the _display device_? +-- @tparam[opt] boolean args.instant_update Call an update cycle right after the +-- widget creation. +-- @treturn battery_widget The battery_widget instance build. +-- @constructorfct battery_widget.new +function battery_widget.new (args) + args = gtable.crush({ + widget_template = default_template(), + device_path = '', + use_display_device = false + }, args or {}) + + local widget = wbase.make_widget_from_value(args.widget_template) + + widget.device = args.use_display_device + and upower.Client():get_display_device() + or battery_widget.get_device(args.device_path) + + -- Attach signals: + widget.device.on_notify = function (d) + widget:emit_signal('upower::update', d) + end + + -- Call an update cycle if the user asked to instan update the widget. + if args.instant_update then + gtimer.delayed_call(widget.emit_signal, widget, 'upower::update', widget.device) + end + + return widget +end + + +function mt.__call(self, ...) + return battery_widget.new(...) +end + +return setmetatable(battery_widget, mt) diff --git a/config/awesome/module/better-resize.lua b/config/awesome/modules/better-resize.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/better-resize.lua rename to config/awesome/modules/better-resize.lua diff --git a/config/awesome/module/bling/.editorconfig b/config/awesome/modules/bling/.editorconfig old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/.editorconfig rename to config/awesome/modules/bling/.editorconfig diff --git a/config/awesome/module/bling/AUTHORS.md b/config/awesome/modules/bling/AUTHORS.md old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/AUTHORS.md rename to config/awesome/modules/bling/AUTHORS.md diff --git a/config/awesome/module/bling/CODEOWNERS b/config/awesome/modules/bling/CODEOWNERS old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/CODEOWNERS rename to config/awesome/modules/bling/CODEOWNERS diff --git a/config/awesome/module/bling/LICENSE b/config/awesome/modules/bling/LICENSE old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/LICENSE rename to config/awesome/modules/bling/LICENSE diff --git a/config/awesome/module/bling/README.md b/config/awesome/modules/bling/README.md old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/README.md rename to config/awesome/modules/bling/README.md diff --git a/config/awesome/module/bling/bling-dev-1.rockspec b/config/awesome/modules/bling/bling-dev-1.rockspec old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/bling-dev-1.rockspec rename to config/awesome/modules/bling/bling-dev-1.rockspec diff --git a/config/awesome/modules/bling/docs/.nojekyll b/config/awesome/modules/bling/docs/.nojekyll new file mode 100755 index 0000000..e69de29 diff --git a/config/awesome/modules/bling/docs/_sidebar.md b/config/awesome/modules/bling/docs/_sidebar.md new file mode 100755 index 0000000..9216d34 --- /dev/null +++ b/config/awesome/modules/bling/docs/_sidebar.md @@ -0,0 +1,23 @@ +- [Home](home.md) + +- [Layouts](layouts/layout.md) + +- Modules + - [Flash Focus](module/flash.md) + - [Tabbed](module/tabbed.md) + - [Tiled Wallpaper](module/twall.md) + - [Wallpaper Easy Setup](module/wall.md) + - [Window Swallowing](module/swal.md) + - [Scratchpad](module/scratch.md) + +- Signals + - [Playerctl](signals/pctl.md) + +- Widgets + - [Tag Preview](widgets/tag_preview.md) + - [Task Preview](widgets/task_preview.md) + - [Tabbed Misc](widgets/tabbed_misc.md) + - [Window Switcher](widgets/window_switcher.md) + +- Extra + - [Theme Variable Template](theme.md) diff --git a/config/awesome/modules/bling/docs/home.md b/config/awesome/modules/bling/docs/home.md new file mode 100755 index 0000000..6a35a11 --- /dev/null +++ b/config/awesome/modules/bling/docs/home.md @@ -0,0 +1,34 @@ +#
🌟 Bling - Utilities for AwesomeWM 🌟
+ +## Why + +[AwesomeWM](https://awesomewm.org/) is literally what it stands for, an awesome window manager. + +Its unique selling point has always been the widget system, which allows for fancy buttons, sliders, bars, dashboards and anything you can imagine. But that feature can be a curse. Most modules focus on the widget side of things which leave the actual window managing part of AwesomeWM underdeveloped compared to, for example, [xmonad](https://xmonad.org/) even though it's probably just as powerfull in that area. + +This project focuses on that problem - adding new layouts and modules that make use of the widget system, but primarily focus on the new window managing features. + +## Installation +- clone this repo into your `~/.config/awesome` folder + - `git clone https://github.com/BlingCorp/bling.git ~/.config/awesome/bling` +- require the module in your `rc.lua`, and make sure it's under the beautiful module initialization + +```lua +-- other imports + +local beautiful = require("beautiful") + +-- other configuration stuff here + +beautiful.init("some_theme.lua") +local bling = require("bling") +``` + +## Contributors +A special thanks to all our contributors... + + + + + +Made with [contributors-img](https://contrib.rocks). diff --git a/config/awesome/modules/bling/docs/index.html b/config/awesome/modules/bling/docs/index.html new file mode 100755 index 0000000..ea8d732 --- /dev/null +++ b/config/awesome/modules/bling/docs/index.html @@ -0,0 +1,28 @@ + + + + + Bling Docs + + + + + + + +
+ + + + + + diff --git a/config/awesome/modules/bling/docs/javacafe.css b/config/awesome/modules/bling/docs/javacafe.css new file mode 100755 index 0000000..18962da --- /dev/null +++ b/config/awesome/modules/bling/docs/javacafe.css @@ -0,0 +1,1069 @@ +@import url("https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600"); + +* { + -webkit-font-smoothing: antialiased; + -webkit-overflow-scrolling: touch; + -webkit-tap-highlight-color: #ffffff; + -webkit-text-size-adjust: none; + -webkit-touch-callout: none; + box-sizing: border-box; +} + +body:not(.ready) { + overflow: hidden; +} + +body:not(.ready) [data-cloak], +body:not(.ready) .app-nav, +body:not(.ready) > nav { + display: none; +} + +::-webkit-scrollbar, +::-webkit-scrollbar-track, +::-webkit-scrollbar-track-piece { + background: transparent !important; + -webkit-box-shadow: none !important; + -moz-box-shadow: none !important; + box-shadow: none !important; + border: none !important; + width: 8px !important; +} +::-webkit-scrollbar-thumb { + background:#29343d !important; + width:8px !important; + border: none !important; + border-radius: 2px !important; +} + + +div#app { + font-size: 30px; + font-weight: lighter; + margin: 40vh auto; + text-align: center; +} + +div#app:empty::before { + content: 'Loading...'; +} + +.emoji { + height: 1.2rem; + vertical-align: middle; +} + +.progress { + background-color: var(--theme-color, #7ed491); + height: 2px; + left: 0px; + position: fixed; + right: 0px; + top: 0px; + transition: width 0.2s, opacity 0.4s; + width: 0%; + z-index: 999999; +} + +.search a:hover { + color: var(--theme-color, #7ed491); +} + +.search .search-keyword { + color: var(--theme-color, #7ed491); + font-style: normal; + font-weight: bold; +} + +html, +body { + height: 100%; +} + +body { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + color: #34495e; + font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; + font-size: 15px; + letter-spacing: 0; + margin: 0; + overflow-x: hidden; +} + +img { + max-width: 65%; +} + +a[disabled] { + cursor: not-allowed; + opacity: 0.6; +} + +kbd { + border: solid 1px #ccc; + border-radius: 3px; + display: inline-block; + font-size: 12px !important; + line-height: 12px; + margin-bottom: 3px; + padding: 3px 5px; + vertical-align: middle; +} + +li input[type='checkbox'] { + margin: 0 0.2em 0.25em 0; + vertical-align: middle; +} + +.app-nav { + margin: 25px 60px 0 0; + position: absolute; + right: 0; + text-align: right; + z-index: 10; +/* navbar dropdown */ +} + +.app-nav.no-badge { + margin-right: 25px; +} + +.app-nav p { + margin: 0; +} + +.app-nav > a { + margin: 0 1rem; + padding: 5px 0; +} + +.app-nav ul, +.app-nav li { + display: inline-block; + list-style: none; + margin: 0; +} + +.app-nav a { + color: inherit; + font-size: 16px; + text-decoration: none; + transition: color 0.3s; +} + +.app-nav a:hover { + color: var(--theme-color, #7ed491); +} + +.app-nav a.active { + border-bottom: 2px solid var(--theme-color, #7ed491); + color: var(--theme-color, #7ed491); +} + +.app-nav li { + display: inline-block; + margin: 0 1rem; + padding: 5px 0; + position: relative; + cursor: pointer; +} + +.app-nav li ul { + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: #ccc; + border-radius: 4px; + box-sizing: border-box; + display: none; + max-height: calc(100vh - 61px); + overflow-y: auto; + padding: 10px 0; + position: absolute; + right: -15px; + text-align: left; + top: 100%; + white-space: nowrap; +} + +.app-nav li ul li { + display: block; + font-size: 14px; + line-height: 1rem; + margin: 0; + margin: 8px 14px; + white-space: nowrap; +} + +.app-nav li ul a { + display: block; + font-size: inherit; + margin: 0; + padding: 0; +} + +.app-nav li ul a.active { + border-bottom: 0; +} + +.app-nav li:hover ul { + display: block; +} + +.github-corner { + border-bottom: 0; + position: fixed; + right: 0; + text-decoration: none; + top: 0; + z-index: 1; +} + +.github-corner:hover .octo-arm { + -webkit-animation: octocat-wave 560ms ease-in-out; + animation: octocat-wave 560ms ease-in-out; +} + +.github-corner svg { + color: #fff; + fill: var(--theme-color, #7ed491); + height: 80px; + width: 80px; +} + +main { + display: block; + position: relative; + width: 100vw; + height: 100%; + z-index: 0; +} + +main.hidden { + display: none; +} + +.anchor { + display: inline-block; + text-decoration: none; + transition: all 0.3s; +} + +.anchor span { + color: #FFFFFF; +} + +.anchor:hover { + text-decoration: underline; +} + +.sidebar { + border-right: 1px solid rgba(0,0,0,0.07); + overflow-y: auto; + padding: 40px 0 0; + position: absolute; + top: 0; + bottom: 0; + left: 0; + transition: transform 250ms ease-out; + width: 300px; + z-index: 20; +} + +.sidebar > h1 { + margin: 0 auto 1rem; + font-size: 1.5rem; + font-weight: 300; + text-align: center; +} + +.sidebar > h1 a { + color: inherit; + text-decoration: none; +} + +.sidebar > h1 .app-nav { + display: block; + position: static; +} + +.sidebar .sidebar-nav { + line-height: 2em; + padding-bottom: 40px; +} + +.sidebar li.collapse .app-sub-sidebar { + display: none; +} + +.sidebar ul { + margin: 0 0 0 15px; + padding: 0; +} + +.sidebar li > p { + font-weight: 700; + margin: 0; +} + +.sidebar ul, +.sidebar ul li { + list-style: none; +} + +.sidebar ul li a { + border-bottom: none; + display: block; +} + +.sidebar ul li ul { + padding-left: 20px; +} + +.sidebar::-webkit-scrollbar { + width: 4px; +} + +.sidebar::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 4px; +} + +.sidebar:hover::-webkit-scrollbar-thumb { + background: rgba(136,136,136,0.4); +} + +.sidebar:hover::-webkit-scrollbar-track { + background: rgba(136,136,136,0.1); +} + +.sidebar-toggle { + background-color: transparent; + background-color: #1a2026; + border: 0; + outline: none; + padding: 10px; + position: absolute; + bottom: 0; + left: 0; + text-align: center; + transition: opacity 0.3s; + width: 284px; + z-index: 30; + cursor: pointer; +} + +.sidebar-toggle:hover .sidebar-toggle-button { + opacity: 0.4; +} + +.sidebar-toggle span { + background-color: var(--theme-color, #7ed491); + display: block; + margin-bottom: 4px; + width: 16px; + height: 2px; +} + +body.sticky .sidebar, +body.sticky .sidebar-toggle { + position: fixed; +} + +.content { + padding-top: 60px; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 300px; + transition: left 250ms ease; +} + +.markdown-section { + margin: 0 auto; + max-width: 80%; + padding: 30px 15px 40px 15px; + position: relative; +} + +.markdown-section > * { + box-sizing: border-box; + font-size: inherit; +} + +.markdown-section > :first-child { + margin-top: 0 !important; +} + +.markdown-section hr { + border: none; + border-bottom: 1px solid #eee; + margin: 2em 0; +} + +.markdown-section iframe { + border: 1px solid #eee; +/* fix horizontal overflow on iOS Safari */ + width: 1px; + min-width: 100%; +} + +.markdown-section table { + border-collapse: collapse; + border-spacing: 0; + display: block; + margin-bottom: 1rem; + overflow: auto; + width: 100%; +} + +.markdown-section th { + border: 1px solid #29343d; + color: #9fb4c4; + background-color: #13181c; + font-weight: bold; + padding: 6px 13px; +} + +.markdown-section td { + border: 1px solid #29343d; + color: #9fb4c4; + background-color: #13181c; + padding: 6px 13px; +} + +.markdown-section tr { + border-top: 1px solid #303436; +} + +.markdown-section tr:nth-child(2n) { + background-color: #FFFFFF; +} + +.markdown-section p.tip { + background-color: #f8f8f8; + border-bottom-right-radius: 2px; + border-left: 4px solid #f66; + border-top-right-radius: 2px; + margin: 2em 0; + padding: 12px 24px 12px 30px; + position: relative; +} + +.markdown-section p.tip:before { + background-color: #f66; + border-radius: 100%; + color: #fff; + content: '!'; + font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; + font-size: 14px; + font-weight: bold; + left: -12px; + line-height: 20px; + position: absolute; + height: 20px; + width: 20px; + text-align: center; + top: 14px; +} + +.markdown-section p.tip code { + background-color: #eaeaea; +} + +.markdown-section p.tip em { + color: #eaeaea; +} + +.markdown-section p.warn { + background: #eaeaea; + border-radius: 2px; + padding: 1rem; +} + +.markdown-section ul.task-list > li { + list-style-type: none; +} + +body.close .sidebar { + transform: translateX(-300px); +} + +body.close .sidebar-toggle { + width: auto; +} + +body.close .content { + left: 0; +} + +@media print { + .github-corner, + .sidebar-toggle, + .sidebar, + .app-nav { + display: none; + } +} + +@media screen and (max-width: 768px) { + .github-corner, + .sidebar-toggle, + .sidebar { + position: fixed; + } + + .app-nav { + margin-top: 16px; + } + + .app-nav li ul { + top: 30px; + } + + main { + height: auto; + overflow-x: hidden; + } + + .sidebar { + left: -300px; + transition: transform 250ms ease-out; + } + + .content { + left: 0; + max-width: 100vw; + position: static; + padding-top: 20px; + transition: transform 250ms ease; + } + + .app-nav, + .github-corner { + transition: transform 250ms ease-out; + } + + .sidebar-toggle { + background-color: transparent; + width: auto; + padding: 30px 30px 10px 10px; + } + + body.close .sidebar { + transform: translateX(300px); + } + + body.close .sidebar-toggle { + background-color: rgba(255,255,255,0.8); + transition: 1s background-color; + width: 284px; + padding: 10px; + } + + body.close .content { + transform: translateX(300px); + } + + body.close .app-nav, + body.close .github-corner { + display: none; + } + + .github-corner:hover .octo-arm { + -webkit-animation: none; + animation: none; + } + + .github-corner .octo-arm { + -webkit-animation: octocat-wave 560ms ease-in-out; + animation: octocat-wave 560ms ease-in-out; + } +} + +@-webkit-keyframes octocat-wave { + 0%, 100% { + transform: rotate(0); + } + 20%, 60% { + transform: rotate(-25deg); + } + 40%, 80% { + transform: rotate(10deg); + } +} + +@keyframes octocat-wave { + 0%, 100% { + transform: rotate(0); + } + 20%, 60% { + transform: rotate(-25deg); + } + 40%, 80% { + transform: rotate(10deg); + } +} + +section.cover { + align-items: center; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + height: 100vh; + width: 100vw; + display: none; +} + +section.cover.show { + display: flex; +} + +section.cover.has-mask .mask { + background-color: #fff; + opacity: 0.8; + position: absolute; + top: 0; + height: 100%; + width: 100%; +} + +section.cover .cover-main { + flex: 1; + margin: -20px 16px 0; + text-align: center; + position: relative; +} + +section.cover a { + color: inherit; + text-decoration: none; +} + +section.cover a:hover { + text-decoration: none; +} + +section.cover p { + line-height: 1.5rem; + margin: 1em 0; +} + +section.cover h1 { + color: inherit; + font-size: 2.5rem; + font-weight: 300; + margin: 0.625rem 0 2.5rem; + position: relative; + text-align: center; +} + +section.cover h1 a { + display: block; +} + +section.cover h1 small { + bottom: -0.4375rem; + font-size: 1rem; + position: absolute; +} + +section.cover blockquote { + font-size: 1.5rem; + text-align: center; +} + +section.cover ul { + line-height: 1.8; + list-style-type: none; + margin: 1em auto; + max-width: 500px; + padding: 0; +} + +section.cover .cover-main > p:last-child a { + border-color: var(--theme-color, #7ed491); + border-radius: 2rem; + border-style: solid; + border-width: 1px; + box-sizing: border-box; + color: var(--theme-color, #7ed491); + display: inline-block; + font-size: 1.05rem; + letter-spacing: 0.1rem; + margin: 0.5rem 1rem; + padding: 0.75em 2rem; + text-decoration: none; + transition: all 0.15s ease; +} + +section.cover .cover-main > p:last-child a:last-child { + background-color: var(--theme-color, #7ed491); + color: #fff; +} + +section.cover .cover-main > p:last-child a:last-child:hover { + color: inherit; + opacity: 0.8; +} + +section.cover .cover-main > p:last-child a:hover { + color: inherit; +} + +section.cover blockquote > p > a { + border-bottom: 2px solid var(--theme-color, #7ed491); + transition: color 0.3s; +} + +section.cover blockquote > p > a:hover { + color: var(--theme-color, #7ed491); +} + +body { + background-color: #181e24; +} + +/* sidebar */ +.sidebar { + background-color: #1a2026; + color: #fff; +} + +.sidebar > h1 a { + font-weight: bold; +} + +.sidebar li { + margin: 6px 0 6px 0; +} + +.sidebar ul li a { + color: #eaeaea; + font-size: 14px; + font-weight: normal; + overflow: hidden; + text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; +} + +.sidebar ul li a:hover { + text-decoration: underline; +} + +.sidebar ul li ul { + padding: 0; +} + +.sidebar ul li.active > a { + border-right: 2px solid; + color: var(--theme-color, #7ed491); + font-weight: 600; +} + +.app-sub-sidebar li::before { + content: '-'; + padding-right: 4px; + float: left; +} + +/* markdown content found on pages */ +.markdown-section h1, +.markdown-section h2, +.markdown-section h3, +.markdown-section h4, +.markdown-section strong { + color: #eaeaea; + font-weight: 600; +} + +.markdown-section a { + color: var(--theme-color, #7ed491); + font-weight: 600; +} + +.markdown-section h1 { + font-size: 2rem; + margin: 0 0 1rem; +} + +.markdown-section h2 { + font-size: 1.75rem; + margin: 45px 0 0.8rem; +} + +.markdown-section h3 { + font-size: 1.5rem; + margin: 40px 0 0.6rem; +} + +.markdown-section h4 { + font-size: 1.25rem; +} + +.markdown-section h5 { + font-size: 1rem; +} + +.markdown-section h6 { + color: #777; + font-size: 1rem; +} + +.markdown-section figure, +.markdown-section p { + margin: 1.2em 0; +} + +.markdown-section p, +.markdown-section ul, +.markdown-section ol { + line-height: 1.6rem; + word-spacing: 0.05rem; +} + +.markdown-section ul, +.markdown-section ol { + padding-left: 1.5rem; +} + +.markdown-section blockquote { + border-left: 4px solid var(--theme-color, #7ed491); + color: #858585; + margin: 2em 0; + padding-left: 20px; +} + +.markdown-section blockquote p { + font-weight: 600; + margin-left: 0; +} + +.markdown-section iframe { + margin: 1em 0; +} + +.markdown-section em { + color: #7f8c8d; +} + +.markdown-section code, +.markdown-section pre, +.markdown-section output::after { + font-family: 'Roboto Mono', Monaco, courier, monospace; +} + +.markdown-section code, +.markdown-section pre { + color: #575D74; + background-color: #13181c +} + +.markdown-section pre, +.markdown-section output { + margin: 1.2em 0; + position: relative; +} + +.markdown-section pre > code, +.markdown-section output { + border-radius: 2px; + display: block; +} + +.markdown-section pre > code, +.markdown-section output::after { + -moz-osx-font-smoothing: initial; + -webkit-font-smoothing: initial; +} + +.markdown-section code { + border-radius: 2px; + color: #3b4b58 + margin: 0 2px; + padding: 3px 5px; + white-space: pre-wrap; +} + +.markdown-section > :not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) code { + font-size: 0.8rem; +} + +.markdown-section pre { + padding: 0 1.4rem; + line-height: 1.5rem; + overflow: auto; + word-wrap: normal; +} + +.markdown-section pre > code { + color: #eaeaea; + font-size: 0.8rem; + padding: 2.2em 5px; + line-height: inherit; + margin: 0 2px; + max-width: inherit; + overflow: inherit; + white-space: inherit; +} + +.markdown-section output { + padding: 1.7rem 1.4rem; + border: 1px dotted #ccc; +} + +.markdown-section output > :first-child { + margin-top: 0; +} + +.markdown-section output > :last-child { + margin-bottom: 0; +} + +.markdown-section code::after, +.markdown-section code::before, +.markdown-section output::after, +.markdown-section output::before { + letter-spacing: 0.05rem; +} + +.markdown-section pre::after, +.markdown-section output::after { + color: #ccc; + font-size: 0.6rem; + font-weight: 600; + height: 15px; + line-height: 15px; + padding: 5px 10px 0; + position: absolute; + right: 0; + text-align: right; + top: 0; +} + +.markdown-section pre::after, +.markdown-section output::after { + content: attr(data-lang); +} + +.markdown-section p, .markdown-section ul, .markdown-section ol { + color: #eaeaea; +} + +/* code highlight */ +.token.comment { + color: #575D74; +} + +.token.prolog, +.token.doctype, +.token.cdata { + color: #8e908c; +} + +.token.namespace { + opacity: 0.7; +} + +.token.boolean { + color: #FCC5A3 +} + +.token.number { + color: #FCC5A3; +} + +.token.punctuation { + color: #fca3ab; +} + +.token.property { + color: #d7c1ed; +} + +.token.tag { + color: #2973b7; +} + +.token.string { + color: var(--theme-color, #93cfab); +} + +.token.selector { + color: #6679cc; +} + +.token.attr-name { + color: #2973b7; +} + +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #22a2c9; +} + +.token.attr-value, +.token.control, +.token.directive, +.token.unit { + color: var(--theme-color, #7ed491); +} + +.token.keyword { + color: #d7c1ed +} + +.token.function { + color: #bac8ef; +} + +.token.statement { + color: #fca2aa; +} + +.token.regex, +.token.atrule { + color: #22a2c9; +} + +.token.placeholder, +.token.variable { + color: #3d8fd1; +} + +.token.deleted { + text-decoration: line-through; +} + +.token.inserted { + border-bottom: 1px dotted #202746; + text-decoration: none; +} + +.token.italic { + font-style: italic; +} + +.token.bold { + font-weight: bold; +} + +.token.important { + color: #ccaced; +} + +.token.entity { + cursor: help; +} + +code .token { + -moz-osx-font-smoothing: initial; + -webkit-font-smoothing: initial; + min-height: 1.5rem; + position: relative; + left: auto; +} \ No newline at end of file diff --git a/config/awesome/modules/bling/docs/layouts/layout.md b/config/awesome/modules/bling/docs/layouts/layout.md new file mode 100755 index 0000000..85fc547 --- /dev/null +++ b/config/awesome/modules/bling/docs/layouts/layout.md @@ -0,0 +1,65 @@ +## 📎 Layouts + +Choose layouts from the list below and add them to to your `awful.layouts` list in your `rc.lua`. + +Everyone of them supports multiple master clients and master width factor making them easy to use. + +The mstab layout uses the tab theme from the tabbed module. + +```lua +bling.layout.mstab +bling.layout.centered +bling.layout.vertical +bling.layout.horizontal +bling.layout.equalarea +bling.layout.deck +``` + +### Theme Variables + +```lua +-- mstab +theme.mstab_bar_disable = false -- disable the tabbar +theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients +theme.mstab_dont_resize_slaves = false -- whether the tabbed stack windows should be smaller than the + -- currently focused stack window (set it to true if you use + -- transparent terminals. False if you use shadows on solid ones +theme.mstab_bar_padding = "default" -- how much padding there should be between clients and your tabbar + -- by default it will adjust based on your useless gaps. + -- If you want a custom value. Set it to the number of pixels (int) +theme.mstab_border_radius = 0 -- border radius of the tabbar +theme.mstab_bar_height = 40 -- height of the tabbar +theme.mstab_tabbar_position = "top" -- position of the tabbar (mstab currently does not support left,right) +theme.mstab_tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") + -- defaults to the tabbar_style so only change if you want a + -- different style for mstab and tabbed +``` + +### Previews + +#### Mstab (dynamic tabbing layout) + +![](https://imgur.com/HZRgApE.png) + +*screenshot by [JavaCafe01](https://github.com/JavaCafe01)* + +#### Centered + +![](https://media.discordapp.net/attachments/769673106842845194/780095998239834142/unknown.png) + +*screenshot by [HeavyRain266](https://github.com/HeavyRain266)* + +#### Equal area + +![](https://imgur.com/JCFFywv.png) + +*screenshot by [bysmutheye](https://github.com/bysmutheye)* + +#### Deck + +The left area shows the deck layout in action. In this screenshot it is used together with [layout machi](https://github.com/xinhaoyuan/layout-machi) and its sublayout support. + +![](https://cdn.discordapp.com/attachments/635625954219261982/877957824225894430/unknown.png) + +*screenshot by [JavaCafe01](https://github.com/JavaCafe01)* + diff --git a/config/awesome/modules/bling/docs/module/flash.md b/config/awesome/modules/bling/docs/module/flash.md new file mode 100755 index 0000000..a12b78d --- /dev/null +++ b/config/awesome/modules/bling/docs/module/flash.md @@ -0,0 +1,33 @@ +## 🔦 Flash Focus + +Flash focus does an opacity animation effect on a client when it is focused. + + +### Usage + +There are two ways in which you can use this module. You can enable it by calling the `enable()` function: +```lua +bling.module.flash_focus.enable() +``` +This connects to the focus signal of a client, which means that the flash focus will activate however you focus the client. + +The other way is to call the function itself like this: `bling.module.flash_focus.flashfocus(someclient)`. This allows you to activate on certain keybinds like so: +```lua +awful.key({modkey}, "Up", + function() + awful.client.focus.bydirection("up") + bling.module.flash_focus.flashfocus(client.focus) + end, {description = "focus up", group = "client"}) +``` + +### Theme Variables +```lua +theme.flash_focus_start_opacity = 0.6 -- the starting opacity +theme.flash_focus_step = 0.01 -- the step of animation +``` + +### Preview + +![](https://imgur.com/5txYrlV.gif) + +*gif by [JavaCafe01](https://github.com/JavaCafe01)* diff --git a/config/awesome/modules/bling/docs/module/scratch.md b/config/awesome/modules/bling/docs/module/scratch.md new file mode 100755 index 0000000..54f8ddd --- /dev/null +++ b/config/awesome/modules/bling/docs/module/scratch.md @@ -0,0 +1,75 @@ +## 🍃 Scratchpad + +An easy way to create multiple scratchpads. + +### A... what? + +You can think about a scratchpad as a window whose visibility can be toggled, but still runs in the background without being visible (or minimized) most of the time. Many people use it to have one terminal in which to perform minor tasks, but it is the most useful for windows which only need a couple seconds in between your actual activity, such as music players or chat applications. + +### Rubato Animation Support + +#### Awestore is now deprecated from Bling, we are switching to Rubato. + +Please go over to the [rubato](https://github.com/andOrlando/rubato) repository for installation instructions. Give it a star as well! The animations are completely optional, and if you choose not to use it, you do not need rubato installed. + +### Usage + +To initalize a scratchpad you can do something like the following: + +```lua +local bling = require("bling") +local rubato = require("rubato") -- Totally optional, only required if you are using animations. + +-- These are example rubato tables. You can use one for just y, just x, or both. +-- The duration and easing is up to you. Please check out the rubato docs to learn more. +local anim_y = rubato.timed { + pos = 1090, + rate = 60, + easing = rubato.quadratic, + intro = 0.1, + duration = 0.3, + awestore_compat = true -- This option must be set to true. +} + +local anim_x = rubato.timed { + pos = -970, + rate = 60, + easing = rubato.quadratic, + intro = 0.1, + duration = 0.3, + awestore_compat = true -- This option must be set to true. +} + +local term_scratch = bling.module.scratchpad { + command = "wezterm start --class spad", -- How to spawn the scratchpad + rule = { instance = "spad" }, -- The rule that the scratchpad will be searched by + sticky = true, -- Whether the scratchpad should be sticky + autoclose = true, -- Whether it should hide itself when losing focus + floating = true, -- Whether it should be floating (MUST BE TRUE FOR ANIMATIONS) + geometry = {x=360, y=90, height=900, width=1200}, -- The geometry in a floating state + reapply = true, -- Whether all those properties should be reapplied on every new opening of the scratchpad (MUST BE TRUE FOR ANIMATIONS) + dont_focus_before_close = false, -- When set to true, the scratchpad will be closed by the toggle function regardless of whether its focused or not. When set to false, the toggle function will first bring the scratchpad into focus and only close it on a second call + rubato = {x = anim_x, y = anim_y} -- Optional. This is how you can pass in the rubato tables for animations. If you don't want animations, you can ignore this option. +} +``` + +Once initalized, you can use the object (which in this case is named `term_scratch`) like this: + +```lua +term_scratch:toggle() -- toggles the scratchpads visibility +term_scratch:turn_on() -- turns the scratchpads visibility on +term_scratch:turn_off() -- turns the scratchpads visibility off +``` + +You can also connect to signals as you are used to for further customization. For example like that: + +```lua +term_scratch:connect_signal("turn_on", function(c) naughty.notify({title = "Turned on!"}) end) +``` + +The following signals are currently available. `turn_on`, `turn_off` and `inital_apply` pass the client on which they operated as an argument: + +- `turn_on` fires when the scratchpad is turned on on a tag that it wasn't present on before +- `turn_off` fires when the scratchpad is turned off on a tag +- `spawn` fires when the scratchpad is launched with the given command +- `inital_apply` fires after `spawn`, when a corresponding client has been found and the properties have been applied diff --git a/config/awesome/modules/bling/docs/module/swal.md b/config/awesome/modules/bling/docs/module/swal.md new file mode 100755 index 0000000..0b3fed6 --- /dev/null +++ b/config/awesome/modules/bling/docs/module/swal.md @@ -0,0 +1,25 @@ +## 😋 Window Swallowing + +Can your window manager swallow? It probably can... + +### Usage + +To activate and deactivate window swallowing here are the following functions. If you want to activate it, just call the `start` function once in your `rc.lua`. +```lua +bling.module.window_swallowing.start() -- activates window swallowing +bling.module.window_swallowing.stop() -- deactivates window swallowing +bling.module.window_swallowing.toggle() -- toggles window swallowing +``` + +### Theme Variables +```lua +theme.parent_filter_list = {"firefox", "Gimp"} -- class names list of parents that should not be swallowed +theme.child_filter_list = { "Dragon" } -- class names list that should not swallow their parents +theme.swallowing_filter = true -- whether the filters above should be active +``` + +### Preview + +![](https://media.discordapp.net/attachments/635625813143978012/769180910683684864/20-10-23-14-40-32.gif) + +*gif by [Nooo37](https://github.com/Nooo37)* diff --git a/config/awesome/modules/bling/docs/module/tabbed.md b/config/awesome/modules/bling/docs/module/tabbed.md new file mode 100755 index 0000000..e705357 --- /dev/null +++ b/config/awesome/modules/bling/docs/module/tabbed.md @@ -0,0 +1,66 @@ +## 📑 Tabbed + +Tabbed implements a tab container. There are also different themes for the tabs. + +### Usage + +You should bind these functions to keys in order to use the tabbed module effectively: +```lua +bling.module.tabbed.pick() -- picks a client with your cursor to add to the tabbing group +bling.module.tabbed.pop() -- removes the focused client from the tabbing group +bling.module.tabbed.iter() -- iterates through the currently focused tabbing group +bling.module.tabbed.pick_with_dmenu() -- picks a client with a dmenu application (defaults to rofi, other options can be set with a string parameter like "dmenu") +bling.module.tabbed.pick_by_direction(dir) -- picks a client based on direction ("up", "down", "left" or "right") +``` + +### Theme Variables + +```lua +-- For tabbed only +theme.tabbed_spawn_in_tab = false -- whether a new client should spawn into the focused tabbing container + +-- For tabbar in general +theme.tabbar_ontop = false +theme.tabbar_radius = 0 -- border radius of the tabbar +theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") +theme.tabbar_font = "Sans 11" -- font of the tabbar +theme.tabbar_size = 40 -- size of the tabbar +theme.tabbar_position = "top" -- position of the tabbar +theme.tabbar_bg_normal = "#000000" -- background color of the focused client on the tabbar +theme.tabbar_fg_normal = "#ffffff" -- foreground color of the focused client on the tabbar +theme.tabbar_bg_focus = "#1A2026" -- background color of unfocused clients on the tabbar +theme.tabbar_fg_focus = "#ff0000" -- foreground color of unfocused clients on the tabbar +theme.tabbar_bg_focus_inactive = nil -- background color of the focused client on the tabbar when inactive +theme.tabbar_fg_focus_inactive = nil -- foreground color of the focused client on the tabbar when inactive +theme.tabbar_bg_normal_inactive = nil -- background color of unfocused clients on the tabbar when inactive +theme.tabbar_fg_normal_inactive = nil -- foreground color of unfocused clients on the tabbar when inactive +theme.tabbar_disable = false -- disable the tab bar entirely + +-- the following variables are currently only for the "modern" tabbar style +theme.tabbar_color_close = "#f9929b" -- chnges the color of the close button +theme.tabbar_color_min = "#fbdf90" -- chnges the color of the minimize button +theme.tabbar_color_float = "#ccaced" -- chnges the color of the float button +``` + +### Preview + +Modern theme: + + + +*screenshot by [JavaCafe01](https://github.com/JavaCafe01)* + +### Signals +The tabbed module emits a few signals for the purpose of integration, +```lua +-- bling::tabbed::update -- triggered whenever a tabbed object is updated +-- tabobj -- the object that caused the update +-- bling::tabbed::client_added -- triggered whenever a new client is added to a tab group +-- tabobj -- the object that the client was added to +-- client -- the client that added +-- bling::tabbed::client_removed -- triggered whenever a client is removed from a tab group +-- tabobj -- the object that the client was removed from +-- client -- the client that was removed +-- bling::tabbed::changed_focus -- triggered whenever a tab group's focus is changed +-- tabobj -- the modified tab group +``` diff --git a/config/awesome/modules/bling/docs/module/twall.md b/config/awesome/modules/bling/docs/module/twall.md new file mode 100755 index 0000000..69c09c3 --- /dev/null +++ b/config/awesome/modules/bling/docs/module/twall.md @@ -0,0 +1,26 @@ +## 🏬 Tiled Wallpaper + +### Usage + +The function to set an automatically created tiled wallpaper can be called the following way (you don't need to set every option in the table): +```lua +awful.screen.connect_for_each_screen(function(s) -- that way the wallpaper is applied to every screen + bling.module.tiled_wallpaper("x", s, { -- call the actual function ("x" is the string that will be tiled) + fg = "#ff0000", -- define the foreground color + bg = "#00ffff", -- define the background color + offset_y = 25, -- set a y offset + offset_x = 25, -- set a x offset + font = "Hack", -- set the font (without the size) + font_size = 14, -- set the font size + padding = 100, -- set padding (default is 100) + zickzack = true -- rectangular pattern or criss cross + }) +end) +``` + +### Preview + +![](https://media.discordapp.net/attachments/702548913999314964/773887721294135296/tiled-wallpapers.png?width=1920&height=1080) + +*screenshots by [Nooo37](https://github.com/Nooo37)* + diff --git a/config/awesome/modules/bling/docs/module/wall.md b/config/awesome/modules/bling/docs/module/wall.md new file mode 100755 index 0000000..cdab6cc --- /dev/null +++ b/config/awesome/modules/bling/docs/module/wall.md @@ -0,0 +1,142 @@ +## 🎇 Wallpaper Easy Setup + +This is a simple-to-use, extensible, declarative wallpaper manager. + +### Practical Examples + +```lua +-- A default Awesome wallpaper +bling.module.wallpaper.setup() + +-- A slideshow with pictures from different sources changing every 30 minutes +bling.module.wallpaper.setup { + wallpaper = {"/images/my_dog.jpg", "/images/my_cat.jpg"}, + change_timer = 1800 +} + +-- A random wallpaper with images from multiple folders +bling.module.wallpaper.setup { + set_function = bling.module.wallpaper.setters.random, + wallpaper = {"/path/to/a/folder", "/path/to/another/folder"}, + change_timer = 631, -- prime numbers are better for timers + position = "fit", + background = "#424242" +} + +-- wallpapers based on a schedule, like awesome-glorious-widgets dynamic wallpaper +-- https://github.com/manilarome/awesome-glorious-widgets/tree/master/dynamic-wallpaper +bling.module.wallpaper.setup { + set_function = bling.module.wallpaper.setters.simple_schedule, + wallpaper = { + ["06:22:00"] = "morning-wallpaper.jpg", + ["12:00:00"] = "noon-wallpaper.jpg", + ["17:58:00"] = "night-wallpaper.jpg", + ["24:00:00"] = "midnight-wallpaper.jpg", + }, + position = "maximized", +} + +-- random wallpapers, from different folder depending on time of the day +bling.module.wallpaper.setup { + set_function = bling.module.wallpaper.setters.simple_schedule, + wallpaper = { + ["09:00:00"] = "~/Pictures/safe_for_work", + ["18:00:00"] = "~/Pictures/personal", + }, + schedule_set_function = bling.module.wallpaper.setters.random + position = "maximized", + recursive = false, + change_timer = 600 +} + +-- setup for multiple screens at once +-- the 'screen' argument can be a table of screen objects +bling.module.wallpaper.setup { + set_function = bling.module.wallpaper.setters.random, + screen = screen, -- The awesome 'screen' variable is an array of all screen objects + wallpaper = {"/path/to/a/folder", "/path/to/another/folder"}, + change_timer = 631 +} +``` +### Details + +The setup function will do 2 things: call the set-function when awesome requests a wallpaper, and manage a timer to call `set_function` periodically. + +Its argument is a args table that is passed to ohter functions (setters and wallpaper functions), so you define everything with setup. + +The `set_function` is a function called every times a wallpaper is needed. + +The module provides some setters: + +* `bling.module.wallpaper.setters.awesome_wallpaper`: beautiful.theme_assets.wallpaper with defaults from beautiful. +* `bling.module.wallpaper.setters.simple`: slideshow from the `wallpaper` argument. +* `bling.module.wallpaper.setters.random`: same as simple but in a random way. +* `bling.module.wallpaper.setters.simple_schedule`: takes a table of `["HH:MM:SS"] = wallpaper` arguments, where wallpaper is the `wallpaper` argument used by `schedule_set_function`. + +A wallpaper is one of the following elements: + +* a color +* an image +* a folder containing images +* a function that sets a wallpaper +* everything gears.wallpaper functions can manage (cairo surface, cairo pattern string) +* a list containing any of the elements above + +To set up for multiple screens, two possible methods are: +* Call the `setup` function for each screen, passing the appropriate configuration and `screen` arg +* Call the `setup` function once, passing a table of screens as the `screen` arg. This applies the same configuration to all screens in the table +_Note_: Multiple screen setup only works for the `simple` and `random` setters + +```lua +-- This is a valid wallpaper definition +bling.module.wallpaper.setup { + wallpaper = { -- a list + "black", "#112233", -- colors + "wall1.jpg", "wall2.png", -- files + "/path/to/wallpapers", -- folders + -- cairo patterns + "radial:600,50,100:105,550,900:0,#2200ff:0.5,#00ff00:1,#101010", + -- or functions that set a wallpaper + function(args) bling.module.tiled_wallpaper("\\o/", args.screen) end, + bling.module.wallpaper.setters.awesome_wallpaper, + }, + change_timer = 10, +} +``` +The provided setters `simple` and `random` will use 2 internal functions that you can use to write your own setter: + +* `bling.module.wallpaper.prepare_list`: return a list of wallpapers directly usable by `apply` (for now, it just explores folders) +* `bling.module.wallpaper.apply`: a wrapper for gears.wallpaper functions, using the args table of setup + +Here are the defaults: + +```lua +-- Default parameters +bling.module.wallpaper.setup { + screen = nil, -- the screen to apply the wallpaper, as seen in gears.wallpaper functions + screens = nil, -- an array of screens to apply the wallpaper on. If 'screen' is also provided, this is overridden + change_timer = nil, -- the timer in seconds. If set, call the set_function every change_timer seconds + set_function = nil, -- the setter function + + -- parameters used by bling.module.wallpaper.prepare_list + wallpaper = nil, -- the wallpaper object, see simple or simple_schedule documentation + image_formats = {"jpg", "jpeg", "png", "bmp"}, -- when searching in folder, consider these files only + recursive = true, -- when searching in folder, search also in subfolders + + -- parameters used by bling.module.wallpaper.apply + position = nil, -- use a function of gears.wallpaper when applicable ("centered", "fit", "maximized", "tiled") + background = beautiful.bg_normal or "black", -- see gears.wallpaper functions + ignore_aspect = false, -- see gears.wallpaper.maximized + offset = {x = 0, y = 0}, -- see gears.wallpaper functions + scale = 1, -- see gears.wallpaper.centered + + -- parameters that only apply to bling.module.wallpaper.setter.awesome (as a setter or as a wallpaper function) + colors = { -- see beautiful.theme_assets.wallpaper + bg = beautiful.bg_color, -- the actual default is this color but darkened or lightned + fg = beautiful.fg_color, + alt_fg = beautiful.fg_focus + } +} +``` + +Check documentation in [module/wallpaper.lua](module/wallpaper.lua) for more details. diff --git a/config/awesome/modules/bling/docs/signals/pctl.md b/config/awesome/modules/bling/docs/signals/pctl.md new file mode 100755 index 0000000..89a0709 --- /dev/null +++ b/config/awesome/modules/bling/docs/signals/pctl.md @@ -0,0 +1,240 @@ +## 🎵 Playerctl + +This is a signal module in which you can connect to certain bling signals to grab playerctl info. Currently, this is what it supports: + +- Song title and artist +- Album art (the path this module downloaded the art to) +- If playing or not +- Position +- Song length +- If there are no players on + +This module relies on `playerctl` and `curl`. If you have this module disabled, you won't need those programs. With this module, you can create a widget like below without worrying about the backend. + +![](https://user-images.githubusercontent.com/33443763/107377569-fa807900-6a9f-11eb-93c1-174c58eb7bf1.png) + +*screenshot by [javacafe](https://github.com/JavaCafe01)* + +### Usage + +To enable: `playerctl = bling.signal.playerctl.lib/cli()` + +To disable: `playerctl:disable()` + +#### Playerctl_lib Signals + +**Note**: When connecting to signals with the new `playerctl` module, the object itself is always given to you as the first parameter. + +```lua +-- metadata +-- title (string) +-- artist (string) +-- album_path (string) +-- album (string) +-- new (bool) +-- player_name (string) +-- position +-- interval_sec (number) +-- length_sec (number) +-- player_name (string) +-- playback_status +-- playing (boolean) +-- player_name (string) +-- seeked +-- position (number) +-- player_name (string) +-- volume +-- volume (number) +-- player_name (string) +-- loop_status +-- loop_status (string) +-- player_name (string) +-- shuffle +-- shuffle (boolean) +-- player_name (string) +-- exit +-- player_name (string) +-- no_players +-- (No parameters) +``` + +#### Playerctl_cli Signals + +```lua +-- metadata +-- title (string) +-- artist (string) +-- album_path (string) +-- album (string) +-- player_name (string) +-- position +-- interval_sec (number) +-- length_sec (number) +-- playback_status +-- playing (boolean) +-- volume +-- volume (number) +-- loop_status +-- loop_status (string) +-- shuffle +-- shuffle (bool) +-- no_players +-- (No parameters) +``` + +#### Playerctl Functions + +With this library we also give the user a way to interact with Playerctl, such as playing, pausing, seeking, etc. + +Here are the functions provided: + +```lua +-- disable() +-- pause(player) +-- play(player) +-- stop(player) +-- play_pause(player) +-- previous(player) +-- next(player) +-- set_loop_status(loop_status, player) +-- cycle_loop_status(player) +-- set_position(position, player) +-- set_shuffle(shuffle, player) +-- cycle_shuffle(player) +-- set_volume(volume, player) +-- get_manager() +-- get_active_player() +-- get_player_of_name(name) +``` + +### Example Implementation + +Lets say we have an imagebox. If I wanted to set the imagebox to show the album art, all I have to do is this: + +```lua +local art = wibox.widget { + image = "default_image.png", + resize = true, + forced_height = dpi(80), + forced_width = dpi(80), + widget = wibox.widget.imagebox +} + +local name_widget = wibox.widget { + markup = 'No players', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local title_widget = wibox.widget { + markup = 'Nothing Playing', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +local artist_widget = wibox.widget { + markup = 'Nothing Playing', + align = 'center', + valign = 'center', + widget = wibox.widget.textbox +} + +-- Get Song Info +local playerctl = bling.signal.playerctl.lib() +playerctl:connect_signal("metadata", + function(_, title, artist, album_path, album, new, player_name) + -- Set art widget + art:set_image(gears.surface.load_uncached(album_path)) + + -- Set player name, title and artist widgets + name_widget:set_markup_silently(player_name) + title_widget:set_markup_silently(title) + artist_widget:set_markup_silently(artist) +end) +``` + +Thats all! You don't even have to worry about updating the widgets, the signals will handle that for you. + +Here's another example in which you get a notification with the album art, title, and artist whenever the song changes. + +```lua +local naughty = require("naughty") +local playerctl = bling.signal.playerctl.lib() + +playerctl:connect_signal("metadata", + function(_, title, artist, album_path, album, new, player_name) + if new == true then + naughty.notify({title = title, text = artist, image = album_path}) + end +end) +``` + +We can also link a playerctl function to a button click! + +```lua +local playerctl = bling.signal.playerctl.lib() +button:buttons(gears.table.join( + awful.button({}, 1, function() + playerctl:play_pause() + end) +)) +``` + +### Theme Variables and Configuration + +By default, this module will output signals from the most recently active player. If you wish to customize the behavior furthur, the following configuration options are available depending on the selected backend. Here is a summary of the two backends and which configuration options they support. + +| Option | playerctl_cli | playerctl_lib | +| ------------------- | ------------------ | ------------------ | +| ignore | :heavy_check_mark: | :heavy_check_mark: | +| player | :heavy_check_mark: | :heavy_check_mark: | +| update_on_activity | | :heavy_check_mark: | +| interval | :heavy_check_mark: | :heavy_check_mark: | +| debounce_delay | :heavy_check_mark: | :heavy_check_mark: | + +- `ignore`: This option is either a string with a single name or a table of strings containing names of players that will be ignored by this module. It is empty by default. + +- `player`: This option is either a string with a single name or a table of strings containing names of players this module will emit signals for. It also acts as a way to prioritize certain players over others with players listed earlier in the table being preferred over players listed later. The special name `%any` can be used once to match any player not found in the list. It is empty by default. + +- `update_on_activity`: This option is a boolean that, when true, will cause the module to output signals from the most recently active player while still adhering to the player priority specified with the `player` option. If `false`, the module will output signals from the player that started first, again, while still adhering to the player priority. It is `true` by default. + +- `interval`: This option is a number specifying the update interval for fetching the player position. It is 1 by default. + +- `debounce_delay`: This option is a number specifying the debounce timer interval. If a new metadata signal gets emitted before debounce_delay has passed, the last signal will be dropped. +This is to help with some players sending multiple signals. It is `0.35` by default. + +These options can be set through a call to `bling.signal.playerctl.lib/cli()` or these theme variables: + +```lua +theme.playerctl_ignore = {} +theme.playerctl_player = {} +theme.playerctl_update_on_activity = true +theme.playerctl_position_update_interval = 1 +``` + +#### Example Configurations + +```lua +-- Prioritize ncspot over all other players and ignore firefox players (e.g. YouTube and Twitch tabs) completely +playerctl = bling.signal.playerctl.lib { + ignore = "firefox", + player = {"ncspot", "%any"} +} + +-- OR in your theme file: +-- Same config as above but with theme variables +theme.playerctl_ignore = "firefox" +theme.playerctl_player = {"ncspot", "%any"} + +-- Prioritize vlc over all other players and deprioritize spotify +theme.playerctl_backend = "playerctl_lib" +theme.playerctl_player = {"vlc", "%any", "spotify"} + +-- Disable priority of most recently active players +theme.playerctl_update_on_activity = false + +-- Only emit the position signal every 2 seconds +theme.playerctl_position_update_interval = 2 +``` diff --git a/config/awesome/modules/bling/docs/theme.md b/config/awesome/modules/bling/docs/theme.md new file mode 100755 index 0000000..0d1d0b3 --- /dev/null +++ b/config/awesome/modules/bling/docs/theme.md @@ -0,0 +1,117 @@ +```lua +--[[ Bling theme variables template +This file has all theme variables of the bling module. +Every variable has a small comment on what it does. +You might just want to copy that whole part into your theme.lua and start adjusting from there. +--]] + + +-- window swallowing +theme.dont_swallow_classname_list = {"firefox", "Gimp"} -- list of class names that should not be swallowed +theme.dont_swallow_filter_activated = true -- whether the filter above should be active + +-- flash focus +theme.flash_focus_start_opacity = 0.6 -- the starting opacity +theme.flash_focus_step = 0.01 -- the step of animation + +-- playerctl signal +theme.playerctl_backend = "playerctl_cli" -- backend to use +theme.playerctl_ignore = {} -- list of players to be ignored +theme.playerctl_player = {} -- list of players to be used in priority order +theme.playerctl_update_on_activity = true -- whether to prioritize the most recently active players or not +theme.playerctl_position_update_interval = 1 -- the update interval for fetching the position from playerctl + +-- tabbed +theme.tabbed_spawn_in_tab = false -- whether a new client should spawn into the focused tabbing container + +-- tabbar general +theme.tabbar_ontop = false +theme.tabbar_radius = 0 -- border radius of the tabbar +theme.tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") +theme.tabbar_font = "Sans 11" -- font of the tabbar +theme.tabbar_size = 40 -- size of the tabbar +theme.tabbar_position = "top" -- position of the tabbar +theme.tabbar_bg_normal = "#000000" -- background color of the focused client on the tabbar +theme.tabbar_fg_normal = "#ffffff" -- foreground color of the focused client on the tabbar +theme.tabbar_bg_focus = "#1A2026" -- background color of unfocused clients on the tabbar +theme.tabbar_fg_focus = "#ff0000" -- foreground color of unfocused clients on the tabbar +theme.tabbar_bg_focus_inactive = nil -- background color of the focused client on the tabbar when inactive +theme.tabbar_fg_focus_inactive = nil -- foreground color of the focused client on the tabbar when inactive +theme.tabbar_bg_normal_inactive = nil -- background color of unfocused clients on the tabbar when inactive +theme.tabbar_fg_normal_inactive = nil -- foreground color of unfocused clients on the tabbar when inactive +theme.tabbar_disable = false -- disable the tab bar entirely + +-- mstab +theme.mstab_bar_disable = false -- disable the tabbar +theme.mstab_bar_ontop = false -- whether you want to allow the bar to be ontop of clients +theme.mstab_dont_resize_slaves = false -- whether the tabbed stack windows should be smaller than the + -- currently focused stack window (set it to true if you use + -- transparent terminals. False if you use shadows on solid ones +theme.mstab_bar_padding = "default" -- how much padding there should be between clients and your tabbar + -- by default it will adjust based on your useless gaps. + -- If you want a custom value. Set it to the number of pixels (int) +theme.mstab_border_radius = 0 -- border radius of the tabbar +theme.mstab_bar_height = 40 -- height of the tabbar +theme.mstab_tabbar_position = "top" -- position of the tabbar (mstab currently does not support left,right) +theme.mstab_tabbar_style = "default" -- style of the tabbar ("default", "boxes" or "modern") + -- defaults to the tabbar_style so only change if you want a + -- different style for mstab and tabbed + +-- the following variables are currently only for the "modern" tabbar style +theme.tabbar_color_close = "#f9929b" -- chnges the color of the close button +theme.tabbar_color_min = "#fbdf90" -- chnges the color of the minimize button +theme.tabbar_color_float = "#ccaced" -- chnges the color of the float button + +-- tag preview widget +theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA) +theme.tag_preview_client_border_radius = 0 -- Border radius of each client in the widget (With AA) +theme.tag_preview_client_opacity = 0.5 -- Opacity of each client +theme.tag_preview_client_bg = "#000000" -- The bg color of each client +theme.tag_preview_client_border_color = "#ffffff" -- The border color of each client +theme.tag_preview_client_border_width = 3 -- The border width of each client +theme.tag_preview_widget_bg = "#000000" -- The bg color of the widget +theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget +theme.tag_preview_widget_border_width = 3 -- The border width of the widget +theme.tag_preview_widget_margin = 0 -- The margin of the widget + +-- task preview widget +theme.task_preview_widget_border_radius = 0 -- Border radius of the widget (With AA) +theme.task_preview_widget_bg = "#000000" -- The bg color of the widget +theme.task_preview_widget_border_color = "#ffffff" -- The border color of the widget +theme.task_preview_widget_border_width = 3 -- The border width of the widget +theme.task_preview_widget_margin = 0 -- The margin of the widget + +-- tabbed misc widget(s) +theme.bling_tabbed_misc_titlebar_indicator = { + layout_spacing = dpi(4), + icon_size = dpi(20), + icon_margin = dpi(4), + bg_color_focus = "#ff0000", + bg_color = "#00000000", + icon_shape = function(cr, w, h) + gears.shape.rounded_rect(cr, w, h, 0) + end, + layout = wibox.layout.fixed.horizontal +} + +-- window switcher widget +theme.window_switcher_widget_bg = "#000000" -- The bg color of the widget +theme.window_switcher_widget_border_width = 3 -- The border width of the widget +theme.window_switcher_widget_border_radius = 0 -- The border radius of the widget +theme.window_switcher_widget_border_color = "#ffffff" -- The border color of the widget +theme.window_switcher_clients_spacing = 20 -- The space between each client item +theme.window_switcher_client_icon_horizontal_spacing = 5 -- The space between client icon and text +theme.window_switcher_client_width = 150 -- The width of one client widget +theme.window_switcher_client_height = 250 -- The height of one client widget +theme.window_switcher_client_margins = 10 -- The margin between the content and the border of the widget +theme.window_switcher_thumbnail_margins = 10 -- The margin between one client thumbnail and the rest of the widget +theme.thumbnail_scale = false -- If set to true, the thumbnails fit policy will be set to "fit" instead of "auto" +theme.window_switcher_name_margins = 10 -- The margin of one clients title to the rest of the widget +theme.window_switcher_name_valign = "center" -- How to vertically align one clients title +theme.window_switcher_name_forced_width = 200 -- The width of one title +theme.window_switcher_name_font = "sans 11" -- The font of all titles +theme.window_switcher_name_normal_color = "#ffffff" -- The color of one title if the client is unfocused +theme.window_switcher_name_focus_color = "#ff0000" -- The color of one title if the client is focused +theme.window_switcher_icon_valign = "center" -- How to vertically align the one icon +theme.window_switcher_icon_width = 40 -- The width of one icon +``` diff --git a/config/awesome/modules/bling/docs/widgets/tabbed_misc.md b/config/awesome/modules/bling/docs/widgets/tabbed_misc.md new file mode 100755 index 0000000..89c4557 --- /dev/null +++ b/config/awesome/modules/bling/docs/widgets/tabbed_misc.md @@ -0,0 +1,117 @@ +## 🧱 Tabbed Miscellaneous + +This comprises a few widgets to better represent tabbed groups (from the tabbed module) in your desktop. +The widgets currently included are: +- Titlebar Indicator +- Tasklist + +![Preview Image](https://i.imgur.com/ZeYSrxY.png) + +## Titlebar Indicator + +### Usage + +To use the task list indicator: +**NOTE:** Options can be set as theme vars under the table `theme.bling_tabbed_misc_titlebar_indicator` + +```lua +bling.widget.tabbed_misc.titlebar_indicator(client, { + layout = wibox.layout.fixed.vertical, + layout_spacing = dpi(5), -- Set spacing in between items + icon_size = dpi(24), -- Set icon size + icon_margin = 0, -- Set icon margin + fg_color = "#cccccc", -- Normal color for text + fg_color_focus = "#ffffff", -- Color for focused text + bg_color_focus = "#282828", -- Color for the focused items + bg_color = "#1d2021", -- Color for normal / unfocused items + icon_shape = gears.shape.circle -- Set icon shape, +}) +``` + +a widget_template option is also available: +```lua +bling.widget.tabbed_misc.titlebar_indicator(client, { + widget_template = { + { + widget = awful.widget.clienticon, + id = 'icon_role' + }, + widget = wibox.container.margin, + margins = 2, + id = 'bg_role', + update_callback = function(self, client, group) + if client == group.clients[group.focused_idx] then + self.margins = 5 + end + end + } +}) +``` + +### Example Implementation + +You normally embed the widget in your titlebar... +```lua +awful.titlebar(c).widget = { + { -- Left + bling.widget.tabbed_misc.titlebar_indicator(c), + layout = wibox.layout.fixed.horizontal + }, + { -- Middle + { -- Title + align = "center", + widget = awful.titlebar.widget.titlewidget(c) + }, + buttons = buttons, + layout = wibox.layout.flex.horizontal + }, + { -- Right + awful.titlebar.widget.maximizedbutton(c), + awful.titlebar.widget.closebutton (c), + layout = wibox.layout.fixed.horizontal + }, + layout = wibox.layout.align.horizontal + } +``` + +## Tasklist +The module exports a function that can be added to your tasklist as a `update_callback` + +### Usage +```lua +awful.widget.tasklist({ + screen = s, + filter = awful.widget.tasklist.filter.currenttags, + layout = { + spacing = dpi(10), + layout = wibox.layout.fixed.vertical, + }, + style = { + bg_normal = "#00000000", + }, + widget_template = { + { + { + widget = wibox.widget.imagebox, + id = "icon_role", + align = "center", + valign = "center", + }, + width = dpi(24), + height = dpi(24), + widget = wibox.container.constraint, + }, + widget = wibox.container.background, -- IT MUST BE A CONTAINER WIDGET AS THAT IS WHAT THE FUNCTION EXPECTS + update_callback = require("bling.widget.tabbed_misc").custom_tasklist, + id = "background_role", + }, +}) +``` + +If you need to do something else, it can be used like so +```lua +update_callback = function(self, client, index, clients) + require("bling.widget.tabbed_misc").custom_tasklist(self, client, index, clients) + require("naughty").notify({ text = "Tasklist was updated" }) +end +``` diff --git a/config/awesome/modules/bling/docs/widgets/tag_preview.md b/config/awesome/modules/bling/docs/widgets/tag_preview.md new file mode 100755 index 0000000..bdf033d --- /dev/null +++ b/config/awesome/modules/bling/docs/widgets/tag_preview.md @@ -0,0 +1,155 @@ +## 🔍 Tag Preview + +This is a popup widget that will show a preview of a specified tag that illustrates the position, size, content, and icon of all clients. + +![](https://imgur.com/zFdvs4K.gif) + +*gif by [javacafe](https://github.com/JavaCafe01)* + +### Usage + +To enable: + +```lua +bling.widget.tag_preview.enable { + show_client_content = false, -- Whether or not to show the client content + x = 10, -- The x-coord of the popup + y = 10, -- The y-coord of the popup + scale = 0.25, -- The scale of the previews compared to the screen + honor_padding = false, -- Honor padding when creating widget size + honor_workarea = false, -- Honor work area when creating widget size + placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y) + awful.placement.top_left(c, { + margins = { + top = 30, + left = 30 + } + }) + end, + background_widget = wibox.widget { -- Set a background image (like a wallpaper) for the widget + image = beautiful.wallpaper, + horizontal_fit_policy = "fit", + vertical_fit_policy = "fit", + widget = wibox.widget.imagebox + } +} +``` + +Here are the signals available: + +```lua +-- bling::tag_preview::update -- first line is the signal +-- t (tag) -- indented lines are function parameters +-- bling::tag_preview::visibility +-- s (screen) +-- v (boolean) +``` + +By default, the widget is not visible. You must implement when it will update and when it will show. + +### Example Implementation + +We can trigger the widget to show the specific tag when hovering over it in the taglist. The code shown below is the example taglist from the [AwesomeWM docs](https://awesomewm.org/doc/api/classes/awful.widget.taglist.html). Basically, we are going to update the widget and toggle it through the taglist's `create_callback`. (The bling addons are commented) +```lua +s.mytaglist = awful.widget.taglist { + screen = s, + filter = awful.widget.taglist.filter.all, + style = { + shape = gears.shape.powerline + }, + layout = { + spacing = -12, + spacing_widget = { + color = '#dddddd', + shape = gears.shape.powerline, + widget = wibox.widget.separator, + }, + layout = wibox.layout.fixed.horizontal + }, + widget_template = { + { + { + { + { + { + id = 'index_role', + widget = wibox.widget.textbox, + }, + margins = 4, + widget = wibox.container.margin, + }, + bg = '#dddddd', + shape = gears.shape.circle, + widget = wibox.container.background, + }, + { + { + id = 'icon_role', + widget = wibox.widget.imagebox, + }, + margins = 2, + widget = wibox.container.margin, + }, + { + id = 'text_role', + widget = wibox.widget.textbox, + }, + layout = wibox.layout.fixed.horizontal, + }, + left = 18, + right = 18, + widget = wibox.container.margin + }, + id = 'background_role', + widget = wibox.container.background, + -- Add support for hover colors and an index label + create_callback = function(self, c3, index, objects) --luacheck: no unused args + self:get_children_by_id('index_role')[1].markup = ' '..index..' ' + self:connect_signal('mouse::enter', function() + + -- BLING: Only show widget when there are clients in the tag + if #c3:clients() > 0 then + -- BLING: Update the widget with the new tag + awesome.emit_signal("bling::tag_preview::update", c3) + -- BLING: Show the widget + awesome.emit_signal("bling::tag_preview::visibility", s, true) + end + + if self.bg ~= '#ff0000' then + self.backup = self.bg + self.has_backup = true + end + self.bg = '#ff0000' + end) + self:connect_signal('mouse::leave', function() + + -- BLING: Turn the widget off + awesome.emit_signal("bling::tag_preview::visibility", s, false) + + if self.has_backup then self.bg = self.backup end + end) + end, + update_callback = function(self, c3, index, objects) --luacheck: no unused args + self:get_children_by_id('index_role')[1].markup = ' '..index..' ' + end, + }, + buttons = taglist_buttons +} +``` + +### Theme Variables + +```lua +theme.tag_preview_widget_border_radius = 0 -- Border radius of the widget (With AA) +theme.tag_preview_client_border_radius = 0 -- Border radius of each client in the widget (With AA) +theme.tag_preview_client_opacity = 0.5 -- Opacity of each client +theme.tag_preview_client_bg = "#000000" -- The bg color of each client +theme.tag_preview_client_border_color = "#ffffff" -- The border color of each client +theme.tag_preview_client_border_width = 3 -- The border width of each client +theme.tag_preview_widget_bg = "#000000" -- The bg color of the widget +theme.tag_preview_widget_border_color = "#ffffff" -- The border color of the widget +theme.tag_preview_widget_border_width = 3 -- The border width of the widget +theme.tag_preview_widget_margin = 0 -- The margin of the widget +``` + +NOTE: I recommend to only use the widget border radius theme variable when not using shadows with a compositor, as anti-aliased rounding with the outer widgets made with AwesomeWM rely on the actual bg being transparent. If you want rounding with shadows on the widget, use a compositor like [jonaburg's fork](https://github.com/jonaburg/picom). diff --git a/config/awesome/modules/bling/docs/widgets/task_preview.md b/config/awesome/modules/bling/docs/widgets/task_preview.md new file mode 100755 index 0000000..30a85f8 --- /dev/null +++ b/config/awesome/modules/bling/docs/widgets/task_preview.md @@ -0,0 +1,152 @@ +## 🔍 Task Preview + +This is a popup widget that will show a preview of the specified client. It is supposed to mimic the small popup that Windows has when hovering over the application icon. + +![](https://user-images.githubusercontent.com/33443763/124705653-d7b98b80-deaa-11eb-8091-42bbe62365be.png) + +*image by [javacafe](https://github.com/JavaCafe01)* + +### Usage + +To enable: + +```lua +bling.widget.task_preview.enable { + x = 20, -- The x-coord of the popup + y = 20, -- The y-coord of the popup + height = 200, -- The height of the popup + width = 200, -- The width of the popup + placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y) + awful.placement.bottom(c, { + margins = { + bottom = 30 + } + }) + end +} +``` + +To allow for more customization, there is also a `widget_structure` property (as seen in some default awesome widgets) which is optional. An example is as follows - +```lua +bling.widget.task_preview.enable { + x = 20, -- The x-coord of the popup + y = 20, -- The y-coord of the popup + height = 200, -- The height of the popup + width = 200, -- The width of the popup + placement_fn = function(c) -- Place the widget using awful.placement (this overrides x & y) + awful.placement.bottom(c, { + margins = { + bottom = 30 + } + }) + end, + -- Your widget will automatically conform to the given size due to a constraint container. + widget_structure = { + { + { + { + id = 'icon_role', + widget = awful.widget.clienticon, -- The client icon + }, + { + id = 'name_role', -- The client name / title + widget = wibox.widget.textbox, + }, + layout = wibox.layout.flex.horizontal + }, + widget = wibox.container.margin, + margins = 5 + }, + { + id = 'image_role', -- The client preview + resize = true, + valign = 'center', + halign = 'center', + widget = wibox.widget.imagebox, + }, + layout = wibox.layout.fixed.vertical + } +} +``` + +Here are the signals available: + +```lua +-- bling::task_preview::visibility -- first line is the signal +-- s (screen) -- indented lines are function parameters +-- v (boolean) +-- c (client) +``` + +By default, the widget is not visible. You must implement when it will update and when it will show. + +### Example Implementation + +We can trigger the widget to show the specific client when hovering over it in the tasklist. The code shown below is the example icon only tasklist from the [AwesomeWM docs](https://awesomewm.org/doc/api/classes/awful.widget.tasklist.html). Basically, we are going to toggle the widget through the tasklist's `create_callback`. (The bling addons are commented) +```lua +s.mytasklist = awful.widget.tasklist { + screen = s, + filter = awful.widget.tasklist.filter.currenttags, + buttons = tasklist_buttons, + layout = { + spacing_widget = { + { + forced_width = 5, + forced_height = 24, + thickness = 1, + color = '#777777', + widget = wibox.widget.separator + }, + valign = 'center', + halign = 'center', + widget = wibox.container.place, + }, + spacing = 1, + layout = wibox.layout.fixed.horizontal + }, + -- Notice that there is *NO* wibox.wibox prefix, it is a template, + -- not a widget instance. + widget_template = { + { + wibox.widget.base.make_widget(), + forced_height = 5, + id = 'background_role', + widget = wibox.container.background, + }, + { + { + id = 'clienticon', + widget = awful.widget.clienticon, + }, + margins = 5, + widget = wibox.container.margin + }, + nil, + create_callback = function(self, c, index, objects) --luacheck: no unused args + self:get_children_by_id('clienticon')[1].client = c + + -- BLING: Toggle the popup on hover and disable it off hover + self:connect_signal('mouse::enter', function() + awesome.emit_signal("bling::task_preview::visibility", s, + true, c) + end) + self:connect_signal('mouse::leave', function() + awesome.emit_signal("bling::task_preview::visibility", s, + false, c) + end) + end, + layout = wibox.layout.align.vertical, + }, +} +``` + +### Theme Variables +```lua +theme.task_preview_widget_border_radius = 0 -- Border radius of the widget (With AA) +theme.task_preview_widget_bg = "#000000" -- The bg color of the widget +theme.task_preview_widget_border_color = "#ffffff" -- The border color of the widget +theme.task_preview_widget_border_width = 3 -- The border width of the widget +theme.task_preview_widget_margin = 0 -- The margin of the widget +``` + +NOTE: I recommend to only use the widget border radius theme variable when not using shadows with a compositor, as anti-aliased rounding with the outer widgets made with AwesomeWM rely on the actual bg being transparent. If you want rounding with shadows on the widget, use a compositor like [jonaburg's fork](https://github.com/jonaburg/picom). diff --git a/config/awesome/modules/bling/docs/widgets/window_switcher.md b/config/awesome/modules/bling/docs/widgets/window_switcher.md new file mode 100755 index 0000000..8f48257 --- /dev/null +++ b/config/awesome/modules/bling/docs/widgets/window_switcher.md @@ -0,0 +1,67 @@ +## 🎨 Window Switcher + +A popup with client previews that allows you to switch clients similar to the alt-tab menu in MacOS, GNOME, and Windows. + +![](https://user-images.githubusercontent.com/70270606/133311802-8aef1012-346f-4f4c-843d-10d9de54ffeb.png) + +*image by [No37](https://github.com/Nooo37)* + +### Usage + +To enable: + +```lua +bling.widget.window_switcher.enable { + type = "thumbnail", -- set to anything other than "thumbnail" to disable client previews + + -- keybindings (the examples provided are also the default if kept unset) + hide_window_switcher_key = "Escape", -- The key on which to close the popup + minimize_key = "n", -- The key on which to minimize the selected client + unminimize_key = "N", -- The key on which to unminimize all clients + kill_client_key = "q", -- The key on which to close the selected client + cycle_key = "Tab", -- The key on which to cycle through all clients + previous_key = "Left", -- The key on which to select the previous client + next_key = "Right", -- The key on which to select the next client + vim_previous_key = "h", -- Alternative key on which to select the previous client + vim_next_key = "l", -- Alternative key on which to select the next client + + cycleClientsByIdx = awful.client.focus.byidx, -- The function to cycle the clients + filterClients = awful.widget.tasklist.filter.currenttags, -- The function to filter the viewed clients +} +``` + +To run the window swicher you have to emit this signal from within your configuration (usually using a keybind). + +```lua +awesome.emit_signal("bling::window_switcher::turn_on") +``` + +For example: +```lua + awful.key({Mod1}, "Tab", function() + awesome.emit_signal("bling::window_switcher::turn_on") + end, {description = "Window Switcher", group = "bling"}) +``` + +### Theme Variables +```lua +theme.window_switcher_widget_bg = "#000000" -- The bg color of the widget +theme.window_switcher_widget_border_width = 3 -- The border width of the widget +theme.window_switcher_widget_border_radius = 0 -- The border radius of the widget +theme.window_switcher_widget_border_color = "#ffffff" -- The border color of the widget +theme.window_switcher_clients_spacing = 20 -- The space between each client item +theme.window_switcher_client_icon_horizontal_spacing = 5 -- The space between client icon and text +theme.window_switcher_client_width = 150 -- The width of one client widget +theme.window_switcher_client_height = 250 -- The height of one client widget +theme.window_switcher_client_margins = 10 -- The margin between the content and the border of the widget +theme.window_switcher_thumbnail_margins = 10 -- The margin between one client thumbnail and the rest of the widget +theme.thumbnail_scale = false -- If set to true, the thumbnails fit policy will be set to "fit" instead of "auto" +theme.window_switcher_name_margins = 10 -- The margin of one clients title to the rest of the widget +theme.window_switcher_name_valign = "center" -- How to vertically align one clients title +theme.window_switcher_name_forced_width = 200 -- The width of one title +theme.window_switcher_name_font = "sans 11" -- The font of all titles +theme.window_switcher_name_normal_color = "#ffffff" -- The color of one title if the client is unfocused +theme.window_switcher_name_focus_color = "#ff0000" -- The color of one title if the client is focused +theme.window_switcher_icon_valign = "center" -- How to vertically align the one icon +theme.window_switcher_icon_width = 40 -- The width of one icon +``` diff --git a/config/awesome/module/bling/helpers/client.lua b/config/awesome/modules/bling/helpers/client.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/helpers/client.lua rename to config/awesome/modules/bling/helpers/client.lua diff --git a/config/awesome/module/bling/helpers/color.lua b/config/awesome/modules/bling/helpers/color.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/helpers/color.lua rename to config/awesome/modules/bling/helpers/color.lua diff --git a/config/awesome/module/bling/helpers/filesystem.lua b/config/awesome/modules/bling/helpers/filesystem.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/helpers/filesystem.lua rename to config/awesome/modules/bling/helpers/filesystem.lua diff --git a/config/awesome/modules/bling/helpers/icon_theme.lua b/config/awesome/modules/bling/helpers/icon_theme.lua new file mode 100755 index 0000000..c4d4583 --- /dev/null +++ b/config/awesome/modules/bling/helpers/icon_theme.lua @@ -0,0 +1,142 @@ +local lgi = require("lgi") +local Gio = lgi.Gio +local Gtk = lgi.require("Gtk", "3.0") +local gobject = require("gears.object") +local gtable = require("gears.table") +local setmetatable = setmetatable +local ipairs = ipairs + +local icon_theme = { mt = {} } + +local name_lookup = +{ + ["jetbrains-studio"] = "android-studio" +} + +local function get_icon_by_pid_command(self, client, apps) + local pid = client.pid + if pid ~= nil then + local handle = io.popen(string.format("ps -p %d -o comm=", pid)) + local pid_command = handle:read("*a"):gsub("^%s*(.-)%s*$", "%1") + handle:close() + + for _, app in ipairs(apps) do + local executable = app:get_executable() + if executable and executable:find(pid_command, 1, true) then + return self:get_gicon_path(app:get_icon()) + end + end + end +end + +local function get_icon_by_icon_name(self, client, apps) + local icon_name = client.icon_name and client.icon_name:lower() or nil + if icon_name ~= nil then + for _, app in ipairs(apps) do + local name = app:get_name():lower() + if name and name:find(icon_name, 1, true) then + return self:get_gicon_path(app:get_icon()) + end + end + end +end + +local function get_icon_by_class(self, client, apps) + if client.class ~= nil then + local class = name_lookup[client.class] or client.class:lower() + + -- Try to remove dashes + local class_1 = class:gsub("[%-]", "") + + -- Try to replace dashes with dot + local class_2 = class:gsub("[%-]", ".") + + -- Try to match only the first word + local class_3 = class:match("(.-)-") or class + class_3 = class_3:match("(.-)%.") or class_3 + class_3 = class_3:match("(.-)%s+") or class_3 + + local possible_icon_names = { class, class_3, class_2, class_1 } + for _, app in ipairs(apps) do + local id = app:get_id():lower() + for _, possible_icon_name in ipairs(possible_icon_names) do + if id and id:find(possible_icon_name, 1, true) then + return self:get_gicon_path(app:get_icon()) + end + end + end + end +end + +function icon_theme:get_client_icon_path(client) + local apps = Gio.AppInfo.get_all() + + return get_icon_by_pid_command(self, client, apps) or + get_icon_by_icon_name(self, client, apps) or + get_icon_by_class(self, client, apps) or + client.icon or + self:choose_icon({"window", "window-manager", "xfwm4-default", "window_list" }) +end + +function icon_theme:choose_icon(icons_names) + local icon_info = self.gtk_theme:choose_icon(icons_names, self.icon_size, 0); + if icon_info then + local icon_path = icon_info:get_filename() + if icon_path then + return icon_path + end + end + + return "" +end + +function icon_theme:get_gicon_path(gicon) + if gicon == nil then + return "" + end + + local icon_info = self.gtk_theme:lookup_by_gicon(gicon, self.icon_size, 0); + if icon_info then + local icon_path = icon_info:get_filename() + if icon_path then + return icon_path + end + end + + return "" +end + +function icon_theme:get_icon_path(icon_name) + local icon_info = self.gtk_theme:lookup_icon(icon_name, self.icon_size, 0) + if icon_info then + local icon_path = icon_info:get_filename() + if icon_path then + return icon_path + end + end + + return "" +end + +local function new(theme_name, icon_size) + local ret = gobject{} + gtable.crush(ret, icon_theme, true) + + ret.name = theme_name or nil + ret.icon_size = icon_size or 48 + + if theme_name then + ret.gtk_theme = Gtk.IconTheme.new() + Gtk.IconTheme.set_custom_theme(ret.gtk_theme, theme_name); + else + ret.gtk_theme = Gtk.IconTheme.get_default() + end + + return ret +end + +function icon_theme.mt:__call(...) + return new(...) +end + +return setmetatable(icon_theme, icon_theme.mt) \ No newline at end of file diff --git a/config/awesome/module/bling/helpers/init.lua b/config/awesome/modules/bling/helpers/init.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/helpers/init.lua rename to config/awesome/modules/bling/helpers/init.lua diff --git a/config/awesome/module/bling/helpers/shape.lua b/config/awesome/modules/bling/helpers/shape.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/helpers/shape.lua rename to config/awesome/modules/bling/helpers/shape.lua diff --git a/config/awesome/module/bling/helpers/time.lua b/config/awesome/modules/bling/helpers/time.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/helpers/time.lua rename to config/awesome/modules/bling/helpers/time.lua diff --git a/config/awesome/module/bling/icons/layouts/centered.png b/config/awesome/modules/bling/icons/layouts/centered.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/icons/layouts/centered.png rename to config/awesome/modules/bling/icons/layouts/centered.png diff --git a/config/awesome/module/bling/icons/layouts/deck.png b/config/awesome/modules/bling/icons/layouts/deck.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/icons/layouts/deck.png rename to config/awesome/modules/bling/icons/layouts/deck.png diff --git a/config/awesome/module/bling/icons/layouts/equalarea.png b/config/awesome/modules/bling/icons/layouts/equalarea.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/icons/layouts/equalarea.png rename to config/awesome/modules/bling/icons/layouts/equalarea.png diff --git a/config/awesome/module/bling/icons/layouts/horizontal.png b/config/awesome/modules/bling/icons/layouts/horizontal.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/icons/layouts/horizontal.png rename to config/awesome/modules/bling/icons/layouts/horizontal.png diff --git a/config/awesome/module/bling/icons/layouts/mstab.png b/config/awesome/modules/bling/icons/layouts/mstab.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/icons/layouts/mstab.png rename to config/awesome/modules/bling/icons/layouts/mstab.png diff --git a/config/awesome/module/bling/icons/layouts/vertical.png b/config/awesome/modules/bling/icons/layouts/vertical.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/icons/layouts/vertical.png rename to config/awesome/modules/bling/icons/layouts/vertical.png diff --git a/config/awesome/module/bling/images/bling_banner-2x.png b/config/awesome/modules/bling/images/bling_banner-2x.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/images/bling_banner-2x.png rename to config/awesome/modules/bling/images/bling_banner-2x.png diff --git a/config/awesome/module/bling/images/bling_banner.png b/config/awesome/modules/bling/images/bling_banner.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/images/bling_banner.png rename to config/awesome/modules/bling/images/bling_banner.png diff --git a/config/awesome/module/bling/init.lua b/config/awesome/modules/bling/init.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/init.lua rename to config/awesome/modules/bling/init.lua diff --git a/config/awesome/module/bling/layout/centered.lua b/config/awesome/modules/bling/layout/centered.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/layout/centered.lua rename to config/awesome/modules/bling/layout/centered.lua diff --git a/config/awesome/module/bling/layout/deck.lua b/config/awesome/modules/bling/layout/deck.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/layout/deck.lua rename to config/awesome/modules/bling/layout/deck.lua diff --git a/config/awesome/module/bling/layout/equalarea.lua b/config/awesome/modules/bling/layout/equalarea.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/layout/equalarea.lua rename to config/awesome/modules/bling/layout/equalarea.lua diff --git a/config/awesome/module/bling/layout/horizontal.lua b/config/awesome/modules/bling/layout/horizontal.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/layout/horizontal.lua rename to config/awesome/modules/bling/layout/horizontal.lua diff --git a/config/awesome/module/bling/layout/init.lua b/config/awesome/modules/bling/layout/init.lua old mode 100644 new mode 100755 similarity index 88% rename from config/awesome/module/bling/layout/init.lua rename to config/awesome/modules/bling/layout/init.lua index 223d9d4..de30ed6 --- a/config/awesome/module/bling/layout/init.lua +++ b/config/awesome/modules/bling/layout/init.lua @@ -37,7 +37,9 @@ local layouts = { for _, layout_name in ipairs(layouts) do local icon_raw = get_layout_icon_path(layout_name) - beautiful["layout_" .. layout_name] = get_icon(icon_raw) + if beautiful["layout_" .. layout_name] == nil then + beautiful["layout_" .. layout_name] = get_icon(icon_raw) + end M[layout_name] = require(... .. "." .. layout_name) end diff --git a/config/awesome/module/bling/layout/mstab.lua b/config/awesome/modules/bling/layout/mstab.lua old mode 100644 new mode 100755 similarity index 89% rename from config/awesome/module/bling/layout/mstab.lua rename to config/awesome/modules/bling/layout/mstab.lua index 93ceb0e..88ce0cb --- a/config/awesome/module/bling/layout/mstab.lua +++ b/config/awesome/modules/bling/layout/mstab.lua @@ -88,30 +88,17 @@ function update_tabbar( }) -- Change visibility of the tab bar when layout, selected tag or number of clients (visible, master, slave) changes - local function adjust_visiblity(t) - s.tabbar.visible = (#t:clients() - t.master_count > 1) - and (t.layout.name == mylayout.name) + local function adjust_visibility() + local name = awful.layout.getname( awful.layout.get( s ) ) + s.tabbar.visible = (name == mylayout.name) end - tag.connect_signal("property::selected", function(t) - adjust_visiblity(t) - end) - tag.connect_signal("property::layout", function(t, layout) - adjust_visiblity(t) - end) - tag.connect_signal("tagged", function(t, c) - adjust_visiblity(t) - end) - tag.connect_signal("untagged", function(t, c) - adjust_visiblity(t) - end) - tag.connect_signal("property::master_count", function(t) - adjust_visiblity(t) - end) - client.connect_signal("property::minimized", function(c) - local t = c.first_tag - adjust_visiblity(t) - end) + tag.connect_signal("property::selected", adjust_visibility) + tag.connect_signal("property::layout", adjust_visibility) + tag.connect_signal("tagged", adjust_visibility) + tag.connect_signal("untagged", adjust_visibility) + tag.connect_signal("property::master_count", adjust_visibility) + client.connect_signal("property::minimized", adjust_visibility) end -- update the tabbar size and position (to support gap size change on the fly) diff --git a/config/awesome/module/bling/layout/vertical.lua b/config/awesome/modules/bling/layout/vertical.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/layout/vertical.lua rename to config/awesome/modules/bling/layout/vertical.lua diff --git a/config/awesome/module/bling/module/flash_focus.lua b/config/awesome/modules/bling/module/flash_focus.lua old mode 100644 new mode 100755 similarity index 92% rename from config/awesome/module/bling/module/flash_focus.lua rename to config/awesome/modules/bling/module/flash_focus.lua index 246f4a3..35f3cf0 --- a/config/awesome/module/bling/module/flash_focus.lua +++ b/config/awesome/modules/bling/module/flash_focus.lua @@ -27,11 +27,6 @@ local flashfocus = function(c) end end) end - - -- Bring the focused client to the top - if c then - c:raise() - end end local enable = function() diff --git a/config/awesome/module/bling/module/init.lua b/config/awesome/modules/bling/module/init.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/module/init.lua rename to config/awesome/modules/bling/module/init.lua diff --git a/config/awesome/module/bling/module/scratchpad.lua b/config/awesome/modules/bling/module/scratchpad.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/module/scratchpad.lua rename to config/awesome/modules/bling/module/scratchpad.lua diff --git a/config/awesome/module/bling/module/tabbed.lua b/config/awesome/modules/bling/module/tabbed.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/module/tabbed.lua rename to config/awesome/modules/bling/module/tabbed.lua diff --git a/config/awesome/module/bling/module/tiled_wallpaper.lua b/config/awesome/modules/bling/module/tiled_wallpaper.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/module/tiled_wallpaper.lua rename to config/awesome/modules/bling/module/tiled_wallpaper.lua diff --git a/config/awesome/module/bling/module/wallpaper.lua b/config/awesome/modules/bling/module/wallpaper.lua old mode 100644 new mode 100755 similarity index 99% rename from config/awesome/module/bling/module/wallpaper.lua rename to config/awesome/modules/bling/module/wallpaper.lua index 1252bee..e7bddf6 --- a/config/awesome/module/bling/module/wallpaper.lua +++ b/config/awesome/modules/bling/module/wallpaper.lua @@ -347,7 +347,7 @@ function setup(args) end, }) end - if awesome.version == "v4.3" then + if awesome.version == "v4.3" or awesome.version == "4.3" then awful.screen.connect_for_each_screen(set_wallpaper) else screen.connect_signal("request::wallpaper", set_wallpaper) diff --git a/config/awesome/module/bling/module/window_swallowing.lua b/config/awesome/modules/bling/module/window_swallowing.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/module/window_swallowing.lua rename to config/awesome/modules/bling/module/window_swallowing.lua diff --git a/config/awesome/module/bling/signal/init.lua b/config/awesome/modules/bling/signal/init.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/signal/init.lua rename to config/awesome/modules/bling/signal/init.lua diff --git a/config/awesome/module/bling/signal/playerctl/init.lua b/config/awesome/modules/bling/signal/playerctl/init.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/signal/playerctl/init.lua rename to config/awesome/modules/bling/signal/playerctl/init.lua diff --git a/config/awesome/module/bling/signal/playerctl/playerctl_cli.lua b/config/awesome/modules/bling/signal/playerctl/playerctl_cli.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/signal/playerctl/playerctl_cli.lua rename to config/awesome/modules/bling/signal/playerctl/playerctl_cli.lua diff --git a/config/awesome/module/bling/signal/playerctl/playerctl_lib.lua b/config/awesome/modules/bling/signal/playerctl/playerctl_lib.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/signal/playerctl/playerctl_lib.lua rename to config/awesome/modules/bling/signal/playerctl/playerctl_lib.lua diff --git a/config/awesome/module/bling/theme-var-template.lua b/config/awesome/modules/bling/theme-var-template.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/theme-var-template.lua rename to config/awesome/modules/bling/theme-var-template.lua diff --git a/config/awesome/module/bling/widget/app_launcher/init.lua b/config/awesome/modules/bling/widget/app_launcher/init.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/app_launcher/init.lua rename to config/awesome/modules/bling/widget/app_launcher/init.lua diff --git a/config/awesome/module/bling/widget/app_launcher/prompt.lua b/config/awesome/modules/bling/widget/app_launcher/prompt.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/app_launcher/prompt.lua rename to config/awesome/modules/bling/widget/app_launcher/prompt.lua diff --git a/config/awesome/module/bling/widget/init.lua b/config/awesome/modules/bling/widget/init.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/init.lua rename to config/awesome/modules/bling/widget/init.lua diff --git a/config/awesome/module/bling/widget/tabbar/boxes.lua b/config/awesome/modules/bling/widget/tabbar/boxes.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/tabbar/boxes.lua rename to config/awesome/modules/bling/widget/tabbar/boxes.lua diff --git a/config/awesome/module/bling/widget/tabbar/default.lua b/config/awesome/modules/bling/widget/tabbar/default.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/tabbar/default.lua rename to config/awesome/modules/bling/widget/tabbar/default.lua diff --git a/config/awesome/module/bling/widget/tabbar/modern.lua b/config/awesome/modules/bling/widget/tabbar/modern.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/tabbar/modern.lua rename to config/awesome/modules/bling/widget/tabbar/modern.lua diff --git a/config/awesome/module/bling/widget/tabbar/pure.lua b/config/awesome/modules/bling/widget/tabbar/pure.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/tabbar/pure.lua rename to config/awesome/modules/bling/widget/tabbar/pure.lua diff --git a/config/awesome/module/bling/widget/tabbed_misc/custom_tasklist.lua b/config/awesome/modules/bling/widget/tabbed_misc/custom_tasklist.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/tabbed_misc/custom_tasklist.lua rename to config/awesome/modules/bling/widget/tabbed_misc/custom_tasklist.lua diff --git a/config/awesome/module/bling/widget/tabbed_misc/init.lua b/config/awesome/modules/bling/widget/tabbed_misc/init.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/tabbed_misc/init.lua rename to config/awesome/modules/bling/widget/tabbed_misc/init.lua diff --git a/config/awesome/module/bling/widget/tabbed_misc/titlebar_indicator.lua b/config/awesome/modules/bling/widget/tabbed_misc/titlebar_indicator.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/tabbed_misc/titlebar_indicator.lua rename to config/awesome/modules/bling/widget/tabbed_misc/titlebar_indicator.lua diff --git a/config/awesome/module/bling/widget/tag_preview.lua b/config/awesome/modules/bling/widget/tag_preview.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/tag_preview.lua rename to config/awesome/modules/bling/widget/tag_preview.lua diff --git a/config/awesome/module/bling/widget/task_preview.lua b/config/awesome/modules/bling/widget/task_preview.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/bling/widget/task_preview.lua rename to config/awesome/modules/bling/widget/task_preview.lua diff --git a/config/awesome/module/bling/widget/window_switcher.lua b/config/awesome/modules/bling/widget/window_switcher.lua old mode 100644 new mode 100755 similarity index 95% rename from config/awesome/module/bling/widget/window_switcher.lua rename to config/awesome/modules/bling/widget/window_switcher.lua index ac835a5..97dbeb1 --- a/config/awesome/module/bling/widget/window_switcher.lua +++ b/config/awesome/modules/bling/widget/window_switcher.lua @@ -84,12 +84,14 @@ local function draw_widget( name_focus_color, icon_valign, icon_width, - mouse_keys + mouse_keys, + filterClients ) + filterClients = filterClients or awful.widget.tasklist.filter.currenttags local tasklist_widget = type == "thumbnail" and awful.widget.tasklist({ screen = awful.screen.focused(), - filter = awful.widget.tasklist.filter.currenttags, + filter = filterClients, buttons = mouse_keys, style = { font = name_font, @@ -167,7 +169,7 @@ local function draw_widget( }) or awful.widget.tasklist({ screen = awful.screen.focused(), - filter = awful.widget.tasklist.filter.currenttags, + filter = filterClients, buttons = mouse_keys, style = { font = name_font, @@ -274,6 +276,9 @@ local enable = function(opts) local scroll_previous_key = opts.scroll_previous_key or 4 local scroll_next_key = opts.scroll_next_key or 5 + local cycleClientsByIdx = opts.cycleClientsByIdx or awful.client.focus.byidx + local filterClients = opts.filterClients or awful.widget.tasklist.filter.currenttags + local window_switcher_box = awful.popup({ bg = "#00000000", visible = false, @@ -308,7 +313,7 @@ local enable = function(opts) modifiers = { "Any" }, button = scroll_previous_key, on_press = function() - awful.client.focus.byidx(-1) + cycleClientsByIdx(-1) end, }), @@ -316,7 +321,7 @@ local enable = function(opts) modifiers = { "Any" }, button = scroll_next_key, on_press = function() - awful.client.focus.byidx(1) + cycleClientsByIdx(1) end, }) ) @@ -343,21 +348,21 @@ local enable = function(opts) end, [cycle_key] = function() - awful.client.focus.byidx(1) + cycleClientsByIdx(1) end, [previous_key] = function() - awful.client.focus.byidx(1) + cycleClientsByIdx(1) end, [next_key] = function() - awful.client.focus.byidx(-1) + cycleClientsByIdx(-1) end, [vim_previous_key] = function() - awful.client.focus.byidx(1) + cycleClientsByIdx(1) end, [vim_next_key] = function() - awful.client.focus.byidx(-1) + cycleClientsByIdx(-1) end, } @@ -445,8 +450,10 @@ local enable = function(opts) name_focus_color, icon_valign, icon_width, - mouse_keys + mouse_keys, + filterClients ) + window_switcher_box.screen = awful.screen.focused() window_switcher_box.visible = true end) end diff --git a/config/awesome/modules/color/LICENSE b/config/awesome/modules/color/LICENSE new file mode 100755 index 0000000..5207ca9 --- /dev/null +++ b/config/awesome/modules/color/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 andOrlando + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/config/awesome/modules/color/README.md b/config/awesome/modules/color/README.md new file mode 100755 index 0000000..b47ca79 --- /dev/null +++ b/config/awesome/modules/color/README.md @@ -0,0 +1,64 @@ +# color +Contains a bunch of useful function for conversion as well as well as a very nice api for just colors in general. + +It can probably be easiest explained with a code snippet: +```lua +color = require 'color' +dark_green = color.color { r=10, g=30, b=10 } + +dark_green.h, dark_green.s, dark_green.l +-- Returns 120.0 0.5 0.07843137254902 + +dark_green.h = 60 +dark_green.r, dark_green.g, dark_green.b +-- Returns 30.0 30.0 10.0 +``` +As you can see, when you update one variable all the rest update with it. This is done in a relatively intelligent +manner, however. Should you, in the example of the code snippet, update h, s or l again, it won't try to update the +other values. Only when you access non-hsl entries will it update them. Once it's updated, you can access anything +without it updating further until you change something again. + +# What's the point though? +you can do cool stuff like this! + +![Spinny Volume Thing](./images/spinny.gif) + +I do this by keeping track of two colors, one for the background and one for +the foreground. Whenever I go forwards a color, I increment the hue by 40 for +both, and whenever I go backwards I do the opposite. The two colors are exactly +40 hues away. Then, to actually change the color of the arcchart I just use the +hex parameter. The actual animation/easing is done with my +other overengineered ricing project, [rubato](https://github.com/andOrlando/rubato). +While you can only see the colors if your volume is at like 36,000% (the grey +is 1-100%, the color changing one is 101-200%), it was a little annoying to have +it not be smooth should I ever want to blow out my speakers. + +# Useful functions and more info +Furthermore, it comes with a couple nice functions too: +- `color.utils.hex_to_rgb`: takes in a string hex value (no # as of now) and returns rgb values from 0-255 +- `color.utils.rgb_to_hex`: takes in a table with entries r, g and b (or just as the first three entires) and returns a string hex value (with no #) +- `color.utils.rgb_to_hsl`: takes in a table with entries r, g and b (or just as the first three entires) and returns a table with h, s and l +- `color.utils.hsl_to_rgb`: takes in a table with entries h, s and l (or just as the first three entires) and returns a table with r, g and b +- `color.transition`: takes two color objects and a method (constants defined in transition) and returns a function that transitions between the two colors. 0 would be color 1, 1 would be color 2, everything else is a color in between. For best results you probably want to use the HSL mode, + +A couple more notes about the color class: +- r, g and b must be values between 0 and 255 +- s and l must be between 0 and 1, whereas h must be between 0 and 360 +- a must be between 0 and 1 +- by setting `disable_hsl=true` on initialization, you can prevent to hex <-> rgb conversions +- by default it outputs it with a hashtag. If you don't want it to do this, set `hashtag=false` on initialization. + +All the math was taken from [here](https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/). +I basically just put it into lua in a nice way. Me actaully kinda learning how to make this nice api comes +from [here](https://ebens.me/post/implementing-proper-gettersetters-in-lua). Please pardon my godawful codestyle, +I just do what I think looks pleasent, which I suppose is fitting for a ricer. + +# TODO +- [ ] cool name?? (I do have color on luarocks, which is a pretty good name, but idk) +- [X] Add better # support for hex +- [ ] Add better checks (asserts and stuff) +- [X] Add alpha and toggles for whether or not to include it +- [ ] Do better setting of default methods (`obj._props.r = args.r or 0` kinda thing) +- [X] Make do good readme +- [X] Have smarter input reading (as in, don't require a table with r, g and b, look at first three indices +- [ ] Allow for 0-1 rgb diff --git a/config/awesome/modules/color/color-1.1-1.rockspec b/config/awesome/modules/color/color-1.1-1.rockspec new file mode 100755 index 0000000..4ea6d28 --- /dev/null +++ b/config/awesome/modules/color/color-1.1-1.rockspec @@ -0,0 +1,22 @@ +package = "color" +version = "1.1-1" +source = { + url = "git+https://github.com/andOrlando/color.git" +} +description = { + detailed = [[ +Allows for easy access to rgba, hsla or hex by only defining one of them as well as efficient computation of other values when one changes. It also has a couple useful color conversion methods like hex_to_rgba, rgba_to_hex, rgb_to_hsl and hsl_to_rgb and the class uses those methods to calculate the other values when one value updates. + +The main color class itself contains h, s, l, r, g, b and hex values which, when one is updated, updates all the others (but it only does it when the values are needed, ensuring no more calculations than necessary) + +There's a better description in the github's README + ]], + homepage = "https://github.com/andOrlando/color", + license = "MIT" +} +build = { + type = "builtin", + modules = { + color = "color.lua" + } +} diff --git a/config/awesome/modules/color/color.lua b/config/awesome/modules/color/color.lua new file mode 100755 index 0000000..66a99d0 --- /dev/null +++ b/config/awesome/modules/color/color.lua @@ -0,0 +1,170 @@ +local utils = require(COLOR_DIR.."utils") + +--constants for clarity +local ANY = {"r", "g", "b", "h", "s", "l", "hex", "a"} +local ANYSUBHEX = {"r", "g", "b", "h", "s", "l", "a"} +local RGB = {"r", "g", "b"} +local HSL = {"h", "s", "l"} +local HEX = {"hex"} + +--create a color object +local function color(args) + -- The object that will be returned + local obj = {_props = {}} + + -- Default properties here + obj._props.r = args.r or 0 + obj._props.g = args.g or 0 + obj._props.b = args.b or 0 + obj._props.h = args.h or 0 + obj._props.s = args.s or 0 + obj._props.l = args.l or 0 + obj._props.a = args.a or 1 + obj._props.hex = args.hex and args.hex:gsub("#", "") or "000000" + + obj._props.small_rgb = args.small_rgb or false + + -- Default actual normal properties + obj.hashtag = args.hashtag or true + obj.disable_hsl = args.disable_hsl or false + + -- Set access to any + obj._access = ANY + + --temporary values + --alpha since it can be nil and don't wanna overwrite, + --hex_no_alpha just as a placeholder in _alphaize_hex + local alpha, hex_no_alpha + + -- Methods and stuff + function obj:_hex_to_rgba() + obj._props.r, obj._props.g, obj._props.b, alpha = utils.hex_to_rgba(obj._props.hex) + if alpha then self._props.a = alpha end + if obj._props.small_rgb then + obj._props.r = math.floor(obj._props.r / 255) + obj._props.g = math.floor(obj._props.g / 255) + obj._props.b = math.floor(obj._props.b / 255) + end + end + function obj:_rgba_to_hex() + obj._props.hex = utils.rgba_to_hex(obj._props) + end + function obj:_rgb_to_hsl() + obj._props.h, obj._props.s, obj._props.l = utils.rgb_to_hsl(obj._props) + end + function obj:_hsl_to_rgb() + obj._props.r, obj._props.g, obj._props.b = utils.hsl_to_rgb(obj._props) + end + function obj:_alphaize_hex() + hex_no_alpha = #obj._props.hex == 6 and obj._props.hex or obj._props.hex:sub(1, 6) + obj._props.hex = hex_no_alpha..(obj._props.a ~= 1 + and string.format("%02x", math.floor(obj._props.a*255)) or "") + end + function obj:set_no_update(key, value) + obj._props[key] = value + end + + -- Initially set other values + if obj._props.r ~= 0 or obj._props.g ~= 0 or obj._props.b ~= 0 then + obj:_rgba_to_hex() + if not obj.disable_hsl then obj:_rgb_to_hsl() end + + elseif obj._props.hex ~= "000000" then + obj:_hex_to_rgba() + if not obj.disable_hsl then obj:_rgb_to_hsl() end + + elseif obj._props.h ~= 0 or obj._props.s ~= 0 or obj._props.l ~= 0 then + obj:_hsl_to_rgb() + obj:_rgba_to_hex() + + end --otherwise it's just black and everything is correct already + + + -- Set up the metatable + local mt = getmetatable(obj) or {} + + -- Check if it's already in _props to return it + -- TODO: Only remake values if necessary + mt.__index = function(self, key) + if self._props[key] then + -- Check if to just return nil for hsl + if obj.disable_hsl and utils.contains(HSL, key) then return self._props[key] end + + -- Check if something in ANY isn't currently accessible + if not utils.contains(obj._access, key) and utils.contains(ANY, key) then + + if obj._access == RGB then + self:_rgba_to_hex() + if not obj.disable_hsl then obj:_rgb_to_hsl() end + + elseif obj._access == HEX then + self:_rgba_to_hex() + if not obj.disable_hsl then obj:_rgb_to_hsl() end + + elseif obj._access == HSL then + self:_hsl_to_rgb() + self:_rgba_to_hex() + + elseif obj._access == ANYSUBHEX then + self:_alphaize_hex() + end + + -- Reset accessibleness + obj._access = ANY + end + + -- Check for hashtaginess + if obj.hashtag and key == "hex" then return "#"..self._props.hex end + + return self._props[key] + + else return rawget(self, key) end + end + + mt.__newindex = function(self, key, value) + if self._props[key] ~= nil then + + + -- Set what values are currently accessible + if utils.contains(RGB, key) then obj._access = RGB + elseif utils.contains(HSL, key) and not obj.disable_hsl then obj._access = HSL + elseif key == "hex" then obj._access = HEX + elseif key == "a" then obj._access = ANYSUBHEX + + -- If it's not any of those and is small_rgb then update the rgb values + elseif key == "small_rgb" and value ~= obj._props.small_rgb then + if obj._props.small_rgb then + obj._props.r = obj._props.r / 255 + obj._props.g = obj._props.g / 255 + obj._props.b = obj._props.b / 255 + else + obj._props.r = math.floor(obj._props.r * 255) + obj._props.g = math.floor(obj._props.g * 255) + obj._props.b = math.floor(obj._props.b * 255) + end + end + + -- Set the new value + self._props[key] = value + + -- If it's not part of _props just normally set it + else rawset(self, key, value) end + end + + -- performs an operation on the color and returns the new color + local function operate(new, operator) + local newcolor = color {r=obj.r, g=obj.g, b=obj.b} + local key = new:match("%a+") + if operator == "+" then newcolor[key] = newcolor[key] + new:match("[%d\\.]+") + elseif operator == "-" then newcolor[key] = newcolor[key] - new:match("[%d\\.]+") end + return newcolor + end + + mt.__add = function(_, new) return operate(new, "+") end + mt.__sub = function(_, new) return operate(new, "-") end + + setmetatable(obj, mt) + return obj +end + +return color diff --git a/config/awesome/modules/color/images/spinny.gif b/config/awesome/modules/color/images/spinny.gif new file mode 100755 index 0000000..ea28e12 Binary files /dev/null and b/config/awesome/modules/color/images/spinny.gif differ diff --git a/config/awesome/modules/color/init.lua b/config/awesome/modules/color/init.lua new file mode 100755 index 0000000..db86c9b --- /dev/null +++ b/config/awesome/modules/color/init.lua @@ -0,0 +1,7 @@ +COLOR_DIR = (...):match("(.-)[^%.]+$").."color." + +return { + color = require(COLOR_DIR.."color"), + utils = require(COLOR_DIR.."utils"), + transition = require(COLOR_DIR.."transition"), +} diff --git a/config/awesome/modules/color/tags b/config/awesome/modules/color/tags new file mode 100755 index 0000000..3cd7a9d --- /dev/null +++ b/config/awesome/modules/color/tags @@ -0,0 +1,26 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ +!_TAG_PROGRAM_NAME Exuberant Ctags // +!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ +!_TAG_PROGRAM_VERSION Development // +color color.lua /^local function color(args)$/;" f +contains utils.lua /^local function contains(obj, value)$/;" f +hex_to_rgba utils.lua /^local function hex_to_rgba(hex)$/;" f +hsl_to_rgb utils.lua /^local function hsl_to_rgb(obj)$/;" f +if method transition.lua /^ if method == self.RGB then return function(t) return color {$/;" f +mt.__add color.lua /^ mt.__add = function(_, new) return operate(new, "+") end$/;" f +mt.__index color.lua /^ mt.__index = function(self, key)$/;" f +mt.__newindex color.lua /^ mt.__newindex = function(self, key, value)$/;" f +mt.__sub color.lua /^ mt.__sub = function(_, new) return operate(new, "-") end$/;" f +obj:_alphaize_hex color.lua /^ function obj:_alphaize_hex()$/;" f +obj:_hex_to_rgba color.lua /^ function obj:_hex_to_rgba()$/;" f +obj:_hsl_to_rgb color.lua /^ function obj:_hsl_to_rgb()$/;" f +obj:_rgb_to_hsl color.lua /^ function obj:_rgb_to_hsl()$/;" f +obj:_rgba_to_hex color.lua /^ function obj:_rgba_to_hex()$/;" f +obj:set_no_update color.lua /^ function obj:set_no_update(key, value)$/;" f +operate color.lua /^ local function operate(new, operator)$/;" f +rgb_to_hsl utils.lua /^local function rgb_to_hsl(obj)$/;" f +rgba_to_hex utils.lua /^local function rgba_to_hex(obj)$/;" f +round utils.lua /^local function round(x, p)$/;" f +setmetatable(transition, {__call transition.lua /^setmetatable(transition, {__call = function(self, col1, col2, method)$/;" f diff --git a/config/awesome/modules/color/transition.lua b/config/awesome/modules/color/transition.lua new file mode 100755 index 0000000..e73656f --- /dev/null +++ b/config/awesome/modules/color/transition.lua @@ -0,0 +1,26 @@ +local color = require(COLOR_DIR.."color") + +--0 is rgb +--1 is hsl +--2 is hsl but backwards + +local transition = { + RGB = 0, + HSL = 1, + HSLR = 2, +} + +setmetatable(transition, {__call = function(self, col1, col2, method) + if method == self.RGB then return function(t) return color { + r = math.min(math.max(col1.r + t * (col2.r - col1.r), 0), 255), + g = math.min(math.max(col1.g + t * (col2.g - col1.g), 0), 255), + b = math.min(math.max(col1.b + t * (col2.b - col1.b), 0), 255) } + end + else return function(t) return color { + h = math.max(col1.h + t * (col2.h - (method == self.HSLR and 360 or 0) - col1.h), 0) % 360, + s = math.min(math.max(col1.s + t * (col2.s - col1.s), 0), 1), + l = math.min(math.max(col1.l + t * (col2.l - col1.l), 0), 1) } + end end +end}) + +return transition diff --git a/config/awesome/modules/color/utils.lua b/config/awesome/modules/color/utils.lua new file mode 100755 index 0000000..bdcdc62 --- /dev/null +++ b/config/awesome/modules/color/utils.lua @@ -0,0 +1,132 @@ +-- much help from https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/ +-- basically a lua implementation of the above link + +-- Helper "round" method +local function round(x, p) + local power = 10 ^ (p or 0) + return (x * power + 0.5 - (x * power + 0.5) % 1) / power +end + +-- Useful public methods +local function hex_to_rgba(hex) + hex = hex:gsub("#", "") + return + tonumber("0x"..hex:sub(1,2)), + tonumber("0x"..hex:sub(3,4)), + tonumber("0x"..hex:sub(5,6)), + --if alpha exists in hex, return it + #hex == 8 and tonumber("0x"..hex:sub(7,8)) or nil +end + +local function rgba_to_hex(obj) + local r = obj.r or obj[1] + local g = obj.g or obj[2] + local b = obj.b or obj[3] + local a = obj.a or 1 + local h = (obj.hashtag or obj[4]) and "#" or "" + return h..string.format("%02x%02x%02x", + math.floor(r), + math.floor(g), + math.floor(b)) + --this part only shows the alpha channel if it's not 1 + ..(a ~= 1 and string.format("%02x", math.floor(a*255)) or "") +end + +--disclaimer I have no idea what any of the math does +local function rgb_to_hsl(obj) + local r = obj.r or obj[1] + local g = obj.g or obj[2] + local b = obj.b or obj[3] + + local R, G, B = r / 255, g / 255, b / 255 + local max, min = math.max(R, G, B), math.min(R, G, B) + local l, s, h + + -- Get luminance + l = (max + min) / 2 + + -- short circuit saturation and hue if it's grey to prevent divide by 0 + if max == min then + s = 0 + h = obj.h or obj[4] or 0 + return 0, 0, l + end + + -- Get saturation + if l <= 0.5 then s = (max - min) / (max + min) + else s = (max - min) / (2 - max - min) + end + + -- Get hue + if max == R then h = (G - B) / (max - min) * 60 + elseif max == G then h = (2.0 + (B - R) / (max - min)) * 60 + else h = (4.0 + (R - G) / (max - min)) * 60 + end + + -- Make sure it goes around if it's negative (hue is a circle) + if h ~= 360 then h = h % 360 end + + return h, s, l +end + +--no clue about any of this either +local function hsl_to_rgb(obj) + local h = obj.h or obj[1] + local s = obj.s or obj[2] + local l = obj.l or obj[3] + + local temp1, temp2, temp_r, temp_g, temp_b, temp_h + + -- Set the temp variables + if l <= 0.5 then temp1 = l * (s + 1) + else temp1 = l + s - l * s + end + + temp2 = l * 2 - temp1 + + temp_h = h / 360 + + temp_r = temp_h + 1/3 + temp_g = temp_h + temp_b = temp_h - 1/3 + + + -- Make sure it's between 0 and 1 + if temp_r ~= 1 then temp_r = temp_r % 1 end + if temp_g ~= 1 then temp_g = temp_g % 1 end + if temp_b ~= 1 then temp_b = temp_b % 1 end + + local rgb = {} + + -- Bunch of tests + -- Once again I haven't the foggiest what any of this does + for _, v in pairs({{temp_r, "r"}, {temp_g, "g"}, {temp_b, "b"}}) do + + if v[1] * 6 < 1 then rgb[v[2]] = temp2 + (temp1 - temp2) * v[1] * 6 + elseif v[1] * 2 < 1 then rgb[v[2]] = temp1 + elseif v[1] * 3 < 2 then rgb[v[2]] = temp2 + (temp1 - temp2) * (2/3 - v[1]) * 6 + else rgb[v[2]] = temp2 + end + + end + + return + round(rgb.r * 255), + round(rgb.g * 255), + round(rgb.b * 255) +end + +--check if table contains item +local function contains(obj, value) + for _, v in pairs(obj) do if v == value then return true end end + return false +end + +return { + hex_to_rgba = hex_to_rgba, + rgba_to_hex = rgba_to_hex, + rgb_to_hsl = rgb_to_hsl, + hsl_to_rgb = hsl_to_rgb, + contains = contains, + copy = copy +} diff --git a/config/awesome/module/exit-screen.lua b/config/awesome/modules/exit-screen.lua old mode 100644 new mode 100755 similarity index 89% rename from config/awesome/module/exit-screen.lua rename to config/awesome/modules/exit-screen.lua index 63b0a61..067bf63 --- a/config/awesome/module/exit-screen.lua +++ b/config/awesome/modules/exit-screen.lua @@ -4,7 +4,7 @@ local wibox = require("wibox") local beautiful = require("beautiful") local dpi = beautiful.xresources.apply_dpi local helpers = require("helpers") -local lock_screen = require("module.lockscreen") +local lock_screen = require("modules.lockscreen") lock_screen.init() -- Icons @@ -52,7 +52,7 @@ local create_button = function(symbol, hover_color, text, command) align = "center", valign = "center", font = icon_font, - markup = helpers.colorize_text(symbol, beautiful.xforeground .. 55), + markup = helpers.ui.colorize_text(symbol, beautiful.lighter_xbackground), widget = wibox.widget.textbox(), }) @@ -66,8 +66,8 @@ local create_button = function(symbol, hover_color, text, command) forced_height = button_size, forced_width = button_size, border_width = dpi(8), - border_color = button_bg, - shape = helpers.rrect(dpi(20)), + border_color = beautiful.lighter_xbackground, + shape = helpers.ui.rrect(beautiful.border_radius * 2), bg = button_bg, widget = wibox.container.background, }) @@ -77,15 +77,15 @@ local create_button = function(symbol, hover_color, text, command) end))) button:connect_signal("mouse::enter", function() - icon.markup = helpers.colorize_text(icon.text, hover_color) + icon.markup = helpers.ui.colorize_text(icon.text, hover_color) button.border_color = hover_color end) button:connect_signal("mouse::leave", function() - icon.markup = helpers.colorize_text(icon.text, beautiful.xforeground .. 55) - button.border_color = beautiful.widget_border_color + icon.markup = helpers.ui.colorize_text(icon.text, beautiful.lighter_xbackground) + button.border_color = beautiful.lighter_xbackground end) - helpers.add_hover_cursor(button, "hand1") + helpers.ui.add_hover_cursor(button, "hand1") return button end diff --git a/config/awesome/modules/init.lua b/config/awesome/modules/init.lua new file mode 100755 index 0000000..059d661 --- /dev/null +++ b/config/awesome/modules/init.lua @@ -0,0 +1,4 @@ +require(... .. ".better-resize") +require(... .. ".exit-screen") +require(... .. ".savefloats") +require(... .. ".window_switcher").enable() diff --git a/config/awesome/modules/json.lua b/config/awesome/modules/json.lua new file mode 100755 index 0000000..711ef78 --- /dev/null +++ b/config/awesome/modules/json.lua @@ -0,0 +1,388 @@ +-- +-- json.lua +-- +-- Copyright (c) 2020 rxi +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy of +-- this software and associated documentation files (the "Software"), to deal in +-- the Software without restriction, including without limitation the rights to +-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +-- of the Software, and to permit persons to whom the Software is furnished to do +-- so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in all +-- copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-- SOFTWARE. +-- + +local json = { _version = "0.1.2" } + +------------------------------------------------------------------------------- +-- Encode +------------------------------------------------------------------------------- + +local encode + +local escape_char_map = { + [ "\\" ] = "\\", + [ "\"" ] = "\"", + [ "\b" ] = "b", + [ "\f" ] = "f", + [ "\n" ] = "n", + [ "\r" ] = "r", + [ "\t" ] = "t", +} + +local escape_char_map_inv = { [ "/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if rawget(val, 1) ~= nil or next(val) == nil then + -- Treat as array -- check keys are valid and it is not sparse + local n = 0 + for k in pairs(val) do + if type(k) ~= "number" then + error("invalid table: mixed or invalid key types") + end + n = n + 1 + end + if n ~= #val then + error("invalid table: sparse array") + end + -- Encode + for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) + end + stack[val] = nil + return "[" .. table.concat(res, ",") .. "]" + + else + -- Treat as an object + for k, v in pairs(val) do + if type(k) ~= "string" then + error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) + end + stack[val] = nil + return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + -- Check for NaN, -inf and inf + if val ~= val or val <= -math.huge or val >= math.huge then + error("unexpected number value '" .. tostring(val) .. "'") + end + return string.format("%.14g", val) +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then + return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + + +function json.encode(val) + return ( encode(val) ) +end + + +------------------------------------------------------------------------------- +-- Decode +------------------------------------------------------------------------------- + +local parse + +local function create_set(...) + local res = {} + for i = 1, select("#", ...) do + res[ select(i, ...) ] = true + end + return res +end + +local space_chars = create_set(" ", "\t", "\r", "\n") +local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") +local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") +local literals = create_set("true", "false", "null") + +local literal_map = { + [ "true" ] = true, + [ "false" ] = false, + [ "null" ] = nil, +} + + +local function next_char(str, idx, set, negate) + for i = idx, #str do + if set[str:sub(i, i)] ~= negate then + return i + end + end + return #str + 1 +end + + +local function decode_error(str, idx, msg) + local line_count = 1 + local col_count = 1 + for i = 1, idx - 1 do + col_count = col_count + 1 + if str:sub(i, i) == "\n" then + line_count = line_count + 1 + col_count = 1 + end + end + error( string.format("%s at line %d col %d", msg, line_count, col_count) ) +end + + +local function codepoint_to_utf8(n) + -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa + local f = math.floor + if n <= 0x7f then + return string.char(n) + elseif n <= 0x7ff then + return string.char(f(n / 64) + 192, n % 64 + 128) + elseif n <= 0xffff then + return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) + elseif n <= 0x10ffff then + return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, + f(n % 4096 / 64) + 128, n % 64 + 128) + end + error( string.format("invalid unicode codepoint '%x'", n) ) +end + + +local function parse_unicode_escape(s) + local n1 = tonumber( s:sub(1, 4), 16 ) + local n2 = tonumber( s:sub(7, 10), 16 ) + -- Surrogate pair? + if n2 then + return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) + else + return codepoint_to_utf8(n1) + end +end + + +local function parse_string(str, i) + local res = "" + local j = i + 1 + local k = j + + while j <= #str do + local x = str:byte(j) + + if x < 32 then + decode_error(str, j, "control character in string") + + elseif x == 92 then -- `\`: Escape + res = res .. str:sub(k, j - 1) + j = j + 1 + local c = str:sub(j, j) + if c == "u" then + local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) + or str:match("^%x%x%x%x", j + 1) + or decode_error(str, j - 1, "invalid unicode escape in string") + res = res .. parse_unicode_escape(hex) + j = j + #hex + else + if not escape_chars[c] then + decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") + end + res = res .. escape_char_map_inv[c] + end + k = j + 1 + + elseif x == 34 then -- `"`: End of string + res = res .. str:sub(k, j - 1) + return res, j + 1 + end + + j = j + 1 + end + + decode_error(str, i, "expected closing quote for string") +end + + +local function parse_number(str, i) + local x = next_char(str, i, delim_chars) + local s = str:sub(i, x - 1) + local n = tonumber(s) + if not n then + decode_error(str, i, "invalid number '" .. s .. "'") + end + return n, x +end + + +local function parse_literal(str, i) + local x = next_char(str, i, delim_chars) + local word = str:sub(i, x - 1) + if not literals[word] then + decode_error(str, i, "invalid literal '" .. word .. "'") + end + return literal_map[word], x +end + + +local function parse_array(str, i) + local res = {} + local n = 1 + i = i + 1 + while 1 do + local x + i = next_char(str, i, space_chars, true) + -- Empty / end of array? + if str:sub(i, i) == "]" then + i = i + 1 + break + end + -- Read token + x, i = parse(str, i) + res[n] = x + n = n + 1 + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "]" then break end + if chr ~= "," then decode_error(str, i, "expected ']' or ','") end + end + return res, i +end + + +local function parse_object(str, i) + local res = {} + i = i + 1 + while 1 do + local key, val + i = next_char(str, i, space_chars, true) + -- Empty / end of object? + if str:sub(i, i) == "}" then + i = i + 1 + break + end + -- Read key + if str:sub(i, i) ~= '"' then + decode_error(str, i, "expected string for key") + end + key, i = parse(str, i) + -- Read ':' delimiter + i = next_char(str, i, space_chars, true) + if str:sub(i, i) ~= ":" then + decode_error(str, i, "expected ':' after key") + end + i = next_char(str, i + 1, space_chars, true) + -- Read value + val, i = parse(str, i) + -- Set + res[key] = val + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "}" then break end + if chr ~= "," then decode_error(str, i, "expected '}' or ','") end + end + return res, i +end + + +local char_func_map = { + [ '"' ] = parse_string, + [ "0" ] = parse_number, + [ "1" ] = parse_number, + [ "2" ] = parse_number, + [ "3" ] = parse_number, + [ "4" ] = parse_number, + [ "5" ] = parse_number, + [ "6" ] = parse_number, + [ "7" ] = parse_number, + [ "8" ] = parse_number, + [ "9" ] = parse_number, + [ "-" ] = parse_number, + [ "t" ] = parse_literal, + [ "f" ] = parse_literal, + [ "n" ] = parse_literal, + [ "[" ] = parse_array, + [ "{" ] = parse_object, +} + + +parse = function(str, idx) + local chr = str:sub(idx, idx) + local f = char_func_map[chr] + if f then + return f(str, idx) + end + decode_error(str, idx, "unexpected character '" .. chr .. "'") +end + + +function json.decode(str) + if type(str) ~= "string" then + error("expected argument of type string, got " .. type(str)) + end + local res, idx = parse(str, next_char(str, 1, space_chars, true)) + idx = next_char(str, idx, space_chars, true) + if idx <= #str then + decode_error(str, idx, "trailing garbage") + end + return res +end + + +return json diff --git a/config/awesome/module/layout-machi/LICENSE b/config/awesome/modules/layout-machi/LICENSE old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/layout-machi/LICENSE rename to config/awesome/modules/layout-machi/LICENSE diff --git a/config/awesome/module/layout-machi/README.md b/config/awesome/modules/layout-machi/README.md old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/layout-machi/README.md rename to config/awesome/modules/layout-machi/README.md diff --git a/config/awesome/module/layout-machi/editor.lua b/config/awesome/modules/layout-machi/editor.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/layout-machi/editor.lua rename to config/awesome/modules/layout-machi/editor.lua diff --git a/config/awesome/module/layout-machi/engine.lua b/config/awesome/modules/layout-machi/engine.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/layout-machi/engine.lua rename to config/awesome/modules/layout-machi/engine.lua diff --git a/config/awesome/module/layout-machi/icon.png b/config/awesome/modules/layout-machi/icon.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/layout-machi/icon.png rename to config/awesome/modules/layout-machi/icon.png diff --git a/config/awesome/module/layout-machi/init.lua b/config/awesome/modules/layout-machi/init.lua old mode 100644 new mode 100755 similarity index 92% rename from config/awesome/module/layout-machi/init.lua rename to config/awesome/modules/layout-machi/init.lua index 0074062..c2a1675 --- a/config/awesome/module/layout-machi/init.lua +++ b/config/awesome/modules/layout-machi/init.lua @@ -3,7 +3,7 @@ local layout = require(... .. ".layout") local editor = require(... .. ".editor") local switcher = require(... .. ".switcher") local default_editor = editor.default_editor -local default_layout = layout.create{ name_func = default_name } +local default_layout = layout.create{} local gcolor = require("gears.color") local beautiful = require("beautiful") diff --git a/config/awesome/module/layout-machi/layout.lua b/config/awesome/modules/layout-machi/layout.lua old mode 100644 new mode 100755 similarity index 90% rename from config/awesome/module/layout-machi/layout.lua rename to config/awesome/modules/layout-machi/layout.lua index d1ff077..6232c18 --- a/config/awesome/module/layout-machi/layout.lua +++ b/config/awesome/modules/layout-machi/layout.lua @@ -3,7 +3,9 @@ local machi_editor = require(this_package.."editor") local awful = require("awful") local gobject = require("gears.object") local capi = { - screen = screen + screen = screen, + client = client, + mouse = mouse, } local ERROR = 2 @@ -122,16 +124,43 @@ function module.set_geometry(c, area_lu, area_rd, useless_gap, border_width) end end --- TODO: the string need to be updated when its screen geometry changed. local function get_machi_tag_string(tag) - if tag.machi_tag_string == nil then - tag.machi_tag_string = - tostring(tag.screen.geometry.width) .. "x" .. tostring(tag.screen.geometry.height) .. "+" .. - tostring(tag.screen.geometry.x) .. "+" .. tostring(tag.screen.geometry.y) .. '+' .. tag.name - end - return tag.machi_tag_string + return tostring(tag.screen.geometry.width) .. "x" .. tostring(tag.screen.geometry.height) .. "+" .. + tostring(tag.screen.geometry.x) .. "+" .. tostring(tag.screen.geometry.y) .. '+' .. tag.name end +local function sanitize_geometry(geo, parent_area) + local x = geo.x + local width = geo.width + + if x + width > parent_area.x + parent_area.width then + x = parent_area.x + parent_area.width - width + end + if x < parent_area.x then + x = parent_area.x + end + if x + width > parent_area.x + parent_area.width then + width = parent_area.x + parent_area.width - x + end + geo.x = x + geo.width = width + + local y = geo.y + local height = geo.height + if y + height > parent_area.y + parent_area.height then + y = parent_area.y + parent_area.height - height + end + if y < parent_area.y then + y = parent_area.y + end + if y + height > parent_area.y + parent_area.height then + height = parent_area.y + parent_area.height - y + end + geo.y = y + geo.height = height +end + + function module.create(args_or_name, editor, default_cmd) local args if type(args_or_name) == "string" then @@ -284,6 +313,12 @@ function module.create(args_or_name, editor, default_cmd) height = c.height + c.border_width * 2, } + if not c.machi_no_sanitize_geometry then + sanitize_geometry(geo, screen.workarea) + else + c.machi_no_sanitize_geometry = nil + end + if not cd[c].placement and new_placement_cb then cd[c].placement = true new_placement_cb(c, instance, areas, geo) @@ -594,4 +629,26 @@ function module.placement.empty_then_fair(c, instance, areas, geometry) empty_then_maybe_fair(c, instance, areas, geometry, true) end +local function patch_awful_layout() + local old_alayout_move_handler = awful.layout.move_handler + if old_alayout_move_handler == nil then return end + -- Mostly the original one but does not swap clients in machi layouts. + function awful.layout.move_handler(c, context, ...) + if not c.floating and context == "mouse.move" then + local s = capi.mouse.screen + if s.selected_tag and s.selected_tag.layout and + s.selected_tag.layout.machi_set_cmd then + if c.screen ~= s then + c.screen = s + end + return + end + end + return old_alayout_move_handler(c, context, ...) + end + capi.client.disconnect_signal("request::geometry", old_alayout_move_handler) + capi.client.connect_signal("request::geometry", awful.layout.move_handler) +end +patch_awful_layout() + return module diff --git a/config/awesome/module/layout-machi/nested_layout_screenshot.png b/config/awesome/modules/layout-machi/nested_layout_screenshot.png old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/layout-machi/nested_layout_screenshot.png rename to config/awesome/modules/layout-machi/nested_layout_screenshot.png diff --git a/config/awesome/module/layout-machi/rc.patch b/config/awesome/modules/layout-machi/rc.patch old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/layout-machi/rc.patch rename to config/awesome/modules/layout-machi/rc.patch diff --git a/config/awesome/module/layout-machi/switcher.lua b/config/awesome/modules/layout-machi/switcher.lua old mode 100644 new mode 100755 similarity index 99% rename from config/awesome/module/layout-machi/switcher.lua rename to config/awesome/modules/layout-machi/switcher.lua index 5e8328a..da5ee32 --- a/config/awesome/module/layout-machi/switcher.lua +++ b/config/awesome/modules/layout-machi/switcher.lua @@ -478,6 +478,7 @@ function module.start(c, exit_keys) end c:emit_signal("request::activate", "mouse.move", {raise=false}) c:raise() + c.machi_no_sanitize_geometry = true awful.layout.arrange(screen) tablist = nil diff --git a/config/awesome/module/lockscreen/init.lua b/config/awesome/modules/lockscreen/init.lua old mode 100644 new mode 100755 similarity index 73% rename from config/awesome/module/lockscreen/init.lua rename to config/awesome/modules/lockscreen/init.lua index 5a9f122..1e3daf6 --- a/config/awesome/module/lockscreen/init.lua +++ b/config/awesome/modules/lockscreen/init.lua @@ -4,7 +4,7 @@ local gfs = require("gears.filesystem") local lock_screen = {} local config_dir = gfs.get_configuration_dir() -package.cpath = package.cpath .. ";" .. config_dir .. "module/lockscreen/lib/?.so;" +package.cpath = package.cpath .. ";" .. config_dir .. "modules/lockscreen/lib/?.so;" lock_screen.init = function() local pam = require("liblua_pam") @@ -12,7 +12,7 @@ lock_screen.init = function() return pam.auth_current_user(password) -- return password == "awesome" end - require("module.lockscreen.lockscreen") + require("modules.lockscreen.lockscreen") end return lock_screen diff --git a/config/awesome/module/lockscreen/lib/liblua_pam.so b/config/awesome/modules/lockscreen/lib/liblua_pam.so similarity index 100% rename from config/awesome/module/lockscreen/lib/liblua_pam.so rename to config/awesome/modules/lockscreen/lib/liblua_pam.so diff --git a/config/awesome/module/lockscreen/lockscreen.lua b/config/awesome/modules/lockscreen/lockscreen.lua old mode 100644 new mode 100755 similarity index 86% rename from config/awesome/module/lockscreen/lockscreen.lua rename to config/awesome/modules/lockscreen/lockscreen.lua index 02068f3..4cb43a8 --- a/config/awesome/module/lockscreen/lockscreen.lua +++ b/config/awesome/modules/lockscreen/lockscreen.lua @@ -1,29 +1,22 @@ --- Standard awesome library local gears = require("gears") local awful = require("awful") - --- Theme handling library local beautiful = require("beautiful") - --- Widget library +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi local wibox = require("wibox") - --- Helpers local helpers = require("helpers") - --- Lock -local lock_screen = require("module.lockscreen") +local lock_screen = require("modules.lockscreen") -- Word Clock Lock Screen ---------------- -local lock_screen_symbol = helpers.colorize_text("󰍁", beautiful.accent) -local lock_screen_fail_symbol = helpers.colorize_text("󱙲", beautiful.accent) +local lock_screen_symbol = "" +local lock_screen_fail_symbol = "" local lock_animation_icon = wibox.widget({ -- Set forced size to prevent flickering when the icon rotates forced_height = dpi(80), forced_width = dpi(80), - font = beautiful.icon_font_name .. "40", + font = beautiful.icon_font .. "Outlined 40", align = "center", valign = "center", widget = wibox.widget.textbox(lock_screen_symbol), @@ -42,7 +35,10 @@ awful.screen.connect_for_each_screen(function(s) if s == screen.primary then s.mylockscreen = lock_screen_box else - s.mylockscreen = helpers.screen_mask(s, beautiful.darker_bg) + s.mylockscreen = helpers.ui.screen_mask( + s, + beautiful.lock_screen_bg or beautiful.exit_screen_bg or beautiful.xbackground + ) end end) @@ -52,8 +48,8 @@ local function set_visibility(v) end end --- Widgets -------------- +-- Word Clock +---------------- local char = "I T L I S A S A M P M A C Q U A R T E R D C T W E N T Y F I V E X H A L F S T E N F T O P A S T E R U N I N E O N E S I X T H R E E F O U R F I V E T W O E I G H T E L E V E N S E V E N T W E L V E T E N S E O C L O C K" @@ -125,7 +121,7 @@ local time_char = split_str(char, " ") local time = wibox.widget({ forced_num_cols = 11, - spacing = beautiful.useless_gap, + spacing = dpi(6), layout = wibox.layout.grid, }) @@ -133,11 +129,11 @@ local function create_text_widget(index, w) local text_widget = wibox.widget({ id = "t" .. index, markup = w, - font = beautiful.font_name .. "bold 18", + font = beautiful.font_name .. "Bold 24", align = "center", valign = "center", - forced_width = dpi(25), - forced_height = dpi(30), + forced_width = dpi(36), + forced_height = dpi(36), widget = wibox.widget.textbox, }) @@ -148,7 +144,7 @@ end local var_count = 0 for i, m in pairs(time_char) do - local text = helpers.colorize_text(m, beautiful.accent .. "55") + local text = helpers.ui.colorize_text(m, "#ffffff" .. "10") var_count = var_count + 1 local create_dummy_text = true @@ -174,15 +170,14 @@ end local function activate_word(w) for i, m in pairs(char_map[w]) do local text = m.text - - m.markup = helpers.colorize_text(text, beautiful.accent) + m.markup = helpers.ui.colorize_text(text, beautiful.xforeground) end end local function deactivate_word(w) for i, m in pairs(char_map[w]) do local text = m.text - m.markup = helpers.colorize_text(text, beautiful.accent .. "55") + m.markup = helpers.ui.colorize_text(text, "#ffffff" .. "10") end end @@ -252,7 +247,7 @@ local lock_animation_widget_rotate = wibox.container.rotate() local arc = function() return function(cr, width, height) - gears.shape.arc(cr, width, height, dpi(5), 0, math.pi / 2, true, true) + gears.shape.arc(cr, width, height, 5, 0, math.pi / 2, true, true) end end @@ -312,7 +307,7 @@ local function key_animation(char_inserted) if characters_entered == 0 then reset() else - color = beautiful.accent .. "55" + color = beautiful.xcolor7 .. "55" end end @@ -385,22 +380,11 @@ lock_screen_box:setup({ -- Vertical centering nil, { - { - { - helpers.vertical_pad(dpi(10)), - time, - lock_animation, - spacing = dpi(50), - layout = wibox.layout.fixed.vertical, - }, - bottom = dpi(60), - right = dpi(60), - left = dpi(60), - widget = wibox.container.margin, - }, - shape = helpers.rrect(beautiful.border_radius), - bg = beautiful.darker_bg, - widget = wibox.container.background, + helpers.ui.vertical_pad(dpi(20)), + time, + lock_animation, + spacing = dpi(60), + layout = wibox.layout.fixed.vertical, }, expand = "none", layout = wibox.layout.align.vertical, diff --git a/config/awesome/modules/overflow.lua b/config/awesome/modules/overflow.lua new file mode 100755 index 0000000..7676385 --- /dev/null +++ b/config/awesome/modules/overflow.lua @@ -0,0 +1,538 @@ +--------------------------------------------------------------------------- +-- 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 +-- @supermodule wibox.layout.fixed +--------------------------------------------------------------------------- + +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 ipairs(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_max = math.max(used_max, h) + used_in_dir = used_in_dir + w + end + end + + local spacing = self._private.spacing * (num_widgets - 1) + used_in_dir = used_in_dir + spacing + + local need_scrollbar = scrollbar_enabled and used_in_dir > avail_in_dir + + -- Even if `used_max == orig_(width|height)` already, `base.fit_widget` + -- will clamp return values, so we can "overextend" here. + if need_scrollbar 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_max = math.max(used_max, h) + used_in_dir = used_in_dir + w + 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.scroll_factor + + 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.scroll_factor + + 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 ipairs(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. +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. +-- +-- The amount of units scrolled is affected by `step`. +-- +-- @method overflow:scroll +-- @tparam number amount The amount to scroll by. +-- @emits property::overflow::scroll_factor +-- @emitstparam property::overflow::scroll_factor number scroll_factor The new +-- scroll factor. +-- @emits widget::layout_changed +-- @emits widget::redraw_needed +function overflow:scroll(amount) + if amount == 0 then + return + end + local interval = self._private.used_in_dir + local delta = self._private.step / interval + + local factor = self._private.scroll_factor + (delta * amount) + self:set_scroll_factor(factor) +end + + +--- The scroll factor. +-- +-- The scroll factor represents how far the layout's content is currently +-- scrolled. It is represented as a fraction from `0` to `1`, where `0` is the +-- start of the content and `1` is the end. +-- +-- @property scroll_factor +-- @tparam number scroll_factor The scroll factor. +-- @propemits true false + +function overflow:set_scroll_factor(factor) + local current = self._private.scroll_factor + local interval = self._private.used_in_dir - self._private.avail_in_dir + if current == factor + -- the content takes less space than what is available, i.e. everything + -- is already visible + or interval <= 0 + -- the scroll factor is out of range + or (current <= 0 and factor < 0) + or (current >= 1 and factor > 1) then + return + end + + self._private.scroll_factor = math.min(1, math.max(factor, 0)) + + self:emit_signal("widget::layout_changed") + self:emit_signal("property::scroll_factor", factor) +end + +function overflow:get_scroll_factor() + return self._private.scroll_factor +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 + +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 `"right"`/`"bottom"`. +-- +--@DOC_wibox_layout_overflow_scrollbar_position_EXAMPLE@ +-- +-- @property scrollbar_position +-- @tparam string scrollbar_position The scrollbar position. +-- @propemits true false + +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 + +function overflow:get_scrollbar_position() + return self._private.scrollbar_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 + +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 + +function overflow:get_scrollbar_enabled() + return self._private.scrollbar_enabled +end + +-- Wraps a callback function for `mousegrabber` that is capable of +-- updating the scroll factor. +local function build_grabber(container, initial_x, initial_y, geo) + local is_y = container._private.dir == "y" + local bar_interval = container._private.avail_in_dir - container._private.bar_length + local start_pos = container._private.scroll_factor * bar_interval + local start = is_y and initial_y or initial_x + + -- Calculate a matrix transforming from screen coordinates into widget + -- coordinates. + -- This is required for mouse movement to work when the widget has been + -- transformed by something like `wibox.container.rotate`. + local matrix_from_device = geo.hierarchy:get_matrix_from_device() + local wgeo = geo.drawable.drawable:geometry() + local matrix = matrix_from_device:translate(-wgeo.x, -wgeo.y) + + return function(mouse) + if not mouse.buttons[1] then + return false + end + + local x, y = matrix:transform_point(mouse.x, mouse.y) + local pos = is_y and x and y + container:set_scroll_factor((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(_, x, y, button_id, _, geo) + if button_id ~= 1 then + return + end + mousegrabber.run(build_grabber(container, x, y, geo), "fleur") + end) +end + + +--- The scrollbar widget. +-- This widget is rendered as the scrollbar element. +-- +-- The default is `wibox.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 + +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 + +function overflow:get_scrollbar_widget() + return self._private.scrollbar_widget +end + +local function new(dir, ...) + local ret = fixed[dir](...) + + gtable.crush(ret, overflow, true) + ret.widget_name = gobject.modulename(2) + -- Tell the widget system to prevent clicks outside the layout's extends + -- to register with child widgets, even if they actually extend that far. + -- This prevents triggering button presses on hidden/clipped widgets. + ret.clip_child_extends = true + + -- Manually set the scroll factor here. We don't know the bounding size yet. + ret._private.scroll_factor = 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 + self:scroll(-1) + elseif button == 5 then + self:scroll(1) + 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.overflow.horizontal +function overflow.vertical(...) + return new("vertical", ...) +end + +return setmetatable(overflow, overflow.mt) \ No newline at end of file diff --git a/config/awesome/module/savefloats.lua b/config/awesome/modules/savefloats.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/module/savefloats.lua rename to config/awesome/modules/savefloats.lua diff --git a/config/awesome/module/window_switcher.lua b/config/awesome/modules/window_switcher.lua old mode 100644 new mode 100755 similarity index 52% rename from config/awesome/module/window_switcher.lua rename to config/awesome/modules/window_switcher.lua index ece26fc..953a955 --- a/config/awesome/module/window_switcher.lua +++ b/config/awesome/modules/window_switcher.lua @@ -1,9 +1,8 @@ -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 @@ -57,184 +56,102 @@ local window_switcher_hide = function(window_switcher_box) collectgarbage("collect") end -local function draw_widget( - type, - background, - border_width, - border_radius, - border_color, - clients_spacing, - client_icon_horizontal_spacing, - client_width, - client_height, - client_margins, - thumbnail_margins, - thumbnail_scale, - name_margins, - name_valign, - name_forced_width, - name_font, - name_normal_color, - name_focus_color, - icon_valign, - icon_width, - mouse_keys -) +local function draw_widget(mouse_keys) local tasklist_widget = awful.widget.tasklist({ screen = awful.screen.focused(), filter = awful.widget.tasklist.filter.currenttags, buttons = mouse_keys, style = { - font = beautiful.font_name .. "medium 9", + font = beautiful.font, + bg_normal = beautiful.xbackground, + bg_focus = beautiful.lighter_xbackground, fg_normal = beautiful.xforeground, fg_focus = beautiful.accent, + shape = gears.shape.rounded_rect, }, layout = { - layout = wibox.layout.flex.horizontal, - max_widget_size = dpi(300), - spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, }, widget_template = { - widget = wibox.container.background, - bg = beautiful.lighter_bg, - shape = helpers.rrect(beautiful.border_radius), - id = "bg_role", - forced_width = dpi(450), - create_callback = 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, { { { - { - { - horizontal_fit_policy = "auto", - vertical_fit_policy = "auto", - id = "thumbnail", - clip_shape = helpers.rrect(dpi(6)), - widget = wibox.widget.imagebox, - }, - margins = dpi(0), - widget = wibox.container.margin, - }, + awful.widget.clienticon, + forced_height = dpi(80), + forced_width = dpi(80), halign = "center", valign = "center", widget = wibox.container.place, }, { { + widget = wibox.container.scroll.horizontal, + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, { - widget = awful.widget.clienticon, - }, - forced_width = dpi(30), - valign = "center", - widget = wibox.container.place, - }, - { - { - forced_width = dpi(200), - valign = "center", id = "text_role", widget = wibox.widget.textbox, }, - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin, }, - layout = wibox.layout.align.horizontal, + halign = "center", + valign = "center", + widget = wibox.container.place, }, - layout = wibox.layout.flex.vertical, + spacing = dpi(15), + layout = wibox.layout.fixed.vertical, }, - left = dpi(20), - right = dpi(20), - top = dpi(20), + margins = dpi(15), widget = wibox.container.margin, }, + forced_width = dpi(150), + forced_height = dpi(150), + id = "background_role", + widget = wibox.container.background, }, }) return wibox.widget({ { - { - tasklist_widget, - margins = dpi(300), - widget = wibox.container.margin, - }, - halign = "center", - content_fill_horizontal = true, - widget = wibox.container.place, + tasklist_widget, + margins = dpi(15), + widget = wibox.container.margin, }, - bg = "#00000000", + bg = beautiful.xbackground, + shape = gears.shape.rounded_rect, widget = wibox.container.background, }) end -local enable = function(opts) - local opts = opts or {} +local enable = function() + local hide_window_switcher_key = "Escape" - local type = opts.type or "thumbnail" - local background = beautiful.window_switcher_widget_bg or "#00000000" - local border_width = beautiful.window_switcher_widget_border_width or dpi(3) - local border_radius = beautiful.window_switcher_widget_border_radius or dpi(6) - local border_color = beautiful.window_switcher_widget_border_color or "#ffffff" - local clients_spacing = beautiful.window_switcher_clients_spacing or dpi(20) - local client_icon_horizontal_spacing = beautiful.window_switcher_client_icon_horizontal_spacing or dpi(5) - local client_width = beautiful.window_switcher_client_width or dpi(type == "thumbnail" and 150 or 500) - local client_height = beautiful.window_switcher_client_height or dpi(type == "thumbnail" and 250 or 50) - local client_margins = beautiful.window_switcher_client_margins or dpi(10) - local thumbnail_margins = beautiful.window_switcher_thumbnail_margins or dpi(5) - local thumbnail_scale = beautiful.thumbnail_scale or false - local name_margins = beautiful.window_switcher_name_margins or dpi(10) - local name_valign = beautiful.window_switcher_name_valign or "center" - local name_forced_width = beautiful.window_switcher_name_forced_width or dpi(type == "thumbnail" and 200 or 550) - local name_font = beautiful.window_switcher_name_font or beautiful.font_name .. "medium 10" - local name_normal_color = beautiful.window_switcher_name_normal_color or beautiful.xforeground - local name_focus_color = beautiful.window_switcher_name_focus_color or beautiful.accent - local icon_valign = beautiful.window_switcher_icon_valign or "center" - local icon_width = beautiful.window_switcher_icon_width or dpi(40) - 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 window_switcher_box = wibox({ + local select_client_key = 1 + local minimize_key = "n" + local unminimize_key = "N" + local kill_client_key = "q" + + local cycle_key = "Tab" + + local previous_key = "Left" + local next_key = "Right" + + local vim_previous_key = "h" + local vim_next_key = "l" + + local scroll_previous_key = 4 + local scroll_next_key = 5 + + local window_switcher_box = awful.popup({ bg = "#00000000", visible = false, ontop = true, - type = "splash", + placement = awful.placement.centered, screen = awful.screen.focused(), widget = wibox.container.background, -- A dummy widget to make awful.popup not scream - widget = { - { - draw_widget(), - margins = dpi(10), - widget = wibox.container.margin, - }, - shape_border_width = beautiful.widget_border_width, - shape_border_color = beautiful.widget_border_color, - bg = "#00000000", - shape = helpers.rrect(dpi(6)), - widget = wibox.container.background, - }, + widget = draw_widget(), }) - awful.placement.maximize(window_switcher_box) - local mouse_keys = gears.table.join( awful.button({ modifiers = { "Any" }, @@ -313,7 +230,7 @@ local enable = function(opts) end end) - awesome.connect_signal("bling::window_switcher::turn_on", function() + awesome.connect_signal("window_switcher::turn_on", function() local number_of_clients = get_num_clients() if number_of_clients == 0 then return @@ -360,29 +277,7 @@ local enable = function(opts) end end) - window_switcher_box.widget = draw_widget( - type, - background, - border_width, - border_radius, - border_color, - clients_spacing, - client_icon_horizontal_spacing, - client_width, - client_height, - client_margins, - thumbnail_margins, - thumbnail_scale, - name_margins, - name_valign, - name_forced_width, - name_font, - name_normal_color, - name_focus_color, - icon_valign, - icon_width, - mouse_keys - ) + window_switcher_box.widget = draw_widget(mouse_keys) window_switcher_box.visible = true end) end diff --git a/config/awesome/rc.lua b/config/awesome/rc.lua old mode 100644 new mode 100755 index 591380e..2270170 --- a/config/awesome/rc.lua +++ b/config/awesome/rc.lua @@ -1,60 +1,57 @@ +--- ░█▀▄░█░█░█░█░█░█░█▀█░▀░█▀▀░░░█▀█░█░█░█▀▀░█▀▀░█▀█░█▄█░█▀▀ +--- ░█▀▄░▄▀▄░░█░░█▀█░█░█░░░▀▀█░░░█▀█░█▄█░█▀▀░▀▀█░█░█░█░█░█▀▀ +--- ░▀░▀░▀░▀░░▀░░▀░▀░▀░▀░░░▀▀▀░░░▀░▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀▀▀ +--- ~~~~~~~~~~~~~~~~~~ @author rxyhn ~~~~~~~~~~~~~~~~~~~~~~ +--- ~~~~~~~~~~~~ https://github.com/rxyhn ~~~~~~~~~~~~~~~~~~ + pcall(require, "luarocks.loader") ---[[ - _____ __ _ __ _____ _____ _____ _______ _____ -| | | | | ___| ___| | | ___| -| - | | | | ___|___ | | | | | | ___| -|__|__|_______|_____|_____|_____|__|_|__|_____| - -============== @author rxyhn ================== -======== https://github.com/rxyhn ============= ---]] - --- 🎨 Themes -themes = { - "day", -- [1] 🌕 Beautiful Light Colorscheme - "night", -- [2] 🌑 Aesthetic Dark Colorscheme -} -theme = themes[2] --- =================================================================== --- 🌊 Default Applications -terminal = "kitty" -editor = "nvim" -vscode = "code" -browser = "firefox" -web_search_cmd = "xdg-open https://google.com/search?q=" -file_manager = "nautilus" -music_client = terminal .. " --class music -e ncmpcpp" -launcher = "rofi -show drun -theme " .. os.getenv("HOME") .. "/.config/awesome/theme/rofi.rasi" --- 🌏 Weather API -openweathermap_key = "" -- API Key -openweathermap_city_id = "" -- City ID -weather_units = "metric" --- =================================================================== --- 📚 Library -local gfs = require("gears.filesystem") -local awful = require("awful") +local gears = require("gears") local beautiful = require("beautiful") -dpi = beautiful.xresources.apply_dpi --- =================================================================== --- 🌟 Load theme -local theme_dir = gfs.get_configuration_dir() .. "theme/" .. theme .. "/" + +--- ░▀█▀░█░█░█▀▀░█▄█░█▀▀ +--- ░░█░░█▀█░█▀▀░█░█░█▀▀ +--- ░░▀░░▀░▀░▀▀▀░▀░▀░▀▀▀ + +local theme_dir = gears.filesystem.get_configuration_dir() .. "theme/" beautiful.init(theme_dir .. "theme.lua") --- =================================================================== --- 🖥 Get screen geometry -screen_width = awful.screen.focused().geometry.width -screen_height = awful.screen.focused().geometry.height --- =================================================================== --- 🚀 Launch Autostart -awful.spawn.with_shell(gfs.get_configuration_dir() .. "configuration/autostart") --- =================================================================== --- 🤖 Import Configuration & module +---passed + +--- ░█▀▀░█▀█░█▀█░█▀▀░▀█▀░█▀▀░█░█░█▀▄░█▀█░▀█▀░▀█▀░█▀█░█▀█░█▀▀ +--- ░█░░░█░█░█░█░█▀▀░░█░░█░█░█░█░█▀▄░█▀█░░█░░░█░░█░█░█░█░▀▀█ +--- ░▀▀▀░▀▀▀░▀░▀░▀░░░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░▀░░▀░░▀▀▀░▀▀▀░▀░▀░▀▀▀ + require("configuration") -require("module") --- =================================================================== --- ✨ Import Daemons, UI & Widgets +---passed +--- ░█▄█░█▀█░█▀▄░█░█░█░░░█▀▀░█▀▀ +--- ░█░█░█░█░█░█░█░█░█░░░█▀▀░▀▀█ +--- ░▀░▀░▀▀▀░▀▀░░▀▀▀░▀▀▀░▀▀▀░▀▀▀ + +require("modules") + +--- ░█▀▄░█▀█░█▀▀░█▄█░█▀█░█▀█░█▀▀ +--- ░█░█░█▀█░█▀▀░█░█░█░█░█░█░▀▀█ +--- ░▀▀░░▀░▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀▀▀ + require("signal") + +--- ░█░█░▀█▀ +--- ░█░█░░█░ +--- ░▀▀▀░▀▀▀ + require("ui") --- =================================================================== --- 🗑 Garbage Collector Settings + +--- ░█▀▀░█▀█░█▀▄░█▀▄░█▀█░█▀▀░█▀▀ +--- ░█░█░█▀█░█▀▄░█▀▄░█▀█░█░█░█▀▀ +--- ░▀▀▀░▀░▀░▀░▀░▀▀░░▀░▀░▀▀▀░▀▀▀ + +--- Enable for lower memory consumption collectgarbage("setpause", 110) collectgarbage("setstepmul", 1000) +gears.timer({ + timeout = 5, + autostart = true, + call_now = true, + callback = function() + collectgarbage("collect") + end, +}) diff --git a/config/awesome/signal/battery.lua b/config/awesome/signal/battery.lua old mode 100644 new mode 100755 index 73f13b4..595c036 --- a/config/awesome/signal/battery.lua +++ b/config/awesome/signal/battery.lua @@ -1,68 +1,14 @@ --- Provides: --- signal::battery --- percentage (integer) --- signal::charger --- plugged (boolean) +--- This uses UPowerGlib.Device (https://lazka.github.io/pgi-docs/UPowerGlib-1.0/classes/Device.html) +--- Provides: +--- signal::battery +--- percentage +--- state +local upower_widget = require("modules.battery_widget") +local battery_listener = upower_widget({ + device_path = "/org/freedesktop/UPower/devices/battery_BAT0", + instant_update = true, +}) -local awful = require("awful") - -local update_interval = 30 - --- Subscribe to power supply status changes with acpi_listen -local charger_script = [[ - sh -c ' - acpi_listen | grep --line-buffered ac_adapter - ' -]] - --- First get battery file path --- If there are multiple, only get the first one --- TODO support multiple batteries -awful.spawn.easy_async_with_shell( - 'sh -c \'out="$(find /sys/class/power_supply/BAT?/capacity)" && (echo "$out" | head -1) || false\' ', - function(battery_file, _, __, exit_code) - -- No battery file found - if not (exit_code == 0) then - return - end - -- Periodically get battery info - awful.widget.watch("cat " .. battery_file, update_interval, function(_, stdout) - -- awful.widget.watch("check-battery", update_interval, function(_, stdout) - awesome.emit_signal("signal::battery", tonumber(stdout)) - end) - end -) - --- First get charger file path -awful.spawn.easy_async_with_shell( - 'sh -c \'out="$(find /sys/class/power_supply/*/online)" && (echo "$out" | head -1) || false\' ', - function(charger_file, _, __, exit_code) - -- No charger file found - if not (exit_code == 0) then - return - end - -- Then initialize function that emits charger info - local emit_charger_info = function() - awful.spawn.easy_async_with_shell("cat " .. charger_file, function(out) - local status = tonumber(out) == 1 - awesome.emit_signal("signal::charger", status) - end) - end - - -- Run once to initialize widgets - emit_charger_info() - - -- Kill old acpi_listen process - awful.spawn.easy_async_with_shell( - "ps x | grep \"acpi_listen\" | grep -v grep | awk '{print $1}' | xargs kill", - function() - -- Update charger status with each line printed - awful.spawn.with_line_callback(charger_script, { - stdout = function(_) - emit_charger_info() - end, - }) - end - ) - end -) +battery_listener:connect_signal("upower::update", function(_, device) + awesome.emit_signal("signal::battery", device.percentage, device.state) +end) diff --git a/config/awesome/signal/brightness.lua b/config/awesome/signal/brightness.lua old mode 100644 new mode 100755 index 9273f30..f175505 --- a/config/awesome/signal/brightness.lua +++ b/config/awesome/signal/brightness.lua @@ -1,33 +1,42 @@ --- Provides: --- signal::brightness --- percentage (integer) +--- Provides: +--- signal::brightness +--- percentage (integer) local awful = require("awful") --- Subscribe to backlight changes --- Requires inotify-tools +--- Subscribe to backlight changes +--- Requires inotify-tools local brightness_subscribe_script = [[ bash -c " - while (inotifywait -e modify /sys/class/backlight/?*/brightness -qq) do echo; done + while (inotifywait -e modify /sys/class/backlight/?**/brightness -qq) do echo; done "]] local brightness_script = [[ sh -c " - brightnessctl i | grep -oP '\(\K[^%\)]+' + brightnessctl g +"]] + +local brightness_max = [[ + sh -c " + brightnessctl m "]] local emit_brightness_info = function() awful.spawn.with_line_callback(brightness_script, { - stdout = function(line) - percentage = math.floor(tonumber(line)) - awesome.emit_signal("signal::brightness", percentage) + stdout = function(value) + awful.spawn.with_line_callback(brightness_max, { + stdout = function(max) + local percentage = tonumber(value) / tonumber(max) * 100 + awesome.emit_signal("signal::brightness", math.floor(percentage + 0.5)) + end, + }) end, }) end --- Run once to initialize widgets +--- Run once to initialize widgets emit_brightness_info() --- Kill old inotifywait process +--- Kill old inotifywait process awful.spawn.easy_async_with_shell( "ps x | grep \"inotifywait -e modify /sys/class/backlight\" | grep -v grep | awk '{print $1}' | xargs kill", function() diff --git a/config/awesome/signal/cpu.lua b/config/awesome/signal/cpu.lua deleted file mode 100644 index bdbf8e4..0000000 --- a/config/awesome/signal/cpu.lua +++ /dev/null @@ -1,18 +0,0 @@ --- Provides: --- signal::cpu --- used percentage (integer) -local awful = require("awful") - -local update_interval = 5 -local cpu_idle_script = [[ - sh -c " - vmstat 1 2 | tail -1 | awk '{printf \"%d\", $15}' - "]] - --- Periodically get cpu info -awful.widget.watch(cpu_idle_script, update_interval, function(widget, stdout) - -- local cpu_idle = stdout:match('+(.*)%.%d...(.*)%(') - local cpu_idle = stdout - cpu_idle = string.gsub(cpu_idle, "^%s*(.-)%s*$", "%1") - awesome.emit_signal("signal::cpu", 100 - tonumber(cpu_idle)) -end) diff --git a/config/awesome/signal/disk.lua b/config/awesome/signal/disk.lua deleted file mode 100644 index 7296932..0000000 --- a/config/awesome/signal/disk.lua +++ /dev/null @@ -1,25 +0,0 @@ --- Provides: --- signal::disk --- used (integer - mega bytes) --- total (integer - mega bytes) -local awful = require("awful") -local helpers = require("helpers") - -local update_interval = 180 -- every 3 minutes - --- Use /dev/sdxY according to your setup -local disk_script = [[ - bash -c " - df -kH -B 1MB /dev/sda3 | tail -1 | awk '{printf \"%d@%d\", $4, $3}' - " -]] - --- Periodically get disk space info -awful.widget.watch(disk_script, update_interval, function(_, stdout) - -- Get `available` and `used` instead of `used` and `total`, - -- since the total size reported by the `df` command includes - -- the 5% storage reserved for `root`, which is misleading. - local available = tonumber(stdout:match("^(.*)@")) / 1000 - local used = tonumber(stdout:match("@(.*)$")) / 1000 - awesome.emit_signal("signal::disk", used, used + available) -end) diff --git a/config/awesome/signal/github.lua b/config/awesome/signal/github.lua new file mode 100755 index 0000000..c0f3965 --- /dev/null +++ b/config/awesome/signal/github.lua @@ -0,0 +1,174 @@ +local gobject = require("gears.object") +local gtable = require("gears.table") +local gtimer = require("gears.timer") +local json = require("modules.json") +local helpers = require("helpers") +local user_vars = require("user_variables") +local string = string +local ipairs = ipairs + +local github = {} +local instance = nil + +local UPDATE_INTERVAL = 60 * 60 * 1 -- 1 hour +local PATH = helpers.filesystem.get_cache_dir("github") + +function github:get_username() + return self._private.username +end + +local function github_events(self) + local link = "https://api.github.com/users/%s/received_events" + local path = PATH .. "events/" + local avatars_path = path .. "avatars/" + local DATA_PATH = path .. "data.json" + + local old_data = nil + + helpers.filesystem.remote_watch( + DATA_PATH, + string.format(link, self._private.username), + UPDATE_INTERVAL, + function(content) + if content == nil or content == false then + self:emit_signal("events::error") + return + end + + local data = json.decode(content) + + if data == nil then + self:emit_signal("events::error") + return + end + + for index, event in ipairs(data) do + if old_data ~= nil and old_data[event.id] == nil then + self:emit_signal("new_event", event) + end + + local is_downloading = false + local path_to_avatar = avatars_path .. event.actor.id + helpers.filesystem.is_file_readable(path_to_avatar, function(result) + if result == false then + is_downloading = true + helpers.filesystem.save_uri(path_to_avatar, event.actor.avatar_url, function() + is_downloading = false + if index == #data then + self:emit_signal("events", data, avatars_path) + end + end) + elseif index == #data and is_downloading == false then + self:emit_signal("events", data, avatars_path) + end + end) + end + end, + function(old_content) + local data = json.decode(old_content) + if data ~= nil then + old_data = {} + for _, event in ipairs(data) do + old_data[event.id] = event.id + end + end + end + ) +end + +local function github_prs(self) + local path = PATH .. "created_prs/" + local avatars_path = path .. "avatars/" + local DATA_PATH = path .. "data.json" + + local link = "https://api.github.com/search/issues?q=author%3A" .. self._private.username .. "+type%3Apr" + + local old_data = nil + + helpers.filesystem.remote_watch(DATA_PATH, link, UPDATE_INTERVAL, function(content) + if content == nil or content == false then + self:emit_signal("prs::error") + return + end + + local data = json.decode(content) + if data == nil then + self:emit_signal("prs::error") + return + end + + for index, pr in ipairs(data.items) do + if old_data ~= nil and old_data[pr.id] == nil then + self:emit_signal("new_pr", pr) + end + + local is_downloading = false + local path_to_avatar = avatars_path .. pr.user.id + helpers.filesystem.is_file_readable(path_to_avatar, function(result) + if result == false then + is_downloading = true + helpers.filesystem.save_uri(path_to_avatar, pr.user.avatar_url, function() + is_downloading = false + if index == #data.items then + self:emit_signal("prs", data.items, avatars_path) + end + end) + elseif index == #data.items and is_downloading == false then + self:emit_signal("prs", data.items, avatars_path) + end + end) + end + end, function(old_content) + local data = json.decode(old_content) + if data ~= nil then + old_data = {} + for _, pr in ipairs(data.items) do + old_data[pr.id] = pr.id + end + end + end) +end + +local function github_contributions(self) + local link = "https://github-contributions.vercel.app/api/v1/%s" + local path = PATH .. "contributions/" + local DATA_PATH = path .. "data.json" + + helpers.filesystem.remote_watch( + DATA_PATH, + string.format(link, self._private.username), + UPDATE_INTERVAL, + function(content) + self:emit_signal("contributions", content) + end + ) +end + +function github:refresh() + github_events(self) + github_prs(self) + github_contributions(self) +end + +local function new() + local ret = gobject({}) + gtable.crush(ret, github, true) + + ret._private = {} + ret._private.username = user_vars.widget.github.username + + if ret._private.username ~= nil then + ret:refresh() + else + gtimer.delayed_call(function() + ret:emit_signal("missing_credentials") + end) + end + + return ret +end + +if not instance then + instance = new() +end +return instance diff --git a/config/awesome/signal/init.lua b/config/awesome/signal/init.lua old mode 100644 new mode 100755 index 1d21ffe..4f0f549 --- a/config/awesome/signal/init.lua +++ b/config/awesome/signal/init.lua @@ -1,11 +1,3 @@ -require("signal.battery") -require("signal.brightness") -require("signal.cpu") -require("signal.disk") -require("signal.network") -require("signal.playerctl") -require("signal.ram") -require("signal.todo") -require("signal.uptime") -require("signal.volume") -require("signal.weather") \ No newline at end of file +---require(... .. ".battery") +---require(... .. ".brightness") +require(... .. ".volume") diff --git a/config/awesome/signal/network.lua b/config/awesome/signal/network.lua deleted file mode 100644 index 05c4680..0000000 --- a/config/awesome/signal/network.lua +++ /dev/null @@ -1,26 +0,0 @@ --- Provides: --- signal::network --- status (boolean) --- ssid (string) -local awful = require("awful") -local naughty = require("naughty") - -local update_interval = 5 -local network_script = [[ - bash -c " - iwgetid -r - "]] - --- Periodically get cpu info -awful.widget.watch(network_script, update_interval, function(_, stdout) - -- local network = stdout:match('+(.*)%.%d...(.*)%(') - local net_ssid = stdout - local net_status = true - - if net_ssid == "" then - net_status = false - end - - net_ssid = string.gsub(net_ssid, "^%s*(.-)%s*$", "%1") - awesome.emit_signal("signal::network", net_status, net_ssid) -end) diff --git a/config/awesome/signal/playerctl.lua b/config/awesome/signal/playerctl.lua old mode 100644 new mode 100755 index 40ef01a..5fc755c --- a/config/awesome/signal/playerctl.lua +++ b/config/awesome/signal/playerctl.lua @@ -1,16 +1,17 @@ --- Notification handling library -local naughty = require("naughty") +local bling = require("modules.bling") --- Playerctl -local playerctl = require("module.bling").signal.playerctl.lib() +local playerctl = {} +local instance = nil -playerctl:connect_signal("metadata", function(_, title, artist, album_path, album, new, player_name) - if new == true then - naughty.notify({ - app_name = "Music", - title = title, - text = artist, - image = album_path, - }) - end -end) +local function new() + return bling.signal.playerctl.lib({ + update_on_activity = true, + player = { "spotify", "mpd", "%any" }, + debounce_delay = 1, + }) +end + +if not instance then + instance = new() +end +return instance diff --git a/config/awesome/signal/ram.lua b/config/awesome/signal/ram.lua deleted file mode 100644 index 2a5bfb5..0000000 --- a/config/awesome/signal/ram.lua +++ /dev/null @@ -1,23 +0,0 @@ --- Provides: --- signal::ram --- used (integer - mega bytes) --- total (integer - mega bytes) -local awful = require("awful") - -local update_interval = 20 --- Returns the used amount of ram in percentage --- TODO output of free is affected by system language. The following command --- works for any language: --- free -m | sed -n '2p' | awk '{printf "%d available out of %d\n", $7, $2}' -local ram_script = [[ - sh -c " - free -m | grep 'Mem:' | awk '{printf \"%d@@%d@\", $7, $2}' - "]] - --- Periodically get ram info -awful.widget.watch(ram_script, update_interval, function(widget, stdout) - local available = stdout:match("(.*)@@") - local total = stdout:match("@@(.*)@") - local used = tonumber(total) - tonumber(available) - awesome.emit_signal("signal::ram", used, tonumber(total)) -end) diff --git a/config/awesome/signal/todo.lua b/config/awesome/signal/todo.lua deleted file mode 100644 index 8a47aaa..0000000 --- a/config/awesome/signal/todo.lua +++ /dev/null @@ -1,50 +0,0 @@ --- Provides: --- signal::todo --- total (integer) --- done (integer) --- undone (integer) -local awful = require("awful") - -local todo_file_path = "~/.config/awesome/" - --- Subscribe to todo changes --- Requires inotify-tools -local todo_subscribe_script = [[ - bash -c " - while (inotifywait -e modify "]] .. todo_file_path .. [[" -qq) do echo; done -"]] - -local todo_script = [[ - bash -c " - todo_done=$(todo raw done | wc -l) - todo_undone=$(todo raw todo | wc -l) - - echo "$todo_done"@@"$todo_undone" -"]] - -local emit_todo_info = function() - awful.spawn.with_line_callback(todo_script, { - stdout = function(line) - local done = tonumber(line:match("(.*)@@")) - local undone = tonumber(line:match("@@(.*)")) - local total = undone + done - awesome.emit_signal("signal::todo", total, done, undone) - end, - }) -end - --- Run once to initialize widgets -emit_todo_info() - --- Kill old inotifywait process -awful.spawn.easy_async_with_shell( - 'ps x | grep "inotifywait -e modify ' .. todo_file_path .. "\" | grep -v grep | awk '{print $1}' | xargs kill", - function() - -- Update todo status with each line printed - awful.spawn.with_line_callback(todo_subscribe_script, { - stdout = function(_) - emit_todo_info() - end, - }) - end -) diff --git a/config/awesome/signal/uptime.lua b/config/awesome/signal/uptime.lua deleted file mode 100644 index 5ac010c..0000000 --- a/config/awesome/signal/uptime.lua +++ /dev/null @@ -1,47 +0,0 @@ --- Provides: --- signal::uptime --- up (string) -local awful = require("awful") -local naughty = require("naughty") - --- Uptime Script from https://github.com/niraj998 -local uptime_script = [[ - sh -c " - cmd=$(uptime) - - hr=$( echo $cmd | cut -d \":\" -f3 | awk '{print $NF}') - mt=$( echo $cmd | cut -d \":\" -f4 | cut -c1-2 ) - day=$(echo $cmd | grep day) - - if [ -z \"$day\" ]; then - hour=$(uptime -p | grep hour) - if [ -z \"$hour\" ]; then - uptime -p | awk '{print $2 \"m\"}' - else - if [ \"$mt\" -lt \"10\"]; then - mt=$( echo $cmd | cut -d \":\" -f4 | cut -c2 ) - echo \"${hr}h ${mt}m\" - else - echo \"${hr}h ${mt}m\" - fi - fi - else - day=$(echo $day | cut -d \" \" -f3) - if [ \"$mt\" -lt \"10\" ]; then - mt=$( echo $cmd | cut -d \":\" -f4 | cut -c2 ) - echo \"${day}d ${hr}h ${mt}m\" - else - echo \"${day}d ${hr}h ${mt}m\" - fi - fi - "]] - -local update_interval = 60 - --- Periodically get uptime info -awful.widget.watch(uptime_script, update_interval, function(_, stdout) - local uptime_value = stdout - - uptime_value = string.gsub(uptime_value, "^%s*(.-)%s*$", "%1") - awesome.emit_signal("signal::uptime", uptime_value) -end) diff --git a/config/awesome/signal/volume.lua b/config/awesome/signal/volume.lua old mode 100644 new mode 100755 index 5b929f5..205ee53 --- a/config/awesome/signal/volume.lua +++ b/config/awesome/signal/volume.lua @@ -1,49 +1,48 @@ --- Provides: --- signal::volume --- percentage (integer) --- muted (boolean) +--- Provides: +--- signal::volume +--- percentage (integer) +--- muted (boolean) local awful = require("awful") local volume_old = -1 local muted_old = -1 local function emit_volume_info() - -- Get volume info of the currently active sink - -- The currently active sink has a star `*` in front of its index - -- 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) - local volume = stdout:match("(%d+)%% /") - local muted = stdout:match("muted:(%s+)[yes]") - local muted_int = muted and 1 or 0 - local volume_int = tonumber(volume) - -- Only send signal if there was a change - -- We need this since we use `pactl subscribe` to detect - -- volume events. These are not only triggered when the - -- user adjusts the volume through a keybind, but also - -- through `pavucontrol` or even without user intervention, - -- when a media file starts playing. - if volume_int ~= volume_old or muted_int ~= muted_old then - awesome.emit_signal("signal::volume", volume_int, muted) - volume_old = volume_int - muted_old = muted_int - end + --- Get volume info of the currently active sink + awful.spawn.easy_async_with_shell('echo -n $(pamixer --get-mute); echo "_$(pamixer --get-volume)"', function(stdout) + local bool = string.match(stdout, "(.-)_") + local volume = string.match(stdout, "%d+") + local muted_int = -1 + if bool == "true" then + muted_int = 1 + else + muted_int = 0 end - ) + local volume_int = tonumber(volume) + + --- Only send signal if there was a change + --- We need this since we use `pactl subscribe` to detect + --- volume events. These are not only triggered when the + --- user adjusts the volume through a keybind, but also + --- through `pavucontrol` or even without user intervention, + --- when a media file starts playing. + if volume_int ~= volume_old or muted_int ~= muted_old then + awesome.emit_signal("signal::volume", volume_int, muted_int) + volume_old = volume_int + muted_old = muted_int + end + end) end --- Run once to initialize widgets +--- Run once to initialize widgets emit_volume_info() --- Sleeps until pactl detects an event (volume up/down/toggle mute) +--- Sleeps until pactl detects an event (volume up/down/toggle mute) local volume_script = [[ bash -c " LANG=C pactl subscribe 2> /dev/null | grep --line-buffered \"Event 'change' on sink #\" "]] --- Kill old pactl subscribe processes +--- Kill old pactl subscribe processes awful.spawn.easy_async({ "pkill", "--full", @@ -51,7 +50,7 @@ awful.spawn.easy_async({ os.getenv("USER"), "^pactl subscribe", }, function() - -- Run emit_volume_info() with each line printed + --- Run emit_volume_info() with each line printed awful.spawn.with_line_callback(volume_script, { stdout = function(line) emit_volume_info() diff --git a/config/awesome/signal/weather.lua b/config/awesome/signal/weather.lua deleted file mode 100644 index e7f70c7..0000000 --- a/config/awesome/signal/weather.lua +++ /dev/null @@ -1,99 +0,0 @@ --- Provides: --- signal::weather --- temperature (integer) --- description (string) --- icon_code (string) -local awful = require("awful") -local beautiful = require("beautiful") -local helpers = require("helpers") - --- Configuration -local key = openweathermap_key -local city_id = openweathermap_city_id -local units = weather_units --- Don't update too often, because your requests might get blocked for 24 hours -local update_interval = 1200 -local temp_file = "/tmp/awesomewm-signal-weather-" .. city_id .. "-" .. units - -local sun_icon = "" -local moon_icon = "" -local dcloud_icon = "" -local ncloud_icon = "" -local cloud_icon = "" -local rain_icon = "" -local storm_icon = "" -local snow_icon = "" -local mist_icon = "" -local whatever_icon = "" - -local weather_icons = { - ["01d"] = { icon = sun_icon, color = beautiful.xcolor3 }, - ["01n"] = { icon = moon_icon, color = beautiful.xcolor4 }, - ["02d"] = { icon = dcloud_icon, color = beautiful.xcolor3 }, - ["02n"] = { icon = ncloud_icon, color = beautiful.xcolor6 }, - ["03d"] = { icon = cloud_icon, color = beautiful.xforeground }, - ["03n"] = { icon = cloud_icon, color = beautiful.xforeground }, - ["04d"] = { icon = cloud_icon, color = beautiful.xforeground }, - ["04n"] = { icon = cloud_icon, color = beautiful.xforeground }, - ["09d"] = { icon = rain_icon, color = beautiful.xcolor4 }, - ["09n"] = { icon = rain_icon, color = beautiful.xcolor4 }, - ["10d"] = { icon = rain_icon, color = beautiful.xcolor4 }, - ["10n"] = { icon = rain_icon, color = beautiful.xcolor4 }, - ["11d"] = { icon = storm_icon, color = beautiful.xforeground }, - ["11n"] = { icon = storm_icon, color = beautiful.xforeground }, - ["13d"] = { icon = snow_icon, color = beautiful.xcolor6 }, - ["13n"] = { icon = snow_icon, color = beautiful.xcolor6 }, - ["40d"] = { icon = mist_icon, color = beautiful.xcolor5 }, - ["40n"] = { icon = mist_icon, color = beautiful.xcolor5 }, - ["50d"] = { icon = mist_icon, color = beautiful.xcolor5 }, - ["50n"] = { icon = mist_icon, color = beautiful.xcolor5 }, - ["_"] = { icon = whatever_icon, color = beautiful.xcolor2 }, -} - -local weather_details_script = [[ - bash -c ' - KEY="]] .. key .. [[" - CITY="]] .. city_id .. [[" - UNITS="]] .. units .. [[" - - weather=$(curl -sf "http://api.openweathermap.org/data/2.5/weather?APPID=$KEY&id=$CITY&units=$UNITS") - - if [ ! -z "$weather" ]; then - weather_temp=$(echo "$weather" | jq ".main.temp" | cut -d "." -f 1) - weather_icon=$(echo "$weather" | jq -r ".weather[].icon" | head -1) - weather_description=$(echo "$weather" | jq -r ".weather[].description" | head -1) - - echo "$weather_icon" "$weather_description"@@"$weather_temp" - else - echo "..." - fi - ']] - -helpers.remote_watch(weather_details_script, update_interval, temp_file, function(stdout) - local icon_code = string.sub(stdout, 1, 3) - local weather_details = string.sub(stdout, 5) - weather_details = string.gsub(weather_details, "^%s*(.-)%s*$", "%1") - -- Replace "-0" with "0" degrees - weather_details = string.gsub(weather_details, "%-0", "0") - -- Capitalize first letter of the description - weather_details = weather_details:sub(1, 1):upper() .. weather_details:sub(2) - local description = weather_details:match("(.*)@@") - local temperature = weather_details:match("@@(.*)") - local icon - local color - local weather_icon - - if icon_code == "..." then - -- Remove temp_file to force an update the next time - awful.spawn.with_shell("rm " .. temp_file) - icon = weather_icons["_"].icon - color = weather_icons["_"].color - weather_icon = helpers.colorize_text(icon, color) - awesome.emit_signal("signal::weather", 999, "Weather unavailable", weather_icon) - else - icon = weather_icons[icon_code].icon - color = weather_icons[icon_code].color - weather_icon = helpers.colorize_text(icon, color) - awesome.emit_signal("signal::weather", tonumber(temperature), description, weather_icon) - end -end) diff --git a/config/awesome/theme/assets/bg.png b/config/awesome/theme/assets/bg.png deleted file mode 100644 index 78a32aa..0000000 Binary files a/config/awesome/theme/assets/bg.png and /dev/null differ diff --git a/config/awesome/theme/assets/icons/awesome.png b/config/awesome/theme/assets/icons/awesome.png deleted file mode 100644 index 1e2600a..0000000 Binary files a/config/awesome/theme/assets/icons/awesome.png and /dev/null differ diff --git a/config/awesome/theme/assets/icons/awesome_logo.svg b/config/awesome/theme/assets/icons/awesome_logo.svg deleted file mode 100644 index 80ae1a3..0000000 --- a/config/awesome/theme/assets/icons/awesome_logo.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/config/awesome/theme/assets/icons/awesome_logo_and_name.svg b/config/awesome/theme/assets/icons/awesome_logo_and_name.svg deleted file mode 100644 index 1338398..0000000 --- a/config/awesome/theme/assets/icons/awesome_logo_and_name.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/config/awesome/theme/assets/icons/brightness.png b/config/awesome/theme/assets/icons/brightness.png deleted file mode 100644 index ff6a6a3..0000000 Binary files a/config/awesome/theme/assets/icons/brightness.png and /dev/null differ diff --git a/config/awesome/theme/assets/icons/init.lua b/config/awesome/theme/assets/icons/init.lua deleted file mode 100644 index 4a5eb99..0000000 --- a/config/awesome/theme/assets/icons/init.lua +++ /dev/null @@ -1,14 +0,0 @@ --- Icons directory -local dir = os.getenv("HOME") .. "/.config/awesome/theme/assets/icons/" - -return { - -- notifs - notification = dir .. "notification.svg", - notification_bell = dir .. "notification_bell.svg", - - -- system - ram = dir .. "ram.svg", - cpu = dir .. "cpu.svg", - temp = dir .. "temp.svg", - disk = dir .. "disk.svg", -} diff --git a/config/awesome/theme/assets/icons/mute.png b/config/awesome/theme/assets/icons/mute.png deleted file mode 100644 index 4933ab1..0000000 Binary files a/config/awesome/theme/assets/icons/mute.png and /dev/null differ diff --git a/config/awesome/theme/assets/icons/notification-bell.png b/config/awesome/theme/assets/icons/notification-bell.png deleted file mode 100644 index d66a633..0000000 Binary files a/config/awesome/theme/assets/icons/notification-bell.png and /dev/null differ diff --git a/config/awesome/theme/assets/icons/notification.png b/config/awesome/theme/assets/icons/notification.png deleted file mode 100644 index c7e5677..0000000 Binary files a/config/awesome/theme/assets/icons/notification.png and /dev/null differ diff --git a/config/awesome/theme/assets/icons/taglist/dot.png b/config/awesome/theme/assets/icons/taglist/dot.png deleted file mode 100644 index 00a5ab4..0000000 Binary files a/config/awesome/theme/assets/icons/taglist/dot.png and /dev/null differ diff --git a/config/awesome/theme/assets/icons/taglist/dot.svg b/config/awesome/theme/assets/icons/taglist/dot.svg deleted file mode 100644 index f705217..0000000 --- a/config/awesome/theme/assets/icons/taglist/dot.svg +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/config/awesome/theme/assets/icons/taglist/ghost.png b/config/awesome/theme/assets/icons/taglist/ghost.png deleted file mode 100644 index 57f444a..0000000 Binary files a/config/awesome/theme/assets/icons/taglist/ghost.png and /dev/null differ diff --git a/config/awesome/theme/assets/icons/taglist/ghost.svg b/config/awesome/theme/assets/icons/taglist/ghost.svg deleted file mode 100644 index 1496d8d..0000000 --- a/config/awesome/theme/assets/icons/taglist/ghost.svg +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/config/awesome/theme/assets/icons/taglist/pacman.png b/config/awesome/theme/assets/icons/taglist/pacman.png deleted file mode 100644 index d999d84..0000000 Binary files a/config/awesome/theme/assets/icons/taglist/pacman.png and /dev/null differ diff --git a/config/awesome/theme/assets/icons/taglist/pacman.svg b/config/awesome/theme/assets/icons/taglist/pacman.svg deleted file mode 100644 index 47fe395..0000000 --- a/config/awesome/theme/assets/icons/taglist/pacman.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/config/awesome/theme/assets/icons/volume.png b/config/awesome/theme/assets/icons/volume.png deleted file mode 100644 index 2c02d4a..0000000 Binary files a/config/awesome/theme/assets/icons/volume.png and /dev/null differ diff --git a/config/awesome/theme/assets/montereyNight.png b/config/awesome/theme/assets/montereyNight.png new file mode 100755 index 0000000..afec9dc Binary files /dev/null and b/config/awesome/theme/assets/montereyNight.png differ diff --git a/config/awesome/theme/assets/music.png b/config/awesome/theme/assets/music.png new file mode 100755 index 0000000..aae8c49 Binary files /dev/null and b/config/awesome/theme/assets/music.png differ diff --git a/config/awesome/theme/assets/nasa.png b/config/awesome/theme/assets/nasa.png new file mode 100644 index 0000000..f2cbddc Binary files /dev/null and b/config/awesome/theme/assets/nasa.png differ diff --git a/config/awesome/theme/assets/no_music.png b/config/awesome/theme/assets/no_music.png deleted file mode 100644 index 9dd2c7f..0000000 Binary files a/config/awesome/theme/assets/no_music.png and /dev/null differ diff --git a/config/awesome/theme/assets/pfp.png b/config/awesome/theme/assets/pfp.png old mode 100644 new mode 100755 diff --git a/config/awesome/theme/assets/wallpaper.jpg b/config/awesome/theme/assets/wallpaper.jpg deleted file mode 100755 index 2c58630..0000000 Binary files a/config/awesome/theme/assets/wallpaper.jpg and /dev/null differ diff --git a/config/awesome/theme/assets/wallpaperbak.jpg b/config/awesome/theme/assets/wallpaperbak.jpg deleted file mode 100644 index 234060d..0000000 Binary files a/config/awesome/theme/assets/wallpaperbak.jpg and /dev/null differ diff --git a/config/awesome/theme/day/theme.lua b/config/awesome/theme/day/theme.lua deleted file mode 100644 index 74acb4e..0000000 --- a/config/awesome/theme/day/theme.lua +++ /dev/null @@ -1,284 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local gfs = require("gears.filesystem") - --- Theme handling library -local themes_path = gfs.get_themes_dir() -local theme = dofile(themes_path .. "default/theme.lua") -local theme_assets = require("beautiful.theme_assets") -local xresources = require("beautiful.xresources") -local xrdb = xresources.get_current_theme() - --- Helpers -local helpers = require("helpers") - --- Beautiful Day Theme --------------------------- - --- Catppuccin Dawn Colorscheme -local color_palette = { - rosewater = "#DC907F", - flamingo = "#DD7878", - pink = "#EC83D0", - mauve = "#9247ED", - red = "#BB0D33", - maroon = "#E63B4A", - peach = "#FE640B", - yellow = "#E49320", - green = "#53A947", - teal = "#23979F", - sky = "#04A5E5", - blue = "#3474EE", - sapphire = "#209FB5", - lavender = "#7287FD", - white = "#575279", - gray2 = "#696486", - gray1 = "#7B7794", - gray0 = "#8E89A1", - black5 = "#A09BAE", - black4 = "#B2AEBC", - black0 = "#C4C0C9", - black3 = "#D7D2D6", - black1 = "#E9E5E4", - black2 = "#FBF7F1", -} - -theme.xbackground = color_palette.black2 -theme.xforeground = color_palette.white -theme.xcolor0 = color_palette.gray0 -theme.xcolor1 = color_palette.red -theme.xcolor2 = color_palette.green -theme.xcolor3 = color_palette.yellow -theme.xcolor4 = color_palette.blue -theme.xcolor5 = color_palette.mauve -theme.xcolor6 = color_palette.pink -theme.xcolor7 = color_palette.white -theme.xcolor8 = color_palette.gray1 -theme.xcolor9 = color_palette.maroon -theme.xcolor10 = color_palette.teal -theme.xcolor11 = color_palette.peach -theme.xcolor12 = color_palette.sky -theme.xcolor13 = color_palette.lavender -theme.xcolor14 = color_palette.flamingo -theme.xcolor15 = color_palette.white -theme.darker_bg = color_palette.black1 -theme.lighter_bg = color_palette.black3 -theme.dashboard_fg = color_palette.gray2 -theme.transparent = "#00000000" - --- PFP -theme.pfp = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/pfp.png") - --- Awesome Logo -theme.awesome_logo = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/awesome_logo.svg") - --- Fonts -theme.font_name = "Iosevka Nerd Font Mono " -theme.font = theme.font_name .. "8" -theme.icon_font_name = "Material Design Icons Desktop " -theme.icon_font = theme.icon_font_name .. "18" -theme.font_taglist = theme.icon_font_name .. "16" -theme.prompt_font = theme.font_name .. "Bold 10" - --- Background Colors -theme.bg_dark = theme.darker_bg -theme.bg_normal = theme.xbackground -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 - --- Accent colors -theme.accent = theme.xcolor6 -theme.hover_effect = theme.accent .. "44" - --- Foreground Colors -theme.fg_normal = theme.xforeground -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 = dpi(0) -theme.border_normal = theme.darker_bg -theme.border_focus = theme.darker_bg -theme.widget_border_width = dpi(2) -theme.widget_border_color = theme.darker_bg - --- Radius -theme.border_radius = dpi(10) -theme.client_radius = theme.border_radius -theme.dashboard_radius = theme.border_radius -theme.widget_radius = theme.border_radius - --- Titlebars -theme.titlebar_enabled = true -theme.titlebar_bg = theme.xbackground -theme.titlebar_fg = theme.xforeground - --- Music -theme.music_bg = theme.xbackground -theme.music_bg_accent = theme.darker_bg -theme.music_accent = theme.lighter_bg - --- Pop up notifications -theme.pop_size = dpi(190) -theme.pop_bg = theme.xbackground -theme.pop_vol_color = theme.accent -theme.pop_brightness_color = theme.accent -theme.pop_bar_bg = theme.accent .. "44" -theme.pop_fg = theme.xforeground -theme.pop_border_radius = theme.border_radius - --- Tooltip -theme.tooltip_bg = theme.darker_bg -theme.tooltip_widget_bg = theme.xbackground -theme.tooltip_height = dpi(245) -theme.tooltip_width = dpi(200) -theme.tooltip_gap = dpi(10) -theme.tooltip_box_margin = dpi(10) -theme.tooltip_border_radius = theme.border_radius -theme.tooltip_box_border_radius = theme.widget_radius - --- Edge snap -theme.snap_bg = theme.xcolor8 -theme.snap_shape = helpers.rrect(0) - --- Prompts -theme.prompt_bg = theme.transparent -theme.prompt_fg = theme.xforeground - --- Dashboard -theme.dashboard_bg = theme.darker_bg -theme.dashboard_box_bg = theme.xbackground -theme.dashboard_box_fg = theme.dashboard_fg - --- Control center -theme.control_center_radius = dpi(20) -theme.control_center_widget_radius = theme.border_radius -theme.control_center_bg = theme.darker_bg -theme.control_center_widget_bg = theme.xbackground -theme.control_center_button_bg = theme.lighter_bg - --- 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 - --- Mainmenu -theme.menu_font = theme.font_name .. "medium 10" -theme.menu_height = dpi(30) -theme.menu_width = dpi(150) -theme.menu_bg_normal = theme.xbackground -theme.menu_bg_focus = theme.lighter_bg -theme.menu_fg_normal = theme.xforeground -theme.menu_fg_focus = theme.accent -theme.menu_border_width = dpi(0) -theme.menu_border_color = theme.xcolor0 -theme.menu_submenu = "» " -theme.menu_submenu_icon = nil - --- Hotkeys Pop Up -theme.hotkeys_bg = theme.xbackground -theme.hotkeys_fg = theme.xforeground -theme.hotkeys_modifiers_fg = theme.xforeground -theme.hotkeys_font = theme.font_name .. "11" -theme.hotkeys_description_font = theme.font_name .. "9" -theme.hotkeys_shape = helpers.rrect(theme.border_radius) -theme.hotkeys_group_margin = dpi(40) - --- Layout List -theme.layoutlist_border_color = theme.lighter_bg -theme.layoutlist_border_width = theme.border_width -theme.layoutlist_shape_selected = helpers.rrect(dpi(10)) -theme.layoutlist_bg_selected = theme.lighter_bg - --- Recolor Layout icons: -theme = theme_assets.recolor_layout(theme, theme.xforeground) - --- Gaps -theme.useless_gap = dpi(5) - --- Wibar -theme.wibar_bg = theme.darker_bg -theme.wibar_widget_bg = theme.xbackground - --- Dock -theme.dock_bg = theme.wibar_bg -theme.dock_focused_bg = theme.lighter_bg -theme.dock_accent = theme.accent - --- Systray -theme.systray_icon_spacing = dpi(15) -theme.bg_systray = theme.wibar_bg -theme.systray_icon_size = dpi(15) -theme.systray_max_rows = 2 - --- Tabs -theme.mstab_bar_height = dpi(60) -theme.mstab_bar_padding = dpi(0) -theme.mstab_border_radius = theme.border_radius -theme.tabbar_disable = true -theme.tabbar_style = "modern" -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 -theme.mstab_bar_ontop = true - --- Notifications -theme.notification_spacing = dpi(20) -theme.notification_border_radius = theme.border_radius -theme.notification_border_width = dpi(0) - --- Notif center -theme.notif_center_radius = theme.border_radius -theme.notif_center_box_radius = theme.notif_center_radius / 2 -theme.notif_center_notifs_bg = theme.xbackground -theme.notif_center_notifs_bg_accent = theme.darker_bg -theme.notif_center_notifs_accent = theme.lighter_bg - --- Swallowing -theme.dont_swallow_classname_list = { - "firefox", - "gimp", - "Google-chrome", - "Thunar", -} - --- Layout Machi -theme.machi_switcher_border_color = theme.darker_bg -theme.machi_switcher_border_opacity = 0.25 -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_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.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 = 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 -theme.task_preview_widget_margin = dpi(15) - -theme.fade_duration = 250 - -return theme diff --git a/config/awesome/theme/night/theme.lua b/config/awesome/theme/night/theme.lua deleted file mode 100644 index 9ede486..0000000 --- a/config/awesome/theme/night/theme.lua +++ /dev/null @@ -1,281 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local gfs = require("gears.filesystem") - --- Theme handling library -local themes_path = gfs.get_themes_dir() -local theme = dofile(themes_path .. "default/theme.lua") -local theme_assets = require("beautiful.theme_assets") -local xresources = require("beautiful.xresources") -local xrdb = xresources.get_current_theme() - --- Helpers -local helpers = require("helpers") - --- Aesthetic Night Theme ---------------------------- - --- Rxyhn's Catppuccin Colorscheme -local color_palette = { - rosewater = "#F5E0DC", -- Rosewater - flamingo = "#F2CDCD", -- Flamingo - mauve = "#DDB6F2", -- Mauve - pink = "#F5C2E7", -- Pink - red = "#F28FAD", -- Red - maroon = "#E8A2AF", -- Maroon - peach = "#F8BD96", -- Peach - yellow = "#FAE3B0", -- Yellow - green = "#ABE9B3", -- Green - blue = "#96CDFB", -- Blue - sky = "#89DCEB", -- Sky - teal = "#B5E8E0", -- Teal - lavender = "#C9CBFF", -- Lavender - white = "#c5c8c9", - black0 = "#0d1416", - black1 = "#111719", - black2 = "#131a1c", - black3 = "#192022", - black4 = "#202729", - gray0 = "#363D3E", - gray1 = "#4A5051", - gray2 = "#5C6262", -} - -theme.xbackground = color_palette.black2 -theme.xforeground = color_palette.white -theme.xcolor0 = color_palette.gray0 -theme.xcolor1 = color_palette.red -theme.xcolor2 = color_palette.green -theme.xcolor3 = color_palette.yellow -theme.xcolor4 = color_palette.blue -theme.xcolor5 = color_palette.mauve -theme.xcolor6 = color_palette.pink -theme.xcolor7 = color_palette.white -theme.xcolor8 = color_palette.gray1 -theme.xcolor9 = color_palette.maroon -theme.xcolor10 = color_palette.teal -theme.xcolor11 = color_palette.peach -theme.xcolor12 = color_palette.sky -theme.xcolor13 = color_palette.lavender -theme.xcolor14 = color_palette.flamingo -theme.xcolor15 = color_palette.white -theme.darker_bg = color_palette.black0 -theme.lighter_bg = color_palette.black3 -theme.dashboard_fg = color_palette.gray2 -theme.transparent = "#00000000" - --- PFP -theme.pfp = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/pfp.png") - --- Awesome Logo -theme.awesome_logo = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/awesome_logo.svg") - --- Fonts -theme.font_name = "Iosevka Nerd Font Mono " -theme.font = theme.font_name .. "8" -theme.icon_font_name = "Material Design Icons Desktop " -theme.icon_font = theme.icon_font_name .. "18" -theme.font_taglist = theme.icon_font_name .. "16" -theme.prompt_font = theme.font_name .. "Bold 10" - --- Background Colors -theme.bg_dark = theme.darker_bg -theme.bg_normal = theme.xbackground -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 - --- Accent colors -theme.accent = theme.xcolor4 -theme.hover_effect = theme.accent .. "44" - --- Foreground Colors -theme.fg_normal = theme.xforeground -theme.fg_focus = theme.accent -theme.fg_urgent = theme.xcolor1 -theme.fg_minimize = theme.xcolor0 - --- Borders -theme.border_width = dpi(0) -theme.oof_border_width = dpi(0) -theme.border_normal = theme.darker_bg -theme.border_focus = theme.darker_bg -theme.widget_border_width = dpi(2) -theme.widget_border_color = theme.darker_bg - --- Radius -theme.border_radius = dpi(10) -theme.client_radius = theme.border_radius -theme.dashboard_radius = theme.border_radius -theme.widget_radius = theme.border_radius - --- Titlebars -theme.titlebar_enabled = true -theme.titlebar_bg = theme.xbackground -theme.titlebar_fg = theme.xforeground - --- Music -theme.music_bg = theme.xbackground -theme.music_bg_accent = theme.darker_bg -theme.music_accent = theme.lighter_bg - --- Pop up -theme.pop_size = dpi(190) -theme.pop_bg = theme.xbackground -theme.pop_vol_color = theme.accent -theme.pop_brightness_color = theme.accent -theme.pop_bar_bg = theme.accent .. "44" -theme.pop_fg = theme.xforeground -theme.pop_border_radius = theme.border_radius - --- Tooltip -theme.tooltip_bg = theme.darker_bg -theme.tooltip_widget_bg = theme.xbackground -theme.tooltip_height = dpi(245) -theme.tooltip_width = dpi(200) -theme.tooltip_gap = dpi(10) -theme.tooltip_box_margin = dpi(10) -theme.tooltip_border_radius = theme.border_radius -theme.tooltip_box_border_radius = theme.widget_radius - --- Edge snap -theme.snap_bg = theme.xcolor8 -theme.snap_shape = helpers.rrect(0) - --- Prompts -theme.prompt_bg = theme.transparent -theme.prompt_fg = theme.xforeground - --- Dashboard -theme.dashboard_bg = theme.darker_bg -theme.dashboard_box_bg = theme.lighter_bg -theme.dashboard_box_fg = theme.dashboard_fg - --- Control center -theme.control_center_radius = dpi(20) -theme.control_center_widget_radius = theme.border_radius -theme.control_center_bg = theme.darker_bg -theme.control_center_widget_bg = theme.xbackground -theme.control_center_button_bg = theme.lighter_bg - --- 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 - --- Mainmenu -theme.menu_font = theme.font_name .. "medium 10" -theme.menu_height = dpi(30) -theme.menu_width = dpi(150) -theme.menu_bg_normal = theme.xbackground -theme.menu_bg_focus = theme.lighter_bg -theme.menu_fg_normal = theme.xforeground -theme.menu_fg_focus = theme.accent -theme.menu_border_width = dpi(0) -theme.menu_border_color = theme.xcolor0 -theme.menu_submenu = "» " -theme.menu_submenu_icon = nil - --- Hotkeys Pop Up -theme.hotkeys_bg = theme.xbackground -theme.hotkeys_fg = theme.xforeground -theme.hotkeys_modifiers_fg = theme.xforeground -theme.hotkeys_font = theme.font_name .. "11" -theme.hotkeys_description_font = theme.font_name .. "9" -theme.hotkeys_shape = helpers.rrect(theme.border_radius) -theme.hotkeys_group_margin = dpi(40) - --- Layout List -theme.layoutlist_border_color = theme.lighter_bg -theme.layoutlist_border_width = theme.border_width -theme.layoutlist_shape_selected = helpers.rrect(dpi(10)) -theme.layoutlist_bg_selected = theme.lighter_bg - --- Recolor Layout icons: -theme = theme_assets.recolor_layout(theme, theme.xforeground) - --- Gaps -theme.useless_gap = dpi(5) - --- Wibar -theme.wibar_bg = theme.darker_bg -theme.wibar_widget_bg = theme.lighter_bg - --- Dock -theme.dock_bg = theme.wibar_bg -theme.dock_focused_bg = theme.lighter_bg -theme.dock_accent = theme.accent - --- Systray -theme.systray_icon_spacing = dpi(15) -theme.bg_systray = theme.wibar_bg -theme.systray_icon_size = dpi(15) -theme.systray_max_rows = 2 - --- Tabs -theme.mstab_bar_height = dpi(60) -theme.mstab_bar_padding = dpi(0) -theme.mstab_border_radius = theme.border_radius -theme.tabbar_disable = true -theme.tabbar_style = "modern" -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 -theme.mstab_bar_ontop = true - --- Notifications -theme.notification_spacing = dpi(20) -theme.notification_border_radius = theme.border_radius -theme.notification_border_width = dpi(0) - --- Notif center -theme.notif_center_radius = theme.border_radius -theme.notif_center_box_radius = theme.notif_center_radius / 2 -theme.notif_center_notifs_bg = theme.lighter_bg -theme.notif_center_notifs_accent = theme.xcolor0 - --- Swallowing -theme.dont_swallow_classname_list = { - "firefox", - "gimp", - "Google-chrome", - "Thunar", -} - --- Layout Machi -theme.machi_switcher_border_color = theme.darker_bg -theme.machi_switcher_border_opacity = 0.25 -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_client_border_radius = dpi(5) -theme.tag_preview_client_opacity = 0.1 -theme.tag_preview_client_bg = theme.xbackground -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 -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 -theme.task_preview_widget_margin = dpi(15) - -theme.fade_duration = 250 - -return theme diff --git a/config/awesome/theme/picom.conf b/config/awesome/theme/picom.conf deleted file mode 100644 index 7621479..0000000 --- a/config/awesome/theme/picom.conf +++ /dev/null @@ -1,107 +0,0 @@ -#========================= Corners =========================# -corner-radius = 12; -rounded-corners-exclude = [ - # "!window_type = 'normal'", - # "class_g ?= 'rofi'", -]; - -round-borders = 1; -round-borders-exclude = [ - #"class_g = 'TelegramDesktop'", -]; - -#========================= Shadows =========================# -shadow-opacity = 0.50; -shadow-radius = 14; -shadow-opacity = 0.50; -shadow-offset-x = -14; -shadow-offset-y = -14; - -shadow-exclude = [ - "class_g = 'slop'", - "window_type = 'menu'", - "window_type = 'desktop'", - "class_g = 'Firefox' && window_type *= 'utility'", - "_GTK_FRAME_EXTENTS@:c" -]; - -#========================= Fading =========================# -fading = true; -fade-in-step = 0.03; -fade-out-step = 0.03; -fade-delta = 5; - -no-fading-openclose = false -no-fading-destroyed-argb = true - -fade-exclude = [ - "class_g = 'slop'" # maim -] - -#========================= Opacity =========================# -# inactive-opacity = 1; -frame-opacity = 1; -inactive-opacity-override = false; - -# active-opacity = 1.0; -# inactive-dim = 0.0; - -focus-exclude = [ - "class_g = 'Cairo-clock'", - "class_g ?= 'rofi'", - "class_g ?= 'slop'" -]; - -opacity-rule = [ - "85:class_g = 'splash'" -]; - -#========================= Blurring =========================# -blur: { - method = "dual_kawase"; - strength = 5.0; - deviation = 1.0; - kernel = "11x11gaussian"; -} - -blur-background = true; -blur-background-frame = true; -blur-background-fixed = true; - -blur-background-exclude = [ - "class_g = 'slop'", - "class_g = 'Firefox' && argb", - "_GTK_FRAME_EXTENTS@:c" -]; - -#========================= General Settings =========================# -backend = "glx"; -vsync = true; -daemon = false; -dbus = false; -mark-wmwin-focused = true; -mark-ovredir-focused = true; -detect-rounded-corners = true; -detect-client-opacity = true; -detect-client-leader = true; -detect-transient = true; -glx-no-stencil = true; -use-damage = true; -resize-damage = 1; -transparent-clipping = false; - -wintypes: -{ - tooltip = { fade = true; shadow = false; focus = true; }; - menu = { full-shadow = true;}; - popup_menu = { full-shadow = true;}; - utility = {full-shadow = true;}; - toolbar = {full-shadow = true;}; - normal = {full-shadow = true;}; - notification = {full-shadow = true;}; - dialog = {full-shadow = true}; - dock = {full-shadow = true;}; - dropdown_menu = { full-shadow = true;}; -}; - - diff --git a/config/awesome/theme/rofi.rasi b/config/awesome/theme/rofi.rasi deleted file mode 100644 index 21ae17a..0000000 --- a/config/awesome/theme/rofi.rasi +++ /dev/null @@ -1,87 +0,0 @@ -configuration { - modi: "drun"; - display-drun: "Apps"; - drun-display-format: "{name}"; - font: "Iosevka 8"; - show-icons: true; - icon-theme: "Papirus"; -} - -@theme "/dev/null" - -* { - bg: #061115; - fg: #d9d7d6; - accent: #1c252c; - darkerAccent: #162026; - active: #484e5b; - rad: 12px; - - background-color: @bg; - text-color: @fg; -} - -window { - 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 20px; - border-radius: @rad; - background-color: @darkerAccent; -} - -textbox { - str: ""; - expand: false; - padding: 0 1% 0; - horizontal-align: 0.5; - vertical-align: 0.5; - border-radius: @rad; - background-color: @accent; - text-color: @bg; - font: "Material Icons 17"; -} - -entry{ - expand: true; - padding: 2%; - placeholder: "Search"; - border-radius: @rad; - background-color: @darkerAccent; -} - -listview { - columns: 2; - lines: 2; - cycle: false; - margin: 20px; -} - -element { - orientation: vertical; - padding: 1em; -} - -element-text, element-icon { - padding: 0.2em; - horizontal-align: 0.5; - background-color: inherit; -} - -element-icon { size: 48px; } -listview, element, element selected, element-text, element-icon { cursor: pointer; } - -element selected { - background-color: @darkerAccent; - text-color: @fg; - border-radius: @rad; -} diff --git a/config/awesome/theme/theme.lua b/config/awesome/theme/theme.lua old mode 100644 new mode 100755 index 83540d2..ccd865a --- a/config/awesome/theme/theme.lua +++ b/config/awesome/theme/theme.lua @@ -1,269 +1,253 @@ --- Standard awesome library +--- ░▀█▀░█░█░█▀▀░█▄█░█▀▀ +--- ░░█░░█▀█░█▀▀░█░█░█▀▀ +--- ░░▀░░▀░▀░▀▀▀░▀░▀░▀▀▀ + local gears = require("gears") local gfs = require("gears.filesystem") - --- Theme handling library local themes_path = gfs.get_themes_dir() local theme = dofile(themes_path .. "default/theme.lua") 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") +--- ░█▀█░█▀▀░█▀▀░▀█▀░█░█░█▀▀░▀█▀░▀█▀░█▀▀░░░█▀█░▀█▀░█▀▀░█░█░▀█▀ +--- ░█▀█░█▀▀░▀▀█░░█░░█▀█░█▀▀░░█░░░█░░█░░░░░█░█░░█░░█░█░█▀█░░█░ +--- ░▀░▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░░▀░░▀▀▀░▀▀▀░░░▀░▀░▀▀▀░▀▀▀░▀░▀░░▀░ --- Theme ----------- - --- 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.darker_bg = "#0a1419" -theme.lighter_bg = "#162026" -theme.dashboard_fg = "#666c79" +--- Special +theme.xforeground = "#D9D7D6" +theme.darker_xbackground = "#000a0e" +theme.xbackground = "#061115" +theme.lighter_xbackground = "#0d181c" +theme.one_bg = "#131e22" +theme.one_bg2 = "#1c272b" +theme.one_bg3 = "#242f33" +theme.grey = "#313c40" +theme.grey_fg = "#3b464a" +theme.grey_fg2 = "#455054" +theme.light_grey = "#4f5a5e" theme.transparent = "#00000000" --- PFP -theme.pfp = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/pfp.png") +--- Black +theme.xcolor0 = "#1C252C" +theme.xcolor8 = "#484E5B" --- Wallpaper -theme.wallpaper = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/bg.png") +--- Red +theme.xcolor1 = "#DF5B61" +theme.xcolor9 = "#F16269" --- Awesome Logo -theme.awesome_logo = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/awesome.png") +--- Green +theme.xcolor2 = "#78B892" +theme.xcolor10 = "#8CD7AA" --- Notifications bell icon -theme.notification_bell_icon = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/notification-bell.png") +--- Yellow +theme.xcolor3 = "#DE8F78" +theme.xcolor11 = "#E9967E" --- Notifications icon -theme.notification_icon = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/notification.png") +--- Blue +theme.xcolor4 = "#6791C9" +theme.xcolor12 = "#79AAEB" --- Popup notifications icon -theme.volume_icon = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/volume.png") -theme.volume_muted_icon = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/mute.png") -theme.brightness_icon = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/icons/brightness.png") +--- Magenta +theme.xcolor5 = "#BC83E3" +theme.xcolor13 = "#C488EC" --- Fonts -theme.font_name = "Iosevka Nerd Font Mono " -theme.font = theme.font_name .. "8" -theme.icon_font_name = "Material Icons " -theme.icon_font = theme.icon_font_name .. "18" -theme.font_taglist = theme.icon_font_name .. "13" +--- Cyan +theme.xcolor6 = "#67AFC1" +theme.xcolor14 = "#7ACFE4" --- Background Colors -theme.bg_dark = theme.darker_bg +--- White +theme.xcolor7 = "#D9D7D6" +theme.xcolor15 = "#E5E5E5" + +--- ░█▀▀░█▀█░█▀█░▀█▀░█▀▀ +--- ░█▀▀░█░█░█░█░░█░░▀▀█ +--- ░▀░░░▀▀▀░▀░▀░░▀░░▀▀▀ + +--- Ui Fonts +theme.font_name = "Roboto " +theme.font = theme.font_name .. "Medium 10" + +--- Icon Fonts +theme.icon_font = "Material Icons " + +--- ░█▀▀░█▀█░█░░░█▀█░█▀▄░█▀▀ +--- ░█░░░█░█░█░░░█░█░█▀▄░▀▀█ +--- ░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀▀▀ + +--- Background Colors theme.bg_normal = theme.xbackground 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 +--- Foreground Colors theme.fg_normal = theme.xforeground -theme.fg_focus = theme.xforeground +theme.fg_focus = theme.accent theme.fg_urgent = theme.xcolor1 theme.fg_minimize = theme.xcolor0 --- Borders -theme.border_width = dpi(0) -theme.oof_border_width = dpi(0) -theme.border_normal = theme.darker_bg -theme.border_focus = theme.darker_bg -theme.widget_border_width = dpi(2) -theme.widget_border_color = theme.darker_bg +--- Accent colors +function theme.random_accent_color() + local accents = { + theme.xcolor9, + theme.xcolor10, + theme.xcolor11, + theme.xcolor12, + theme.xcolor13, + theme.xcolor14, + } --- Radius -theme.border_radius = dpi(12) -theme.client_radius = dpi(10) -theme.dashboard_radius = dpi(10) -theme.bar_radius = dpi(10) + local i = math.random(1, #accents) + return accents[i] +end --- Taglist -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.accent = theme.xcolor4 -theme.taglist_bg_focus = theme.lighter_bg -theme.taglist_fg_focus = theme.xcolor3 +--- UI events +theme.leave_event = transparent +theme.enter_event = "#ffffff" .. "10" +theme.press_event = "#ffffff" .. "15" +theme.release_event = "#ffffff" .. "10" -theme.taglist_bg_urgent = theme.wibar_bg -theme.taglist_fg_urgent = theme.xcolor6 +--- Widgets +theme.widget_bg = "#162026" -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.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 +--- Titlebars theme.titlebar_enabled = true -theme.titlebar_size = dpi(45) -theme.titlebar_unfocused = theme.xcolor0 +theme.titlebar_bg = theme.xbackground +theme.titlebar_fg = theme.xforeground --- Pop up notifications -theme.pop_size = dpi(180) -theme.pop_bg = theme.xbackground -theme.pop_bar_bg = theme.xcolor0 -theme.pop_vol_color = theme.xcolor4 -theme.pop_brightness_color = theme.xcolor5 -theme.pop_fg = theme.xforeground -theme.pop_border_radius = theme.border_radius +--- Wibar +theme.wibar_bg = "#0B161A" +theme.wibar_height = dpi(40) --- Tooltip -theme.tooltip_bg = theme.xbackground -theme.tooltip_height = dpi(245) -theme.tooltip_width = dpi(200) -theme.tooltip_gap = dpi(10) -theme.tooltip_box_margin = dpi(10) -theme.tooltip_border_radius = theme.border_radius -theme.tooltip_box_border_radius = theme.bar_radius +--- Music +theme.music_bg = theme.xbackground +theme.music_bg_accent = theme.darker_xbackground +theme.music_accent = theme.lighter_xbackground --- Edge snap +--- ░█░█░▀█▀░░░█▀▀░█░░░█▀▀░█▄█░█▀▀░█▀█░▀█▀░█▀▀ +--- ░█░█░░█░░░░█▀▀░█░░░█▀▀░█░█░█▀▀░█░█░░█░░▀▀█ +--- ░▀▀▀░▀▀▀░░░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░░▀░░▀▀▀ + +--- Image Assets +theme.wallpaper = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/nasa.png") +theme.pfp = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/pfp.png") +theme.music = gears.surface.load_uncached(gfs.get_configuration_dir() .. "theme/assets/music.png") + +--- Icon Theme +--- Define the icon theme for application icons. If not set then the icons +--- from /usr/share/icons and /usr/share/icons/hicolor will be used. +theme.icon_theme = "WhiteSur-dark" + +--- Borders +theme.border_width = 0 +theme.oof_border_width = 0 +theme.border_color_marked = theme.titlebar_bg +theme.border_color_active = theme.titlebar_bg +theme.border_color_normal = theme.titlebar_bg +theme.border_color_new = theme.titlebar_bg +theme.border_color_urgent = theme.titlebar_bg +theme.border_color_floating = theme.titlebar_bg +theme.border_color_maximized = theme.titlebar_bg +theme.border_color_fullscreen = theme.titlebar_bg + +--- Corner Radius +theme.border_radius = 12 + +--- Edge snap theme.snap_bg = theme.xcolor8 -theme.snap_shape = helpers.rrect(0) +theme.snap_shape = helpers.ui.rrect(0) --- Prompts -theme.prompt_bg = transparent -theme.prompt_fg = theme.xforeground +--- Main Menu +theme.main_menu_bg = theme.lighter_xbackground --- dashboard -theme.dashboard_width = dpi(300) -theme.dashboard_box_bg = theme.lighter_bg -theme.dashboard_box_fg = theme.dashboard_fg +--- Tooltip +theme.tooltip_bg = theme.lighter_xbackground +theme.tooltip_fg = theme.xforeground +theme.tooltip_font = theme.font_name .. "Regular 10" --- Playerctl -theme.playerctl_ignore = {"firefox", "qutebrowser", "chromium", "brave"} -theme.playerctl_player = {"spotify", "mpd", "%any"} -theme.playerctl_update_on_activity = false -theme.playerctl_position_update_interval = 1 - --- Mainmenu -theme.menu_font = theme.font_name .. "medium 10" -theme.menu_height = dpi(30) -theme.menu_width = dpi(150) -theme.menu_bg_normal = theme.xbackground -theme.menu_bg_focus = theme.lighter_bg -theme.menu_fg_normal= theme.xforeground -theme.menu_fg_focus= theme.xcolor4 -theme.menu_border_width = dpi(0) -theme.menu_border_color = theme.xcolor0 -theme.menu_submenu = "» " -theme.menu_submenu_icon = nil - --- Hotkeys Pop Up +--- Hotkeys Pop Up theme.hotkeys_bg = theme.xbackground theme.hotkeys_fg = theme.xforeground theme.hotkeys_modifiers_fg = theme.xforeground -theme.hotkeys_font = theme.font_name .. "11" -theme.hotkeys_description_font = theme.font_name .. "9" -theme.hotkeys_shape = helpers.rrect(theme.border_radius) -theme.hotkeys_group_margin = dpi(40) +theme.hotkeys_font = theme.font_name .. "Medium 12" +theme.hotkeys_description_font = theme.font_name .. "Regular 10" +theme.hotkeys_shape = helpers.ui.rrect(theme.border_radius) +theme.hotkeys_group_margin = dpi(50) --- Layout List -theme.layoutlist_border_color = theme.lighter_bg -theme.layoutlist_border_width = theme.border_width -theme.layoutlist_shape_selected = helpers.rrect(dpi(10)) -theme.layoutlist_bg_selected = theme.lighter_bg +--- Tag list +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) --- Recolor Layout icons: +--- Tag preview +theme.tag_preview_widget_margin = dpi(10) +theme.tag_preview_widget_border_radius = theme.border_radius +theme.tag_preview_client_border_radius = theme.border_radius / 2 +theme.tag_preview_client_opacity = 1 +theme.tag_preview_client_bg = theme.wibar_bg +theme.tag_preview_client_border_color = theme.wibar_bg +theme.tag_preview_client_border_width = 0 +theme.tag_preview_widget_bg = theme.wibar_bg +theme.tag_preview_widget_border_color = theme.wibar_bg +theme.tag_preview_widget_border_width = 0 + +--- Layout List +theme.layoutlist_shape_selected = helpers.ui.rrect(theme.border_radius) +theme.layoutlist_bg_selected = theme.widget_bg + +--- Recolor Layout icons: theme = theme_assets.recolor_layout(theme, theme.xforeground) --- Gaps -theme.useless_gap = dpi(5) +--- Gaps +theme.useless_gap = dpi(2) --- Wibar -theme.wibar_width = dpi(45) -theme.wibar_bg = theme.xbackground -theme.wibar_position = "left" +--- Systray +theme.systray_icon_size = dpi(20) +theme.systray_icon_spacing = dpi(10) +theme.bg_systray = theme.wibar_bg +--- theme.systray_max_rows = 2 --- Tabs +--- Tabs theme.mstab_bar_height = dpi(60) theme.mstab_bar_padding = dpi(0) theme.mstab_border_radius = theme.border_radius theme.tabbar_disable = true theme.tabbar_style = "modern" -theme.tabbar_bg_focus = theme.lighter_bg -theme.tabbar_bg_normal = theme.darker_bg +theme.tabbar_bg_focus = theme.widget_bg +theme.tabbar_bg_normal = theme.lighter_xbackground 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 +theme.tabbar_size = 0 theme.mstab_bar_ontop = true --- Notifications -theme.notification_spacing = 24 -theme.notification_border_radius = dpi(6) -theme.notification_border_width = dpi(0) +--- Notifications +theme.notification_spacing = dpi(4) +theme.notification_bg = theme.xbackground +theme.notification_bg_alt = theme.lighter_xbackground --- Notif center -theme.notif_center_radius = theme.border_radius -theme.notif_center_box_radius = theme.notif_center_radius / 2 +--- Notif center +theme.notif_center_notifs_bg = theme.one_bg2 +theme.notif_center_notifs_bg_alt = theme.one_bg2 --- Swallowing +--- Swallowing theme.dont_swallow_classname_list = { - "firefox", "gimp", "Google-chrome", "Thunar" + "firefox", + "gimp", + "Google-chrome", + "Thunar", } --- Layout Machi -theme.machi_switcher_border_color = theme.darker_bg +--- Layout Machi +theme.machi_switcher_border_color = theme.lighter_xbackground theme.machi_switcher_border_opacity = 0.25 -theme.machi_editor_border_color = theme.darker_bg +theme.machi_editor_border_color = theme.lighter_xbackground theme.machi_editor_border_opacity = 0.25 theme.machi_editor_active_opacity = 0.25 --- Tag Preview -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.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 = 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 -theme.task_preview_widget_margin = dpi(15) - -theme.fade_duration = 250 - return theme diff --git a/config/awesome/theme/themes b/config/awesome/theme/themes deleted file mode 100755 index ed688f8..0000000 --- a/config/awesome/theme/themes +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh -# Simple theme-switcher script. -# author https://github.com/rxyhn - -# var -######## -awesome=$HOME/.config/awesome/rc.lua -theme=$HOME/.config/awesome/theme -term=$HOME/.config/alacritty/alacritty.yml - -# Beautiful day themes -######################### -day () { - # colorscheme - sed -i "17s/.*/theme = themes[1]/g" $awesome - # picom - sed -i "14s/.*/shadow-opacity = 0.25;/g" $theme/picom.conf - # alacritty - sed -i "4s/.*/ - .config\/alacritty\/themes\/day.yml/g" $term -} - -# Aesthetic night themes -########################### -night () { - # colorscheme - sed -i "17s/.*/theme = themes[2]/g" $awesome - # picom - sed -i "14s/.*/shadow-opacity = 0.50;/g" $theme/picom.conf - # alacritty - sed -i "4s/.*/ - .config\/alacritty\/themes\/night.yml/g" $term -} - -case $1 in - day) - day - ;; - - night) - night - ;; - - *) -esac diff --git a/config/awesome/ui/bar/init.lua b/config/awesome/ui/bar/init.lua deleted file mode 100644 index 0a68d79..0000000 --- a/config/awesome/ui/bar/init.lua +++ /dev/null @@ -1 +0,0 @@ -require("ui.bar.topwibar") diff --git a/config/awesome/ui/bar/taglist.lua b/config/awesome/ui/bar/taglist.lua deleted file mode 100644 index fd724da..0000000 --- a/config/awesome/ui/bar/taglist.lua +++ /dev/null @@ -1,288 +0,0 @@ -local wibox = require("wibox") -local awful = require("awful") -local gears = require("gears") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Papirus Taglist from https://github.com/crylia -local icon_cache = {} - -function Get_icon(theme, client, program_string, class_string, is_steam) - client = client or nil - program_string = program_string or nil - class_string = class_string or nil - is_steam = is_steam or nil - - if theme and (client or program_string or class_string) then - local clientName - if is_steam then - clientName = "steam_icon_" .. tostring(client) .. ".svg" - elseif client then - if client.class then - clientName = string.lower(client.class:gsub(" ", "")) .. ".svg" - elseif client.name then - clientName = string.lower(client.name:gsub(" ", "")) .. ".svg" - else - if client.icon then - return client.icon - else - return "/usr/share/icons/Papirus-Dark/128x128/apps/application-default-icon.svg" - end - end - else - if program_string then - clientName = program_string .. ".svg" - else - clientName = class_string .. ".svg" - end - end - - for index, icon in ipairs(icon_cache) do - if icon:match(clientName) then - return icon - end - end - - local resolutions = { "128x128", "96x96", "64x64", "48x48", "42x42", "32x32", "24x24", "16x16" } - for i, res in ipairs(resolutions) do - local iconDir = "/usr/share/icons/" .. theme .. "/" .. res .. "/apps/" - local ioStream = io.open(iconDir .. clientName, "r") - if ioStream ~= nil then - icon_cache[#icon_cache + 1] = iconDir .. clientName - return iconDir .. clientName - else - clientName = clientName:gsub("^%l", string.upper) - iconDir = "/usr/share/icons/" .. theme .. "/" .. res .. "/apps/" - ioStream = io.open(iconDir .. clientName, "r") - if ioStream ~= nil then - icon_cache[#icon_cache + 1] = iconDir .. clientName - return iconDir .. clientName - elseif not class_string then - return "/usr/share/icons/Papirus-Dark/128x128/apps/application-default-icon.svg" - else - clientName = class_string .. ".svg" - iconDir = "/usr/share/icons/" .. theme .. "/" .. res .. "/apps/" - ioStream = io.open(iconDir .. clientName, "r") - if ioStream ~= nil then - icon_cache[#icon_cache + 1] = iconDir .. clientName - return iconDir .. clientName - else - return "/usr/share/icons/Papirus-Dark/128x128/apps/application-default-icon.svg" - end - end - end - end - if client then - return "/usr/share/icons/Papirus-Dark/128x128/apps/application-default-icon.svg" - end - end -end - -local list_update = function(widget, buttons, label, data, objects) - widget:reset() - - for i, object in ipairs(objects) do - local tag_icon = wibox.widget({ - nil, - { - id = "icon", - resize = true, - widget = wibox.widget.imagebox, - }, - nil, - layout = wibox.layout.align.horizontal, - }) - - local tag_icon_margin = wibox.widget({ - tag_icon, - forced_width = dpi(33), - margins = dpi(3), - widget = wibox.container.margin, - }) - - local tag_label = wibox.widget({ - text = "", - align = "center", - valign = "center", - visible = true, - font = beautiful.font_name .. "Bold 12", - forced_width = dpi(25), - widget = wibox.widget.textbox, - }) - - local tag_label_margin = wibox.widget({ - tag_label, - left = dpi(5), - right = dpi(5), - widget = wibox.container.margin, - }) - - local tag_widget = wibox.widget({ - - id = "widget_margin", - { - id = "container", - tag_label_margin, - layout = wibox.layout.fixed.horizontal, - }, - - fg = beautiful.xforeground, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, 5) - end, - widget = wibox.container.background, - }) - - local function create_buttons(buttons, object) - if buttons then - local btns = {} - for _, b in ipairs(buttons) do - local btn = awful.button({ - modifiers = b.modifiers, - button = b.button, - on_press = function() - b:emit_signal("press", object) - end, - on_release = function() - b:emit_signal("release", object) - end, - }) - btns[#btns + 1] = btn - end - return btns - end - end - - tag_widget:buttons(create_buttons(buttons, object)) - - local text, bg_color, bg_image, icon, args = label(object, tag_label) - tag_label:set_text(object.index) - if object.urgent == true then - tag_widget:set_bg(beautiful.xcolor1) - tag_widget:set_fg(beautiful.xforeground) - elseif object == awful.screen.focused().selected_tag then - tag_widget:set_bg(beautiful.lighter_bg) - tag_widget:set_fg(beautiful.xforeground) - else - tag_widget:set_bg(beautiful.lighter_bg .. 55) - end - - -- Set the icon for each client - for _, client in ipairs(object:clients()) do - tag_label_margin:set_right(0) - local icon = wibox.widget({ - { - id = "icon_container", - { - id = "icon", - resize = true, - widget = wibox.widget.imagebox, - }, - widget = wibox.container.place, - }, - tag_icon_margin, - forced_width = dpi(33), - margins = dpi(6), - widget = wibox.container.margin, - }) - icon.icon_container.icon:set_image(Get_icon("Papirus-Dark", client)) - tag_widget.container:setup({ - icon, - strategy = "exact", - layout = wibox.container.constraint, - }) - end - - local old_wibox, old_cursor, old_bg - tag_widget:connect_signal("mouse::enter", function() - old_bg = tag_widget.bg - if object == awful.screen.focused().selected_tag then - tag_widget.bg = beautiful.accent .. 55 - else - tag_widget.bg = beautiful.accent .. 55 - end - local w = mouse.current_wibox - if w then - old_cursor, old_wibox = w.cursor, w - w.cursor = "hand1" - end - end) - - tag_widget:connect_signal("button::press", function() - if object == awful.screen.focused().selected_tag then - tag_widget.bg = beautiful.accent .. 55 - else - tag_widget.bg = beautiful.accent - end - end) - - tag_widget:connect_signal("button::release", function() - if object == awful.screen.focused().selected_tag then - tag_widget.bg = beautiful.accent - else - tag_widget.bg = beautiful.accent .. 55 - end - end) - - tag_widget:connect_signal("mouse::leave", function() - tag_widget.bg = old_bg - if old_wibox then - old_wibox.cursor = old_cursor - old_wibox = nil - end - end) - - -- Bling tag preview - tag_widget:connect_signal("mouse::enter", function() - if #object:clients() > 0 then - awesome.emit_signal("bling::tag_preview::update", object) - awesome.emit_signal("bling::tag_preview::visibility", awful.screen.focused(), true) - end - end) - - tag_widget:connect_signal("mouse::leave", function() - awesome.emit_signal("bling::tag_preview::visibility", awful.screen.focused(), false) - end) - - widget:add(tag_widget) - widget:set_spacing(dpi(6)) - end -end - -local tag_list = function(s) - return awful.widget.taglist( - s, - awful.widget.taglist.filter.noempty, - gears.table.join( - awful.button({}, 1, function(t) - t:view_only() - end), - awful.button({ modkey }, 1, function(t) - if client.focus then - client.focus:move_to_tag(t) - end - end), - awful.button({}, 3, function(t) - if client.focus then - client.focus:toggle_tag(t) - end - end), - awful.button({ modkey }, 3, function(t) - if client.focus then - client.focus:toggle_tag(t) - end - end), - awful.button({}, 4, function(t) - awful.tag.viewnext(t.screen) - end), - awful.button({}, 5, function(t) - awful.tag.viewprev(t.screen) - end) - ), - {}, - list_update, - wibox.layout.fixed.horizontal() - ) -end - -return tag_list diff --git a/config/awesome/ui/bar/topwibar.lua b/config/awesome/ui/bar/topwibar.lua deleted file mode 100644 index 2f9b7af..0000000 --- a/config/awesome/ui/bar/topwibar.lua +++ /dev/null @@ -1,419 +0,0 @@ -local awful = require("awful") -local gears = require("gears") -local wibox = require("wibox") -local beautiful = require("beautiful") -local helpers = require("helpers") - -awful.screen.connect_for_each_screen(function(s) - local awesome_icon = wibox.widget({ - widget = wibox.widget.imagebox, - image = beautiful.awesome_logo, - resize = true, - }) - - local launcher = wibox.widget({ - { - awesome_icon, - top = dpi(6), - bottom = dpi(6), - left = dpi(12), - right = dpi(12), - widget = wibox.container.margin, - }, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - bg = beautiful.wibar_widget_bg, - widget = wibox.container.background, - }) - - launcher:buttons(gears.table.join(awful.button({}, 1, function() - central_panel:toggle() - end))) - - helpers.add_hover_cursor(awesome_icon, "hand2") - - local search_icon = wibox.widget({ - font = "icomoon bold 14", - align = "center", - valign = "center", - widget = wibox.widget.textbox(), - }) - - local reset_search_icon = function() - search_icon.markup = helpers.colorize_text("", beautiful.accent) - end - reset_search_icon() - - local search_text = wibox.widget({ - markup = helpers.colorize_text("Search", beautiful.xcolor8), - align = "center", - valign = "center", - font = beautiful.prompt_font, - widget = wibox.widget.textbox(), - }) - - local search = wibox.widget({ - { - { - search_icon, - search_text, - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal, - }, - left = dpi(15), - widget = wibox.container.margin, - }, - forced_height = dpi(35), - forced_width = dpi(200), - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - bg = beautiful.wibar_widget_bg, - widget = wibox.container.background, - }) - - local function generate_prompt_icon(icon, color) - return "" .. icon .. " " - end - - function activate_prompt(action) - search_icon.visible = false - local prompt - if action == "run" then - prompt = generate_prompt_icon("", beautiful.accent) - elseif action == "web_search" then - prompt = generate_prompt_icon("", beautiful.accent) - end - helpers.prompt(action, search_text, prompt, function() - search_icon.visible = true - end) - end - - search:buttons(gears.table.join( - awful.button({}, 1, function() - activate_prompt("run") - end), - awful.button({}, 3, function() - activate_prompt("web_search") - end) - )) - - helpers.add_hover_cursor(search, "hand2") - - -- battery - local charge_icon = wibox.widget({ - markup = helpers.colorize_text("󱐋", beautiful.wibar_bg), - align = "center", - valign = "center", - font = beautiful.icon_font_name .. "16", - widget = wibox.widget.textbox, - visible = false, - }) - - local batt = wibox.widget({ - color = beautiful.xcolor2, - background_color = beautiful.xcolor2 .. "55", - bar_shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - value = 50, - max_value = 100, - widget = wibox.widget.progressbar, - }) - - local batt_container = wibox.widget({ - { - batt, - forced_height = dpi(35), - forced_width = dpi(100), - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - bg = beautiful.wibar_widget_bg, - widget = wibox.container.background, - }, - charge_icon, - valign = "center", - layout = wibox.layout.stack, - }) - - local batt_last_value = 100 - local batt_low_value = 40 - local batt_critical_value = 20 - awesome.connect_signal("signal::battery", function(value) - batt.value = value - batt_last_value = value - local color - - if charge_icon.visible then - color = beautiful.xcolor6 - elseif value <= batt_critical_value then - color = beautiful.xcolor1 - elseif value <= batt_low_value then - color = beautiful.xcolor3 - else - color = beautiful.xcolor2 - end - - batt.color = color - batt.background_color = color .. "44" - end) - - awesome.connect_signal("signal::charger", function(state) - local color - if state then - charge_icon.visible = true - color = beautiful.xcolor6 - elseif batt_last_value <= batt_critical_value then - charge_icon.visible = false - color = beautiful.xcolor1 - elseif batt_last_value <= batt_low_value then - charge_icon.visible = false - color = beautiful.xcolor3 - else - charge_icon.visible = false - color = beautiful.xcolor2 - end - - batt.color = color - batt.background_color = color .. "44" - end) - - local vertical_separator = wibox.widget({ - orientation = "vertical", - color = beautiful.wibar_bg, - forced_height = dpi(1), - forced_width = dpi(1), - span_ratio = 0.90, - widget = wibox.widget.separator, - }) - - -- clock - local hours = wibox.widget.textclock("%H") - local minutes = wibox.widget.textclock("%M") - - local make_little_dot = function(color) - return wibox.widget({ - bg = color, - forced_width = dpi(2), - forced_height = dpi(2), - shape = gears.shape.circle, - widget = wibox.container.background, - }) - end - - local time = { - { - font = beautiful.font_name .. "Bold 12", - align = "right", - valign = "center", - widget = hours, - }, - { - nil, - { - make_little_dot(beautiful.xforeground), - make_little_dot(beautiful.xforeground), - spacing = dpi(4), - widget = wibox.layout.fixed.vertical, - }, - expand = "none", - widget = wibox.layout.align.vertical, - }, - { - font = beautiful.font_name .. "Bold 12", - align = "left", - valign = "center", - widget = minutes, - }, - spacing = dpi(4), - layout = wibox.layout.fixed.horizontal, - } - - local layoutbox_buttons = gears.table.join( - -- Left click - awful.button({}, 1, function(c) - awful.layout.inc(1) - end), - - -- Right click - awful.button({}, 3, function(c) - awful.layout.inc(-1) - end), - - -- Scrolling - awful.button({}, 4, function() - awful.layout.inc(-1) - end), - awful.button({}, 5, function() - awful.layout.inc(1) - end) - ) - - s.mylayoutbox = awful.widget.layoutbox(s) - s.mylayoutbox:buttons(layoutbox_buttons) - - local layoutbox = wibox.widget({ - s.mylayoutbox, - left = dpi(2), - right = dpi(2), - top = dpi(3), - bottom = dpi(3), - widget = wibox.container.margin, - }) - - helpers.add_hover_cursor(layoutbox, "hand2") - - local right_container = wibox.widget({ - { - { - time, - vertical_separator, - layoutbox, - layout = wibox.layout.fixed.horizontal, - spacing = dpi(10), - }, - top = dpi(4), - bottom = dpi(4), - left = dpi(8), - right = dpi(8), - widget = wibox.container.margin, - }, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - bg = beautiful.wibar_widget_bg, - widget = wibox.container.background, - }) - - right_container:connect_signal("mouse::enter", function() - right_container.bg = beautiful.wibar_widget_bg .. 55 - tooltip_toggle() - end) - - right_container:connect_signal("mouse::leave", function() - right_container.bg = beautiful.wibar_widget_bg - tooltip_toggle() - end) - - -- Systray - s.systray = wibox.widget.systray() - s.systray.base_size = beautiful.systray_icon_size - s.traybox = wibox({ - screen = s, - width = dpi(100), - height = dpi(150), - bg = "#00000000", - visible = false, - ontop = true, - }) - s.traybox:setup({ - { - { - nil, - s.systray, - direction = "west", - widget = wibox.container.rotate, - }, - margins = dpi(15), - widget = wibox.container.margin, - }, - bg = beautiful.wibar_bg, - shape = helpers.rrect(beautiful.border_radius), - widget = wibox.container.background, - }) - awful.placement.top_right(s.traybox, { - margins = { - top = beautiful.useless_gap * 16, - bottom = beautiful.useless_gap * 4, - left = beautiful.useless_gap * 4, - right = beautiful.useless_gap * 4, - }, - }) - s.traybox:buttons(gears.table.join(awful.button({}, 2, function() - s.traybox.visible = false - end))) - - -- Create the wibox - s.mywibar = awful.wibar({ - type = "dock", - position = "top", - screen = s, - height = dpi(50), - width = s.geometry.width - dpi(40), - bg = beautiful.transparent, - ontop = true, - visible = true, - }) - - awful.placement.top(s.mywibar, { margins = beautiful.useless_gap * 3 }) - - -- Remove wibar on full screen - local function remove_wibar(c) - if c.fullscreen or c.maximized then - c.screen.mywibar.visible = false - else - c.screen.mywibar.visible = true - end - end - - -- Remove wibar on full screen - local function add_wibar(c) - if c.fullscreen or c.maximized then - c.screen.mywibar.visible = true - end - end - - -- Hide bar when a splash widget is visible - awesome.connect_signal("widgets::splash::visibility", function(vis) - screen.primary.mywibar.visible = not vis - end) - - client.connect_signal("property::fullscreen", remove_wibar) - - client.connect_signal("request::unmanage", add_wibar) - - -- Create the taglist widget - s.mytaglist = require("ui.bar.taglist")(s) - - -- Add widgets to the wibox - s.mywibar:setup({ - { - { - layout = wibox.layout.align.horizontal, - expand = "none", - { - launcher, - nil, - search, - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal, - }, - { - widget = s.mytaglist, - }, - { - batt_container, - right_container, - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal, - }, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - bg = beautiful.wibar_bg, - shape = helpers.rrect(beautiful.border_radius), - widget = wibox.container.background, - }) -end) - --- Systray toggle -function systray_toggle() - local s = awful.screen.focused() - s.traybox.visible = not s.traybox.visible -end diff --git a/config/awesome/ui/central-panel/dashboard/date.lua b/config/awesome/ui/central-panel/dashboard/date.lua deleted file mode 100644 index e19e147..0000000 --- a/config/awesome/ui/central-panel/dashboard/date.lua +++ /dev/null @@ -1,38 +0,0 @@ --- Standard awesome library -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - --- Date ---------- - -local date_day = wibox.widget({ - font = beautiful.font_name .. "medium 8", - format = helpers.colorize_text("%A", beautiful.xforeground .. "c6"), - valign = "center", - widget = wibox.widget.textclock, -}) - -local date_month = wibox.widget({ - font = beautiful.font_name .. "medium 11", - format = "%d %B", - valign = "center", - widget = wibox.widget.textclock, -}) - -local date = wibox.widget({ - date_day, - nil, - date_month, - expand = "none", - widget = wibox.layout.align.vertical, -}) - -return date diff --git a/config/awesome/ui/central-panel/dashboard/init.lua b/config/awesome/ui/central-panel/dashboard/init.lua deleted file mode 100644 index 8ccf946..0000000 --- a/config/awesome/ui/central-panel/dashboard/init.lua +++ /dev/null @@ -1,109 +0,0 @@ --- Theme handling library -local beautiful = require("beautiful") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - -local function centered_widget(widget) - local w = wibox.widget({ - nil, - { - nil, - widget, - expand = "none", - layout = wibox.layout.align.vertical, - }, - expand = "none", - layout = wibox.layout.align.horizontal, - }) - - return w -end - -local function create_boxed_widget(widget_to_be_boxed, width, height, bg_color) - local box_container = wibox.container.background() - box_container.bg = bg_color - box_container.forced_height = height - box_container.forced_width = width - box_container.shape = helpers.rrect(dpi(5)) - - local boxed_widget = wibox.widget({ - -- Add margins - { - -- Add background color - { - -- The actual widget goes here - widget_to_be_boxed, - top = dpi(9), - bottom = dpi(9), - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin, - }, - widget = box_container, - }, - margins = dpi(10), - color = "#FF000000", - widget = wibox.container.margin, - }) - - return boxed_widget -end - --- Aesthetic Dashboard -------------------------- - --- Widget - -local dashboard = function(s) - s.profile = require("ui.central-panel.dashboard.profile") - s.music = require("ui.central-panel.dashboard.music") - s.media = require("ui.central-panel.dashboard.mediakeys") - s.time = require("ui.central-panel.dashboard.time") - s.date = require("ui.central-panel.dashboard.date") - s.todo = require("ui.central-panel.dashboard.todo") - s.weather = require("ui.central-panel.dashboard.weather") - s.stats = require("ui.central-panel.dashboard.stats") - - s.time_boxed = create_boxed_widget(centered_widget(s.time), dpi(260), dpi(90), beautiful.transparent) - s.date_boxed = create_boxed_widget(s.date, dpi(120), dpi(50), beautiful.dashboard_box_bg) - s.todo_boxed = create_boxed_widget(s.todo, dpi(120), dpi(120), beautiful.dashboard_box_bg) - s.weather_boxed = create_boxed_widget(s.weather, dpi(120), dpi(120), beautiful.dashboard_box_bg) - s.stats_boxed = create_boxed_widget(s.stats, dpi(120), dpi(190), beautiful.dashboard_box_bg) - - -- Dashboard setup - return wibox.widget({ - nil, - { - s.time_boxed, - { - { - s.profile, - s.stats_boxed, - layout = wibox.layout.fixed.vertical, - }, - { - s.date_boxed, - s.todo_boxed, - s.weather_boxed, - layout = wibox.layout.fixed.vertical, - }, - layout = wibox.layout.fixed.horizontal, - }, - { - s.music, - s.media, - layout = wibox.layout.fixed.horizontal, - }, - s.notifs_boxed, - layout = wibox.layout.fixed.vertical, - }, - expand = "none", - layout = wibox.layout.align.horizontal, - }) -end - -return dashboard diff --git a/config/awesome/ui/central-panel/dashboard/mediakeys.lua b/config/awesome/ui/central-panel/dashboard/mediakeys.lua deleted file mode 100644 index 51594d0..0000000 --- a/config/awesome/ui/central-panel/dashboard/mediakeys.lua +++ /dev/null @@ -1,93 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - --- Media Keys ---------------- - ---playerctl -local playerctl = require("module.bling").signal.playerctl.lib() - --- Helpers -local create_media_button = function(symbol, color, command, playpause) - local icon = wibox.widget({ - markup = helpers.colorize_text(symbol, color), - font = beautiful.icon_font_name .. "16", - align = "center", - valign = "center", - widget = wibox.widget.textbox(), - }) - - playerctl:connect_signal("playback_status", function(_, playing, __) - if playpause then - if playing then - icon:set_markup_silently(helpers.colorize_text("󰏦", color)) - else - icon:set_markup_silently(helpers.colorize_text("󰐍", color)) - end - end - end) - - icon:buttons(gears.table.join(awful.button({}, 1, function() - command() - end))) - - icon:connect_signal("mouse::enter", function() - icon.markup = helpers.colorize_text(icon.text, beautiful.xcolor15) - end) - - icon:connect_signal("mouse::leave", function() - icon.markup = helpers.colorize_text(icon.text, color) - end) - - return icon -end - --- Widget -local media_play_command = function() - playerctl:play_pause() -end -local media_prev_command = function() - playerctl:previous() -end -local media_next_command = function() - playerctl:next() -end - -local media_play = create_media_button("󰐍", beautiful.xforeground, media_play_command, true) -local media_prev = create_media_button("󰒮", beautiful.xforeground, media_prev_command, false) -local media_next = create_media_button("󰒭", beautiful.xforeground, media_next_command, false) - -local media = wibox.widget({ - { - { - { - media_prev, - media_play, - media_next, - expand = "none", - layout = wibox.layout.align.vertical, - }, - margins = dpi(9), - widget = wibox.container.margin, - }, - bg = beautiful.dashboard_box_bg, - shape = helpers.rrect(5), - forced_width = dpi(40), - forced_height = dpi(120), - widget = wibox.container.background, - }, - margins = dpi(10), - widget = wibox.container.margin, -}) - -return media diff --git a/config/awesome/ui/central-panel/dashboard/music.lua b/config/awesome/ui/central-panel/dashboard/music.lua deleted file mode 100644 index dd8ae91..0000000 --- a/config/awesome/ui/central-panel/dashboard/music.lua +++ /dev/null @@ -1,167 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - --- Music ----------- - -local music_text = wibox.widget({ - font = beautiful.font_name .. "medium 8", - valign = "center", - widget = wibox.widget.textbox, -}) - -local music_art = wibox.widget({ - image = gears.filesystem.get_configuration_dir() .. "theme/assets/no_music.png", - resize = true, - widget = wibox.widget.imagebox, -}) - -local music_art_container = wibox.widget({ - music_art, - forced_height = dpi(120), - forced_width = dpi(120), - widget = wibox.container.background, -}) - -local filter_color = { - type = "linear", - from = { 0, 0 }, - to = { 0, 120 }, - stops = { { 0, beautiful.dashboard_box_bg .. "cc" }, { 1, beautiful.dashboard_box_bg } }, -} - -local music_art_filter = wibox.widget({ - { - bg = filter_color, - forced_height = dpi(120), - forced_width = dpi(120), - widget = wibox.container.background, - }, - direction = "east", - widget = wibox.container.rotate, -}) - -local music_title = wibox.widget({ - font = beautiful.font_name .. "medium 9", - valign = "center", - widget = wibox.widget.textbox, -}) - -local music_artist = wibox.widget({ - font = beautiful.font_name .. "medium 12", - valign = "center", - widget = wibox.widget.textbox, -}) - -local music_pos = wibox.widget({ - font = beautiful.font_name .. "medium 8", - valign = "center", - widget = wibox.widget.textbox, -}) - --- playerctl ---------------- - -local playerctl = require("module.bling").signal.playerctl.lib() - -playerctl:connect_signal("metadata", function(_, title, artist, album_path, __, ___, ____) - if title == "" then - title = "Nothing Playing" - end - if artist == "" then - artist = "Nothing Playing" - end - if album_path == "" then - album_path = gears.filesystem.get_configuration_dir() .. "theme/assets/no_music.png" - end - - music_art:set_image(gears.surface.load_uncached(album_path)) - music_title:set_markup_silently(helpers.colorize_text(title, beautiful.xforeground .. "b3")) - music_artist:set_markup_silently(helpers.colorize_text(artist, beautiful.xforeground .. "e6")) -end) - -playerctl:connect_signal("playback_status", function(_, playing, __) - if playing then - music_text:set_markup_silently(helpers.colorize_text("Now Playing", beautiful.xforeground .. "cc")) - else - music_text:set_markup_silently(helpers.colorize_text("Music", beautiful.xforeground .. "cc")) - end -end) - -playerctl:connect_signal("position", function(_, interval_sec, length_sec, player_name) - local pos_now = tostring(os.date("!%M:%S", math.floor(interval_sec))) - local pos_length = tostring(os.date("!%M:%S", math.floor(length_sec))) - local pos_markup = helpers.colorize_text(pos_now .. " / " .. pos_length, beautiful.xforeground .. "66") - - music_pos:set_markup_silently(pos_markup) -end) - -local music = wibox.widget({ - { - { - { - music_art_container, - music_art_filter, - layout = wibox.layout.stack, - }, - { - { - music_text, - { - { - { - step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, - speed = 50, - { - widget = music_artist, - }, - forced_width = dpi(180), - widget = wibox.container.scroll.horizontal, - }, - { - step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, - speed = 50, - { - widget = music_title, - }, - forced_width = dpi(180), - widget = wibox.container.scroll.horizontal, - }, - layout = wibox.layout.fixed.vertical, - }, - bottom = dpi(15), - widget = wibox.container.margin, - }, - music_pos, - expand = "none", - layout = wibox.layout.align.vertical, - }, - top = dpi(9), - bottom = dpi(9), - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin, - }, - layout = wibox.layout.stack, - }, - bg = beautiful.dashboard_box_bg, - shape = helpers.rrect(dpi(5)), - forced_width = dpi(200), - forced_height = dpi(120), - widget = wibox.container.background, - }, - margins = dpi(10), - widget = wibox.container.margin, -}) - -return music diff --git a/config/awesome/ui/central-panel/dashboard/profile.lua b/config/awesome/ui/central-panel/dashboard/profile.lua deleted file mode 100644 index afb15fc..0000000 --- a/config/awesome/ui/central-panel/dashboard/profile.lua +++ /dev/null @@ -1,39 +0,0 @@ --- Standard awesome library -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - --- Profile ------------- - -local profile_pic_img = wibox.widget({ - image = beautiful.pfp, - halign = "center", - valign = "center", - widget = wibox.widget.imagebox, -}) - -local profile_pic_container = wibox.widget({ - shape = helpers.rrect(5), - forced_height = dpi(120), - forced_width = dpi(120), - widget = wibox.container.background, -}) - -local profile = wibox.widget({ - { - profile_pic_img, - widget = profile_pic_container, - }, - margins = dpi(10), - widget = wibox.container.margin, -}) - -return profile diff --git a/config/awesome/ui/central-panel/dashboard/stats.lua b/config/awesome/ui/central-panel/dashboard/stats.lua deleted file mode 100644 index a425f17..0000000 --- a/config/awesome/ui/central-panel/dashboard/stats.lua +++ /dev/null @@ -1,187 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") - --- Notification library -local naughty = require("naughty") - --- Widget library -local wibox = require("wibox") - --- rubato -local rubato = require("module.rubato") - --- Helpers -local helpers = require("helpers") - --- Stats ----------- - -local stats_text = wibox.widget({ - font = beautiful.font_name .. "medium 8", - markup = helpers.colorize_text("Stats", beautiful.dashboard_box_fg), - valign = "center", - widget = wibox.widget.textbox, -}) - --- Vars -local vol_color = beautiful.xcolor4 -local brightness_color = beautiful.xcolor5 -local cpu_color = beautiful.xcolor6 -local ram_color = beautiful.xcolor2 - --- Helpers -local function create_slider_widget(slider_color) - local slider_widget = wibox.widget({ - { - id = "slider", - max_value = 100, - value = 20, - background_color = slider_color .. "44", - color = slider_color, - shape = gears.shape.rounded_rect, - bar_shape = gears.shape.rounded_rect, - widget = wibox.widget.progressbar, - }, - forced_width = dpi(4), - forced_height = dpi(145), - direction = "east", - widget = wibox.container.rotate, - }) - - return slider_widget -end - -local stats_tooltip = wibox.widget({ - visible = false, - top_only = true, - layout = wibox.layout.stack, -}) - -local tooltip_counter = 0 -local function create_tooltip(w) - local tooltip = wibox.widget({ - font = beautiful.font_name .. "medium 8", - align = "right", - valign = "center", - widget = wibox.widget.textbox, - }) - - tooltip_counter = tooltip_counter + 1 - local index = tooltip_counter - - stats_tooltip:insert(index, tooltip) - - w:connect_signal("mouse::enter", function() - -- Raise tooltip to the top of the stack - stats_tooltip:set(1, tooltip) - stats_tooltip.visible = true - end) - w:connect_signal("mouse::leave", function() - stats_tooltip.visible = false - end) - - return tooltip -end - --- Widget -local vol = create_slider_widget(vol_color) -local brightness = create_slider_widget(brightness_color) -local cpu = create_slider_widget(cpu_color) -local ram = create_slider_widget(ram_color) - -local vol_tooltip = create_tooltip(vol) -local brightness_tooltip = create_tooltip(brightness) -local cpu_tooltip = create_tooltip(cpu) -local ram_tooltip = create_tooltip(ram) - -awesome.connect_signal("signal::volume", function(value, muted) - local fill_color - local vol_value = value or 0 - - if muted then - fill_color = beautiful.xcolor8 - else - fill_color = vol_color - end - - vol.slider.value = vol_value - vol.slider.color = fill_color - vol_tooltip.markup = helpers.colorize_text(vol_value .. "%", vol_color) -end) - -awesome.connect_signal("signal::brightness", function(value) - brightness.slider.value = value - brightness_tooltip.markup = helpers.colorize_text(value .. "%", brightness_color) -end) - -awesome.connect_signal("signal::cpu", function(value) - cpu.slider.value = value - cpu_tooltip.markup = helpers.colorize_text(value .. "%", cpu_color) -end) - -awesome.connect_signal("signal::ram", function(used, total) - local r_average = (used / total) * 100 - local r_used = string.format("%.1f", used / 1000) .. "G" - - ram.slider.value = r_average - ram_tooltip.markup = helpers.colorize_text(r_used, ram_color) -end) - -vol:buttons(gears.table.join( - awful.button({}, 1, function() - helpers.volume_control(0) - end), - -- Scrolling - awful.button({}, 4, function() - helpers.volume_control(5) - end), - awful.button({}, 5, function() - helpers.volume_control(-5) - end) -)) - -brightness:buttons(gears.table.join( - -- Scrolling - awful.button({}, 4, function() - awful.spawn.with_shell("brightnessctl set 5%+ -q") - end), - awful.button({}, 5, function() - awful.spawn.with_shell("brightnessctl set 5%- -q") - end) -)) - -local stats = wibox.widget({ - { - stats_text, - nil, - stats_tooltip, - expand = "none", - layout = wibox.layout.align.horizontal, - }, - { - nil, - { - nil, - { - vol, - brightness, - cpu, - ram, - spacing = dpi(24), - layout = wibox.layout.fixed.horizontal, - }, - expand = "none", - layout = wibox.layout.fixed.vertical, - }, - expand = "none", - layout = wibox.layout.align.horizontal, - }, - spacing = dpi(10), - layout = wibox.layout.fixed.vertical, -}) - -return stats diff --git a/config/awesome/ui/central-panel/dashboard/time.lua b/config/awesome/ui/central-panel/dashboard/time.lua deleted file mode 100644 index f137234..0000000 --- a/config/awesome/ui/central-panel/dashboard/time.lua +++ /dev/null @@ -1,57 +0,0 @@ --- Standard awesome library -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - --- Time ---------- -local hours = wibox.widget.textclock("%H") -local minutes = wibox.widget.textclock("%M") - -local make_little_dot = function(color) - return wibox.widget({ - bg = color, - forced_width = dpi(10), - forced_height = dpi(10), - shape = helpers.rrect(dpi(2)), - widget = wibox.container.background, - }) -end - -local time = { - { - font = beautiful.font_name .. "bold 44", - align = "right", - valign = "top", - widget = hours, - }, - { - nil, - { - make_little_dot(beautiful.xcolor1), - make_little_dot(beautiful.xcolor4), - make_little_dot(beautiful.xcolor5), - spacing = dpi(10), - widget = wibox.layout.fixed.vertical, - }, - expand = "none", - widget = wibox.layout.align.vertical, - }, - { - font = beautiful.font_name .. "bold 44", - align = "left", - valign = "top", - widget = minutes, - }, - spacing = dpi(20), - layout = wibox.layout.fixed.horizontal, -} - -return time diff --git a/config/awesome/ui/central-panel/dashboard/todo.lua b/config/awesome/ui/central-panel/dashboard/todo.lua deleted file mode 100644 index 1ba68b5..0000000 --- a/config/awesome/ui/central-panel/dashboard/todo.lua +++ /dev/null @@ -1,113 +0,0 @@ --- Standard awesome library -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - --- Todo ---------- - -local todo_text = wibox.widget({ - font = beautiful.font_name .. "medium 8", - markup = helpers.colorize_text("Todo", beautiful.dashboard_box_fg), - valign = "center", - widget = wibox.widget.textbox, -}) - -local todo_badge = wibox.widget({ - font = beautiful.font_name .. "medium 8", - markup = helpers.colorize_text("0", beautiful.xcolor1), - valign = "center", - widget = wibox.widget.textbox, -}) - -local todo_stat_color = beautiful.xcolor8 -local todo_stat = wibox.widget({ - colors = { todo_stat_color }, - bg = todo_stat_color .. "44", - value = 5, - min_value = 0, - max_value = 8, - thickness = dpi(8), - rounded_edge = true, - start_angle = math.pi * 3 / 2, - widget = wibox.container.arcchart, -}) - -local todo_done = wibox.widget({ - font = beautiful.font_name .. "bold 14", - markup = "0", - valign = "bottom", - widget = wibox.widget.textbox, -}) - -local todo_total = wibox.widget({ - font = beautiful.font_name .. "bold 8", - markup = helpers.colorize_text("/0", beautiful.xcolor8), - valign = "bottom", - widget = wibox.widget.textbox, -}) - -local todo = wibox.widget({ - { - todo_text, - nil, - todo_badge, - expand = "none", - layout = wibox.layout.align.horizontal, - }, - { - { - { - todo_stat, - reflection = { horizontal = true }, - widget = wibox.container.mirror, - }, - { - nil, - { - nil, - { - todo_done, - todo_total, - spacing = dpi(1), - layout = wibox.layout.fixed.horizontal, - }, - expand = "none", - layout = wibox.layout.align.vertical, - }, - expand = "none", - layout = wibox.layout.align.horizontal, - }, - layout = wibox.layout.stack, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - layout = wibox.layout.fixed.vertical, -}) - -awesome.connect_signal("signal::todo", function(total, done, undone) - todo_badge.markup = helpers.colorize_text("-" .. undone, beautiful.xcolor1) - - todo_total.markup = helpers.colorize_text("/" .. total, beautiful.xcolor8) - - if total == 0 then - todo_badge.visible = false - total = 1 - else - todo_badge.visible = true - end - - todo_done.markup = done - todo_stat.max_value = total - todo_stat.value = done -end) - -return todo diff --git a/config/awesome/ui/central-panel/dashboard/weather.lua b/config/awesome/ui/central-panel/dashboard/weather.lua deleted file mode 100644 index c6bde0e..0000000 --- a/config/awesome/ui/central-panel/dashboard/weather.lua +++ /dev/null @@ -1,65 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - --- Weather ------------- - -local weather_text = wibox.widget({ - font = beautiful.font_name .. "medium 8", - markup = helpers.colorize_text("Weather unavailable", beautiful.dashboard_box_fg), - valign = "center", - widget = wibox.widget.textbox, -}) - -local weather_temp = wibox.widget({ - font = beautiful.font_name .. "medium 11", - markup = "999°C", - valign = "center", - widget = wibox.widget.textbox, -}) - -local weather_icon = wibox.widget({ - font = "icomoon 36", - markup = helpers.colorize_text("", beautiful.xcolor2), - align = "right", - valign = "bottom", - widget = wibox.widget.textbox, -}) - -local weather = wibox.widget({ - { - weather_text, - weather_temp, - spacing = dpi(3), - layout = wibox.layout.fixed.vertical, - }, - nil, - weather_icon, - expand = "none", - layout = wibox.layout.align.vertical, -}) - -awesome.connect_signal("signal::weather", function(temperature, description, icon_widget) - local weather_temp_symbol - if weather_units == "metric" then - weather_temp_symbol = "°C" - elseif weather_units == "imperial" then - weather_temp_symbol = "°F" - end - - weather_icon.markup = icon_widget - weather_text.markup = helpers.colorize_text(description, beautiful.dashboard_box_fg) - weather_temp.markup = temperature .. weather_temp_symbol -end) - -return weather diff --git a/config/awesome/ui/central-panel/init.lua b/config/awesome/ui/central-panel/init.lua deleted file mode 100644 index 5f9b524..0000000 --- a/config/awesome/ui/central-panel/init.lua +++ /dev/null @@ -1,148 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") - --- Widget library -local wibox = require("wibox") - --- rubato -local rubato = require("module.rubato") - --- Helpers -local helpers = require("helpers") - --- Aesthetic Dashboard -------------------------- -local panel_visible = false - -awful.screen.connect_for_each_screen(function(s) - -- Dashboard and animations init - local separator = wibox.widget({ - orientation = "horizontal", - opacity = 0.0, - forced_height = 15, - widget = wibox.widget.separator, - }) - - central_panel = wibox({ - type = "dock", - screen = s, - height = dpi(670), - width = dpi(620), - bg = beautiful.transparent, - ontop = true, - visible = false, - }) - - awful.placement.centered(central_panel, { honor_workarea = true, margins = beautiful.useless_gap * 5 }) - - -- Rubato - local slide = rubato.timed({ - pos = dpi(-s.geometry.height), - rate = 60, - duration = 0.25, - intro = 0.125, - easing = rubato.quadratic, - awestore_compat = true, - subscribed = function(pos) - central_panel.y = pos - end, - }) - - local central_panel_status = false - - slide.ended:subscribe(function() - if central_panel_status then - central_panel.visible = false - end - end) - - -- Make toogle button - local central_panel_show = function() - central_panel.visible = true - slide:set(dpi(80)) - central_panel_status = false - - central_panel:emit_signal("opened") - end - - local central_panel_hide = function() - slide:set(-s.geometry.height) - central_panel_status = true - - central_panel:emit_signal("closed") - end - - function central_panel:toggle() - self.opened = not self.opened - if self.opened then - central_panel_hide() - else - central_panel_show() - end - end - - function central_panel:switch_pane(mode) - if mode == "dashboard_mode" then - -- Update Content - central_panel:get_children_by_id("settings_id")[1].visible = false - central_panel:get_children_by_id("dashboard_id")[1].visible = true - elseif mode == "settings_mode" then - -- Update Content - central_panel:get_children_by_id("dashboard_id")[1].visible = false - central_panel:get_children_by_id("settings_id")[1].visible = true - end - end - - central_panel:setup({ - { - { - expand = "none", - layout = wibox.layout.fixed.vertical, - { - layout = wibox.layout.align.horizontal, - expand = "none", - nil, - require("ui.widgets.central-panel-switch"), - nil, - }, - separator, - { - layout = wibox.layout.stack, - { - id = "dashboard_id", - visible = true, - layout = wibox.layout.fixed.vertical, - { - layout = wibox.layout.flex.horizontal, - spacing = 10, - spacing_widget = wibox.widget.separator({ - span_ratio = 0.80, - color = beautiful.lighter_bg, - }), - require("ui.central-panel.dashboard")(s), - require("ui.central-panel.notif-center")(s), - }, - }, - { - id = "settings_id", - visible = false, - layout = wibox.layout.fixed.vertical, - { - layout = wibox.layout.fixed.vertical, - require("ui.central-panel.settings")(s), - }, - }, - }, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - bg = beautiful.dashboard_bg, - shape = helpers.rrect(beautiful.notif_center_radius), - widget = wibox.container.background, - }) -end) diff --git a/config/awesome/ui/central-panel/notif-center/build-notifbox/empty-notifbox.lua b/config/awesome/ui/central-panel/notif-center/build-notifbox/empty-notifbox.lua deleted file mode 100644 index 624ce8e..0000000 --- a/config/awesome/ui/central-panel/notif-center/build-notifbox/empty-notifbox.lua +++ /dev/null @@ -1,52 +0,0 @@ -local wibox = require("wibox") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local gears = require("gears") -local icons = require("theme.assets.icons") - -local empty_notifbox = wibox.widget({ - { - layout = wibox.layout.fixed.vertical, - spacing = dpi(20), - { - expand = "none", - layout = wibox.layout.align.horizontal, - nil, - { - image = gears.color.recolor_image(icons.notification_bell, beautiful.accent), - resize = true, - forced_height = dpi(140), - forced_width = dpi(140), - widget = wibox.widget.imagebox, - }, - nil, - }, - { - text = "No Notifications? :(", - font = beautiful.font_name .. "Bold 14", - align = "center", - valign = "center", - widget = wibox.widget.textbox, - }, - }, - margins = dpi(20), - widget = wibox.container.margin, -}) - -local separator_for_empty_msg = wibox.widget({ - orientation = "vertical", - opacity = 0.0, - widget = wibox.widget.separator, -}) - --- Make empty_notifbox center -local centered_empty_notifbox = wibox.widget({ - layout = wibox.layout.align.vertical, - forced_height = dpi(500), - expand = "none", - separator_for_empty_msg, - empty_notifbox, - separator_for_empty_msg, -}) - -return centered_empty_notifbox diff --git a/config/awesome/ui/central-panel/notif-center/clear-all/init.lua b/config/awesome/ui/central-panel/notif-center/clear-all/init.lua deleted file mode 100644 index 11ebeed..0000000 --- a/config/awesome/ui/central-panel/notif-center/clear-all/init.lua +++ /dev/null @@ -1,49 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") -local notifbox_core = require("ui.central-panel.notif-center.build-notifbox") -local reset_notifbox_layout = notifbox_core.reset_notifbox_layout - -local clear_all_textbox = wibox.widget({ - text = "Clear", - font = beautiful.font_name .. "Bold 12", - align = "center", - valign = "center", - widget = wibox.widget.textbox, -}) - -local clear_all_button = wibox.widget({ - { - clear_all_textbox, - top = dpi(5), - bottom = dpi(5), - left = dpi(20), - right = dpi(20), - widget = wibox.container.margin, - }, - widget = clickable_container, -}) - -clear_all_button:buttons(gears.table.join(awful.button({}, 1, nil, function() - reset_notifbox_layout() -end))) - -local clear_all_button_wrapped = wibox.widget({ - nil, - { - clear_all_button, - bg = beautiful.notif_center_notifs_bg, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - widget = wibox.container.background, - }, - nil, - expand = "none", - layout = wibox.layout.align.vertical, -}) - -return clear_all_button_wrapped diff --git a/config/awesome/ui/central-panel/notif-center/init.lua b/config/awesome/ui/central-panel/notif-center/init.lua deleted file mode 100644 index 7524b7d..0000000 --- a/config/awesome/ui/central-panel/notif-center/init.lua +++ /dev/null @@ -1,36 +0,0 @@ -local wibox = require("wibox") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - -local notif_center = function(s) - s.clear_all = require("ui.central-panel.notif-center.clear-all") - s.notifbox_layout = require("ui.central-panel.notif-center.build-notifbox").notifbox_layout - - return wibox.widget({ - expand = "none", - layout = wibox.layout.align.vertical, - { - { - { - s.notifbox_layout, - spacing = dpi(10), - layout = wibox.layout.fixed.vertical, - }, - forced_height = dpi(550), - widget = wibox.container.constraint, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - nil, - { - nil, - nil, - s.clear_all, - expand = "none", - layout = wibox.layout.align.horizontal, - }, - }) -end - -return notif_center diff --git a/config/awesome/ui/central-panel/settings/init.lua b/config/awesome/ui/central-panel/settings/init.lua deleted file mode 100644 index 87fad8d..0000000 --- a/config/awesome/ui/central-panel/settings/init.lua +++ /dev/null @@ -1,375 +0,0 @@ -local gears = require("gears") -local awful = require("awful") -local beautiful = require("beautiful") -local wibox = require("wibox") -local helpers = require("helpers") -local icons = require("theme.assets.icons") - -local format_item = function(widget) - return wibox.widget({ - { - { - layout = wibox.layout.align.vertical, - expand = "none", - nil, - widget, - nil, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - forced_height = dpi(88), - bg = beautiful.control_center_widget_bg, - shape = helpers.rrect(beautiful.control_center_widget_radius), - widget = wibox.container.background, - }) -end - -local format_item_no_fix_height = function(widget) - return wibox.widget({ - { - { - layout = wibox.layout.align.vertical, - expand = "none", - nil, - widget, - nil, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - bg = beautiful.control_center_widget_bg, - shape = helpers.rrect(beautiful.control_center_widget_radius), - widget = wibox.container.background, - }) -end - -local function format_progress_bar(bar, icon) - local widget_icon = wibox.widget({ - image = gears.color.recolor_image(icon, beautiful.xforeground), - widget = wibox.widget.imagebox, - resize = true, - }) - local w = wibox.widget({ - { - { - { - bar, - reflection = { horizontal = true }, - widget = wibox.container.mirror, - }, - { - nil, - { - nil, - { - widget_icon, - margins = dpi(20), - widget = wibox.container.margin, - }, - expand = "none", - layout = wibox.layout.align.vertical, - }, - expand = "none", - layout = wibox.layout.align.horizontal, - }, - layout = wibox.layout.stack, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - layout = wibox.layout.fixed.vertical, - }) - - return w -end - -local function create_boxed_widget(widget_to_be_boxed, width, height, radius, bg_color) - local box_container = wibox.container.background() - box_container.bg = bg_color - box_container.forced_height = height - box_container.forced_width = width - box_container.shape = helpers.rrect(radius) - - local boxed_widget = wibox.widget({ - { - nil, - { - widget_to_be_boxed, - layout = wibox.layout.align.vertical, - expand = "none", - }, - layout = wibox.layout.align.horizontal, - }, - widget = box_container, - }) - return boxed_widget -end - -local function create_arc_container(markup, widget) - local text = wibox.widget({ - font = beautiful.font_name .. "Bold 10", - markup = helpers.colorize_text(markup, beautiful.dashboard_box_fg), - valign = "center", - widget = wibox.widget.textbox, - }) - - local arc_container = wibox.widget({ - { - { - text, - nil, - expand = "none", - layout = wibox.layout.align.horizontal, - }, - widget, - layout = wibox.layout.fixed.vertical, - }, - margins = dpi(10), - widget = wibox.container.margin, - }) - - return arc_container -end - -local function create_buttons(icon, color) - local button = wibox.widget({ - id = "icon", - markup = helpers.colorize_text(icon, color), - font = beautiful.icon_font_name .. "16", - align = "center", - valign = "center", - widget = wibox.widget.textbox, - }) - - local button_container = wibox.widget({ - { - { - button, - margins = dpi(15), - forced_height = dpi(48), - forced_width = dpi(48), - widget = wibox.container.margin, - }, - widget = require("ui.widgets.clickable-container"), - }, - bg = beautiful.control_center_button_bg, - shape = gears.shape.circle, - widget = wibox.container.background, - }) - - return button_container -end - --- widgets -------------- - --- color indicator -local off = beautiful.control_center_button_bg -local on = beautiful.accent - --- wifi button -local wifi = create_buttons("󰤨", beautiful.xforeground) -local wifi_status = false - -awesome.connect_signal("signal::network", function(status, ssid) - wifi_status = status - awesome.emit_signal("widget::network") -end) - -awesome.connect_signal("widget::network", function() - local w, fill_color - if wifi_status == true then - fill_color = on - wifi:buttons({ - awful.button({}, 1, function() - awful.spawn("nmcli radio wifi off") - end), - }) - else - fill_color = off - wifi:buttons({ - awful.button({}, 1, function() - awful.spawn("nmcli radio wifi on") - end), - }) - end - wifi.bg = fill_color -end) - --- bluetooth button -local bluetooth = create_buttons("󰂯", beautiful.xforeground) -local bluetooth_status = true - -bluetooth:buttons({ - awful.button({}, 1, function() - bluetooth_status = not bluetooth_status - if bluetooth_status then - bluetooth.bg = off - awful.spawn("bluetoothctl power off") - else - bluetooth.bg = on - awful.spawn("bluetoothctl power on") - end - end), -}) - --- screenrec button -local mic = require("ui.widgets.microphone") - --- screenrec button -local screenrec = require("ui.widgets.screenrec")() - --- screenshot button -local screenshot = create_buttons("󰆞", beautiful.xforeground) -screenshot:buttons({ - awful.button({}, 1, function() - central_panel:toggle() - awful.spawn.with_shell("screensht area") - end), -}) - --- cpu arc -local cpu_bar = require("ui.widgets.arc.cpu_arc") -local cpu = format_progress_bar(cpu_bar, icons.cpu) -local cpu_details = create_arc_container("Cpu", cpu) -local cpu_box = create_boxed_widget( - cpu_details, - dpi(50), - dpi(150), - beautiful.control_center_widget_radius, - beautiful.control_center_widget_bg -) - --- ram arc -local ram_bar = require("ui.widgets.arc.ram_arc") -local ram = format_progress_bar(ram_bar, icons.ram) -local ram_details = create_arc_container("Ram", ram) -local ram_box = create_boxed_widget( - ram_details, - dpi(50), - dpi(150), - beautiful.control_center_widget_radius, - beautiful.control_center_widget_bg -) - --- temp arc -local temp_bar = require("ui.widgets.arc.temp_arc") -local temp = format_progress_bar(temp_bar, icons.temp) -local temp_details = create_arc_container("Temp", temp) -local temp_box = create_boxed_widget( - temp_details, - dpi(50), - dpi(150), - beautiful.control_center_widget_radius, - beautiful.control_center_widget_bg -) - --- disk arc -local disk_bar = require("ui.widgets.arc.disk_arc") -local disk = format_progress_bar(disk_bar, icons.disk) -local disk_details = create_arc_container("Disk", disk) -local disk_box = create_boxed_widget( - disk_details, - dpi(50), - dpi(150), - beautiful.control_center_widget_radius, - beautiful.control_center_widget_bg -) - --- Control Center --------------------- -local control_center = function(s) - s.control_center_row_one = wibox.widget({ - layout = wibox.layout.align.horizontal, - forced_height = dpi(60), - nil, - format_item(require("ui.widgets.user-profile")()), - { - format_item({ - layout = wibox.layout.fixed.horizontal, - require("ui.widgets.end-session")(), - }), - left = dpi(20), - widget = wibox.container.margin, - }, - }) - - s.control_center_row_two = wibox.widget({ - { - { - wifi, - bluetooth, - mic, - screenrec, - screenshot, - spacing = dpi(6), - layout = wibox.layout.flex.horizontal, - }, - margins = dpi(12), - widget = wibox.container.margin, - }, - shape = helpers.rrect(beautiful.control_center_widget_radius), - bg = beautiful.control_center_widget_bg, - widget = wibox.container.background, - }) - - s.control_center_row_five = wibox.widget({ - layout = wibox.layout.flex.horizontal, - spacing = dpi(20), - ram_box, - cpu_box, - temp_box, - disk_box, - }) - - s.control_center_row_three = wibox.widget({ - layout = wibox.layout.flex.horizontal, - spacing = dpi(20), - format_item_no_fix_height({ - layout = wibox.layout.fixed.vertical, - spacing = dpi(5), - nil, - require("ui.widgets.dnd"), - require("ui.widgets.blue-light"), - require("ui.widgets.airplane-mode"), - nil, - }), - { - layout = wibox.layout.flex.vertical, - spacing = dpi(20), - format_item_no_fix_height({ - layout = wibox.layout.align.vertical, - expand = "none", - nil, - require("ui.widgets.floating-mode"), - nil, - }), - { - layout = wibox.layout.flex.horizontal, - spacing = dpi(20), - require("ui.widgets.theme-switcher").day, - nil, - require("ui.widgets.theme-switcher").night, - }, - }, - }) - - s.control_center_row_four = require("ui.widgets.vol-bri-slider") - - return wibox.widget({ - { - s.control_center_row_one, - s.control_center_row_two, - s.control_center_row_three, - s.control_center_row_four, - s.control_center_row_five, - spacing = dpi(20), - layout = wibox.layout.fixed.vertical, - }, - margins = dpi(10), - widget = wibox.container.margin, - }) -end - -return control_center diff --git a/config/awesome/ui/dashboard/date.lua b/config/awesome/ui/dashboard/date.lua deleted file mode 100644 index 242e96c..0000000 --- a/config/awesome/ui/dashboard/date.lua +++ /dev/null @@ -1,40 +0,0 @@ --- Standard awesome library -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - - --- Date ---------- - -local date_day = wibox.widget{ - font = beautiful.font_name .. "medium 8", - format = helpers.colorize_text("%A", beautiful.xforeground .. "c6"), - valign = "center", - widget = wibox.widget.textclock -} - -local date_month = wibox.widget{ - font = beautiful.font_name .. "medium 11", - format = "%d %B", - valign = "center", - widget = wibox.widget.textclock -} - -local date = wibox.widget{ - date_day, - nil, - date_month, - expand = "none", - widget = wibox.layout.align.vertical -} - -return date diff --git a/config/awesome/ui/dashboard/init.lua b/config/awesome/ui/dashboard/init.lua deleted file mode 100644 index d67668a..0000000 --- a/config/awesome/ui/dashboard/init.lua +++ /dev/null @@ -1,186 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Widget library -local wibox = require("wibox") - --- rubato -local rubato = require("module.rubato") - --- Helpers -local helpers = require("helpers") - --- Get screen geometry -local screen_width = awful.screen.focused().geometry.width -local screen_height = awful.screen.focused().geometry.height - - --- dashboard ------------- - --- Helpers -local function centered_widget(widget) - local w = wibox.widget{ - nil, - { - nil, - widget, - expand = "none", - layout = wibox.layout.align.vertical - }, - expand = "none", - layout = wibox.layout.align.horizontal - } - - return w -end - -local function create_boxed_widget(widget_to_be_boxed, width, height, bg_color) - local box_container = wibox.container.background() - box_container.bg = bg_color - box_container.forced_height = height - box_container.forced_width = width - box_container.shape = helpers.rrect(dpi(5)) - - local boxed_widget = wibox.widget { - -- Add margins - { - -- Add background color - { - -- The actual widget goes here - widget_to_be_boxed, - top = dpi(9), - bottom = dpi(9), - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin - }, - widget = box_container, - }, - margins = dpi(10), - color = "#FF000000", - widget = wibox.container.margin - } - - return boxed_widget -end - - --- Widget -local profile = require("ui.dashboard.profile") --- local music = require("ui.dashboard.music") --- local media = require("ui.dashboard.mediakeys") -local time = require("ui.dashboard.time") -local date = require("ui.dashboard.date") -local todo = require("ui.dashboard.todo") -local weather = require("ui.dashboard.weather") -local stats = require("ui.dashboard.stats") -local notifs = require("ui.dashboard.notifs") - - -local time_boxed = create_boxed_widget(centered_widget(time), dpi(260), dpi(95), beautiful.transparent) -local date_boxed = create_boxed_widget(date, dpi(120), dpi(50), beautiful.dashboard_box_bg) -local todo_boxed = create_boxed_widget(todo, dpi(120), dpi(120), beautiful.dashboard_box_bg) -local weather_boxed = create_boxed_widget(weather, dpi(120), dpi(120), beautiful.dashboard_box_bg) -local stats_boxed = create_boxed_widget(stats, dpi(120), dpi(190), beautiful.dashboard_box_bg) -local notifs_boxed = create_boxed_widget(notifs, dpi(260), dpi(190), beautiful.dashboard_box_bg) - --- dashboard -dashboard = wibox({ - type = "dock", - screen = screen.primary, - height = screen_height - dpi(50), - width = beautiful.dashboard_width or dpi(300), - shape = helpers.rrect(beautiful.border_radius), - ontop = true, - visible = false -}) -dashboard.y = dpi(25) - -local slide = rubato.timed{ - pos = dpi(-300), - rate = 60, - intro = 0.3, - duration = 0.8, - easing = rubato.quadratic, - awestore_compat = true, - subscribed = function(pos) dashboard.x = pos end -} - -local slide_strut = rubato.timed{ - pos = dpi(0), - rate = 60, - intro = 0.3, - duration = 0.8, - easing = rubato.quadratic, - awestore_compat = true, - subscribed = function(width) dashboard:struts{left = width, right = 0, top = 0, bottom = 0} end -} - -local dashboard_status = false - -slide.ended:subscribe(function() - if dashboard_status then - dashboard.visible = false - end -end) - -dashboard_show = function() - dashboard.visible = true - slide:set(100) - slide_strut:set(375) - dashboard_status = false -end - -dashboard_hide = function() - slide:set(-375) - slide_strut:set(0) - dashboard_status = true -end - -dashboard_toggle = function() - if dashboard.visible then - dashboard_hide() - else - dashboard_show() - end -end - -dashboard:setup { - { - { - nil, - { - { - { - profile, - stats_boxed, - layout = wibox.layout.fixed.vertical - }, - { - date_boxed, - todo_boxed, - weather_boxed, - layout = wibox.layout.fixed.vertical - }, - layout = wibox.layout.fixed.horizontal - }, - - notifs_boxed, - layout = wibox.layout.fixed.vertical - }, - expand = "none", - layout = wibox.layout.align.horizontal - }, - margins = dpi(10), - widget = wibox.container.margin - }, - bg = beautiful.xbackground, - shape = helpers.rrect(beautiful.dashboard_radius), - widget = wibox.container.background - } diff --git a/config/awesome/ui/dashboard/mediakeys.lua b/config/awesome/ui/dashboard/mediakeys.lua deleted file mode 100644 index 7ebd589..0000000 --- a/config/awesome/ui/dashboard/mediakeys.lua +++ /dev/null @@ -1,88 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - - --- Media Keys ---------------- - ---playerctl -local playerctl = require("module.bling").signal.playerctl.lib() - --- Helpers -local create_media_button = function(symbol, color, command, playpause) - - local icon = wibox.widget{ - markup = helpers.colorize_text(symbol, color), - font = beautiful.icon_font_name .. "16", - align = "center", - valign = "center", - widget = wibox.widget.textbox() - } - - playerctl:connect_signal("playback_status", function(_, playing, __) - if playpause then - if playing then - icon:set_markup_silently(helpers.colorize_text("", color)) - else - icon:set_markup_silently(helpers.colorize_text("", color)) - end - end - end) - - icon:buttons(gears.table.join(awful.button({}, 1, function() command() end))) - - icon:connect_signal("mouse::enter", function() - icon.markup = helpers.colorize_text(icon.text, beautiful.xcolor15) - end) - - icon:connect_signal("mouse::leave", function() - icon.markup = helpers.colorize_text(icon.text, color) - end) - - return icon -end - --- Widget -local media_play_command = function() playerctl:play_pause() end -local media_prev_command = function() playerctl:previous() end -local media_next_command = function() playerctl:next() end - -local media_play = create_media_button("", beautiful.xforeground, media_play_command, true) -local media_prev = create_media_button("", beautiful.xforeground, media_prev_command, false) -local media_next = create_media_button("", beautiful.xforeground, media_next_command, false) - -local media = wibox.widget{ - { - { - { - media_prev, - media_play, - media_next, - expand = "none", - layout = wibox.layout.align.vertical - }, - margins = dpi(9), - widget = wibox.container.margin - }, - bg = beautiful.dashboard_box_bg, - shape = helpers.rrect(5), - forced_width = dpi(40), - forced_height = dpi(120), - widget = wibox.container.background - }, - margins = dpi(10), - widget = wibox.container.margin -} - -return media diff --git a/config/awesome/ui/dashboard/music.lua b/config/awesome/ui/dashboard/music.lua deleted file mode 100644 index 84f5d31..0000000 --- a/config/awesome/ui/dashboard/music.lua +++ /dev/null @@ -1,169 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - - --- Music ----------- - -local music_text = wibox.widget{ - font = beautiful.font_name .. "medium 8", - valign = "center", - widget = wibox.widget.textbox -} - -local music_art = wibox.widget { - image = gears.filesystem.get_configuration_dir() .. "theme/assets/no_music.png", - resize = true, - widget = wibox.widget.imagebox -} - -local music_art_container = wibox.widget { - music_art, - forced_height = dpi(120), - forced_width = dpi(120), - widget = wibox.container.background -} - -local filter_color = { - type = 'linear', - from = {0, 0}, - to = {0, 120}, - stops = {{0, beautiful.dashboard_box_bg .. "cc"}, {1, beautiful.dashboard_box_bg}} -} - -local music_art_filter = wibox.widget { - { - bg = filter_color, - forced_height = dpi(120), - forced_width = dpi(120), - widget = wibox.container.background - }, - direction = "east", - widget = wibox.container.rotate -} - -local music_title = wibox.widget{ - font = beautiful.font_name .. "medium 9", - valign = "center", - widget = wibox.widget.textbox -} - -local music_artist = wibox.widget{ - font = beautiful.font_name .. "medium 12", - valign = "center", - widget = wibox.widget.textbox -} - -local music_pos = wibox.widget{ - font = beautiful.font_name .. "medium 8", - valign = "center", - widget = wibox.widget.textbox -} - - --- playerctl ---------------- - -local playerctl = require("module.bling").signal.playerctl.lib() - -playerctl:connect_signal("metadata", function(_, title, artist, album_path, __, ___, ____) - if title == "" then title = "Nothing Playing" end - if artist == "" then artist = "Nothing Playing" end - if album_path == "" then album_path = gears.filesystem.get_configuration_dir() .. "theme/assets/no_music.png" end - - music_art:set_image(gears.surface.load_uncached(album_path)) - music_title:set_markup_silently(helpers.colorize_text(title, beautiful.xforeground .. "b3")) - music_artist:set_markup_silently(helpers.colorize_text(artist, beautiful.xforeground .. "e6")) -end) - -playerctl:connect_signal("playback_status", function(_, playing, __) - if playing then - music_text:set_markup_silently(helpers.colorize_text("Now Playing", beautiful.xforeground .. "cc")) - else - music_text:set_markup_silently(helpers.colorize_text("Music", beautiful.xforeground .. "cc")) - end -end) - -playerctl:connect_signal("position", function(_, interval_sec, length_sec, player_name) - local pos_now = tostring(os.date("!%M:%S", math.floor(interval_sec))) - local pos_length = tostring(os.date("!%M:%S", math.floor(length_sec))) - local pos_markup = helpers.colorize_text(pos_now .. " / " .. pos_length, beautiful.xforeground .. "66") - - music_pos:set_markup_silently(pos_markup) -end) - - -local music = wibox.widget{ - { - { - { - music_art_container, - music_art_filter, - layout = wibox.layout.stack - }, - { - { - music_text, - { - { - { - step_function = wibox.container.scroll - .step_functions - .waiting_nonlinear_back_and_forth, - speed = 50, - { - widget = music_artist, - }, - forced_width = dpi(180), - widget = wibox.container.scroll.horizontal - }, - { - step_function = wibox.container.scroll - .step_functions - .waiting_nonlinear_back_and_forth, - speed = 50, - { - widget = music_title, - }, - forced_width = dpi(180), - widget = wibox.container.scroll.horizontal - }, - layout = wibox.layout.fixed.vertical - }, - bottom = dpi(15), - widget = wibox.container.margin - }, - music_pos, - expand = "none", - layout = wibox.layout.align.vertical - }, - top = dpi(9), - bottom = dpi(9), - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin - }, - layout = wibox.layout.stack - }, - bg = beautiful.dashboard_box_bg, - shape = helpers.rrect(dpi(5)), - forced_width = dpi(200), - forced_height = dpi(120), - widget = wibox.container.background - }, - margins = dpi(10), - widget = wibox.container.margin -} - -return music \ No newline at end of file diff --git a/config/awesome/ui/dashboard/notifs.lua b/config/awesome/ui/dashboard/notifs.lua deleted file mode 100644 index 183c5b5..0000000 --- a/config/awesome/ui/dashboard/notifs.lua +++ /dev/null @@ -1,234 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Notification library -local naughty = require("naughty") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - - --- Notification Center ------------------------- - -local notifs_text = wibox.widget{ - font = beautiful.font_name .. "medium 8", - markup = helpers.colorize_text("Notifications", beautiful.dashboard_box_fg), - valign = "center", - widget = wibox.widget.textbox -} - -local notifs_clear = wibox.widget { - markup = "", - font = beautiful.icon_font_name .. "13", - align = "center", - valign = "center", - widget = wibox.widget.textbox -} - -notifs_clear:buttons(gears.table.join( - awful.button({}, 1, function() - _G.reset_notifs_container() - end) -)) - -local notifs_empty = wibox.widget { - { - nil, - { - nil, - { - markup = helpers.colorize_text('You have no notifs!', beautiful.xforeground .. "e6"), - font = beautiful.font_name .. '8', - align = 'center', - valign = 'center', - widget = wibox.widget.textbox - }, - expand = "none", - layout = wibox.layout.align.vertical - }, - expand = "none", - layout = wibox.layout.align.horizontal - }, - forced_height = dpi(110), - widget = wibox.container.background -} - -local notifs_container = wibox.widget{ - spacing = dpi(10), - forced_width = dpi(240), - layout = wibox.layout.fixed.vertical -} - -local remove_notifs_empty = true - -reset_notifs_container = function() - notifs_container:reset(notifs_container) - notifs_container:insert(1, notifs_empty) - remove_notifs_empty = true -end - -remove_notif = function(box) - notifs_container:remove_widgets(box) - - if #notifs_container.children == 0 then - notifs_container:insert(1, notifs_empty) - remove_notifs_empty = true - end -end - -local create_notif = function(icon, n, width) - local time = os.date("%H:%M") - local box = {} - - box = wibox.widget { - { - { - { - { - image = icon, - resize = true, - clip_shape = helpers.rrect(dpi(2)), - halign = "center", - valign = "center", - widget = wibox.widget.imagebox - }, - strategy = 'exact', - height = dpi(40), - width = dpi(40), - widget = wibox.container.constraint - }, - { - { - nil, - { - { - { - step_function = wibox.container.scroll - .step_functions - .waiting_nonlinear_back_and_forth, - speed = 50, - { - markup = n.title, - font = beautiful.font_name .. "medium 8", - align = "left", - widget = wibox.widget.textbox - }, - forced_width = dpi(140), - widget = wibox.container.scroll.horizontal - }, - nil, - { - markup = helpers.colorize_text(time, beautiful.xforeground .. "b3"), - align = "right", - valign = "bottom", - font = beautiful.font, - widget = wibox.widget.textbox - }, - expand = "none", - layout = wibox.layout.align.horizontal - }, - { - markup = helpers.colorize_text(n.message, beautiful.dashboard_box_fg), - align = "left", - font = beautiful.font_name .. "medium 8", - forced_width = dpi(165), - widget = wibox.widget.textbox - }, - spacing = dpi(2), - layout = wibox.layout.fixed.vertical - }, - expand = "none", - layout = wibox.layout.align.vertical - }, - left = dpi(12), - widget = wibox.container.margin - }, - layout = wibox.layout.align.horizontal - }, - margins = dpi(8), - widget = wibox.container.margin - }, - bg = beautiful.xcolor0, - shape = helpers.rrect(dpi(4)), - forced_height = dpi(64), - widget = wibox.container.background - } - - box:buttons(gears.table.join( - awful.button({}, 1, function() - _G.remove_notif(box) - end) - )) - - box:connect_signal("mouse::enter", function() - box.bg = beautiful.xcolor8 - end) - - box:connect_signal("mouse::leave", function() - box.bg = beautiful.xcolor0 - end) - - return box -end - -notifs_container:buttons(gears.table.join( - awful.button({}, 4, nil, function() - if #notifs_container.children == 1 then return end - notifs_container:insert(1, notifs_container.children[#notifs_container.children]) - notifs_container:remove(#notifs_container.children) - end), - - awful.button({}, 5, nil, function() - if #notifs_container.children == 1 then return end - notifs_container:insert(#notifs_container.children + 1, notifs_container.children[1]) - notifs_container:remove(1) - end) -)) - -notifs_container:insert(1, notifs_empty) - -naughty.connect_signal("request::display", function(n) - - if #notifs_container.children == 1 and remove_notifs_empty then - notifs_container:reset(notifs_container) - remove_notifs_empty = false - end - - local notif_color = beautiful.groups_bg - if n.urgency == 'critical' then - notif_color = beautiful.xcolor1 .. '66' - end - local appicon = n.icon or n.app_icon - if not appicon then appicon = gears.color.recolor_image(beautiful.notification_icon, beautiful.xcolor4) end - - notifs_container:insert(1, create_notif(appicon, n, width)) -end) - -local notifs = wibox.widget { - { - { - notifs_text, - nil, - notifs_clear, - expand = "none", - layout = wibox.layout.align.horizontal - }, - left = dpi(5), - right = dpi(5), - layout = wibox.container.margin - }, - notifs_container, - spacing = dpi(10), - layout = wibox.layout.fixed.vertical -} - -return notifs diff --git a/config/awesome/ui/dashboard/profile.lua b/config/awesome/ui/dashboard/profile.lua deleted file mode 100644 index 32289eb..0000000 --- a/config/awesome/ui/dashboard/profile.lua +++ /dev/null @@ -1,41 +0,0 @@ --- Standard awesome library -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - - --- Profile ------------- - -local profile_pic_img = wibox.widget{ - image = beautiful.pfp, - halign = "center", - valign = "center", - widget = wibox.widget.imagebox -} - -local profile_pic_container = wibox.widget{ - shape = helpers.rrect(5), - forced_height = dpi(120), - forced_width = dpi(120), - widget = wibox.container.background -} - -local profile = wibox.widget{ - { - profile_pic_img, - widget = profile_pic_container - }, - margins = dpi(10), - widget = wibox.container.margin -} - -return profile diff --git a/config/awesome/ui/dashboard/stats.lua b/config/awesome/ui/dashboard/stats.lua deleted file mode 100644 index 2022dc8..0000000 --- a/config/awesome/ui/dashboard/stats.lua +++ /dev/null @@ -1,179 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Notification library -local naughty = require("naughty") - --- Widget library -local wibox = require("wibox") - --- rubato -local rubato = require("module.rubato") - --- Helpers -local helpers = require("helpers") - - --- Stats ----------- - -local stats_text = wibox.widget{ - font = beautiful.font_name .. "medium 8", - markup = helpers.colorize_text("Stats", beautiful.dashboard_box_fg), - valign = "center", - widget = wibox.widget.textbox -} - --- Vars -local vol_color = beautiful.xcolor4 -local brightness_color = beautiful.xcolor5 -local cpu_color = beautiful.xcolor6 -local ram_color = beautiful.xcolor2 - --- Helpers -local function create_slider_widget(slider_color) - local slider_widget = wibox.widget { - { - id = "slider", - max_value = 100, - value = 20, - background_color = "#1C252C", - color = slider_color, - shape = gears.shape.rounded_rect, - bar_shape = gears.shape.rounded_rect, - widget = wibox.widget.progressbar - }, - forced_width = dpi(4), - forced_height = dpi(145), - direction = "east", - widget = wibox.container.rotate - } - - return slider_widget -end - -local stats_tooltip = wibox.widget { - visible = false, - top_only = true, - layout = wibox.layout.stack -} - -local tooltip_counter = 0 -local function create_tooltip(w) - local tooltip = wibox.widget { - font = beautiful.font_name .. "medium 8", - align = "right", - valign = "center", - widget = wibox.widget.textbox - } - - tooltip_counter = tooltip_counter + 1 - local index = tooltip_counter - - stats_tooltip:insert(index, tooltip) - - w:connect_signal("mouse::enter", function() - -- Raise tooltip to the top of the stack - stats_tooltip:set(1, tooltip) - stats_tooltip.visible = true - end) - w:connect_signal("mouse::leave", function () - stats_tooltip.visible = false - end) - - return tooltip -end - --- Widget -local vol = create_slider_widget(vol_color) -local brightness = create_slider_widget(brightness_color) -local cpu = create_slider_widget(cpu_color) -local ram = create_slider_widget(ram_color) - -local vol_tooltip = create_tooltip(vol) -local brightness_tooltip = create_tooltip(brightness) -local cpu_tooltip = create_tooltip(cpu) -local ram_tooltip = create_tooltip(ram) - -awesome.connect_signal("signal::volume", function(value, muted) - local fill_color - local vol_value = value or 0 - - if muted then - fill_color = beautiful.xcolor8 - else - fill_color = vol_color - end - - vol.slider.value = vol_value - vol.slider.color = fill_color - vol_tooltip.markup = helpers.colorize_text(vol_value .. "%", vol_color) -end) - -awesome.connect_signal("signal::brightness", function (value) - brightness.slider.value = value - brightness_tooltip.markup = helpers.colorize_text(value .. "%", brightness_color) -end) - -awesome.connect_signal("signal::cpu", function(value) - cpu.slider.value = value - cpu_tooltip.markup = helpers.colorize_text(value .. "%", cpu_color) -end) - -awesome.connect_signal("signal::ram", function(used, total) - local r_average = (used / total) * 100 - local r_used = string.format("%.1f", used / 1000) .. "G" - - ram.slider.value = r_average - ram_tooltip.markup = helpers.colorize_text(r_used, ram_color) -end) - -vol:buttons(gears.table.join( - awful.button({}, 1, function() helpers.volume_control(0) end), - -- Scrolling - awful.button({}, 4, function() helpers.volume_control(5) end), - awful.button({}, 5, function() helpers.volume_control(-5) end) -)) - -brightness:buttons(gears.table.join( - -- Scrolling - awful.button({}, 4, function() awful.spawn.with_shell("brightnessctl set 5%+ -q") end), - awful.button({}, 5, function() awful.spawn.with_shell("brightnessctl set 5%- -q") end) -)) - -local stats = wibox.widget{ - { - stats_text, - nil, - stats_tooltip, - expand = "none", - layout = wibox.layout.align.horizontal - }, - { - nil, - { - nil, - { - vol, - brightness, - cpu, - ram, - spacing = dpi(24), - layout = wibox.layout.fixed.horizontal - }, - expand = "none", - layout = wibox.layout.fixed.vertical - }, - expand = "none", - layout = wibox.layout.align.horizontal - }, - spacing = dpi(10), - layout = wibox.layout.fixed.vertical -} - -return stats diff --git a/config/awesome/ui/dashboard/time.lua b/config/awesome/ui/dashboard/time.lua deleted file mode 100644 index b8fec43..0000000 --- a/config/awesome/ui/dashboard/time.lua +++ /dev/null @@ -1,41 +0,0 @@ --- Standard awesome library -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - - --- Time ---------- - -local time_hour = wibox.widget{ - font = beautiful.font_name .. "bold 48", - format = helpers.colorize_text("%H", "#cfcdcc"), - align = "center", - valign = "center", - widget = wibox.widget.textclock -} - -local time_min = wibox.widget{ - font = beautiful.font_name .. "bold 48", - format = "%M", - align = "center", - valign = "center", - widget = wibox.widget.textclock -} - -local time = wibox.widget{ - time_hour, - time_min, - spacing = dpi(25), - widget = wibox.layout.fixed.horizontal -} - -return time diff --git a/config/awesome/ui/dashboard/todo.lua b/config/awesome/ui/dashboard/todo.lua deleted file mode 100644 index c453a33..0000000 --- a/config/awesome/ui/dashboard/todo.lua +++ /dev/null @@ -1,114 +0,0 @@ --- Standard awesome library -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - - --- Todo ---------- - -local todo_text = wibox.widget{ - font = beautiful.font_name .. "medium 8", - markup = helpers.colorize_text("Todo", beautiful.dashboard_box_fg), - valign = "center", - widget = wibox.widget.textbox -} - -local todo_badge = wibox.widget{ - font = beautiful.font_name .. "medium 8", - markup = helpers.colorize_text("0", beautiful.xcolor1), - valign = "center", - widget = wibox.widget.textbox -} - -local todo_stat = wibox.widget{ - colors = {beautiful.xcolor8}, - bg = "#1C252C", - value = 5, - min_value = 0, - max_value = 8, - thickness = dpi(8), - rounded_edge = true, - start_angle = math.pi * 3 / 2, - widget = wibox.container.arcchart -} - -local todo_done = wibox.widget{ - font = beautiful.font_name .. "bold 14", - markup = "0", - valign = "bottom", - widget = wibox.widget.textbox -} - -local todo_total = wibox.widget{ - font = beautiful.font_name .. "bold 8", - markup = helpers.colorize_text("/0", beautiful.xcolor8), - valign = "bottom", - widget = wibox.widget.textbox -} - -local todo = wibox.widget{ - { - todo_text, - nil, - todo_badge, - expand = "none", - layout = wibox.layout.align.horizontal - }, - { - { - { - todo_stat, - reflection = {horizontal = true}, - widget = wibox.container.mirror - }, - { - nil, - { - nil, - { - todo_done, - todo_total, - spacing = dpi(1), - layout = wibox.layout.fixed.horizontal - }, - expand = "none", - layout = wibox.layout.align.vertical - }, - expand = "none", - layout = wibox.layout.align.horizontal - }, - layout = wibox.layout.stack - }, - margins = dpi(10), - widget = wibox.container.margin - }, - layout = wibox.layout.fixed.vertical -} - -awesome.connect_signal("signal::todo", function(total, done, undone) - todo_badge.markup = helpers.colorize_text("-" .. undone, beautiful.xcolor1) - - todo_total.markup = helpers.colorize_text("/" .. total, beautiful.xcolor8) - - if total == 0 then - todo_badge.visible = false - total = 1 - else - todo_badge.visible = true - end - - todo_done.markup = done - todo_stat.max_value = total - todo_stat.value = done -end) - -return todo diff --git a/config/awesome/ui/dashboard/weather.lua b/config/awesome/ui/dashboard/weather.lua deleted file mode 100644 index 1c7d46b..0000000 --- a/config/awesome/ui/dashboard/weather.lua +++ /dev/null @@ -1,67 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - - --- Weather ------------- - -local weather_text = wibox.widget{ - font = beautiful.font_name .. "medium 8", - markup = helpers.colorize_text("Weather unavailable", beautiful.dashboard_box_fg), - valign = "center", - widget = wibox.widget.textbox -} - -local weather_temp = wibox.widget{ - font = beautiful.font_name .. "medium 11", - markup = "999°C", - valign = "center", - widget = wibox.widget.textbox -} - -local weather_icon = wibox.widget{ - font = "icomoon 36", - markup = helpers.colorize_text("", beautiful.xcolor2), - align = "right", - valign = "bottom", - widget = wibox.widget.textbox -} - -local weather = wibox.widget{ - { - weather_text, - weather_temp, - spacing = dpi(3), - layout = wibox.layout.fixed.vertical - }, - nil, - weather_icon, - expand = "none", - layout = wibox.layout.align.vertical -} - -awesome.connect_signal("signal::weather", function(temperature, description, icon_widget) - local weather_temp_symbol - if weather_units == "metric" then - weather_temp_symbol = "°C" - elseif weather_units == "imperial" then - weather_temp_symbol = "°F" - end - - weather_icon.markup = icon_widget - weather_text.markup = helpers.colorize_text(description, beautiful.dashboard_box_fg) - weather_temp.markup = temperature .. weather_temp_symbol -end) - -return weather diff --git a/config/awesome/ui/decorations/init.lua b/config/awesome/ui/decorations/init.lua old mode 100644 new mode 100755 index 51450e3..6185815 --- a/config/awesome/ui/decorations/init.lua +++ b/config/awesome/ui/decorations/init.lua @@ -1,2 +1,175 @@ -require("ui.decorations.titlebar") -require("ui.decorations.music") +local awful = require("awful") +local beautiful = require("beautiful") +local helpers = require("helpers") +local gears = require("gears") +local wibox = require("wibox") + +-- Disable popup tooltip on titlebar button hover +awful.titlebar.enable_tooltip = false + +local decorations = {} + +function decorations.hide(c) + if not c.custom_decoration or not (c.custom_decoration["top"] and c.custom_decoration["bottom"]) then + awful.titlebar.hide(c, "top") + awful.titlebar.hide(c, "bottom") + end +end + +function decorations.show(c) + if not c.custom_decoration or not (c.custom_decoration["top"] and c.custom_decoration["bottom"]) then + awful.titlebar.show(c, "top") + awful.titlebar.show(c, "bottom") + end +end + +function decorations.cycle(c) + if not c.custom_decoration or not (c.custom_decoration["top"] and c.custom_decoration["bottom"]) then + awful.titlebar.toggle(c, "top") + awful.titlebar.toggle(c, "bottom") + end +end + +-- Helper function to be used by decoration themes to enable client rounding +function decorations.enable_rounding() + -- Apply rounded corners to clients if needed + if beautiful.border_radius and beautiful.border_radius > 0 then + client.connect_signal("manage", function(c, startup) + if not c.fullscreen and not c.maximized then + c.shape = helpers.ui.rrect(beautiful.border_radius) + end + end) + + -- Fullscreen and maximized clients should not have rounded corners + local function no_round_corners(c) + if c.fullscreen or c.maximized then + c.shape = gears.shape.rectangle + else + c.shape = helpers.ui.rrect(beautiful.border_radius) + end + end + + client.connect_signal("property::fullscreen", no_round_corners) + client.connect_signal("property::maximized", no_round_corners) + + beautiful.snap_shape = helpers.ui.rrect(beautiful.border_radius * 2) + else + beautiful.snap_shape = gears.shape.rectangle + end +end + +local button_commands = { + ["close"] = { + fun = function(c) + c:kill() + end, + track_property = nil, + }, + ["maximize"] = { + fun = function(c) + c.maximized = not c.maximized + c:raise() + end, + track_property = "maximized", + }, + ["minimize"] = { + fun = function(c) + c.minimized = true + end, + }, + ["sticky"] = { + fun = function(c) + c.sticky = not c.sticky + c:raise() + end, + track_property = "sticky", + }, + ["ontop"] = { + fun = function(c) + c.ontop = not c.ontop + c:raise() + end, + track_property = "ontop", + }, + ["floating"] = { + fun = function(c) + c.floating = not c.floating + c:raise() + end, + track_property = "floating", + }, +} + +decorations.button = function(c, shape, color, unfocused_color, hover_color, size, margin, cmd) + local button = wibox.widget({ + bg = (client.focus and c == client.focus) and color or unfocused_color, + shape = shape, + widget = wibox.container.background(), + }) + + -- Instead of adding spacing between the buttons, we add margins + -- around them. That way it is more forgiving to click them + -- (especially if they are very small) + local button_widget = wibox.widget({ + widget = wibox.container.place, + { + widget = wibox.container.margin, + margins = margin, + { + button, + widget = wibox.container.constraint, + height = size, + width = size, + strategy = "exact", + }, + }, + }) + + button_widget:buttons(gears.table.join(awful.button({}, 1, function() + button_commands[cmd].fun(c) + end))) + + local p = button_commands[cmd].track_property + -- Track client property if needed + if p then + c:connect_signal("property::" .. p, function() + button.bg = c[p] and color .. "40" or color + end) + c:connect_signal("focus", function() + button.bg = c[p] and color .. "40" or color + end) + button_widget:connect_signal("mouse::leave", function() + if c == client.focus then + button.bg = c[p] and color .. "40" or color + else + button.bg = unfocused_color + end + end) + else + button_widget:connect_signal("mouse::leave", function() + if c == client.focus then + button.bg = color + else + button.bg = unfocused_color + end + end) + c:connect_signal("focus", function() + button.bg = color + end) + end + button_widget:connect_signal("mouse::enter", function() + button.bg = hover_color + end) + c:connect_signal("unfocus", function() + button.bg = unfocused_color + end) + + return button_widget +end + +function decorations.init() + require("ui.decorations.titlebar") + require("ui.decorations.music") +end + +return decorations diff --git a/config/awesome/ui/decorations/music.lua b/config/awesome/ui/decorations/music.lua old mode 100644 new mode 100755 index ad0758b..bf08b1c --- a/config/awesome/ui/decorations/music.lua +++ b/config/awesome/ui/decorations/music.lua @@ -1,125 +1,64 @@ --- Standard awesome library local gears = require("gears") local awful = require("awful") - --- Theme library local beautiful = require("beautiful") - --- Ruled +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi local ruled = require("ruled") - --- Widget library local wibox = require("wibox") - --- Helpers +local playerctl_daemon = require("signal.playerctl") +local widgets = require("ui.widgets") local helpers = require("helpers") +local animation = require("modules.animation") --- Aesthetic Music Player ----------------------------- +--- Custom mouse friendly ncmpcpp UI with album art +--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- Music icon ----------------- - -local big_music_icon = wibox.widget({ - align = "center", - font = beautiful.icon_font_name .. "15", - markup = helpers.colorize_text("󰎇", beautiful.accent), - widget = wibox.widget.textbox(), -}) - -local small_music_icon = wibox.widget({ - align = "center", - font = beautiful.icon_font_name .. "11", - markup = helpers.colorize_text("󰎇", beautiful.xforeground), - widget = wibox.widget.textbox(), -}) - -local container_music_icon = wibox.widget({ - big_music_icon, - { - small_music_icon, - top = dpi(11), - widget = wibox.container.margin, - }, - spacing = dpi(-9), - layout = wibox.layout.fixed.horizontal, -}) - -local music_icon = wibox.widget({ - nil, - { - container_music_icon, - spacing = dpi(14), - layout = wibox.layout.fixed.horizontal, - }, - expand = "none", - layout = wibox.layout.align.horizontal, -}) - --- Helpers -------------- - -local control_button_bg = "#00000000" -local control_button_bg_hover = beautiful.hover_effect -local control_button = function(c, symbol, color, font, size, on_click, on_right_click) - local icon = wibox.widget({ - markup = helpers.colorize_text(symbol, color), - font = font, +--- Music icon +local function music_icon() + local big_music_icon = wibox.widget({ align = "center", - valign = "center", + font = beautiful.icon_font .. "Round 15", + markup = helpers.ui.colorize_text("", beautiful.accent), widget = wibox.widget.textbox(), }) - local button = wibox.widget({ - icon, - bg = control_button_bg, - shape = helpers.rrect(dpi(5)), - widget = wibox.container.background, + local small_music_icon = wibox.widget({ + align = "center", + font = beautiful.icon_font .. "Round 11", + markup = helpers.ui.colorize_text("", beautiful.xforeground), + widget = wibox.widget.textbox(), }) - local container = wibox.widget({ - button, - strategy = "min", - width = dpi(30), - widget = wibox.container.constraint, + local container_music_icon = wibox.widget({ + big_music_icon, + { + small_music_icon, + top = dpi(11), + widget = wibox.container.margin, + }, + spacing = dpi(-9), + layout = wibox.layout.fixed.horizontal, }) - container:buttons(gears.table.join(awful.button({}, 1, on_click), awful.button({}, 3, on_right_click))) + local music_icon = wibox.widget({ + nil, + { + container_music_icon, + spacing = dpi(14), + layout = wibox.layout.fixed.horizontal, + }, + expand = "none", + layout = wibox.layout.align.horizontal, + }) - container:connect_signal("mouse::enter", function() - button.bg = control_button_bg_hover - end) - container:connect_signal("mouse::leave", function() - button.bg = control_button_bg - end) - - return container + return music_icon end --- Play Pause button -local music_play_pause = control_button( - c, - "󰐊", - beautiful.xforeground, - beautiful.icon_font_name .. "22", - dpi(30), - function() - awful.spawn.with_shell("mpc -q toggle") - end -) +--- Volume slider +local function volume_slider() + local vol_color = beautiful.accent --- Loop button -local loop = control_button(c, "󰑖", beautiful.xforeground, beautiful.icon_font_name .. "12", dpi(30), function() - awful.spawn.with_shell("mpc repeat") -end) - --- Shuffle playlist button -local shuffle = control_button(c, "󰒝", beautiful.xforeground, beautiful.icon_font_name .. "12", dpi(30), function() - awful.spawn.with_shell("mpc random") -end) - -local function create_slider_widget(slider_color) - local slider_widget = wibox.widget({ + local slider = wibox.widget({ { id = "slider", max_value = 100, @@ -133,8 +72,8 @@ local function create_slider_widget(slider_color) forced_width = dpi(60), shape = gears.shape.rounded_bar, bar_shape = gears.shape.rounded_bar, - color = slider_color, - background_color = slider_color .. "44", + color = vol_color, + background_color = vol_color .. "44", widget = wibox.widget.progressbar, }, expand = "none", @@ -142,19 +81,15 @@ local function create_slider_widget(slider_color) layout = wibox.layout.align.horizontal, }) - return slider_widget -end + local stats_tooltip = wibox.widget({ + visible = false, + top_only = true, + layout = wibox.layout.stack, + }) -local stats_tooltip = wibox.widget({ - visible = false, - top_only = true, - layout = wibox.layout.stack, -}) - -local tooltip_counter = 0 -local function create_tooltip(w) + local tooltip_counter = 0 local tooltip = wibox.widget({ - font = beautiful.font_name .. "bold 10", + font = beautiful.font_name .. "Bold 10", align = "right", valign = "center", widget = wibox.widget.textbox, @@ -162,48 +97,115 @@ local function create_tooltip(w) tooltip_counter = tooltip_counter + 1 local index = tooltip_counter - stats_tooltip:insert(index, tooltip) - w:connect_signal("mouse::enter", function() - -- Raise tooltip to the top of the stack + local button = widgets.button.text.normal({ + normal_shape = gears.shape.circle, + font = beautiful.icon_font .. "Round ", + size = 14, + text_normal_bg = vol_color, + normal_bg = beautiful.music_bg, + text = "", + paddings = dpi(5), + animate_size = false, + on_release = function() + awful.spawn("pamixer -t") + end, + }) + + local anim = animation:new({ + pos = 0, + duration = 0.2, + easing = animation.easing.linear, + update = function(self, pos) + slider.slider.value = pos + end, + }) + + awesome.connect_signal("signal::volume", function(value, muted) + local fill_color + local vol_value = tonumber(value) or 0 + + if muted == 1 or value == 0 then + anim:set(0) + + button.text = "" + fill_color = beautiful.xcolor8 + else + anim:set(value) + + button.text = "" + fill_color = vol_color + end + + slider.slider.value = vol_value + slider.slider.color = fill_color + tooltip.markup = helpers.ui.colorize_text(vol_value .. "%", vol_color) + end) + + slider:connect_signal("mouse::enter", function() + --- Raise tooltip to the top of the stack stats_tooltip:set(1, tooltip) stats_tooltip.visible = true end) - w:connect_signal("mouse::leave", function() + slider:connect_signal("mouse::leave", function() stats_tooltip.visible = false end) - return tooltip + slider:buttons(gears.table.join( + --- Scrolling + awful.button({}, 4, function() + awful.spawn("pamixer -i 5") + end), + awful.button({}, 5, function() + awful.spawn("pamixer -d 5") + end) + )) + + local widget = wibox.widget({ + { + button, + slider, + layout = wibox.layout.fixed.horizontal, + }, + tooltip, + layout = wibox.layout.align.horizontal, + }) + + return widget end --- Decorations ------------------ +--- Music art cover +local music_art = wibox.widget({ + image = beautiful.music, + resize = true, + clip_shape = helpers.ui.rrect(beautiful.border_radius), + widget = wibox.widget.imagebox, +}) - - - - - - - - - - - - -local music_now = wibox.widget({ - font = beautiful.font_name .. "bold 10", +--- Music title +local title_now = wibox.widget({ + font = beautiful.font_name .. "Bold 12", valign = "center", widget = wibox.widget.textbox, }) +--- Music artist +local artist_now = wibox.widget({ + font = beautiful.font_name .. "Medium 10", + valign = "center", + widget = wibox.widget.textbox, +}) + +--- Music position +local music_length = 0 local music_pos = wibox.widget({ - font = beautiful.font_name .. "bold 10", + font = beautiful.font_name .. "Medium 10", valign = "center", widget = wibox.widget.textbox, }) +--- Music position bar local music_bar = wibox.widget({ max_value = 100, value = 0, @@ -219,181 +221,101 @@ music_bar:connect_signal("button::press", function(_, lx, __, button, ___, w) end end) -local music_play_pause_textbox = music_play_pause:get_all_children()[1]:get_all_children()[1] -local loop_textbox = loop:get_all_children()[1]:get_all_children()[1] -local shuffle_textbox = shuffle:get_all_children()[1]:get_all_children()[1] +--- Playlist button +local playlist = function(c) + return widgets.button.text.normal({ + normal_shape = gears.shape.rounded_rect, + font = beautiful.icon_font .. "Round ", + size = 14, + text_normal_bg = beautiful.xforeground, + normal_bg = beautiful.music_bg_accent, + text = "", + on_release = function() + helpers.misc.send_key(c, "1") + end, + }) +end --- Volume --------- +--- Visualizer button +local visualizer = function(c) + return widgets.button.text.normal({ + normal_shape = gears.shape.rounded_rect, + font = "icomoon ", + size = 14, + text_normal_bg = beautiful.xforeground, + normal_bg = beautiful.music_bg_accent, + text = "", + on_release = function() + helpers.misc.send_key(c, "8") + end, + }) +end -local vol_color = beautiful.accent -local vol_slider = create_slider_widget(vol_color) -local vol_tooltip = create_tooltip(vol_slider) - -local vol_icon = wibox.widget({ - align = "center", - font = beautiful.icon_font_name .. "16", - markup = helpers.colorize_text("󰕾", beautiful.accent), - widget = wibox.widget.textbox, -}) - -local vol_button = wibox.widget({ - vol_icon, - bg = control_button_bg, - shape = helpers.rrect(dpi(5)), - widget = wibox.container.background, -}) - -local vol = wibox.widget({ - vol_button, - strategy = "min", - width = dpi(30), - widget = wibox.container.constraint, -}) - -vol:connect_signal("mouse::enter", function() - vol_button.bg = control_button_bg_hover -end) -vol:connect_signal("mouse::leave", function() - vol_button.bg = control_button_bg -end) -vol:buttons(gears.table.join(awful.button({}, 1, function() - helpers.volume_control(0) -end))) - -awesome.connect_signal("signal::volume", function(value, muted) - local fill_color - local vol_value = value or 0 - - if muted then - vol_icon.markup = helpers.colorize_text("󰖁", beautiful.xcolor8) - fill_color = beautiful.xcolor8 - else - vol_icon.markup = helpers.colorize_text("󰕾", beautiful.accent) - fill_color = vol_color - end - - vol_slider.slider.value = vol_value - vol_slider.slider.color = fill_color - vol_tooltip.markup = helpers.colorize_text(vol_value .. "%", vol_color) -end) - -vol_slider:buttons(gears.table.join( - awful.button({}, 1, function() - helpers.volume_control(0) - end), - -- Scrolling - awful.button({}, 4, function() - helpers.volume_control(5) - end), - awful.button({}, 5, function() - helpers.volume_control(-5) - end) -)) - --- Playerctl ---------------- - -local playerctl = require("module.bling").signal.playerctl.lib() -local music_length = 0 - -playerctl:connect_signal("metadata", function(_, title, artist, album_path, album, ___, player_name) +--- PLayerctl +--- ------------- +playerctl_daemon:connect_signal("metadata", function(_, title, artist, album_path, album, ___, player_name) if player_name == "mpd" then - local m_now = artist .. " - " .. title .. "/" .. album + if title == "" then + title = "Nothing Playing" + end + if artist == "" then + artist = "Nothing Playing" + end + if album_path == "" then + album_path = beautiful.music + end - - music_now:set_markup_silently(m_now) + music_art:set_image(gears.surface.load_uncached(album_path)) + title_now:set_markup_silently(helpers.ui.colorize_text(string.upper(title), beautiful.accent)) + artist_now:set_markup_silently(artist) end end) -playerctl:connect_signal("position", function(_, interval_sec, length_sec, player_name) +playerctl_daemon:connect_signal("position", function(_, interval_sec, length_sec, player_name) if player_name == "mpd" then local pos_now = tostring(os.date("!%M:%S", math.floor(interval_sec))) local pos_length = tostring(os.date("!%M:%S", math.floor(length_sec))) - local pos_markup = pos_now .. helpers.colorize_text(" / " .. pos_length, beautiful.xforeground) + local pos_markup = pos_now .. helpers.ui.colorize_text(" / " .. pos_length, beautiful.xcolor8) - music_art:set_image(gears.surface.load_uncached(album_path)) music_pos:set_markup_silently(pos_markup) music_bar.value = (interval_sec / length_sec) * 100 music_length = length_sec end end) -playerctl:connect_signal("playback_status", function(_, playing, player_name) - if player_name == "mpd" then - if playing then - music_play_pause_textbox:set_markup_silently(helpers.colorize_text("󰏤", beautiful.accent)) - else - music_play_pause_textbox:set_markup_silently(helpers.colorize_text("󰐊", beautiful.accent)) - end - end -end) - -playerctl:connect_signal("loop_status", function(_, loop_status, player_name) - if player_name == "mpd" then - if loop_status == "none" then - loop_textbox:set_markup_silently("󰑖") - else - loop_textbox:set_markup_silently(helpers.colorize_text("󰑖", beautiful.accent)) - end - end -end) - -playerctl:connect_signal("shuffle", function(_, shuffle, player_name) - if player_name == "mpd" then - if shuffle then - shuffle_textbox:set_markup_silently(helpers.colorize_text("󰒝", beautiful.accent)) - else - shuffle_textbox:set_markup_silently("󰒝") - end - end -end) - local music_create_decoration = function(c) - -- Hide default titlebar + --- Hide default titlebar awful.titlebar.hide(c, beautiful.titlebar_pos) - -- Titlebar + --- Decoration Init awful.titlebar(c, { position = "top", size = dpi(45), bg = beautiful.transparent }):setup({ { { { - { - { - vol, - nil, - vol_slider, - spacing = dpi(2), - layout = wibox.layout.fixed.horizontal, - }, - stats_tooltip, - layout = wibox.layout.align.horizontal, - }, + volume_slider(), top = dpi(10), - bottom = dpi(5), + bottom = dpi(10), right = dpi(10), left = dpi(15), widget = wibox.container.margin, }, forced_width = dpi(200), - widget = wibox.container.background, - }, - { - widget = music_icon, + widget = wibox.container.constraint, }, + music_icon(), layout = wibox.layout.align.horizontal, }, bg = beautiful.music_bg, - shape = helpers.prrect(beautiful.border_radius, true, true, false, false), + shape = helpers.ui.prrect(beautiful.border_radius, true, true, false, false), widget = wibox.container.background, }) - -- Sidebar + --- Sidebar awful.titlebar(c, { position = "left", size = dpi(200) }):setup({ { nil, { - music_art_container, + music_art, bottom = dpi(20), left = dpi(25), right = dpi(25), @@ -404,97 +326,83 @@ local music_create_decoration = function(c) layout = wibox.layout.align.vertical, }, bg = beautiful.music_accent, - shape = helpers.prrect(dpi(10), false, true, false, false), + shape = helpers.ui.prrect(beautiful.border_radius * 2, false, true, false, false), widget = wibox.container.background, }) - -- Toolbar - awful.titlebar(c, { position = "bottom", size = dpi(63), bg = beautiful.transparent }):setup({ + --- Toolbar + awful.titlebar(c, { position = "bottom", size = dpi(70), bg = beautiful.transparent }):setup({ { + layout = wibox.layout.align.vertical, music_bar, { { + layout = wibox.layout.align.horizontal, + expand = "none", { - control_button( - c, - "󰒮", - beautiful.xforeground, - beautiful.icon_font_name .. "14", - dpi(30), - function() - awful.spawn.with_shell("mpc -q prev") - end - ), - -- Toggle play pause - music_play_pause, - control_button( - c, - "󰒭", - beautiful.xforeground, - beautiful.icon_font_name .. "14", - dpi(30), - function() - awful.spawn.with_shell("mpc -q next") - end - ), - layout = wibox.layout.flex.horizontal, - }, - { + music_art, { - step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, - speed = 50, { - widget = music_now, + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, + title_now, + forced_width = dpi(150), + widget = wibox.container.scroll.horizontal, }, - -- forced_width = dpi(110), - widget = wibox.container.scroll.horizontal, - }, - left = dpi(15), - right = dpi(20), - widget = wibox.container.margin, - }, - { - music_pos, - { - loop, - shuffle, - -- Go to list of playlists - control_button( - c, - "󰲸", - beautiful.xforeground, - beautiful.icon_font_name .. "12", - dpi(30), - function() - helpers.send_key(c, "1") - end - ), - -- Go to visualizer - control_button(c, "", beautiful.xforeground, "icomoon 12", dpi(30), function() - helpers.send_key(c, "8") - end), - layout = wibox.layout.flex.horizontal, + { + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, + artist_now, + forced_width = dpi(150), + widget = wibox.container.scroll.horizontal, + }, + spacing = dpi(2), + layout = wibox.layout.flex.vertical, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + { + widgets.playerctl.shuffle(beautiful.xforeground, beautiful.music_bg_accent), + widgets.playerctl.previous(12, beautiful.xforeground, beautiful.music_bg_accent), + widgets.playerctl.play(beautiful.music_bg_accent, beautiful.accent), + widgets.playerctl.next(12, beautiful.xforeground, beautiful.music_bg_accent), + widgets.playerctl.loop(beautiful.xforeground, beautiful.music_bg_accent), + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + { + --- Music Position + music_pos, + { + playlist(c), + visualizer(c), + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal, }, spacing = dpi(10), layout = wibox.layout.fixed.horizontal, }, - layout = wibox.layout.align.horizontal, }, - margins = dpi(15), + top = dpi(15), + bottom = dpi(15), + left = dpi(25), + right = dpi(25), widget = wibox.container.margin, }, - layout = wibox.layout.align.vertical, }, bg = beautiful.music_bg_accent, - shape = helpers.prrect(beautiful.border_radius, false, false, true, true), + shape = helpers.ui.prrect(beautiful.border_radius, false, false, true, true), widget = wibox.container.background, }) - -- Set custom decoration flags + --- Set custom decoration flags c.custom_decoration = { top = true, left = true, bottom = true } end --- Add the titlebar whenever a new music client is spawned +--- Add the titlebar whenever a new music client is spawned ruled.client.connect_signal("request::rules", function() ruled.client.append_rule({ id = "music", diff --git a/config/awesome/ui/decorations/titlebar.lua b/config/awesome/ui/decorations/titlebar.lua old mode 100644 new mode 100755 index d108349..8d32ed8 --- a/config/awesome/ui/decorations/titlebar.lua +++ b/config/awesome/ui/decorations/titlebar.lua @@ -2,130 +2,151 @@ local awful = require("awful") local gears = require("gears") local wibox = require("wibox") local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi local helpers = require("helpers") +local decorations = require("ui.decorations") -local function create_title_button(c, color_focus, color_unfocus, shp) - local ico = wibox.widget({ - markup = "", - widget = wibox.widget.textbox, - }) - local tb = wibox.widget({ - ico, - forced_width = dpi(16), - forced_height = dpi(16), - bg = color_focus .. 80, - shape = shp, - widget = wibox.container.background, - }) +--- MacOS like window decorations +--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - local function update() - if client.focus == c then - tb.bg = color_focus - else - tb.bg = color_unfocus - end - end - update() +--- Disable this if using `picom` to round your corners +--- decorations.enable_rounding() - c:connect_signal("focus", update) - c:connect_signal("unfocus", update) +local button_size = dpi(16) +local button_margin = { top = dpi(2), bottom = dpi(2), left = dpi(5), right = dpi(5) } +local button_color_unfocused = beautiful.xcolor8 +local button_shape = gears.shape.circle - tb:connect_signal("mouse::enter", function() - local clr = client.focus ~= c and color_focus or color_focus .. 55 - tb.bg = clr - end) - tb:connect_signal("mouse::leave", function() - local clr = client.focus == c and color_focus or color_unfocus - tb.bg = clr - end) - - tb.visible = true - return tb +local function close(c) + return decorations.button( + c, + button_shape, + beautiful.xcolor1, + button_color_unfocused, + beautiful.xcolor9, + button_size, + button_margin, + "close" + ) end --- Add a titlebar if titlebars_enabled is set to true in the rules. -client.connect_signal("request::titlebars", function(c) - -- buttons for the titlebar - local buttons = gears.table.join( - awful.button({}, 1, function() - c:emit_signal("request::activate", "titlebar", { raise = true }) - awful.mouse.client.move(c) - end), - awful.button({}, 3, function() - c:emit_signal("request::activate", "titlebar", { raise = true }) - awful.mouse.client.resize(c) - end) +local function minimize(c) + return decorations.button( + c, + button_shape, + beautiful.xcolor3, + button_color_unfocused, + beautiful.xcolor11, + button_size, + button_margin, + "minimize" ) +end - local close = create_title_button(c, beautiful.xcolor1, beautiful.xcolor8 .. 55, gears.shape.circle) - close:connect_signal("button::press", function() - c:kill() - end) +local function maximize(c) + return decorations.button( + c, + button_shape, + beautiful.xcolor2, + button_color_unfocused, + beautiful.xcolor10, + button_size, + button_margin, + "maximize" + ) +end - local minimize = create_title_button(c, beautiful.xcolor3, beautiful.xcolor8 .. 55, gears.shape.circle) - minimize:connect_signal("button::press", function() - c.minimized = true - end) - - local maximize = create_title_button(c, beautiful.xcolor2, beautiful.xcolor8 .. 55, gears.shape.circle) - maximize:connect_signal("button::press", function() - helpers.maximize(c) - end) - - -- Titlebars setup - -------------------- - - awful.titlebar(c, { position = "top", size = dpi(45), bg = beautiful.transparent }):setup({ +--- Add a titlebar if titlebars_enabled is set to true in the rules. +client.connect_signal("request::titlebars", function(c) + awful.titlebar( + c, + { position = "top", size = dpi(38), font = beautiful.font_name .. "Medium 10", bg = beautiful.transparent } + ):setup({ { layout = wibox.layout.align.horizontal, - { + { --- Left { - close, - minimize, - maximize, + close(c), + minimize(c), + maximize(c), + --- Create some extra padding at the edge + helpers.ui.horizontal_pad(dpi(5)), layout = wibox.layout.fixed.horizontal, - spacing = dpi(10), }, - left = dpi(15), + left = dpi(10), widget = wibox.container.margin, }, - { - { - { -- Title - align = "center", - widget = awful.titlebar.widget.titlewidget(c), + { --- Middle + { --- Title + align = "center", + font = beautiful.font_name .. "Medium 10", + widget = awful.titlebar.widget.titlewidget(c), + buttons = { + --- Move client + awful.button({ + modifiers = {}, + button = 1, + on_press = function() + c.maximized = false + c:activate({ context = "mouse_click", action = "mouse_move" }) + end, + }), + + --- Kill client + awful.button({ + modifiers = {}, + button = 2, + on_press = function() + c:kill() + end, + }), + + --- Resize client + awful.button({ + modifiers = {}, + button = 3, + on_press = function() + c.maximized = false + c:activate({ context = "mouse_click", action = "mouse_resize" }) + end, + }), + + --- Side button up + awful.button({ + modifiers = {}, + button = 9, + on_press = function() + c.floating = not c.floating + end, + }), + + --- Side button down + awful.button({ + modifiers = {}, + button = 8, + on_press = function() + c.ontop = not c.ontop + end, + }), }, - layout = wibox.layout.flex.horizontal, - spacing = dpi(10), }, - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin, - buttons = buttons, - }, - { - { - layout = wibox.layout.fixed.horizontal, - spacing = dpi(10), - }, - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin, - buttons = buttons, + layout = wibox.layout.flex.horizontal, }, + --- Right + nil, }, bg = beautiful.titlebar_bg, - shape = helpers.prrect(beautiful.border_radius, true, true, false, false), + shape = helpers.ui.prrect(beautiful.border_radius, true, true, false, false), widget = wibox.container.background, }) awful.titlebar(c, { position = "bottom", - size = dpi(24), + size = dpi(19), bg = beautiful.transparent, }):setup({ bg = beautiful.titlebar_bg, - shape = helpers.prrect(beautiful.border_radius, false, false, true, true), + shape = helpers.ui.prrect(beautiful.border_radius, false, false, true, true), widget = wibox.container.background, }) end) diff --git a/config/awesome/ui/decorations/twitch.lua b/config/awesome/ui/decorations/twitch.lua deleted file mode 100644 index 61f9c90..0000000 --- a/config/awesome/ui/decorations/twitch.lua +++ /dev/null @@ -1,468 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme library -local beautiful = require("beautiful") - --- Ruled -local ruled = require("ruled") - --- Widget library -local wibox = require("wibox") - --- Helpers -local helpers = require("helpers") - - --- Music icon ----------------- - -local big_music_icon = wibox.widget{ - align = "center", - font = beautiful.icon_font_name .. "Bold 16", - markup = helpers.colorize_text("", beautiful.xcolor4), - widget = wibox.widget.textbox() -} - -local small_music_icon = wibox.widget{ - align = "center", - font = beautiful.icon_font_name .. "Bold 12", - markup = helpers.colorize_text("", beautiful.xforeground), - widget = wibox.widget.textbox() -} - -local container_music_icon = wibox.widget { - big_music_icon, - { - small_music_icon, - top = dpi(12), - widget = wibox.container.margin - }, - spacing = dpi(-8), - layout = wibox.layout.fixed.horizontal -} - -local music_icon = wibox.widget{ - nil, - { - container_music_icon, - spacing = dpi(14), - layout = wibox.layout.fixed.horizontal - }, - expand = "none", - layout = wibox.layout.align.horizontal, - } - --- Helpers -------------- - -local control_button_bg = "#00000000" -local control_button_bg_hover = beautiful.xcolor0 -local control_button = function(c, symbol, color, font, size, on_click, on_right_click) - local icon = wibox.widget{ - markup = helpers.colorize_text(symbol, color), - font = font, - align = "center", - valign = "center", - widget = wibox.widget.textbox() - } - - local button = wibox.widget { - icon, - bg = control_button_bg, - shape = helpers.rrect(dpi(5)), - widget = wibox.container.background - } - - local container = wibox.widget { - button, - strategy = "min", - width = dpi(30), - widget = wibox.container.constraint, - } - - container:buttons(gears.table.join( - awful.button({ }, 1, on_click), - awful.button({ }, 3, on_right_click) - )) - - container:connect_signal("mouse::enter", function () - button.bg = control_button_bg_hover - end) - container:connect_signal("mouse::leave", function () - button.bg = control_button_bg - end) - - return container -end - -local music_play_pause = control_button(c, "", beautiful.xforeground, beautiful.icon_font_name .. "Round 22", dpi(30), function() - awful.spawn.with_shell("mpc -q toggle") -end) - --- Loop button -local loop = control_button(c, "", beautiful.xforeground, beautiful.icon_font_name .. "Round 12", dpi(30), function() - awful.spawn.with_shell("mpc repeat") -end) - --- Shuffle playlist -local shuffle = control_button(c, "", beautiful.xforeground, beautiful.icon_font_name .. "Round 12", dpi(30), function() - awful.spawn.with_shell("mpc random") -end) - -local function create_slider_widget(slider_color) - local slider_widget = wibox.widget { - { - id = "slider", - max_value = 100, - value = 20, - margins = { - top = dpi(7), - bottom = dpi(7), - left = dpi(6), - right = dpi(6), - }, - forced_width = dpi(60), - shape = gears.shape.rounded_bar, - bar_shape = gears.shape.rounded_bar, - color = slider_color, - background_color = beautiful.xcolor0, - widget = wibox.widget.progressbar - }, - expand = "none", - forced_width = 60, - layout = wibox.layout.align.horizontal - } - - return slider_widget -end - -local stats_tooltip = wibox.widget { - visible = false, - top_only = true, - layout = wibox.layout.stack -} - -local tooltip_counter = 0 -local function create_tooltip(w) - local tooltip = wibox.widget { - font = beautiful.font_name .. "bold 10", - align = "right", - valign = "center", - widget = wibox.widget.textbox - } - - tooltip_counter = tooltip_counter + 1 - local index = tooltip_counter - - stats_tooltip:insert(index, tooltip) - - w:connect_signal("mouse::enter", function() - -- Raise tooltip to the top of the stack - stats_tooltip:set(1, tooltip) - stats_tooltip.visible = true - end) - w:connect_signal("mouse::leave", function () - stats_tooltip.visible = false - end) - - return tooltip -end - - --- Decorations ----------------- - -local music_art = wibox.widget { - image = gears.filesystem.get_configuration_dir() .. "theme/assets/no_music.png", - resize = true, - widget = wibox.widget.imagebox -} - -local music_art_container = wibox.widget{ - music_art, - shape = helpers.rrect(dpi(5)), - widget = wibox.container.background -} - -local music_now = wibox.widget{ - font = beautiful.font_name .. "bold 10", - valign = "center", - widget = wibox.widget.textbox -} - -local music_pos = wibox.widget{ - font = beautiful.font_name .. "bold 10", - valign = "center", - widget = wibox.widget.textbox -} - -local music_bar = wibox.widget { - max_value = 100, - value = 0, - background_color = beautiful.xcolor0, - color = beautiful.xcolor4, - forced_height = dpi(3), - widget = wibox.widget.progressbar -} - -music_bar:connect_signal("button::press", function(_, lx, __, button, ___, w) - if button == 1 then - awful.spawn.with_shell("mpc seek " .. math.ceil(lx * 100 / w.width) .. "%") - end -end) - - -local music_play_pause_textbox = music_play_pause:get_all_children()[1]:get_all_children()[1] -local loop_textbox = loop:get_all_children()[1]:get_all_children()[1] -local shuffle_textbox = shuffle:get_all_children()[1]:get_all_children()[1] - --- Volume --------- - -local vol_color = beautiful.xcolor4 -local vol_slider = create_slider_widget(vol_color) -local vol_tooltip = create_tooltip(vol_slider) - -local vol_icon = wibox.widget{ - align = "center", - font = "icomoon 16", - markup = "", - widget = wibox.widget.textbox -} - -local vol_button = wibox.widget{ - vol_icon, - bg = control_button_bg, - shape = helpers.rrect(dpi(5)), - widget = wibox.container.background -} - -local vol = wibox.widget { - vol_button, - strategy = "min", - width = dpi(30), - widget = wibox.container.constraint, -} - -vol:connect_signal("mouse::enter", function () - vol_button.bg = control_button_bg_hover -end) -vol:connect_signal("mouse::leave", function () - vol_button.bg = control_button_bg -end) -vol:buttons(gears.table.join( - awful.button({}, 1, function() helpers.volume_control(0) end) -)) - -awesome.connect_signal("signal::volume", function(value, muted) - local fill_color - local vol_value = value or 0 - - if muted then - vol_icon.markup = helpers.colorize_text("", beautiful.xcolor8) - fill_color = beautiful.xcolor8 - else - vol_icon.markup = helpers.colorize_text("", beautiful.xforeground) - fill_color = vol_color - end - - vol_slider.slider.value = vol_value - vol_slider.slider.color = fill_color - vol_tooltip.markup = helpers.colorize_text(vol_value .. "%", vol_color) -end) - -vol_slider:buttons(gears.table.join( - awful.button({}, 1, function() helpers.volume_control(0) end), - -- Scrolling - awful.button({}, 4, function() helpers.volume_control(5) end), - awful.button({}, 5, function() helpers.volume_control(-5) end) -)) - --- Playerctl ---------------- - -local playerctl = require("module.bling").signal.playerctl.lib() -local music_length = 0 - -playerctl:connect_signal("metadata", function(_, title, artist, album_path, album, ___, player_name) - if player_name == "mpd" then - local m_now = artist .. " - " .. title .. "/" .. album - - - music_now:set_markup_silently(m_now) - end -end) - -playerctl:connect_signal("position", function(_, interval_sec, length_sec, player_name) - if player_name == "mpd" then - local pos_now = tostring(os.date("!%M:%S", math.floor(interval_sec))) - local pos_length = tostring(os.date("!%M:%S", math.floor(length_sec))) - local pos_markup = pos_now .. helpers.colorize_text(" / " .. pos_length, beautiful.xcolor8) - - music_art:set_image(gears.surface.load_uncached(album_path)) - music_pos:set_markup_silently(pos_markup) - music_bar.value = (interval_sec / length_sec) * 100 - music_length = length_sec - end -end) - -playerctl:connect_signal("playback_status", function(_, playing, player_name) - if player_name == "mpd" then - if playing then - music_play_pause_textbox:set_markup_silently(helpers.colorize_text("", beautiful.xcolor4)) - else - music_play_pause_textbox:set_markup_silently(helpers.colorize_text("", beautiful.xcolor4)) - end - end -end) - -playerctl:connect_signal("loop_status", function(_, loop_status, player_name) - if player_name == "mpd" then - if loop_status == "none" then - loop_textbox:set_markup_silently("") - else - loop_textbox:set_markup_silently("") - end - end -end) - -playerctl:connect_signal("shuffle", function(_, shuffle, player_name) - if player_name == "mpd" then - if shuffle then - shuffle_textbox:set_markup_silently("") - else - shuffle_textbox:set_markup_silently("") - end - end -end) - -local music_create_decoration = function (c) - - -- Hide default titlebar - awful.titlebar.hide(c, beautiful.titlebar_pos) - - -- Titlebar - awful.titlebar(c, { position = "top", size = beautiful.titlebar_size, bg = beautiful.xbackground }):setup { - { - { - { - { - vol, - nil, - vol_slider, - spacing = dpi(2), - layout = wibox.layout.fixed.horizontal - }, - stats_tooltip, - layout = wibox.layout.align.horizontal - }, - top = dpi(10), - bottom = dpi(10), - right = dpi(10), - left = dpi(15), - widget = wibox.container.margin - }, - forced_width = dpi(200), - widget = wibox.container.background - }, - { - widget = music_icon - }, - layout = wibox.layout.align.horizontal - } - - -- Sidebar - awful.titlebar(c, { position = "left", size = dpi(200), bg = beautiful.xbackground }):setup { - { - nil, - { - music_art_container, - bottom = dpi(20), - left = dpi(25), - right = dpi(25), - widget = wibox.container.margin - }, - nil, - expand = "none", - layout = wibox.layout.align.vertical - }, - bg = beautiful.bg_accent, - shape = helpers.prrect(dpi(10), false, true, false, false), - widget = wibox.container.background, - } - - -- Toolbar - awful.titlebar(c, { position = "bottom", size = dpi(63), bg = beautiful.bg_secondary }):setup { - music_bar, - { - { - { - -- Go to playlist and focus currently playing song - control_button(c, "", beautiful.xforeground, beautiful.icon_font_name .. "Round 14", dpi(30), function() - awful.spawn.with_shell("mpc -q prev") - end), - -- Toggle play pause - music_play_pause, - -- Go to list of playlists - control_button(c, "", beautiful.xforeground, beautiful.icon_font_name .. "Round 14", dpi(30), function() - awful.spawn.with_shell("mpc -q next") - end), - layout = wibox.layout.flex.horizontal - }, - { - { - step_function = wibox.container.scroll - .step_functions - .waiting_nonlinear_back_and_forth, - speed = 50, - { - widget = music_now, - }, - -- forced_width = dpi(110), - widget = wibox.container.scroll.horizontal - }, - left = dpi(15), - right = dpi(20), - widget = wibox.container.margin - }, - { - music_pos, - { - loop, - shuffle, - -- Go to list of playlists - control_button(c, "", beautiful.xforeground, beautiful.icon_font_name .. "Round 12", dpi(30), function() - helpers.send_key(c, "1") - end), - -- Go to visualizer - control_button(c, "", beautiful.xforeground, "icomoon 12", dpi(30), function() - helpers.send_key(c, "8") - end), - layout = wibox.layout.flex.horizontal - }, - spacing = dpi(10), - layout = wibox.layout.fixed.horizontal - }, - layout = wibox.layout.align.horizontal - }, - margins = dpi(15), - widget = wibox.container.margin - }, - layout = wibox.layout.align.vertical - } - - -- Set custom decoration flags - c.custom_decoration = { top = true, left = true, bottom = true } -end - --- Add the titlebar whenever a new music client is spawned -ruled.client.connect_signal("request::rules", function() - ruled.client.append_rule { - id = "music", - rule = {instance = "music"}, - callback = music_create_decoration - } -end) - diff --git a/config/awesome/ui/init.lua b/config/awesome/ui/init.lua old mode 100644 new mode 100755 index b843bd2..5fdf5d4 --- a/config/awesome/ui/init.lua +++ b/config/awesome/ui/init.lua @@ -1,4 +1,19 @@ -require("ui.bar") -require("ui.central-panel") -require("ui.decorations") -require("ui.notifs") +require(... .. ".notifications") +require(... .. ".popups") + +local decorations = require(... .. ".decorations") +decorations.init() + +local bottom_panel = require(... .. ".panels.bottom-panel") +local central_panel = require(... .. ".panels.central-panel") +local info_panel = require(... .. ".panels.info-panel") +local notification_panel = require(... .. ".panels.notification-panel") + +local awful = require("awful") +awful.screen.connect_for_each_screen(function(s) + --- Panels + bottom_panel(s) + central_panel(s) + info_panel(s) + notification_panel(s) +end) diff --git a/config/awesome/ui/lockscreen/init.lua b/config/awesome/ui/lockscreen/init.lua deleted file mode 100644 index 6280313..0000000 --- a/config/awesome/ui/lockscreen/init.lua +++ /dev/null @@ -1,18 +0,0 @@ -local awful = require("awful") -local gfs = require('gears.filesystem') - -local lock_screen = {} - -local config_dir = gfs.get_configuration_dir() -package.cpath = package.cpath .. ";" .. config_dir .. "ui/lockscreen/lib/?.so;" - -lock_screen.init = function() - local pam = require("liblua_pam") - lock_screen.authenticate = function(password) - return pam.auth_current_user(password) - -- return password == "awesome" - end - require("ui.lockscreen.lockscreen") -end - -return lock_screen diff --git a/config/awesome/ui/lockscreen/lib/liblua_pam.so b/config/awesome/ui/lockscreen/lib/liblua_pam.so deleted file mode 100755 index fb05778..0000000 Binary files a/config/awesome/ui/lockscreen/lib/liblua_pam.so and /dev/null differ diff --git a/config/awesome/ui/lockscreen/lockscreen.lua b/config/awesome/ui/lockscreen/lockscreen.lua deleted file mode 100644 index 9826c2b..0000000 --- a/config/awesome/ui/lockscreen/lockscreen.lua +++ /dev/null @@ -1,420 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - --- Notification library -local naughty = require("naughty") - --- Widget library -local wibox = require("wibox") - --- rubato -local rubato = require("module.rubato") - --- Helpers -local helpers = require("helpers") - --- Lock -local lock_screen = require("ui.lockscreen") - - --- Lock Screen ----------------- - -lock_screen_box = wibox({visible = false, ontop = true, type = "splash", screen = screen.primary}) -awful.placement.maximize(lock_screen_box) --- lock_screen_box.bg = beautiful.transparent -lock_screen_box.bg = beautiful.xbackground .. "22" - --- Add lockscreen to each screen -awful.screen.connect_for_each_screen(function(s) - if s == screen.primary then - s.mylockscreen = lock_screen_box - else - s.mylockscreen = helpers.screen_mask(s, beautiful.lock_screen_bg or beautiful.exit_screen_bg or beautiful.xbackground) - end -end) - --- Vars -local char = "I T L I S A S A M P M A C Q U A R T E R D C T W E N T Y F I V E X H A L F S T E N F T O P A S T E R U N I N E O N E S I X T H R E E F O U R F I V E T W O E I G H T E L E V E N S E V E N T W E L V E T E N S E O C L O C K" - -local pos_map = { - ["it"] = {1, 2}, - ["is"] = {4, 5}, - ["a"] = {12, 12}, - ["quarter"] = {14, 20}, - ["twenty"] = {23,28}, - ["five"] = {29, 32}, - ["half"] = {34, 37}, - ["ten"] = {39, 41}, - ["past"] = {45, 48}, - ["to"] = {43, 44}, - ["1"] = {56, 58}, - ["2"] = {75, 77}, - ["3"] = {62, 66}, - ["4"] = {67, 70}, - ["5"] = {71, 74}, - ["6"] = {59, 61}, - ["7"] = {89, 93}, - ["8"] = {78, 82}, - ["9"] = {52, 55}, - ["10"] = {100, 102}, - ["11"] = {83, 88}, - ["12"] = {94, 99}, - ["oclock"] = {105, 110} -} - -local char_map = { - ["it"] = {}, - ["is"] = {}, - ["a"] = {}, - ["quarter"] = {}, - ["twenty"] = {}, - ["five"] = {}, - ["half"] = {}, - ["ten"] = {}, - ["past"] = {}, - ["to"] = {}, - ["1"] = {}, - ["2"] = {}, - ["3"] = {}, - ["4"] = {}, - ["5"] = {}, - ["6"] = {}, - ["7"] = {}, - ["8"] = {}, - ["9"] = {}, - ["10"] = {}, - ["11"] = {}, - ["12"] = {}, - ["oclock"] = {} -} - -local reset_map = {4, 12, 14, 23, 29, 34, 39, 43, 45, 52, 56, 59, 62, 67, 71, 75, 78, 83, 89, 94, 100, 105} - -function split_str(s, delimiter) - result = {}; - for match in (s..delimiter):gmatch("(.-)"..delimiter) do - table.insert(result, match); - end - - return result; -end - -local time_char = split_str(char, " ") - --- Helpers - -local time = wibox.widget{ - forced_num_cols = 11, - spacing = beautiful.useless_gap, - layout = wibox.layout.grid -} - -local function create_text_widget(index, w) - local text_widget = wibox.widget{ - id = "t"..index, - markup = w, - font = beautiful.font_name .. "bold 18", - align = "center", - valign = "center", - forced_width = dpi(25), - forced_height = dpi(30), - widget = wibox.widget.textbox - } - - time:add(text_widget) - - return text_widget -end - -local var_count = 0 -for i, m in pairs(time_char) do - -- local text = helpers.colorize_text(m, "#162026") - local text = helpers.colorize_text(m, beautiful.lighter_bg .. "55") - - var_count = var_count + 1 - local create_dummy_text = true - - for j, k in pairs(pos_map) do - if i >= pos_map[j][1] and i <= pos_map[j][2] then - char_map[j][var_count] = create_text_widget(i, text) - create_dummy_text = false - end - - for _, n in pairs(reset_map) do - if i == n then - var_count = 1 - end - end - - end - - if create_dummy_text then - create_text_widget(i, text) - end - -end - -local function activate_word(w) - for i, m in pairs(char_map[w]) do - local text = m.text - - m.markup = helpers.colorize_text(text, beautiful.xforeground) - - end -end - -local function deactivate_word(w) - for i, m in pairs(char_map[w]) do - local text = m.text - - m.markup = helpers.colorize_text(text, beautiful.lighter_bg .. "55") - - end -end - -local function reset_time() - - for j, k in pairs(char_map) do - deactivate_word(j) - end - - activate_word("it") - activate_word("is") - -end - -gears.timer { - timeout = 1, - call_now = true, - autostart = true, - callback = function() - local time = os.date('%I' .. ':%M') - local h,m = time:match('(%d+):(%d+)') - local min = tonumber(m) - local hour = tonumber(h) - - reset_time() - - if min >= 0 and min <= 2 or min >= 58 and min <= 59 then - activate_word("oclock") - elseif min >= 3 and min <= 7 or min >= 53 and min <= 57 then - activate_word("five") - elseif min >= 8 and min <= 12 or min >= 48 and min <= 52 then - activate_word("ten") - elseif min >= 13 and min <= 17 or min >= 43 and min <= 47 then - activate_word("a") - activate_word("quarter") - elseif min >= 18 and min <= 22 or min >= 38 and min <= 42 then - activate_word("twenty") - elseif min >= 23 and min <= 27 or min >= 33 and min <= 37 then - activate_word("twenty") - activate_word("five") - elseif min >= 28 and min <= 32 then - activate_word("half") - end - - if min >= 3 and min <= 32 then - activate_word("past") - elseif min >= 33 and min <= 57 then - activate_word("to") - end - - local hh - - if min >= 0 and min <= 30 then - hh = hour - else - hh = hour + 1 - end - - if hh > 12 then - hh = hh - 12 - end - - activate_word(tostring(hh)) - end -} - --- Lock animation -local lock_screen_symbol = "" -local lock_screen_fail_symbol = "" -local lock_animation_icon = wibox.widget { - -- Set forced size to prevent flickering when the icon rotates - forced_height = dpi(80), - forced_width = dpi(80), - font = beautiful.icon_font_name .. "Outlined 24", - align = "center", - valign = "center", - widget = wibox.widget.textbox(lock_screen_symbol) -} - -local lock_animation_widget_rotate = wibox.container.rotate() - -local arc = function() - return function(cr, width, height) - gears.shape.arc(cr, width, height, dpi(5), 0, math.pi/3, true, true) - end -end - -local lock_animation_arc = wibox.widget { - shape = arc(), - bg = "#00000000", - forced_width = dpi(50), - forced_height = dpi(50), - widget = wibox.container.background -} - -local lock_animation = { - { - lock_animation_arc, - widget = lock_animation_widget_rotate - }, - lock_animation_icon, - layout = wibox.layout.stack -} - --- Lock helper functions -local characters_entered = 0 -local function reset() - characters_entered = 0; - lock_animation_icon.markup = helpers.colorize_text(lock_screen_symbol, beautiful.xcolor7) - lock_animation_widget_rotate.direction = "north" - lock_animation_arc.bg = "#00000000" -end - -local function fail() - characters_entered = 0; - lock_animation_icon.text = lock_screen_fail_symbol - lock_animation_widget_rotate.direction = "north" - lock_animation_arc.bg = "#00000000" -end - -local animation_colors = { - -- Rainbow sequence =) - beautiful.xcolor1, - beautiful.xcolor5, - beautiful.xcolor4, - beautiful.xcolor6, - beautiful.xcolor2, - beautiful.xcolor3, -} - -local animation_directions = {"north", "west", "south", "east"} - --- Function that "animates" every key press -local function key_animation(char_inserted) - local color - local direction = animation_directions[(characters_entered % 4) + 1] - if char_inserted then - color = animation_colors[(characters_entered % 6) + 1] - lock_animation_icon.text = lock_screen_symbol - else - if characters_entered == 0 then - reset() - else - color = beautiful.xcolor7 .. "55" - end - end - - lock_animation_arc.bg = color - lock_animation_widget_rotate.direction = direction -end - -local function set_visibility(v) - for s in screen do - s.mylockscreen.visible = v - end -end - --- Get input from user -local some_textbox = wibox.widget.textbox() -local function grab_password() - awful.prompt.run { - hooks = { - -- Custom escape behaviour: Do not cancel input with Escape - -- Instead, this will just clear any input received so far. - {{ }, 'Escape', - function(_) - reset() - grab_password() - end - }, - -- Fix for Control+Delete crashing the keygrabber - {{ 'Control' }, 'Delete', function () - reset() - grab_password() - end} - }, - keypressed_callback = function(mod, key, cmd) - -- Only count single character keys (thus preventing - -- "Shift", "Escape", etc from triggering the animation) - if #key == 1 then - characters_entered = characters_entered + 1 - key_animation(true) - elseif key == "BackSpace" then - if characters_entered > 0 then - characters_entered = characters_entered - 1 - end - key_animation(false) - end - - -- Debug - -- naughty.notify { title = 'You pressed:', text = key } - end, - exe_callback = function(input) - -- Check input - if lock_screen.authenticate(input) then - -- YAY - reset() - set_visibility(false) - else - -- NAY - fail() - grab_password() - end - end, - textbox = some_textbox, - } -end - -function lock_screen_show() - set_visibility(true) - grab_password() -end - -lock_screen_box:setup { - -- Horizontal centering - nil, - { - -- Vertical centering - nil, - { - { - { - helpers.vertical_pad(dpi(10)), - time, - lock_animation, - spacing = dpi(50), - layout = wibox.layout.fixed.vertical - }, - bottom = dpi(60), - right = dpi(60), - left = dpi(60), - widget = wibox.container.margin - }, - shape = helpers.rrect(beautiful.border_radius), - bg = beautiful.xbackground, - widget = wibox.container.background - }, - expand = "none", - layout = wibox.layout.align.vertical - }, - expand = "none", - layout = wibox.layout.align.horizontal -} diff --git a/config/awesome/ui/main-menu/init.lua b/config/awesome/ui/main-menu/init.lua new file mode 100755 index 0000000..6f17aa1 --- /dev/null +++ b/config/awesome/ui/main-menu/init.lua @@ -0,0 +1,134 @@ +local awful = require("awful") +local menu = require("ui.widgets.menu") +local hotkeys_popup = require("awful.hotkeys_popup") +local apps = require("configuration.apps") +local focused = awful.screen.focused() + +local instance = nil + +local function awesome_menu() + return menu({ + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Show Help", + on_press = function() + hotkeys_popup.show_help(nil, awful.screen.focused()) + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Manual", + on_press = function() + awful.spawn(apps.default.terminal .. " -e man awesome") + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Edit Config", + on_press = function() + awful.spawn(apps.default.text_editor .. " " .. awesome.conffile) + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Restart", + on_press = function() + awesome.restart() + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Quit", + on_press = function() + awesome.quit() + end, + }), + }) +end + +local function widget() + return menu({ + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Applications", + on_press = function() + awful.spawn(apps.default.app_launcher, false) + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Terminal", + on_press = function() + awful.spawn(apps.default.terminal, false) + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Web Browser", + on_press = function() + awful.spawn(apps.default.web_browser, false) + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "File Manager", + on_press = function() + awful.spawn(apps.default.file_manager, false) + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Text Editor", + on_press = function() + awful.spawn(apps.default.code_editor, false) + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Music Player", + on_press = function() + awful.spawn(apps.default.music_player, false) + end, + }), + menu.separator(), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Dashboard", + on_press = function() + awesome.emit_signal("central_panel::toggle", focused) + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Info Center", + on_press = function() + awesome.emit_signal("info_panel::toggle", focused) + end, + }), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Notification Center", + on_press = function() + awesome.emit_signal("notification_panel::toggle", focused) + end, + }), + menu.separator(), + menu.button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "Exit", + on_press = function() + awesome.emit_signal("module::exit_screen:show") + end, + }), + menu.sub_menu_button({ + icon = { icon = "", font = "Material Icons Round " }, + text = "AwesomeWM", + sub_menu = awesome_menu(), + }), + }) +end + +if not instance then + instance = widget() +end +return instance diff --git a/config/awesome/ui/notifications/battery.lua b/config/awesome/ui/notifications/battery.lua new file mode 100755 index 0000000..cfc6297 --- /dev/null +++ b/config/awesome/ui/notifications/battery.lua @@ -0,0 +1,54 @@ +local gears = require("gears") +local beautiful = require("beautiful") +local naughty = require("naughty") +local icons = require("icons") + +local display_high = true +local display_low = true +local display_charge = true + +awesome.connect_signal("signal::battery", function(percentage, state) + local value = percentage + + -- only display message if its not charging and low + if value <= 15 and display_low and state == 2 then + naughty.notification({ + title = "Battery Status", + text = "Running low at " .. math.floor(value) .. "%", + app_name = "AwesomeWM", + image = gears.color.recolor_image(icons.battery_low, beautiful.xcolor1), + }) + display_low = false + end + + -- only display message once if its fully charged and high + if display_high and state == 4 and value > 90 then + naughty.notification({ + title = "Battery Status", + text = "Fully charged!", + app_name = "AwesomeWM", + image = gears.color.recolor_image(icons.battery, beautiful.xcolor2), + }) + display_high = false + end + + -- only display once if charging + if display_charge and state == 1 then + naughty.notification({ + title = "Battery Status", + text = "Charging", + app_name = "AwesomeWM", + image = gears.color.recolor_image(icons.charging, beautiful.xcolor6), + }) + display_charge = false + end + + if value < 88 and value > 18 then + display_low = true + display_high = true + end + + if state == 2 then + display_charge = true + end +end) diff --git a/config/awesome/ui/notifications/error.lua b/config/awesome/ui/notifications/error.lua new file mode 100755 index 0000000..849786f --- /dev/null +++ b/config/awesome/ui/notifications/error.lua @@ -0,0 +1,12 @@ +local naughty = require("naughty") + +-- 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", + app_name = "Awesome", + title = "Oops, an error happened" .. (startup and " during startup!" or "!"), + message = message, + }) +end) diff --git a/config/awesome/ui/notifications/init.lua b/config/awesome/ui/notifications/init.lua new file mode 100755 index 0000000..bd64445 --- /dev/null +++ b/config/awesome/ui/notifications/init.lua @@ -0,0 +1,340 @@ +local gears = require("gears") +local wibox = require("wibox") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local naughty = require("naughty") +local helpers = require("helpers") +local menubar = require("menubar") +local animation = require("modules.animation") +local widgets = require("ui.widgets") + +-- Naughty Notifications with animation +-- ------------------------------------- + +naughty.persistence_enabled = true +naughty.config.defaults.ontop = true +naughty.config.defaults.timeout = 6 +naughty.config.defaults.title = "System Notification" +naughty.config.defaults.position = "top_right" + +local function get_oldest_notification() + for _, notification in ipairs(naughty.active) do + if notification and notification.timeout > 0 then + return notification + end + end + + -- Fallback to first one. + return naughty.active[1] +end + +-- Handle notification icon +naughty.connect_signal("request::icon", function(n, context, hints) + -- Handle other contexts here + if context ~= "app_icon" then + return + end + + -- Use XDG icon + local path = menubar.utils.lookup_icon(hints.app_icon) or menubar.utils.lookup_icon(hints.app_icon:lower()) + + if path then + n.icon = path + end +end) + +-- Use XDG icon +naughty.connect_signal("request::action_icon", function(a, context, hints) + a.icon = menubar.utils.lookup_icon(hints.id) +end) + +naughty.connect_signal("request::display", function(n) + -- random accent color + local accent_colors = beautiful.random_accent_color() + + -- table of icons + local app_icons = { + ["firefox"] = { icon = "" }, + ["discord"] = { icon = "" }, + ["music"] = { icon = "" }, + ["screenshot tool"] = { icon = "" }, + ["color picker"] = { icon = "" }, + } + + local app_icon = nil + local tolow = string.lower + + if app_icons[tolow(n.app_name)] then + app_icon = app_icons[tolow(n.app_name)].icon + else + app_icon = "" + end + + local app_icon_n = wibox.widget({ + { + font = beautiful.icon_font .. "Round 10", + markup = "" .. app_icon .. "", + align = "center", + valign = "center", + widget = wibox.widget.textbox, + }, + bg = accent_colors, + widget = wibox.container.background, + shape = gears.shape.circle, + forced_height = dpi(20), + forced_width = dpi(20), + }) + + local icon = wibox.widget({ + { + { + { + image = n.icon, + resize = true, + clip_shape = gears.shape.circle, + halign = "center", + valign = "center", + widget = wibox.widget.imagebox, + }, + border_width = dpi(2), + border_color = accent_colors, + shape = gears.shape.circle, + widget = wibox.container.background, + }, + strategy = "exact", + height = dpi(50), + width = dpi(50), + widget = wibox.container.constraint, + }, + { + nil, + nil, + { + nil, + nil, + app_icon_n, + layout = wibox.layout.align.horizontal, + expand = "none", + }, + layout = wibox.layout.align.vertical, + expand = "none", + }, + layout = wibox.layout.stack, + }) + + local app_name = widgets.text({ + size = 12, + bold = true, + text = n.app_name:gsub("^%l", string.upper), + }) + + local dismiss = widgets.button.text.normal({ + font = beautiful.icon_font .. "Round ", + paddings = dpi(2), + size = 10, + bold = true, + text = "", + text_normal_bg = accent_colors, + animate_size = false, + on_release = function() + n:destroy(naughty.notification_closed_reason.dismissed_by_user) + end, + }) + + local timeout_arc = wibox.widget({ + widget = wibox.container.arcchart, + forced_width = dpi(26), + forced_height = dpi(26), + max_value = 100, + min_value = 0, + value = 0, + thickness = dpi(4), + rounded_edge = true, + bg = beautiful.notification_bg, + colors = { + { + type = "linear", + from = { 0, 0 }, + to = { 400, 400 }, + stops = { + { 0, accent_colors }, + { 0.2, accent_colors }, + { 0.4, accent_colors }, + { 0.6, accent_colors }, + { 0.8, accent_colors }, + }, + }, + }, + dismiss, + }) + + local title = wibox.widget({ + widget = wibox.container.scroll.horizontal, + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, + widgets.text({ + font = beautiful.font_name, + size = 11, + bold = true, + text = n.title, + }), + }) + + local message = wibox.widget({ + widget = wibox.container.scroll.horizontal, + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, + widgets.text({ + font = beautiful.font_name, + size = 11, + text = n.message, + }), + }) + + local actions = wibox.widget({ + notification = n, + base_layout = wibox.widget({ + spacing = dpi(3), + layout = wibox.layout.flex.horizontal, + }), + widget_template = { + { + { + { + id = "text_role", + font = beautiful.notification_font, + widget = wibox.widget.textbox, + }, + left = dpi(6), + right = dpi(6), + widget = wibox.container.margin, + }, + widget = wibox.container.place, + }, + bg = beautiful.widget_bg, + forced_height = dpi(25), + forced_width = dpi(70), + widget = wibox.container.background, + }, + style = { + underline_normal = false, + underline_selected = true, + }, + widget = naughty.list.actions, + }) + + local widget = naughty.layout.box({ + notification = n, + type = "notification", + cursor = "hand2", + -- For antialiasing: The real shape is set in widget_template + shape = gears.shape.rectangle, + maximum_width = dpi(350), + maximum_height = dpi(180), + bg = "#00000000", + widget_template = { + { + layout = wibox.layout.fixed.vertical, + { + { + { + layout = wibox.layout.align.horizontal, + app_name, + nil, + timeout_arc, + }, + margins = { top = dpi(5), bottom = dpi(5), left = dpi(15), right = dpi(15) }, + widget = wibox.container.margin, + }, + bg = beautiful.notification_bg_alt, + widget = wibox.container.background, + }, + { + { + layout = wibox.layout.fixed.vertical, + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(10), + icon, + { + expand = "none", + layout = wibox.layout.align.vertical, + nil, + { + layout = wibox.layout.fixed.vertical, + title, + message, + }, + nil, + }, + }, + { + helpers.ui.vertical_pad(dpi(10)), + { + actions, + shape = helpers.ui.rrect(beautiful.border_radius / 2), + widget = wibox.container.background, + }, + visible = n.actions and #n.actions > 0, + layout = wibox.layout.fixed.vertical, + }, + }, + margins = dpi(15), + widget = wibox.container.margin, + }, + }, + -- Anti-aliasing container + shape = helpers.ui.rrect(beautiful.border_radius), + bg = beautiful.notification_bg, + widget = wibox.container.background, + }, + }) + + -- Don't destroy the notification on click + widget.buttons = {} + + local anim = animation:new({ + duration = n.timeout, + target = 100, + easing = animation.easing.linear, + reset_on_stop = false, + update = function(self, pos) + timeout_arc.value = pos + end, + }) + + anim:connect_signal("ended", function() + n:destroy() + end) + + widget:connect_signal("mouse::enter", function() + -- Absurdly big number because setting it to 0 doesn't work + n:set_timeout(4294967) + anim:stop() + end) + + widget:connect_signal("mouse::leave", function() + anim:start() + end) + + local notification_height = widget.height + beautiful.notification_spacing + local total_notifications_height = #naughty.active * notification_height + + if total_notifications_height > n.screen.workarea.height then + get_oldest_notification():destroy(naughty.notification_closed_reason.too_many_on_screen) + end + + anim:start() + + -- Destroy popups notifs if dont_disturb mode is on + if _G.dnd_state then + naughty.destroy_all_notifications(nil, 1) + end +end) + +require(... .. ".error") +require(... .. ".battery") +require(... .. ".playerctl") diff --git a/config/awesome/ui/notifications/playerctl.lua b/config/awesome/ui/notifications/playerctl.lua new file mode 100755 index 0000000..12ab2b5 --- /dev/null +++ b/config/awesome/ui/notifications/playerctl.lua @@ -0,0 +1,13 @@ +local naughty = require("naughty") +local playerctl_daemon = require("signal.playerctl") + +playerctl_daemon:connect_signal("metadata", function(_, title, artist, album_path, album, new, player_name) + if new == true then + naughty.notify({ + app_name = "Music", + title = title, + text = artist, + image = album_path, + }) + end +end) diff --git a/config/awesome/ui/notifs/init.lua b/config/awesome/ui/notifs/init.lua deleted file mode 100644 index 03a5533..0000000 --- a/config/awesome/ui/notifs/init.lua +++ /dev/null @@ -1,245 +0,0 @@ -local awful = require("awful") -local gears = require("gears") -local wibox = require("wibox") -local beautiful = require("beautiful") -local naughty = require("naughty") -local helpers = require("helpers") -local ruled = require("ruled") -local menubar = require("menubar") -local icons = require("theme.assets.icons") - --- Notifications ------------------- - -naughty.connect_signal("request::icon", function(n, context, hints) - if context ~= "app_icon" then - return - end - - local path = menubar.utils.lookup_icon(hints.app_icon) or menubar.utils.lookup_icon(hints.app_icon:lower()) - - if path then - n.icon = path - end -end) - --- Import stuff --- Popup notifications -require("ui.notifs.popup") - -naughty.config.defaults.ontop = true -naughty.config.defaults.screen = awful.screen.focused() -naughty.config.defaults.timeout = 3 -naughty.config.defaults.title = "Notification" -naughty.config.defaults.position = "bottom_right" - -naughty.config.presets.low.timeout = 3 -naughty.config.presets.critical.timeout = 0 - -naughty.config.presets.normal = { - font = beautiful.font, - fg = beautiful.fg_normal, - bg = beautiful.bg_normal, -} - -naughty.config.presets.low = { - font = beautiful.font, - fg = beautiful.fg_normal, - bg = beautiful.bg_normal, -} - -naughty.config.presets.critical = { - font = beautiful.font_name .. "10", - fg = beautiful.xcolor1, - bg = beautiful.bg_normal, - timeout = 0, -} - -naughty.config.presets.ok = naughty.config.presets.normal -naughty.config.presets.info = naughty.config.presets.normal -naughty.config.presets.warn = naughty.config.presets.critical - -ruled.notification.connect_signal("request::rules", function() - -- All notifications will match this rule. - ruled.notification.append_rule({ - rule = {}, - properties = { screen = awful.screen.preferred, implicit_timeout = 6 }, - }) -end) - -naughty.connect_signal("request::display", function(n) - local appicon = n.app_icon - if not appicon then - appicon = gears.color.recolor_image(icons.notification, beautiful.accent) - end - local time = os.date("%H:%M") - - local action_widget = { - { - { - id = "text_role", - align = "center", - valign = "center", - font = beautiful.font, - widget = wibox.widget.textbox, - }, - left = dpi(6), - right = dpi(6), - widget = wibox.container.margin, - }, - bg = beautiful.lighter_bg, - forced_height = dpi(25), - forced_width = dpi(20), - shape = helpers.rrect(beautiful.border_radius / 2), - widget = wibox.container.background, - } - - local actions = wibox.widget({ - notification = n, - base_layout = wibox.widget({ - spacing = dpi(8), - layout = wibox.layout.flex.horizontal, - }), - widget_template = action_widget, - style = { underline_normal = false, underline_selected = true }, - widget = naughty.list.actions, - }) - - helpers.add_hover_cursor(actions, "hand2") - - naughty.layout.box({ - notification = n, - type = "notification", - bg = beautiful.transparent, - widget_template = { - { - { - { - { - { - { - { - { - image = appicon, - resize = true, - widget = wibox.widget.imagebox, - }, - strategy = "max", - height = dpi(20), - widget = wibox.container.constraint, - }, - right = dpi(10), - widget = wibox.container.margin, - }, - { - markup = "" .. n.app_name .. "", - align = "left", - font = beautiful.font_name .. "10", - widget = wibox.widget.textbox, - }, - { - markup = "" .. time .. "", - align = "right", - font = beautiful.font, - widget = wibox.widget.textbox, - }, - layout = wibox.layout.align.horizontal, - }, - top = dpi(10), - left = dpi(20), - right = dpi(20), - bottom = dpi(10), - widget = wibox.container.margin, - }, - bg = beautiful.darker_bg, - widget = wibox.container.background, - }, - { - { - { - helpers.vertical_pad(10), - { - { - step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, - speed = 50, - { - markup = "" .. n.title .. "", - font = beautiful.font_name .. "9", - align = "left", - widget = wibox.widget.textbox, - }, - forced_width = dpi(210), - widget = wibox.container.scroll.horizontal, - }, - { - step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, - speed = 50, - { - markup = n.message, - align = "left", - font = beautiful.font, - widget = wibox.widget.textbox, - }, - forced_width = dpi(210), - widget = wibox.container.scroll.horizontal, - }, - spacing = 0, - layout = wibox.layout.flex.vertical, - }, - helpers.vertical_pad(10), - layout = wibox.layout.align.vertical, - }, - left = dpi(20), - right = dpi(20), - widget = wibox.container.margin, - }, - { - { - nil, - { - { - image = n.icon, - resize = true, - clip_shape = helpers.rrect(beautiful.border_radius / 2), - widget = wibox.widget.imagebox, - }, - strategy = "max", - height = dpi(40), - widget = wibox.container.constraint, - }, - nil, - expand = "none", - layout = wibox.layout.align.vertical, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - layout = wibox.layout.fixed.horizontal, - }, - { - { actions, layout = wibox.layout.fixed.vertical }, - margins = dpi(10), - visible = n.actions and #n.actions > 0, - widget = wibox.container.margin, - }, - layout = wibox.layout.fixed.vertical, - }, - top = dpi(0), - bottom = dpi(5), - widget = wibox.container.margin, - }, - bg = beautiful.xbackground, - shape = helpers.rrect(beautiful.border_radius), - widget = wibox.container.background, - }, - }) - - -- Destroy popups notifs if dont_disturb mode is on - -- Or if the notif_center is visible - if - _G.dont_disturb_state - or (central_panel and central_panel.visible and central_panel:get_children_by_id("dashboard_id")[1].visible) - then - naughty.destroy_all_notifications(nil, 1) - end -end) diff --git a/config/awesome/ui/notifs/notif-center/build-notifbox/empty-notifbox.lua b/config/awesome/ui/notifs/notif-center/build-notifbox/empty-notifbox.lua deleted file mode 100644 index 3e51187..0000000 --- a/config/awesome/ui/notifs/notif-center/build-notifbox/empty-notifbox.lua +++ /dev/null @@ -1,55 +0,0 @@ -local wibox = require('wibox') -local gears = require('gears') - -local beautiful = require('beautiful') -local dpi = require('beautiful').xresources.apply_dpi - -local empty_notifbox = wibox.widget { - { - layout = wibox.layout.fixed.vertical, - spacing = dpi(20), - { - expand = 'none', - layout = wibox.layout.align.horizontal, - nil, - { - image = gears.color.recolor_image(beautiful.notification_bell_icon, beautiful.xcolor4), - resize = true, - forced_height = dpi(90), - forced_width = dpi(90), - widget = wibox.widget.imagebox, - }, - nil - }, - { - text = "No Notifications? :(", - font = beautiful.font_name .. 'medium 12', - align = 'center', - valign = 'center', - widget = wibox.widget.textbox - }, - }, - margins = dpi(20), - widget = wibox.container.margin - -} - - -local separator_for_empty_msg = wibox.widget -{ - orientation = 'vertical', - opacity = 0.0, - widget = wibox.widget.separator -} - --- Make empty_notifbox center -local centered_empty_notifbox = wibox.widget { - expand = 'none', - layout = wibox.layout.align.vertical, - separator_for_empty_msg, - empty_notifbox, - separator_for_empty_msg -} - -return centered_empty_notifbox - diff --git a/config/awesome/ui/notifs/notif-center/build-notifbox/init.lua b/config/awesome/ui/notifs/notif-center/build-notifbox/init.lua deleted file mode 100644 index 512dace..0000000 --- a/config/awesome/ui/notifs/notif-center/build-notifbox/init.lua +++ /dev/null @@ -1,77 +0,0 @@ -local wibox = require('wibox') -local awful = require('awful') -local gears = require('gears') -local naughty = require('naughty') -local beautiful = require('beautiful') -local dpi = beautiful.xresources.apply_dpi - -local empty_notifbox = require('ui.notifs.notif-center.build-notifbox.empty-notifbox') -local notifbox_scroller = require('ui.notifs.notif-center.build-notifbox.notifbox-scroller') - -local notif_core = {} - -notif_core.remove_notifbox_empty = true - -notif_core.notifbox_layout = wibox.widget { - layout = wibox.layout.fixed.vertical, - spacing = dpi(7), - empty_notifbox -} - -notifbox_scroller(notif_core.notifbox_layout) - -notif_core.reset_notifbox_layout = function() - notif_core.notifbox_layout:reset() - notif_core.notifbox_layout:insert(1, empty_notifbox) - notif_core.remove_notifbox_empty = true -end - -local notifbox_add = function(n, notif_icon, notifbox_color) - if #notif_core.notifbox_layout.children == 1 and notif_core.remove_notifbox_empty then - notif_core.notifbox_layout:reset(notif_core.notifbox_layout) - notif_core.remove_notifbox_empty = false - end - - local notifbox_box = require('ui.notifs.notif-center.build-notifbox.notifbox-builder') - notif_core.notifbox_layout:insert( - 1, - notifbox_box( - n, - notif_icon, - n.title, - n.message, - n.app_name, - notifbox_color - ) - ) -end - -local notifbox_add_expired = function(n, notif_icon, notifbox_color) - n:connect_signal( - 'destroyed', - function(self, reason, keep_visble) - if reason == 1 then - notifbox_add(n, notif_icon, notifbox_color) - end - end - ) -end - -naughty.connect_signal( - 'request::display', - function(n) - local notifbox_color = beautiful.xcolor0 - if n.urgency == 'critical' then - notifbox_color = n.bg .. '66' - end - - local notif_icon = n.icon or n.app_icon - if not notif_icon then - notif_icon = gears.color.recolor_image(beautiful.notification_icon, beautiful.xcolor4) - end - - notifbox_add_expired(n, notif_icon, notifbox_color) - end -) - -return notif_core diff --git a/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-builder.lua b/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-builder.lua deleted file mode 100644 index 5081daa..0000000 --- a/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-builder.lua +++ /dev/null @@ -1,177 +0,0 @@ -local wibox = require('wibox') -local awful = require('awful') -local gears = require('gears') -local beautiful = require('beautiful') - -local dpi = beautiful.xresources.apply_dpi - -local builder = require('ui.notifs.notif-center.build-notifbox.notifbox-ui-elements') -local notifbox_core = require('ui.notifs.notif-center.build-notifbox') - -local notifbox_layout = notifbox_core.notifbox_layout -local remove_notifbox_empty = notifbox_core.remove_notifbox_empty -local reset_notifbox_layout = notifbox_core.reset_notifbox_layout - -local return_date_time = function(format) - return os.date(format) -end - -local parse_to_seconds = function(time) - local hourInSec = tonumber(string.sub(time, 1, 2)) * 3600 - local minInSec = tonumber(string.sub(time, 4, 5)) * 60 - local getSec = tonumber(string.sub(time, 7, 8)) - return (hourInSec + minInSec + getSec) -end - -notifbox_box = function(notif, icon, title, message, app, bgcolor) - - local time_of_pop = return_date_time('%H:%M:%S') - local exact_time = return_date_time('%I:%M %p') - local exact_date_time = return_date_time('%b %d, %I:%M %p') - - local notifbox_timepop = wibox.widget { - id = 'time_pop', - markup = nil, - font = beautiful.font_name .. 'medium 10', - align = 'left', - valign = 'center', - visible = true, - widget = wibox.widget.textbox - } - - local notifbox_dismiss = builder.notifbox_dismiss() - - local time_of_popup = gears.timer { - timeout = 60, - call_now = true, - autostart = true, - callback = function() - - local time_difference = nil - - time_difference = parse_to_seconds(return_date_time('%H:%M:%S')) - parse_to_seconds(time_of_pop) - time_difference = tonumber(time_difference) - - if time_difference < 60 then - notifbox_timepop:set_markup('now') - - elseif time_difference >= 60 and time_difference < 3600 then - local time_in_minutes = math.floor(time_difference / 60) - notifbox_timepop:set_markup(time_in_minutes .. 'm ago') - - elseif time_difference >= 3600 and time_difference < 86400 then - notifbox_timepop:set_markup(exact_time) - - elseif time_difference >= 86400 then - notifbox_timepop:set_markup(exact_date_time) - return false - - end - - collectgarbage('collect') - end - } - - local notifbox_template = wibox.widget { - id = 'notifbox_template', - expand = 'none', - { - { - layout = wibox.layout.fixed.vertical, - spacing = dpi(5), - { - expand = 'none', - layout = wibox.layout.align.horizontal, - { - layout = wibox.layout.fixed.horizontal, - spacing = dpi(5), - builder.notifbox_icon(icon), - builder.notifbox_appname(app), - }, - nil, - { - notifbox_timepop, - notifbox_dismiss, - layout = wibox.layout.fixed.horizontal - } - }, - { - layout = wibox.layout.fixed.vertical, - spacing = dpi(5), - { - builder.notifbox_title(title), - builder.notifbox_message(message), - layout = wibox.layout.fixed.vertical - }, - builder.notifbox_actions(notif), - }, - - }, - margins = dpi(10), - widget = wibox.container.margin - }, - bg = bgcolor, - shape = function(cr, width, height) - gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.notif_center_box_radius) - end, - widget = wibox.container.background, - } - - -- Put the generated template to a container - local notifbox = wibox.widget { - notifbox_template, - shape = function(cr, width, height) - gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.notif_center_box_radius) - end, - widget = wibox.container.background - } - - -- Delete notification box - local notifbox_delete = function() - notifbox_layout:remove_widgets(notifbox, true) - end - - -- Delete notifbox on LMB - notifbox_dismiss:buttons( - awful.util.table.join( - awful.button( - {}, - 1, - function() - if #notifbox_layout.children == 1 then - reset_notifbox_layout() - else - notifbox_delete() - end - collectgarbage('collect') - end - ) - ) - ) - - -- Add hover, and mouse leave events - notifbox_template:connect_signal( - 'mouse::enter', - function() - notifbox.bg = beautiful.xcolor8 - notifbox_timepop.visible = false - notifbox_dismiss.visible = true - end - ) - - notifbox_template:connect_signal( - 'mouse::leave', - function() - notifbox.bg = beautiful.tranparent - notifbox_timepop.visible = true - notifbox_dismiss.visible = false - end - ) - - collectgarbage('collect') - - return notifbox -end - - -return notifbox_box \ No newline at end of file diff --git a/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-geometry.lua b/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-geometry.lua deleted file mode 100644 index 433f5a3..0000000 --- a/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-geometry.lua +++ /dev/null @@ -1,30 +0,0 @@ -local wibox = require('wibox') -local awful = require('awful') -local naughty = require('naughty') - -local find_widget_in_wibox = function(wb, widget) - local function find_widget_in_hierarchy(h, widget) - if h:get_widget() == widget then - return h - end - local result - - for _, ch in ipairs(h:get_children()) do - result = result or find_widget_in_hierarchy(ch, widget) - end - return result - end - local h = wb._drawable._widget_hierarchy - return h and find_widget_in_hierarchy(h, widget) -end - - -local focused = awful.screen.focused() -local h = find_widget_in_wibox(focused.top_panel, focused.music) -local x, y, width, height = h:get_matrix_to_device():transform_rectangle(0, 0, h:get_size()) --- local geo = focused.mywibox:geometry() --- x, y = x + geo.x, y + geo.y --- print(string.format("The widget is inside of the rectangle (%d, %d, %d, %d) on the screen", x, y, width, height) - - -naughty.notification({message=tostring(height)}) \ No newline at end of file diff --git a/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-scroller.lua b/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-scroller.lua deleted file mode 100644 index f05d323..0000000 --- a/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-scroller.lua +++ /dev/null @@ -1,37 +0,0 @@ -local awful = require('awful') -local gears = require('gears') - -local add_button_event = function(widget) - - widget:buttons( - gears.table.join( - awful.button( - {}, - 4, - nil, - function() - if #widget.children == 1 then - return - end - widget:insert(1, widget.children[#widget.children]) - widget:remove(#widget.children) - end - ), - awful.button( - {}, - 5, - nil, - function() - if #widget.children == 1 then - return - end - widget:insert(#widget.children + 1, widget.children[1]) - widget:remove(1) - end - ) - ) - ) - -end - -return add_button_event \ No newline at end of file diff --git a/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-ui-elements.lua b/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-ui-elements.lua deleted file mode 100644 index 39f96f8..0000000 --- a/config/awesome/ui/notifs/notif-center/build-notifbox/notifbox-ui-elements.lua +++ /dev/null @@ -1,135 +0,0 @@ -local wibox = require('wibox') -local beautiful = require('beautiful') -local naughty = require('naughty') -local gears = require('gears') - -local dpi = beautiful.xresources.apply_dpi -local helpers = require('helpers') - -local button_container = require('ui.widgets.button') - -local ui_notif_builder = {} - --- Notification icon container -ui_notif_builder.notifbox_icon = function(ico_image) - local noti_icon = wibox.widget { - { - id = 'icon', - resize = true, - forced_height = dpi(25), - forced_width = dpi(25), - widget = wibox.widget.imagebox - }, - layout = wibox.layout.fixed.horizontal - } - noti_icon.icon:set_image(ico_image) - return noti_icon -end - --- Notification title container -ui_notif_builder.notifbox_title = function(title) - return wibox.widget { - markup = title, - font = beautiful.font_name .. 'Bold 12', - align = 'left', - valign = 'center', - widget = wibox.widget.textbox - } -end - --- Notification message container -ui_notif_builder.notifbox_message = function(msg) - return wibox.widget { - markup = msg, - font = beautiful.font_name .. 'medium 10', - align = 'left', - valign = 'center', - widget = wibox.widget.textbox - } -end - --- Notification app name container -ui_notif_builder.notifbox_appname = function(app) - return wibox.widget { - markup = app, - font = beautiful.font_name .. 'Bold 12', - align = 'left', - valign = 'center', - widget = wibox.widget.textbox - } -end - --- Notification actions container -ui_notif_builder.notifbox_actions = function(n) - actions_template = wibox.widget { - notification = n, - base_layout = wibox.widget { - spacing = dpi(0), - layout = wibox.layout.flex.horizontal - }, - widget_template = { - { - { - { - { - id = 'text_role', - font = beautiful.font_name .. 'medium 10', - widget = wibox.widget.textbox - }, - widget = wibox.container.place - }, - widget = button_container - }, - bg = beautiful.lighter_bg, - shape = gears.shape.rounded_rect, - forced_height = dpi(30), - widget = wibox.container.background - }, - margins = dpi(4), - widget = wibox.container.margin - }, - style = { underline_normal = false, underline_selected = true }, - widget = naughty.list.actions, - } - - return actions_template -end - - --- Notification dismiss button -ui_notif_builder.notifbox_dismiss = function() - - local dismiss_icon = wibox.widget { - { - id = 'dismiss_icon', - markup = helpers.colorize_text("", beautiful.xcolor1), - font = beautiful.icon_font_name .. "Round 10", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - layout = wibox.layout.fixed.horizontal - } - - local dismiss_button = wibox.widget { - { - dismiss_icon, - margins = dpi(5), - widget = wibox.container.margin - }, - widget = button_container - } - - local notifbox_dismiss = wibox.widget { - dismiss_button, - visible = false, - bg = beautiful.lighter_bg, - shape = gears.shape.circle, - widget = wibox.container.background - } - - return notifbox_dismiss -end - - -return ui_notif_builder \ No newline at end of file diff --git a/config/awesome/ui/notifs/notif-center/clear-all/init.lua b/config/awesome/ui/notifs/notif-center/clear-all/init.lua deleted file mode 100644 index eb4317e..0000000 --- a/config/awesome/ui/notifs/notif-center/clear-all/init.lua +++ /dev/null @@ -1,58 +0,0 @@ -local awful = require('awful') -local wibox = require('wibox') -local gears = require('gears') -local beautiful = require('beautiful') - -local dpi = beautiful.xresources.apply_dpi -local button_container = require('ui.widgets.button') - -local notifbox_core = require('ui.notifs.notif-center.build-notifbox') -local reset_notifbox_layout = notifbox_core.reset_notifbox_layout - -local clear_all_icon = wibox.widget { - { - markup = "", - font = beautiful.icon_font_name .. "Round 16", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - layout = wibox.layout.fixed.horizontal -} - -local clear_all_button = wibox.widget { - { - clear_all_icon, - margins = dpi(7), - widget = wibox.container.margin - }, - widget = button_container -} - -clear_all_button:buttons( - gears.table.join( - awful.button( - {}, - 1, - nil, - function() - reset_notifbox_layout() - end - ) - ) -) - -local clear_all_button_wrapped = wibox.widget { - nil, - { - clear_all_button, - bg = beautiful.xcolor0, - shape = gears.shape.circle, - widget = wibox.container.background - }, - nil, - expand = 'none', - layout = wibox.layout.align.vertical -} - -return clear_all_button_wrapped \ No newline at end of file diff --git a/config/awesome/ui/notifs/notif-center/dont-disturb/init.lua b/config/awesome/ui/notifs/notif-center/dont-disturb/init.lua deleted file mode 100644 index 314799c..0000000 --- a/config/awesome/ui/notifs/notif-center/dont-disturb/init.lua +++ /dev/null @@ -1,120 +0,0 @@ -local awful = require('awful') -local naughty = require('naughty') -local wibox = require('wibox') -local gears = require('gears') -local beautiful = require('beautiful') - -local dpi = beautiful.xresources.apply_dpi -local button_container = require('ui.widgets.button') - -local config_dir = gears.filesystem.get_configuration_dir() -local widget_dir = config_dir .. 'ui/notifs/notif-center/dont-disturb/' - -_G.dont_disturb = false - -local dont_disturb_icon = wibox.widget { - { - id = 'icon', - markup = "", - font = beautiful.icon_font_name .. "Round 16", - align = "center", - valign = "center", - widget = wibox.widget.textbox - }, - layout = wibox.layout.fixed.horizontal -} - -local function update_icon() - - local widget_icon_name = nil - local dd_icon = dont_disturb_icon.icon - - if dont_disturb then - widget_icon_name = 'toggled-on' - dd_icon:set_markup_silently("") - else - widget_icon_name = 'toggled-off' - dd_icon:set_markup_silently("") - end -end - -local check_disturb_status = function() - - awful.spawn.easy_async_with_shell( - 'cat ' .. widget_dir .. 'disturb_status', - function(stdout) - - local status = stdout - - if status:match('true') then - dont_disturb = true - elseif status:match('false') then - dont_disturb = false - else - dont_disturb = false - awful.spawn.with_shell('echo "false" > ' .. widget_dir .. 'disturb_status') - end - - update_icon() - end - ) -end - -check_disturb_status() - -local toggle_disturb = function() - if dont_disturb then - dont_disturb = false - else - dont_disturb = true - end - awful.spawn.with_shell('echo "' .. tostring(dont_disturb) .. '" > ' .. widget_dir .. 'disturb_status') - update_icon() -end - -local dont_disturb_button = wibox.widget { - { - dont_disturb_icon, - margins = dpi(7), - widget = wibox.container.margin - }, - widget = button_container -} - -dont_disturb_button:buttons( - gears.table.join( - awful.button( - {}, - 1, - nil, - function() - toggle_disturb() - end - ) - ) -) - -local dont_disturb_wrapped = wibox.widget { - nil, - { - dont_disturb_button, - bg = beautiful.xcolor0, - shape = gears.shape.circle, - widget = wibox.container.background - }, - nil, - expand = 'none', - layout = wibox.layout.align.vertical -} - --- Create a notification sound -naughty.connect_signal( - 'request::display', - function(n) - if not dont_disturb then - awful.spawn.with_shell('canberra-gtk-play -i message') - end - end -) - -return dont_disturb_wrapped \ No newline at end of file diff --git a/config/awesome/ui/notifs/notif-center/init.lua b/config/awesome/ui/notifs/notif-center/init.lua deleted file mode 100644 index babb4c5..0000000 --- a/config/awesome/ui/notifs/notif-center/init.lua +++ /dev/null @@ -1,45 +0,0 @@ -local wibox = require('wibox') -local beautiful = require('beautiful') -local dpi = require('beautiful').xresources.apply_dpi - --- Notification Center -------------------------- - - --- header -local notif_header = wibox.widget { - text = 'Notification Center', - font = beautiful.font_name .. 'Bold 14', - align = 'left', - valign = 'center', - widget = wibox.widget.textbox -} - --- build notif-center -local notif_center = function(s) - - s.dont_disturb = require('ui.notifs.notif-center.dont-disturb') - s.clear_all = require('ui.notifs.notif-center.clear-all') - s.notifbox_layout = require('ui.notifs.notif-center.build-notifbox').notifbox_layout - - return wibox.widget { - expand = 'none', - layout = wibox.layout.fixed.vertical, - spacing = dpi(10), - { - expand = 'none', - layout = wibox.layout.align.horizontal, - notif_header, - nil, - { - layout = wibox.layout.fixed.horizontal, - spacing = dpi(5), - s.dont_disturb, - s.clear_all - }, - }, - s.notifbox_layout - } -end - -return notif_center \ No newline at end of file diff --git a/config/awesome/ui/notifs/popup.lua b/config/awesome/ui/notifs/popup.lua deleted file mode 100644 index 8ee03bd..0000000 --- a/config/awesome/ui/notifs/popup.lua +++ /dev/null @@ -1,200 +0,0 @@ -local gears = require("gears") -local awful = require("awful") -local beautiful = require("beautiful") -local wibox = require("wibox") -local helpers = require("helpers") - --- Pop Up Notification ------------- - -local pop_icon = wibox.widget({ - forced_height = dpi(100), - forced_width = dpi(100), - font = beautiful.icon_font_name .. "80", - align = "center", - valign = "center", - widget = wibox.widget.textbox(), -}) - -local pop_bar = wibox.widget({ - max_value = 100, - value = 0, - background_color = beautiful.pop_bar_bg, - color = beautiful.bg_accent, - shape = gears.shape.rounded_bar, - bar_shape = gears.shape.rounded_bar, - forced_height = dpi(25), - widget = wibox.widget.progressbar, -}) - -local pop = wibox({ - type = "dock", - screen = screen.primary, - height = beautiful.pop_size, - width = beautiful.pop_size, - shape = helpers.rrect(beautiful.pop_border_radius), - bg = beautiful.transparent, - ontop = true, - visible = false, -}) - -pop:setup({ - { - { - { - pop_icon, - layout = wibox.layout.fixed.vertical, - }, - nil, - pop_bar, - layout = wibox.layout.align.vertical, - }, - top = dpi(15), - bottom = dpi(30), - left = dpi(30), - right = dpi(30), - widget = wibox.container.margin, - }, - bg = beautiful.xbackground, - shape = helpers.rrect(beautiful.pop_border_radius), - widget = wibox.container.background, -}) -awful.placement.bottom(pop, { margins = { bottom = dpi(100) } }) - -local pop_timeout = gears.timer({ - timeout = 1.4, - autostart = true, - callback = function() - pop.visible = false - end, -}) - -local function toggle_pop() - if pop.visible then - pop_timeout:again() - else - pop.visible = true - pop_timeout:start() - end -end - -local vol_first_time = true -awesome.connect_signal("signal::volume", function(value, muted) - if vol_first_time then - vol_first_time = false - else - pop_icon.markup = helpers.colorize_text("󰕾", beautiful.accent) - pop_bar.value = value - - if muted then - pop_icon.markup = helpers.colorize_text("󰖁", beautiful.xcolor8) - pop_bar.color = beautiful.xcolor8 - else - pop_bar.color = beautiful.accent - end - - toggle_pop() - end -end) - -awesome.connect_signal("signal::brightness", function(value) - pop_icon.markup = helpers.colorize_text("󰖨", beautiful.accent) - pop_bar.value = value - pop_bar.color = beautiful.accent - - toggle_pop() -end) - --- Layout list ------------------ - -local layout_list = 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, - }, -}) - -local layout_popup = awful.popup({ - widget = wibox.widget({ - { layout_list, 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", -}) - -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(layout_list.layouts, layout_list.current_layout, -1), nil) - end, - }, - { - { modkey }, - " ", - function() - awful.layout.set(gears.table.iterate_value(layout_list.layouts, layout_list.current_layout, 1), nil) - end, - }, - }, -}) diff --git a/config/awesome/ui/panels/bottom-panel/battery.lua b/config/awesome/ui/panels/bottom-panel/battery.lua new file mode 100755 index 0000000..3e49717 --- /dev/null +++ b/config/awesome/ui/panels/bottom-panel/battery.lua @@ -0,0 +1,127 @@ +local awful = require("awful") +local wibox = require("wibox") +local beautiful = require("beautiful") +local gears = require("gears") +local apps = require("configuration.apps") +local dpi = require("beautiful").xresources.apply_dpi +local helpers = require("helpers") +local wbutton = require("ui.widgets.button") + +return function() + local happy_color = beautiful.xcolor2 + local sad_color = beautiful.xcolor1 + local ok_color = beautiful.xcolor3 + local charging_color = beautiful.xcolor6 + + local charging_icon = wibox.widget({ + markup = helpers.ui.colorize_text("", beautiful.xforeground), + font = beautiful.icon_font .. "Round 14", + align = "center", + valign = "center", + widget = wibox.widget.textbox, + }) + + local battery_bar = wibox.widget({ + max_value = 100, + value = 50, + forced_width = dpi(30), + border_width = dpi(1), + paddings = dpi(2), + bar_shape = helpers.ui.rrect(2), + shape = helpers.ui.rrect(5), + color = beautiful.xforeground, + background_color = beautiful.transparent, + border_color = beautiful.xforeground, + widget = wibox.widget.progressbar, + }) + + local battery_decoration = wibox.widget({ + { + wibox.widget.textbox, + widget = wibox.container.background, + bg = beautiful.xforeground, + forced_width = dpi(8.2), + forced_height = dpi(8.2), + shape = function(cr, width, height) + gears.shape.pie(cr, width, height, 0, math.pi) + end, + }, + direction = "east", + widget = wibox.container.rotate(), + }) + + local battery = wibox.widget({ + charging_icon, + { + battery_bar, + battery_decoration, + layout = wibox.layout.fixed.horizontal, + spacing = dpi(-1.6), + }, + layout = wibox.layout.fixed.horizontal, + spacing = dpi(1), + }) + + local battery_percentage_text = wibox.widget({ + id = "percent_text", + text = "50%", + font = beautiful.font_name .. "Medium 12", + align = "center", + valign = "center", + widget = wibox.widget.textbox, + }) + + local battery_widget = wibox.widget({ + layout = wibox.layout.fixed.horizontal, + spacing = dpi(5), + { + battery, + top = dpi(1), + bottom = dpi(1), + widget = wibox.container.margin, + }, + battery_percentage_text, + }) + + local widget = wbutton.elevated.state({ + child = battery_widget, + normal_bg = beautiful.wibar_bg, + on_release = function() + awful.spawn(apps.default.power_manager, false) + end, + }) + + local last_value = 100 + awesome.connect_signal("signal::battery", function(value, state) + battery_bar.value = value + last_value = value + + battery_percentage_text:set_text(math.floor(value) .. "%") + + if charging_icon.visible then + battery_bar.color = charging_color + elseif value <= 15 then + battery_bar.color = sad_color + elseif value <= 30 then + battery_bar.color = ok_color + else + battery_bar.color = happy_color + end + + if state == 1 then + charging_icon.visible = true + battery_bar.color = charging_color + elseif last_value <= 15 then + charging_icon.visible = false + battery_bar.color = sad_color + elseif last_value <= 30 then + charging_icon.visible = false + battery_bar.color = ok_color + else + charging_icon.visible = false + battery_bar.color = happy_color + end + end) + + return widget +end diff --git a/config/awesome/ui/panels/bottom-panel/clock.lua b/config/awesome/ui/panels/bottom-panel/clock.lua new file mode 100755 index 0000000..bda1586 --- /dev/null +++ b/config/awesome/ui/panels/bottom-panel/clock.lua @@ -0,0 +1,31 @@ +local wibox = require("wibox") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local helpers = require("helpers") +local wbutton = require("ui.widgets.button") + +return function(s) + local accent_color = beautiful.xforeground + local clock = wibox.widget({ + widget = wibox.widget.textclock, + format = "%a %b %e %l:%M %p", + align = "center", + valign = "center", + font = beautiful.font_name .. "Medium 12", + }) + + clock.markup = helpers.ui.colorize_text(clock.text, accent_color) + clock:connect_signal("widget::redraw_needed", function() + clock.markup = helpers.ui.colorize_text(clock.text, accent_color) + end) + + local widget = wbutton.elevated.state({ + child = clock, + normal_bg = beautiful.wibar_bg, + on_release = function() + awesome.emit_signal("info_panel::toggle", s) + end, + }) + + return widget +end diff --git a/config/awesome/ui/panels/bottom-panel/init.lua b/config/awesome/ui/panels/bottom-panel/init.lua new file mode 100755 index 0000000..dc4b58f --- /dev/null +++ b/config/awesome/ui/panels/bottom-panel/init.lua @@ -0,0 +1,305 @@ +local awful = require("awful") +local gears = require("gears") +local wibox = require("wibox") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local helpers = require("helpers") +local widgets = require("ui.widgets") +local wbutton = require("ui.widgets.button") +local animation = require("modules.animation") + +return function(s) + --- Widgets + --- ~~~~~~~~~~ + s.clock = require("ui.panels.bottom-panel.clock")(s) + ---s.battery = require("ui.panels.bottom-panel.battery")() + s.network = require("ui.panels.bottom-panel.network")() + + --- Animated tag list + --- ~~~~~~~~~~~~~~~~~~~~ + + --- Taglist buttons + local modkey = "Mod4" + local taglist_buttons = gears.table.join( + awful.button({}, 1, function(t) + t:view_only() + end), + awful.button({ modkey }, 1, function(t) + if client.focus then + client.focus:move_to_tag(t) + end + end), + awful.button({}, 3, awful.tag.viewtoggle), + awful.button({ modkey }, 3, function(t) + if client.focus then + client.focus:toggle_tag(t) + end + end), + awful.button({}, 4, function(t) + awful.tag.viewnext(t.screen) + end), + awful.button({}, 5, function(t) + awful.tag.viewprev(t.screen) + end) + ) + + local function tag_list(s) + local taglist = awful.widget.taglist({ + screen = s, + filter = awful.widget.taglist.filter.all, + layout = { layout = wibox.layout.fixed.horizontal }, + widget_template = { + widget = wibox.container.margin, + forced_width = dpi(40), + forced_height = dpi(40), + create_callback = function(self, c3, _) + local indicator = wibox.widget({ + widget = wibox.container.place, + valign = "center", + { + widget = wibox.container.background, + forced_height = dpi(8), + shape = gears.shape.rounded_bar, + }, + }) + + self.indicator_animation = animation:new({ + duration = 0.125, + easing = animation.easing.linear, + update = function(self, pos) + indicator.children[1].forced_width = pos + end, + }) + + self:set_widget(indicator) + + if c3.selected then + self.widget.children[1].bg = beautiful.accent + self.indicator_animation:set(dpi(32)) + elseif #c3:clients() == 0 then + self.widget.children[1].bg = beautiful.xcolor8 + self.indicator_animation:set(dpi(8)) + else + self.widget.children[1].bg = beautiful.accent + self.indicator_animation:set(dpi(16)) + end + + --- Tag preview + self:connect_signal("mouse::enter", function() + if #c3:clients() > 0 then + awesome.emit_signal("bling::tag_preview::update", c3) + awesome.emit_signal("bling::tag_preview::visibility", s, true) + end + end) + + self:connect_signal("mouse::leave", function() + awesome.emit_signal("bling::tag_preview::visibility", s, false) + end) + end, + update_callback = function(self, c3, _) + if c3.selected then + self.widget.children[1].bg = beautiful.accent + self.indicator_animation:set(dpi(32)) + elseif #c3:clients() == 0 then + self.widget.children[1].bg = beautiful.xcolor8 + self.indicator_animation:set(dpi(8)) + else + self.widget.children[1].bg = beautiful.accent + self.indicator_animation:set(dpi(16)) + end + end, + }, + buttons = taglist_buttons, + }) + + local widget = widgets.button.elevated.state({ + normal_bg = beautiful.widget_bg, + normal_shape = gears.shape.rounded_bar, + child = { + taglist, + margins = { left = dpi(10), right = dpi(10) }, + widget = wibox.container.margin, + }, + on_release = function() + awesome.emit_signal("central_panel::toggle", s) + end, + }) + + return wibox.widget({ + widget, + margins = dpi(5), + widget = wibox.container.margin, + }) + end + + --- Systray + --- ~~~~~~~~~~ + local function system_tray() + local mysystray = wibox.widget.systray() + mysystray.base_size = beautiful.systray_icon_size + + local widget = wibox.widget({ + widget = wibox.container.constraint, + strategy = "max", + width = dpi(0), + { + widget = wibox.container.margin, + margins = dpi(10), + mysystray, + }, + }) + + local system_tray_animation = animation:new({ + easing = animation.easing.linear, + duration = 0.125, + update = function(self, pos) + widget.width = pos + end, + }) + + local arrow = wbutton.text.state({ + text_normal_bg = beautiful.accent, + normal_bg = beautiful.wibar_bg, + font = beautiful.icon_font .. "Round ", + size = 18, + text = "", + on_turn_on = function(self) + system_tray_animation:set(400) + self:set_text("") + end, + on_turn_off = function(self) + system_tray_animation:set(0) + self:set_text("") + end, + }) + + return wibox.widget({ + layout = wibox.layout.fixed.horizontal, + arrow, + widget, + }) + end + + --- Notif panel + --- ~~~~~~~~~~~~~~ + local function notif_panel() + local icon = wibox.widget({ + markup = helpers.ui.colorize_text("", beautiful.accent), + align = "center", + valign = "center", + font = beautiful.icon_font .. "Round 18", + widget = wibox.widget.textbox, + }) + + local widget = wbutton.elevated.state({ + child = icon, + normal_bg = beautiful.wibar_bg, + on_release = function() + awesome.emit_signal("notification_panel::toggle", s) + end, + }) + + return widget + end + + --- Layoutbox + --- ~~~~~~~~~~~~ + local function layoutbox() + local layoutbox_buttons = gears.table.join( + --- Left click + awful.button({}, 1, function(c) + awful.layout.inc(1) + end), + + --- Right click + awful.button({}, 3, function(c) + awful.layout.inc(-1) + end), + + --- Scrolling + awful.button({}, 4, function() + awful.layout.inc(-1) + end), + awful.button({}, 5, function() + awful.layout.inc(1) + end) + ) + + s.mylayoutbox = awful.widget.layoutbox() + s.mylayoutbox:buttons(layoutbox_buttons) + + local widget = wbutton.elevated.state({ + child = s.mylayoutbox, + normal_bg = beautiful.wibar_bg, + }) + + return widget + end + + --- Create the bottom_panel + --- ~~~~~~~~~~~~~~~~~~~~~~~~~~ + s.bottom_panel = awful.popup({ + screen = s, + type = "dock", + maximum_height = beautiful.wibar_height, + minimum_width = s.geometry.width, + maximum_width = s.geometry.width, + placement = function(c) + awful.placement.bottom(c) + end, + bg = beautiful.transparent, + widget = { + { + { + layout = wibox.layout.align.horizontal, + expand = "none", + s.clock, + ---s.stats, + tag_list(s), + { + system_tray(), + + s.network, + notif_panel(), + layoutbox(), + layout = wibox.layout.fixed.horizontal, + }, + }, + left = dpi(10), + right = dpi(10), + widget = wibox.container.margin, + }, + bg = beautiful.wibar_bg, + widget = wibox.container.background, + }, + }) + + s.bottom_panel:struts({ + bottom = s.bottom_panel.maximum_height, + }) + + --- Remove bottom_panel on full screen + local function remove_bottom_panel(c) + if c.fullscreen or c.maximized then + c.screen.bottom_panel.visible = false + else + c.screen.bottom_panel.visible = true + end + end + + --- Remove bottom_panel on full screen + local function add_bottom_panel(c) + if c.fullscreen or c.maximized then + c.screen.bottom_panel.visible = true + end + end + + --- Hide bar when a splash widget is visible + awesome.connect_signal("widgets::splash::visibility", function(vis) + screen.primary.bottom_panel.visible = not vis + end) + + client.connect_signal("property::fullscreen", remove_bottom_panel) + client.connect_signal("request::unmanage", add_bottom_panel) +end diff --git a/config/awesome/ui/panels/bottom-panel/network.lua b/config/awesome/ui/panels/bottom-panel/network.lua new file mode 100755 index 0000000..54a9943 --- /dev/null +++ b/config/awesome/ui/panels/bottom-panel/network.lua @@ -0,0 +1,68 @@ +local awful = require("awful") +local watch = awful.widget.watch +local wibox = require("wibox") +local gears = require("gears") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local apps = require("configuration.apps") +local wbutton = require("ui.widgets.button") + +return function() + local network = wibox.widget({ + { + id = "icon", + text = "", + align = "center", + valign = "center", + font = beautiful.icon_font .. "Round 18", + widget = wibox.widget.textbox, + }, + layout = wibox.layout.align.horizontal, + }) + + local widget = wbutton.elevated.state({ + child = network, + normal_bg = beautiful.wibar_bg, + on_release = function() + awful.spawn(apps.default.network_manager, false) + end, + }) + + watch( + [[sh -c " + nmcli g | tail -n 1 | awk '{ print $1 }' + "]], + 5, + function(_, stdout) + local net_ssid = stdout + net_ssid = string.gsub(net_ssid, "^%s*(.-)%s*$", "%1") + + if not net_ssid:match("disconnected") then + local getstrength = [[ + awk '/^\s*w/ { print int($3 * 100 / 70) }' /proc/net/wireless + ]] + awful.spawn.easy_async_with_shell(getstrength, function(stdout) + if not tonumber(stdout) then + return + end + local strength = tonumber(stdout) + if strength <= 20 then + network.icon:set_text("") + elseif strength <= 40 then + network.icon:set_text("") + elseif strength <= 60 then + network.icon:set_text("") + elseif strength <= 80 then + network.icon:set_text("") + else + network.icon:set_text("") + end + end) + else + network.icon:set_text("") + end + end + ) + + return widget +end diff --git a/config/awesome/ui/panels/bottom-panel/stats.lua b/config/awesome/ui/panels/bottom-panel/stats.lua new file mode 100755 index 0000000..a2862c5 --- /dev/null +++ b/config/awesome/ui/panels/bottom-panel/stats.lua @@ -0,0 +1,34 @@ +local awful = require("awful") +local watch = awful.widget.watch +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") +local icons = require("icons") + + + +local function ram() + local stats = widget(icons.ram) + + watch('bash -c "free | grep -z Mem.*Swap.*"', 10, function(_, stdout) + local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap = stdout:match( + "(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)" + ) + stats:set_value(used / total * 100) + collectgarbage("collect") + end) + + return stats +end + +return function(s) + local accent_color = beautiful.xforeground + local ram = wibox.widget({ + widget = wibox.widget.textbox + align = "center", + valign = "center", + font = beautiful.font_name .. "Medium 12", + text = ram() + }) \ No newline at end of file diff --git a/config/awesome/ui/panels/central-panel/init.lua b/config/awesome/ui/panels/central-panel/init.lua new file mode 100755 index 0000000..b684b07 --- /dev/null +++ b/config/awesome/ui/panels/central-panel/init.lua @@ -0,0 +1,193 @@ +local awful = require("awful") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") +local gears = require("gears") +local icons = require("icons") + +return function(s) + s.awesomewm = wibox.widget({ + { + image = icons.awesome_logo, + resize = true, + halign = "center", + valign = "center", + widget = wibox.widget.imagebox, + }, + strategy = "exact", + height = dpi(50), + widget = wibox.container.constraint, + }) + + --- Header + local function header() + local dashboard_text = wibox.widget({ + markup = helpers.ui.colorize_text("Dashboard -", "#666c79"), + font = beautiful.font_name .. "Black 14", + valign = "center", + widget = wibox.widget.textbox, + }) + + local function search_box() + local search_icon = wibox.widget({ + font = "icomoon bold 12", + align = "center", + valign = "center", + widget = wibox.widget.textbox(), + }) + + local reset_search_icon = function() + search_icon.markup = helpers.ui.colorize_text("", beautiful.accent) + end + reset_search_icon() + + local search_text = wibox.widget({ + --- markup = helpers.ui.colorize_text("Search", beautiful.xcolor8), + align = "center", + valign = "center", + font = beautiful.font, + widget = wibox.widget.textbox(), + }) + + local search = wibox.widget({ + { + { + search_icon, + { + search_text, + bottom = dpi(2), + widget = wibox.container.margin, + }, + layout = wibox.layout.fixed.horizontal, + }, + left = dpi(15), + widget = wibox.container.margin, + }, + forced_height = dpi(35), + forced_width = dpi(420), + shape = gears.shape.rounded_bar, + bg = beautiful.widget_bg, + widget = wibox.container.background(), + }) + + local function generate_prompt_icon(icon, color) + return "" .. icon .. " " + end + + local function activate_prompt(action) + search_icon.visible = false + local prompt + if action == "run" then + prompt = generate_prompt_icon("", beautiful.accent) + elseif action == "web_search" then + prompt = generate_prompt_icon("", beautiful.accent) + end + helpers.misc.prompt(action, search_text, prompt, function() + search_icon.visible = true + end) + end + + search:buttons(gears.table.join( + awful.button({}, 1, function() + activate_prompt("run") + end), + awful.button({}, 3, function() + activate_prompt("web_search") + end) + )) + + return search + end + + local widget = wibox.widget({ + { + dashboard_text, + nil, + search_box(), + layout = wibox.layout.align.horizontal, + }, + margins = dpi(10), + widget = wibox.container.margin, + }) + + return widget + end + + s.stats = require("ui.panels.central-panel.stats") + s.user_profile = require("ui.panels.central-panel.user-profile") + s.quick_settings = require("ui.panels.central-panel.quick-settings") + s.slider = require("ui.panels.central-panel.slider") + s.music_player = require("ui.panels.central-panel.music-player") + + s.central_panel = awful.popup({ + type = "dock", + screen = s, + minimum_height = dpi(700), + maximum_height = dpi(700), + minimum_width = dpi(700), + maximum_width = dpi(700), + bg = beautiful.transparent, + ontop = true, + visible = false, + placement = function(w) + awful.placement.bottom(w, { + margins = { top = dpi(5), bottom = beautiful.wibar_height + dpi(5), left = dpi(5), right = dpi(5) }, + }) + end, + widget = { + { + { + { + s.awesomewm, + halign = "center", + valign = "center", + widget = wibox.container.place, + }, + margins = dpi(20), + widget = wibox.container.margin, + }, + { + { + { + header(), + nil, + { + { + s.user_profile, + s.quick_settings, + s.slider, + layout = wibox.layout.fixed.vertical, + }, + { + s.stats, + s.music_player, + layout = wibox.layout.fixed.vertical, + }, + layout = wibox.layout.align.horizontal, + }, + layout = wibox.layout.align.vertical, + }, + margins = dpi(10), + widget = wibox.container.margin, + }, + shape = helpers.ui.prrect(beautiful.border_radius * 2, true, true, false, false), + bg = beautiful.wibar_bg, + widget = wibox.container.background, + }, + layout = wibox.layout.align.vertical, + }, + bg = beautiful.widget_bg, + shape = helpers.ui.rrect(beautiful.border_radius), + widget = wibox.container.background, + }, + }) + + --- Toggle container visibility + awesome.connect_signal("central_panel::toggle", function(scr) + if scr == s then + s.central_panel.visible = not s.central_panel.visible + end + end) +end diff --git a/config/awesome/ui/panels/central-panel/music-player.lua b/config/awesome/ui/panels/central-panel/music-player.lua new file mode 100755 index 0000000..3235f50 --- /dev/null +++ b/config/awesome/ui/panels/central-panel/music-player.lua @@ -0,0 +1,160 @@ +local gears = require("gears") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") +local widgets = require("ui.widgets") +local playerctl_daemon = require("signal.playerctl") + +---- Music Player +---- ~~~~~~~~~~~~ +local music_text = wibox.widget({ + font = beautiful.font_name .. "Medium 10", + valign = "center", + widget = wibox.widget.textbox, +}) + +local music_art = wibox.widget({ + image = beautiful.music, + resize = true, + widget = wibox.widget.imagebox, +}) + +local music_art_container = wibox.widget({ + music_art, + forced_height = dpi(120), + forced_width = dpi(120), + widget = wibox.container.background, +}) + +local filter_color = { + type = "linear", + from = { 0, 0 }, + to = { 0, 120 }, + stops = { { 0, beautiful.widget_bg .. "cc" }, { 1, beautiful.widget_bg } }, +} + +local music_art_filter = wibox.widget({ + { + bg = filter_color, + forced_height = dpi(120), + forced_width = dpi(120), + widget = wibox.container.background, + }, + direction = "east", + widget = wibox.container.rotate, +}) + +local music_title = wibox.widget({ + font = beautiful.font_name .. "Regular 14", + align = "center", + valign = "center", + widget = wibox.widget.textbox, +}) + +local music_artist = wibox.widget({ + font = beautiful.font_name .. "Bold 16", + align = "center", + valign = "center", + widget = wibox.widget.textbox, +}) + +local music = wibox.widget({ + { + { + { + music_art_container, + music_art_filter, + layout = wibox.layout.stack, + }, + { + { + { + music_text, + helpers.ui.vertical_pad(dpi(20)), + { + { + { + widget = wibox.container.scroll.horizontal, + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, + music_artist, + }, + { + widget = wibox.container.scroll.horizontal, + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, + music_title, + }, + layout = wibox.layout.fixed.vertical, + }, + halign = "center", + valign = "center", + widget = wibox.container.place, + }, + layout = wibox.layout.fixed.vertical, + }, + nil, + { + { + widgets.playerctl.previous(20, beautiful.xforeground, beautiful.transparent), + widgets.playerctl.play(beautiful.accent, beautiful.transparent), + widgets.playerctl.next(20, beautiful.xforeground, beautiful.transparent), + layout = wibox.layout.flex.horizontal, + }, + forced_height = dpi(70), + margins = dpi(10), + widget = wibox.container.margin, + }, + expand = "none", + layout = wibox.layout.align.vertical, + }, + top = dpi(9), + bottom = dpi(9), + left = dpi(10), + right = dpi(10), + widget = wibox.container.margin, + }, + layout = wibox.layout.stack, + }, + bg = beautiful.widget_bg, + shape = helpers.ui.rrect(beautiful.border_radius), + forced_width = dpi(200), + forced_height = dpi(200), + widget = wibox.container.background, + }, + margins = dpi(10), + color = "#FF000000", + widget = wibox.container.margin, +}) + +--- playerctl +--- ------------- +playerctl_daemon:connect_signal("metadata", function(_, title, artist, album_path, __, ___, ____) + if title == "" then + title = "Nothing Playing" + end + if artist == "" then + artist = "Nothing Playing" + end + if album_path == "" then + album_path = gears.filesystem.get_configuration_dir() .. "theme/assets/no_music.png" + end + + music_art:set_image(gears.surface.load_uncached(album_path)) + music_title:set_markup_silently(helpers.ui.colorize_text(title, beautiful.xforeground)) + music_artist:set_markup_silently(helpers.ui.colorize_text(artist, beautiful.accent)) +end) + +playerctl_daemon:connect_signal("playback_status", function(_, playing, __) + if playing then + music_text:set_markup_silently(helpers.ui.colorize_text("Now Playing", "#666c79")) + else + music_text:set_markup_silently(helpers.ui.colorize_text("Music", "#666c79")) + end +end) + +return music diff --git a/config/awesome/ui/notifs/notif-center/dont-disturb/disturb_status b/config/awesome/ui/panels/central-panel/quick-settings/airplane-mode/airplane_mode_status old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/ui/notifs/notif-center/dont-disturb/disturb_status rename to config/awesome/ui/panels/central-panel/quick-settings/airplane-mode/airplane_mode_status diff --git a/config/awesome/ui/widgets/airplane-mode/icons/airplane-mode-off.svg b/config/awesome/ui/panels/central-panel/quick-settings/airplane-mode/icons/airplane-mode-off.svg old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/ui/widgets/airplane-mode/icons/airplane-mode-off.svg rename to config/awesome/ui/panels/central-panel/quick-settings/airplane-mode/icons/airplane-mode-off.svg diff --git a/config/awesome/ui/widgets/airplane-mode/icons/airplane-mode.svg b/config/awesome/ui/panels/central-panel/quick-settings/airplane-mode/icons/airplane-mode.svg old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/ui/widgets/airplane-mode/icons/airplane-mode.svg rename to config/awesome/ui/panels/central-panel/quick-settings/airplane-mode/icons/airplane-mode.svg diff --git a/config/awesome/ui/panels/central-panel/quick-settings/airplane-mode/init.lua b/config/awesome/ui/panels/central-panel/quick-settings/airplane-mode/init.lua new file mode 100755 index 0000000..fcf9ddd --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/airplane-mode/init.lua @@ -0,0 +1,117 @@ +local awful = require("awful") +local gears = require("gears") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local config_dir = gears.filesystem.get_configuration_dir() +local widget_dir = config_dir .. "ui/panels/central-panel/quick-settings/airplane-mode/" +local widget_icon_dir = widget_dir .. "icons/" +local widgets = require("ui.widgets") + +local airplane_mode_state = false + +local function button(icon) + return widgets.button.text.state({ + forced_width = dpi(60), + forced_height = dpi(60), + normal_bg = beautiful.one_bg3, + normal_shape = gears.shape.circle, + on_normal_bg = beautiful.accent, + text_normal_bg = beautiful.accent, + text_on_normal_bg = beautiful.one_bg3, + font = beautiful.icon_font .. "Round ", + size = 17, + text = icon, + }) +end + +local widget = button("") + +local update_widget = function() + if airplane_mode_state then + widget:turn_on() + else + widget:turn_off() + end +end + +local check_airplane_mode_state = function() + local cmd = "cat " .. widget_dir .. "airplane_mode_status" + + awful.spawn.easy_async_with_shell(cmd, function(stdout) + local status = stdout + + if status:match("true") then + airplane_mode_state = true + elseif status:match("false") then + airplane_mode_state = false + else + airplane_mode_state = false + awful.spawn.easy_async_with_shell('echo "false" > ' .. widget_dir .. "airplane_mode", function(stdout) end) + end + update_widget() + end) +end + +check_airplane_mode_state() + +local airplane_off_cmd = [[ + + rfkill unblock wlan + + # Create an AwesomeWM Notification + awesome-client " + naughty = require('naughty') + naughty.notification({ + app_name = 'Network Manager', + title = 'Airplane mode disabled!', + message = 'Initializing network devices', + icon = ']] .. widget_icon_dir .. "airplane-mode-off" .. ".svg" .. [[' + }) + " + ]] .. "echo false > " .. widget_dir .. "airplane_mode_status" .. [[ +]] + +local airplane_on_cmd = [[ + + rfkill block wlan + + # Create an AwesomeWM Notification + awesome-client " + naughty = require('naughty') + naughty.notification({ + app_name = 'Network Manager', + title = 'Airplane mode enabled!', + message = 'Disabling radio devices', + icon = ']] .. widget_icon_dir .. "airplane-mode" .. ".svg" .. [[' + }) + " + ]] .. "echo true > " .. widget_dir .. "airplane_mode_status" .. [[ +]] + +local toggle_action = function() + if airplane_mode_state then + awful.spawn.easy_async_with_shell(airplane_off_cmd, function(stdout) + airplane_mode_state = false + update_widget() + end) + else + awful.spawn.easy_async_with_shell(airplane_on_cmd, function(stdout) + airplane_mode_state = true + update_widget() + end) + end +end + +widget:buttons(gears.table.join(awful.button({}, 1, nil, function() + toggle_action() +end))) + +gears.timer({ + timeout = 5, + autostart = true, + callback = function() + check_airplane_mode_state() + end, +}) + +return widget diff --git a/config/awesome/ui/panels/central-panel/quick-settings/blue-light.lua b/config/awesome/ui/panels/central-panel/quick-settings/blue-light.lua new file mode 100755 index 0000000..bfff352 --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/blue-light.lua @@ -0,0 +1,79 @@ +local awful = require("awful") +local gears = require("gears") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local widgets = require("ui.widgets") + +local blue_light_state = false + +local function button(icon) + return widgets.button.text.state({ + forced_width = dpi(60), + forced_height = dpi(60), + normal_bg = beautiful.one_bg3, + normal_shape = gears.shape.circle, + on_normal_bg = beautiful.accent, + text_normal_bg = beautiful.accent, + text_on_normal_bg = beautiful.one_bg3, + font = beautiful.icon_font .. "Round ", + size = 17, + text = icon, + }) +end + +local widget = button("") + +local update_widget = function() + if blue_light_state then + widget:turn_on() + else + widget:turn_off() + end +end + +local kill_state = function() + awful.spawn.easy_async_with_shell( + [[ + redshift -x + kill -9 $(pgrep redshift) + ]], + function(stdout) + stdout = tonumber(stdout) + if stdout then + blue_light_state = false + update_widget() + end + end + ) +end + +kill_state() + +local toggle_action = function() + awful.spawn.easy_async_with_shell( + [[ + if [ ! -z $(pgrep redshift) ]; + then + redshift -x && pkill redshift && killall redshift + echo 'OFF' + else + redshift -l 0:0 -t 4500:4500 -r &>/dev/null & + echo 'ON' + fi + ]], + function(stdout) + if stdout:match("ON") then + blue_light_state = true + else + blue_light_state = false + end + update_widget() + end + ) +end + +widget:buttons(gears.table.join(awful.button({}, 1, nil, function() + toggle_action() +end))) + +return widget diff --git a/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/icons/bluetooth-off.svg b/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/icons/bluetooth-off.svg new file mode 100755 index 0000000..f3e52ab --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/icons/bluetooth-off.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/icons/bluetooth.svg b/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/icons/bluetooth.svg new file mode 100755 index 0000000..32fbc3e --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/icons/bluetooth.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/icons/loading.svg b/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/icons/loading.svg new file mode 100755 index 0000000..cd7bc0e --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/icons/loading.svg @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/init.lua b/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/init.lua new file mode 100755 index 0000000..fa135e5 --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/bluetooth/init.lua @@ -0,0 +1,111 @@ +local awful = require("awful") +local watch = awful.widget.watch +local gears = require("gears") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local config_dir = gears.filesystem.get_configuration_dir() +local widget_dir = config_dir .. "ui/panels/central-panel/quick-settings/bluetooth/" +local widget_icon_dir = widget_dir .. "icons/" +local widgets = require("ui.widgets") + +local bluetooth_state = false + +local function button(icon) + return widgets.button.text.state({ + forced_width = dpi(60), + forced_height = dpi(60), + normal_bg = beautiful.one_bg3, + normal_shape = gears.shape.circle, + on_normal_bg = beautiful.accent, + text_normal_bg = beautiful.accent, + text_on_normal_bg = beautiful.one_bg3, + font = beautiful.icon_font .. "Round ", + size = 17, + text = icon, + }) +end + +local widget = button("") + +local update_widget = function() + if bluetooth_state then + widget:turn_on() + else + widget:turn_off() + end +end + +local check_bluetooth_state = function() + awful.spawn.easy_async_with_shell("rfkill list bluetooth", function(stdout) + if stdout:match("Soft blocked: yes") then + bluetooth_state = false + else + bluetooth_state = true + end + + update_widget() + end) +end + +check_bluetooth_state() + +local power_on_cmd = [[ + rfkill unblock bluetooth + + # Create an AwesomeWM Notification + awesome-client " + naughty = require('naughty') + naughty.notification({ + app_name = 'Bluetooth Manager', + title = 'System Notification', + message = 'Initializing bluetooth device...', + icon = ']] .. widget_icon_dir .. "loading" .. ".svg" .. [[' + }) + " + + # Add a delay here so we can enable the bluetooth + sleep 1 + + bluetoothctl power on +]] + +local power_off_cmd = [[ + bluetoothctl power off + rfkill block bluetooth + + # Create an AwesomeWM Notification + awesome-client " + naughty = require('naughty') + naughty.notification({ + app_name = 'Bluetooth Manager', + title = 'System Notification', + message = 'The bluetooth device has been disabled.', + icon = ']] .. widget_icon_dir .. "bluetooth-off" .. ".svg" .. [[' + }) + " +]] + +local toggle_action = function() + if bluetooth_state then + awful.spawn.easy_async_with_shell(power_off_cmd, function(stdout) + bluetooth_state = false + update_widget() + end) + else + awful.spawn.easy_async_with_shell(power_on_cmd, function(stdout) + bluetooth_state = true + update_widget() + end) + end +end + +widget:buttons(gears.table.join(awful.button({}, 1, nil, function() + toggle_action() +end))) + +watch("rfkill list bluetooth", 5, function(_, stdout) + check_bluetooth_state() + collectgarbage("collect") +end) + +return widget diff --git a/config/awesome/ui/widgets/airplane-mode/airplane_mode b/config/awesome/ui/panels/central-panel/quick-settings/dnd/dnd_status old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/ui/widgets/airplane-mode/airplane_mode rename to config/awesome/ui/panels/central-panel/quick-settings/dnd/dnd_status diff --git a/config/awesome/ui/panels/central-panel/quick-settings/dnd/init.lua b/config/awesome/ui/panels/central-panel/quick-settings/dnd/init.lua new file mode 100755 index 0000000..9ae47ac --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/dnd/init.lua @@ -0,0 +1,78 @@ +local awful = require("awful") +local gears = require("gears") +local naughty = require("naughty") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local config_dir = gears.filesystem.get_configuration_dir() +local widget_dir = config_dir .. "ui/panels/central-panel/quick-settings/dnd/" +local widgets = require("ui.widgets") + +_G.dnd_state = false + +local function button(icon) + return widgets.button.text.state({ + forced_width = dpi(60), + forced_height = dpi(60), + normal_bg = beautiful.one_bg3, + normal_shape = gears.shape.circle, + on_normal_bg = beautiful.accent, + text_normal_bg = beautiful.accent, + text_on_normal_bg = beautiful.one_bg3, + font = beautiful.icon_font .. "Round ", + size = 17, + text = icon, + }) +end + +local widget = button("") + +local update_widget = function() + if dnd_state then + widget:turn_on() + else + widget:turn_off() + end +end + +local check_dnd_status = function() + awful.spawn.easy_async_with_shell("cat " .. widget_dir .. "dnd_status", function(stdout) + local status = stdout + + if status:match("true") then + dnd_state = true + elseif status:match("false") then + dnd_state = false + else + dnd_state = false + awful.spawn.with_shell("echo 'false' > " .. widget_dir .. "dnd_status") + end + + update_widget() + end) +end + +check_dnd_status() + +local toggle_action = function() + if dnd_state then + dnd_state = false + else + dnd_state = true + end + awful.spawn.easy_async_with_shell("echo " .. tostring(dnd_state) .. " > " .. widget_dir .. "dnd_status", function() + update_widget() + end) +end + +widget:buttons(gears.table.join(awful.button({}, 1, nil, function() + toggle_action() +end))) + +--- Create a notification sound +naughty.connect_signal("request::display", function(n) + if not dnd_state then + awful.spawn("canberra-gtk-play -i bell", false) + end +end) + +return widget diff --git a/config/awesome/ui/panels/central-panel/quick-settings/floating-mode.lua b/config/awesome/ui/panels/central-panel/quick-settings/floating-mode.lua new file mode 100755 index 0000000..0d809e4 --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/floating-mode.lua @@ -0,0 +1,55 @@ +local awful = require("awful") +local gears = require("gears") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local widgets = require("ui.widgets") + +local floating_mode_state = false + +local function button(icon) + return widgets.button.text.state({ + forced_width = dpi(60), + forced_height = dpi(60), + normal_bg = beautiful.one_bg3, + normal_shape = gears.shape.circle, + on_normal_bg = beautiful.accent, + text_normal_bg = beautiful.accent, + text_on_normal_bg = beautiful.one_bg3, + font = "icomoon bold ", + size = 17, + text = icon, + }) +end + +local widget = button("") + +local update_widget = function() + if floating_mode_state then + widget:turn_on() + else + widget:turn_off() + end +end + +local toggle_action = function() + local tags = awful.screen.focused().tags + if not floating_mode_state then + for _, tag in ipairs(tags) do + awful.layout.set(awful.layout.suit.floating, tag) + end + floating_mode_state = true + update_widget() + else + for _, tag in ipairs(tags) do + awful.layout.set(awful.layout.suit.tile, tag) + end + floating_mode_state = false + update_widget() + end +end + +widget:buttons(gears.table.join(awful.button({}, 1, nil, function() + toggle_action() +end))) + +return widget diff --git a/config/awesome/ui/panels/central-panel/quick-settings/init.lua b/config/awesome/ui/panels/central-panel/quick-settings/init.lua new file mode 100755 index 0000000..583c915 --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/init.lua @@ -0,0 +1,72 @@ +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") + +local quick_settings_text = wibox.widget({ + font = beautiful.font_name .. "Medium 10", + markup = helpers.ui.colorize_text("Quick Settings", "#666c79"), + valign = "center", + widget = wibox.widget.textbox, +}) + +--- Buttons +--- ~~~~~~~ +local airplane_mode = require(... .. ".airplane-mode") +local bluetooth = require(... .. ".bluetooth") +local blue_light = require(... .. ".blue-light") +local dnd = require(... .. ".dnd") +local microphone = require(... .. ".microphone") +local floating_mode = require(... .. ".floating-mode") +local screenshot_area = require(... .. ".screenshot").area +local screenshot_full = require(... .. ".screenshot").full + +-- 4x4 grid of button +local buttons = wibox.widget({ + airplane_mode, + blue_light, + floating_mode, + screenshot_area, + bluetooth, + microphone, + dnd, + screenshot_full, + spacing = dpi(22), + forced_num_cols = 4, + forced_num_rows = 4, + layout = wibox.layout.grid, +}) + +local widget = wibox.widget({ + { + { + { + quick_settings_text, + helpers.ui.vertical_pad(dpi(20)), + { + buttons, + left = dpi(12), + right = dpi(12), + widget = wibox.container.margin, + }, + layout = wibox.layout.fixed.vertical, + }, + top = dpi(9), + bottom = dpi(9), + left = dpi(10), + right = dpi(10), + widget = wibox.container.margin, + }, + widget = wibox.container.background, + forced_height = dpi(210), + forced_width = dpi(350), + bg = beautiful.widget_bg, + shape = helpers.ui.rrect(beautiful.border_radius), + }, + margins = dpi(10), + color = "#FF000000", + widget = wibox.container.margin, +}) + +return widget diff --git a/config/awesome/ui/panels/central-panel/quick-settings/microphone.lua b/config/awesome/ui/panels/central-panel/quick-settings/microphone.lua new file mode 100755 index 0000000..0d5332f --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/microphone.lua @@ -0,0 +1,38 @@ +local awful = require("awful") +local watch = awful.widget.watch +local gears = require("gears") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local widgets = require("ui.widgets") + +local function button(icon) + return widgets.button.text.state({ + forced_width = dpi(60), + forced_height = dpi(60), + normal_bg = beautiful.one_bg3, + normal_shape = gears.shape.circle, + on_normal_bg = beautiful.accent, + text_normal_bg = beautiful.accent, + text_on_normal_bg = beautiful.one_bg3, + font = beautiful.icon_font .. "Round ", + size = 17, + text = icon, + }) +end + +local widget = button("") + +widget:buttons(gears.table.join(awful.button({}, 1, nil, function() + awful.spawn.with_shell("pamixer --default-source -t") +end))) + +watch("pamixer --default-source --get-mute", 5, function(_, stdout) + if stdout:match("true") then + widget:turn_off() + else + widget:turn_on() + end + collectgarbage("collect") +end, widget) + +return widget diff --git a/config/awesome/ui/panels/central-panel/quick-settings/screenshot.lua b/config/awesome/ui/panels/central-panel/quick-settings/screenshot.lua new file mode 100755 index 0000000..fe61d36 --- /dev/null +++ b/config/awesome/ui/panels/central-panel/quick-settings/screenshot.lua @@ -0,0 +1,40 @@ +local awful = require("awful") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local gears = require("gears") +local widgets = require("ui.widgets") +local apps = require("configuration.apps") + +local screenshot = {} + +local function button(icon, command) + return widgets.button.text.normal({ + forced_width = dpi(60), + forced_height = dpi(60), + normal_bg = beautiful.one_bg3, + normal_shape = gears.shape.circle, + on_normal_bg = beautiful.accent, + text_normal_bg = beautiful.accent, + text_on_normal_bg = beautiful.one_bg3, + font = beautiful.icon_font .. "Round ", + size = 17, + text = icon, + on_release = function() + awesome.emit_signal("central_panel::toggle", awful.screen.focused()) + gears.timer({ + timeout = 1, + autostart = true, + single_shot = true, + callback = function() + awful.spawn.with_shell(command) + end, + }) + end, + }) +end + +screenshot.area = button("", apps.utils.area_screenshot) +screenshot.full = button("", apps.utils.full_screenshot) + +return screenshot diff --git a/config/awesome/ui/panels/central-panel/slider.lua b/config/awesome/ui/panels/central-panel/slider.lua new file mode 100755 index 0000000..2e2ab72 --- /dev/null +++ b/config/awesome/ui/panels/central-panel/slider.lua @@ -0,0 +1,94 @@ +local awful = require("awful") +local beautiful = require("beautiful") +local gears = require("gears") +local dpi = beautiful.xresources.apply_dpi +local helpers = require("helpers") +local wibox = require("wibox") + +--- Sliders +--- ~~~~~~~ +local function sliders(icons) + local icon = wibox.widget({ + markup = icons, + font = beautiful.icon_font .. "Round 17", + align = "center", + valign = "center", + widget = wibox.widget.textbox, + }) + + local widget = wibox.widget({ + icon, + { + id = "slider", + value = 10, + maximum = 100, + forced_width = dpi(220), + shape = gears.shape.rounded_bar, + bar_shape = gears.shape.rounded_bar, + bar_color = beautiful.grey, + bar_margins = { bottom = dpi(18), top = dpi(18) }, + bar_active_color = beautiful.accent, + handle_width = dpi(14), + handle_shape = gears.shape.circle, + handle_color = beautiful.accent, + handle_border_width = dpi(3), + handle_border_color = beautiful.widget_bg, + widget = wibox.widget.slider, + }, + { + id = "text", + markup = "10%", + font = beautiful.font_name .. "13", + align = "center", + valign = "center", + widget = wibox.widget.textbox, + }, + layout = wibox.layout.fixed.horizontal, + forced_height = dpi(42), + spacing = dpi(17), + }) + + return widget +end + + +--- Volume +--- ~~~~~~ +local volume = sliders("") +local volume_slider = volume:get_children_by_id("slider")[1] +local volume_text = volume:get_children_by_id("text")[1] + +awful.spawn.easy_async_with_shell("pamixer --get-volume", function(stdout) + local value = string.gsub(stdout, "^%s*(.-)%s*$", "%1") + volume_slider.value = tonumber(value) + volume_text.markup = value .. "%" +end) + +volume_slider:connect_signal("property::value", function(_, new_value) + volume_text.markup = new_value .. "%" + volume_slider.value = new_value + awful.spawn("pamixer --set-volume " .. new_value, false) +end) + +return wibox.widget({ + { + { + { + + volume, + spacing = dpi(12), + layout = wibox.layout.fixed.vertical, + }, + margins = { top = dpi(12), bottom = dpi(12), left = dpi(18), right = dpi(12) }, + widget = wibox.container.margin, + }, + widget = wibox.container.background, + forced_height = dpi(120), + forced_width = dpi(350), + bg = beautiful.widget_bg, + shape = helpers.ui.rrect(beautiful.border_radius), + }, + margins = dpi(10), + color = "#FF000000", + widget = wibox.container.margin, +}) diff --git a/config/awesome/ui/panels/central-panel/stats.lua b/config/awesome/ui/panels/central-panel/stats.lua new file mode 100755 index 0000000..3badb64 --- /dev/null +++ b/config/awesome/ui/panels/central-panel/stats.lua @@ -0,0 +1,177 @@ +local awful = require("awful") +local watch = awful.widget.watch +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") +local icons = require("icons") + +local function create_boxed_widget(widget_to_be_boxed, width, height, bg_color) + local box_container = wibox.container.background() + box_container.bg = bg_color + box_container.forced_height = height + box_container.forced_width = width + box_container.shape = helpers.ui.rrect(beautiful.border_radius) + + local boxed_widget = wibox.widget({ + --- Add margins + { + --- Add background color + { + --- The actual widget goes here + widget_to_be_boxed, + top = dpi(9), + bottom = dpi(9), + left = dpi(10), + right = dpi(10), + widget = wibox.container.margin, + }, + widget = box_container, + }, + margins = dpi(10), + color = "#FF000000", + widget = wibox.container.margin, + }) + + return boxed_widget +end + +local function widget(img) + local icon = wibox.widget({ + { + image = img, + resize = true, + widget = wibox.widget.imagebox, + }, + margins = dpi(25), + widget = wibox.container.margin, + }) + + local widget = wibox.widget({ + widget = wibox.container.arcchart, + max_value = 100, + min_value = 0, + value = 50, + thickness = dpi(8), + rounded_edge = true, + bg = beautiful.grey, + colors = { beautiful.accent }, + start_angle = math.pi * 3 / 2, + icon, + }) + + return widget +end + +local function cpu() + local stats = widget(icons.cpu) + + local total_prev = 0 + local idle_prev = 0 + + watch( + [[bash -c " + cat /proc/stat | grep '^cpu ' + "]], + 10, + function(_, stdout) + local user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice = stdout:match( + "(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s" + ) + + local total = user + nice + system + idle + iowait + irq + softirq + steal + + local diff_idle = idle - idle_prev + local diff_total = total - total_prev + local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10 + + stats:set_value(diff_usage) + + total_prev = total + idle_prev = idle + collectgarbage("collect") + end + ) + + return stats +end + +local function temperature() + local stats = widget(icons.temp) + + local max_temp = 80 + + awful.spawn.easy_async_with_shell( + [[ + temp_path=null + for i in /sys/class/hwmon/hwmon*/temp*_input; + do + temp_path="$(echo "$(<$(dirname $i)/name): $(cat ${i%_*}_label 2>/dev/null || + echo $(basename ${i%_*})) $(readlink -f $i)");" + + label="$(echo $temp_path | awk '{print $2}')" + + if [ "$label" = "Package" ]; + then + echo ${temp_path} | awk '{print $5}' | tr -d ';\n' + exit; + fi + done + ]], + function(stdout) + local temp_path = stdout:gsub("%\n", "") + if temp_path == "" or not temp_path then + temp_path = "/sys/class/thermal/thermal_zone0/temp" + end + + watch([[ + sh -c "cat ]] .. temp_path .. [[" + ]], 10, function(_, stdout) + local temp = stdout:match("(%d+)") + stats:set_value((temp / 1000) / max_temp * 100) + collectgarbage("collect") + end) + end + ) + + return stats +end + +local function ram() + local stats = widget(icons.ram) + + watch('bash -c "free | grep -z Mem.*Swap.*"', 10, function(_, stdout) + local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap = stdout:match( + "(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)" + ) + stats:set_value(used / total * 100) + collectgarbage("collect") + end) + + return stats +end + +local function hdd() + local stats = widget(icons.disk) + + watch([[bash -c "df -h /home|grep '^/' | awk '{print $5}'"]], 10, function(_, stdout) + local space_consumed = stdout:match("(%d+)") + stats:set_value(tonumber(space_consumed)) + collectgarbage("collect") + end) + + return stats +end + +local stats = wibox.widget({ + create_boxed_widget(cpu(), dpi(115), dpi(120), beautiful.one_bg3), + create_boxed_widget(temperature(), dpi(115), dpi(120), beautiful.one_bg3), + create_boxed_widget(ram(), dpi(115), dpi(120), beautiful.one_bg3), + create_boxed_widget(hdd(), dpi(115), dpi(120), beautiful.one_bg3), + forced_num_cols = 2, + forced_num_rows = 2, + layout = wibox.layout.grid, +}) + +return create_boxed_widget(stats, dpi(200), dpi(300), beautiful.widget_bg) diff --git a/config/awesome/ui/panels/central-panel/user-profile.lua b/config/awesome/ui/panels/central-panel/user-profile.lua new file mode 100755 index 0000000..875313a --- /dev/null +++ b/config/awesome/ui/panels/central-panel/user-profile.lua @@ -0,0 +1,216 @@ +local awful = require("awful") +local focused = awful.screen.focused() +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") +local gears = require("gears") +local widgets = require("ui.widgets") + +local function create_boxed_widget(widget_to_be_boxed, width, height, bg_color) + local box_container = wibox.container.background() + box_container.bg = bg_color + box_container.forced_height = height + box_container.forced_width = width + box_container.shape = helpers.ui.rrect(beautiful.border_radius) + + local boxed_widget = wibox.widget({ + --- Add margins + { + --- Add background color + { + --- The actual widget goes here + widget_to_be_boxed, + top = dpi(10), + bottom = dpi(10), + left = dpi(10), + right = dpi(10), + widget = wibox.container.margin, + }, + widget = box_container, + }, + margins = dpi(10), + color = "#FF000000", + widget = wibox.container.margin, + }) + + return boxed_widget +end + +local function widget() + local icon = wibox.widget({ + { + font = beautiful.icon_font .. "Round 14", + markup = helpers.ui.colorize_text("", beautiful.widget_bg), + align = "center", + valign = "center", + widget = wibox.widget.textbox, + }, + bg = beautiful.accent, + widget = wibox.container.background, + shape = gears.shape.circle, + forced_height = dpi(25), + forced_width = dpi(25), + }) + + local image = wibox.widget({ + { + { + { + image = beautiful.pfp, + resize = true, + clip_shape = gears.shape.circle, + halign = "center", + valign = "center", + widget = wibox.widget.imagebox, + }, + border_width = dpi(2), + border_color = beautiful.accent, + shape = gears.shape.circle, + widget = wibox.container.background, + }, + strategy = "exact", + height = dpi(80), + width = dpi(80), + widget = wibox.container.constraint, + }, + { + nil, + nil, + { + nil, + nil, + icon, + layout = wibox.layout.align.horizontal, + expand = "none", + }, + layout = wibox.layout.align.vertical, + expand = "none", + }, + layout = wibox.layout.stack, + }) + + --- username + local profile_name = wibox.widget({ + widget = wibox.widget.textbox, + markup = "Rayhan Kafi Pratama", + font = beautiful.font_name .. "Bold 13", + align = "left", + valign = "center", + }) + + awful.spawn.easy_async_with_shell( + [[ + sh -c ' + fullname="$(getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1 | tr -d "\n")" + if [ -z "$fullname" ]; + then + printf "$(whoami)@$(hostname)" + else + printf "$fullname" + fi + ' + ]], + function(stdout) + local stdout = stdout:gsub("%\n", "") + profile_name:set_markup(stdout) + end + ) + + --- uptime + local uptime_time = wibox.widget({ + widget = wibox.widget.textbox, + markup = "up 3 hours, 33 minutes", + font = beautiful.font_name .. "Regular 11", + align = "left", + valign = "center", + }) + + local update_uptime = function() + awful.spawn.easy_async_with_shell("uptime -p", function(stdout) + local uptime = stdout:gsub("%\n", "") + uptime_time:set_markup(uptime) + end) + end + + gears.timer({ + timeout = 60, + autostart = true, + call_now = true, + callback = function() + update_uptime() + end, + }) + + local profile = wibox.widget({ + { + image, + { + nil, + { + { + widget = wibox.container.scroll.horizontal, + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, + profile_name, + }, + { + widget = wibox.container.scroll.horizontal, + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, + uptime_time, + }, + layout = wibox.layout.fixed.vertical, + spacing = dpi(2), + }, + layout = wibox.layout.align.vertical, + expand = "none", + }, + layout = wibox.layout.fixed.horizontal, + spacing = dpi(15), + }, + { + nil, + nil, + { + widgets.button.text.normal({ + forced_width = dpi(50), + forced_height = dpi(50), + font = "icomoon bold ", + text_normal_bg = beautiful.xforeground, + normal_bg = beautiful.one_bg3, + text = "", + size = 17, + on_release = function() + lock_screen_show() + awesome.emit_signal("central_panel::toggle", focused) + end, + }), + widgets.button.text.normal({ + forced_width = dpi(50), + forced_height = dpi(50), + font = "icomoon bold ", + text_normal_bg = beautiful.accent, + normal_bg = beautiful.one_bg3, + text = "", + size = 17, + on_release = function() + awesome.emit_signal("module::exit_screen:show") + awesome.emit_signal("central_panel::toggle", focused) + end, + }), + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + layout = wibox.layout.align.horizontal, + }, + layout = wibox.layout.align.vertical, + }) + + return profile +end + +return create_boxed_widget(widget(), dpi(350), dpi(145), beautiful.widget_bg) diff --git a/config/awesome/ui/panels/info-panel/calendar.lua b/config/awesome/ui/panels/info-panel/calendar.lua new file mode 100755 index 0000000..2bb7fd4 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/calendar.lua @@ -0,0 +1,169 @@ +local gobject = require("gears.object") +local gtable = require("gears.table") +local gshape = require("gears.shape") +local wibox = require("wibox") +local widgets = require("ui.widgets") +local beautiful = require("beautiful") +local helpers = require("helpers") +local dpi = beautiful.xresources.apply_dpi +local setmetatable = setmetatable +local os = os + +local calendar = { mt = {} } + +local function day_name_widget(name) + return wibox.widget({ + widget = wibox.container.background, + forced_width = dpi(30), + forced_height = dpi(30), + widgets.text({ + halign = "center", + size = 12, + bold = true, + text = name, + }), + }) +end + +local function date_widget(date, is_current, is_another_month) + local text_color = beautiful.xforeground + if is_current == true then + text_color = beautiful.widget_bg + elseif is_another_month == true then + text_color = helpers.color.darken(beautiful.xforeground, 0.5) + end + + return wibox.widget({ + widget = wibox.container.background, + forced_width = dpi(30), + forced_height = dpi(30), + shape = gshape.circle, + bg = is_current and beautiful.accent, + widgets.text({ + halign = "center", + size = 10, + color = text_color, + text = date, + }), + }) +end + +function calendar:set_date(date) + self.date = date + + self.days:reset() + + local current_date = os.date("*t") + + self.days:add(day_name_widget("Su")) + self.days:add(day_name_widget("Mo")) + self.days:add(day_name_widget("Tu")) + self.days:add(day_name_widget("We")) + self.days:add(day_name_widget("Th")) + self.days:add(day_name_widget("Fr")) + self.days:add(day_name_widget("Sa")) + + local first_day = os.date("*t", os.time({ year = date.year, month = date.month, day = 1 })) + local last_day = os.date("*t", os.time({ year = date.year, month = date.month + 1, day = 0 })) + local month_days = last_day.day + + local time = os.time({ year = date.year, month = date.month, day = 1 }) + self.month:set_text(os.date("%B %Y", time)) + + local days_to_add_at_month_start = first_day.wday - 1 + local days_to_add_at_month_end = 42 - last_day.day - days_to_add_at_month_start + + local previous_month_last_day = os.date("*t", os.time({ year = date.year, month = date.month, day = 0 })).day + for day = previous_month_last_day - days_to_add_at_month_start, previous_month_last_day - 1, 1 do + self.days:add(date_widget(day, false, true)) + end + + for day = 1, month_days do + local is_current = day == current_date.day and date.month == current_date.month + self.days:add(date_widget(day, is_current, false)) + end + + for day = 1, days_to_add_at_month_end do + self.days:add(date_widget(day, false, true)) + end +end + +function calendar:set_date_current() + self:set_date(os.date("*t")) +end + +function calendar:increase_date() + local new_calendar_month = self.date.month + 1 + self:set_date({ year = self.date.year, month = new_calendar_month, day = self.date.day }) +end + +function calendar:decrease_date() + local new_calendar_month = self.date.month - 1 + self:set_date({ year = self.date.year, month = new_calendar_month, day = self.date.day }) +end + +local function new() + local ret = gobject({}) + gtable.crush(ret, calendar, true) + + ret.month = widgets.button.text.normal({ + animate_size = false, + text = os.date("%B %Y"), + size = 16, + bold = true, + text_normal_bg = beautiful.accent, + normal_bg = beautiful.widget_bg, + on_release = function() + ret:set_date_current() + end, + }) + + local month = wibox.widget({ + layout = wibox.layout.align.horizontal, + widgets.button.text.normal({ + font = "Material Icons Round ", + text_normal_bg = beautiful.xforeground, + normal_bg = beautiful.widget_bg, + text = "", + on_release = function() + ret:decrease_date() + end, + }), + ret.month, + widgets.button.text.normal({ + font = "Material Icons Round ", + text_normal_bg = beautiful.xforeground, + normal_bg = beautiful.widget_bg, + text = "", + on_release = function() + ret:increase_date() + end, + }), + }) + + ret.days = wibox.widget({ + layout = wibox.layout.grid, + forced_num_rows = 6, + forced_num_cols = 7, + spacing = dpi(5), + expand = true, + }) + + local widget = wibox.widget({ + layout = wibox.layout.fixed.vertical, + spacing = dpi(15), + month, + ret.days, + }) + + ret:set_date(os.date("*t")) + + gtable.crush(widget, calendar, true) + return widget +end + +function calendar.mt:__call(...) + return new(...) +end + +return setmetatable(calendar, calendar.mt) diff --git a/config/awesome/ui/panels/info-panel/init.lua b/config/awesome/ui/panels/info-panel/init.lua new file mode 100755 index 0000000..e55b351 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/init.lua @@ -0,0 +1,95 @@ +local awful = require("awful") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") + +return function(s) + --- Date + local time_format = " %I:%M " + local date_formate = " %A %B %d " + local time = wibox.container.place(wibox.widget.textclock(time_format, 60)) + local date = wibox.container.place(wibox.widget.textclock(date_formate, 60)) + + local date_time = wibox.widget({ + { + time, + date, + layout = wibox.layout.fixed.vertical, + }, + margins = dpi(20), + widget = wibox.container.margin, + }) + + --- Calendar + s.calendar = require("ui.panels.info-panel.calendar")() + + --- Weather + s.weather = require("ui.panels.info-panel.weather") + + s.info_panel = awful.popup({ + type = "dock", + screen = s, + minimum_height = s.geometry.height - (beautiful.wibar_height + dpi(10)), + maximum_height = s.geometry.height - (beautiful.wibar_height + dpi(10)), + minimum_width = dpi(350), + maximum_width = dpi(350), + bg = beautiful.transparent, + ontop = true, + visible = false, + placement = function(w) + awful.placement.bottom_left(w, { + margins = { top = dpi(5), bottom = beautiful.wibar_height + dpi(5), left = dpi(5), right = dpi(5) }, + }) + end, + widget = { + { + { + date_time, + { + { + s.calendar, + margins = { top = dpi(8), left = dpi(16), bottom = dpi(16), right = dpi(16) }, + widget = wibox.container.margin, + }, + bg = beautiful.widget_bg, + shape = helpers.ui.rrect(beautiful.border_radius), + widget = wibox.container.background, + }, + { + top = dpi(20), + widget = wibox.container.margin, + }, + { + { + s.weather, + margins = dpi(16), + widget = wibox.container.margin, + }, + bg = beautiful.widget_bg, + shape = helpers.ui.rrect(beautiful.border_radius), + widget = wibox.container.background, + }, + + layout = wibox.layout.fixed.vertical, + }, + top = dpi(10), + bottom = dpi(30), + left = dpi(25), + right = dpi(25), + widget = wibox.container.margin, + }, + bg = beautiful.wibar_bg, + shape = helpers.ui.rrect(beautiful.border_radius), + widget = wibox.container.background, + }, + }) + + --- Toggle container visibility + awesome.connect_signal("info_panel::toggle", function(scr) + if scr == s then + s.info_panel.visible = not s.info_panel.visible + end + end) +end diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-clear-night.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-clear-night.svg new file mode 100755 index 0000000..ecf451a --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-clear-night.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-clear-sky.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-clear-sky.svg new file mode 100755 index 0000000..e84065c --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-clear-sky.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-clouds-night.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-clouds-night.svg new file mode 100755 index 0000000..1a00dff --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-clouds-night.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-clouds.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-clouds.svg new file mode 100755 index 0000000..d709745 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-clouds.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-few-clouds-night.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-few-clouds-night.svg new file mode 100755 index 0000000..e8243ae --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-few-clouds-night.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-few-clouds.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-few-clouds.svg new file mode 100755 index 0000000..7279f9f --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-few-clouds.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-fog.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-fog.svg new file mode 100755 index 0000000..81d0a39 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-fog.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-freezing-rain.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-freezing-rain.svg new file mode 100755 index 0000000..d83c93a --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-freezing-rain.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-overcast-symbolic.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-overcast-symbolic.svg new file mode 100755 index 0000000..79a543f --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-overcast-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-overcast.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-overcast.svg new file mode 100755 index 0000000..e85bb96 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-overcast.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-severe-alert.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-severe-alert.svg new file mode 100755 index 0000000..3a512f7 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-severe-alert.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-showers-scattered.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-showers-scattered.svg new file mode 100755 index 0000000..7749e85 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-showers-scattered.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-showers.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-showers.svg new file mode 100755 index 0000000..b0f387f --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-showers.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-snow-rain.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-snow-rain.svg new file mode 100755 index 0000000..391fac5 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-snow-rain.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-snow-scattered.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-snow-scattered.svg new file mode 100755 index 0000000..9be2009 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-snow-scattered.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-snow.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-snow.svg new file mode 100755 index 0000000..d1f7d1c --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-snow.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-storm.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-storm.svg new file mode 100755 index 0000000..cb2cba6 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-storm.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/config/awesome/ui/panels/info-panel/weather/icons/weather-windy.svg b/config/awesome/ui/panels/info-panel/weather/icons/weather-windy.svg new file mode 100755 index 0000000..65bec4f --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/icons/weather-windy.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/awesome/ui/panels/info-panel/weather/init.lua b/config/awesome/ui/panels/info-panel/weather/init.lua new file mode 100755 index 0000000..0092f45 --- /dev/null +++ b/config/awesome/ui/panels/info-panel/weather/init.lua @@ -0,0 +1,208 @@ +local awful = require("awful") +local wibox = require("wibox") +local gears = require("gears") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local filesystem = gears.filesystem +local json = require("modules.json") +local user_vars = require("user_variables") +local icon_dir = filesystem.get_configuration_dir() .. "ui/panels/info-panel/weather/icons/" + +local GET_FORECAST_CMD = [[bash -c "curl -s --show-error -X GET '%s'"]] + +local icon_map = { + ["01d"] = "weather-clear-sky", + ["02d"] = "weather-few-clouds", + ["03d"] = "weather-clouds", + ["04d"] = "weather-few-clouds", + ["09d"] = "weather-showers-scattered", + ["10d"] = "weather-showers", + ["11d"] = "weather-strom", + ["13d"] = "weather-snow", + ["50d"] = "weather-fog", + ["01n"] = "weather-clear-night", + ["02n"] = "weather-few-clouds-night", + ["03n"] = "weather-clouds-night", + ["04n"] = "weather-clouds-night", + ["09n"] = "weather-showers-scattered", + ["10n"] = "weather-showers", + ["11n"] = "weather-strom", + ["13n"] = "weather-snow", + ["50n"] = "weather-fog", +} + +local current_weather_widget = wibox.widget({ + { + { + id = "icon", + image = icon_dir .. "weather-showers.svg", + resize = true, + forced_height = dpi(42), + forced_width = dpi(42), + widget = wibox.widget.imagebox, + }, + { + { + { + id = "description", + text = "Mostly cloudy", + font = beautiful.font_name .. "Bold 10", + widget = wibox.widget.textbox, + }, + { + id = "humidity", + text = "Humidity: 80%", + font = beautiful.font_name .. "Light 9", + widget = wibox.widget.textbox, + }, + layout = wibox.layout.fixed.vertical, + }, + widget = wibox.container.place, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.horizontal, + }, + nil, + { + { + { + id = "tempareture_current", + markup = "20°", + align = "right", + font = beautiful.font_name .. "Bold 16", + widget = wibox.widget.textbox, + }, + { + id = "feels_like", + markup = "Feels like: 19°", + font = beautiful.font_name .. "Light 8", + widget = wibox.widget.textbox, + }, + spacing = dpi(-6), + layout = wibox.layout.fixed.vertical, + }, + widget = wibox.container.place, + }, + layout = wibox.layout.align.horizontal, +}) + +local hourly_widget = function() + local widget = wibox.widget({ + { + { + id = "time", + text = "12PM", + font = beautiful.font_name .. "Light 9", + widget = wibox.widget.textbox, + }, + widget = wibox.container.place, + }, + { + { + id = "icon", + image = icon_dir .. "weather-clear-sky.svg", + resize = true, + forced_height = dpi(16), + forced_width = dpi(16), + widget = wibox.widget.imagebox, + }, + widget = wibox.container.place, + }, + { + { + id = "tempareture", + markup = "1°", + font = beautiful.font_name .. "Light 9", + widget = wibox.widget.textbox, + }, + widget = wibox.container.place, + }, + spacing = dpi(6), + layout = wibox.layout.fixed.vertical, + }) + + widget.update = function(result) + local time = widget:get_children_by_id("time")[1] + local icon = widget:get_children_by_id("icon")[1] + local temp = widget:get_children_by_id("tempareture")[1] + temp:set_markup(math.floor(result.temp) .. "°") + time:set_text(os.date("%I%p", tonumber(result.dt))) + icon.image = icon_dir .. icon_map[result.weather[1].icon] .. ".svg" + icon:emit_signal("widget::redraw_needed") + end + return widget +end + +local hourly_widget_1 = hourly_widget() +local hourly_widget_2 = hourly_widget() +local hourly_widget_3 = hourly_widget() +local hourly_widget_4 = hourly_widget() +local hourly_widget_5 = hourly_widget() + +local weather_widget = wibox.widget({ + { + text = "Weather", + font = beautiful.font_name .. "Bold 16", + align = "center", + widget = wibox.widget.textbox, + }, + current_weather_widget, + { + hourly_widget_1, + hourly_widget_2, + hourly_widget_3, + hourly_widget_4, + hourly_widget_5, + layout = wibox.layout.flex.horizontal, + }, + spacing = dpi(10), + layout = wibox.layout.fixed.vertical, +}) + +local api_key = user_vars.widget.weather.key +local coordinates = user_vars.widget.weather.coordinates + +local show_hourly_forecast = true +local show_daily_forecast = true +local units = "metric" + +local url = ( + "https://api.openweathermap.org/data/2.5/onecall" + .. "?lat=" + .. coordinates[1] + .. "&lon=" + .. coordinates[2] + .. "&appid=" + .. api_key + .. "&units=" + .. units + .. "&exclude=minutely" + .. (show_hourly_forecast == false and ",hourly" or "") + .. (show_daily_forecast == false and ",daily" or "") +) + +awful.widget.watch(string.format(GET_FORECAST_CMD, url), 600, function(_, stdout, stderr) + if stderr == "" then + local result = json.decode(stdout) + -- Current weather setup + local icon = current_weather_widget:get_children_by_id("icon")[1] + local description = current_weather_widget:get_children_by_id("description")[1] + local humidity = current_weather_widget:get_children_by_id("humidity")[1] + local temp_current = current_weather_widget:get_children_by_id("tempareture_current")[1] + local feels_like = current_weather_widget:get_children_by_id("feels_like")[1] + icon.image = icon_dir .. icon_map[result.current.weather[1].icon] .. ".svg" + icon:emit_signal("widget::redraw_needed") + description:set_text(result.current.weather[1].description:gsub("^%l", string.upper)) + humidity:set_text("Humidity: " .. result.current.humidity .. "%") + temp_current:set_markup(math.floor(result.current.temp) .. "°") + feels_like:set_markup("Feels like: " .. math.floor(result.current.feels_like) .. "°") + -- Hourly widget setup + hourly_widget_1.update(result.hourly[1]) + hourly_widget_2.update(result.hourly[2]) + hourly_widget_3.update(result.hourly[3]) + hourly_widget_4.update(result.hourly[4]) + hourly_widget_5.update(result.hourly[5]) + end +end) + +return weather_widget diff --git a/config/awesome/ui/panels/notification-panel/github-activity/icons/alert-circle.svg b/config/awesome/ui/panels/notification-panel/github-activity/icons/alert-circle.svg new file mode 100755 index 0000000..1c42eaf --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/github-activity/icons/alert-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/ui/panels/notification-panel/github-activity/icons/git-branch.svg b/config/awesome/ui/panels/notification-panel/github-activity/icons/git-branch.svg new file mode 100755 index 0000000..3f06c34 --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/github-activity/icons/git-branch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/ui/panels/notification-panel/github-activity/icons/git-pull-request.svg b/config/awesome/ui/panels/notification-panel/github-activity/icons/git-pull-request.svg new file mode 100755 index 0000000..c2e2867 --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/github-activity/icons/git-pull-request.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/ui/panels/notification-panel/github-activity/icons/github.png b/config/awesome/ui/panels/notification-panel/github-activity/icons/github.png new file mode 100755 index 0000000..628da97 Binary files /dev/null and b/config/awesome/ui/panels/notification-panel/github-activity/icons/github.png differ diff --git a/config/awesome/ui/panels/notification-panel/github-activity/icons/message-square.svg b/config/awesome/ui/panels/notification-panel/github-activity/icons/message-square.svg new file mode 100755 index 0000000..758ba42 --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/github-activity/icons/message-square.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/ui/panels/notification-panel/github-activity/icons/repo.svg b/config/awesome/ui/panels/notification-panel/github-activity/icons/repo.svg new file mode 100755 index 0000000..f74a595 --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/github-activity/icons/repo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/ui/panels/notification-panel/github-activity/icons/star.svg b/config/awesome/ui/panels/notification-panel/github-activity/icons/star.svg new file mode 100755 index 0000000..0a3d39e --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/github-activity/icons/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/awesome/ui/panels/notification-panel/github-activity/init.lua b/config/awesome/ui/panels/notification-panel/github-activity/init.lua new file mode 100755 index 0000000..89f9337 --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/github-activity/init.lua @@ -0,0 +1,223 @@ +local awful = require("awful") +local wibox = require("wibox") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local gfs = require("gears.filesystem") +local widgets = require("ui.widgets") +local helpers = require("helpers") +local github_daemon = require("signal.github") +local collectgarbage = collectgarbage +local setmetatable = setmetatable +local tostring = tostring +local string = string +local ipairs = ipairs +local os = os + +local widget_dir = gfs.get_configuration_dir() .. "ui/panels/notification-panel/github-activity" +local icons_dir = widget_dir .. "/icons/" + +local github = { mt = {} } + +local function generate_action_string(event) + local action_string = event.type + local icon = "repo.svg" + local link = "http://github.com/" .. event.repo.name + + if event.type == "PullRequestEvent" then + action_string = event.payload.action .. " a pull request in" + link = event.pr_url + icon = "git-pull-request.svg" + elseif event.type == "IssuesEvent" then + action_string = event.payload.action .. " an issue in" + link = event.issue_url + icon = "alert-circle.svg" + elseif event.type == "IssueCommentEvent" then + action_string = event.payload.action == "created" and "commented in issue" or event.action .. " a comment in" + link = event.issue_url + icon = "message-square.svg" + elseif event.type == "WatchEvent" then + action_string = "starred" + icon = "star.svg" + elseif event.type == "ForkEvent" then + action_string = "forked" + icon = "git-branch.svg" + elseif event.type == "CreateEvent" then + action_string = "created" + end + + return { action_string = action_string, link = link, icon = icon } +end + +local function widget() + local missing_credentials_text = wibox.widget({ + widget = wibox.container.place, + halign = "center", + valign = "center", + widgets.text({ + halign = "center", + size = 25, + color = beautiful.xcolor1, + text = "Missing Credentials", + }), + }) + + local error_icon = wibox.widget({ + widget = wibox.container.place, + halign = "center", + valign = "center", + { + widgets.text({ + halign = "center", + size = 125, + color = beautiful.xcolor3, + font = "Material Icons Round ", + text = "", + }), + widgets.text({ + halign = "center", + color = beautiful.xcolor3, + text = "Error", + bold = true, + }), + layout = wibox.layout.fixed.vertical, + }, + }) + + local scrollbox = wibox.widget({ + layout = require("modules.overflow").vertical, + spacing = dpi(10), + scrollbar_widget = { + widget = wibox.widget.separator, + shape = helpers.ui.rrect(beautiful.border_radius), + }, + scrollbar_width = dpi(10), + step = 50, + }) + + return missing_credentials_text, error_icon, scrollbox +end + +local function spacer_vertical(amount) + return wibox.widget({ + layout = wibox.layout.fixed.vertical, + forced_height = amount, + }) +end + +local function github_activity() + local missing_credentials_text, error_icon, scrollbox = widget() + + local github_activity_widget = wibox.widget({ + layout = wibox.layout.stack, + top_only = true, + missing_credentials_text, + error_icon, + scrollbox, + }) + + github_daemon:connect_signal("events::error", function() + github_activity_widget:raise_widget(error_icon) + end) + + github_daemon:connect_signal("missing_credentials", function() + github_activity_widget:raise_widget(missing_credentials_text) + end) + + github_daemon:connect_signal("events", function(self, events, path_to_avatars) + scrollbox:reset() + collectgarbage("collect") + github_activity_widget:raise_widget(scrollbox) + + for index, event in ipairs(events) do + local action_and_link = generate_action_string(event) + + local avatar = widgets.button.elevated.normal({ + paddings = dpi(5), + normal_bg = beautiful.wibar_bg, + child = { + widget = wibox.widget.imagebox, + forced_width = dpi(40), + forced_height = dpi(40), + clip_shape = helpers.ui.rrect(beautiful.border_radius), + image = path_to_avatars .. event.actor.id, + }, + on_release = function() + awful.spawn("xdg-open http://github.com/" .. event.actor.login, false) + end, + }) + + local repo_info = widgets.button.elevated.normal({ + paddings = dpi(5), + normal_bg = beautiful.wibar_bg, + halign = "left", + child = { + { + step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth, + fps = 60, + speed = 75, + { + markup = " " + .. event.actor.display_login + .. " " + .. action_and_link.action_string + .. " " + .. event.repo.name + .. "", + font = beautiful.font_name .. "Regular 11", + widget = wibox.widget.textbox, + }, + forced_width = dpi(300), + widget = wibox.container.scroll.horizontal, + }, + { + { + { + image = icons_dir .. action_and_link.icon, + resize = true, + forced_height = dpi(16), + forced_width = dpi(16), + widget = wibox.widget.imagebox, + }, + valign = "center", + layout = wibox.container.place, + }, + { + markup = helpers.misc.to_time_ago( + os.difftime(os.time(os.date("!*t")), helpers.misc.parse_date(event.created_at)) + ), + font = beautiful.font_name .. "Regular 11", + widget = wibox.widget.textbox, + }, + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal, + }, + layout = wibox.layout.align.vertical, + }, + on_release = function() + awful.spawn("xdg-open " .. action_and_link.link, false) + end, + }) + + local content = wibox.widget({ + avatar, + repo_info, + spacing = dpi(5), + layout = wibox.layout.fixed.horizontal, + }) + + scrollbox:add(content) + + if index == #events then + scrollbox:add(spacer_vertical(20)) + end + end + end) + + return github_activity_widget +end + +function github.mt:__call() + return github_activity() +end + +return setmetatable(github, github.mt) diff --git a/config/awesome/ui/panels/notification-panel/init.lua b/config/awesome/ui/panels/notification-panel/init.lua new file mode 100755 index 0000000..addce56 --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/init.lua @@ -0,0 +1,51 @@ +local awful = require("awful") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") + +return function(s) + --- notification_panel and animations init + s.notification_panel = awful.popup({ + type = "dock", + screen = s, + minimum_height = s.geometry.height - (beautiful.wibar_height + dpi(10)), + maximum_height = s.geometry.height - (beautiful.wibar_height + dpi(10)), + minimum_width = dpi(350), + maximum_width = dpi(350), + bg = beautiful.transparent, + ontop = true, + visible = false, + placement = function(w) + awful.placement.bottom_right(w, { + margins = { top = dpi(5), bottom = beautiful.wibar_height + dpi(5), left = dpi(5), right = dpi(5) }, + }) + end, + widget = { + { + { + layout = wibox.layout.flex.vertical, + spacing = dpi(20), + nil, + require("ui.panels.notification-panel.notif-center")(s), + require("ui.panels.notification-panel.github-activity"), + nil, + }, + margins = dpi(20), + widget = wibox.container.margin, + }, + id = "notification_panel", + bg = beautiful.wibar_bg, + shape = helpers.ui.rrect(beautiful.border_radius), + widget = wibox.container.background, + }, + }) + + --- Toggle container visibility + awesome.connect_signal("notification_panel::toggle", function(scr) + if scr == s then + s.notification_panel.visible = not s.notification_panel.visible + end + end) +end diff --git a/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/empty-notifbox.lua b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/empty-notifbox.lua new file mode 100755 index 0000000..1074a94 --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/empty-notifbox.lua @@ -0,0 +1,35 @@ +local helpers = require("helpers") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi +local wibox = require("wibox") + +local separator_for_empty_msg = wibox.widget({ + orientation = "vertical", + opacity = 0.0, + widget = wibox.widget.separator, +}) + +return wibox.widget({ + separator_for_empty_msg, + { + { + widget = wibox.widget.textbox, + markup = helpers.ui.colorize_text("", beautiful.accent), + font = beautiful.icon_font .. "Round 84", + valign = "center", + align = "center", + }, + { + widget = wibox.widget.textbox, + markup = helpers.ui.colorize_text("No Notifications", beautiful.xforeground), + font = beautiful.font_name .. "Bold 14", + valign = "center", + align = "center", + }, + spacing = dpi(10), + layout = wibox.layout.fixed.vertical, + }, + separator_for_empty_msg, + layout = wibox.layout.align.vertical, + expand = "none", +}) diff --git a/config/awesome/ui/central-panel/notif-center/build-notifbox/init.lua b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/init.lua old mode 100644 new mode 100755 similarity index 59% rename from config/awesome/ui/central-panel/notif-center/build-notifbox/init.lua rename to config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/init.lua index baf8f2c..0306f57 --- a/config/awesome/ui/central-panel/notif-center/build-notifbox/init.lua +++ b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/init.lua @@ -1,12 +1,10 @@ local wibox = require("wibox") -local awful = require("awful") -local gears = require("gears") local naughty = require("naughty") local beautiful = require("beautiful") local dpi = beautiful.xresources.apply_dpi -local icons = require("theme.assets.icons") -local empty_notifbox = require("ui.central-panel.notif-center.build-notifbox.empty-notifbox") -local notifbox_scroller = require("ui.central-panel.notif-center.build-notifbox.notifbox-scroller") + +local empty_notifbox = require("ui.panels.notification-panel.notif-center.build-notifbox.empty-notifbox") +local notifbox_scroller = require("ui.panels.notification-panel.notif-center.build-notifbox.notifbox-scroller") local notif_core = {} @@ -32,30 +30,22 @@ local notifbox_add = function(n, notif_icon, notifbox_color) notif_core.remove_notifbox_empty = false end - local notifbox_box = require("ui.central-panel.notif-center.build-notifbox.notifbox-builder") + local notifbox_box = require("ui.panels.notification-panel.notif-center.build-notifbox.notifbox-builder") notif_core.notifbox_layout:insert(1, notifbox_box(n, notif_icon, n.title, n.message, n.app_name, notifbox_color)) end -local notifbox_add_expired = function(n, notif_icon, notifbox_color) - n:connect_signal("destroyed", function(self, reason, keep_visble) - if reason == 1 then - notifbox_add(n, notif_icon, notifbox_color) - end - end) -end - naughty.connect_signal("request::display", function(n) - local notifbox_color = beautiful.notif_center_notifs_bg + local notifbox_color = beautiful.transparent if n.urgency == "critical" then notifbox_color = n.bg .. "66" end local notif_icon = n.icon or n.app_icon if not notif_icon then - notif_icon = gears.color.recolor_image(icons.notification, beautiful.accent) + notif_icon = beautiful.theme_assets.awesome_icon(24, beautiful.xcolor8, beautiful.widget_bg) end - notifbox_add_expired(n, notif_icon, notifbox_color) + notifbox_add(n, notif_icon, notifbox_color) end) return notif_core diff --git a/config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-builder.lua b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-builder.lua old mode 100644 new mode 100755 similarity index 82% rename from config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-builder.lua rename to config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-builder.lua index 987f321..a1d4266 --- a/config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-builder.lua +++ b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-builder.lua @@ -2,14 +2,12 @@ local wibox = require("wibox") local awful = require("awful") local gears = require("gears") local beautiful = require("beautiful") - local dpi = beautiful.xresources.apply_dpi -local builder = require("ui.central-panel.notif-center.build-notifbox.notifbox-ui-elements") -local notifbox_core = require("ui.central-panel.notif-center.build-notifbox") +local builder = require("ui.panels.notification-panel.notif-center.build-notifbox.notifbox-ui-elements") +local notifbox_core = require("ui.panels.notification-panel.notif-center.build-notifbox") local notifbox_layout = notifbox_core.notifbox_layout -local remove_notifbox_empty = notifbox_core.remove_notifbox_empty local reset_notifbox_layout = notifbox_core.reset_notifbox_layout local return_date_time = function(format) @@ -40,7 +38,7 @@ notifbox_box = function(notif, icon, title, message, app, bgcolor) local notifbox_dismiss = builder.notifbox_dismiss() - local time_of_popup = gears.timer({ + gears.timer({ timeout = 60, call_now = true, autostart = true, @@ -105,44 +103,27 @@ notifbox_box = function(notif, icon, title, message, app, bgcolor) }, bg = bgcolor, shape = function(cr, width, height) - gears.shape.partially_rounded_rect( - cr, - width, - height, - true, - true, - true, - true, - beautiful.notif_center_box_radius - ) + gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.border_radius) end, widget = wibox.container.background, }) - -- Put the generated template to a container + --- Put the generated template to a container local notifbox = wibox.widget({ notifbox_template, shape = function(cr, width, height) - gears.shape.partially_rounded_rect( - cr, - width, - height, - true, - true, - true, - true, - beautiful.notif_center_box_radius - ) + gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.border_radius) end, widget = wibox.container.background, }) - -- Delete notification box + --- Delete notification box local notifbox_delete = function() notifbox_layout:remove_widgets(notifbox, true) end - notifbox_dismiss:buttons(awful.util.table.join(awful.button({}, 1, function() + --- Delete notifbox on LMB + notifbox:buttons(awful.util.table.join(awful.button({}, 1, function() if #notifbox_layout.children == 1 then reset_notifbox_layout() else @@ -151,13 +132,15 @@ notifbox_box = function(notif, icon, title, message, app, bgcolor) collectgarbage("collect") end))) - -- Add hover, and mouse leave events + --- Add hover, and mouse leave events notifbox_template:connect_signal("mouse::enter", function() + notifbox.bg = beautiful.notif_center_notifs_bg notifbox_timepop.visible = false notifbox_dismiss.visible = true end) notifbox_template:connect_signal("mouse::leave", function() + notifbox.bg = beautiful.tranparent notifbox_timepop.visible = true notifbox_dismiss.visible = false end) diff --git a/config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-geometry.lua b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-geometry.lua old mode 100644 new mode 100755 similarity index 76% rename from config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-geometry.lua rename to config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-geometry.lua index ac2d424..ac577b2 --- a/config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-geometry.lua +++ b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-geometry.lua @@ -1,4 +1,3 @@ -local wibox = require("wibox") local awful = require("awful") local naughty = require("naughty") @@ -21,10 +20,5 @@ end local focused = awful.screen.focused() local h = find_widget_in_wibox(focused.top_panel, focused.music) local x, y, width, height = h:get_matrix_to_device():transform_rectangle(0, 0, h:get_size()) --- local geo = focused.mywibox:geometry() - --- x, y = x + geo.x, y + geo.y - --- print(string.format("The widget is inside of the rectangle (%d, %d, %d, %d) on the screen", x, y, width, height) naughty.notification({ message = tostring(height) }) diff --git a/config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-scroller.lua b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-scroller.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-scroller.lua rename to config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-scroller.lua diff --git a/config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-ui-elements.lua b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-ui-elements.lua old mode 100644 new mode 100755 similarity index 78% rename from config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-ui-elements.lua rename to config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-ui-elements.lua index 8fc461d..bafae05 --- a/config/awesome/ui/central-panel/notif-center/build-notifbox/notifbox-ui-elements.lua +++ b/config/awesome/ui/panels/notification-panel/notif-center/build-notifbox/notifbox-ui-elements.lua @@ -8,7 +8,7 @@ local clickable_container = require("ui.widgets.clickable-container") local ui_notifbox_builder = {} --- Notification icon container +--- Notification icon container ui_notifbox_builder.notifbox_icon = function(ico_image) local noti_icon = wibox.widget({ { @@ -24,7 +24,7 @@ ui_notifbox_builder.notifbox_icon = function(ico_image) return noti_icon end --- Notification title container +--- Notification title container ui_notifbox_builder.notifbox_title = function(title) return wibox.widget({ markup = title, @@ -35,7 +35,7 @@ ui_notifbox_builder.notifbox_title = function(title) }) end --- Notification message container +--- Notification message container ui_notifbox_builder.notifbox_message = function(msg) return wibox.widget({ markup = msg, @@ -46,7 +46,7 @@ ui_notifbox_builder.notifbox_message = function(msg) }) end --- Notification app name container +--- Notification app name container ui_notifbox_builder.notifbox_appname = function(app) return wibox.widget({ markup = app, @@ -57,7 +57,7 @@ ui_notifbox_builder.notifbox_appname = function(app) }) end --- Notification actions container +--- Notification actions container ui_notifbox_builder.notifbox_actions = function(n) actions_template = wibox.widget({ notification = n, @@ -78,12 +78,12 @@ ui_notifbox_builder.notifbox_actions = function(n) }, widget = clickable_container, }, - bg = beautiful.accent, + bg = beautiful.notif_center_notifs_bg_alt, shape = gears.shape.rounded_rect, - forced_height = 30, + forced_height = dpi(30), widget = wibox.container.background, }, - margins = 4, + margins = dpi(4), widget = wibox.container.margin, }, style = { underline_normal = false, underline_selected = true }, @@ -93,19 +93,23 @@ ui_notifbox_builder.notifbox_actions = function(n) return actions_template end --- Notification dismiss button +--- Notification dismiss button ui_notifbox_builder.notifbox_dismiss = function() - local dismiss_imagebox = wibox.widget({ - align = "center", - valign = "center", - font = beautiful.icon_font_name .. "10", - markup = helpers.colorize_text("󰅖", beautiful.xcolor1), - widget = wibox.widget.textbox(), + local dismiss_textbox = wibox.widget({ + { + id = "dismiss_icon", + font = beautiful.icon_font .. "Round 10", + markup = helpers.ui.colorize_text("", beautiful.xcolor1), + align = "center", + valign = "center", + widget = wibox.widget.textbox, + }, + layout = wibox.layout.fixed.horizontal, }) local dismiss_button = wibox.widget({ { - dismiss_imagebox, + dismiss_textbox, margins = dpi(5), widget = wibox.container.margin, }, @@ -115,7 +119,7 @@ ui_notifbox_builder.notifbox_dismiss = function() local notifbox_dismiss = wibox.widget({ dismiss_button, visible = false, - bg = beautiful.notif_center_notifs_accent, + bg = beautiful.notif_center_notifs_bg_alt, shape = gears.shape.circle, widget = wibox.container.background, }) diff --git a/config/awesome/ui/panels/notification-panel/notif-center/init.lua b/config/awesome/ui/panels/notification-panel/notif-center/init.lua new file mode 100755 index 0000000..7666fe6 --- /dev/null +++ b/config/awesome/ui/panels/notification-panel/notif-center/init.lua @@ -0,0 +1,26 @@ +local wibox = require("wibox") +local gears = require("gears") +local beautiful = require("beautiful") +local dpi = beautiful.xresources.apply_dpi + +local notif_center = function(s) + s.notifbox_layout = require("ui.panels.notification-panel.notif-center.build-notifbox").notifbox_layout + + return wibox.widget({ + { + { + s.notifbox_layout, + layout = wibox.layout.fixed.vertical, + }, + margins = dpi(10), + widget = wibox.container.margin, + }, + bg = beautiful.widget_bg, + shape = function(cr, w, h) + gears.shape.rounded_rect(cr, w, h, beautiful.border_radius) + end, + widget = wibox.container.background, + }) +end + +return notif_center diff --git a/config/awesome/ui/popups/brightness.lua b/config/awesome/ui/popups/brightness.lua new file mode 100755 index 0000000..10165bd --- /dev/null +++ b/config/awesome/ui/popups/brightness.lua @@ -0,0 +1,122 @@ +local gears = require("gears") +local awful = require("awful") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") +local animation = require("modules.animation") + +local brightness_osd_icon = wibox.widget({ + { + id = "popup_icon", + markup = helpers.ui.colorize_text("", beautiful.xforeground), + font = beautiful.icon_font .. "Round 96", + align = "center", + valign = "center", + widget = wibox.widget.textbox(), + }, + forced_height = dpi(150), + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin, +}) + +local brightness_osd_bar = wibox.widget({ + nil, + { + id = "brightness_osd_progressbar", + max_value = 100, + value = 0, + background_color = "#ffffff20", + color = beautiful.xforeground, + shape = gears.shape.rounded_rect, + bar_shape = gears.shape.rounded_rect, + forced_height = dpi(24), + widget = wibox.widget.progressbar, + }, + nil, + expand = "none", + layout = wibox.layout.align.vertical, +}) + +local brightness_osd_height = dpi(200) +local brightness_osd_width = dpi(200) + +screen.connect_signal("request::desktop_decoration", function(s) + s.brightness_osd = awful.popup({ + type = "notification", + screen = s, + height = brightness_osd_height, + width = brightness_osd_width, + maximum_height = brightness_osd_height, + maximum_width = brightness_osd_width, + bg = beautiful.transparent, + ontop = true, + visible = false, + widget = { + { + { + layout = wibox.layout.fixed.vertical, + { + { + layout = wibox.layout.align.horizontal, + expand = "none", + nil, + brightness_osd_icon, + nil, + }, + brightness_osd_bar, + spacing = dpi(10), + layout = wibox.layout.fixed.vertical, + }, + }, + left = dpi(24), + right = dpi(24), + bottom = dpi(24), + widget = wibox.container.margin, + }, + bg = beautiful.xbackground, + shape = gears.shape.rounded_rect, + widget = wibox.container.background, + }, + }) + + awful.placement.centered(s.brightness_osd) + + local anim = animation:new({ + pos = 0, + duration = 0.2, + easing = animation.easing.linear, + update = function(self, pos) + brightness_osd_bar.brightness_osd_progressbar.value = pos + end, + }) + + local hide_timer = gears.timer({ + timeout = 2, + callback = function() + s.brightness_osd.visible = false + end, + }) + + local show = false + awesome.connect_signal("signal::brightness", function(value) + if show == true then + anim:set(value) + + brightness_osd_bar.brightness_osd_progressbar.value = value + brightness_osd_bar.brightness_osd_progressbar.color = beautiful.xforeground + + if s.brightness_osd.visible then + hide_timer:again() + else + s.brightness_osd.visible = true + hide_timer:again() + end + else + brightness_osd_bar.brightness_osd_progressbar.value = value + show = true + end + end) +end) diff --git a/config/awesome/ui/popups/init.lua b/config/awesome/ui/popups/init.lua new file mode 100755 index 0000000..d60d93b --- /dev/null +++ b/config/awesome/ui/popups/init.lua @@ -0,0 +1,3 @@ +require(... .. ".brightness") +require(... .. ".layoutlist") +require(... .. ".volume") diff --git a/config/awesome/ui/popups/layoutlist.lua b/config/awesome/ui/popups/layoutlist.lua new file mode 100755 index 0000000..8c1e16a --- /dev/null +++ b/config/awesome/ui/popups/layoutlist.lua @@ -0,0 +1,102 @@ +local gears = require("gears") +local awful = require("awful") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") + +--- Layout list +screen.connect_signal("request::desktop_decoration", function(s) + local layout_list = 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, + }, + }) + + local layout_popup = awful.popup({ + widget = wibox.widget({ + { layout_list, margins = dpi(24), widget = wibox.container.margin }, + bg = beautiful.xbackground, + shape = helpers.ui.rrect(beautiful.border_radius), + widget = wibox.container.background, + }), + placement = awful.placement.centered, + ontop = true, + visible = false, + bg = beautiful.xbackground .. "00", + }) + + 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 = { + { + { mod, "Shift" }, + " ", + function() + awful.layout.set( + gears.table.iterate_value(layout_list.layouts, layout_list.current_layout, -1), + nil + ) + end, + }, + { + { mod }, + " ", + function() + awful.layout.set(gears.table.iterate_value(layout_list.layouts, layout_list.current_layout, 1), nil) + end, + }, + }, + }) +end) diff --git a/config/awesome/ui/popups/volume.lua b/config/awesome/ui/popups/volume.lua new file mode 100755 index 0000000..5ecbb14 --- /dev/null +++ b/config/awesome/ui/popups/volume.lua @@ -0,0 +1,131 @@ +local gears = require("gears") +local awful = require("awful") +local beautiful = require("beautiful") +local xresources = require("beautiful.xresources") +local dpi = xresources.apply_dpi +local wibox = require("wibox") +local helpers = require("helpers") +local animation = require("modules.animation") + +local volume_osd_icon = wibox.widget({ + { + id = "popup_icon", + markup = helpers.ui.colorize_text("", beautiful.xforeground), + font = beautiful.icon_font .. "Round 96", + align = "center", + valign = "center", + widget = wibox.widget.textbox(), + }, + forced_height = dpi(150), + top = dpi(12), + bottom = dpi(12), + widget = wibox.container.margin, +}) + +local volume_osd_bar = wibox.widget({ + nil, + { + id = "volume_osd_progressbar", + max_value = 100, + value = 0, + background_color = "#ffffff20", + color = beautiful.xforeground, + shape = gears.shape.rounded_rect, + bar_shape = gears.shape.rounded_rect, + forced_height = dpi(24), + widget = wibox.widget.progressbar, + }, + nil, + expand = "none", + layout = wibox.layout.align.vertical, +}) + +local volume_osd_height = dpi(200) +local volume_osd_width = dpi(200) + +screen.connect_signal("request::desktop_decoration", function(s) + s.volume_osd = awful.popup({ + type = "notification", + screen = s, + height = volume_osd_height, + width = volume_osd_width, + maximum_height = volume_osd_height, + maximum_width = volume_osd_width, + bg = beautiful.transparent, + ontop = true, + visible = false, + widget = { + { + { + layout = wibox.layout.fixed.vertical, + { + { + layout = wibox.layout.align.horizontal, + expand = "none", + nil, + volume_osd_icon, + nil, + }, + volume_osd_bar, + spacing = dpi(10), + layout = wibox.layout.fixed.vertical, + }, + }, + left = dpi(24), + right = dpi(24), + bottom = dpi(24), + widget = wibox.container.margin, + }, + bg = beautiful.xbackground, + shape = gears.shape.rounded_rect, + widget = wibox.container.background, + }, + }) + + awful.placement.centered(s.volume_osd) + + local anim = animation:new({ + pos = 0, + duration = 0.2, + easing = animation.easing.linear, + update = function(self, pos) + volume_osd_bar.volume_osd_progressbar.value = pos + end, + }) + + local hide_timer = gears.timer({ + timeout = 2, + callback = function() + s.volume_osd.visible = false + end, + }) + + local show = false + awesome.connect_signal("signal::volume", function(value, muted) + if show == true then + if muted == 1 or value == 0 then + anim:set(0) + + volume_osd_icon.popup_icon:set_markup_silently(helpers.ui.colorize_text("", beautiful.xcolor8)) + volume_osd_bar.volume_osd_progressbar.color = beautiful.xcolor8 + else + anim:set(value) + + volume_osd_icon.popup_icon:set_markup_silently(helpers.ui.colorize_text("", beautiful.xforeground)) + volume_osd_bar.volume_osd_progressbar.color = beautiful.xforeground + end + + volume_osd_bar.volume_osd_progressbar.value = value + + if s.volume_osd.visible then + hide_timer:again() + else + s.volume_osd.visible = true + hide_timer:again() + end + else + volume_osd_bar.volume_osd_progressbar.value = value + show = true + end + end) +end) diff --git a/config/awesome/ui/tooltip/init.lua b/config/awesome/ui/tooltip/init.lua deleted file mode 100644 index 5968826..0000000 --- a/config/awesome/ui/tooltip/init.lua +++ /dev/null @@ -1,348 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local awful = require("awful") - --- Theme handling library -local beautiful = require("beautiful") -local xresources = require("beautiful.xresources") -local dpi = xresources.apply_dpi - --- Widget library -local wibox = require("wibox") - --- rubato -local rubato = require("module.rubato") - --- Helpers -local helpers = require("helpers") - --- Get screen geometry -local screen_width = awful.screen.focused().geometry.width -local screen_height = awful.screen.focused().geometry.height - - --- Helpers -------------- - -local function create_boxed_widget(widget_to_be_boxed, width, height, inner_pad) - local box_container = wibox.container.background() - box_container.bg = beautiful.xcolor0 - box_container.forced_height = height - box_container.forced_width = width - box_container.shape = helpers.rrect(beautiful.tooltip_box_border_radius) - - local inner = dpi(0) - - if inner_pad then inner = beautiful.tooltip_box_margin end - - local boxed_widget = wibox.widget { - -- Add margins - { - -- Add background color - { - -- The actual widget goes here - widget_to_be_boxed, - margins = inner, - widget = wibox.container.margin - }, - widget = box_container, - }, - margins = beautiful.tooltip_gap / 2, - color = "#FF000000", - widget = wibox.container.margin - } - - return boxed_widget -end - - --- Battery -------------- - -local batt_bar = wibox.widget { - max_value = 100, - value = 20, - background_color = beautiful.transparent, - color = beautiful.xcolor8, - widget = wibox.widget.progressbar -} - -local batt_bar_container = wibox.widget { - batt_bar, - direction = "east", - widget = wibox.container.rotate -} - -local batt_icon = wibox.widget{ - markup = helpers.colorize_text("", beautiful.xcolor1), - font = beautiful.icon_font_name .. "Round 18", - align = "center", - valign = "center", - widget = wibox.widget.textbox -} - -local batt_icon_container = wibox.widget{ - nil, - { - nil, - batt_icon, - expand = "none", - layout = wibox.layout.align.vertical - }, - expand = "none", - layout = wibox.layout.align.horizontal -} - -local batt = wibox.widget{ - batt_bar_container, - batt_icon_container, - layout = wibox.layout.stack -} - -local batt_val = 0 -local batt_charger - -awesome.connect_signal("signal::battery", function(value) - batt_val = value - awesome.emit_signal("widget::battery") -end) - -awesome.connect_signal("signal::charger", function(state) - batt_charger = state - awesome.emit_signal("widget::battery") -end) - -awesome.connect_signal("widget::battery", function() - local b = "" - local fill_color = beautiful.xcolor2 - - if batt_val >= 88 and batt_val <= 100 then - b = "" - elseif batt_val >= 76 and batt_val < 88 then - b = "" - elseif batt_val >= 64 and batt_val < 76 then - b = "" - elseif batt_val >= 52 and batt_val < 64 then - b = "" - elseif batt_val >= 40 and batt_val < 52 then - b = "" - elseif batt_val >= 28 and batt_val < 40 then - b = "" - elseif batt_val >= 16 and batt_val < 28 then - b = "" - else - b = "" - end - - if batt_charger then - b = "" - if batt_val >= 11 and batt_val <= 30 then - fill_color = beautiful.xcolor3 - elseif batt_val <= 10 then - fill_color = beautiful.xcolor1 - end - else - if batt_val >= 11 and batt_val <= 30 then - fill_color = beautiful.xcolor3 - elseif batt_val <= 10 then - fill_color = beautiful.xcolor1 - end - end - - batt_bar.value = batt_val - batt_icon.markup = helpers.colorize_text(b, fill_color) -end) - - --- Date ----------- - -local date_day = wibox.widget{ - font = beautiful.font_name .. "bold 10", - format = helpers.colorize_text("%A", beautiful.xcolor4), - align = "center", - valign = "center", - widget = wibox.widget.textclock -} - -local date_month = wibox.widget{ - font = beautiful.font_name .. "bold 14", - format = "%d %B %Y", - align = "center", - valign = "center", - widget = wibox.widget.textclock -} - -local date = wibox.widget{ - date_day, - nil, - date_month, - layout = wibox.layout.align.vertical -} - - --- Separator ---------------- - -local separator = wibox.widget{ - { - bg = beautiful.xcolor5, - shape = helpers.rrect(dpi(5)), - forced_width = dpi(3), - widget = wibox.container.background - }, - right = dpi(5), - widget = wibox.container.margin -} - - --- Analog clock ------------------- - -local analog_clock = require("ui.widgets.analog_clock") - - --- Wifi ----------- - -local wifi_status_icon = wibox.widget{ - markup = "Offline", - font = beautiful.icon_font_name .. "Round 14", - valign = "center", - align = "center", - widget = wibox.widget.textbox -} - -local wifi = wibox.widget{ - wifi_status_icon, - forced_width = dpi(30), - forced_height = dpi(30), - bg = beautiful.xcolor8, - shape = gears.shape.circle, - widget = wibox.container.background -} - -local wifi_status = false - -awesome.connect_signal("signal::network", function(status, ssid) - wifi_status = status - awesome.emit_signal("widget::network") -end) - -awesome.connect_signal("widget::network", function () - local w, fill_color - if wifi_status == true then - w = "" - fill_color = beautiful.xcolor2 - else - w = "" - fill_color = beautiful.xcolor1 - end - - wifi.shape_border_color = fill_color - wifi_status_icon.markup = helpers.colorize_text(w, fill_color) -end) - - --- UpTime ------------- - -local uptime_label = wibox.widget{ - font = beautiful.font_name .. "medium 9", - markup = helpers.colorize_text("Uptime", beautiful.xcolor5), - valign = "center", - widget = wibox.widget.textbox -} - -local uptime_text = wibox.widget { - font = beautiful.font_name .. "bold 13", - markup = helpers.colorize_text("-", beautiful.xcolor5), - valign = "center", - widget = wibox.widget.textbox -} - -awesome.connect_signal("signal::uptime", function(uptime_value) - uptime_text.markup = uptime_value -end) - -local uptime_container = wibox.widget{ - separator, - { - uptime_label, - nil, - uptime_text, - layout = wibox.layout.align.vertical - }, - { - wifi, - layout = wibox.layout.align.vertical - }, - layout = wibox.layout.align.horizontal -} - - --- Widget ------------- - -local batt_boxed = create_boxed_widget(batt, dpi(50), dpi(110)) -local uptime_boxed = create_boxed_widget(uptime_container, dpi(170), dpi(50), true) -local analog_clock_boxed = create_boxed_widget(analog_clock, dpi(110), dpi(110), true) - - --- Tooltip setup -------------------- - -stats_tooltip = wibox({ - type = "dock", - screen = screen.primary, - height = beautiful.tooltip_height, - width = beautiful.tooltip_width, - shape = helpers.rrect(beautiful.tooltip_border_radius), - bg = beautiful.transparent, - ontop = true, - visible = false -}) - -awful.placement.bottom_left(stats_tooltip, { - margins = { - left = beautiful.wibar_width + 55, - bottom = dpi(33) - } -}) - -stats_tooltip_show = function() - stats_tooltip.visible = true -end - -stats_tooltip_hide = function() - stats_tooltip.visible = false -end - -stats_tooltip:setup { - { - { - { - { - date, - { - analog_clock_boxed, - batt_boxed, - layout = wibox.layout.fixed.horizontal - }, - layout = wibox.layout.fixed.vertical - }, - layout = wibox.layout.fixed.horizontal - }, - { - uptime_boxed, - layout = wibox.layout.fixed.horizontal - }, - layout = wibox.layout.fixed.vertical - }, - margins = beautiful.tooltip_gap, - widget = wibox.container.margin - }, - shape = helpers.rrect(beautiful.tooltip_border_radius), - bg = beautiful.tooltip_bg, - widget = wibox.container.background -} diff --git a/config/awesome/ui/widgets/airplane-mode/init.lua b/config/awesome/ui/widgets/airplane-mode/init.lua deleted file mode 100755 index 23aa198..0000000 --- a/config/awesome/ui/widgets/airplane-mode/init.lua +++ /dev/null @@ -1,171 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") -local config_dir = gears.filesystem.get_configuration_dir() -local widget_dir = config_dir .. "ui/widgets/airplane-mode/" -local widget_icon_dir = widget_dir .. "icons/" -local ap_state = false - -local action_name = wibox.widget({ - text = "Airplane Mode", - font = beautiful.font_name .. "Bold 12", - align = "left", - widget = wibox.widget.textbox, -}) - -local action_status = wibox.widget({ - text = "Off", - font = beautiful.font_name .. "11", - align = "left", - widget = wibox.widget.textbox, -}) - -local action_info = wibox.widget({ - layout = wibox.layout.fixed.vertical, - action_name, - action_status, -}) - -local button_widget = wibox.widget({ - { - id = "icon", - image = gears.color.recolor_image(widget_icon_dir .. "airplane-mode-off.svg", beautiful.xforeground), - widget = wibox.widget.imagebox, - resize = true, - }, - layout = wibox.layout.align.horizontal, -}) - -local widget_button = wibox.widget({ - { - { - button_widget, - margins = dpi(15), - forced_height = dpi(48), - forced_width = dpi(48), - widget = wibox.container.margin, - }, - widget = clickable_container, - }, - bg = beautiful.control_center_button_bg, - shape = gears.shape.circle, - widget = wibox.container.background, -}) - -local update_widget = function() - if ap_state then - action_status:set_text("On") - widget_button.bg = beautiful.accent - button_widget.icon:set_image( - gears.color.recolor_image(widget_icon_dir .. "airplane-mode.svg", beautiful.xforeground) - ) - else - action_status:set_text("Off") - widget_button.bg = beautiful.control_center_button_bg - button_widget.icon:set_image( - gears.color.recolor_image(widget_icon_dir .. "airplane-mode-off.svg", beautiful.xforeground) - ) - end -end - -local check_airplane_mode_state = function() - local cmd = "cat " .. widget_dir .. "airplane_mode" - - awful.spawn.easy_async_with_shell(cmd, function(stdout) - local status = stdout - - if status:match("true") then - ap_state = true - elseif status:match("false") then - ap_state = false - else - ap_state = false - awful.spawn.easy_async_with_shell('echo "false" > ' .. widget_dir .. "airplane_mode", function(stdout) end) - end - update_widget() - end) -end - -check_airplane_mode_state() - -local ap_off_cmd = [[ - - rfkill unblock wlan - - # Create an AwesomeWM Notification - awesome-client " - naughty = require('naughty') - naughty.notification({ - app_name = 'Network Manager', - title = 'Airplane mode disabled!', - message = 'Initializing network devices', - icon = ']] .. widget_icon_dir .. "airplane-mode-off" .. ".svg" .. [[' - }) - " - ]] .. "echo false > " .. widget_dir .. "airplane_mode" .. [[ -]] - -local ap_on_cmd = [[ - - rfkill block wlan - - # Create an AwesomeWM Notification - awesome-client " - naughty = require('naughty') - naughty.notification({ - app_name = 'Network Manager', - title = 'Airplane mode enabled!', - message = 'Disabling radio devices', - icon = ']] .. widget_icon_dir .. "airplane-mode" .. ".svg" .. [[' - }) - " - ]] .. "echo true > " .. widget_dir .. "airplane_mode" .. [[ -]] - -local toggle_action = function() - if ap_state then - awful.spawn.easy_async_with_shell(ap_off_cmd, function(stdout) - ap_state = false - update_widget() - end) - else - awful.spawn.easy_async_with_shell(ap_on_cmd, function(stdout) - ap_state = true - update_widget() - end) - end -end - -widget_button:buttons(gears.table.join(awful.button({}, 1, nil, function() - toggle_action() -end))) - -action_info:buttons(gears.table.join(awful.button({}, 1, nil, function() - toggle_action() -end))) - -gears.timer({ - timeout = 5, - autostart = true, - callback = function() - check_airplane_mode_state() - end, -}) - -local action_widget = wibox.widget({ - layout = wibox.layout.fixed.horizontal, - spacing = dpi(10), - widget_button, - { - layout = wibox.layout.align.vertical, - expand = "none", - nil, - action_info, - nil, - }, -}) - -return action_widget diff --git a/config/awesome/ui/widgets/analog-clock/init.lua b/config/awesome/ui/widgets/analog-clock.lua old mode 100644 new mode 100755 similarity index 100% rename from config/awesome/ui/widgets/analog-clock/init.lua rename to config/awesome/ui/widgets/analog-clock.lua diff --git a/config/awesome/ui/widgets/analog_clock.lua b/config/awesome/ui/widgets/analog_clock.lua deleted file mode 100644 index 886c256..0000000 --- a/config/awesome/ui/widgets/analog_clock.lua +++ /dev/null @@ -1,79 +0,0 @@ --- Standard awesome library -local gears = require("gears") -local wibox = require("wibox") -local math = require("math") - --- Theme handling library -local beautiful = require("beautiful") - --- C libraries -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) - local cr = cairo.Context(img) - local angle = (minute / 60) * 2 * math.pi - cr:translate(500, 500) - cr:rotate(angle) - cr:translate(-500, -500) - cr:set_source(gears.color(beautiful.xforeground)) - cr:rectangle(485, 100, 30, 420) - cr:fill() - return img -end - -local function create_hour_pointer(hour) - local img = cairo.ImageSurface(cairo.Format.ARGB32, 1000, 1000) - local cr = cairo.Context(img) - local angle = ((hour % 12) / 12) * 2 * math.pi - cr:translate(500, 500) - cr:rotate(angle) - cr:translate(-500, -500) - cr:set_source(gears.color(beautiful.xcolor4)) - cr:rectangle(480, 200, 40, 320) - cr:fill() - return img -end - -local minute_pointer = create_minute_pointer(37) -local hour_pointer = create_hour_pointer(17) - -local minute_pointer_img = wibox.widget.imagebox() -local hour_pointer_img = wibox.widget.imagebox() - -local analog_clock = wibox.widget { - { -- circle - wibox.widget.textbox(""), - shape = function(cr, width, height) gears.shape.circle(cr, width, height, height / 2) end, - shape_border_width = 4, - shape_border_color = beautiful.xcolor8, - bg = "alpha", - widget = wibox.container.background - }, - minute_pointer_img, - hour_pointer_img, - layout = wibox.layout.stack -} - -local minute = 0 -local hour = 0 - -gears.timer { - timeout = 30, - call_now = true, - autostart = true, - callback = function() - minute = os.date("%M") - hour = os.date("%H") - minute_pointer = create_minute_pointer(minute) - hour_pointer = create_hour_pointer(hour + (minute / 60)) - minute_pointer_img.image = minute_pointer - hour_pointer_img.image = hour_pointer - end -} - -return analog_clock diff --git a/config/awesome/ui/widgets/arc/cpu_arc.lua b/config/awesome/ui/widgets/arc/cpu_arc.lua deleted file mode 100644 index 1fe2bd1..0000000 --- a/config/awesome/ui/widgets/arc/cpu_arc.lua +++ /dev/null @@ -1,27 +0,0 @@ -local awful = require("awful") -local watch = awful.widget.watch -local wibox = require("wibox") -local beautiful = require("beautiful") -local xresources = require("beautiful.xresources") -local dpi = xresources.apply_dpi - -local active_color = beautiful.accent - -local cpu_arc = wibox.widget({ - start_angle = 3 * math.pi / 2, - min_value = 0, - max_value = 100, - value = 50, - thickness = dpi(8), - rounded_edge = true, - bg = active_color .. "44", - paddings = dpi(10), - colors = { active_color }, - widget = wibox.container.arcchart, -}) - -awesome.connect_signal("signal::cpu", function(value) - cpu_arc.value = value -end) - -return cpu_arc diff --git a/config/awesome/ui/widgets/arc/disk_arc.lua b/config/awesome/ui/widgets/arc/disk_arc.lua deleted file mode 100644 index 55d60d7..0000000 --- a/config/awesome/ui/widgets/arc/disk_arc.lua +++ /dev/null @@ -1,27 +0,0 @@ -local awful = require("awful") -local watch = awful.widget.watch -local wibox = require("wibox") -local beautiful = require("beautiful") -local xresources = require("beautiful.xresources") -local dpi = xresources.apply_dpi - -local active_color = beautiful.accent - -local disk_arc = wibox.widget({ - start_angle = 3 * math.pi / 2, - min_value = 0, - max_value = 100, - value = 50, - thickness = dpi(8), - rounded_edge = true, - bg = active_color .. "44", - paddings = dpi(10), - colors = { active_color }, - widget = wibox.container.arcchart, -}) - -awesome.connect_signal("signal::disk", function(used, total) - disk_arc.value = used * 100 / total -end) - -return disk_arc diff --git a/config/awesome/ui/widgets/arc/ram_arc.lua b/config/awesome/ui/widgets/arc/ram_arc.lua deleted file mode 100644 index 02507dc..0000000 --- a/config/awesome/ui/widgets/arc/ram_arc.lua +++ /dev/null @@ -1,31 +0,0 @@ -local awful = require("awful") -local watch = awful.widget.watch -local wibox = require("wibox") -local beautiful = require("beautiful") -local xresources = require("beautiful.xresources") -local dpi = xresources.apply_dpi - -local active_color = beautiful.accent - -local ram_arc = wibox.widget({ - start_angle = 3 * math.pi / 2, - min_value = 0, - max_value = 100, - value = 50, - thickness = dpi(8), - rounded_edge = true, - bg = active_color .. "44", - paddings = dpi(10), - colors = { active_color }, - widget = wibox.container.arcchart, -}) - -watch('bash -c "free | grep -z Mem.*Swap.*"', 10, function(_, stdout) - local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap = stdout:match( - "(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)" - ) - ram_arc:set_value(used / total * 100) - collectgarbage("collect") -end) - -return ram_arc diff --git a/config/awesome/ui/widgets/arc/temp_arc.lua b/config/awesome/ui/widgets/arc/temp_arc.lua deleted file mode 100644 index e3d0997..0000000 --- a/config/awesome/ui/widgets/arc/temp_arc.lua +++ /dev/null @@ -1,58 +0,0 @@ -local awful = require("awful") -local watch = awful.widget.watch -local wibox = require("wibox") -local beautiful = require("beautiful") -local xresources = require("beautiful.xresources") -local dpi = xresources.apply_dpi - -local active_color = beautiful.accent - -local temp_arc = wibox.widget({ - start_angle = 3 * math.pi / 2, - min_value = 0, - max_value = 100, - value = 50, - thickness = dpi(8), - rounded_edge = true, - bg = active_color .. "44", - paddings = dpi(10), - colors = { active_color }, - widget = wibox.container.arcchart, -}) - -local max_temp = 80 - -awful.spawn.easy_async_with_shell( - [[ - temp_path=null - for i in /sys/class/hwmon/hwmon*/temp*_input; - do - temp_path="$(echo "$(<$(dirname $i)/name): $(cat ${i%_*}_label 2>/dev/null || - echo $(basename ${i%_*})) $(readlink -f $i)");" - - label="$(echo $temp_path | awk '{print $2}')" - - if [ "$label" = "Package" ]; - then - echo ${temp_path} | awk '{print $5}' | tr -d ';\n' - exit; - fi - done - ]], - function(stdout) - local temp_path = stdout:gsub("%\n", "") - if temp_path == "" or not temp_path then - temp_path = "/sys/class/thermal/thermal_zone0/temp" - end - - watch([[ - sh -c "cat ]] .. temp_path .. [[" - ]], 10, function(_, stdout) - local temp = stdout:match("(%d+)") - temp_arc:set_value((temp / 1000) / max_temp * 100) - collectgarbage("collect") - end) - end -) - -return temp_arc diff --git a/config/awesome/ui/widgets/blue-light/icons/blue-light-off.svg b/config/awesome/ui/widgets/blue-light/icons/blue-light-off.svg deleted file mode 100644 index cd6572a..0000000 --- a/config/awesome/ui/widgets/blue-light/icons/blue-light-off.svg +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/config/awesome/ui/widgets/blue-light/icons/blue-light.svg b/config/awesome/ui/widgets/blue-light/icons/blue-light.svg deleted file mode 100644 index c0d42cc..0000000 --- a/config/awesome/ui/widgets/blue-light/icons/blue-light.svg +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - diff --git a/config/awesome/ui/widgets/blue-light/init.lua b/config/awesome/ui/widgets/blue-light/init.lua deleted file mode 100644 index 5073592..0000000 --- a/config/awesome/ui/widgets/blue-light/init.lua +++ /dev/null @@ -1,137 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") -local config_dir = gears.filesystem.get_configuration_dir() -local widget_dir = config_dir .. "ui/widgets/blue-light/" -local widget_icon_dir = widget_dir .. "icons/" - -local blue_light_state = false - -local action_name = wibox.widget({ - text = "Blue Light", - font = beautiful.font_name .. "Bold 12", - align = "left", - widget = wibox.widget.textbox, -}) - -local action_status = wibox.widget({ - text = "Off", - font = beautiful.font_name .. "11", - align = "left", - widget = wibox.widget.textbox, -}) - -local action_info = wibox.widget({ - layout = wibox.layout.fixed.vertical, - action_name, - action_status, -}) - -local button_widget = wibox.widget({ - { - id = "icon", - image = gears.color.recolor_image(widget_icon_dir .. "blue-light-off.svg", beautiful.xforeground), - widget = wibox.widget.imagebox, - resize = true, - }, - layout = wibox.layout.align.horizontal, -}) - -local widget_button = wibox.widget({ - { - { - button_widget, - margins = dpi(15), - forced_height = dpi(48), - forced_width = dpi(48), - widget = wibox.container.margin, - }, - widget = clickable_container, - }, - bg = beautiful.control_center_button_bg, - shape = gears.shape.circle, - widget = wibox.container.background, -}) - -local update_widget = function() - if blue_light_state then - action_status:set_text("On") - widget_button.bg = beautiful.accent - button_widget.icon:set_image( - gears.color.recolor_image(widget_icon_dir .. "blue-light.svg", beautiful.xforeground) - ) - else - action_status:set_text("Off") - widget_button.bg = beautiful.control_center_button_bg - button_widget.icon:set_image( - gears.color.recolor_image(widget_icon_dir .. "blue-light-off.svg", beautiful.xforeground) - ) - end -end - -local kill_state = function() - awful.spawn.easy_async_with_shell( - [[ - redshift -x - kill -9 $(pgrep redshift) - ]], - function(stdout) - stdout = tonumber(stdout) - if stdout then - blue_light_state = false - update_widget() - end - end - ) -end - -kill_state() - -local toggle_action = function() - awful.spawn.easy_async_with_shell( - [[ - if [ ! -z $(pgrep redshift) ]; - then - redshift -x && pkill redshift && killall redshift - echo 'OFF' - else - redshift -l 0:0 -t 4500:4500 -r &>/dev/null & - echo 'ON' - fi - ]], - function(stdout) - if stdout:match("ON") then - blue_light_state = true - else - blue_light_state = false - end - update_widget() - end - ) -end - -widget_button:buttons(gears.table.join(awful.button({}, 1, nil, function() - toggle_action() -end))) - -action_info:buttons(gears.table.join(awful.button({}, 1, nil, function() - toggle_action() -end))) - -local action_widget = wibox.widget({ - layout = wibox.layout.fixed.horizontal, - spacing = dpi(10), - widget_button, - { - layout = wibox.layout.align.vertical, - expand = "none", - nil, - action_info, - nil, - }, -}) - -return action_widget diff --git a/config/awesome/ui/widgets/button.lua b/config/awesome/ui/widgets/button.lua deleted file mode 100644 index a6311da..0000000 --- a/config/awesome/ui/widgets/button.lua +++ /dev/null @@ -1,59 +0,0 @@ -local wibox = require('wibox') -local beautiful = require('beautiful') - -local create_click_events = function(widget) - - local container = wibox.widget { - widget, - widget = wibox.container.background - } - - -- Old and new widget - local old_cursor, old_wibox - - -- Mouse hovers on the widget - container:connect_signal( - 'mouse::enter', - function() - container.bg = beautiful.xcolor8 - -- Hm, no idea how to get the wibox from this signal's arguments... - local w = mouse.current_wibox - if w then - old_cursor, old_wibox = w.cursor, w - w.cursor = 'hand1' - end - end - ) - - -- Mouse leaves the widget - container:connect_signal( - 'mouse::leave', - function() - container.bg = beautiful.transparent - if old_wibox then - old_wibox.cursor = old_cursor - old_wibox = nil - end - end - ) - - -- Mouse pressed the widget - container:connect_signal( - 'button::press', - function() - container.bg = beautiful.xcolor4 - end - ) - - -- Mouse releases the widget - container:connect_signal( - 'button::release', - function() - container.bg = beautiful.xcolor8 - end - ) - - return container -end - -return create_click_events diff --git a/config/awesome/ui/widgets/button/elevated.lua b/config/awesome/ui/widgets/button/elevated.lua new file mode 100755 index 0000000..c32857d --- /dev/null +++ b/config/awesome/ui/widgets/button/elevated.lua @@ -0,0 +1,453 @@ +------------------------------------------- +-- @author https://github.com/Kasper24 +-- @copyright 2021-2022 Kasper24 +------------------------------------------- + +local wcontainer = require("ui.widgets.container") +local beautiful = require("beautiful") +local animation = require("modules.animation") +local helpers = require("helpers") +local dpi = beautiful.xresources.apply_dpi +local setmetatable = setmetatable +local string = string + +local elevated_button = { mt = {} } + +local function effect(widget, bg, shape, border_width, border_color) + local animation_targets = {} + + if bg ~= nil then + animation_targets.color = helpers.color.hex_to_rgb(bg) + end + if shape ~= nil then + widget:get_children_by_id("background_role")[1].shape = shape + end + if border_width ~= nil then + animation_targets.border_width = border_width + end + if border_color ~= nil then + animation_targets.border_color = helpers.color.hex_to_rgb(border_color) + end + + widget.animation:set(animation_targets) +end + +local function button(args) + args.forced_width = args.forced_width or nil + args.forced_height = args.forced_height or nil + args.margins = args.margins or dpi(0) + args.paddings = args.paddings or dpi(10) + args.halign = args.halign or "center" + args.valign = args.valign or "center" + + args.bg = args.normal_bg or beautiful.xbackground + args.shape = args.normal_shape or helpers.ui.rrect(beautiful.border_radius) + args.border_width = args.normal_border_width or nil + args.border_color = args.normal_border_color or beautiful.transparent + + args.hover_effect = args.hover_effect == nil and true or args.hover_effect + + local widget = wcontainer(args) + + if args.hover_effect == true then + helpers.ui.add_hover_cursor(widget, "hand1") + end + + widget.animation = animation:new({ + pos = { + color = helpers.color.hex_to_rgb(args.normal_bg), + border_width = args.normal_border_width, + border_color = helpers.color.hex_to_rgb(args.normal_border_color), + }, + easing = animation.easing.linear, + duration = 0.2, + update = function(self, pos) + if pos.color then + widget:get_children_by_id("background_role")[1].bg = helpers.color.rgb_to_hex(pos.color) + end + if pos.border_width then + widget:get_children_by_id("background_role")[1].border_width = pos.border_width + end + if pos.border_color then + widget:get_children_by_id("background_role")[1].border_color = helpers.color.rgb_to_hex( + pos.border_color + ) + end + end, + }) + + return widget +end + +function elevated_button.state(args) + args = args or {} + + args.normal_bg = args.normal_bg or beautiful.xbackground + args.hover_bg = args.hover_bg or helpers.color.button_color(args.normal_bg, 0.1) + args.press_bg = args.press_bg or helpers.color.button_color(args.normal_bg, 0.2) + + args.on_normal_bg = args.on_normal_bg or args.press_bg + args.on_hover_bg = args.on_hover_bg or helpers.color.button_color(args.on_normal_bg, 0.1) + args.on_press_bg = args.on_press_bg or helpers.color.button_color(args.on_normal_bg, 0.2) + + args.normal_shape = args.normal_shape or helpers.ui.rrect(beautiful.border_radius) + args.hover_shape = args.hover_shape or nil + args.press_shape = args.press_shape or nil + args.on_normal_shape = args.on_normal_shape or nil + args.on_hover_shape = args.on_hover_shape or nil + args.on_press_shape = args.on_press_shape or nil + + args.normal_border_width = args.normal_border_width or nil + args.hover_border_width = args.hover_border_width or nil + args.press_border_width = args.press_border_width or nil + args.on_normal_border_width = args.on_normal_border_width or nil + args.on_hover_border_width = args.on_hover_border_width or nil + args.on_press_border_width = args.on_press_border_width or nil + + args.normal_border_color = args.normal_border_color or beautiful.transparent + args.hover_border_color = args.hover_border_color or beautiful.transparent + args.press_border_color = args.press_border_color or beautiful.transparent + args.on_normal_border_color = args.on_normal_border_color or beautiful.transparent + args.on_hover_border_color = args.on_hover_border_color or beautiful.transparent + args.on_press_border_color = args.on_press_border_color or beautiful.transparent + + args.on_hover = args.on_hover or nil + args.on_leave = args.on_leave or nil + + args.on_press = args.on_press or nil + args.on_release = args.on_release or nil + + args.on_secondary_press = args.on_secondary_press or nil + args.on_secondary_release = args.on_secondary_release or nil + + args.on_scroll_up = args.on_scroll_up or nil + args.on_scroll_down = args.on_scroll_down or nil + + args.on_turn_on = args.on_turn_on or nil + args.on_turn_off = args.on_turn_off or nil + + args.hover_effect = args.hover_effect == nil and true or args.hover_effect + + local widget = button(args) + widget._private.state = false + + function widget:turn_on() + if widget._private.state == false then + effect( + widget, + args.on_normal_bg, + args.on_normal_shape, + args.on_normal_border_width, + args.on_normal_border_color + ) + if args.child and args.child.on_turn_on ~= nil then + args.child:on_turn_on() + end + widget._private.state = true + end + end + + if args.on_by_default == true then + widget:turn_on() + end + + function widget:turn_off() + if widget._private.state == true then + effect(widget, args.normal_bg, args.normal_shape, args.normal_border_width, args.normal_border_color) + if args.child and args.child.on_turn_off ~= nil then + args.child:on_turn_off() + end + widget._private.state = false + end + end + + function widget:toggle() + if widget._private.state == true then + widget:turn_off() + else + widget:turn_on() + end + end + + widget:connect_signal("mouse::enter", function(self, find_widgets_result) + if args.hover_effect == false then + return + end + + if widget._private.state == true then + effect( + widget, + args.on_hover_bg, + args.on_hover_shape, + args.on_hover_border_width, + args.on_hover_border_color + ) + else + effect(widget, args.hover_bg, args.hover_shape, args.hover_border_width, args.hover_border_color) + end + if args.on_hover ~= nil then + args.on_hover(self, widget._private.state) + end + if args.child and args.child.on_hover ~= nil then + args.child:on_hover(self, widget._private.state) + end + end) + + widget:connect_signal("mouse::leave", function(self, find_widgets_result) + if widget.button ~= nil then + widget:emit_signal("button::release", 1, 1, widget.button, {}, find_widgets_result, true) + end + + if widget._private.state == true then + effect( + widget, + args.on_normal_bg, + args.on_normal_shape, + args.on_normal_border_width, + args.on_normal_border_color + ) + else + effect(widget, args.normal_bg, args.normal_shape, args.normal_border_width, args.normal_border_color) + end + if args.on_leave ~= nil then + args.on_leave(self, widget._private.state) + end + if args.child and args.child.on_leave ~= nil then + args.child:on_leave(self, widget._private.state) + end + end) + + widget:connect_signal("button::press", function(self, lx, ly, button, mods, find_widgets_result) + if #mods > 0 then + return + end + + widget.button = button + + if button == 1 then + if widget._private.state == true then + if args.on_turn_off then + widget:turn_off() + args.on_turn_off(self, lx, ly, button, mods, find_widgets_result) + elseif args.on_press then + args.on_press(self, lx, ly, button, mods, find_widgets_result) + end + else + if args.on_turn_on then + widget:turn_on() + args.on_turn_on(self, lx, ly, button, mods, find_widgets_result) + elseif args.on_press then + args.on_press(self, lx, ly, button, mods, find_widgets_result) + end + end + + if args.child and args.child.on_press ~= nil then + args.child:on_press(self, lx, ly, button, mods, find_widgets_result) + end + elseif button == 3 then + if args.child and args.child.on_secondary_press ~= nil then + args.child:on_secondary_press(self, lx, ly, button, mods, find_widgets_result) + end + if args.on_secondary_press ~= nil then + args.on_secondary_press(self, lx, ly, button, mods, find_widgets_result) + end + elseif button == 4 then + if args.on_scroll_up ~= nil then + args.on_scroll_up(self, lx, ly, button, mods, find_widgets_result) + end + elseif button == 5 then + if args.on_scroll_down ~= nil then + args.on_scroll_down(self, lx, ly, button, mods, find_widgets_result) + end + end + end) + + widget:connect_signal("button::release", function(self, lx, ly, button, mods, find_widgets_result, fake) + widget.button = nil + + if button == 1 then + if args.on_turn_on ~= nil or args.on_turn_off ~= nil or args.on_press then + if widget._private.state == true then + effect( + widget, + args.on_normal_bg, + args.on_normal_shape, + args.on_normal_border_width, + args.on_normal_border_color + ) + else + effect( + widget, + args.normal_bg, + args.normal_shape, + args.normal_border_width, + args.normal_border_color + ) + end + end + if args.child and args.child.on_release ~= nil then + args.child:on_release(self, lx, ly, button, mods, find_widgets_result) + end + if args.on_release ~= nil and fake ~= true then + args.on_release(self, lx, ly, button, mods, find_widgets_result) + end + elseif button == 3 then + if args.child and args.child.on_secondary_release ~= nil then + args.child:on_secondary_release(self, lx, ly, button, mods, find_widgets_result) + end + if args.on_secondary_release ~= nil and fake ~= true then + args.on_secondary_release(self, lx, ly, button, mods, find_widgets_result) + end + end + end) + + return widget +end + +function elevated_button.normal(args) + args = args or {} + + args.normal_bg = args.normal_bg or beautiful.xbackground + args.hover_bg = args.hover_bg or helpers.color.button_color(args.normal_bg, 0.1) + args.press_bg = args.press_bg or helpers.color.button_color(args.normal_bg, 0.2) + + args.normal_shape = args.normal_shape or helpers.ui.rrect(beautiful.border_radius) + args.hover_shape = args.hover_shape or nil + args.press_shape = args.press_shape or nil + + args.normal_border_width = args.normal_border_width or nil + args.hover_border_width = args.hover_border_width or nil + args.press_border_width = args.press_border_width or nil + + args.normal_border_color = args.normal_border_color or beautiful.transparent + args.hover_border_color = args.hover_border_color or beautiful.transparent + args.press_border_color = args.press_border_color or beautiful.transparent + + args.on_hover = args.on_hover or nil + args.on_leave = args.on_leave or nil + + args.on_press = args.on_press or nil + args.on_release = args.on_release or nil + + args.on_secondary_press = args.on_secondary_press or nil + args.on_secondary_release = args.on_secondary_release or nil + + args.on_scroll_up = args.on_scroll_up or nil + args.on_scroll_down = args.on_scroll_down or nil + + local widget = button(args) + + widget:connect_signal("mouse::enter", function(self, find_widgets_result) + effect(widget, args.hover_bg, args.hover_shape, args.hover_border_width, args.hover_border_color) + if args.on_hover ~= nil then + args.on_hover(self, find_widgets_result) + end + if args.child and args.child.on_hover ~= nil then + args.child:on_hover(self, find_widgets_result) + end + end) + + widget:connect_signal("mouse::leave", function(self, find_widgets_result) + if widget.button ~= nil then + if widget.button == 1 then + if args.on_release ~= nil or args.on_press ~= nil then + effect( + widget, + args.normal_bg, + args.normal_shape, + args.normal_border_width, + args.normal_border_color + ) + end + if args.child and args.child.on_release ~= nil then + args.child:on_release(self, 1, 1, widget.button, {}, find_widgets_result) + end + elseif widget.button == 3 then + if args.on_secondary_release ~= nil or args.on_secondary_press ~= nil then + effect( + widget, + args.normal_bg, + args.normal_shape, + args.normal_border_width, + args.normal_border_color + ) + end + if args.child and args.child.on_secondary_release ~= nil then + args.child:on_secondary_release(self, 1, 1, widget.button, {}, find_widgets_result) + end + end + widget.button = nil + end + effect(widget, args.normal_bg, args.normal_shape, args.normal_border_width, args.normal_border_color) + if args.on_leave ~= nil then + args.on_leave(self, find_widgets_result) + end + if args.child and args.child.on_leave ~= nil then + args.child:on_leave(self, find_widgets_result) + end + end) + + widget:connect_signal("button::press", function(self, lx, ly, button, mods, find_widgets_result) + if #mods > 0 then + return + end + + widget.button = button + if button == 1 then + if args.on_press ~= nil then + args.on_press(self, lx, ly, button, mods, find_widgets_result) + effect(widget, args.press_bg, args.press_shape, args.press_border_width, args.press_border_color) + end + + if args.child and args.child.on_press ~= nil then + args.child:on_press(self, lx, ly, button, mods, find_widgets_result) + end + elseif button == 3 then + if args.on_secondary_press ~= nil then + args.on_secondary_press(self, lx, ly, button, mods, find_widgets_result) + effect(widget, args.press_bg, args.press_shape, args.press_border_width, args.press_border_color) + + if args.child and args.child.on_secondary_press ~= nil then + args.child:on_secondary_press(self, lx, ly, button, mods, find_widgets_result) + end + end + elseif button == 4 then + if args.on_scroll_up ~= nil then + args.on_scroll_up(self, lx, ly, button, mods, find_widgets_result) + end + elseif button == 5 then + if args.on_scroll_down ~= nil then + args.on_scroll_down(self, lx, ly, button, mods, find_widgets_result) + end + end + end) + + widget:connect_signal("button::release", function(self, lx, ly, button, mods, find_widgets_result) + widget.button = nil + if button == 1 then + if args.on_release ~= nil or args.on_press ~= nil then + effect(widget, args.normal_bg, args.normal_shape, args.normal_border_width, args.normal_border_color) + end + if args.on_release ~= nil then + args.on_release(self, lx, ly, button, mods, find_widgets_result) + end + if args.child and args.child.on_release ~= nil then + args.child:on_release(self, lx, ly, button, mods, find_widgets_result) + end + elseif button == 3 then + if args.on_secondary_release ~= nil or args.on_secondary_press ~= nil then + effect(widget, args.normal_bg, args.normal_shape, args.normal_border_width, args.normal_border_color) + end + if args.on_secondary_release ~= nil then + args.on_secondary_release(self, lx, ly, button, mods, find_widgets_result) + end + if args.child and args.child.on_secondary_release ~= nil then + args.child:on_secondary_release(self, lx, ly, button, mods, find_widgets_result) + end + end + end) + + return widget +end + +return setmetatable(elevated_button, elevated_button.mt) diff --git a/config/awesome/ui/widgets/button/image.lua b/config/awesome/ui/widgets/button/image.lua new file mode 100755 index 0000000..df2a7c6 --- /dev/null +++ b/config/awesome/ui/widgets/button/image.lua @@ -0,0 +1,106 @@ +------------------------------------------- +-- @author https://github.com/Kasper24 +-- @copyright 2021-2022 Kasper24 +------------------------------------------- + +local gtable = require("gears.table") +local wibox = require("wibox") +local ewidget = require("ui.widgets.button.elevated") +local animation = require("modules.animation") +local setmetatable = setmetatable + +local image_button = { mt = {} } + +function image_button:set_image(image) + self._private.image:set_image(image) +end + +local function button(args, type) + args = args or {} + + args.image_width = args.image_width or nil + args.image_height = args.image_height or nil + args.image_halign = args.image_halign or "center" + args.image_valign = args.image_valign or "center" + args.horizontal_fit_policy = args.horizontal_fit_policy or "auto" + args.vertical_fit_policy = args.vertical_fit_policy or "auto" + args.image = args.image or nil + + local image_widget = wibox.widget({ + widget = wibox.widget.imagebox, + forced_width = args.image_width, + forced_height = args.image_height, + halign = args.image_halign, + valign = args.image_valign, + horizontal_fit_policy = args.horizontal_fit_policy, + vertical_fit_policy = args.vertical_fit_policy, + resize = true, + image = args.image, + }) + + args.child = image_widget + local widget = type == "normal" and ewidget.normal(args) or ewidget.state(args) + + gtable.crush(widget, image_button, true) + widget._private.image = image_widget + + widget.size_animation = animation:new({ + pos = 50, + easing = animation.easing.linear, + duration = 0.2, + update = function(self, pos) + image_widget.forced_width = pos + image_widget.forced_height = pos + end, + }) + + return widget, image_widget +end + +function image_button.state(args) + args = args or {} + + local widget, image_widget = button(args, "state") + + function image_widget:on_press() + widget.size_animation:set(20) + end + + function image_widget:on_release() + if widget.size_animation.state == true then + widget.size_animation.ended:subscribe(function() + widget.size_animation:set(50) + widget.size_animation.ended:unsubscribe() + end) + else + widget.size_animation:set(50) + end + end + + return widget +end + +function image_button.normal(args) + args = args or {} + + local widget, text_widget = button(args, "normal") + + function text_widget:on_press() + widget.size_animation:set(20) + end + + function text_widget:on_release() + if widget.size_animation.state == true then + widget.size_animation.ended:subscribe(function() + widget.size_animation:set(50) + widget.size_animation.ended:unsubscribe() + end) + else + widget.size_animation:set(50) + end + end + + return widget +end + +return setmetatable(image_button, image_button.mt) diff --git a/config/awesome/ui/widgets/button/init.lua b/config/awesome/ui/widgets/button/init.lua new file mode 100755 index 0000000..46a4682 --- /dev/null +++ b/config/awesome/ui/widgets/button/init.lua @@ -0,0 +1,5 @@ +return { + elevated = require("ui.widgets.button.elevated"), + image = require("ui.widgets.button.image"), + text = require("ui.widgets.button.text"), +} diff --git a/config/awesome/ui/widgets/button/text.lua b/config/awesome/ui/widgets/button/text.lua new file mode 100755 index 0000000..5e0e63c --- /dev/null +++ b/config/awesome/ui/widgets/button/text.lua @@ -0,0 +1,184 @@ +------------------------------------------- +-- @author https://github.com/Kasper24 +-- @copyright 2021-2022 Kasper24 +------------------------------------------- + +local gtable = require("gears.table") +local twidget = require("ui.widgets.text") +local ewidget = require("ui.widgets.button.elevated") +local beautiful = require("beautiful") +local animation = require("modules.animation") +local helpers = require("helpers") +local setmetatable = setmetatable +local math = math + +local text_button = { mt = {} } + +function text_button:set_font(font) + self._private.text:set_font(font) +end + +function text_button:set_bold(bold) + self._private.text:set_bold(bold) +end + +function text_button:set_size(font, size) + self._private.text:set_size(font, size) +end + +function text_button:set_color(color) + self._private.text:set_color(color) +end + +function text_button:set_text(text) + self._private.text:set_text(text) +end + +local function effect(widget, text_bg) + if text_bg ~= nil then + widget.text_animation:set(helpers.color.hex_to_rgb(text_bg)) + end +end + +local function button(args, type) + args = args or {} + + args.color = args.text_normal_bg + local text_widget = twidget(args) + + args.child = text_widget + local widget = type == "normal" and ewidget.normal(args) or ewidget.state(args) + + gtable.crush(widget, text_button, true) + widget._private.text = text_widget + + widget.text_animation = animation:new({ + pos = helpers.color.hex_to_rgb(args.text_normal_bg), + easing = animation.easing.linear, + duration = 0.2, + update = function(self, pos) + text_widget:set_color(helpers.color.rgb_to_hex(pos)) + end, + }) + + widget.size_animation = animation:new({ + pos = args.size, + easing = animation.easing.linear, + duration = 0.2, + update = function(self, pos) + text_widget:set_size(pos) + end, + }) + + return widget, text_widget +end + +function text_button.state(args) + args = args or {} + + args.text_normal_bg = args.text_normal_bg or beautiful.random_accent_color() + args.text_hover_bg = args.text_hover_bg or helpers.color.button_color(args.text_normal_bg, 0.1) + args.text_press_bg = args.text_press_bg or helpers.color.button_color(args.text_normal_bg, 0.2) + + args.text_on_normal_bg = args.text_on_normal_bg or args.text_normal_bg + args.text_on_hover_bg = args.text_on_hover_bg or helpers.color.button_color(args.text_on_normal_bg, 0.1) + args.text_on_press_bg = args.text_on_press_bg or helpers.color.button_color(args.text_on_normal_bg, 0.2) + + args.animate_size = args.animate_size == nil and true or args.animate_size + + local widget, text_widget = button(args, "state") + + function text_widget:on_hover(widget, state) + if state == true then + effect(widget, args.text_on_hover_bg) + else + effect(widget, args.text_hover_bg) + end + end + + function text_widget:on_leave(widget, state) + if state == true then + effect(widget, args.text_on_normal_bg) + else + effect(widget, args.text_normal_bg) + end + end + + function text_widget:on_turn_on() + effect(widget, args.text_on_normal_bg) + end + + if args.on_by_default == true then + text_widget:on_turn_on() + end + + function text_widget:on_turn_off() + effect(widget, args.text_normal_bg) + end + + function text_widget:on_press() + if args.animate_size == true then + widget.size_animation:set(math.max(12, args.size - 20)) + end + end + + function text_widget:on_release() + if args.animate_size == true then + if widget.size_animation.state == true then + widget.size_animation.ended:subscribe(function() + widget.size_animation:set(args.size) + widget.size_animation.ended:unsubscribe() + end) + else + widget.size_animation:set(args.size) + end + end + end + + return widget +end + +function text_button.normal(args) + args = args or {} + + args.text_normal_bg = args.text_normal_bg or beautiful.random_accent_color() + args.text_hover_bg = args.text_hover_bg or helpers.color.button_color(args.text_normal_bg, 0.1) + args.text_press_bg = args.text_press_bg or helpers.color.button_color(args.text_normal_bg, 0.2) + + args.animate_size = args.animate_size == nil and true or args.animate_size + + local widget, text_widget = button(args, "normal") + + function text_widget:on_hover() + effect(widget, args.text_hover_bg) + end + + function text_widget:on_leave() + effect(widget, args.text_normal_bg) + end + + function text_widget:on_press() + effect(widget, args.text_press_bg) + if args.animate_size == true then + widget.size_animation:set(math.max(12, args.size - 20)) + end + end + + function text_widget:on_release() + effect(widget, args.text_normal_bg) + if args.animate_size == true then + if widget.size_animation.state == true then + widget.size_animation.ended:subscribe(function() + widget.size_animation:set(args.size) + widget.size_animation.ended:unsubscribe() + end) + else + widget.size_animation:set(args.size) + end + end + end + + return widget +end + +return setmetatable(text_button, text_button.mt) diff --git a/config/awesome/ui/widgets/central-panel-switch/init.lua b/config/awesome/ui/widgets/central-panel-switch/init.lua deleted file mode 100644 index a0d5356..0000000 --- a/config/awesome/ui/widgets/central-panel-switch/init.lua +++ /dev/null @@ -1,91 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") - --- Variable used for switching panel modes -local central_panel_mode = "dashboard_mode" - -local active_button = beautiful.lighter_bg -local inactive_button = beautiful.transparent - -local settings_text = wibox.widget({ - text = "Settings", - font = beautiful.font_name .. "Bold 11", - align = "center", - valign = "center", - widget = wibox.widget.textbox, -}) - -local settings_button = clickable_container(wibox.container.margin(settings_text, dpi(0), dpi(0), dpi(7), dpi(7))) - -local wrap_settings = wibox.widget({ - settings_button, - forced_width = dpi(93), - bg = inactive_button, - border_width = dpi(1), - border_color = beautiful.lighter_bg, - shape = function(cr, width, height) - gears.shape.partially_rounded_rect(cr, width, height, false, true, true, false, dpi(6)) - end, - widget = wibox.container.background, -}) - -local dashboard_text = wibox.widget({ - text = "Dashboard", - font = beautiful.font_name .. "Bold 11", - align = "center", - valign = "center", - widget = wibox.widget.textbox, -}) - -local dashboard_button = clickable_container(wibox.container.margin(dashboard_text, dpi(0), dpi(0), dpi(7), dpi(7))) - -local wrap_dashboard = wibox.widget({ - dashboard_button, - forced_width = dpi(93), - bg = active_button, - border_width = dpi(1), - border_color = beautiful.lighter_bg, - shape = function(cr, width, height) - gears.shape.partially_rounded_rect(cr, width, height, true, false, false, true, dpi(6)) - end, - widget = wibox.container.background, -}) - -local switcher = wibox.widget({ - expand = "none", - layout = wibox.layout.fixed.horizontal, - wrap_dashboard, - wrap_settings, -}) - -function switch_rdb_pane(central_panel_mode) - if central_panel_mode == "dashboard_mode" then - -- Update button color - wrap_dashboard.bg = active_button - wrap_settings.bg = inactive_button - - -- Change panel content of floating-panel.lua - central_panel:switch_pane(central_panel_mode) - elseif central_panel_mode == "settings_mode" then - -- Update button color - wrap_dashboard.bg = inactive_button - wrap_settings.bg = active_button - - -- Change panel content of floating-panel.lua - central_panel:switch_pane(central_panel_mode) - end -end - -dashboard_button:buttons(gears.table.join(awful.button({}, 1, nil, function() - switch_rdb_pane("dashboard_mode") -end))) - -settings_button:buttons(gears.table.join(awful.button({}, 1, nil, function() - switch_rdb_pane("settings_mode") -end))) - -return switcher diff --git a/config/awesome/ui/widgets/clickable-container/init.lua b/config/awesome/ui/widgets/clickable-container.lua old mode 100644 new mode 100755 similarity index 65% rename from config/awesome/ui/widgets/clickable-container/init.lua rename to config/awesome/ui/widgets/clickable-container.lua index 016bb11..4cdaae3 --- a/config/awesome/ui/widgets/clickable-container/init.lua +++ b/config/awesome/ui/widgets/clickable-container.lua @@ -7,10 +7,13 @@ local create_click_events = function(widget) widget = wibox.container.background, }) + -- Old and new widget local old_cursor, old_wibox + -- Mouse hovers on the widget container:connect_signal("mouse::enter", function() - container.bg = beautiful.hover_effect + container.bg = beautiful.control_center_button_bg + -- Hm, no idea how to get the wibox from this signal's arguments... local w = mouse.current_wibox if w then old_cursor, old_wibox = w.cursor, w @@ -18,20 +21,23 @@ local create_click_events = function(widget) end end) + -- Mouse leaves the widget container:connect_signal("mouse::leave", function() - container.bg = beautiful.transparent + container.bg = beautiful.leave_event if old_wibox then old_wibox.cursor = old_cursor old_wibox = nil end end) + -- Mouse pressed the widget container:connect_signal("button::press", function() - container.bg = beautiful.accent + container.bg = beautiful.press_event end) + -- Mouse releases the widget container:connect_signal("button::release", function() - container.bg = beautiful.hover_effect + container.bg = beautiful.release_event end) return container diff --git a/config/awesome/ui/widgets/container.lua b/config/awesome/ui/widgets/container.lua new file mode 100755 index 0000000..8d895e7 --- /dev/null +++ b/config/awesome/ui/widgets/container.lua @@ -0,0 +1,80 @@ +------------------------------------------- +-- @author https://github.com/Kasper24 +-- @copyright 2021-2022 Kasper24 +------------------------------------------- + +local wibox = require("wibox") +local beautiful = require("beautiful") +local helpers = require("helpers") +local dpi = beautiful.xresources.apply_dpi +local setmetatable = setmetatable + +local container = { mt = {} } + +local function new(args) + args = args or {} + + args.direction = args.direction or nil + args.forced_width = args.forced_width or nil + args.forced_height = args.forced_height or nil + args.constraint_strategy = args.constraint_strategy or nil + args.constraint_width = args.constraint_width or nil + args.constraint_height = args.constraint_height or nil + args.margins = args.margins or dpi(0) + args.paddings = args.paddings or dpi(0) + args.halign = args.halign or nil + args.valign = args.valign or nil + args.child = args.child or nil + + args.bg = args.bg or beautiful.xbackground + args.shape = args.shape or helpers.ui.rrect(beautiful.border_radius) + args.border_width = args.border_width or dpi(0) + args.border_color = args.border_color or beautiful.transparent + + local widget = wibox.widget({ + widget = wibox.container.rotate, + direction = args.direction, + { + widget = wibox.container.constraint, + id = "constraint_role", + strategy = args.constraint_strategy, + width = args.constraint_width, + height = args.constraint_height, + { + widget = wibox.container.margin, + id = "margin_role", + margins = args.margins, + { + widget = wibox.container.background, + id = "background_role", + forced_width = args.forced_width, + forced_height = args.forced_height, + shape = args.shape, + bg = args.bg, + border_width = args.border_width, + border_color = args.border_color, + { + widget = wibox.container.place, + id = "place_role", + halign = args.halign, + valign = args.valign, + { + widget = wibox.container.margin, + id = "padding_role", + margins = args.paddings, + args.child, + }, + }, + }, + }, + }, + }) + + return widget +end + +function container.mt:__call(...) + return new(...) +end + +return setmetatable(container, container.mt) diff --git a/config/awesome/ui/widgets/cute-battery-face/init.lua b/config/awesome/ui/widgets/cute-battery-face/init.lua deleted file mode 100644 index 0c4cd82..0000000 --- a/config/awesome/ui/widgets/cute-battery-face/init.lua +++ /dev/null @@ -1,200 +0,0 @@ -local awful = require("awful") -local gears = require("gears") -local wibox = require("wibox") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local helpers = require("helpers") - --- Cute battery face indicator ------------------- --- Stolen from Elena - -local stroke = beautiful.xbackground -local happy_color = beautiful.xcolor2 -local sad_color = beautiful.xcolor1 -local ok_color = beautiful.xcolor3 -local charging_color = beautiful.xcolor6 - --- Not great not terrible -local ok_threshold = 40 - --- Low percentage -local battery_threshold_low = 20 - -local battery_bar = wibox.widget({ - max_value = 100, - value = 50, - forced_height = dpi(100), - forced_width = dpi(50), - bar_shape = gears.shape.rectangle, - color = happy_color, - background_color = happy_color .. "55", - widget = wibox.widget.progressbar, -}) - -local battery_bar_container = wibox.widget({ - battery_bar, - direction = "east", - widget = wibox.container.rotate, -}) - -local charging_icon = wibox.widget({ - font = beautiful.icon_font_name .. "18", - valign = "center", - markup = helpers.colorize_text("󱐋", stroke .. "80"), - widget = wibox.widget.textbox(), -}) - -local eye_size = dpi(5) -local mouth_size = dpi(10) - -local mouth_shape = function() - return function(cr, width, height) - gears.shape.pie(cr, width, height, 0, math.pi) - end -end - -local mouth_widget = wibox.widget({ - forced_width = mouth_size, - forced_height = mouth_size, - shape = mouth_shape(), - -- shape = gears.shape.pie, - bg = stroke, - widget = wibox.container.background(), -}) - -local frown = wibox.widget({ - { - mouth_widget, - direction = "south", - widget = wibox.container.rotate(), - }, - top = dpi(8), - widget = wibox.container.margin(), -}) - -local smile = wibox.widget({ - mouth_widget, - direction = "north", - widget = wibox.container.rotate(), -}) - -local ok = wibox.widget({ - { - bg = stroke, - shape = helpers.rrect(dpi(2)), - widget = wibox.container.background, - }, - top = dpi(5), - bottom = dpi(1), - widget = wibox.container.margin(), -}) - -local mouth = wibox.widget({ - frown, - ok, - smile, - top_only = true, - widget = wibox.layout.stack(), -}) - -local eye = wibox.widget({ - forced_width = eye_size, - forced_height = eye_size, - shape = gears.shape.circle, - bg = stroke, - widget = wibox.container.background(), -}) - --- 2 eyes 1 semicircle (smile or frown) -local face = wibox.widget({ - eye, - mouth, - eye, - spacing = dpi(4), - layout = wibox.layout.fixed.horizontal, -}) - -local cute_battery_face = wibox.widget({ - { - battery_bar_container, - shape = helpers.rrect(beautiful.widget_radius), - border_color = stroke, - border_width = dpi(4), - widget = wibox.container.background, - }, - { - { - nil, - charging_icon, - nil, - expand = "none", - layout = wibox.layout.align.horizontal, - }, - left = dpi(25), - bottom = dpi(50), - widget = wibox.container.margin, - }, - { - nil, - { - nil, - face, - layout = wibox.layout.align.vertical, - expand = "none", - }, - layout = wibox.layout.align.horizontal, - expand = "none", - }, - top_only = false, - layout = wibox.layout.stack, -}) - -local last_value = 100 -awesome.connect_signal("signal::battery", function(value) - -- Update bar - battery_bar.value = value - last_value = value - local color - -- Update face - if charging_icon.visible then - color = charging_color - mouth:set(1, smile) - elseif value <= battery_threshold_low then - color = sad_color - mouth:set(1, frown) - elseif value <= ok_threshold then - color = ok_color - mouth:set(1, ok) - else - color = happy_color - mouth:set(1, smile) - end - battery_bar.color = color - battery_bar.background_color = color .. "44" -end) - -awesome.connect_signal("signal::charger", function(plugged) - local color - if plugged then - charging_icon.visible = true - color = charging_color - mouth:set(1, smile) - elseif last_value <= battery_threshold_low then - charging_icon.visible = false - color = sad_color - mouth:set(1, frown) - elseif last_value <= ok_threshold then - charging_icon.visible = false - color = ok_color - mouth:set(1, ok) - else - charging_icon.visible = false - color = happy_color - mouth:set(1, smile) - end - battery_bar.color = color - battery_bar.background_color = color .. "44" -end) - -return cute_battery_face diff --git a/config/awesome/ui/widgets/dnd/disturb_status b/config/awesome/ui/widgets/dnd/disturb_status deleted file mode 100644 index c508d53..0000000 --- a/config/awesome/ui/widgets/dnd/disturb_status +++ /dev/null @@ -1 +0,0 @@ -false diff --git a/config/awesome/ui/widgets/dnd/icons/dont-disturb.svg b/config/awesome/ui/widgets/dnd/icons/dont-disturb.svg deleted file mode 100644 index d5dc170..0000000 --- a/config/awesome/ui/widgets/dnd/icons/dont-disturb.svg +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/config/awesome/ui/widgets/dnd/icons/notify.svg b/config/awesome/ui/widgets/dnd/icons/notify.svg deleted file mode 100644 index 92b960b..0000000 --- a/config/awesome/ui/widgets/dnd/icons/notify.svg +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/config/awesome/ui/widgets/dnd/init.lua b/config/awesome/ui/widgets/dnd/init.lua deleted file mode 100644 index 7982f41..0000000 --- a/config/awesome/ui/widgets/dnd/init.lua +++ /dev/null @@ -1,135 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local naughty = require("naughty") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") -local config_dir = gears.filesystem.get_configuration_dir() -local widget_dir = config_dir .. "ui/widgets/dnd/" -local widget_icon_dir = widget_dir .. "icons/" - -_G.dont_disturb_state = false - -local action_name = wibox.widget({ - text = "Do Not Disturb", - font = beautiful.font_name .. "Bold 12", - align = "left", - widget = wibox.widget.textbox, -}) - -local action_status = wibox.widget({ - text = "Off", - font = beautiful.font_name .. "11", - align = "left", - widget = wibox.widget.textbox, -}) - -local action_info = wibox.widget({ - layout = wibox.layout.fixed.vertical, - action_name, - action_status, -}) - -local button_widget = wibox.widget({ - { - id = "icon", - image = gears.color.recolor_image(widget_icon_dir .. "notify.svg", beautiful.xforeground), - widget = wibox.widget.imagebox, - resize = true, - }, - layout = wibox.layout.align.horizontal, -}) - -local widget_button = wibox.widget({ - { - { - button_widget, - margins = dpi(15), - forced_height = dpi(48), - forced_width = dpi(48), - widget = wibox.container.margin, - }, - widget = clickable_container, - }, - bg = beautiful.control_center_button_bg, - shape = gears.shape.circle, - widget = wibox.container.background, -}) - -local update_widget = function() - if dont_disturb_state then - action_status:set_text("On") - widget_button.bg = beautiful.accent - button_widget.icon:set_image( - gears.color.recolor_image(widget_icon_dir .. "dont-disturb.svg", beautiful.xforeground) - ) - else - action_status:set_text("Off") - widget_button.bg = beautiful.control_center_button_bg - button_widget.icon:set_image(gears.color.recolor_image(widget_icon_dir .. "notify.svg", beautiful.xforeground)) - end -end - -local check_disturb_status = function() - awful.spawn.easy_async_with_shell("cat " .. widget_dir .. "disturb_status", function(stdout) - local status = stdout - - if status:match("true") then - dont_disturb_state = true - elseif status:match("false") then - dont_disturb_state = false - else - dont_disturb_state = false - awful.spawn.with_shell("echo 'false' > " .. widget_dir .. "disturb_status") - end - - update_widget() - end) -end - -check_disturb_status() - -local toggle_action = function() - if dont_disturb_state then - dont_disturb_state = false - else - dont_disturb_state = true - end - awful.spawn.easy_async_with_shell( - "echo " .. tostring(dont_disturb_state) .. " > " .. widget_dir .. "disturb_status", - function() - update_widget() - end - ) -end - -widget_button:buttons(gears.table.join(awful.button({}, 1, nil, function() - toggle_action() -end))) - -action_info:buttons(gears.table.join(awful.button({}, 1, nil, function() - toggle_action() -end))) - -local action_widget = wibox.widget({ - layout = wibox.layout.fixed.horizontal, - spacing = dpi(10), - widget_button, - { - layout = wibox.layout.align.vertical, - expand = "none", - nil, - action_info, - nil, - }, -}) - --- Create a notification sound -naughty.connect_signal("request::display", function(n) - if not dont_disturb_state then - awful.spawn.with_shell("canberra-gtk-play -i message") - end -end) - -return action_widget diff --git a/config/awesome/ui/widgets/end-session/init.lua b/config/awesome/ui/widgets/end-session/init.lua deleted file mode 100644 index 98dc666..0000000 --- a/config/awesome/ui/widgets/end-session/init.lua +++ /dev/null @@ -1,43 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") -local helpers = require("helpers") - -local return_button = function() - local widget = wibox.widget({ - { - align = "center", - valign = "center", - font = beautiful.icon_font_name .. "18", - markup = helpers.colorize_text("󰤆", beautiful.xforeground), - widget = wibox.widget.textbox(), - }, - layout = wibox.layout.align.horizontal, - }) - - local widget_button = wibox.widget({ - { - { - widget, - margins = dpi(8), - widget = wibox.container.margin, - }, - widget = clickable_container, - }, - bg = beautiful.transparent, - shape = helpers.rrect(beautiful.control_center_widget_radius), - widget = wibox.container.background, - }) - - widget_button:buttons(gears.table.join(awful.button({}, 1, nil, function() - awesome.emit_signal("module::exit_screen:show") - central_panel:toggle() - end))) - - return widget_button -end - -return return_button diff --git a/config/awesome/ui/widgets/floating-mode/floating_mode b/config/awesome/ui/widgets/floating-mode/floating_mode deleted file mode 100644 index c508d53..0000000 --- a/config/awesome/ui/widgets/floating-mode/floating_mode +++ /dev/null @@ -1 +0,0 @@ -false diff --git a/config/awesome/ui/widgets/floating-mode/icons/floating.svg b/config/awesome/ui/widgets/floating-mode/icons/floating.svg deleted file mode 100644 index bdc513d..0000000 --- a/config/awesome/ui/widgets/floating-mode/icons/floating.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/config/awesome/ui/widgets/floating-mode/icons/tile.svg b/config/awesome/ui/widgets/floating-mode/icons/tile.svg deleted file mode 100644 index 6c3d8c3..0000000 --- a/config/awesome/ui/widgets/floating-mode/icons/tile.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/config/awesome/ui/widgets/floating-mode/init.lua b/config/awesome/ui/widgets/floating-mode/init.lua deleted file mode 100755 index a738585..0000000 --- a/config/awesome/ui/widgets/floating-mode/init.lua +++ /dev/null @@ -1,175 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") -local config_dir = gears.filesystem.get_configuration_dir() -local widget_dir = config_dir .. "ui/widgets/floating-mode/" -local widget_icon_dir = widget_dir .. "icons/" - -local floating_state = false - -local action_name = wibox.widget({ - text = "Floating Mode", - font = beautiful.font_name .. "Bold 12", - align = "left", - widget = wibox.widget.textbox, -}) - -local action_status = wibox.widget({ - text = "Off", - font = beautiful.font_name .. "11", - align = "left", - widget = wibox.widget.textbox, -}) - -local action_info = wibox.widget({ - layout = wibox.layout.fixed.vertical, - action_name, - action_status, -}) - -local button_widget = wibox.widget({ - { - id = "icon", - image = gears.color.recolor_image(widget_icon_dir .. "floating.svg", beautiful.xforeground), - widget = wibox.widget.imagebox, - resize = true, - }, - layout = wibox.layout.align.horizontal, -}) - -local widget_button = wibox.widget({ - { - { - button_widget, - margins = dpi(15), - forced_height = dpi(48), - forced_width = dpi(48), - widget = wibox.container.margin, - }, - widget = clickable_container, - }, - bg = beautiful.control_center_button_bg, - shape = gears.shape.circle, - widget = wibox.container.background, -}) - -local update_widget = function() - if floating_state then - action_status:set_text("On") - widget_button.bg = beautiful.accent - button_widget.icon:set_image( - gears.color.recolor_image(widget_icon_dir .. "floating.svg", beautiful.xforeground) - ) - else - action_status:set_text("Off") - widget_button.bg = beautiful.control_center_button_bg - button_widget.icon:set_image( - gears.color.recolor_image(widget_icon_dir .. "floating.svg", beautiful.xforeground) - ) - end -end - -local check_floating_mode_state = function() - local cmd = "cat " .. widget_dir .. "floating_mode" - - awful.spawn.easy_async_with_shell(cmd, function(stdout) - local status = stdout - - if status:match("true") then - floating_state = true - elseif status:match("false") then - floating_state = false - else - floating_state = false - awful.spawn.easy_async_with_shell('echo "false" > ' .. widget_dir .. "floating_mode", function(stdout) end) - end - update_widget() - end) -end - -check_floating_mode_state() - -local ap_off_cmd = [[ - - # Create an AwesomeWM Notification - awesome-client " - naughty = require('naughty') - naughty.notification({ - app_name = 'Layout Manager', - title = 'Floating mode disabled!', - message = 'Set global layout to tile', - icon = ']] .. widget_icon_dir .. "tile" .. ".svg" .. [[' - }) - " - ]] .. "echo false > " .. widget_dir .. "floating_mode" .. [[ -]] - -local ap_on_cmd = [[ - - # Create an AwesomeWM Notification - awesome-client " - naughty = require('naughty') - naughty.notification({ - app_name = 'Layout Manager', - title = 'Floating mode enabled!', - message = 'Set global layout to floating', - icon = ']] .. widget_icon_dir .. "floating" .. ".svg" .. [[' - }) - " - ]] .. "echo true > " .. widget_dir .. "floating_mode" .. [[ -]] - -local toggle_global_floating = function() - local tags = awful.screen.focused().tags - if not floating_state then - for _, tag in ipairs(tags) do - awful.layout.set(awful.layout.suit.floating, tag) - end - awful.spawn.easy_async_with_shell(ap_on_cmd, function(stdout) - floating_state = true - update_widget() - end) - else - for _, tag in ipairs(tags) do - awful.layout.set(awful.layout.suit.tile, tag) - end - awful.spawn.easy_async_with_shell(ap_off_cmd, function(stdout) - floating_state = false - update_widget() - end) - end -end - -widget_button:buttons(gears.table.join(awful.button({}, 1, nil, function() - toggle_global_floating() -end))) - -action_info:buttons(gears.table.join(awful.button({}, 1, nil, function() - toggle_global_floating() -end))) - -gears.timer({ - timeout = 5, - autostart = true, - callback = function() - check_floating_mode_state() - end, -}) - -local action_widget = wibox.widget({ - layout = wibox.layout.fixed.horizontal, - spacing = dpi(10), - widget_button, - { - layout = wibox.layout.align.vertical, - expand = "none", - nil, - action_info, - nil, - }, -}) - -return action_widget diff --git a/config/awesome/ui/widgets/init.lua b/config/awesome/ui/widgets/init.lua new file mode 100755 index 0000000..823d317 --- /dev/null +++ b/config/awesome/ui/widgets/init.lua @@ -0,0 +1,7 @@ +return { + button = require(... .. ".button"), + container = require(... .. ".container"), + menu = require(... .. ".menu"), + playerctl = require(... .. ".playerctl"), + text = require(... .. ".text"), +} diff --git a/config/awesome/ui/widgets/menu.lua b/config/awesome/ui/widgets/menu.lua new file mode 100755 index 0000000..7eba923 --- /dev/null +++ b/config/awesome/ui/widgets/menu.lua @@ -0,0 +1,329 @@ +local awful = require("awful") +local gtable = require("gears.table") +local gtimer = require("gears.timer") +local wibox = require("wibox") +local welevated = require("ui.widgets.button.elevated") +local twidget = require("ui.widgets.text") +local beautiful = require("beautiful") +local helpers = require("helpers") +local dpi = beautiful.xresources.apply_dpi +local setmetatable = setmetatable +local ipairs = ipairs +local capi = { awesome = awesome, mouse = mouse, tag = tag } + +local menu = { mt = {} } + +function menu:set_pos(args) + args = args or {} + + local coords = args.coords + local wibox = args.wibox + local widget = args.widget + local offset = args.offset or { x = 0, y = 0 } + + if offset.x == nil then + offset.x = 0 + end + if offset.y == nil then + offset.y = 0 + end + + local screen_workarea = awful.screen.focused().workarea + local screen_w = screen_workarea.x + screen_workarea.width + local screen_h = screen_workarea.y + screen_workarea.height + + if not coords and wibox and widget then + coords = helpers.ui.get_widget_geometry(wibox, widget) + else + coords = args.coords or capi.mouse.coords() + end + + if coords.x + self.width > screen_w then + if self.parent_menu ~= nil then + self.x = coords.x - (self.width * 2) - offset.x + else + self.x = coords.x - self.width + offset.x + end + else + self.x = coords.x + offset.x + end + + if coords.y + self.height > screen_h then + self.y = screen_h - self.height + offset.y + else + self.y = coords.y + offset.y + end +end + +function menu:hide_parents_menus() + if self.parent_menu ~= nil then + self.parent_menu:hide(true) + end +end + +function menu:hide_children_menus() + for _, button in ipairs(self.widget.children) do + if button.sub_menu ~= nil then + button.sub_menu:hide() + button:turn_off() + end + end +end + +function menu:hide(hide_parents) + if self.visible == false then + return + end + + -- Hide self + self.visible = false + + -- Hides all child menus + self:hide_children_menus() + + if hide_parents == true then + self:hide_parents_menus() + end +end + +function menu:show(args) + if self.visible == true then + return + end + + self.can_hide = false + + gtimer({ + timeout = 0.1, + autostart = true, + call_now = false, + single_shot = true, + callback = function() + self.can_hide = true + end, + }) + + -- Hide sub menus belonging to the menu of self + if self.parent_menu ~= nil then + for _, button in ipairs(self.parent_menu.widget.children) do + if button.sub_menu ~= nil and button.sub_menu ~= self then + button.sub_menu:hide() + button:turn_off() + end + end + end + + self:set_pos(args) + self.visible = true + + capi.awesome.emit_signal("menu::toggled_on", self) +end + +function menu:toggle(args) + if self.visible == true then + self:hide() + else + self:show(args) + end +end + +function menu:add(widget) + if widget.sub_menu then + widget.sub_menu.parent_menu = self + end + widget.menu = self + self.widget:add(widget) +end + +function menu:remove(widget) + self.widget:remove(widget) +end + +function menu:reset() + self.widget:reset() +end + +function menu.menu(widgets, width) + local widget = awful.popup({ + x = 32500, + type = "menu", + visible = false, + ontop = true, + minimum_width = width or dpi(300), + maximum_width = width or dpi(300), + shape = helpers.ui.rrect(beautiful.border_radius), + bg = beautiful.main_menu_bg, + widget = wibox.layout.fixed.vertical, + }) + gtable.crush(widget, menu, true) + + awful.mouse.append_client_mousebinding(awful.button({ "Any" }, 1, function(c) + if widget.can_hide == true then + widget:hide(true) + end + end)) + + awful.mouse.append_client_mousebinding(awful.button({ "Any" }, 3, function(c) + if widget.can_hide == true then + widget:hide(true) + end + end)) + + awful.mouse.append_global_mousebinding(awful.button({ "Any" }, 1, function(c) + if widget.can_hide == true then + widget:hide(true) + end + end)) + + awful.mouse.append_global_mousebinding(awful.button({ "Any" }, 3, function(c) + if widget.can_hide == true then + widget:hide(true) + end + end)) + + capi.tag.connect_signal("property::selected", function(t) + widget:hide(true) + end) + + capi.awesome.connect_signal("menu::toggled_on", function(menu) + if menu ~= widget and menu.parent_menu == nil then + widget:hide(true) + end + end) + + for _, menu_widget in ipairs(widgets) do + widget:add(menu_widget) + end + + return widget +end + +function menu.sub_menu_button(args) + args = args or {} + + args.icon = args.icon or nil + args.icon_size = args.icon_size or 12 + args.text = args.text or "" + args.text_size = args.text_size or 12 + args.sub_menu = args.sub_menu or nil + + local icon = args.icon ~= nil + and twidget({ + font = args.icon.font, + size = args.icon_size, + color = beautiful.random_accent_color(), + text = args.icon.icon, + }) + or nil + + local widget = welevated.state({ + forced_height = dpi(35), + margins = dpi(5), + halign = "left", + normal_bg = beautiful.main_menu_bg, + normal_shape = helpers.ui.rrect(beautiful.border_radius / 2), + on_hover = function(self) + local coords = helpers.ui.get_widget_geometry(self.menu, self) + coords.x = coords.x + self.menu.x + self.menu.width + coords.y = coords.y + self.menu.y + args.sub_menu:show({ coords = coords, offset = { x = -5 } }) + self:turn_on() + end, + child = { + layout = wibox.layout.align.horizontal, + forced_width = dpi(270), + { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(15), + icon, + twidget({ + size = args.text_size, + text = args.text, + }), + }, + nil, + twidget({ + font = "Material Icons Round ", + size = 12, + text = "", + }), + }, + }) + + widget.sub_menu = args.sub_menu + + return widget +end + +function menu.button(args) + args = args or {} + + args.icon = args.icon or nil + args.icon_size = args.icon_size or 12 + args.image = args.image + args.text = args.text or "" + args.text_size = args.text_size or 12 + args.on_press = args.on_press or nil + + local icon = nil + + if args.icon ~= nil then + icon = twidget({ + font = args.icon.font, + size = args.icon_size, + color = beautiful.random_accent_color(), + text = args.icon.icon, + }) + elseif args.image ~= nil then + icon = wibox.widget({ + widget = wibox.widget.imagebox, + image = args.image, + }) + end + + local text_widget = twidget({ + size = args.text_size, + text = args.text, + }) + + return welevated.normal({ + forced_height = dpi(35), + margins = dpi(5), + halign = "left", + normal_bg = beautiful.main_menu_bg, + normal_shape = helpers.ui.rrect(beautiful.border_radius / 2), + on_release = function(self) + self.menu:hide(true) + args.on_press(self, text_widget) + end, + on_hover = function(self) + self.menu:hide_children_menus() + end, + child = { + layout = wibox.layout.fixed.horizontal, + spacing = dpi(15), + icon, + text_widget, + }, + }) +end + +function menu.separator() + return wibox.widget({ + widget = wibox.container.margin, + margins = dpi(5), + { + widget = wibox.widget.separator, + forced_height = dpi(2), + orientation = "horizontal", + thickness = dpi(1), + color = beautiful.widget_bg, + }, + }) +end + +function menu.mt:__call(...) + return menu.menu(...) +end + +return setmetatable(menu, menu.mt) diff --git a/config/awesome/ui/widgets/microphone/icons/mic-off.svg b/config/awesome/ui/widgets/microphone/icons/mic-off.svg deleted file mode 100644 index c2dc141..0000000 --- a/config/awesome/ui/widgets/microphone/icons/mic-off.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/config/awesome/ui/widgets/microphone/icons/mic.svg b/config/awesome/ui/widgets/microphone/icons/mic.svg deleted file mode 100644 index 8405e32..0000000 --- a/config/awesome/ui/widgets/microphone/icons/mic.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/config/awesome/ui/widgets/microphone/init.lua b/config/awesome/ui/widgets/microphone/init.lua deleted file mode 100644 index c52c915..0000000 --- a/config/awesome/ui/widgets/microphone/init.lua +++ /dev/null @@ -1,71 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") -local helpers = require("helpers") - -local mic_state = false - -local button_widget = wibox.widget({ - id = "icon", - markup = helpers.colorize_text("󰍬", beautiful.xforeground), - font = beautiful.icon_font_name .. "18", - align = "center", - valign = "center", - widget = wibox.widget.textbox, -}) - -local widget_button = wibox.widget({ - { - { - button_widget, - margins = dpi(12), - forced_height = dpi(48), - forced_width = dpi(48), - widget = wibox.container.margin, - }, - widget = clickable_container, - }, - bg = beautiful.control_center_button_bg, - shape = gears.shape.circle, - widget = wibox.container.background, -}) - -local update_widget = function() - if mic_state then - widget_button.bg = beautiful.accent - else - widget_button.bg = beautiful.control_center_button_bg - end -end - -local initial_action = function(button) - awful.spawn.easy_async_with_shell( - [[sh -c amixer | grep 'Front Left: Capture' | awk -F' ' '{print $6}' | sed -e 's/\[//' -e 's/\]//']], - function(stdout) - if stdout:match("on") then - mic_state = true - else - mic_state = false - end - update_widget() - end - ) -end - -local onclick_action = function() - awful.spawn.with_shell("amixer set Capture toggle") -end - -widget_button:connect_signal("button::press", function(self, _, _, button) - if button == 1 then - onclick_action() - initial_action(self) - end -end) - -initial_action(widget_button) - -return widget_button diff --git a/config/awesome/ui/widgets/pacman_taglist.lua b/config/awesome/ui/widgets/pacman_taglist.lua deleted file mode 100644 index 4e49798..0000000 --- a/config/awesome/ui/widgets/pacman_taglist.lua +++ /dev/null @@ -1,90 +0,0 @@ -local awful = require("awful") -local gears = require("gears") -local gfs = gears.filesystem -local wibox = require("wibox") -local beautiful = require("beautiful") -local xresources = require("beautiful.xresources") -local dpi = xresources.apply_dpi -local helpers = require("helpers") - -local get_taglist = function(s) - -- Taglist buttons - local taglist_buttons = gears.table.join( - awful.button({}, 1, - function(t) t:view_only() end), - awful.button({modkey}, 1, function(t) - if client.focus then client.focus:move_to_tag(t) end - end), awful.button({}, 3, awful.tag.viewtoggle), - awful.button({modkey}, 3, function(t) - if client.focus then client.focus:toggle_tag(t) end - end), awful.button({}, 4, function(t) - awful.tag.viewnext(t.screen) - end), awful.button({}, 5, function(t) - awful.tag.viewprev(t.screen) - end)) - - -- The actual png icons - -- I do have the svgs, but inkscape does a better job of scaling - local ghost = gears.surface.load_uncached( - gfs.get_configuration_dir() .. "theme/assets/icons/taglist/ghost.png") - local ghost_icon = gears.color.recolor_image(ghost, beautiful.xcolor6) - local dot = gears.surface.load_uncached( - gfs.get_configuration_dir() .. "theme/assets/icons/taglist/dot.png") - local dot_icon = gears.color.recolor_image(dot, beautiful.xcolor8) - local pacman = gears.surface.load_uncached( - gfs.get_configuration_dir() .. "theme/assets/icons/taglist/pacman.png") - local pacman_icon = gears.color.recolor_image(pacman, beautiful.xcolor3) - - -- Function to update the tags - local update_tags = function(self, c3) - local imgbox = self:get_children_by_id('icon_role')[1] - if c3.selected then - imgbox.image = pacman_icon - elseif #c3:clients() == 0 then - imgbox.image = dot_icon - else - imgbox.image = ghost_icon - end - end - - local pac_taglist = awful.widget.taglist { - screen = s, - filter = awful.widget.taglist.filter.all, - style = { - shape = helpers.rrect(beautiful.border_radius) - }, - layout = {spacing = 0, layout = wibox.layout.fixed.vertical}, - widget_template = { - { - {id = 'icon_role', widget = wibox.widget.imagebox}, - id = 'margin_role', - margins = dpi(10), - widget = wibox.container.margin - }, - id = 'background_role', - widget = wibox.container.background, - create_callback = function(self, c3, index, objects) - update_tags(self, c3) - self:connect_signal('mouse::enter', function() - if #c3:clients() > 0 then - awesome.emit_signal("bling::tag_preview::update", c3) - awesome.emit_signal("bling::tag_preview::visibility", s, - true) - end - end) - self:connect_signal('mouse::leave', function() - awesome.emit_signal("bling::tag_preview::visibility", s, - false) - end) - end, - update_callback = function(self, c3, index, objects) - update_tags(self, c3) - end - }, - buttons = taglist_buttons - } - - return pac_taglist -end - -return get_taglist diff --git a/config/awesome/ui/widgets/playerctl.lua b/config/awesome/ui/widgets/playerctl.lua new file mode 100755 index 0000000..8e74792 --- /dev/null +++ b/config/awesome/ui/widgets/playerctl.lua @@ -0,0 +1,241 @@ +------------------------------------------- +-- @author https://github.com/Kasper24 +-- @copyright 2021-2022 Kasper24 +------------------------------------------- + +local gshape = require("gears.shape") +local wibox = require("wibox") +local tbutton = require("ui.widgets.button.text") +local ebutton = require("ui.widgets.button.elevated") +local beautiful = require("beautiful") +local general_playerctl_daemon = require("signal.playerctl") +local animation = require("modules.animation") +local setmetatable = setmetatable +local math = math + +local playerctl = {} + +local function create_point_maker() + local self = {} + self.height = 0 + + local margin_x = 0.23 + local margin_y = 0.21 + local margin_yf = 0.15 + local width = 0.18 + + --top slope, bottom slope, bottom y-int, top y-int + local tm, bm, bb, tb + + --bottom left final, top left final, middle right, top middle final, bottom middle final + local blf, tlf, mf, tmf, bmf + + function self:set_height(height) + if height == self.height then + return + end --short circuit + self.height = height + + blf = { x = margin_x * height, y = (1 - margin_yf) * height } + tlf = { x = margin_x * height, y = margin_yf * height } + + --middle, not slope + mf = { x = (1 - margin_x) * height, y = height / 2 } + + tm = (tlf.y - mf.y) / (tlf.x - mf.x) + bm = (blf.y - mf.y) / (blf.x - mf.x) + tb = tlf.y - tlf.x * tm + bb = blf.y - blf.x * bm + + --middle, not slope + tmf = { x = (margin_x + width) * height, y = tm * (margin_x + width) * height + tb } + bmf = { x = (margin_x + width) * height, y = bm * (margin_x + width) * height + bb } + + --points look like this + --p1-p2 p5-p6 + --| | | | + --p4_p3 p8_p7 + self.p1 = { x = margin_x * height, y = margin_y * height } + self.p2 = { x = (margin_x + width) * height, y = margin_y * height } + self.p3 = { x = (margin_x + width) * height, y = (1 - margin_y) * height } + self.p4 = { x = margin_x * height, y = (1 - margin_y) * height } + + self.p5 = { x = (1 - margin_x - width) * height, y = margin_y * height } + self.p6 = { x = (1 - margin_x) * height, y = margin_y * height } + self.p7 = { x = (1 - margin_x) * height, y = (1 - margin_y) * height } + self.p8 = { x = (1 - margin_x - width) * height, y = (1 - margin_y) * height } + + self.p1d = { y = self.p1.y - tlf.y } + self.p2d = { y = self.p2.y - tmf.y } + self.p3d = { y = self.p4.y - bmf.y } + self.p4d = { y = self.p3.y - blf.y } + + self.p5d = { x = self.p5.x - tmf.x, y = self.p5.y - tmf.y } --x moves + self.p6d = { y = self.p6.y - mf.y } + self.p7d = { y = self.p7.y - mf.y } + self.p8d = { x = self.p8.x - bmf.x, y = self.p7.y - bmf.y } --x moves + end + + return self +end + +local function get_draw(pos, pm, icon_color) + return function(_, _, cr, _, height) + pm:set_height(height) + + -- cr:set_source_rgb(1.0, 1.0, 1.0) + cr:set_source(require("gears.color")(icon_color)) + + if pos == 1 then + cr:move_to(pm.p1.x, pm.p1.y - pm.p1d.y) + cr:line_to(pm.p6.x, pm.p6.y - pm.p6d.y) + cr:line_to(pm.p4.x, pm.p4.y - pm.p4d.y) + cr:fill() + return + end + + cr:move_to(pm.p1.x, pm.p1.y - pm.p1d.y * pos) + cr:line_to(pm.p2.x, pm.p2.y - pm.p2d.y * pos) + cr:line_to(pm.p3.x, pm.p3.y - pm.p3d.y * pos) + cr:line_to(pm.p4.x, pm.p4.y - pm.p4d.y * pos) + cr:fill() + + cr:move_to(pm.p5.x - pm.p5d.x * pos, pm.p5.y - pm.p5d.y * pos) + cr:line_to(pm.p6.x, pm.p6.y - pm.p6d.y * pos) + cr:line_to(pm.p7.x, pm.p7.y - pm.p7d.y * pos) + cr:line_to(pm.p8.x - pm.p8d.x * pos, pm.p8.y - pm.p8d.y * pos) + cr:fill() + end +end + +function playerctl.play(icon_color, bg_color) + local playerctl_daemon = general_playerctl_daemon + + local point_maker = create_point_maker() + + local widget = wibox.widget({ + widget = wibox.widget.make_base_widget, + fit = function(_, _, _, height) + return height, height + end, + draw = get_draw(0, point_maker, icon_color), + }) + + local button = ebutton.normal({ + normal_shape = gshape.rounded_rect, + normal_bg = bg_color, + on_release = function() + playerctl_daemon:play_pause() + end, + child = widget, + }) + + local play_pause_animation = animation:new({ + duration = 0.125, + easing = animation.easing.linear, + update = function(self, pos) + widget.draw = get_draw(pos, point_maker, icon_color) + widget:emit_signal("widget::redraw_needed") + end, + }) + + playerctl_daemon:connect_signal("playback_status", function(self, playing) + if playing then + play_pause_animation:set(0) + else + play_pause_animation:set(1) + end + end) + + playerctl_daemon:connect_signal("no_players", function(self) + play_pause_animation:set(1) + end) + + return button +end + +function playerctl.previous(icon_size, icon_color, bg_color) + local playerctl_daemon = general_playerctl_daemon + + return tbutton.normal({ + normal_shape = gshape.rounded_rect, + font = beautiful.icon_font .. "Round ", + size = icon_size, + text_normal_bg = icon_color, + normal_bg = bg_color, + text = "", + on_release = function() + playerctl_daemon:previous() + end, + }) +end + +function playerctl.next(icon_size, icon_color, bg_color) + local playerctl_daemon = general_playerctl_daemon + + return tbutton.normal({ + normal_shape = gshape.rounded_rect, + font = beautiful.icon_font .. "Round ", + size = icon_size, + text_normal_bg = icon_color, + normal_bg = bg_color, + text = "", + on_release = function() + playerctl_daemon:next() + end, + }) +end + +function playerctl.loop(icon_color, bg_color) + local playerctl_daemon = general_playerctl_daemon + + local widget = tbutton.state({ + normal_shape = gshape.rounded_rect, + font = beautiful.icon_font .. "Round ", + size = 12, + text_normal_bg = icon_color, + normal_bg = bg_color, + text = "", + on_release = function(self) + playerctl_daemon:cycle_loop_status() + end, + }) + + playerctl_daemon:connect_signal("loop_status", function(self, loop_status, player) + if loop_status == "none" then + widget:turn_off() + else + widget:turn_on() + end + end) + + return widget +end + +function playerctl.shuffle(icon_color, bg_color) + local playerctl_daemon = general_playerctl_daemon + + local widget = tbutton.state({ + normal_shape = gshape.rounded_rect, + font = beautiful.icon_font .. "Round ", + size = 12, + text_normal_bg = icon_color, + normal_bg = bg_color, + text = "", + on_release = function(self) + playerctl_daemon:cycle_shuffle() + end, + }) + + playerctl_daemon:connect_signal("shuffle", function(self, shuffle, player) + if shuffle == true then + widget:turn_on() + else + widget:turn_off() + end + end) + + return widget +end + +return setmetatable(playerctl, playerctl.mt) diff --git a/config/awesome/ui/widgets/screenrec/init.lua b/config/awesome/ui/widgets/screenrec/init.lua deleted file mode 100644 index d0fef36..0000000 --- a/config/awesome/ui/widgets/screenrec/init.lua +++ /dev/null @@ -1,217 +0,0 @@ -local wibox = require("wibox") -local awful = require("awful") -local gears = require("gears") -local naughty = require("naughty") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") -local helpers = require("helpers") - --- Screenrec ---------------- --- Stolen from manilarome - --- Status variables -local status_recording = false -local status_audio = true -local ffmpeg_pid = nil - --- User preferences -local user_preferences = { - resolution = "1366x768", - offset = "0,0", - audio = false, - save_directory = "$(xdg-user-dir VIDEOS)/Recordings/", - mic_lvl = "20", - fps = "30", -} - --- Script -local create_save_directory = function() - local create_dir_cmd = [[ - dir="]] .. user_preferences.save_directory .. [[" - - if [ ! -d "$dir" ]; then - mkdir -p "$dir" - fi - ]] - - awful.spawn.easy_async_with_shell(create_dir_cmd, function(stdout) end) -end - -create_save_directory() - -local kill_existing_recording_ffmpeg = function() - awful.spawn.easy_async_with_shell( - [[ - ps x | grep 'ffmpeg -video_size' | grep -v grep | awk '{print $1}' | xargs kill - ]], - function(stdout) end - ) -end - -kill_existing_recording_ffmpeg() - -local turn_on_the_mic = function() - awful.spawn.easy_async_with_shell([[ - amixer set Capture cap - amixer set Capture ]] .. user_preferences.mic_lvl .. [[% - ]], function() end) -end - -local ffmpeg_stop_recording = function() - awful.spawn.easy_async_with_shell( - [[ - ps x | grep 'ffmpeg -video_size' | grep -v grep | awk '{print $1}' | xargs kill -2 - ]], - function(stdout) end - ) -end - -local create_notification = function(file_dir) - local open_video = naughty.action({ - name = "Open", - icon_only = false, - }) - - local delete_video = naughty.action({ - name = "Delete", - icon_only = false, - }) - - open_video:connect_signal("invoked", function() - awful.spawn("xdg-open " .. file_dir, false) - end) - - delete_video:connect_signal("invoked", function() - awful.spawn("gio trash " .. file_dir, false) - end) - - naughty.notification({ - app_name = "Screenrecorder Tool", - timeout = 6, - title = "Screenrec!", - message = "Recording Finished", - actions = { open_video, delete_video }, - }) -end - -local ffmpeg_start_recording = function(audio, filename) - local add_audio_str = " " - - if audio then - turn_on_the_mic() - add_audio_str = "-f pulse -ac 2 -i default" - end - - ffmpeg_pid = awful.spawn.easy_async_with_shell([[ - file_name=]] .. filename .. [[ - - ffmpeg -video_size ]] .. user_preferences.resolution .. [[ -framerate ]] .. user_preferences.fps .. [[ -f x11grab \ - -i :0.0+]] .. user_preferences.offset .. " " .. add_audio_str .. [[ -c:v libx264 -crf 20 -profile:v baseline -level 3.0 -pix_fmt yuv420p $file_name - ]], function(stdout, stderr) - if stderr and stderr:match("Invalid argument") then - naughty.notification({ - app_name = "Screenrecorder Tool", - title = "Screenrec!", - message = "Invalid Configuration! please, put a valid settings!", - timeout = 3, - urgency = "normal", - }) - awesome.emit_signal("widget::screen_recorder") - return - end - create_notification(filename) - end) -end - -local create_unique_filename = function(audio) - awful.spawn.easy_async_with_shell([[ - dir="]] .. user_preferences.save_directory .. [[" - date=$(date '+%Y-%m-%d_%H-%M-%S') - format=.mp4 - - echo "${dir}${date}${format}" | tr -d '\n' - ]], function(stdout) - local filename = stdout - ffmpeg_start_recording(audio, filename) - end) -end - -local start_recording = function(audio_mode) - create_save_directory() - create_unique_filename(audio_mode) -end - -local stop_recording = function() - ffmpeg_stop_recording() -end - --- Buttons -local screen_rec_toggle_imgbox = wibox.widget({ - id = "icon", - markup = helpers.colorize_text("󰻃", beautiful.xforeground), - font = beautiful.icon_font_name .. "18", - align = "center", - valign = "center", - widget = wibox.widget.textbox, -}) - -local screen_rec_toggle_button = wibox.widget({ - { - { - screen_rec_toggle_imgbox, - margins = dpi(12), - forced_height = dpi(48), - forced_width = dpi(48), - widget = wibox.container.margin, - }, - widget = clickable_container, - }, - bg = beautiful.control_center_button_bg, - shape = gears.shape.circle, - widget = wibox.container.background, -}) - --- Start Recording -local sr_recording_start = function() - status_recording = true - screen_rec_toggle_button.bg = beautiful.accent - - start_recording(status_audio) - central_panel:toggle() -end - --- Stop Recording -local sr_recording_stop = function() - status_recording = false - status_audio = false - screen_rec_toggle_button.bg = beautiful.control_center_button_bg - - stop_recording() -end - -awesome.connect_signal("widget::screen_recorder", function() - sr_recording_stop() -end) - --- Main button functions and buttons -local status_checker = function() - if status_recording then - sr_recording_stop() - return - else - sr_recording_start() - return - end -end - -screen_rec_toggle_button:buttons(gears.table.join(awful.button({}, 1, nil, function() - status_checker() -end))) - -local return_button = function() - return screen_rec_toggle_button -end - -return return_button diff --git a/config/awesome/ui/widgets/text.lua b/config/awesome/ui/widgets/text.lua new file mode 100755 index 0000000..110272d --- /dev/null +++ b/config/awesome/ui/widgets/text.lua @@ -0,0 +1,131 @@ +------------------------------------------- +-- @author https://github.com/Kasper24 +-- @copyright 2021-2022 Kasper24 +------------------------------------------- + +local gtable = require("gears.table") +local gstring = require("gears.string") +local wibox = require("wibox") +local beautiful = require("beautiful") +local helpers = require("helpers") +local setmetatable = setmetatable +local tostring = tostring +local string = string + +local text = { mt = {} } + +local function generate_markup(self) + local bold_start = "" + local bold_end = "" + local italic_start = "" + local italic_end = "" + + if self._private.bold == true then + bold_start = "" + bold_end = "" + end + if self._private.italic == true then + italic_start = "" + italic_end = "" + end + + -- Need to unescape in a case the text was escaped by other code before + self._private.text = gstring.xml_unescape(tostring(self._private.text)) + self._private.text = gstring.xml_escape(tostring(self._private.text)) + + self.markup = bold_start + .. italic_start + .. helpers.ui.colorize_text(self._private.text, self._private.color) + .. italic_end + .. bold_end +end + +function text:set_width(width) + self.forced_width = width +end + +function text:set_height(height) + self.forced_height = height +end + +function text:set_halign(halign) + self.align = halign +end + +function text:set_font(font) + self._private.font = font + self._private.layout:set_font_description(beautiful.get_font(font)) + self:emit_signal("widget::redraw_needed") + self:emit_signal("widget::layout_changed") + self:emit_signal("property::font", font) +end + +function text:set_bold(bold) + self._private.bold = bold + generate_markup(self) +end + +function text:set_italic(italic) + self._private.italic = italic + generate_markup(self) +end + +function text:set_size(size) + -- Remove the previous size from the font field + local font = string.gsub(self._private.font, self._private.size, "") + self._private.size = size + self:set_font(font .. size) +end + +function text:set_color(color) + self._private.color = color + generate_markup(self) +end + +function text:set_text(text) + self._private.text = text + generate_markup(self) +end + +local function new(args) + args = args or {} + + args.width = args.width or nil + args.height = args.height or nil + args.halign = args.halign or nil + args.valign = args.valign or nil + args.font = args.font or beautiful.font_name or nil + args.bold = args.bold ~= nil and args.bold or false + args.italic = args.italic ~= nil and args.italic or false + args.size = args.size or 20 + args.color = args.color or beautiful.xforeground + args.text = args.text ~= nil and args.text or "" + + local widget = wibox.widget({ + widget = wibox.widget.textbox, + forced_width = args.width, + forced_height = args.height, + align = args.halign, + valign = args.valign, + font = args.font .. args.size, + }) + + gtable.crush(widget, text, true) + + widget._private.font = args.font + widget._private.bold = args.bold + widget._private.italic = args.italic + widget._private.size = args.size + widget._private.color = args.color + widget._private.text = args.text + + generate_markup(widget) + + return widget +end + +function text.mt:__call(...) + return new(...) +end + +return setmetatable(text, text.mt) diff --git a/config/awesome/ui/widgets/theme-switcher/init.lua b/config/awesome/ui/widgets/theme-switcher/init.lua deleted file mode 100644 index 0ed92bd..0000000 --- a/config/awesome/ui/widgets/theme-switcher/init.lua +++ /dev/null @@ -1,83 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local naughty = require("naughty") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local clickable_container = require("ui.widgets.clickable-container") -local helpers = require("helpers") -local day_night = {} - -local function theme_container(widget, name) - local container = wibox.widget({ - { - { - { - layout = wibox.layout.fixed.horizontal, - spacing = dpi(5), - { - widget, - forced_height = dpi(70), - forced_width = dpi(70), - widget = wibox.container.margin, - }, - { - text = name, - font = beautiful.font_name .. "Bold 10", - align = "center", - widget = wibox.widget.textbox, - }, - }, - margins = dpi(5), - widget = wibox.container.margin, - }, - widget = clickable_container, - }, - shape = helpers.rrect(beautiful.control_center_widget_radius), - bg = beautiful.lighter_bg, - widget = wibox.container.background, - }) - - return container -end - -local night = wibox.widget({ - align = "center", - valign = "center", - font = "icomoon 50", - markup = helpers.colorize_text("", beautiful.xforeground), - widget = wibox.widget.textbox(), -}) - -night:connect_signal("button::press", function() - awful.spawn.with_shell(gears.filesystem.get_configuration_dir() .. "theme/themes night") - awesome.restart() -end) - -local day = wibox.widget({ - align = "center", - valign = "center", - font = "icomoon 50", - markup = helpers.colorize_text("", beautiful.xforeground), - widget = wibox.widget.textbox(), -}) - -day:connect_signal("button::press", function() - awful.spawn.with_shell(gears.filesystem.get_configuration_dir() .. "theme/themes day") - awesome.restart() -end) - -day_night.night = theme_container(night, "Night Themes") -day_night.day = theme_container(day, "Day Themes") - -local update_themes = function() - if theme == themes[2] then - day_night.night.bg = beautiful.accent - else - day_night.day.bg = beautiful.accent - end -end - -update_themes() - -return day_night diff --git a/config/awesome/ui/widgets/user-profile/init.lua b/config/awesome/ui/widgets/user-profile/init.lua deleted file mode 100644 index 93b58fb..0000000 --- a/config/awesome/ui/widgets/user-profile/init.lua +++ /dev/null @@ -1,56 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi - -local create_profile = function() - local profile_imagebox = wibox.widget({ - { - id = "icon", - image = beautiful.pfp, - widget = wibox.widget.imagebox, - resize = true, - forced_height = dpi(50), - clip_shape = gears.shape.circle, - }, - layout = wibox.layout.fixed.horizontal, - }) - - local profile_name = wibox.widget({ - font = beautiful.font_name .. "Bold 14", - markup = "User", - align = "left", - valign = "center", - widget = wibox.widget.textbox, - }) - - awful.spawn.easy_async_with_shell( - [[ - sh -c ' - fullname="$(getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1 | tr -d "\n")" - if [ -z "$fullname" ]; - then - printf "$(whoami)@$(hostname)" - else - printf "$fullname" - fi - ' - ]], - function(stdout) - local stdout = stdout:gsub("%\n", "") - profile_name:set_markup(stdout) - end - ) - - local user_profile = wibox.widget({ - layout = wibox.layout.fixed.horizontal, - spacing = dpi(15), - profile_imagebox, - profile_name, - }) - - return user_profile -end - -return create_profile diff --git a/config/awesome/ui/widgets/vol-bri-slider/init.lua b/config/awesome/ui/widgets/vol-bri-slider/init.lua deleted file mode 100644 index 2473d35..0000000 --- a/config/awesome/ui/widgets/vol-bri-slider/init.lua +++ /dev/null @@ -1,144 +0,0 @@ -local gears = require("gears") -local awful = require("awful") -local beautiful = require("beautiful") -local dpi = beautiful.xresources.apply_dpi -local wibox = require("wibox") -local helpers = require("helpers") - -local bg_color = beautiful.accent -local vol_color = bg_color -local brightness_color = bg_color - --- Helpers -local function create_slider_widget(slider_color) - local slider_widget = wibox.widget({ - { - id = "slider", - max_value = 100, - value = 40, - background_color = bg_color .. "55", - color = slider_color, - shape = gears.shape.rounded_bar, - bar_shape = gears.shape.rounded_bar, - widget = wibox.widget.progressbar, - }, - forced_height = dpi(50), - widget = wibox.container.background, - }) - return slider_widget -end - -local function create_icons(icon, color) - local icon_widget = wibox.widget({ - { - markup = helpers.colorize_text(icon, color), - font = beautiful.icon_font_name .. "14", - align = "left", - valign = "center", - widget = wibox.widget.textbox, - }, - left = dpi(15), - widget = wibox.container.margin, - }) - - return icon_widget -end - --- Widget -local vol = create_slider_widget(vol_color) -local brightness = create_slider_widget(brightness_color) - -local vol_slider_container = wibox.widget({ - { - { - vol, - create_icons("󰕾", beautiful.xforeground), - layout = wibox.layout.stack, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - bg = beautiful.control_center_widget_bg, - widget = wibox.container.background, -}) - -local brightness_slider_container = wibox.widget({ - { - { - brightness, - create_icons("󰖨", beautiful.xforeground), - layout = wibox.layout.stack, - }, - margins = dpi(10), - widget = wibox.container.margin, - }, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, dpi(5)) - end, - bg = beautiful.control_center_widget_bg, - widget = wibox.container.background, -}) - -awesome.connect_signal("signal::volume", function(value, muted) - local fill_color - local vol_value = value or 0 - - if muted then - fill_color = beautiful.xcolor8 - vol.slider.background_color = fill_color .. "44" - else - fill_color = vol_color - end - - vol.slider.value = vol_value - vol.slider.color = fill_color - vol.slider.background_color = fill_color .. "44" -end) - -awesome.connect_signal("signal::brightness", function(value) - brightness.slider.value = value - brightness.slider.background_color = brightness_color .. "44" -end) - -vol:buttons(gears.table.join( - awful.button({}, 1, function() - helpers.volume_control(0) - end), - -- Scrolling - awful.button({}, 4, function() - helpers.volume_control(5) - end), - awful.button({}, 5, function() - helpers.volume_control(-5) - end) -)) - -brightness:buttons(gears.table.join( - -- Scrolling - awful.button({}, 4, function() - awful.spawn.with_shell("brightnessctl set 5%+ -q") - end), - awful.button({}, 5, function() - awful.spawn.with_shell("brightnessctl set 5%- -q") - end) -)) - -local stats = wibox.widget({ - { - { - brightness_slider_container, - vol_slider_container, - spacing = dpi(20), - layout = wibox.layout.flex.horizontal, - }, - expand = "none", - layout = wibox.layout.fixed.vertical, - }, - expand = "none", - layout = wibox.layout.align.horizontal, -}) - -return stats diff --git a/config/awesome/ui/widgets/window_switcher.lua b/config/awesome/ui/widgets/window_switcher.lua deleted file mode 100644 index b948dc3..0000000 --- a/config/awesome/ui/widgets/window_switcher.lua +++ /dev/null @@ -1,421 +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() - local minimized_clients_in_tag = 0 - local matcher = function(c) - return awful.rules.match( - c, - { - minimized = true, - skip_taskbar = false, - hidden = false, - first_tag = awful.screen.focused().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 + #awful.screen.focused().clients -end - -local window_switcher_hide = function(window_switcher_box) - -- 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() - 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) - window_switcher_box.visible = false - window_switcher_box.widget = nil - collectgarbage("collect") -end - -local function draw_widget( - type, - background, - border_width, - border_radius, - border_color, - clients_spacing, - client_icon_horizontal_spacing, - client_width, - client_height, - client_margins, - thumbnail_margins, - thumbnail_scale, - name_margins, - name_valign, - name_forced_width, - name_font, - name_normal_color, - name_focus_color, - icon_valign, - icon_width, - mouse_keys -) - local tasklist_widget = awful.widget.tasklist({ - screen = awful.screen.focused(), - filter = awful.widget.tasklist.filter.currenttags, - buttons = mouse_keys, - style = { - font = beautiful.font, - fg_normal = beautiful.xforeground, - fg_focus = beautiful.xcolor4 - }, - layout = { - layout = wibox.layout.flex.horizontal, - max_widget_size = dpi(300), - spacing = dpi(10), - }, - widget_template = { - widget = wibox.container.background, - bg = beautiful.lighter_bg, - shape = helpers.rrect(5), - id = "bg_role", - forced_width = dpi(450), - create_callback = 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, - { - { - { - { - { - horizontal_fit_policy = "auto", - vertical_fit_policy = "auto", - id = "thumbnail", - clip_shape = helpers.rrect(5), - widget = wibox.widget.imagebox, - }, - margins = dpi(0), - widget = wibox.container.margin, - }, - halign = 'center', - valign = 'center', - widget = wibox.container.place - }, - { - { - { - widget = awful.widget.clienticon, - }, - forced_width = dpi(30), - valign = "center", - widget = wibox.container.place, - }, - { - { - forced_width = dpi(200), - valign = "center", - id = "text_role", - widget = wibox.widget.textbox, - }, - left = dpi(10), - right = dpi(10), - widget = wibox.container.margin - }, - layout = wibox.layout.align.horizontal, - }, - layout = wibox.layout.flex.vertical - }, - left = dpi(20), right = dpi(20), top = dpi(20), - widget = wibox.container.margin - }, - }, - }) - - return wibox.widget({ - { - { - tasklist_widget, - margins = dpi(300), - widget = wibox.container.margin, - }, - halign = 'center', - content_fill_horizontal = true, - widget = wibox.container.place - }, - bg = "#00000000", - widget = wibox.container.background, - }) -end - -local enable = function(opts) - local opts = opts or {} - - local type = opts.type or "thumbnail" - local background = beautiful.window_switcher_widget_bg or "#00000000" - local border_width = beautiful.window_switcher_widget_border_width or dpi(3) - local border_radius = beautiful.window_switcher_widget_border_radius - or dpi(5) - local border_color = beautiful.window_switcher_widget_border_color - or "#ffffff" - local clients_spacing = beautiful.window_switcher_clients_spacing or dpi(20) - local client_icon_horizontal_spacing = beautiful.window_switcher_client_icon_horizontal_spacing - or dpi(5) - local client_width = beautiful.window_switcher_client_width - or dpi(type == "thumbnail" and 150 or 500) - local client_height = beautiful.window_switcher_client_height - or dpi(type == "thumbnail" and 250 or 50) - local client_margins = beautiful.window_switcher_client_margins or dpi(10) - local thumbnail_margins = beautiful.window_switcher_thumbnail_margins - or dpi(5) - local thumbnail_scale = beautiful.thumbnail_scale or false - local name_margins = beautiful.window_switcher_name_margins or dpi(10) - local name_valign = beautiful.window_switcher_name_valign or "center" - local name_forced_width = beautiful.window_switcher_name_forced_width - or dpi(type == "thumbnail" and 200 or 550) - local name_font = beautiful.window_switcher_name_font or beautiful.font - local name_normal_color = beautiful.window_switcher_name_normal_color - or "#FFFFFF" - local name_focus_color = beautiful.window_switcher_name_focus_color - or "#FF0000" - local icon_valign = beautiful.window_switcher_icon_valign or "center" - local icon_width = beautiful.window_switcher_icon_width or dpi(40) - - 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 window_switcher_box = wibox({ - bg = "#00000000", - visible = false, - ontop = true, - type = "splash", - screen = awful.screen.focused(), - widget = wibox.container.background, -- A dummy widget to make awful.popup not scream - widget = { - { - draw_widget(), - margins = dpi(10), - widget = wibox.container.margin, - }, - shape_border_width = beautiful.widget_border_width, - shape_border_color = beautiful.widget_border_color, - bg = "#00000000", - shape = helpers.rrect(5), - widget = wibox.container.background, - }, - }) - - awful.placement.maximize(window_switcher_box) - - 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] = function() - window_switcher_hide(window_switcher_box) - end, - - [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, - } - - window_switcher_box:connect_signal("property::width", function() - if window_switcher_box.visible and get_num_clients() == 0 then - window_switcher_hide(window_switcher_box) - end - end) - - window_switcher_box:connect_signal("property::height", function() - if window_switcher_box.visible and get_num_clients() == 0 then - window_switcher_hide(window_switcher_box) - end - end) - - awesome.connect_signal("bling::window_switcher::turn_on", function() - local number_of_clients = get_num_clients() - 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 = awful.screen.focused().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(window_switcher_box) - end - -- Do nothing - return - end - - -- Run function attached to key, if it exists - if keyboard_keys[key] then - keyboard_keys[key]() - end - end) - - window_switcher_box.widget = draw_widget( - type, - background, - border_width, - border_radius, - border_color, - clients_spacing, - client_icon_horizontal_spacing, - client_width, - client_height, - client_margins, - thumbnail_margins, - thumbnail_scale, - name_margins, - name_valign, - name_forced_width, - name_font, - name_normal_color, - name_focus_color, - icon_valign, - icon_width, - mouse_keys - ) - window_switcher_box.visible = true - end) -end - -return { enable = enable } diff --git a/config/awesome/user_variables.lua b/config/awesome/user_variables.lua new file mode 100755 index 0000000..fb8b479 --- /dev/null +++ b/config/awesome/user_variables.lua @@ -0,0 +1,18 @@ +return { + widget = { + weather = { + --- API Key + key = "5f513362550e218b01a8aa23766dc823", + --- Coordinates + coordinates = { + "33.033818", --- lat + "-96.783212", --- lon + }, + }, + + --- Github activity + github = { + username = "vincentknighttest", + }, + }, +} diff --git a/config/awesome/utilities/screensht b/config/awesome/utilities/screensht new file mode 100755 index 0000000..8c9990e --- /dev/null +++ b/config/awesome/utilities/screensht @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +# stolen from snap + +< + + + diff --git a/config/gtk-4.0/assets/scalable/checkbox-checked-symbolic.svg b/config/gtk-4.0/assets/scalable/checkbox-checked-symbolic.svg new file mode 100755 index 0000000..1b6ab47 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/checkbox-checked-symbolic.svg @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/checkbox-checked-symbolic@2.svg b/config/gtk-4.0/assets/scalable/checkbox-checked-symbolic@2.svg new file mode 100755 index 0000000..e65c483 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/checkbox-checked-symbolic@2.svg @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/checkbox-mixed-symbolic.svg b/config/gtk-4.0/assets/scalable/checkbox-mixed-symbolic.svg new file mode 100755 index 0000000..08a2dfc --- /dev/null +++ b/config/gtk-4.0/assets/scalable/checkbox-mixed-symbolic.svg @@ -0,0 +1,43 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/checkbox-mixed-symbolic@2.svg b/config/gtk-4.0/assets/scalable/checkbox-mixed-symbolic@2.svg new file mode 100755 index 0000000..5ed48af --- /dev/null +++ b/config/gtk-4.0/assets/scalable/checkbox-mixed-symbolic@2.svg @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/combobox-arrow-symbolic.svg b/config/gtk-4.0/assets/scalable/combobox-arrow-symbolic.svg new file mode 100755 index 0000000..f164223 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/combobox-arrow-symbolic.svg @@ -0,0 +1,44 @@ + + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/combobox-arrow-symbolic@2.svg b/config/gtk-4.0/assets/scalable/combobox-arrow-symbolic@2.svg new file mode 100755 index 0000000..075a641 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/combobox-arrow-symbolic@2.svg @@ -0,0 +1,46 @@ + + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/radio-checked-symbolic.svg b/config/gtk-4.0/assets/scalable/radio-checked-symbolic.svg new file mode 100755 index 0000000..cf79833 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/radio-checked-symbolic.svg @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/radio-checked-symbolic@2.svg b/config/gtk-4.0/assets/scalable/radio-checked-symbolic@2.svg new file mode 100755 index 0000000..abfb60a --- /dev/null +++ b/config/gtk-4.0/assets/scalable/radio-checked-symbolic@2.svg @@ -0,0 +1,41 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/radio-mixed-symbolic.svg b/config/gtk-4.0/assets/scalable/radio-mixed-symbolic.svg new file mode 120000 index 0000000..79b7355 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/radio-mixed-symbolic.svg @@ -0,0 +1 @@ +checkbox-mixed-symbolic.svg \ No newline at end of file diff --git a/config/gtk-4.0/assets/scalable/radio-mixed-symbolic@2.svg b/config/gtk-4.0/assets/scalable/radio-mixed-symbolic@2.svg new file mode 120000 index 0000000..b68859d --- /dev/null +++ b/config/gtk-4.0/assets/scalable/radio-mixed-symbolic@2.svg @@ -0,0 +1 @@ +checkbox-mixed-symbolic@2.svg \ No newline at end of file diff --git a/config/gtk-4.0/assets/scalable/window-close-symbolic.svg b/config/gtk-4.0/assets/scalable/window-close-symbolic.svg new file mode 100755 index 0000000..ca32433 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/window-close-symbolic.svg @@ -0,0 +1,41 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/window-close-symbolic@2.svg b/config/gtk-4.0/assets/scalable/window-close-symbolic@2.svg new file mode 100755 index 0000000..4b0ec83 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/window-close-symbolic@2.svg @@ -0,0 +1,41 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/window-maximize-symbolic.svg b/config/gtk-4.0/assets/scalable/window-maximize-symbolic.svg new file mode 100755 index 0000000..ea1d405 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/window-maximize-symbolic.svg @@ -0,0 +1,41 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/window-maximize-symbolic@2.svg b/config/gtk-4.0/assets/scalable/window-maximize-symbolic@2.svg new file mode 100755 index 0000000..ad78e93 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/window-maximize-symbolic@2.svg @@ -0,0 +1,41 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/window-minimize-symbolic.svg b/config/gtk-4.0/assets/scalable/window-minimize-symbolic.svg new file mode 100755 index 0000000..c4efed1 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/window-minimize-symbolic.svg @@ -0,0 +1,45 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/window-minimize-symbolic@2.svg b/config/gtk-4.0/assets/scalable/window-minimize-symbolic@2.svg new file mode 100755 index 0000000..ce383c6 --- /dev/null +++ b/config/gtk-4.0/assets/scalable/window-minimize-symbolic@2.svg @@ -0,0 +1,45 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/window-restore-symbolic.svg b/config/gtk-4.0/assets/scalable/window-restore-symbolic.svg new file mode 100755 index 0000000..780845a --- /dev/null +++ b/config/gtk-4.0/assets/scalable/window-restore-symbolic.svg @@ -0,0 +1,41 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/scalable/window-restore-symbolic@2.svg b/config/gtk-4.0/assets/scalable/window-restore-symbolic@2.svg new file mode 100755 index 0000000..723e47b --- /dev/null +++ b/config/gtk-4.0/assets/scalable/window-restore-symbolic@2.svg @@ -0,0 +1,41 @@ + + + + + + + + diff --git a/config/gtk-4.0/assets/sidebar-view-active-180px-dark.png b/config/gtk-4.0/assets/sidebar-view-active-180px-dark.png new file mode 100755 index 0000000..b48ecbd Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-180px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-180px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-active-180px-dark@2.png new file mode 100755 index 0000000..3660cf4 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-180px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-180px.png b/config/gtk-4.0/assets/sidebar-view-active-180px.png new file mode 100755 index 0000000..219a997 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-180px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-180px@2.png b/config/gtk-4.0/assets/sidebar-view-active-180px@2.png new file mode 100755 index 0000000..a486a67 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-180px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-200px-dark.png b/config/gtk-4.0/assets/sidebar-view-active-200px-dark.png new file mode 100755 index 0000000..edd52d9 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-200px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-200px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-active-200px-dark@2.png new file mode 100755 index 0000000..5796ca8 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-200px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-200px.png b/config/gtk-4.0/assets/sidebar-view-active-200px.png new file mode 100755 index 0000000..c20283d Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-200px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-200px@2.png b/config/gtk-4.0/assets/sidebar-view-active-200px@2.png new file mode 100755 index 0000000..fbb51ac Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-200px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-220px-dark.png b/config/gtk-4.0/assets/sidebar-view-active-220px-dark.png new file mode 100755 index 0000000..341820a Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-220px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-220px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-active-220px-dark@2.png new file mode 100755 index 0000000..bac508a Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-220px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-220px.png b/config/gtk-4.0/assets/sidebar-view-active-220px.png new file mode 100755 index 0000000..01ee8af Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-220px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-220px@2.png b/config/gtk-4.0/assets/sidebar-view-active-220px@2.png new file mode 100755 index 0000000..b31366f Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-220px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-240px-dark.png b/config/gtk-4.0/assets/sidebar-view-active-240px-dark.png new file mode 100755 index 0000000..e8a9dcd Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-240px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-240px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-active-240px-dark@2.png new file mode 100755 index 0000000..35ea54b Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-240px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-240px.png b/config/gtk-4.0/assets/sidebar-view-active-240px.png new file mode 100755 index 0000000..a36938a Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-240px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-240px@2.png b/config/gtk-4.0/assets/sidebar-view-active-240px@2.png new file mode 100755 index 0000000..ab38351 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-240px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-260px-dark.png b/config/gtk-4.0/assets/sidebar-view-active-260px-dark.png new file mode 100755 index 0000000..d21965f Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-260px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-260px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-active-260px-dark@2.png new file mode 100755 index 0000000..aca4d2e Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-260px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-260px.png b/config/gtk-4.0/assets/sidebar-view-active-260px.png new file mode 100755 index 0000000..c45be2e Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-260px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-260px@2.png b/config/gtk-4.0/assets/sidebar-view-active-260px@2.png new file mode 100755 index 0000000..6b8945d Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-260px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-280px-dark.png b/config/gtk-4.0/assets/sidebar-view-active-280px-dark.png new file mode 100755 index 0000000..e13af3a Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-280px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-280px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-active-280px-dark@2.png new file mode 100755 index 0000000..b112e23 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-280px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-280px.png b/config/gtk-4.0/assets/sidebar-view-active-280px.png new file mode 100755 index 0000000..91b968c Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-280px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-active-280px@2.png b/config/gtk-4.0/assets/sidebar-view-active-280px@2.png new file mode 100755 index 0000000..c15804b Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-active-280px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-180px-dark.png b/config/gtk-4.0/assets/sidebar-view-checked-180px-dark.png new file mode 100755 index 0000000..8fd196a Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-180px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-180px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-checked-180px-dark@2.png new file mode 100755 index 0000000..c14de82 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-180px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-180px.png b/config/gtk-4.0/assets/sidebar-view-checked-180px.png new file mode 100755 index 0000000..60e291d Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-180px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-180px@2.png b/config/gtk-4.0/assets/sidebar-view-checked-180px@2.png new file mode 100755 index 0000000..f9b87e1 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-180px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-200px-dark.png b/config/gtk-4.0/assets/sidebar-view-checked-200px-dark.png new file mode 100755 index 0000000..348eae7 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-200px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-200px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-checked-200px-dark@2.png new file mode 100755 index 0000000..164f44f Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-200px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-200px.png b/config/gtk-4.0/assets/sidebar-view-checked-200px.png new file mode 100755 index 0000000..e37b397 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-200px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-200px@2.png b/config/gtk-4.0/assets/sidebar-view-checked-200px@2.png new file mode 100755 index 0000000..73e7bac Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-200px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-220px-dark.png b/config/gtk-4.0/assets/sidebar-view-checked-220px-dark.png new file mode 100755 index 0000000..1615692 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-220px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-220px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-checked-220px-dark@2.png new file mode 100755 index 0000000..3f7709d Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-220px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-220px.png b/config/gtk-4.0/assets/sidebar-view-checked-220px.png new file mode 100755 index 0000000..2330bfc Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-220px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-220px@2.png b/config/gtk-4.0/assets/sidebar-view-checked-220px@2.png new file mode 100755 index 0000000..ada0908 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-220px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-240px-dark.png b/config/gtk-4.0/assets/sidebar-view-checked-240px-dark.png new file mode 100755 index 0000000..229bc61 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-240px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-240px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-checked-240px-dark@2.png new file mode 100755 index 0000000..0ac3268 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-240px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-240px.png b/config/gtk-4.0/assets/sidebar-view-checked-240px.png new file mode 100755 index 0000000..b79b643 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-240px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-240px@2.png b/config/gtk-4.0/assets/sidebar-view-checked-240px@2.png new file mode 100755 index 0000000..4a8833e Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-240px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-260px-dark.png b/config/gtk-4.0/assets/sidebar-view-checked-260px-dark.png new file mode 100755 index 0000000..2341114 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-260px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-260px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-checked-260px-dark@2.png new file mode 100755 index 0000000..5390468 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-260px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-260px.png b/config/gtk-4.0/assets/sidebar-view-checked-260px.png new file mode 100755 index 0000000..a986d5a Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-260px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-260px@2.png b/config/gtk-4.0/assets/sidebar-view-checked-260px@2.png new file mode 100755 index 0000000..b909ebe Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-260px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-280px-dark.png b/config/gtk-4.0/assets/sidebar-view-checked-280px-dark.png new file mode 100755 index 0000000..b15e5de Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-280px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-280px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-checked-280px-dark@2.png new file mode 100755 index 0000000..5999912 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-280px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-280px.png b/config/gtk-4.0/assets/sidebar-view-checked-280px.png new file mode 100755 index 0000000..b64e8ff Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-280px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-checked-280px@2.png b/config/gtk-4.0/assets/sidebar-view-checked-280px@2.png new file mode 100755 index 0000000..1934cd0 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-checked-280px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-180px-dark.png b/config/gtk-4.0/assets/sidebar-view-hover-180px-dark.png new file mode 100755 index 0000000..904174a Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-180px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-180px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-hover-180px-dark@2.png new file mode 100755 index 0000000..4c727f2 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-180px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-180px.png b/config/gtk-4.0/assets/sidebar-view-hover-180px.png new file mode 100755 index 0000000..4e92a30 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-180px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-180px@2.png b/config/gtk-4.0/assets/sidebar-view-hover-180px@2.png new file mode 100755 index 0000000..a429243 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-180px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-200px-dark.png b/config/gtk-4.0/assets/sidebar-view-hover-200px-dark.png new file mode 100755 index 0000000..ab77744 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-200px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-200px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-hover-200px-dark@2.png new file mode 100755 index 0000000..abbef5d Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-200px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-200px.png b/config/gtk-4.0/assets/sidebar-view-hover-200px.png new file mode 100755 index 0000000..d4df15a Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-200px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-200px@2.png b/config/gtk-4.0/assets/sidebar-view-hover-200px@2.png new file mode 100755 index 0000000..943e796 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-200px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-220px-dark.png b/config/gtk-4.0/assets/sidebar-view-hover-220px-dark.png new file mode 100755 index 0000000..1ab6817 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-220px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-220px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-hover-220px-dark@2.png new file mode 100755 index 0000000..5fc0713 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-220px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-220px.png b/config/gtk-4.0/assets/sidebar-view-hover-220px.png new file mode 100755 index 0000000..3ad3862 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-220px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-220px@2.png b/config/gtk-4.0/assets/sidebar-view-hover-220px@2.png new file mode 100755 index 0000000..473915a Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-220px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-240px-dark.png b/config/gtk-4.0/assets/sidebar-view-hover-240px-dark.png new file mode 100755 index 0000000..1bfcda2 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-240px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-240px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-hover-240px-dark@2.png new file mode 100755 index 0000000..fcaed6b Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-240px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-240px.png b/config/gtk-4.0/assets/sidebar-view-hover-240px.png new file mode 100755 index 0000000..d3818a2 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-240px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-240px@2.png b/config/gtk-4.0/assets/sidebar-view-hover-240px@2.png new file mode 100755 index 0000000..f966901 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-240px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-260px-dark.png b/config/gtk-4.0/assets/sidebar-view-hover-260px-dark.png new file mode 100755 index 0000000..c29f00e Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-260px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-260px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-hover-260px-dark@2.png new file mode 100755 index 0000000..d133ab0 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-260px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-260px.png b/config/gtk-4.0/assets/sidebar-view-hover-260px.png new file mode 100755 index 0000000..ecd3bc0 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-260px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-260px@2.png b/config/gtk-4.0/assets/sidebar-view-hover-260px@2.png new file mode 100755 index 0000000..223b684 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-260px@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-280px-dark.png b/config/gtk-4.0/assets/sidebar-view-hover-280px-dark.png new file mode 100755 index 0000000..1fd1482 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-280px-dark.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-280px-dark@2.png b/config/gtk-4.0/assets/sidebar-view-hover-280px-dark@2.png new file mode 100755 index 0000000..e1aa51d Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-280px-dark@2.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-280px.png b/config/gtk-4.0/assets/sidebar-view-hover-280px.png new file mode 100755 index 0000000..4f76257 Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-280px.png differ diff --git a/config/gtk-4.0/assets/sidebar-view-hover-280px@2.png b/config/gtk-4.0/assets/sidebar-view-hover-280px@2.png new file mode 100755 index 0000000..44f64da Binary files /dev/null and b/config/gtk-4.0/assets/sidebar-view-hover-280px@2.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-active.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-active.png new file mode 100755 index 0000000..494db63 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-active.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-active@2.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-active@2.png new file mode 100755 index 0000000..9dc78af Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-active@2.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-hover.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-hover.png new file mode 100755 index 0000000..868650f Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-hover.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-hover@2.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-hover@2.png new file mode 100755 index 0000000..2eda2c6 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-hover@2.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-insensitive.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-insensitive.png new file mode 100755 index 0000000..97b995d Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-insensitive.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-insensitive@2.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-insensitive@2.png new file mode 100755 index 0000000..5981108 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above-insensitive@2.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-above.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above.png new file mode 100755 index 0000000..7e9d4d1 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-above@2.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above@2.png new file mode 100755 index 0000000..3672b6f Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-above@2.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-active.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-active.png new file mode 100755 index 0000000..5502303 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-active.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-active@2.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-active@2.png new file mode 100755 index 0000000..416dd1f Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-active@2.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-hover.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-hover.png new file mode 100755 index 0000000..d8a29e8 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-hover.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-hover@2.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-hover@2.png new file mode 100755 index 0000000..3d8fca1 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-hover@2.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-insensitive.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-insensitive.png new file mode 100755 index 0000000..76e3a86 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-insensitive.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-insensitive@2.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-insensitive@2.png new file mode 100755 index 0000000..7987146 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below-insensitive@2.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-below.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below.png new file mode 100755 index 0000000..b85a985 Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below.png differ diff --git a/config/gtk-4.0/assets/slider-horz-scale-has-marks-below@2.png b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below@2.png new file mode 100755 index 0000000..b7e02ad Binary files /dev/null and b/config/gtk-4.0/assets/slider-horz-scale-has-marks-below@2.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-active.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-active.png new file mode 100755 index 0000000..e92c9fe Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-active.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-active@2.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-active@2.png new file mode 100755 index 0000000..0885a36 Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-active@2.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-hover.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-hover.png new file mode 100755 index 0000000..5812aaf Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-hover.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-hover@2.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-hover@2.png new file mode 100755 index 0000000..b6e9423 Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-hover@2.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-insensitive.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-insensitive.png new file mode 100755 index 0000000..e2d1f05 Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-insensitive.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-insensitive@2.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-insensitive@2.png new file mode 100755 index 0000000..4ce51eb Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above-insensitive@2.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-above.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above.png new file mode 100755 index 0000000..8b5c591 Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-above@2.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above@2.png new file mode 100755 index 0000000..680c473 Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-above@2.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-active.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-active.png new file mode 100755 index 0000000..410e5b0 Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-active.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-active@2.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-active@2.png new file mode 100755 index 0000000..d377bb8 Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-active@2.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-hover.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-hover.png new file mode 100755 index 0000000..154f1ec Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-hover.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-hover@2.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-hover@2.png new file mode 100755 index 0000000..911593c Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-hover@2.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-insensitive.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-insensitive.png new file mode 100755 index 0000000..70734ab Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-insensitive.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-insensitive@2.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-insensitive@2.png new file mode 100755 index 0000000..e6e8e2e Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below-insensitive@2.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-below.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below.png new file mode 100755 index 0000000..f957b0b Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below.png differ diff --git a/config/gtk-4.0/assets/slider-vert-scale-has-marks-below@2.png b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below@2.png new file mode 100755 index 0000000..1265f7c Binary files /dev/null and b/config/gtk-4.0/assets/slider-vert-scale-has-marks-below@2.png differ diff --git a/config/gtk-4.0/gtk-dark.css b/config/gtk-4.0/gtk-dark.css new file mode 100755 index 0000000..94640fc --- /dev/null +++ b/config/gtk-4.0/gtk-dark.css @@ -0,0 +1,6249 @@ +/* This stylesheet is generated, DO NOT EDIT */ +window.background.csd > contents > leaflet.unfolded > box > headerbar { + background-image: none; + background-color: #162026; + border: none; +} + +window.background.csd > contents > leaflet.unfolded > box > stack > widget > box > widget > headerbar, +window.background.csd > contents > leaflet.unfolded > box > stack > widget > overlay > leaflet.folded > box > headerbar { + background-image: none; + background-color: #061115; +} + +window.background.csd > contents > leaflet.unfolded > box > searchbar > revealer > box { + background-color: #162026; + border-color: #000304; +} + +.titlebar:not(headerbar) > separator { + background-image: image(#000304); + background-color: transparent; + border-right: none; +} + +.card, window.background.csd stack stack stack frame > list, +window.background.csd > stack > stack > box > frame > list, +window.background.csd > stack > stack > box > box > frame > list, +window.background.csd > stack > box > stack > box > frame > list, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame > list, +window.background.csd > stack > box > stack > box > scrolledwindow > viewport > frame > list, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame > list, window.background.csd > stack > list, +window.background.csd > stack > scrolledwindow > viewport > box > list, +window.background.csd > box > stack > scrolledwindow > viewport > box > list, listview.boxed-list, +list.boxed-list, listview.content:not(.conversation-listbox), +list.content:not(.conversation-listbox), scrolledwindow viewport.frame > box.vertical list.frame { + border-radius: 12px; + box-shadow: inset 0 0 8px rgba(255, 255, 255, 0.03), inset 0 0 3px rgba(255, 255, 255, 0.02), inset 0 0 0 1px rgba(255, 255, 255, 0.04), inset 0 1px rgba(255, 255, 255, 0.06); + background-color: rgba(255, 255, 255, 0.05); + border: none; + color: #dadada; +} + +.card > separator, window.background.csd stack stack stack frame > list > separator, +window.background.csd > stack > stack > box > frame > list > separator, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame > list > separator, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame > list > separator, window.background.csd > stack > list > separator, +window.background.csd > stack > scrolledwindow > viewport > box > list > separator, listview.boxed-list > separator, +list.boxed-list > separator, listview.content:not(.conversation-listbox) > separator, +list.content:not(.conversation-listbox) > separator, scrolledwindow viewport.frame > box.vertical list.frame > separator { + background: none; + min-height: 0; +} + +window.background.csd stack stack stack frame > list row.activatable, +window.background.csd > stack > stack > box > frame > list row.activatable, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame > list row.activatable, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame > list row.activatable, window.background.csd > stack > list row.activatable, listview.boxed-list > row.expander list > row, +list.boxed-list > row.expander list > row, listview.boxed-list > row, +list.boxed-list > row, listview.content:not(.conversation-listbox) > row, +list.content:not(.conversation-listbox) > row, scrolledwindow viewport.frame > box.vertical list.frame > row.activatable { + border: none; +} + +window.background.csd stack stack stack frame > list row.activatable:first-child, window.background.csd > stack > list row.activatable:first-child, listview.boxed-list > row.expander list > row:first-child, +list.boxed-list > row.expander list > row:first-child, listview.boxed-list > row:first-child, +list.boxed-list > row:first-child, listview.content:not(.conversation-listbox) > row:first-child, +list.content:not(.conversation-listbox) > row:first-child, scrolledwindow viewport.frame > box.vertical list.frame > row.activatable:first-child { + border-top-left-radius: 12px; + border-top-right-radius: 12px; +} + +window.background.csd stack stack stack frame > list row.activatable:last-child, window.background.csd > stack > list row.activatable:last-child, listview.boxed-list > row.expander list > row:last-child, +list.boxed-list > row.expander list > row:last-child, listview.boxed-list > row:last-child, +list.boxed-list > row:last-child, listview.content:not(.conversation-listbox) > row:last-child, +list.content:not(.conversation-listbox) > row:last-child, scrolledwindow viewport.frame > box.vertical list.frame > row.activatable:last-child { + border-bottom-left-radius: 12px; + border-bottom-right-radius: 12px; +} + +window.background.csd stack stack stack frame > list row.activatable:only-child, window.background.csd > stack > list row.activatable:only-child, listview.boxed-list > row.expander list > row:only-child, +list.boxed-list > row.expander list > row:only-child, listview.boxed-list > row:only-child, +list.boxed-list > row:only-child, listview.content:not(.conversation-listbox) > row:only-child, +list.content:not(.conversation-listbox) > row:only-child, scrolledwindow viewport.frame > box.vertical list.frame > row.activatable:only-child { + border-radius: 12px; +} + +popover.emoji-picker emoji:focus, popover.emoji-picker emoji:hover, +calendar > grid > label.day-number:selected, columnview.view:selected, columnview.view:selected:focus, +treeview.view:selected, +treeview.view:selected:focus, +entry > text > selection, gridview > child:selected, flowbox > flowboxchild:selected, textview > text selection:focus, textview > text selection, iconview:selected:focus, .view:selected:focus { + background-color: #79AAEB; + color: white; +} + +popover.emoji-picker emoji:disabled:focus, popover.emoji-picker emoji:disabled:hover, +calendar > grid > label.day-number:disabled:selected, columnview.view:disabled:selected, +treeview.view:disabled:selected, +entry > text > selection:disabled, gridview > child:disabled:selected, flowbox > flowboxchild:disabled:selected, textview > text selection:disabled, iconview:disabled:selected:focus, .view:disabled:selected:focus { + color: #bcd5f5; +} + +row:selected label, label:selected { + color: white; +} + +row:selected label:disabled, label:disabled:selected { + color: #bcd5f5; +} + +.linked:not(.vertical) > dropdown > box > button.combo:dir(ltr), .linked:not(.vertical) > dropdown > box > button.combo:dir(rtl), .linked:not(.vertical) > combobox > box > button.combo:dir(ltr), .linked:not(.vertical) > combobox > box > button.combo:dir(rtl), .linked > menubutton:not(:only-child) > button { + border-radius: 0; + border-right-style: none; +} + +spinbutton:not(.vertical) > button, spinbutton:not(.vertical) > text, .linked:not(.vertical) > button, .linked:not(.vertical) > entry, .linked:not(.vertical) > entry:focus-within { + border-radius: 0; + border-right-style: none; +} + +spinbutton:not(.vertical) > button:first-child, spinbutton:not(.vertical) > text:first-child, .linked:not(.vertical) > button:first-child, .linked:not(.vertical) > entry:first-child, .linked:not(.vertical) > entry:first-child:focus-within { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +spinbutton:not(.vertical) > button:last-child, spinbutton:not(.vertical) > text:last-child, .linked:not(.vertical) > button:last-child, .linked:not(.vertical) > entry:last-child, .linked:not(.vertical) > entry:last-child:focus-within { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + border-right-style: solid; +} + +spinbutton:not(.vertical) > button:only-child, spinbutton:not(.vertical) > text:only-child, .linked:not(.vertical) > button:only-child, .linked:not(.vertical) > entry:only-child, .linked:not(.vertical) > entry:only-child:focus-within { + border-radius: 6px; + border-style: solid; +} + +spinbutton.vertical > button, spinbutton.vertical > text, .linked.vertical > button, .linked.vertical > entry, .linked.vertical > entry:focus-within { + border-radius: 0; + border-bottom-style: none; +} + +spinbutton.vertical > button:first-child, spinbutton.vertical > text:first-child, .linked.vertical > button:first-child, .linked.vertical > entry:first-child, .linked.vertical > entry:first-child:focus-within { + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} + +spinbutton.vertical > button:last-child, spinbutton.vertical > text:last-child, .linked.vertical > button:last-child, .linked.vertical > entry:last-child, .linked.vertical > entry:last-child:focus-within { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + border-bottom-style: solid; +} + +spinbutton.vertical > button:only-child, spinbutton.vertical > text:only-child, .linked.vertical > button:only-child, .linked.vertical > entry:only-child, .linked.vertical > entry:only-child:focus-within { + border-radius: 6px; + border-style: solid; +} + +.app-notification button, notebook > header > tabs > tab button.flat:active, +notebook > header > tabs > tab button.close-button:active, +notebook > header > tabs > tab button.image-button.flat:active, notebook > header > tabs > tab button.flat:hover, +notebook > header > tabs > tab button.close-button:hover, +notebook > header > tabs > tab button.image-button.flat:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, +list > row button.image-button:not(.flat), modelbutton.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; +} + +infobar.info > revealer > box button, infobar.info:hover > revealer > box button, infobar.info:backdrop > revealer > box button, infobar.question > revealer > box button, infobar.question:hover > revealer > box button, infobar.question:backdrop > revealer > box button, infobar.warning > revealer > box button, infobar.warning:hover > revealer > box button, infobar.warning:backdrop > revealer > box button, infobar.error > revealer > box button, infobar.error:hover > revealer > box button, infobar.error:backdrop > revealer > box button, .selection-mode headerbar button, headerbar.selection-mode button { + color: white; + background-color: rgba(255, 255, 255, 0); + border-color: rgba(255, 255, 255, 0.5); + background-image: none; + box-shadow: none; +} + +infobar.info > revealer > box button.flat, infobar.question > revealer > box button.flat, infobar.warning > revealer > box button.flat, infobar.error > revealer > box button.flat, .selection-mode headerbar button.flat, headerbar.selection-mode button.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: white; + background-color: rgba(255, 255, 255, 0); + background-image: none; +} + +infobar.info > revealer > box button.flat:disabled, infobar.question > revealer > box button.flat:disabled, infobar.warning > revealer > box button.flat:disabled, infobar.error > revealer > box button.flat:disabled, .selection-mode headerbar button.flat:disabled, headerbar.selection-mode button.flat:disabled, infobar.info > revealer > box button.flat:disabled label, infobar.question > revealer > box button.flat:disabled label, infobar.warning > revealer > box button.flat:disabled label, infobar.error > revealer > box button.flat:disabled label, .selection-mode headerbar button.flat:disabled label, headerbar.selection-mode button.flat:disabled label { + color: rgba(255, 255, 255, 0.4); +} + +infobar.info > revealer > box button:hover, infobar.question > revealer > box button:hover, infobar.warning > revealer > box button:hover, infobar.error > revealer > box button:hover, .selection-mode headerbar button:hover, headerbar.selection-mode button:hover { + color: white; + background-color: rgba(255, 255, 255, 0.2); + border-color: rgba(255, 255, 255, 0.5); + box-shadow: none; +} + +infobar.info > revealer > box button:active, infobar.question > revealer > box button:active, infobar.warning > revealer > box button:active, infobar.error > revealer > box button:active, .selection-mode headerbar button:active, headerbar.selection-mode button:active, infobar.info > revealer > box button:checked, infobar.question > revealer > box button:checked, infobar.warning > revealer > box button:checked, infobar.error > revealer > box button:checked, .selection-mode headerbar button:checked, headerbar.selection-mode button:checked { + color: white; + background-color: rgba(255, 255, 255, 0.4); + border-color: rgba(255, 255, 255, 0.5); + box-shadow: none; +} + +infobar.info > revealer > box button:disabled, infobar.question > revealer > box button:disabled, infobar.warning > revealer > box button:disabled, infobar.error > revealer > box button:disabled, .selection-mode headerbar button:disabled, headerbar.selection-mode button:disabled { + background-color: rgba(255, 255, 255, 0); + border-color: rgba(255, 255, 255, 0.4); + box-shadow: none; +} + +infobar.info > revealer > box button:disabled, infobar.question > revealer > box button:disabled, infobar.warning > revealer > box button:disabled, infobar.error > revealer > box button:disabled, .selection-mode headerbar button:disabled, headerbar.selection-mode button:disabled, infobar.info > revealer > box button:disabled label, infobar.question > revealer > box button:disabled label, infobar.warning > revealer > box button:disabled label, infobar.error > revealer > box button:disabled label, .selection-mode headerbar button:disabled label, headerbar.selection-mode button:disabled label { + color: rgba(255, 255, 255, 0.5); +} + +infobar.info > revealer > box button:disabled:active, infobar.question > revealer > box button:disabled:active, infobar.warning > revealer > box button:disabled:active, infobar.error > revealer > box button:disabled:active, .selection-mode headerbar button:disabled:active, headerbar.selection-mode button:disabled:active, infobar.info > revealer > box button:disabled:checked, infobar.question > revealer > box button:disabled:checked, infobar.warning > revealer > box button:disabled:checked, infobar.error > revealer > box button:disabled:checked, .selection-mode headerbar button:disabled:checked, headerbar.selection-mode button:disabled:checked { + color: #79AAEB; + background-color: rgba(255, 255, 255, 0.5); + border-color: rgba(255, 255, 255, 0.4); +} + +.background { + color: #dedede; + background-color: #0d181c; +} + +.background.csd { + border-radius: 12px; +} + +.background.csd.maximized, .background.csd.tiled, .background.csd.fullscreen { + border-radius: 12px; +} + +.background.solid-csd { + border-radius: 0; +} + +dnd { + color: #dedede; +} + +.normal-icons { + -gtk-icon-size: 16px; +} + +.large-icons { + -gtk-icon-size: 32px; +} + +spinner:disabled, +arrow:disabled, +scrollbar:disabled, +check:disabled, +radio:disabled, +treeview.expander:disabled { + -gtk-icon-filter: opacity(0.5); +} + +iconview, .view { + color: #dadada; + background-color: #061115; + transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +iconview:selected, .view:selected { + color: white; + background-color: #79AAEB; + transition: all 350ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +textview { + background-color: #061115; +} + +textview > text { + background-color: #061115; +} + +textview border { + background-color: #0a1519; +} + +textview:drop(active) { + caret-color: #E9967E; +} + +iconview, iconview:hover, iconview:selected { + border-radius: 6px; +} + +.content-view > rubberband, columnview.view > rubberband, +treeview.view > rubberband, flowbox > rubberband, +rubberband, +gridview > rubberband { + border: 1px solid #4d8ee4; + background-color: rgba(77, 142, 228, 0.2); +} + +flowbox > flowboxchild { + padding: 3px; + border-radius: 6px; +} + +flowbox > flowboxchild:selected { + outline-offset: -2px; +} + +flowbox.search-bar { + border-bottom: 1px solid #000304; +} + +gridview > child { + padding: 3px; +} + +gridview > child:selected { + outline-color: #3680e1; +} + +gridview > child box { + border-spacing: 8px; + margin: 12px; +} + +coverflow cover { + color: #dadada; + background-color: #061115; + border: 1px solid black; +} + +headerbar .subtitle, label.separator, .dim-label, row label.subtitle, +entry > text > placeholder { + opacity: 0.55; + text-shadow: none; +} + +label.separator { + color: #dedede; +} + +label > selection { + color: white; + background-color: #79AAEB; +} + +label:disabled { + color: rgba(222, 222, 222, 0.35); +} + +label:disabled selection { + color: #bcd5f5; +} + +.accent { + color: #79AAEB; +} + +.success { + color: #8CD7AA; +} + +.warning { + color: #E9967E; +} + +.error { + color: #F16269; +} + +window.assistant .sidebar { + background-color: #061115; +} + +window.assistant.csd .sidebar { + border-top-style: none; +} + +window.assistant .sidebar > label { + padding: 6px 12px; +} + +window.assistant .sidebar > label.highlight { + background-color: #79AAEB; + color: white; +} + +toast, .osd popover > arrow, +.osd popover > contents, popover.touch-selection > arrow, +popover.touch-selection > contents, popover.magnifier > arrow, +popover.magnifier > contents, .osd { + color: #d3d7df; + border: none; + background-color: #1a1a1a; + background-clip: padding-box; + border-radius: 6px; +} + +.osd { + padding: 6px; + margin: 6px; + box-shadow: 0 3px 8px rgba(0, 0, 0, 0.35); +} + +.osd.circular { + border-radius: 100%; +} + +@keyframes spin { + to { + transform: rotate(1turn); + } +} + +spinner { + background: none; + opacity: 0; + -gtk-icon-source: -gtk-icontheme("process-working-symbolic"); +} + +spinner:checked { + opacity: 1; + animation: spin 1s linear infinite; +} + +spinner:checked:disabled { + opacity: 0.5; +} + +.large-title { + font-weight: 300; + font-size: 24pt; +} + +.title-1 { + font-weight: 800; + font-size: 20pt; +} + +.title-2 { + font-weight: 800; + font-size: 15pt; +} + +.title-3 { + font-weight: 700; + font-size: 15pt; +} + +.title-4 { + font-weight: 700; + font-size: 13pt; +} + +.heading { + font-weight: 700; + font-size: 11pt; +} + +.body { + font-weight: 400; + font-size: 11pt; +} + +.caption { + font-weight: 400; + font-size: 9pt; +} + +.caption-heading { + font-weight: 700; + font-size: 9pt; +} + +.monospace { + font-family: monospace; +} + +.numeric { + font-feature-settings: "tnum"; +} + +spinbutton > text, .linked > entry:not(:only-child) { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; + border: none; +} + +spinbutton > text:focus, .linked > entry:focus:not(:only-child) { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); + transition-duration: 300ms; +} + +spinbutton > text:disabled, .linked > entry:disabled:not(:only-child) { + color: rgba(222, 222, 222, 0.35); + background-color: rgba(255, 255, 255, 0.02); +} + + +entry { + min-height: 24px; + border: none; + padding: 2px 8px; + border-radius: 6px; + caret-color: currentColor; + transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + animation-timing-function: ease-in-out; + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; +} + + +entry.search { + border-radius: 6px; +} + + +entry > image { + color: #b3b5b6; +} + + +entry > image.left { + padding-left: 0; + padding-right: 5px; +} + + +entry > image.right { + padding-right: 0; + padding-left: 5px; +} + + +entry.flat:focus-within, +entry.flat:backdrop, +entry.flat:disabled, +entry.flat:backdrop:disabled, +entry.flat { + min-height: 0; + background-image: none; + border-color: transparent; + border-radius: 0; +} + + +entry:hover { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05), inset 0 0 0 2px transparent; + transition-duration: 200ms; +} + + +entry:focus-within { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); + transition-duration: 300ms; +} + + +entry:focus-within > placeholder { + opacity: 0; +} + + +entry:disabled { + color: rgba(222, 222, 222, 0.35); + background-color: rgba(255, 255, 255, 0.02); +} + + +entry.warning { + color: white; + background-color: #8e6154; + border-image: none; +} + + +entry.warning image { + color: white; +} + + +entry.warning:focus-within { + color: white; + background-color: #E9967E; + box-shadow: none; +} + + +entry.warning > selection { + background-color: white; + color: #E9967E; +} + + +entry.error { + color: white; + background-color: #934247; + border-image: none; +} + + +entry.error image { + color: white; +} + + +entry.error:focus-within { + color: white; + background-color: #F16269; + box-shadow: none; +} + + +entry.error > selection { + background-color: white; + color: #F16269; +} + + +entry.search-missing { + color: white; + background-color: #934247; + border-image: none; +} + + +entry.search-missing image { + color: white; +} + + +entry.search-missing:focus-within { + color: white; + background-color: #F16269; + box-shadow: none; +} + + +entry.search-missing > selection { + background-color: white; + color: #F16269; +} + + +entry:drop(active):focus, +entry:drop(active) { + border-color: #E9967E; + box-shadow: none; + border-image: none; +} + +.osd entry { + color: #d3d7df; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(82, 82, 82, 0.96); + border-image: none; +} + +.osd entry image, .osd entry image:hover { + color: inherit; +} + +.osd entry:focus { + color: white; + border-color: #a5c6f2; + background-color: #79AAEB; + border-image: none; +} + +.osd entry:disabled { + color: rgba(211, 215, 223, 0.35); + background-color: rgba(82, 82, 82, 0.81); + border-image: none; +} + +.osd entry selection:focus, .osd entry selection { + color: #79AAEB; + background-color: white; +} + + +entry > progress { + margin: 0 -6px; + border-radius: 0; + border-width: 0 0 2px; + border-color: #79AAEB; + border-style: solid; + background-image: none; + background-color: transparent; + box-shadow: none; +} + + +entry progress > trough > progress { + background-color: transparent; + background-image: none; + border-radius: 0; + border-width: 0 0 2px; + border-color: #79AAEB; + border-style: solid; + box-shadow: none; +} + +.linked:not(.vertical) > entry, .linked:not(.vertical) > entry:focus-within { + min-height: 20px; +} + +.linked:not(.vertical) > entry + button.combo { + padding-left: 0; +} + +.linked.vertical > entry + button.combo { + padding: 0; +} + +.entry-tag { + margin: 8px; + border-radius: 50px; + box-shadow: none; + background-color: #F16269; + color: white; + border: none; +} + +.entry-tag:hover { + box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12); +} + +:dir(ltr) .entry-tag { + margin-left: 8px; + margin-right: 0px; + padding-left: 8px; + padding-right: 4px; +} + +:dir(rtl) .entry-tag { + margin-left: 0px; + margin-right: 8px; + padding-left: 4px; + padding-right: 8px; +} + +.entry-tag.button { + box-shadow: none; + border: none; + background-color: transparent; +} + +.entry-tag.button:not(:hover):not(:active) { + color: rgba(222, 222, 222, 0.35); +} + +treeview entry:focus-within:dir(rtl), treeview entry:focus-within:dir(ltr) { + background-color: #061115; + transition-property: color, background; +} + +treeview entry.flat, treeview entry { + border-radius: 0; + background-image: none; + background-color: #061115; +} + +treeview entry.flat:focus-within, treeview entry:focus-within { + border-color: #79AAEB; +} + +editablelabel > stack > text { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; +} + +@keyframes needs_attention { + from { + background-image: radial-gradient(farthest-side, #bcd4f5 0%, rgba(188, 212, 245, 0) 0%); + } + to { + background-image: radial-gradient(farthest-side, #bcd4f5 95%, rgba(188, 212, 245, 0)); + } +} + +stacksidebar row.needs-attention > label, stackswitcher > button.needs-attention > label, stackswitcher > button.needs-attention > image { + animation: needs_attention 150ms ease-in; + background-image: radial-gradient(farthest-side, #bcd4f5 96%, rgba(188, 212, 245, 0)); + background-size: 6px 6px, 6px 6px; + background-repeat: no-repeat; + background-position: right 3px, right 2px; +} + +stacksidebar row.needs-attention > label:backdrop, stackswitcher > button.needs-attention > label:backdrop, stackswitcher > button.needs-attention > image:backdrop { + background-size: 6px 6px, 0 0; +} + +stacksidebar row.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > image:dir(rtl) { + background-position: left 3px, left 2px; +} + +.scale-popup button, tabbox > tab button.tab-close-button, .toolbar button, splitbutton.suggested-action > button, splitbutton.suggested-action > menubutton > button, splitbutton.destructive-action > button, splitbutton.destructive-action > menubutton > button, splitbutton.opaque > button, splitbutton.opaque > menubutton > button, splitbutton.flat > button, +splitbutton.flat > menubutton > button, menubutton.suggested-action > button, menubutton.destructive-action > button, menubutton.opaque > button, menubutton.flat > button, +button.flat { + border: none; + background-color: transparent; + box-shadow: none; + background-clip: padding-box; +} + +.scale-popup button:hover, tabbox > tab button.tab-close-button:hover, .toolbar button:hover, splitbutton.suggested-action > button:hover, splitbutton.suggested-action > menubutton > button:hover, splitbutton.destructive-action > button:hover, splitbutton.destructive-action > menubutton > button:hover, splitbutton.opaque > button:hover, splitbutton.opaque > menubutton > button:hover, splitbutton.flat > button:hover, +splitbutton.flat > menubutton > button:hover, menubutton.suggested-action > button:hover, menubutton.destructive-action > button:hover, menubutton.opaque > button:hover, menubutton.flat > button:hover, +button.flat:hover { + color: #c5c5c5; + background-color: rgba(255, 255, 255, 0.15); + background-image: none; + box-shadow: none; +} + +.scale-popup button:active, tabbox > tab button.tab-close-button:active, .toolbar button:active, splitbutton.suggested-action > button:active, splitbutton.suggested-action > menubutton > button:active, splitbutton.destructive-action > button:active, splitbutton.destructive-action > menubutton > button:active, splitbutton.opaque > button:active, splitbutton.opaque > menubutton > button:active, splitbutton.flat > button:active, +splitbutton.flat > menubutton > button:active, menubutton.suggested-action > button:active, menubutton.destructive-action > button:active, menubutton.opaque > button:active, menubutton.flat > button:active, +button.flat:active { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.25); +} + +.scale-popup button:checked, tabbox > tab button.tab-close-button:checked, .toolbar button:checked, splitbutton.suggested-action > button:checked, splitbutton.suggested-action > menubutton > button:checked, splitbutton.destructive-action > button:checked, splitbutton.destructive-action > menubutton > button:checked, splitbutton.opaque > button:checked, splitbutton.opaque > menubutton > button:checked, splitbutton.flat > button:checked, +splitbutton.flat > menubutton > button:checked, menubutton.suggested-action > button:checked, menubutton.destructive-action > button:checked, menubutton.opaque > button:checked, menubutton.flat > button:checked, +button.flat:checked { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.35); +} + +.scale-popup button:disabled, tabbox > tab button.tab-close-button:disabled, .toolbar button:disabled, splitbutton.suggested-action > button:disabled, splitbutton.suggested-action > menubutton > button:disabled, splitbutton.destructive-action > button:disabled, splitbutton.destructive-action > menubutton > button:disabled, splitbutton.opaque > button:disabled, splitbutton.opaque > menubutton > button:disabled, splitbutton.flat > button:disabled, +splitbutton.flat > menubutton > button:disabled, menubutton.suggested-action > button:disabled, menubutton.destructive-action > button:disabled, menubutton.opaque > button:disabled, menubutton.flat > button:disabled, +button.flat:disabled { + background-color: transparent; +} + +.scale-popup button:disabled label, tabbox > tab button.tab-close-button:disabled label, .toolbar button:disabled label, splitbutton.suggested-action > button:disabled label, splitbutton.destructive-action > button:disabled label, splitbutton.opaque > button:disabled label, splitbutton.flat > button:disabled label, menubutton.suggested-action > button:disabled label, menubutton.destructive-action > button:disabled label, menubutton.opaque > button:disabled label, menubutton.flat > button:disabled label, +button.flat:disabled label, .scale-popup button:disabled, tabbox > tab button.tab-close-button:disabled, .toolbar button:disabled, splitbutton.suggested-action > button:disabled, splitbutton.suggested-action > menubutton > button:disabled, splitbutton.destructive-action > button:disabled, splitbutton.destructive-action > menubutton > button:disabled, splitbutton.opaque > button:disabled, splitbutton.opaque > menubutton > button:disabled, splitbutton.flat > button:disabled, +splitbutton.flat > menubutton > button:disabled, menubutton.suggested-action > button:disabled, menubutton.destructive-action > button:disabled, menubutton.opaque > button:disabled, menubutton.flat > button:disabled, +button.flat:disabled { + color: rgba(222, 222, 222, 0.35); +} + + +button.opaque { + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + + +.osd button.opaque:focus:focus-visible { + outline-color: rgba(255, 255, 255, 0.15); +} + + +button.opaque:hover { + background-image: image(alpha(currentColor,0.1)); +} + + +button.keyboard-activating.opaque, +button.opaque:active { + background-image: image(rgba(0, 0, 0, 0.2)); +} + + +button.opaque:checked { + background-image: image(rgba(0, 0, 0, 0.15)); +} + + +button.opaque:checked:hover { + background-image: image(rgba(0, 0, 0, 0.05)); +} + + +button.opaque:checked.keyboard-activating, +button.opaque:checked:active { + background-image: image(rgba(0, 0, 0, 0.3)); +} + + +button { + min-height: 24px; + min-width: 18px; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + border: 1px solid; + border-radius: 6px; + padding: 0 8px; + background-clip: padding-box; + color: #dedede; + border-color: rgba(0, 0, 0, 0.15); + background-color: #1C252C; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px rgba(255, 255, 255, 0.02), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + + +button separator { + margin: 4px 1px; +} + + +button.flat { + min-height: 24px; + transition: none; +} + + +button.flat:hover { + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-duration: 350ms; +} + + +button.flat:hover:active { + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + + +button.flat:checked:hover { + background-image: none; +} + + +button.flat.toggle.popup { + min-width: 20px; +} + + +button.opaque { + background-color: #374043; + color: #dedede; +} + + +button:hover { + color: #f8f8f8; + border-color: rgba(0, 0, 0, 0.15); + background-color: #222d35; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); + background-clip: padding-box; + -gtk-icon-filter: brightness(1.2); +} + + +button.keyboard-activating, +button:active, +button:checked { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); + background-clip: padding-box; + transition-duration: 200ms; +} + + +button.keyboard-activating:not(:disabled) label:disabled, +button:active:not(:disabled) label:disabled, +button:checked:not(:disabled) label:disabled { + color: inherit; + opacity: 0.6; +} + + +button:disabled { + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(28, 37, 44, 0.55); + box-shadow: none; + background-clip: padding-box; +} + + +button:disabled label, +button:disabled { + color: rgba(222, 222, 222, 0.35); +} + + +button:disabled:active, +button:disabled:checked { + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(121, 170, 235, 0.55); + opacity: 0.6; + background-clip: padding-box; +} + + +button:disabled:active label, +button:disabled:active, +button:disabled:checked label, +button:disabled:checked { + color: rgba(255, 255, 255, 0.55); +} + + +button.image-button { + min-height: 24px; + padding-left: 6px; + padding-right: 6px; +} + + +button.text-button { + min-height: 24px; + padding-left: 12px; + padding-right: 12px; +} + + +button.text-button.image-button, +button.image-text-button { + min-height: 24px; + padding-left: 6px; + padding-right: 6px; +} + + +button.text-button.image-button > box, +button.text-button.image-button > box > box, +button.image-text-button > box, +button.image-text-button > box > box { + border-spacing: 4px; +} + + +button.text-button.image-button > box > label, +button.text-button.image-button > box > box > label, +button.image-text-button > box > label, +button.image-text-button > box > box > label { + padding-left: 2px; + padding-right: 2px; +} + + +button.text-button.image-button label:first-child, +button.image-text-button label:first-child { + padding-left: 8px; + padding-right: 3px; +} + + +button.text-button.image-button label:last-child, +button.image-text-button label:last-child { + padding-right: 8px; + padding-left: 3px; +} + + +button.text-button.image-button label:only-child, +button.image-text-button label:only-child { + padding-left: 8px; + padding-right: 8px; +} + + +button.text-button.image-button.popup, +button.image-text-button.popup { + padding-right: 6px; + padding-left: 6px; +} + + +button.arrow-button { + padding-left: 9px; + padding-right: 9px; +} + + +button.arrow-button > box { + border-spacing: 4px; +} + + +button.arrow-button.text-button > box { + border-spacing: 4px; +} + + +button.font separator { + background-color: transparent; + background-image: none; +} + + +button.font > box { + border-spacing: 6px; +} + + +button.font > box > box > label { + font-weight: bold; +} + +stackswitcher button.circular, .app-notification button.image-button:not(.text-button), row button.circular, searchbar > revealer > box .close, searchbar button.flat, menubutton.circular > button, +button.circular, +button.close { + border-radius: 9999px; + padding: 0; + min-height: 28px; + min-width: 28px; +} + +.app-notification button.image-button:not(.text-button) label, searchbar > revealer > box .close label, searchbar button.flat label, menubutton.circular > button label, +button.circular label, +button.close label { + padding: 0; +} + +menubutton.pill > button, +button.pill { + padding: 9px 30px; + border-radius: 9999px; +} + + +button.card { + background-color: rgba(255, 255, 255, 0.05); + background-clip: padding-box; + font-weight: inherit; + padding: 6px; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + + +button.card:hover { + background-image: image(alpha(currentColor,0.03)); +} + + +button.card.keyboard-activating, +button.card:active { + background-image: image(alpha(currentColor,0.08)); +} + + +button.card:checked { + background-color: rgba(255, 255, 255, 0.05); + background-image: image(alpha(currentColor,0.1)); +} + + +button.card:checked:hover { + background-image: image(alpha(currentColor,0.13)); +} + + +button.card:checked.keyboard-activating, +button.card:checked:active { + background-image: image(alpha(currentColor,0.19)); +} + + +button.card:checked.has-open-popup { + background-image: image(alpha(currentColor,0.13)); +} + + +button.card:drop(active) { + color: #E9967E; + box-shadow: inset 0 0 0 1px #E9967E; +} + + +button:drop(active) { + color: #E9967E; + border-color: #E9967E; + box-shadow: inset 0 0 0 1px #E9967E; +} + + +button.osd { + color: #d3d7df; + background-color: #1a1a1a; + border-color: #060606; + box-shadow: none; +} + + +button.osd.image-button { + padding: 0; + min-height: 42px; + min-width: 42px; +} + + +button.osd:hover { + color: #79AAEB; + box-shadow: none; + background-color: rgba(82, 82, 82, 0.96); +} + + +button.osd.keyboard-activating, +button.osd:active, +button.osd:checked { + color: white; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.25); + background-image: none; + box-shadow: none; + background-clip: padding-box; +} + + +button.osd:disabled { + color: rgba(211, 215, 223, 0.35); + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.03); + box-shadow: none; +} + +toast button, popover.touch-selection button, popover.magnifier button, menubutton.osd > button, .osd button { + color: #d3d7df; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.08); + box-shadow: none; +} + +toast button:hover, popover.touch-selection button:hover, popover.magnifier button:hover, .osd button:hover { + color: #d3d7df; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.16); + box-shadow: none; +} + +toast button.keyboard-activating, popover.touch-selection button.keyboard-activating, popover.magnifier button.keyboard-activating, toast button:active, popover.touch-selection button:active, popover.magnifier button:active, toast button:checked, popover.touch-selection button:checked, popover.magnifier button:checked, .osd button.keyboard-activating, .osd button:active, .osd button:checked { + color: white; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.25); + background-image: none; + box-shadow: none; + background-clip: padding-box; +} + +toast button:disabled, popover.touch-selection button:disabled, popover.magnifier button:disabled, .osd button:disabled { + color: rgba(211, 215, 223, 0.35); + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.03); + box-shadow: none; +} + +toast button.flat, popover.touch-selection button.flat, popover.magnifier button.flat, .osd button.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + box-shadow: none; +} + +toast button.flat:hover, popover.touch-selection button.flat:hover, popover.magnifier button.flat:hover, .osd button.flat:hover { + color: #d3d7df; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.16); + box-shadow: none; +} + +toast button.flat:disabled, popover.touch-selection button.flat:disabled, popover.magnifier button.flat:disabled, .osd button.flat:disabled { + color: rgba(211, 215, 223, 0.35); + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.03); + box-shadow: none; + background-image: none; +} + +toast button.flat:active, popover.touch-selection button.flat:active, popover.magnifier button.flat:active, toast button.flat:checked, popover.touch-selection button.flat:checked, popover.magnifier button.flat:checked, .osd button.flat:active, .osd button.flat:checked { + color: white; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.25); + background-image: none; + box-shadow: none; + background-clip: padding-box; +} + +.osd .linked:not(.vertical):not(.path-bar) > button:hover:not(:checked):not(:active):not(:only-child), .osd .linked:not(.vertical):not(.path-bar) > button:hover:not(:checked):not(:active) + button:not(:checked):not(:active) { + box-shadow: none; +} + + +button.suggested-action { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + + +button.suggested-action.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: #79AAEB; +} + + +button.suggested-action:hover { + color: white; + background-color: #8fb8ee; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + + +button.suggested-action:active, +button.suggested-action:checked { + color: white; + background-color: #639ce8; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); + box-shadow: none; +} + + +button.suggested-action.flat:disabled { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: rgba(222, 222, 222, 0.35); +} + + +button.suggested-action:disabled { + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(28, 37, 44, 0.55); + box-shadow: none; +} + + +button.suggested-action:disabled label, +button.suggested-action:disabled { + color: rgba(222, 222, 222, 0.35); +} + + +button.destructive-action { + color: white; + background-color: #F16269; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + + +button.destructive-action.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: #F16269; +} + + +button.destructive-action:hover { + color: white; + background-color: #f3797f; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + + +button.destructive-action:active, +button.destructive-action:checked { + color: white; + background-color: #ef4b53; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); + box-shadow: none; +} + + +button.destructive-action.flat:disabled { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: rgba(222, 222, 222, 0.35); +} + + +button.destructive-action:disabled { + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(28, 37, 44, 0.55); + box-shadow: none; +} + + +button.destructive-action:disabled label, +button.destructive-action:disabled { + color: rgba(222, 222, 222, 0.35); +} + +stackswitcher > button { + outline-offset: -3px; +} + +stackswitcher > button > label { + padding-left: 6px; + padding-right: 6px; +} + +stackswitcher > button > image { + padding-left: 6px; + padding-right: 6px; +} + +stackswitcher > button.text-button { + padding-left: 10px; + padding-right: 10px; +} + +stackswitcher > button.image-button { + padding-left: 2px; + padding-right: 2px; +} + +stackswitcher > button.needs-attention:active > label, stackswitcher > button.needs-attention:active > image, stackswitcher > button.needs-attention:checked > label, stackswitcher > button.needs-attention:checked > image { + animation: none; + background-image: none; +} + + +button.font separator, +button.file separator { + background-color: transparent; +} + +menubutton { + margin: 0; +} + +menubutton.osd { + background: none; + color: inherit; +} + +menubutton.suggested-action { + background-color: #79AAEB; + color: white; +} + +menubutton.destructive-action { + background-color: #F16269; + color: white; +} + +menubutton.opaque { + background-color: #374043; + color: #dedede; +} + +menubutton.suggested-action, menubutton.destructive-action, menubutton.opaque { + border-radius: 6px; +} + +menubutton.suggested-action.circular, menubutton.suggested-action.pill, menubutton.destructive-action.circular, menubutton.destructive-action.pill, menubutton.opaque.circular, menubutton.opaque.pill { + border-radius: 9999px; +} + +menubutton.suggested-action > button, menubutton.suggested-action > button:checked, menubutton.destructive-action > button, menubutton.destructive-action > button:checked, menubutton.opaque > button, menubutton.opaque > button:checked { + background-color: transparent; + color: inherit; +} + +menubutton.image-button > button { + min-width: 24px; + padding-left: 5px; + padding-right: 5px; +} + +menubutton arrow { + min-height: 16px; + min-width: 16px; +} + +menubutton arrow.none { + -gtk-icon-source: -gtk-icontheme("open-menu-symbolic"); +} + +menubutton arrow.down { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +menubutton arrow.up { + -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); +} + +menubutton arrow.left { + -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); +} + +menubutton arrow.right { + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); +} + +.linked > menubutton:first-child > button { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.linked > menubutton:last-child > button { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +splitbutton { + border-radius: 6px; +} + +splitbutton, splitbutton > separator { + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-property: background; +} + +splitbutton > separator { + margin-top: 6px; + margin-bottom: 6px; + background: none; +} + +splitbutton > menubutton > button { + padding-left: 4px; + padding-right: 4px; +} + +splitbutton.image-button > button { + min-width: 24px; + padding-left: 6px; + padding-right: 6px; +} + +splitbutton.text-button.image-button > button, splitbutton.image-text-button > button { + padding-left: 9px; + padding-right: 9px; +} + +splitbutton.text-button.image-button > button > box, splitbutton.image-text-button > button > box { + border-spacing: 6px; +} + +splitbutton > button:dir(ltr), +splitbutton > menubutton > button:dir(rtl) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + margin-right: -1px; +} + +splitbutton > button:dir(rtl), +splitbutton > menubutton > button:dir(ltr) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; +} + +splitbutton.flat > separator { + background: rgba(255, 255, 255, 0.12); +} + +splitbutton.flat:hover, splitbutton.flat:active, splitbutton.flat:checked { + background: alpha(currentColor,0.07); +} + +splitbutton.flat:hover > separator, splitbutton.flat:active > separator, splitbutton.flat:checked > separator { + background: none; +} + +splitbutton.flat:focus-within:focus-visible > separator { + background: none; +} + +splitbutton.flat > button, +splitbutton.flat > menubutton > button { + border-radius: 6px; +} + +splitbutton.suggested-action { + background-color: #79AAEB; + color: white; +} + +splitbutton.destructive-action { + background-color: #F16269; + color: white; +} + +splitbutton.opaque { + background-color: #374043; + color: #dedede; +} + +splitbutton.suggested-action > button, splitbutton.suggested-action > button:checked, splitbutton.suggested-action > menubutton > button, splitbutton.suggested-action > menubutton > button:checked, splitbutton.destructive-action > button, splitbutton.destructive-action > button:checked, splitbutton.destructive-action > menubutton > button, splitbutton.destructive-action > menubutton > button:checked, splitbutton.opaque > button, splitbutton.opaque > button:checked, splitbutton.opaque > menubutton > button, splitbutton.opaque > menubutton > button:checked { + color: inherit; + background-color: transparent; +} + +splitbutton.suggested-action > menubutton > button:dir(ltr), splitbutton.destructive-action > menubutton > button:dir(ltr), splitbutton.opaque > menubutton > button:dir(ltr) { + box-shadow: inset 1px 0 rgba(255, 255, 255, 0.12); +} + +splitbutton.suggested-action > menubutton > button:dir(rtl), splitbutton.destructive-action > menubutton > button:dir(rtl), splitbutton.opaque > menubutton > button:dir(rtl) { + box-shadow: inset -1px 0 rgba(255, 255, 255, 0.12); +} + +splitbutton > menubutton > button > arrow.none { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +buttoncontent { + border-spacing: 6px; +} + +buttoncontent > label { + font-weight: bold; +} + +buttoncontent > label:dir(ltr) { + padding-right: 2px; +} + +buttoncontent > label:dir(rtl) { + padding-left: 2px; +} + +.arrow-button > box > buttoncontent > label:dir(ltr), splitbutton > button > buttoncontent > label:dir(ltr) { + padding-right: 0; +} + +.arrow-button > box > buttoncontent > label:dir(rtl), splitbutton > button > buttoncontent > label:dir(rtl) { + padding-left: 0; +} + +.linked:not(.vertical):not(.path-bar) > entry:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); +} + +.linked:not(.vertical):not(.path-bar) > entry:drop(active):not(:only-child) { + box-shadow: inset 0 0 0 2px #E9967E; +} + +.linked:not(.vertical):not(.path-bar) > entry.warning:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px #E9967E; +} + +.linked:not(.vertical):not(.path-bar) > entry.error:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px #F16269; +} + +.linked:not(.vertical):not(.path-bar) > button + button { + border-left-style: none; +} + +.linked:not(.vertical).path-bar > button + button { + border-left-style: none; +} + +.linked.vertical > entry:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); +} + +.linked.vertical > entry:drop(active):not(:only-child) { + box-shadow: inset 0 0 0 2px #E9967E; +} + +.linked.vertical > entry.warning:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px #E9967E; +} + +.linked.vertical > entry.error:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px #F16269; +} + +.linked.vertical > button + button { + border-top-style: none; +} + +modelbutton.flat { + transition: all 100ms cubic-bezier(0, 0, 0.2, 1); + min-height: 26px; + padding-left: 8px; + padding-right: 8px; + outline-offset: -3px; + border-radius: 6px; +} + +modelbutton.flat:hover { + background-color: #222c2f; + transition-duration: 50ms; +} + +modelbutton.flat:active, modelbutton.flat:active arrow, modelbutton.flat:selected, modelbutton.flat:selected arrow { + background-color: #79AAEB; + color: white; + transition: none; + animation: none; +} + +modelbutton.flat:checked { + color: #dedede; +} + +modelbutton.flat:disabled { + color: rgba(222, 222, 222, 0.35); +} + +modelbutton.flat check:last-child, +modelbutton.flat radio:last-child { + margin-left: 8px; +} + +modelbutton.flat check:first-child, +modelbutton.flat radio:first-child { + margin-right: 8px; +} + +modelbutton.flat arrow.left, modelbutton.flat arrow.right { + background-color: transparent; + background-image: none; + min-width: 16px; + min-height: 16px; + transition: none; + color: #afafaf; + opacity: 1; +} + +modelbutton.flat arrow.left:hover, modelbutton.flat arrow.left:selected, modelbutton.flat arrow.left:focus, modelbutton.flat arrow.right:hover, modelbutton.flat arrow.right:selected, modelbutton.flat arrow.right:focus { + background-color: transparent; + background-image: none; + transition: none; + color: white; +} + +modelbutton.flat arrow.left.left, modelbutton.flat arrow.right.left { + -gtk-icon-source: -gtk-icontheme("go-previous-symbolic"); +} + +modelbutton.flat arrow.left.right, modelbutton.flat arrow.right.right { + -gtk-icon-source: -gtk-icontheme("go-next-symbolic"); +} + +popover.menu box.circular-buttons button.circular.image-button.model, +list > row button.image-button:not(.flat) { + border: 1px solid rgba(255, 255, 255, 0); +} + +popover.menu box.circular-buttons button.circular.image-button.model:hover, +list > row button.image-button:not(.flat):hover { + color: #f8f8f8; + border-color: rgba(0, 0, 0, 0.15); + background-color: #222d35; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +popover.menu box.circular-buttons button.circular.image-button.model:active, popover.menu box.circular-buttons button.circular.image-button.model:checked, +list > row button.image-button:not(.flat):active, +list > row button.image-button:not(.flat):checked { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); +} + +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, +list > row button.image-button:not(.flat).suggested-action { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, +list > row button.image-button:not(.flat).destructive-action { + color: white; + background-color: #F16269; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + +link, button.link { + color: #79AAEB; +} + +link:visited, button.link:visited { + color: #b4b4b4; +} + +*:selected link:visited, *:selected button.link:visited { + color: #c9ddf7; +} + +link:hover, button.link:hover { + color: #a5c6f2; +} + +*:selected link:hover, *:selected button.link:hover { + color: #f2f7fd; +} + +link:active, button.link:active { + color: #79AAEB; +} + +*:selected link:active, *:selected button.link:active { + color: #e4eefb; +} + +infobar.info > revealer > box link, infobar.info:hover > revealer > box link, infobar.info:backdrop > revealer > box link, infobar.question > revealer > box link, infobar.question:hover > revealer > box link, infobar.question:backdrop > revealer > box link, infobar.warning > revealer > box link, infobar.warning:hover > revealer > box link, infobar.warning:backdrop > revealer > box link, infobar.error > revealer > box link, infobar.error:hover > revealer > box link, infobar.error:backdrop > revealer > box link, .selection-mode headerbar .subtitle:link, headerbar.selection-mode .subtitle:link, link:selected, *:selected link, button.link:selected, *:selected button.link { + color: #e4eefb; +} + +button.link > label { + text-decoration-line: underline; +} + +spinbutton { + font-feature-settings: "tnum"; +} + +spinbutton:drop(active) { + box-shadow: none; +} + +spinbutton button:active { + color: white; +} + +spinbutton:disabled { + color: rgba(222, 222, 222, 0.35); +} + +spinbutton > text { + padding: 6px; + border: 1px solid rgba(0, 0, 0, 0.15); +} + +spinbutton > text:focus-within { + border-color: rgba(188, 212, 245, 0.75); + box-shadow: inset 0 0 0 1px rgba(188, 212, 245, 0.75); +} + +spinbutton > text:drop(active) { + border-color: #E9967E; + box-shadow: inset 0 0 0 1px #E9967E; +} + +spinbutton:not(.vertical) { + padding: 0; + border-spacing: 0; +} + +spinbutton:not(.vertical) > text { + padding-top: 2px; + padding-bottom: 2px; + min-width: 28px; +} + +spinbutton:not(.vertical) > button, spinbutton:not(.vertical) > text { + min-height: 20px; +} + +spinbutton:not(.vertical):dir(ltr) > text, spinbutton:not(.vertical):dir(rtl) > button.up { + border-radius: 6px 0 0 6px; +} + +spinbutton:not(.vertical) > button + button { + border-left-style: none; +} + +spinbutton:not(.vertical) > button:hover:not(:active), +spinbutton:not(.vertical) > button:hover + button { + box-shadow: inset 1px 0 rgba(255, 255, 255, 0.12); +} + +spinbutton:not(.vertical) > button:disabled + button:not(:disabled):not(:active):not(:checked):not(:hover), +spinbutton:not(.vertical) > button:not(:disabled):not(:active):not(:checked):not(:hover) + button:disabled { + box-shadow: inset 1px 0 rgba(255, 255, 255, 0); +} + +spinbutton:not(.vertical) > button:first-child:hover:not(:active), +spinbutton:not(.vertical) > button.up:dir(rtl):hover:not(:active), +spinbutton:not(.vertical) > text + button:not(:active):hover { + box-shadow: none; +} + +spinbutton:not(.vertical) > text:focus-within + button { + border-left-color: rgba(188, 212, 245, 0.75); +} + +spinbutton:not(.vertical) > text:drop(active) + button { + border-left-color: #E9967E; +} + +.osd spinbutton:not(.vertical), .osd spinbutton:not(.vertical):focus-within, .osd spinbutton:not(.vertical):drop(active) { + border-image: none; +} + +.osd spinbutton:not(.vertical) > button:hover:not(:active), +.osd spinbutton:not(.vertical) > button:hover + button { + box-shadow: inset 1px 0 rgba(0, 0, 0, 0.15); +} + +.osd spinbutton:not(.vertical) > button:first-child:hover:not(:active), +.osd spinbutton:not(.vertical) > button.up:dir(rtl):hover:not(:active), +.osd spinbutton:not(.vertical) > text + button:not(:active):hover { + box-shadow: none; +} + +.osd spinbutton:not(.vertical) > text:focus-within + button { + border-left-color: rgba(188, 212, 245, 0.75); +} + +spinbutton.vertical > button, spinbutton.vertical > text { + padding-left: 4px; + padding-right: 4px; + min-width: 0; +} + +spinbutton.vertical > button.up { + border-radius: 6px 6px 0 0; +} + +spinbutton.vertical > text:focus-within + button { + border-top-color: rgba(188, 212, 245, 0.75); +} + +spinbutton.vertical > text:drop(active) + button { + border-top-color: #E9967E; +} + +treeview spinbutton:not(.vertical), row spinbutton:not(.vertical) { + min-height: 0; + padding: 0 3px; + border-style: none; + border-radius: 6px; + background-color: rgba(222, 222, 222, 0.08); +} + +treeview spinbutton:not(.vertical):focus, treeview spinbutton:not(.vertical):hover, treeview spinbutton:not(.vertical):selected, row spinbutton:not(.vertical):focus, row spinbutton:not(.vertical):hover, row spinbutton:not(.vertical):selected { + background-color: rgba(222, 222, 222, 0.12); +} + +treeview spinbutton:not(.vertical):focus-within, row spinbutton:not(.vertical):focus-within { + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); + transition: box-shadow 150ms cubic-bezier(0, 0, 0.2, 1); +} + +treeview spinbutton:not(.vertical) > text, treeview spinbutton:not(.vertical) > text:hover, treeview spinbutton:not(.vertical) > text:focus, row spinbutton:not(.vertical) > text, row spinbutton:not(.vertical) > text:hover, row spinbutton:not(.vertical) > text:focus { + background: none; + border: none; + box-shadow: none; +} + +treeview spinbutton:not(.vertical) > button.up, +treeview spinbutton:not(.vertical) > button.down, row spinbutton:not(.vertical) > button.up, +row spinbutton:not(.vertical) > button.down { + border: none; + border-color: transparent; + box-shadow: none; + border-radius: 100px; + min-height: 22px; + min-width: 22px; + padding: 0; + margin: 4px 2px; + background-color: transparent; +} + +treeview spinbutton:not(.vertical) > button.up:hover, +treeview spinbutton:not(.vertical) > button.down:hover, row spinbutton:not(.vertical) > button.up:hover, +row spinbutton:not(.vertical) > button.down:hover { + background-color: rgba(222, 222, 222, 0.1); +} + +treeview spinbutton:not(.vertical) > button.up:active, +treeview spinbutton:not(.vertical) > button.down:active, row spinbutton:not(.vertical) > button.up:active, +row spinbutton:not(.vertical) > button.down:active { + background-color: rgba(222, 222, 222, 0.15); + color: #dedede; +} + +treeview spinbutton:not(.vertical) > button:hover:not(:active), +treeview spinbutton:not(.vertical) > button:hover + button, row spinbutton:not(.vertical) > button:hover:not(:active), +row spinbutton:not(.vertical) > button:hover + button { + box-shadow: none; +} + +treeview spinbutton:not(.vertical) > button:disabled + button:not(:disabled):not(:active):not(:checked):not(:hover), +treeview spinbutton:not(.vertical) > button:not(:disabled):not(:active):not(:checked):not(:hover) + button:disabled, row spinbutton:not(.vertical) > button:disabled + button:not(:disabled):not(:active):not(:checked):not(:hover), +row spinbutton:not(.vertical) > button:not(:disabled):not(:active):not(:checked):not(:hover) + button:disabled { + box-shadow: none; +} + +treeview spinbutton:not(.vertical) > text:focus + button, row spinbutton:not(.vertical) > text:focus + button { + border-left-color: transparent; +} + +treeview spinbutton:not(.vertical) > text:drop(active) + button, row spinbutton:not(.vertical) > text:drop(active) + button { + border-left-color: transparent; +} + +dropdown > popover.menu.background > contents { + padding: 0; +} + +dropdown > button > box { + border-spacing: 6px; +} + +dropdown, +combobox { + min-height: 24px; +} + +dropdown button.combo, +combobox button.combo { + min-width: 0; + min-height: 24px; + padding-left: 12px; + padding-right: 12px; +} + +dropdown > popover.menu > contents modelbutton, +combobox > popover.menu > contents modelbutton { + padding-left: 10px; + padding-right: 10px; +} + +dropdown button.combo arrow, +combobox button.combo arrow { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); + -gtk-icon-source: -gtk-scaled(url("assets/combobox-arrow-dark.png"), url("assets/combobox-arrow-dark@2.png")); + min-height: 16px; + min-width: 18px; + padding: 0; + margin: 2px -10px 2px 0; + border-radius: 5px; + border: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.15), 0 1px 2px 0 rgba(0, 0, 0, 0.05); +} + +.background dropdown button.combo:disabled arrow, .background dropdown button.combo:backdrop arrow, .background combobox button.combo:disabled arrow, .background combobox button.combo:backdrop arrow { + background-color: rgba(255, 255, 255, 0.25); +} + +dropdown button.combo:checked, .background dropdown button.combo:checked, +combobox button.combo:checked, .background combobox button.combo:checked { + transition: none; +} + +dropdown:drop(active) button.combo, +combobox:drop(active) button.combo { + color: #E9967E; + border-color: #E9967E; + box-shadow: none; +} + +dropdown popover, +combobox popover { + margin-top: 3px; + padding: 0; +} + +dropdown popover listview, +combobox popover listview { + margin: 6px 0; +} + +dropdown popover listview > row, +combobox popover listview > row { + padding: 6px; +} + +dropdown popover listview > row:selected, +combobox popover listview > row:selected { + color: white; + background-color: #79AAEB; +} + +dropdown popover .dropdown-searchbar, +combobox popover .dropdown-searchbar { + padding: 6px; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +dropdown .linked:not(.vertical) > entry + button.combo arrow, .linked:not(.vertical) > dropdown > box > button.combo arrow, +combobox .linked:not(.vertical) > entry + button.combo arrow, .linked:not(.vertical) > combobox > box > button.combo arrow { + background-color: transparent; + box-shadow: none; + -gtk-icon-source: -gtk-scaled(url("assets/combobox-arrow-dark.png"), url("assets/combobox-arrow-dark@2.png")); +} + +dropdown .linked:not(.vertical) > entry + button.combo:checked arrow, dropdown .linked:not(.vertical) > entry + button.combo:active arrow, .linked:not(.vertical) > dropdown > box > button.combo:checked arrow, .linked:not(.vertical) > dropdown > box > button.combo:active arrow, +combobox .linked:not(.vertical) > entry + button.combo:checked arrow, +combobox .linked:not(.vertical) > entry + button.combo:active arrow, .linked:not(.vertical) > combobox > box > button.combo:checked arrow, .linked:not(.vertical) > combobox > box > button.combo:active arrow { + border-radius: 0; + background-color: transparent; + -gtk-icon-source: -gtk-scaled(url("assets/combobox-arrow-dark.png"), url("assets/combobox-arrow-dark@2.png")); +} + +.linked:not(.vertical) > dropdown:first-child > box > button.combo, .linked:not(.vertical) > combobox:first-child > box > button.combo { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.linked:not(.vertical) > dropdown:last-child > box > button.combo, .linked:not(.vertical) > combobox:last-child > box > button.combo { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + border-right: 1px solid rgba(0, 0, 0, 0.15); +} + +.linked:not(.vertical) > dropdown:only-child > box > button.combo, .linked:not(.vertical) > combobox:only-child > box > button.combo { + border-radius: 6px; +} + +.linked.vertical > dropdown:first-child > box > button.combo, .linked.vertical > combobox:first-child > box > button.combo { + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} + +.linked.vertical > dropdown:last-child > box > button.combo, .linked.vertical > combobox:last-child > box > button.combo { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; +} + +.linked.vertical > dropdown:only-child > box > button.combo, .linked.vertical > combobox:only-child > box > button.combo { + border-radius: 6px; +} + +searchbar > revealer > box, .toolbar { + padding: 3px 6px; + border-spacing: 6px; +} + +.toolbar separator { + background: none; +} + +.toolbar.horizontal separator { + margin: 0 6px; +} + +.toolbar.vertical separator { + margin: 6px 0; +} + +.toolbar button { + margin: 1px; +} + +.osd .toolbar { + background-color: transparent; +} + +.toolbar.osd { + padding: 6px; + border: none; + border-radius: 10px; + background-color: #1a1a1a; + box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.2), 0 3px 5px 0 rgba(0, 0, 0, 0.15); +} + +.toolbar.osd scalebutton { + margin: 0; +} + +.toolbar.osd.left, .toolbar.osd.right, .toolbar.osd.top, .toolbar.osd.bottom { + border-radius: 0; +} + +.toolbar.osd.top { + border-width: 0 0 1px 0; +} + +.toolbar.osd.bottom { + border-width: 1px 0 0 0; +} + +.toolbar.osd.left { + border-width: 0 1px 0 0; +} + +.toolbar.osd.right { + border-width: 0 0 0 1px; +} + +searchbar:not(.inline) > revealer > box { + border-style: solid; + border-color: #242e31; + background-color: #000a0e; + border-width: 0 0 1px; + box-shadow: none; + color: #FDFDFD; +} + +searchbar > revealer > box { + padding: 6px; + border-spacing: 6px; +} + +searchbar > revealer > box entry { + margin: 0; +} + +searchbar > revealer > box .close { + min-width: 18px; + min-height: 18px; + padding: 4px; + border-radius: 50%; +} + +actionbar > revealer > box { + padding: 6px; + border-spacing: 6px; + border-top: 1px solid rgba(255, 255, 255, 0.12); + background-color: #080f12; + box-shadow: none; +} + +actionbar > revealer > box entry, actionbar > revealer > box button { + margin: 0; +} + +actionbar > revealer > box, actionbar > revealer > box > box.start, actionbar > revealer > box > box.end { + border-spacing: 6px; +} + +headerbar separator.titlebutton { + min-width: 0; + min-height: 0; + background-color: transparent; + border: none; +} + +headerbar separator.titlebutton:backdrop { + opacity: 0.65; +} + +headerbar entry { + color: #FDFDFD; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; +} + +headerbar entry image, headerbar entry image:hover { + color: inherit; +} + +headerbar entry:backdrop { + opacity: 0.65; + background-image: none; +} + +headerbar entry:hover { + color: #FDFDFD; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05), inset 0 0 0 2px transparent; + transition-duration: 200ms; +} + +headerbar entry:focus { + background-image: none; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); +} + +headerbar entry:disabled { + color: rgba(253, 253, 253, 0.35); + background-color: rgba(255, 255, 255, 0.02); +} + +headerbar entry selection:focus { + background-color: #79AAEB; + color: white; +} + +headerbar entry progress { + border-color: #79AAEB; + background-image: none; + background-color: transparent; +} + +headerbar entry.warning { + color: white; + border-color: rgba(255, 255, 255, 0.12); + background-color: #8c5e51; +} + +headerbar entry.warning:focus { + color: white; + background-color: #E9967E; +} + +headerbar entry.warning selection { + background-color: white; + color: #E9967E; +} + +headerbar entry.error { + color: white; + border-color: rgba(255, 255, 255, 0.12); + background-color: #913f45; +} + +headerbar entry.error:focus { + color: white; + background-color: #F16269; +} + +headerbar entry.error selection { + background-color: white; + color: #F16269; +} + +headerbar button { + color: #FDFDFD; + background-color: transparent; + background-image: none; + border: none; + box-shadow: none; +} + +headerbar button:backdrop { + opacity: 0.65; + background-image: none; +} + +headerbar button:hover { + color: #f8f8f8; + background-color: rgba(253, 253, 253, 0.1); + background-image: none; + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +headerbar button:active { + color: #FDFDFD; + background-color: rgba(253, 253, 253, 0.25); + background-image: none; + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-duration: 300ms; +} + +headerbar button:checked { + color: #FDFDFD; + background-color: rgba(253, 253, 253, 0.12); + background-image: none; + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-duration: 300ms; +} + +headerbar button:checked:hover { + background-image: none; +} + +headerbar button:disabled { + background-image: none; + background-color: transparent; + box-shadow: none; +} + +headerbar button:disabled label, headerbar button:disabled { + color: rgba(253, 253, 253, 0.35); +} + +headerbar button.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; +} + +headerbar { + min-height: 42px; + padding: 0 16px; + color: #FDFDFD; + background-color: #000a0e; + border-bottom: 1px solid #000304; + box-shadow: none; + margin: 0; +} + +headerbar:backdrop { + transition: 150ms ease-out; + color: rgba(253, 253, 253, 0.7); + background-color: #000a0e; + border-color: black; + box-shadow: none; +} + +headerbar .title { + padding-left: 12px; + padding-right: 12px; +} + +headerbar .subtitle { + font-size: smaller; + padding-left: 12px; + padding-right: 12px; + margin-top: -3px; +} + +headerbar > windowhandle > box { + padding: 0; +} + +headerbar > windowhandle > box, +headerbar > windowhandle > box > box.start, +headerbar > windowhandle > box > box.end { + border-spacing: 6px; +} + +headerbar button, headerbar spinbutton, headerbar entry, headerbar stackswitcher { + margin-top: 8px; + margin-bottom: 8px; +} + +headerbar menubutton.popup { + margin-top: 0; + margin-bottom: 0; +} + +.linked.raised > headerbar { + border-radius: 6px; + border: none; + box-shadow: none; +} + +.linked.raised > headerbar:disabled { + background: none; +} + +headerbar stackswitcher.linked:not(.vertical) > button { + min-width: 24px; + border-radius: 6px; +} + +headerbar .linked:not(.vertical) > entry { + color: #FDFDFD; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; + margin: 8px 4px; + padding: 0 12px; + border-radius: 6px; + border: none; +} + +headerbar .linked:not(.vertical) > entry image, headerbar .linked:not(.vertical) > entry image:hover { + color: inherit; +} + +headerbar .linked:not(.vertical) > entry:focus { + border-radius: 6px; + background-image: none; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); +} + +headerbar .linked:not(.vertical) > entry:disabled { + border-radius: 6px; + color: rgba(253, 253, 253, 0.35); + background-color: rgba(255, 255, 255, 0.02); +} + +headerbar .linked:not(.vertical) > entry:backdrop { + opacity: 0.65; + background-image: none; +} + +headerbar stackswitcher { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); + border-radius: 6px; + padding: 0; +} + +headerbar stackswitcher > button { + margin: 0; + font-weight: 500; +} + +headerbar stackswitcher > button:not(:first-child) { + border-width: 0 0 0 1px; + border-style: none solid none none; + border-radius: 0; + border-image: linear-gradient(to bottom, transparent 16%, rgba(255, 255, 255, 0.1) 16%, rgba(255, 255, 255, 0.1) 84%, transparent 84%) 0 0 0 1/0 0 0 1px stretch; +} + +headerbar stackswitcher > button:checked { + border-image: none; +} + +headerbar stackswitcher button:checked + button { + border-image: none; +} + +headerbar switch { + margin-top: 0; + margin-bottom: 0; +} + +headerbar switch:backdrop { + opacity: 0.75; +} + +headerbar.titlebar headerbar:not(.titlebar) { + background: none; + box-shadow: none; +} + +headerbar windowhandle box.linked > button { + background-color: rgba(255, 255, 255, 0.05); +} + +headerbar windowhandle box.linked > button:hover { + background-color: rgba(255, 255, 255, 0.1); +} + +headerbar windowhandle box.linked > button:active { + background-color: rgba(255, 255, 255, 0.16); +} + +headerbar windowhandle box.linked > button:checked { + background-color: rgba(255, 255, 255, 0.12); +} + +.selection-mode headerbar, headerbar.selection-mode { + color: white; + background-color: #bcd4f5; + border-color: #aac9f2; + box-shadow: none; + background-image: none; + text-shadow: none; +} + +.selection-mode headerbar:backdrop, headerbar.selection-mode:backdrop { + background-color: #bcd4f5; + color: rgba(255, 255, 255, 0.6); + border-color: #aac9f2; +} + +.selection-mode headerbar button, headerbar.selection-mode button { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; +} + +.selection-mode headerbar .selection-menu, headerbar.selection-mode .selection-menu { + box-shadow: none; + padding-left: 10px; + padding-right: 10px; +} + +.selection-mode headerbar .selection-menu .arrow, headerbar.selection-mode .selection-menu .arrow { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +.maximized .selection-mode headerbar, .maximized headerbar.selection-mode { + background-color: #bcd4f5; +} + +.tiled headerbar, .tiled headerbar:backdrop, .maximized headerbar, .maximized headerbar:backdrop { + border-radius: 12px 12px 0 0; + box-shadow: none; +} + +.maximized headerbar { + background-color: #000a0e; + border-color: #000304; + box-shadow: none; +} + +.maximized headerbar:backdrop { + background-color: #000a0e; + border-color: black; +} + +headerbar.default-decoration { + min-height: 32px; + padding: 0 12px; + background-color: #000a0e; +} + +.tiled headerbar.default-decoration, .maximized headerbar.default-decoration, .fullscreen headerbar.default-decoration { + box-shadow: none; +} + +headerbar.default-decoration windowcontrols button, +headerbar.default-decoration windowcontrols menubutton { + border: none; + min-width: 16px; + min-height: 16px; + margin: 0; + padding: 0; +} + +headerbar.default-decoration windowcontrols menubutton button { + min-height: 20px; + min-width: 20px; + margin: 0; + padding: 4px; +} + +.titlebar > box.left.horizontal, +.titlebar > box.right.horizontal { + padding: 0 6px; +} + +window > .titlebar:not(headerbar), window > .titlebar:not(headerbar):backdrop, window.csd > .titlebar:not(headerbar), window.csd > .titlebar:not(headerbar):backdrop { + padding: 0; + background: none; + border: none; + box-shadow: none; +} + +.titlebar:not(headerbar) > separator { + min-width: 1px; +} + +pathbar > button { + min-width: 12px; + min-height: 26px; +} + +pathbar > button.text-button, pathbar > button.image-button, pathbar > button { + padding-left: 6px; + padding-right: 6px; +} + +pathbar > button:hover { + box-shadow: none; +} + +pathbar > button:active, pathbar > button:checked { + background-color: #b8b8b8; + color: rgba(0, 0, 0, 0.75); + border-color: rgba(0, 0, 0, 0.15); +} + +pathbar > button:disabled { + border-color: rgba(0, 0, 0, 0.15); +} + +pathbar > button.text-button.image-button label { + padding-left: 0; + padding-right: 0; +} + +pathbar > button.text-button.image-button label:last-child, pathbar > button label:last-child { + padding-right: 10px; +} + +pathbar > button.text-button.image-button label:first-child, pathbar > button label:first-child { + padding-left: 10px; +} + +pathbar > button.slider-button, pathbar > button:not(.image-button):not(.text-button) { + padding-left: 1px; + padding-right: 1px; +} + +pathbar > button image { + padding-left: 6px; + padding-right: 6px; +} + +columnview.view, +treeview.view { + border-left-color: #242e31; + border-top-color: #242e31; +} + +columnview.view acceleditor > label, +treeview.view acceleditor > label { + background-color: #79AAEB; +} + +columnview.view:selected, columnview.view:selected:focus, +treeview.view:selected, +treeview.view:selected:focus { + border-radius: 0; + border-left-color: #bcd5f5; + border-top-color: rgba(222, 222, 222, 0.15); +} + +columnview.view:disabled, +treeview.view:disabled { + color: rgba(222, 222, 222, 0.35); +} + +columnview.view:disabled:selected, +treeview.view:disabled:selected { + color: #afccf3; +} + +columnview.view.separator, +treeview.view.separator { + min-height: 2px; + color: rgba(255, 255, 255, 0.12); +} + +columnview.view > dndtarget:drop(active), +treeview.view > dndtarget:drop(active) { + border-style: solid none; + border-width: 1px; + border-color: #acc4e5; +} + +columnview.view > dndtarget:drop(active).after, +treeview.view > dndtarget:drop(active).after { + border-top-style: none; +} + +columnview.view > dndtarget:drop(active).before, +treeview.view > dndtarget:drop(active).before { + border-bottom-style: none; +} + +columnview.view.expander, +treeview.view.expander { + min-width: 16px; + min-height: 16px; + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); + color: #72787a; +} + +columnview.view.expander:dir(rtl), +treeview.view.expander:dir(rtl) { + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); +} + +columnview.view.expander:hover, +treeview.view.expander:hover { + color: #dedede; +} + +columnview.view.expander:selected, +treeview.view.expander:selected { + color: #d7e6f9; +} + +columnview.view.expander:selected:hover, +treeview.view.expander:selected:hover { + color: white; +} + +columnview.view.expander:checked, +treeview.view.expander:checked { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +columnview.view.progressbar, +treeview.view.progressbar { + color: white; + border-radius: 6px; + background-color: #79AAEB; +} + +columnview.view.progressbar:selected, columnview.view.progressbar:selected:focus, +treeview.view.progressbar:selected, +treeview.view.progressbar:selected:focus { + color: #79AAEB; + box-shadow: none; + background-color: white; +} + +columnview.view.trough, +treeview.view.trough { + color: #dedede; + background-color: rgba(255, 255, 255, 0.12); + border-radius: 6px; + border-width: 0; +} + +columnview.view.trough:selected, columnview.view.trough:selected:focus, +treeview.view.trough:selected, +treeview.view.trough:selected:focus { + color: white; + background-color: rgba(0, 0, 0, 0.2); + border-radius: 6px; + border-width: 0; +} + +columnview.view > header > button, +treeview.view > header > button { + min-height: 26px; + min-width: 38px; + padding: 0 6px; + font-weight: bold; + color: #b3b5b6; + background-color: #061115; + background-image: none; + box-shadow: none; + border-style: none solid none none; + border-radius: 0; + border-image: linear-gradient(to bottom, #061115 20%, rgba(255, 255, 255, 0.11) 20%, rgba(255, 255, 255, 0.11) 80%, #061115 80%) 0 1 0 0/0 1px 0 0 stretch; +} + +columnview.view > header > button:hover, +treeview.view > header > button:hover { + color: #79AAEB; +} + +columnview.view > header > button:active, +treeview.view > header > button:active { + color: #dedede; +} + +columnview.view > header > button:active, columnview.view > header > button:hover, +treeview.view > header > button:active, +treeview.view > header > button:hover { + background-color: #061115; +} + +columnview.view > header > button:disabled, +treeview.view > header > button:disabled { + border-color: #0d181c; + background-image: none; +} + +columnview.view > header > button:last-child, +treeview.view > header > button:last-child { + border-right-style: none; + border-image: none; +} + +columnview.view button.dnd, columnview.view button.dnd:selected, columnview.view button.dnd:hover, columnview.view button.dnd:active, +columnview.view header.button.dnd, +columnview.view header.button.dnd:selected, +columnview.view header.button.dnd:hover, +columnview.view header.button.dnd:active, +treeview.view button.dnd, +treeview.view button.dnd:selected, +treeview.view button.dnd:hover, +treeview.view button.dnd:active, +treeview.view header.button.dnd, +treeview.view header.button.dnd:selected, +treeview.view header.button.dnd:hover, +treeview.view header.button.dnd:active { + padding: 0 6px; + transition: none; + color: white; + background-color: #79AAEB; + border-radius: 0; + border-style: none; +} + +menubar { + padding: 0; + background-color: #000a0e; + color: #FDFDFD; + box-shadow: inset 0 -1px rgba(255, 255, 255, 0.12); +} + +menubar:backdrop { + color: rgba(253, 253, 253, 0.8); +} + +menubar > item { + transition: all 0.2s cubic-bezier(0, 0, 0.2, 1); + padding: 4px 6px; + border: none; + border-radius: 3px; +} + +menubar > item:hover { + transition: none; + color: #f8f8f8; + background-color: rgba(253, 253, 253, 0.1); + background-image: none; + box-shadow: none; +} + +menubar > item:disabled { + color: rgba(253, 253, 253, 0.4); +} + +menubar > item popover.menu.background > contents { + padding: 6px; + border-radius: 10px; +} + +menubar > item popover.menu popover.menu { + padding: 0 0 6px 0; +} + +menubar > item popover.menu.background popover.menu.background > contents { + margin: 0; + border-radius: 10px; +} + +popover.background { + background-color: transparent; + font: initial; +} + +popover > arrow, +popover > contents { + color: #dedede; + background-clip: border-box; + background-color: #162026; + box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.55); + border: 1px solid #213039; +} + +popover, popover:backdrop { + background-color: transparent; +} + +popover > contents { + padding: 6px; + border-radius: 12px; +} + +popover > contents > list, +popover > contents > .view, +popover > contents > toolbar { + border-style: none; + background-color: transparent; +} + +popover > contents separator { + background-color: rgba(255, 255, 255, 0.08); + margin: 3px; +} + +popover > contents > scrolledwindow > viewport > stack > box { + padding: 0; +} + +popover > contents listview.view { + padding: 0; + margin: 0; +} + +popover > contents listview.view > row { + margin: 0; + padding: 3px 6px; +} + +popover entry { + background-color: #202a2f; +} + +.osd popover, popover.touch-selection, popover.magnifier { + background-color: transparent; +} + +.osd popover > arrow, +.osd popover > contents, popover.touch-selection > arrow, +popover.touch-selection > contents, popover.magnifier > arrow, +popover.magnifier > contents { + border: none; + box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.35); +} + +cursor-handle { + background-color: transparent; + background-image: none; + box-shadow: none; + border-style: none; +} + +cursor-handle.top { + -gtk-icon-source: -gtk-icontheme("selection-start-symbolic"); +} + +cursor-handle.bottom { + -gtk-icon-source: -gtk-icontheme("selection-end-symbolic"); +} + +popover.menu { + padding: 0; +} + +popover.menu box.inline-buttons { + padding: 0 6px; +} + +popover.menu box.inline-buttons button.image-button.model { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + min-height: 28px; + min-width: 28px; + padding: 0; + border: none; + outline: none; + transition: none; +} + +popover.menu box.inline-buttons button.image-button.model:selected { + color: white; + background-image: image(#79AAEB); +} + +popover.menu box.circular-buttons { + padding: 6px; +} + +popover.menu box.circular-buttons button.circular.image-button.model { + padding: 6px; + border: none; +} + +popover.menu box.circular-buttons button.circular.image-button.model:focus { + background-color: rgba(255, 255, 255, 0.1); +} + +popover.menu box.circular-buttons button.circular.image-button.model:active:focus { + color: white; + background-color: #79AAEB; +} + +popover.menu > arrow, popover.menu.background > contents { + background-color: #162026; + color: #dedede; +} + +popover.menu.background separator { + margin: 6px 0; +} + +popover.menu accelerator { + color: alpha(currentColor,0.55); +} + +popover.menu accelerator:dir(ltr) { + margin-left: 6px; +} + +popover.menu accelerator:dir(rtl) { + margin-right: 6px; +} + +popover.menu arrow.left, +popover.menu radio.left, +popover.menu check.left { + margin-left: -2px; + margin-right: 6px; +} + +popover.menu arrow.right, +popover.menu radio.right, +popover.menu check.right { + margin-left: 6px; + margin-right: -2px; +} + +popover.menu modelbutton { + min-height: 22px; + min-width: 88px; + padding: 2px 6px; + border-radius: 7px; + transition: none; + color: #dadada; +} + +popover.menu modelbutton:focus { + background-color: transparent; + color: #dedede; + box-shadow: inset 0 0 0 2px rgba(222, 222, 222, 0.06); + transition: none; +} + +popover.menu modelbutton:hover { + color: white; + background-color: #79AAEB; + transition: background-color 100ms cubic-bezier(0, 0, 0.2, 1); +} + +popover.menu modelbutton:hover:focus { + color: white; + background-color: #79AAEB; + box-shadow: none; +} + +popover.menu modelbutton:selected:active { + color: white; + background-color: #639ce8; + transition: background-color 100ms cubic-bezier(0, 0, 0.2, 1); +} + +popover.menu label.title { + font-weight: bold; + padding: 3px 26px; +} + +tabbar tab, +dnd tab, tabbox > tab, notebook > header > tabs > tab { + color: rgba(222, 222, 222, 0.35); + background-color: rgba(6, 17, 21, 0); + border: none; + transition: all 150ms ease-out; + border-radius: 6px; + padding: 2px 10px; + margin: 0; + box-shadow: none; +} + +tabbar tab:hover:not(:checked), +dnd tab:hover:not(:checked), tabbox > tab:hover:not(:checked), notebook > header > tabs > tab:hover:not(:checked) { + color: rgba(222, 222, 222, 0.675); + background-color: rgba(222, 222, 222, 0.06); + box-shadow: none; +} + +tabbar tab:checked, +dnd tab:checked, tabbox > tab:checked, notebook > header > tabs > tab:checked { + color: #dedede; + background-color: rgba(222, 222, 222, 0.12); + box-shadow: none; +} + +notebook { + padding: 0; +} + +notebook.frame { + border: 1px solid #242e31; +} + +notebook > stack:not(:only-child) { + background-color: #061115; +} + +notebook > header.top { + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +notebook > header.bottom { + border-top: 1px solid rgba(255, 255, 255, 0.12); +} + +notebook > header.right { + border-left: 1px solid rgba(255, 255, 255, 0.12); +} + +notebook > header.left { + border-right: 1px solid rgba(255, 255, 255, 0.12); +} + +notebook > header button.flat.toggle.popup { + min-width: 32px; + border: none; + box-shadow: none; + border-radius: 6px; + padding: 0 3px; + margin-top: -2px; + margin-bottom: -2px; + margin-left: 3px; +} + +notebook > header button.flat.toggle.popup:active, notebook > header button.flat.toggle.popup:checked { + color: #dedede; + background-color: rgba(255, 255, 255, 0.15); +} + +notebook > header.top { + padding: 3px; +} + +notebook > header.top > tabs { + margin: 0; +} + +notebook > header.top > tabs > tab { + outline-offset: -4px; + min-width: 24px; + min-height: 24px; +} + +notebook > header.top > tabs > tab + tab { + margin-left: 3px; +} + +notebook > header.bottom { + padding: 3px; +} + +notebook > header.bottom > tabs { + margin: 0; +} + +notebook > header.bottom > tabs > tab { + outline-offset: -4px; + min-width: 24px; + min-height: 24px; +} + +notebook > header.bottom > tabs > tab + tab { + margin-left: 3px; +} + +notebook > header.right { + padding: 3px; +} + +notebook > header.right > tabs { + margin: 0; +} + +notebook > header.right > tabs > tab { + outline-offset: -4px; + min-width: 24px; + min-height: 24px; +} + +notebook > header.right > tabs > tab + tab { + margin-top: 3px; +} + +notebook > header.left { + padding: 3px; +} + +notebook > header.left > tabs { + margin: 0; +} + +notebook > header.left > tabs > tab { + outline-offset: -4px; + min-width: 24px; + min-height: 24px; +} + +notebook > header.left > tabs > tab + tab { + margin-top: 3px; +} + +notebook > header.top > tabs > arrow.up, notebook > header.bottom > tabs > arrow.up { + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); +} + +notebook > header.top > tabs > arrow.up:last-child, notebook > header.bottom > tabs > arrow.up:last-child { + margin-left: 2px; +} + +notebook > header.top > tabs > arrow.down, notebook > header.bottom > tabs > arrow.down { + -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); +} + +notebook > header.top > tabs > arrow.down:first-child, notebook > header.bottom > tabs > arrow.down:first-child { + margin-right: 2px; +} + +notebook > header.left > tabs > arrow.up, notebook > header.right > tabs > arrow.up { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +notebook > header.left > tabs > arrow.up:last-child, notebook > header.right > tabs > arrow.up:last-child { + margin-top: 2px; +} + +notebook > header.left > tabs > arrow.down, notebook > header.right > tabs > arrow.down { + -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); +} + +notebook > header.left > tabs > arrow.down:first-child, notebook > header.right > tabs > arrow.down:first-child { + margin-bottom: 2px; +} + +notebook > header > tabs > arrow { + color: rgba(222, 222, 222, 0.35); +} + +notebook > header > tabs > arrow:hover { + color: rgba(222, 222, 222, 0.675); +} + +notebook > header > tabs > arrow:active { + color: #dedede; +} + +notebook > header > tabs > arrow:disabled { + color: rgba(222, 222, 222, 0.05); +} + +notebook > header > tabs > tab button.flat, +notebook > header > tabs > tab button.close-button, +notebook > header > tabs > tab button.image-button.flat { + border-radius: 3px; + padding: 0; + color: #95999a; + margin-left: 3px; + margin-right: -6px; + min-height: 16px; + min-width: 16px; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 3px; + margin-right: -3px; +} + +notebook > header > tabs > tab button.flat:hover, +notebook > header > tabs > tab button.close-button:hover, +notebook > header > tabs > tab button.image-button.flat:hover { + color: #dedede; + background-color: rgba(255, 255, 255, 0.1); +} + +notebook > header > tabs > tab button.flat:active, +notebook > header > tabs > tab button.close-button:active, +notebook > header > tabs > tab button.image-button.flat:active { + color: #f8f8f8; + background-color: rgba(255, 255, 255, 0.2); +} + +tabbox { + background-color: #000a0e; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); + padding: 0 3px 3px; +} + +tabbox > tab + tab { + margin-left: 3px; +} + +tabbox > tab button.tab-close-button { + border-radius: 3px; + border: none; + padding: 0; + min-height: 16px; + min-width: 16px; + margin-top: 4px; + margin-bottom: 4px; + margin-right: -6px; +} + +tabbox > tab button.tab-close-button:hover { + color: #dedede; + background-color: rgba(255, 255, 255, 0.1); +} + +tabbox > tab button.tab-close-button:active, tabbox > tab button.tab-close-button:active:hover { + color: #f8f8f8; + background-color: rgba(255, 255, 255, 0.2); +} + +scrollbar { + background-color: transparent; + transition: 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + outline: none; +} + +scrollbar, scrollbar button { + border: none; +} + +scrollbar.vertical button.down { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +scrollbar.vertical button.up { + -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); +} + +scrollbar.horizontal button.down { + -gtk-icon-source: -gtk-icontheme("pan-right-symbolic"); +} + +scrollbar.horizontal button.up { + -gtk-icon-source: -gtk-icontheme("pan-left-symbolic"); +} + +scrollbar > range > trough { + background: none; + padding: 0; + margin: 0; + border: none; + outline: none; + transition: none; +} + +scrollbar > range > trough > slider { + min-width: 4px; + min-height: 4px; + margin: -1px; + border: 4px solid transparent; + border-radius: 12px; + background-clip: padding-box; + background-color: #61676a; + box-shadow: none; + outline: none; + transition: all 200ms linear; +} + +scrollbar > range > trough > slider:hover { + background-color: #4c5356; +} + +scrollbar > range > trough > slider:hover:active { + background-color: #767b7d; +} + +scrollbar > range > trough > slider:disabled { + background-color: transparent; +} + +scrollbar > range.fine-tune > trough > slider { + min-width: 4px; + min-height: 4px; +} + +scrollbar > range.fine-tune.horizontal > trough > slider { + border-width: 5px 4px; +} + +scrollbar > range.fine-tune.vertical > trough > slider { + border-width: 4px 5px; +} + +scrollbar.overlay-indicator { + background: none; + color: inherit; + box-shadow: none; + padding: 0; +} + +scrollbar.overlay-indicator > range > trough { + outline: none; + background: none; +} + +scrollbar.overlay-indicator > range > trough > slider { + outline: none; +} + +scrollbar.overlay-indicator:not(.dragging):not(.hovering) { + opacity: 0.4; + border-color: transparent; + background-color: transparent; + box-shadow: none; +} + +scrollbar.overlay-indicator:not(.dragging):not(.hovering) > range > trough > slider { + margin: 0; + min-width: 4px; + min-height: 4px; + background-color: #9fa3a4; + border: none; +} + +scrollbar.overlay-indicator:not(.dragging):not(.hovering).horizontal > range > trough > slider { + margin: 0 3px; + min-width: 40px; +} + +scrollbar.overlay-indicator:not(.dragging):not(.hovering).vertical > range > trough > slider { + margin: 3px 0; + min-height: 40px; +} + +scrollbar.overlay-indicator.dragging, scrollbar.overlay-indicator.hovering { + opacity: 0.99; +} + +scrollbar.horizontal > range > trough > slider { + min-width: 40px; +} + +scrollbar.vertical > range > trough > slider { + min-height: 40px; +} + +@keyframes switch_ripple_effect { + from { + background-image: linear-gradient(0deg, rgba(222, 222, 222, 0.25) 0%, rgba(222, 222, 222, 0.35) 100%), radial-gradient(circle farthest-corner at center, transparent 0%, transparent 0%); + } + to { + background-image: linear-gradient(0deg, #a5c6f2 0%, #79AAEB 100%), radial-gradient(circle farthest-corner at center, rgba(121, 170, 235, 0.75) 100%, rgba(121, 170, 235, 0) 0%); + } +} + +switch { + transition: all 150ms cubic-bezier(0, 0, 0.2, 1); + border-radius: 9999px; + background-color: transparent; + background-clip: padding-box; + color: transparent; + min-width: 40px; + min-height: 24px; + font-size: 0; + padding: 0; + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + background-image: linear-gradient(0deg, rgba(222, 222, 222, 0.25) 0%, rgba(222, 222, 222, 0.35) 100%), radial-gradient(circle farthest-corner at center, transparent 0%, transparent 0%); +} + +switch:disabled { + color: transparent; + background-color: transparent; + background-image: linear-gradient(0deg, rgba(222, 222, 222, 0.1) 0%, rgba(222, 222, 222, 0.15) 100%); +} + +switch:checked { + animation: switch_ripple_effect 0.3s cubic-bezier(0, 0, 0.2, 1); + background-color: transparent; + color: transparent; + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); + transition: background-image 0.3s, box-shadow 0; + background-image: linear-gradient(0deg, #a5c6f2 0%, #79AAEB 100%), radial-gradient(circle farthest-corner at center, rgba(121, 170, 235, 0.75) 100%, transparent 0%); +} + +switch:checked:disabled { + background-color: transparent; + background-image: linear-gradient(0deg, white 0%, #e8f0fc 100%); + color: transparent; +} + +switch > slider { + transition: all 150ms cubic-bezier(0, 0, 0.2, 1), box-shadow 150ms cubic-bezier(0, 0, 0.2, 1), margin 0; + min-width: 22px; + min-height: 22px; + margin: 1px 0 1px 1px; + padding: 0; + border-radius: 9999px; + background-color: white; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); +} + +switch, switch > slider { + outline-color: transparent; + color: transparent; + border: none; +} + +switch:hover > slider { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15), 0 2px 3px 0 rgba(0, 0, 0, 0.1); +} + +switch:checked > slider { + margin: 1px 1px 1px 0; + background-color: white; +} + +switch:checked:disabled > slider { + animation: none; +} + +.view.content-view.check:not(list), +.content-view .tile check:not(list) { + min-height: 40px; + min-width: 40px; + margin: 0; + padding: 0; +} + +checkbutton.text-button, radiobutton.text-button { + padding: 2px 0; + outline-offset: 0; +} + +checkbutton.text-button:hover, radiobutton.text-button:hover { + color: #b8b8b8; +} + +checkbutton.text-button:disabled, radiobutton.text-button:disabled { + color: rgba(222, 222, 222, 0.35); +} + +checkbutton label:not(:only-child):first-child, radiobutton label:not(:only-child):first-child { + margin-left: 4px; +} + +checkbutton label:not(:only-child):last-child, radiobutton label:not(:only-child):last-child { + margin-right: 4px; +} + +check, +radio { + min-width: 14px; + min-height: 14px; + margin: 3px; + padding: 0; + color: transparent; + background-color: #061115; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + background-clip: padding-box; + border: none; + -gtk-icon-size: 14px; + background-image: linear-gradient(0deg, #6a6a6a 0%, #545454 100%); + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 1px 2px rgba(0, 0, 0, 0.25); +} + +check:hover, +radio:hover { + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); +} + +check:active, +radio:active { + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); +} + +check:disabled, +radio:disabled { + background-image: none; + background-color: rgba(255, 255, 255, 0.08); + box-shadow: none; +} + +check:checked, check:indeterminate, +radio:checked, +radio:indeterminate { + color: white; + background-color: #79AAEB; + background-image: linear-gradient(0deg, #639ce8 0%, #8fb8ee 100%); +} + +check:checked:hover, check:indeterminate:hover, +radio:checked:hover, +radio:indeterminate:hover { + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); +} + +check:checked:active, check:indeterminate:active, +radio:checked:active, +radio:indeterminate:active { + background-color: #79AAEB; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); +} + +check:checked:disabled, check:indeterminate:disabled, +radio:checked:disabled, +radio:indeterminate:disabled { + color: rgba(175, 175, 175, 0.35); + background-image: none; + background-color: rgba(255, 255, 255, 0.08); + box-shadow: none; +} + + +check { + border-radius: 3px; +} + + +check:checked { + -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/scalable/checkbox-checked-symbolic.svg")), -gtk-recolor(url("assets/scalable/checkbox-checked-symbolic@2.svg"))); +} + + +check:indeterminate { + -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/scalable/checkbox-mixed-symbolic.svg")), -gtk-recolor(url("assets/scalable/checkbox-mixed-symbolic@2.svg"))); +} + + +radio { + border-radius: 9999px; +} + + +radio:checked { + -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/scalable/radio-checked-symbolic.svg")), -gtk-recolor(url("assets/scalable/radio-checked-symbolic@2.svg"))); +} + + +radio:indeterminate { + -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/scalable/radio-mixed-symbolic.svg")), -gtk-recolor(url("assets/scalable/radio-mixed-symbolic@2.svg"))); +} + +scale { + min-height: 15px; + min-width: 15px; + padding: 3px; +} + +scale > trough > slider { + min-height: 15px; + min-width: 15px; + margin: -7px; +} + +scale.fine-tune > trough > slider { + margin: -4px; +} + +scale.fine-tune > trough > fill, +scale.fine-tune > trough > highlight, +scale.fine-tune > trough { + border-radius: 5px; +} + +scale > trough { + outline-offset: 2px; + border-radius: 6px; + background-color: rgba(0, 0, 0, 0.2); +} + +scale > trough:disabled { + background-color: rgba(0, 0, 0, 0.12); +} + +.osd scale > trough { + background-color: rgba(0, 0, 0, 0.2); +} + +.osd scale > trough highlight { + background-color: #79AAEB; +} + +modelbutton:hover scale > trough, row:selected scale > trough, infobar scale > trough { + background-color: rgba(0, 0, 0, 0.2); +} + +modelbutton:hover scale > trough > trough > highlight, row:selected scale > trough > trough > highlight, infobar scale > trough > trough > highlight { + background-color: white; +} + +modelbutton:hover scale > trough > trough > highlight:disabled, row:selected scale > trough > trough > highlight:disabled, infobar scale > trough > trough > highlight:disabled { + background-color: #c3d9f6; +} + +modelbutton:hover scale > trough:disabled, row:selected scale > trough:disabled, infobar scale > trough:disabled { + background-color: rgba(0, 0, 0, 0.1); +} + +scale > trough > highlight { + border-radius: 6px; + background-color: #79AAEB; +} + +scale > trough > highlight:disabled { + background-color: rgba(121, 170, 235, 0.55); +} + +scale > trough > fill { + border-radius: 6px; + background-color: rgba(121, 170, 235, 0.5); +} + +scale > trough > fill:disabled { + background-color: transparent; +} + +scale > trough > slider { + background-color: white; + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 100%; + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.05); + background-clip: padding-box; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-property: background, border; + outline: none; +} + +scale > trough > slider:hover { + background-color: white; + border-color: rgba(255, 255, 255, 0.12); + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1), 0 2px 2px 0 rgba(0, 0, 0, 0.05); +} + +scale > trough > slider:active { + background-color: white; + border-color: rgba(255, 255, 255, 0.12); + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +scale > trough > slider:disabled { + background-color: #f2f2f2; + border-color: rgba(242, 242, 242, 0.12); + box-shadow: none; +} + +modelbutton:hover scale > trough > slider, row:selected scale > trough > slider, infobar scale > trough > slider { + background-color: white; + border-color: white; +} + +modelbutton:hover scale > trough > slider:hover, row:selected scale > trough > slider:hover, infobar scale > trough > slider:hover { + background-color: #ebf2fc; + border-color: #ebf2fc; +} + +modelbutton:hover scale > trough > slider:active, row:selected scale > trough > slider:active, infobar scale > trough > slider:active { + background-color: #bcd5f5; + border-color: #bcd5f5; +} + +modelbutton:hover scale > trough > slider:disabled, row:selected scale > trough > slider:disabled, infobar scale > trough > slider:disabled { + background-color: #c3d9f6; + border-color: #c3d9f6; +} + +.osd scale > trough > slider { + background-color: white; + border-color: rgba(255, 255, 255, 0.12); +} + +.osd scale > trough > slider:hover { + background-color: white; + border-color: rgba(255, 255, 255, 0.12); + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1), 0 2px 2px 0 rgba(0, 0, 0, 0.05); +} + +.osd scale > trough > slider:active { + background-color: #f7f7f7; + border-color: rgba(255, 255, 255, 0.12); + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +scale > value { + color: alpha(currentColor,0.4); +} + +scale > marks { + color: alpha(currentColor,0.4); +} + +scale > marks.top { + margin-bottom: 1px; + margin-top: -4px; +} + +scale > marks.bottom { + margin-top: 1px; + margin-bottom: -4px; +} + +scale > marks.top { + margin-right: 1px; + margin-left: -4px; +} + +scale > marks.bottom { + margin-left: 1px; + margin-right: -4px; +} + +scale.fine-tune > marks.top { + margin-bottom: 0px; + margin-top: -2px; +} + +scale.fine-tune > marks.bottom { + margin-top: 0px; + margin-bottom: -2px; +} + +scale.fine-tune > marks.top { + margin-right: 0px; + margin-left: -2px; +} + +scale.fine-tune > marks.bottom { + margin-left: 0px; + margin-right: -2px; +} + +scale.horizontal indicator { + min-height: 3px; + min-width: 1px; +} + +scale.horizontal.fine-tune indicator { + min-height: 2px; +} + +scale.vertical indicator { + min-height: 1px; + min-width: 3px; +} + +scale.vertical.fine-tune indicator { + min-width: 2px; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above.png"), url("assets/slider-horz-scale-has-marks-above@2.png")); + min-height: 26px; + min-width: 24px; + margin-top: -14px; + background-position: top; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-top: -11px; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.horizontal.marks-before:not(.marks-after) slider:hover { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-hover.png"), url("assets/slider-horz-scale-has-marks-above-hover@2.png")); + min-height: 26px; + min-width: 24px; + margin-top: -14px; + background-position: top; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-top: -11px; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.horizontal.marks-before:not(.marks-after) slider:active { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-active.png"), url("assets/slider-horz-scale-has-marks-above-active@2.png")); + min-height: 26px; + min-width: 24px; + margin-top: -14px; + background-position: top; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-top: -11px; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.horizontal.marks-before:not(.marks-after) slider:disabled { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-insensitive.png"), url("assets/slider-horz-scale-has-marks-above-insensitive@2.png")); + min-height: 26px; + min-width: 24px; + margin-top: -14px; + background-position: top; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-top: -11px; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below.png"), url("assets/slider-horz-scale-has-marks-below@2.png")); + min-height: 26px; + min-width: 24px; + margin-bottom: -14px; + background-position: bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-bottom: -11px; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.horizontal.marks-after:not(.marks-before) slider:hover { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-hover.png"), url("assets/slider-horz-scale-has-marks-below-hover@2.png")); + min-height: 26px; + min-width: 24px; + margin-bottom: -14px; + background-position: bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-bottom: -11px; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.horizontal.marks-after:not(.marks-before) slider:active { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-active.png"), url("assets/slider-horz-scale-has-marks-below-active@2.png")); + min-height: 26px; + min-width: 24px; + margin-bottom: -14px; + background-position: bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-bottom: -11px; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.horizontal.marks-after:not(.marks-before) slider:disabled { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-insensitive.png"), url("assets/slider-horz-scale-has-marks-below-insensitive@2.png")); + min-height: 26px; + min-width: 24px; + margin-bottom: -14px; + background-position: bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-bottom: -11px; +} + +scale.vertical.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.vertical.marks-before:not(.marks-after) slider { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above.png"), url("assets/slider-vert-scale-has-marks-above@2.png")); + min-height: 24px; + min-width: 26px; + margin-left: -14px; + background-position: left bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-left: -11px; +} + +scale.vertical.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.vertical.marks-before:not(.marks-after) slider:hover { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-hover.png"), url("assets/slider-vert-scale-has-marks-above-hover@2.png")); + min-height: 24px; + min-width: 26px; + margin-left: -14px; + background-position: left bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-left: -11px; +} + +scale.vertical.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.vertical.marks-before:not(.marks-after) slider:active { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-active.png"), url("assets/slider-vert-scale-has-marks-above-active@2.png")); + min-height: 24px; + min-width: 26px; + margin-left: -14px; + background-position: left bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-left: -11px; +} + +scale.vertical.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.vertical.marks-before:not(.marks-after) slider:disabled { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-insensitive.png"), url("assets/slider-vert-scale-has-marks-above-insensitive@2.png")); + min-height: 24px; + min-width: 26px; + margin-left: -14px; + background-position: left bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-left: -11px; +} + +scale.vertical.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.vertical.marks-after:not(.marks-before) slider { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below.png"), url("assets/slider-vert-scale-has-marks-below@2.png")); + min-height: 24px; + min-width: 26px; + margin-right: -14px; + background-position: right bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-right: -11px; +} + +scale.vertical.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.vertical.marks-after:not(.marks-before) slider:hover { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-hover.png"), url("assets/slider-vert-scale-has-marks-below-hover@2.png")); + min-height: 24px; + min-width: 26px; + margin-right: -14px; + background-position: right bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-right: -11px; +} + +scale.vertical.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.vertical.marks-after:not(.marks-before) slider:active { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-active.png"), url("assets/slider-vert-scale-has-marks-below-active@2.png")); + min-height: 24px; + min-width: 26px; + margin-right: -14px; + background-position: right bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-right: -11px; +} + +scale.vertical.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.vertical.marks-after:not(.marks-before) slider:disabled { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-insensitive.png"), url("assets/slider-vert-scale-has-marks-below-insensitive@2.png")); + min-height: 24px; + min-width: 26px; + margin-right: -14px; + background-position: right bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-right: -11px; +} + +progressbar { + padding: 0; + font-size: smaller; + color: rgba(222, 222, 222, 0.7); + font-feature-settings: "tnum"; +} + +progressbar.horizontal > trough { + min-width: 150px; +} + +progressbar.horizontal > trough, progressbar.horizontal > trough > progress { + min-height: 4px; + border-radius: 2px; +} + +progressbar.vertical > trough { + min-height: 80px; +} + +progressbar.vertical > trough, progressbar.vertical > trough > progress { + min-width: 4px; + border-radius: 2px; +} + +progressbar.osd { + min-width: 3px; + min-height: 3px; + background-color: transparent; +} + +progressbar.osd > trough { + border-style: none; + background-color: transparent; + box-shadow: none; +} + +progressbar.osd > progress { + border-style: none; + border-radius: 0; +} + +progressbar > trough > progress { + background-color: #79AAEB; + border: none; + border-radius: 6px; + box-shadow: none; +} + +row:selected progressbar > trough > progress, infobar progressbar > trough > progress { + background-color: white; +} + +progressbar > trough { + min-height: 4px; + min-width: 4px; + border: none; + border-radius: 6px; + background-color: #05090b; +} + +row:selected progressbar > trough, infobar progressbar > trough { + background-color: rgba(0, 0, 0, 0.2); +} + +levelbar block { + min-width: 32px; + min-height: 1px; +} + +levelbar.vertical block { + min-width: 1px; + min-height: 32px; +} + +levelbar trough { + border: none; + padding: 3px; + border-radius: 6px; + background-color: #05090b; +} + +levelbar.horizontal.discrete block { + margin: 0 1px; +} + +levelbar.vertical.discrete block { + margin: 1px 0; +} + +levelbar block:not(.empty) { + border: 1px solid #79AAEB; + background-color: #79AAEB; + border-radius: 6px; +} + +levelbar block.low { + border-color: #E9967E; + background-color: #E9967E; +} + +levelbar block.high { + border-color: #79AAEB; + background-color: #79AAEB; +} + +levelbar block.full { + border-color: #8CD7AA; + background-color: #8CD7AA; +} + +levelbar block.empty { + background-color: #061115; + border-color: #061115; +} + +window.dialog.print drawing { + color: #dedede; + background: none; + border: none; + padding: 0; +} + +window.dialog.print drawing paper { + border: 1px solid rgba(255, 255, 255, 0.12); + background: #061115; + padding: 0; +} + +window.dialog.print .dialog-action-box { + margin: 12px; +} + +frame, +.frame { + border: 1px solid rgba(255, 255, 255, 0.12); +} + +frame > list, +.frame > list { + border: none; +} + +frame { + border-radius: 12px; +} + +frame > label { + margin: 4px; +} + +frame > list { + border-radius: 10px; + box-shadow: inset 0 0 8px rgba(255, 255, 255, 0.03), inset 0 0 3px rgba(255, 255, 255, 0.02); +} + +scrolledwindow viewport.frame { + border: none; +} + +scrolledwindow viewport.frame .frame { + border: none; +} + +scrolledwindow viewport.frame .frame > textview { + border-radius: 6px; + background: none; +} + +scrolledwindow viewport.frame .frame > textview > text { + border-radius: 6px; + border: 1px solid rgba(255, 255, 255, 0.12); +} + +scrolledwindow viewport.frame > box.vertical list.content.view { + border-top-left-radius: 12px; + border-top-right-radius: 12px; +} + +scrolledwindow viewport.frame > box.vertical list.frame { + padding: 0; +} + +scrolledwindow viewport.frame > box.vertical list.frame list { + border: none; + box-shadow: none; + border-radius: 0; + margin: 0; + background: none; +} + +scrolledwindow viewport.frame > box.vertical list.frame list > row.activatable, scrolledwindow viewport.frame > box.vertical list.frame list > row.activatable:first-child, scrolledwindow viewport.frame > box.vertical list.frame list > row.activatable:last-child { + border-radius: 0; +} + +scrolledwindow > overshoot.top { + background-image: radial-gradient(farthest-side at top, alpha(currentColor,0.12) 85%, alpha(currentColor,0)), radial-gradient(farthest-side at top, alpha(currentColor,0.05), alpha(currentColor,0)); + background-size: 100% 3%, 100% 50%; + background-repeat: no-repeat; + background-position: top; + background-color: transparent; + border: none; + box-shadow: none; +} + +scrolledwindow > overshoot.bottom { + background-image: radial-gradient(farthest-side at bottom, alpha(currentColor,0.12) 85%, alpha(currentColor,0)), radial-gradient(farthest-side at bottom, alpha(currentColor,0.05), alpha(currentColor,0)); + background-size: 100% 3%, 100% 50%; + background-repeat: no-repeat; + background-position: bottom; + background-color: transparent; + border: none; + box-shadow: none; +} + +scrolledwindow > overshoot.left { + background-image: radial-gradient(farthest-side at left, alpha(currentColor,0.12) 85%, alpha(currentColor,0)), radial-gradient(farthest-side at left, alpha(currentColor,0.05), alpha(currentColor,0)); + background-size: 3% 100%, 50% 100%; + background-repeat: no-repeat; + background-position: left; + background-color: transparent; + border: none; + box-shadow: none; +} + +scrolledwindow > overshoot.right { + background-image: radial-gradient(farthest-side at right, alpha(currentColor,0.12) 85%, alpha(currentColor,0)), radial-gradient(farthest-side at right, alpha(currentColor,0.05), alpha(currentColor,0)); + background-size: 3% 100%, 50% 100%; + background-repeat: no-repeat; + background-position: right; + background-color: transparent; + border: none; + box-shadow: none; +} + +scrolledwindow > junction { + border-style: solid none none solid; + border-width: 1px; + border-color: rgba(255, 255, 255, 0.12); + background-color: #071419; +} + +scrolledwindow > junction:dir(rtl) { + border-style: solid solid none none; +} + +separator { + background-color: rgba(255, 255, 255, 0.12); + min-width: 1px; + min-height: 1px; +} + +separator.spacer { + background: none; +} + +separator.spacer.horizontal { + min-width: 12px; +} + +separator.spacer.vertical { + min-height: 12px; +} + +listview, +list { + background-color: #061115; + border-color: rgba(255, 255, 255, 0.12); + background-clip: padding-box; + color: #dedede; +} + +listview > row, +list > row { + background-clip: padding-box; +} + +listview > row.expander, +list > row.expander { + padding: 0; +} + +listview > row.expander .row-header, +list > row.expander .row-header { + padding: 3px; +} + +listview.horizontal row.separator, listview.separators.horizontal > row:not(.separator), +list.horizontal row.separator, +list.separators.horizontal > row:not(.separator) { + border-left: 1px solid rgba(255, 255, 255, 0.12); +} + +listview:not(.horizontal) row.separator, listview.separators:not(.horizontal) > row:not(.separator), +list:not(.horizontal) row.separator, +list.separators:not(.horizontal) > row:not(.separator) { + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +listview.boxed-list > row.expander list, +list.boxed-list > row.expander list { + background-color: transparent; + box-shadow: none; + border: none; +} + +listview.view { + color: #dedede; + background-color: transparent; +} + +row.has-open-popup.activatable, row.activatable:hover { + background-color: rgba(255, 255, 255, 0.05); +} + +row.activatable:active { + color: #dedede; + background-color: rgba(255, 255, 255, 0.2); + transition-duration: 200ms; +} + +row.activatable:disabled { + color: rgba(222, 222, 222, 0.35); +} + +row.activatable:disabled image { + color: inherit; +} + +row.activatable:selected { + color: #dedede; + background-color: rgba(255, 255, 255, 0.15); +} + +row.activatable:selected label { + color: #dedede; +} + +row.activatable:selected.has-open-popup, row.activatable:selected:hover { + background-color: rgba(255, 255, 255, 0.2); +} + +row { + background-clip: padding-box; +} + +row label.subtitle { + font-size: smaller; +} + +row > box.header { + margin-left: 12px; + margin-right: 12px; + min-height: 44px; +} + +row > box.header > .icon:disabled { + filter: opacity(0.45); +} + +row > box.header > box.title { + margin-top: 6px; + margin-bottom: 6px; + border-spacing: 3px; +} + +row:not(:hover) { + transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +row:selected { + color: #dedede; + background-color: rgba(255, 255, 255, 0.15); +} + +row:selected label { + color: #dedede; +} + +row.combo image.dropdown-arrow:disabled { + filter: opacity(0.45); +} + +row.combo listview.inline { + background: none; + border: none; + box-shadow: none; + color: inherit; +} + +row.combo listview.inline, row.combo listview.inline:disabled { + background: none; + color: inherit; +} + +row.combo popover > contents { + min-width: 120px; +} + +columnview > listview > row { + padding: 0; +} + +columnview > listview > row > cell { + padding: 8px 6px; +} + +columnview > listview > row > cell:not(:first-child) { + border-left: 1px solid transparent; +} + +columnview.column-separators > listview > row > cell { + border-left-color: rgba(255, 255, 255, 0.12); +} + +columnview.data-table > listview > row > cell { + padding-top: 2px; + padding-bottom: 2px; +} + +treeexpander { + border-spacing: 6px; +} + +columnview row:not(:selected) cell editablelabel:not(.editing):focus-within { + outline: 2px solid rgba(255, 255, 255, 0.12); +} + +columnview row:not(:selected) cell editablelabel.editing:focus-within { + outline: 2px solid #79AAEB; +} + +columnview row:not(:selected) cell editablelabel.editing text selection { + color: white; + background-color: #79AAEB; +} + +.rich-list { + /* rich lists usually containing other widgets than just labels/text */ +} + +.rich-list > row { + padding: 8px 12px; + min-height: 32px; + /* should be tall even when only containing a label */ +} + +.rich-list > row > box { + border-spacing: 12px; +} + +.app-notification { + padding: 6px; + margin: 6px 16px 16px 16px; + color: #dedede; + background-color: rgba(0, 10, 14, 0.85); + border-radius: 12px; + border: none; + box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.25), inset 0 0 0 1px rgba(255, 255, 255, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.75); +} + +.app-notification border { + border: none; +} + +.app-notification button { + min-height: 22px; + padding: 2px 8px; +} + +.app-notification button:hover { + color: #c5c5c5; + background-color: rgba(255, 255, 255, 0.15); + background-image: none; + box-shadow: none; +} + +.app-notification button:active, .app-notification button:checked { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.25); +} + +.app-notification button:disabled { + background-color: transparent; +} + +.app-notification button:disabled label, .app-notification button:disabled { + color: rgba(222, 222, 222, 0.35); +} + +expander { + min-width: 16px; + min-height: 16px; + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); +} + +expander:dir(rtl) { + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); +} + +expander:hover { + color: white; +} + +expander:checked { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +expander:disabled { + filter: opacity(0.45); +} + +expander-widget > box > title { + border-radius: 6px; +} + +expander-widget > box > title > expander { + opacity: .7; +} + +expander-widget > box > title:hover > expander { + opacity: 1; +} + +.navigation-sidebar:not(decoration):not(window):drop(active):focus, .navigation-sidebar:not(decoration):not(window):drop(active), +placessidebar:not(decoration):not(window):drop(active):focus, +placessidebar:not(decoration):not(window):drop(active), +stackswitcher:not(decoration):not(window):drop(active):focus, +stackswitcher:not(decoration):not(window):drop(active), +expander-widget:not(decoration):not(window):drop(active):focus, +expander-widget:not(decoration):not(window):drop(active) { + box-shadow: none; +} + + +calendar { + color: #dedede; + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 6px; + padding: 2px 6px; + margin: 0; +} + + +calendar > header { + color: #dedede; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + + +calendar > header > button { + border: none; + box-shadow: none; + background: none; + border-radius: 0; +} + + +calendar > header > button:hover { + background-color: rgba(222, 222, 222, 0.1); +} + + +calendar > header > button:active { + background-color: #79AAEB; +} + + +calendar > header > button:backdrop { + background: none; +} + + +calendar > grid > label.today { + background-color: rgba(222, 222, 222, 0.15); + border-radius: 3px; +} + + +calendar > grid > label.today:selected { + box-shadow: none; +} + + +calendar > grid > label:focus { + outline-style: none; +} + + +calendar > grid > label.day-number { + padding: 4px; +} + + +calendar > grid > label.day-number:selected { + border-radius: 6px; +} + + +calendar > grid > label.day-number.other-month { + color: alpha(currentColor,0.3); +} + +window.dialog.message.background { + background-color: #0d181c; +} + +window.dialog.message .titlebar { + min-height: 28px; + background-color: #0d181c; + border: none; +} + +window.dialog.message box.dialog-vbox.vertical { + border-spacing: 10px; +} + +window.dialog.message label.title { + font-weight: 800; + font-size: 15pt; +} + +window.dialog.message .dialog-action-area { + padding: 6px; +} + +window.dialog.message .dialog-action-area > button { + min-height: 20px; + padding: 4px 8px; + box-shadow: none; + border-radius: 6px; + margin: 0 3px 3px 3px; + border: none; +} + +window.dialog.message .dialog-action-area > button:not(.suggested-action):not(.destructive-action) { + border-radius: 6px; + background-color: transparent; +} + +window.dialog.message .dialog-action-area > button:not(.suggested-action):not(.destructive-action):hover { + color: #c5c5c5; + background-color: rgba(255, 255, 255, 0.15); + background-image: none; + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +window.dialog.message .dialog-action-area > button:not(.suggested-action):not(.destructive-action):active { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); +} + +window.dialog.message .dialog-action-area > button.suggested-action, window.dialog.message .dialog-action-area > button.destructive-action { + border-radius: 6px; +} + +window.dialog.message.csd.background { + border-bottom-left-radius: 12px; + border-bottom-right-radius: 12px; + border: none; +} + +window.dialog.message.csd.background, window.dialog.message.csd .titlebar { + background-color: #0d181c; +} + +window.aboutdialog image.large-icons { + -gtk-icon-size: 128px; +} + +filechooser paned.horizontal > separator { + background-image: image(#000304); +} + +filechooser #pathbarbox { + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +filechooserbutton > button > box { + border-spacing: 6px; +} + +filechooserbutton:drop(active) { + box-shadow: none; + border-color: transparent; +} + +.sidebar:dir(ltr), .sidebar.left, .sidebar.left:dir(rtl) { + border-right: 1px solid #000304; + border-left-style: none; +} + +.sidebar:dir(rtl), .sidebar.right { + border-left: 1px solid #000304; + border-right-style: none; +} + +.sidebar { + border-style: none; + background-color: #0d181c; +} + +.sidebar list { + background-color: transparent; +} + +.sidebar list > separator { + min-height: 0; + background: none; + border: none; +} + +paned .sidebar.left, paned .sidebar.right, paned .sidebar.left:dir(rtl), paned .sidebar:dir(rtl), paned .sidebar:dir(ltr), paned .sidebar { + border: none; +} + +separator.sidebar { + background-color: #000304; + min-height: 1px; + min-width: 1px; +} + +separator.sidebar.left, separator.sidebar.right, separator.sidebar.left:dir(rtl), separator.sidebar:dir(rtl), separator.sidebar:dir(ltr), separator.sidebar { + border: none; +} + +stacksidebar list.separators:not(.horizontal) > row:not(.separator) { + border-bottom: none; +} + +stacksidebar row { + padding: 4px; +} + +stacksidebar row > label { + padding-left: 6px; + padding-right: 6px; +} + +stacksidebar row.needs-attention > label { + background-size: 6px 6px, 0 0; +} + +.navigation-sidebar { + padding: 6px 0; +} + +.navigation-sidebar > separator { + margin: 6px 0; +} + +.navigation-sidebar > row { + min-height: 36px; + padding: 0 8px; + border-radius: 6px; + margin: 0 6px 2px; +} + +.navigation-sidebar > row:hover, .navigation-sidebar > row:focus-visible:focus-within { + background-color: rgba(222, 222, 222, 0.1); +} + +.navigation-sidebar > row:active { + color: #dedede; + background-color: rgba(222, 222, 222, 0.2); +} + +.navigation-sidebar > row:selected { + color: #dedede; + background-color: rgba(222, 222, 222, 0.15); +} + +.navigation-sidebar > row:selected label { + color: #dedede; +} + +.navigation-sidebar > row:selected:hover { + background-color: rgba(222, 222, 222, 0.2); +} + +.navigation-sidebar > row:selected:focus-visible:focus-within { + outline-width: 0; + color: white; + background-color: #79AAEB; +} + +.navigation-sidebar > row:selected:focus-visible:focus-within:hover { + background-color: #4d8ee4; +} + +.navigation-sidebar > row:disabled { + color: rgba(222, 222, 222, 0.35); +} + +placessidebar > viewport.frame { + border-style: none; +} + +placessidebar .navigation-sidebar > row { + min-height: 24px; + padding: 2px 10px; +} + +placessidebar .navigation-sidebar > row > revealer { + padding: 0 10px; +} + +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(ltr) { + padding-right: 6px; +} + +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(rtl) { + padding-left: 6px; +} + +placessidebar .navigation-sidebar > row label.sidebar-label:dir(ltr) { + padding-right: 6px; +} + +placessidebar .navigation-sidebar > row label.sidebar-label:dir(rtl) { + padding-left: 6px; +} + +placessidebar .navigation-sidebar > row button.sidebar-button { + min-width: 22px; + min-height: 22px; + margin-top: 2px; + margin-bottom: 2px; + padding: 0; + border-radius: 9999px; +} + +placessidebar .navigation-sidebar > row button.sidebar-button > image { + opacity: 0.85; +} + +placessidebar .navigation-sidebar > row button.sidebar-button:active, placessidebar .navigation-sidebar > row button.sidebar-button:checked { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.25); + border-color: rgba(0, 0, 0, 0.15); +} + +placessidebar .navigation-sidebar > row button.sidebar-button:not(:hover):not(:active) > image { + opacity: 0.65; +} + +placessidebar .navigation-sidebar > row:selected button.sidebar-button { + color: #dedede; + border-color: rgba(0, 0, 0, 0.15); + background-color: #1C252C; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px rgba(255, 255, 255, 0.02), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +placessidebar .navigation-sidebar > row:selected button.sidebar-button:active, placessidebar .navigation-sidebar > row:selected button.sidebar-button:checked { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.25); + border-color: rgba(0, 0, 0, 0.15); +} + +placessidebar .navigation-sidebar > row.sidebar-placeholder-row { + padding: 0 8px; + min-height: 2px; + background-image: linear-gradient(to bottom, #E9967E, #E9967E); + background-clip: content-box; +} + +placessidebar .navigation-sidebar > row.sidebar-new-bookmark-row { + color: #79AAEB; +} + +placessidebar .navigation-sidebar > row:drop(active):not(:disabled) { + box-shadow: inset 0 1px #E9967E, inset 0 -1px #E9967E; +} + +placessidebar .navigation-sidebar > row:drop(active):not(:disabled), placessidebar .navigation-sidebar > row:drop(active):not(:disabled) label, placessidebar .navigation-sidebar > row:drop(active):not(:disabled) image { + color: #E9967E; +} + +placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected { + background-color: #E9967E; +} + +placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected, placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected label, placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected image { + color: #dadada; +} + +placesview .server-list-button > image { + -gtk-icon-transform: rotate(0turn); +} + +placesview .server-list-button:checked > image { + transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + -gtk-icon-transform: rotate(-0.5turn); +} + +placesview > actionbar > revealer > box > label { + padding-left: 8px; + padding-right: 8px; +} + +paned > separator { + min-width: 1px; + min-height: 1px; + background: none; + background-size: 1px 1px; +} + +paned > separator.wide { + min-width: 5px; + min-height: 5px; +} + +paned.horizontal > separator:dir(ltr) { + margin: 0 -8px 0 0; + padding: 0 8px 0 0; + box-shadow: inset 1px 0 rgba(255, 255, 255, 0.12); +} + +paned.horizontal > separator:dir(rtl) { + margin: 0 0 0 -8px; + padding: 0 0 0 8px; + box-shadow: inset -1px 0 rgba(255, 255, 255, 0.12); +} + +paned.horizontal > separator.wide { + margin: 0; + padding: 0; + box-shadow: inset 1px 0 rgba(255, 255, 255, 0.12), inset -1px 0 rgba(255, 255, 255, 0.12); +} + +paned.vertical > separator { + margin: 0 0 -8px 0; + padding: 0 0 8px 0; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12); +} + +paned.vertical > separator.wide { + margin: 0; + padding: 0; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12), inset 0 -1px rgba(255, 255, 255, 0.12); +} + +video { + background: black; +} + +video image.osd { + min-width: 64px; + min-height: 64px; + border-radius: 32px; +} + +infobar { + border-style: none; +} + +infobar.info > revealer > box, infobar.info:backdrop > revealer > box { + background-color: #79AAEB; +} + +infobar.info > revealer > box selection, infobar.info:backdrop > revealer > box selection { + color: #79AAEB; +} + +infobar.question > revealer > box, infobar.question:backdrop > revealer > box { + background-color: #79AAEB; +} + +infobar.question > revealer > box selection, infobar.question:backdrop > revealer > box selection { + color: #79AAEB; +} + +infobar.warning > revealer > box, infobar.warning:backdrop > revealer > box { + background-color: #E9967E; +} + +infobar.warning > revealer > box selection, infobar.warning:backdrop > revealer > box selection { + color: #E9967E; +} + +infobar.error > revealer > box, infobar.error:backdrop > revealer > box { + background-color: #F16269; +} + +infobar.error > revealer > box selection, infobar.error:backdrop > revealer > box selection { + color: #F16269; +} + +infobar.info > revealer > box, infobar.info:hover > revealer > box, infobar.info:backdrop > revealer > box, infobar.question > revealer > box, infobar.question:hover > revealer > box, infobar.question:backdrop > revealer > box, infobar.warning > revealer > box, infobar.warning:hover > revealer > box, infobar.warning:backdrop > revealer > box, infobar.error > revealer > box, infobar.error:hover > revealer > box, infobar.error:backdrop > revealer > box { + color: white; + caret-color: currentColor; +} + +infobar.info > revealer > box button, infobar.info:hover > revealer > box button, infobar.info:backdrop > revealer > box button, infobar.question > revealer > box button, infobar.question:hover > revealer > box button, infobar.question:backdrop > revealer > box button, infobar.warning > revealer > box button, infobar.warning:hover > revealer > box button, infobar.warning:backdrop > revealer > box button, infobar.error > revealer > box button, infobar.error:hover > revealer > box button, infobar.error:backdrop > revealer > box button { + min-height: 28px; +} + +infobar.info > revealer > box selection, infobar.info:hover > revealer > box selection, infobar.info:backdrop > revealer > box selection, infobar.question > revealer > box selection, infobar.question:hover > revealer > box selection, infobar.question:backdrop > revealer > box selection, infobar.warning > revealer > box selection, infobar.warning:hover > revealer > box selection, infobar.warning:backdrop > revealer > box selection, infobar.error > revealer > box selection, infobar.error:hover > revealer > box selection, infobar.error:backdrop > revealer > box selection { + background-color: white; +} + +infobar .close, +searchbar .close { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + min-width: 16px; + min-height: 16px; + padding: 4px; + border-radius: 1000px; +} + +infobar .close:hover, +searchbar .close:hover { + color: #c5c5c5; + background-color: rgba(255, 255, 255, 0.15); + background-image: none; + box-shadow: none; +} + +tooltip { + border-radius: 6px; + box-shadow: none; +} + +tooltip.background { + background-color: #343434; + background-clip: padding-box; + border-radius: 6px; + color: #d3d7df; +} + +tooltip.background label { + padding: 6px; +} + +tooltip > box { + border-spacing: 6px; +} + +colorswatch, colorswatch:drop(active) { + border-style: none; +} + +colorswatch.top { + border-top-left-radius: 2.5px; + border-top-right-radius: 2.5px; +} + +colorswatch.top overlay { + border-top-left-radius: 2px; + border-top-right-radius: 2px; +} + +colorswatch.bottom { + border-bottom-left-radius: 2.5px; + border-bottom-right-radius: 2.5px; +} + +colorswatch.bottom overlay { + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; +} + +colorswatch.left, colorswatch:first-child:not(.top) { + border-top-left-radius: 2.5px; + border-bottom-left-radius: 2.5px; +} + +colorswatch.left overlay, colorswatch:first-child:not(.top) overlay { + border-top-left-radius: 2px; + border-bottom-left-radius: 2px; +} + +colorswatch.right, colorswatch:last-child:not(.bottom) { + border-top-right-radius: 2.5px; + border-bottom-right-radius: 2.5px; +} + +colorswatch.right overlay, colorswatch:last-child:not(.bottom) overlay { + border-top-right-radius: 2px; + border-bottom-right-radius: 2px; +} + +colorswatch.dark overlay { + color: rgba(255, 255, 255, 0.7); +} + +colorswatch.dark overlay:hover { + border-color: rgba(255, 255, 255, 0.12); +} + +colorswatch.light overlay { + color: rgba(0, 0, 0, 0.7); +} + +colorswatch.light overlay:hover { + border-color: rgba(255, 255, 255, 0.12); +} + +colorswatch overlay { + border: 1px solid rgba(255, 255, 255, 0.12); +} + +colorswatch overlay:hover { + background-color: rgba(255, 255, 255, 0.2); +} + +colorswatch:disabled { + opacity: 0.5; +} + +colorswatch:disabled overlay { + border-color: rgba(0, 0, 0, 0.6); + box-shadow: none; +} + +colorswatch#add-color-button { + border-style: solid; + border-width: 1px; + color: #dedede; + border-color: rgba(0, 0, 0, 0.15); + background-color: #1C252C; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px rgba(255, 255, 255, 0.02), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +colorswatch#add-color-button:hover { + color: #f8f8f8; + border-color: rgba(0, 0, 0, 0.15); + background-color: #222d35; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +colorswatch#add-color-button overlay { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; +} + +button.color { + padding: 0; +} + +button.color > colorswatch:only-child { + border-radius: 3px; +} + +button.color > colorswatch:only-child > overlay { + border-radius: 2px; +} + +button.color > colorswatch:only-child:disabled { + filter: none; +} + +button.color > colorswatch:only-child.light > overlay { + border-color: rgba(255, 255, 255, 0.12); +} + +button.color colorswatch:first-child:last-child { + margin: 3px; +} + +button.color colorswatch:first-child:last-child, button.color colorswatch:first-child:last-child > overlay { + border-radius: 3px; +} + +colorchooser .popover.osd { + border-radius: 6px; +} + +.content-view { + background-color: #061115; +} + +.content-view:hover { + -gtk-icon-filter: brightness(1.2); +} + +.content-view .tile { + margin: 2px; + background-color: black; + border-radius: 0; + padding: 0; +} + +.content-view .tile:active, .content-view .tile:selected { + background-color: #79AAEB; +} + +.content-view .tile:disabled { + background-color: #0a1519; +} + +.osd .scale-popup button.flat { + border-style: none; + border-radius: 6px; +} + +.scale-popup button { + border: none; +} + +.context-menu { + font: initial; +} + +.monospace { + font-family: Monospace; +} + +.keycap { + min-width: 16px; + min-height: 20px; + padding: 3px 6px; + color: #dedede; + background-color: #061115; + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 6px; + box-shadow: inset 0px -2px 0px rgba(0, 0, 0, 0.15); +} + +stackswitcher button.text-button { + min-width: 80px; +} + +*:drop(active):focus, +*:drop(active) { + box-shadow: inset 0 0 0 1px #E9967E; +} + +window { + border-width: 0; + outline-color: rgba(255, 255, 255, 0.1); + outline-offset: -1px; + outline-style: solid; + outline-width: 1px; +} + +window.csd { + transition: box-shadow 150ms cubic-bezier(0, 0, 0.2, 1); + border-radius: 12px; + box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.35), 0 8px 8px 0 rgba(0, 0, 0, 0.35), 0 16px 16px 0 rgba(0, 0, 0, 0.35), 0 0 0 2px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.75); + margin: 0; +} + +window.csd:backdrop { + box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.35), 0 8px 8px 0 transparent, 0 16px 16px 0 transparent, 0 0 0 2px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.75); +} + +window.csd.popup { + border-radius: 10px; + box-shadow: 0 5px 8px rgba(0, 0, 0, 0.15), 0 8px 15px rgba(0, 0, 0, 0.08), 0 0 0 2px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.75); +} + +window.csd.dialog.message { + border-radius: 12px; +} + +.solid-csd window.csd { + border: 1px solid #000304; + border-radius: 0; + margin: 0; + background-color: #000a0e; + box-shadow: none; +} + +window.maximized, window.fullscreen, window:backdrop { + outline-width: 0; +} + +window.popup { + box-shadow: none; +} + +window.ssd { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35); +} + +windowcontrols { + border-spacing: 6px; +} + +windowcontrols:not(.empty).start:dir(ltr), windowcontrols:not(.empty).end:dir(rtl) { + margin-right: 8px; +} + +windowcontrols:not(.empty).start:dir(rtl), windowcontrols:not(.empty).end:dir(ltr) { + margin-left: 8px; +} + +windowcontrols button { + margin: 0; + padding: 0; +} + +windowcontrols button.close, windowcontrols button.maximize, windowcontrols button.minimize { + min-width: 16px; + min-height: 16px; + margin: 0; + padding: 0; + background-position: center; + background-repeat: no-repeat; + background-size: 16px 16px; +} + +windowcontrols button.close, windowcontrols button.close:hover, windowcontrols button.close:focus, windowcontrols button.close:active, windowcontrols button.close:backdrop, windowcontrols button.maximize, windowcontrols button.maximize:hover, windowcontrols button.maximize:focus, windowcontrols button.maximize:active, windowcontrols button.maximize:backdrop, windowcontrols button.minimize, windowcontrols button.minimize:hover, windowcontrols button.minimize:focus, windowcontrols button.minimize:active, windowcontrols button.minimize:backdrop { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: transparent; +} + +windowcontrols button.close:backdrop, windowcontrols button.maximize:backdrop, windowcontrols button.minimize:backdrop { + opacity: 1; +} + +windowcontrols button.close { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-dark.png"), url("windows-assets/titlebutton-close-dark@2.png")); +} + +windowcontrols button.close:backdrop { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-backdrop-dark.png"), url("windows-assets/titlebutton-close-backdrop-dark@2.png")); +} + +windowcontrols button.close:backdrop:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-backdrop-hover-dark.png"), url("windows-assets/titlebutton-close-backdrop-hover-dark@2.png")); +} + +windowcontrols button.close:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-hover-dark.png"), url("windows-assets/titlebutton-close-hover-dark@2.png")); +} + +windowcontrols button.close:active { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-active-dark.png"), url("windows-assets/titlebutton-close-active-dark@2.png")); +} + +windowcontrols button.maximize { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-dark.png"), url("windows-assets/titlebutton-maximize-dark@2.png")); +} + +windowcontrols button.maximize:backdrop { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-backdrop-dark.png"), url("windows-assets/titlebutton-maximize-backdrop-dark@2.png")); +} + +windowcontrols button.maximize:backdrop:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-backdrop-hover-dark.png"), url("windows-assets/titlebutton-maximize-backdrop-hover-dark@2.png")); +} + +windowcontrols button.maximize:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-hover-dark.png"), url("windows-assets/titlebutton-maximize-hover-dark@2.png")); +} + +windowcontrols button.maximize:active { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-active-dark.png"), url("windows-assets/titlebutton-maximize-active-dark@2.png")); +} + +windowcontrols button.minimize { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-dark.png"), url("windows-assets/titlebutton-minimize-dark@2.png")); +} + +windowcontrols button.minimize:backdrop { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-backdrop-dark.png"), url("windows-assets/titlebutton-minimize-backdrop-dark@2.png")); +} + +windowcontrols button.minimize:backdrop:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-backdrop-hover-dark.png"), url("windows-assets/titlebutton-minimize-backdrop-hover-dark@2.png")); +} + +windowcontrols button.minimize:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-hover-dark.png"), url("windows-assets/titlebutton-minimize-hover-dark@2.png")); +} + +windowcontrols button.minimize:active { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-active-dark.png"), url("windows-assets/titlebutton-minimize-active-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize, .maximized windowcontrols button.maximize { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-dark.png"), url("windows-assets/titlebutton-restore-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize:backdrop, .maximized windowcontrols button.maximize:backdrop { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-backdrop-dark.png"), url("windows-assets/titlebutton-restore-backdrop-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize:backdrop:hover, .maximized windowcontrols button.maximize:backdrop:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-backdrop-hover-dark.png"), url("windows-assets/titlebutton-restore-backdrop-hover-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize:hover, .maximized windowcontrols button.maximize:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-hover-dark.png"), url("windows-assets/titlebutton-restore-hover-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize:active, .maximized windowcontrols button.maximize:active { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-active-dark.png"), url("windows-assets/titlebutton-restore-active-dark@2.png")); +} + +popover.emoji-picker { + padding: 0; + border-radius: 12px; +} + +popover.emoji-picker > contents { + padding: 0; +} + +.emoji-searchbar { + padding: 6px; + border-spacing: 6px; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +.emoji-toolbar { + padding: 2px; + border-spacing: 2px; + border-top: 1px solid rgba(255, 255, 255, 0.12); +} + +button.emoji-section { + margin: 3px 1px; + padding: 1px 12px; + border-radius: 6px; + border: none; + outline-offset: -2px; + box-shadow: none; + transition: none; + animation: none; +} + +button.emoji-section:first-child { + margin-left: 6px; +} + +button.emoji-section:last-child { + margin-right: 6px; +} + +popover.emoji-picker emoji { + font-size: x-large; + padding: 6px; + border-radius: 6px; +} + +emoji-completion-row > box { + border-spacing: 6px; + padding: 3px 10px; +} + +emoji-completion-row:focus, +emoji-completion-row:hover { + background-color: #79AAEB; + color: white; +} + +emoji-completion-row emoji:focus, +emoji-completion-row emoji:hover { + background-color: rgba(255, 255, 255, 0.12); +} + +popover.entry-completion > contents { + padding: 0; +} + +statusbar { + padding: 6px 12px; +} + +window.background.csd stack stack stack frame, +window.background.csd > stack > stack > box > frame, +window.background.csd > stack > stack > box > box > frame, +window.background.csd > stack > box > stack > box > frame, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame, +window.background.csd > stack > box > stack > box > scrolledwindow > viewport > frame, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame { + border: none; +} + +window.background.csd stack stack stack frame > border, +window.background.csd > stack > stack > box > frame > border, +window.background.csd > stack > stack > box > box > frame > border, +window.background.csd > stack > box > stack > box > frame > border, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame > border, +window.background.csd > stack > box > stack > box > scrolledwindow > viewport > frame > border, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame > border { + border: none; +} + +window.background.csd > stack > box > box > list, +window.background.csd > stack > box > stack > scrolledwindow > viewport > list { + border-bottom-left-radius: 12px; +} + +window.background.csd.maximized > stack > box > box > list, +window.background.csd.maximized > stack > box > stack > scrolledwindow > viewport > list, window.background.csd.tiled > stack > box > box > list, +window.background.csd.tiled > stack > box > stack > scrolledwindow > viewport > list, window.background.csd.fullscreen > stack > box > box > list, +window.background.csd.fullscreen > stack > box > stack > scrolledwindow > viewport > list { + border-bottom-left-radius: 12px; +} + +window.nightthemeswitcher headerbar { + background: #000a0e; + color: #FDFDFD; +} + +window.background.csd > contents > leaflet.unfolded > box > scrolledwindow > viewport > widget > stack > list.navigation-sidebar { + background-color: #162026; +} + +window.background.csd > contents > leaflet.unfolded > box > scrolledwindow > viewport > widget > stack > list.navigation-sidebar > separator { + background-color: transparent; + margin: 0; + min-height: 0; +} + +window.background.csd > contents > leaflet.unfolded > box > scrolledwindow > viewport > widget > stack > box > list.navigation-sidebar { + background-color: #162026; +} + +window.background.csd > contents > leaflet.unfolded > box > stack.background { + background-color: #061115; +} + +avatar { + border-radius: 9999px; + font-weight: bold; +} + +avatar.color1 { + background-image: linear-gradient(#83b6ec, #337fdc); + color: #cfe1f5; +} + +avatar.color2 { + background-image: linear-gradient(#7ad9f1, #0f9ac8); + color: #caeaf2; +} + +avatar.color3 { + background-image: linear-gradient(#8de6b1, #29ae74); + color: #cef8d8; +} + +avatar.color4 { + background-image: linear-gradient(#b5e98a, #6ab85b); + color: #e6f9d7; +} + +avatar.color5 { + background-image: linear-gradient(#f8e359, #d29d09); + color: #f9f4e1; +} + +avatar.color6 { + background-image: linear-gradient(#ffcb62, #d68400); + color: #ffead1; +} + +avatar.color7 { + background-image: linear-gradient(#ffa95a, #ed5b00); + color: #ffe5c5; +} + +avatar.color8 { + background-image: linear-gradient(#f78773, #e62d42); + color: #f8d2ce; +} + +avatar.color9 { + background-image: linear-gradient(#e973ab, #e33b6a); + color: #fac7de; +} + +avatar.color10 { + background-image: linear-gradient(#cb78d4, #9945b5); + color: #e7c2e8; +} + +avatar.color11 { + background-image: linear-gradient(#9e91e8, #7a59ca); + color: #d5d2f5; +} + +avatar.color12 { + background-image: linear-gradient(#e3cf9c, #b08952); + color: #f2eade; +} + +avatar.color13 { + background-image: linear-gradient(#be916d, #785336); + color: #e5d6ca; +} + +avatar.color14 { + background-image: linear-gradient(#c0bfbc, #6e6d71); + color: #d8d7d3; +} + +avatar.contrasted { + color: white; +} + +avatar.image { + background: none; +} + +preferencespage > scrolledwindow > viewport > clamp > box { + margin: 24px 12px; + border-spacing: 24px; +} + +preferencesgroup > box, preferencesgroup > box .labels { + border-spacing: 6px; +} + +preferencesgroup > box > box.header:not(.single-line) { + margin-bottom: 6px; +} + +preferencesgroup > box > box.single-line { + min-height: 34px; +} + +preferencesgroup > box button.background-preview-button, preferencesgroup > box button.background-preview-button:hover, preferencesgroup > box button.background-preview-button:active, preferencesgroup > box button.background-preview-button:checked { + background: none; + border: none; + box-shadow: none; + padding: 3px; + border: 2px solid transparent; + border-radius: 9px; +} + +preferencesgroup > box button.background-preview-button:checked { + border: 2px solid #79AAEB; +} + +statuspage > scrolledwindow > viewport > box { + margin: 36px 12px; + border-spacing: 36px; +} + +statuspage > scrolledwindow > viewport > box > clamp > box { + border-spacing: 12px; +} + +statuspage > scrolledwindow > viewport > box > clamp > box > .icon { + -gtk-icon-size: 128px; + color: alpha(currentColor,0.55); +} + +statuspage > scrolledwindow > viewport > box > clamp > box > .icon:disabled { + opacity: 0.45; +} + +statuspage > scrolledwindow > viewport > box > clamp > box > .icon:not(:last-child) { + margin-bottom: 24px; +} + +statuspage.compact > scrolledwindow > viewport > box { + margin: 24px 12px; + border-spacing: 24px; +} + +statuspage.compact > scrolledwindow > viewport > box > clamp > box > .icon { + -gtk-icon-size: 96px; +} + +statuspage.compact > scrolledwindow > viewport > box > clamp > box > .icon:not(:last-child) { + margin-bottom: 12px; +} + +statuspage.compact > scrolledwindow > viewport > box > clamp > box > .title { + font-size: 18pt; +} + +.osd .card, .card.osd { + background-color: alpha(currentColor,0.1); + color: inherit; + box-shadow: none; +} + +.osd .card:focus:focus-visible, .card.osd:focus:focus-visible { + outline-color: rgba(255, 255, 255, 0.05); +} + +.card.activatable { + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +.card.activatable:hover { + background-image: image(alpha(currentColor,0.03)); +} + +.card.activatable:active { + background-image: image(alpha(currentColor,0.08)); +} + +toast { + margin: 12px; + margin-bottom: 18px; + border-radius: 10px; + border-spacing: 6px; + padding: 6px; + box-shadow: 0 3px 8px rgba(0, 0, 0, 0.35); +} + +toast:dir(ltr) { + padding-left: 12px; +} + +toast:dir(rtl) { + padding-right: 12px; +} + +toast > widget { + margin: 0 6px; +} + +viewswitcher { + margin: 0; +} + +viewswitcher.wide { + border-spacing: 3px; +} + +viewswitcher.wide button.toggle { + margin: 8px 0; +} + +viewswitcher.narrow button.toggle { + border-radius: 0; + margin: 0; + min-height: 0; +} + +viewswitcher button.toggle { + font-weight: normal; + padding: 0; +} + +viewswitcher button.toggle > stack > box.narrow { + font-size: 0.75rem; + padding-top: 7px; + padding-bottom: 5px; + border-spacing: 4px; +} + +viewswitcher button.toggle > stack > box.narrow > stack > label { + padding-left: 8px; + padding-right: 8px; +} + +viewswitcher button.toggle > stack > box.wide { + padding: 0 12px; + border-spacing: 6px; +} + +viewswitcherbar actionbar > revealer > box { + padding: 0; +} + +viewswitchertitle viewswitcher { + margin-left: 12px; + margin-right: 12px; +} + +indicatorbin > indicator, indicatorbin > mask { + min-width: 12px; + min-height: 12px; + border-radius: 9999px; + margin: 0; +} + +indicatorbin > indicator { + margin: 1px; + background: alpha(currentColor,0.4); +} + +indicatorbin > indicator > label { + font-size: 0.6rem; + font-weight: normal; + padding: 1px 4px; + color: white; +} + +indicatorbin > mask { + padding: 0; + background: black; +} + +indicatorbin.needs-attention > indicator { + background: #79AAEB; +} + +indicatorbin.needs-attention > indicator > label { + color: white; +} + +tabbar .box { + min-height: 28px; +} + +tabbar tabbox > separator.hidden { + opacity: 0; +} + +tabbar tabbox > revealer > indicator { + min-width: 2px; + border-radius: 2px; + background: alpha(#79AAEB,0.5); +} + +tabbar .start-action, +tabbar .end-action { + padding: 6px; +} + +tabbar .start-action:dir(ltr), +tabbar .end-action:dir(rtl) { + padding-right: 0; +} + +tabbar .start-action:dir(rtl), +tabbar .end-action:dir(ltr) { + padding-left: 0; +} + +tabbar:not(.inline) .box { + background-color: #0d181c; + color: #dadada; + margin-top: -1px; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); + padding: 0 3px 3px; +} + +tabbar:not(.inline):backdrop .box > scrolledwindow, +tabbar:not(.inline):backdrop .box > .start-action, +tabbar:not(.inline):backdrop .box > .end-action { + filter: opacity(0.5); +} + +dnd tab { + background-color: #061115; + color: #dadada; + box-shadow: none; + margin: 24px; +} + +tabbar tab, +dnd tab { + padding-right: 3px; + margin: 0; +} + +tabbar tab + tab, +dnd tab + tab { + margin-left: 3px; +} + +tabbar tab button.tab-close-button, +dnd tab button.tab-close-button { + border-radius: 3px; + min-height: 20px; + min-width: 20px; + padding: 0; +} + +tabbar tab indicator, +dnd tab indicator { + min-height: 2px; + border-radius: 2px; + background: alpha(#79AAEB,0.5); +} + +tabview:drop(active), +tabbox:drop(active) { + box-shadow: none; +} + +.unfolded stacksidebar.sidebar { + border: none; +} + +@define-color theme_fg_color #dedede; +@define-color theme_text_color currentColor; +@define-color theme_bg_color #0d181c; +@define-color theme_base_color #061115; +@define-color theme_selected_bg_color #79AAEB; +@define-color theme_selected_fg_color white; +@define-color fg_color #dedede; +@define-color text_color currentColor; +@define-color bg_color #0d181c; +@define-color base_color #061115; +@define-color selected_bg_color #79AAEB; +@define-color selected_fg_color white; +@define-color insensitive_bg_color #0a1519; +@define-color insensitive_fg_color rgba(222, 222, 222, 0.35); +@define-color insensitive_base_color #061115; +@define-color theme_unfocused_fg_color #dedede; +@define-color theme_unfocused_text_color currentColor; +@define-color theme_unfocused_bg_color #0d181c; +@define-color theme_unfocused_base_color #061115; +@define-color unfocused_insensitive_color #565d60; +@define-color borders rgba(255, 255, 255, 0.12); +@define-color unfocused_borders rgba(255, 255, 255, 0.12); +@define-color warning_color #E9967E; +@define-color error_color #F16269; +@define-color success_color #8CD7AA; +@define-color placeholder_text_color #A8A8A8; +@define-color link_color #79AAEB; +@define-color content_view_bg #061115; +/* Very contrasty background for text views (@theme_text_color foreground) */ +@define-color text_view_bg black; +@define-color wm_title alpha(#fdfdfd, 0.8); +@define-color wm_unfocused_title alpha(#fdfdfd, 0.5); +@define-color wm_bg #000a0e; +@define-color wm_bg_unfocused #000a0e; +@define-color wm_border_focused black; +@define-color wm_border_unfocused black; +@define-color wm_highlight alpha(white, 0.12); +@define-color wm_shadow alpha(black, 0.75); +@define-color wm_button_close_bg #ff767d; +@define-color wm_button_close_hover_bg #fb6c73; +@define-color wm_button_close_active_bg #F16269; +@define-color wm_icon_close_bg #dd4e55; +@define-color wm_button_hover_bg #0d181c; +@define-color wm_button_active_bg #0d181c; +@define-color wm_button_hover_border #242e31; +@define-color wm_icon_bg #afafaf; +@define-color wm_icon_unfocused_bg rgba(175, 175, 175, 0.35); +@define-color wm_icon_hover_bg #dedede; +@define-color wm_icon_active_bg #dedede; +@define-color titlebar_gradient_a #000a0e; +@define-color titlebar_gradient_b #000a0e; +@define-color budgie_tasklist_indicator_color #dedede; +@define-color budgie_tasklist_indicator_color_active #79AAEB; +@define-color budgie_tasklist_indicator_color_active_window #2a425b; +@define-color budgie_tasklist_indicator_color_attention #E9967E; +@define-color STRAWBERRY_100 #FF9262; +@define-color STRAWBERRY_300 #FF793E; +@define-color STRAWBERRY_500 #F15D22; +@define-color STRAWBERRY_700 #CF3B00; +@define-color STRAWBERRY_900 #AC1800; +@define-color ORANGE_100 #FFDB91; +@define-color ORANGE_300 #FFCA40; +@define-color ORANGE_500 #FAA41A; +@define-color ORANGE_700 #DE8800; +@define-color ORANGE_900 #C26C00; +@define-color BANANA_100 #FFFFA8; +@define-color BANANA_300 #FFFA7D; +@define-color BANANA_500 #FFCE51; +@define-color BANANA_700 #D1A023; +@define-color BANANA_900 #A27100; +@define-color LIME_100 #A2F3BE; +@define-color LIME_300 #8ADBA6; +@define-color LIME_500 #73C48F; +@define-color LIME_700 #479863; +@define-color LIME_900 #1C6D38; +@define-color BLUEBERRY_100 #94A6FF; +@define-color BLUEBERRY_300 #6A7CE0; +@define-color BLUEBERRY_500 #3F51B5; +@define-color BLUEBERRY_700 #213397; +@define-color BLUEBERRY_900 #031579; +@define-color GRAPE_100 #D25DE6; +@define-color GRAPE_300 #B84ACB; +@define-color GRAPE_500 #9C27B0; +@define-color GRAPE_700 #830E97; +@define-color GRAPE_900 #6A007E; +@define-color COCOA_100 #9F9792; +@define-color COCOA_300 #7B736E; +@define-color COCOA_500 #574F4A; +@define-color COCOA_700 #463E39; +@define-color COCOA_900 #342C27; +@define-color SILVER_100 #EEE; +@define-color SILVER_300 #CCC; +@define-color SILVER_500 #AAA; +@define-color SILVER_700 #888; +@define-color SILVER_900 #666; +@define-color SLATE_100 #888; +@define-color SLATE_300 #666; +@define-color SLATE_500 #444; +@define-color SLATE_700 #222; +@define-color SLATE_900 #111; +@define-color BLACK_100 #474341; +@define-color BLACK_300 #403C3A; +@define-color BLACK_500 #393634; +@define-color BLACK_700 #33302F; +@define-color BLACK_900 #2B2928; diff --git a/config/gtk-4.0/gtk.css b/config/gtk-4.0/gtk.css new file mode 100755 index 0000000..94640fc --- /dev/null +++ b/config/gtk-4.0/gtk.css @@ -0,0 +1,6249 @@ +/* This stylesheet is generated, DO NOT EDIT */ +window.background.csd > contents > leaflet.unfolded > box > headerbar { + background-image: none; + background-color: #162026; + border: none; +} + +window.background.csd > contents > leaflet.unfolded > box > stack > widget > box > widget > headerbar, +window.background.csd > contents > leaflet.unfolded > box > stack > widget > overlay > leaflet.folded > box > headerbar { + background-image: none; + background-color: #061115; +} + +window.background.csd > contents > leaflet.unfolded > box > searchbar > revealer > box { + background-color: #162026; + border-color: #000304; +} + +.titlebar:not(headerbar) > separator { + background-image: image(#000304); + background-color: transparent; + border-right: none; +} + +.card, window.background.csd stack stack stack frame > list, +window.background.csd > stack > stack > box > frame > list, +window.background.csd > stack > stack > box > box > frame > list, +window.background.csd > stack > box > stack > box > frame > list, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame > list, +window.background.csd > stack > box > stack > box > scrolledwindow > viewport > frame > list, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame > list, window.background.csd > stack > list, +window.background.csd > stack > scrolledwindow > viewport > box > list, +window.background.csd > box > stack > scrolledwindow > viewport > box > list, listview.boxed-list, +list.boxed-list, listview.content:not(.conversation-listbox), +list.content:not(.conversation-listbox), scrolledwindow viewport.frame > box.vertical list.frame { + border-radius: 12px; + box-shadow: inset 0 0 8px rgba(255, 255, 255, 0.03), inset 0 0 3px rgba(255, 255, 255, 0.02), inset 0 0 0 1px rgba(255, 255, 255, 0.04), inset 0 1px rgba(255, 255, 255, 0.06); + background-color: rgba(255, 255, 255, 0.05); + border: none; + color: #dadada; +} + +.card > separator, window.background.csd stack stack stack frame > list > separator, +window.background.csd > stack > stack > box > frame > list > separator, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame > list > separator, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame > list > separator, window.background.csd > stack > list > separator, +window.background.csd > stack > scrolledwindow > viewport > box > list > separator, listview.boxed-list > separator, +list.boxed-list > separator, listview.content:not(.conversation-listbox) > separator, +list.content:not(.conversation-listbox) > separator, scrolledwindow viewport.frame > box.vertical list.frame > separator { + background: none; + min-height: 0; +} + +window.background.csd stack stack stack frame > list row.activatable, +window.background.csd > stack > stack > box > frame > list row.activatable, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame > list row.activatable, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame > list row.activatable, window.background.csd > stack > list row.activatable, listview.boxed-list > row.expander list > row, +list.boxed-list > row.expander list > row, listview.boxed-list > row, +list.boxed-list > row, listview.content:not(.conversation-listbox) > row, +list.content:not(.conversation-listbox) > row, scrolledwindow viewport.frame > box.vertical list.frame > row.activatable { + border: none; +} + +window.background.csd stack stack stack frame > list row.activatable:first-child, window.background.csd > stack > list row.activatable:first-child, listview.boxed-list > row.expander list > row:first-child, +list.boxed-list > row.expander list > row:first-child, listview.boxed-list > row:first-child, +list.boxed-list > row:first-child, listview.content:not(.conversation-listbox) > row:first-child, +list.content:not(.conversation-listbox) > row:first-child, scrolledwindow viewport.frame > box.vertical list.frame > row.activatable:first-child { + border-top-left-radius: 12px; + border-top-right-radius: 12px; +} + +window.background.csd stack stack stack frame > list row.activatable:last-child, window.background.csd > stack > list row.activatable:last-child, listview.boxed-list > row.expander list > row:last-child, +list.boxed-list > row.expander list > row:last-child, listview.boxed-list > row:last-child, +list.boxed-list > row:last-child, listview.content:not(.conversation-listbox) > row:last-child, +list.content:not(.conversation-listbox) > row:last-child, scrolledwindow viewport.frame > box.vertical list.frame > row.activatable:last-child { + border-bottom-left-radius: 12px; + border-bottom-right-radius: 12px; +} + +window.background.csd stack stack stack frame > list row.activatable:only-child, window.background.csd > stack > list row.activatable:only-child, listview.boxed-list > row.expander list > row:only-child, +list.boxed-list > row.expander list > row:only-child, listview.boxed-list > row:only-child, +list.boxed-list > row:only-child, listview.content:not(.conversation-listbox) > row:only-child, +list.content:not(.conversation-listbox) > row:only-child, scrolledwindow viewport.frame > box.vertical list.frame > row.activatable:only-child { + border-radius: 12px; +} + +popover.emoji-picker emoji:focus, popover.emoji-picker emoji:hover, +calendar > grid > label.day-number:selected, columnview.view:selected, columnview.view:selected:focus, +treeview.view:selected, +treeview.view:selected:focus, +entry > text > selection, gridview > child:selected, flowbox > flowboxchild:selected, textview > text selection:focus, textview > text selection, iconview:selected:focus, .view:selected:focus { + background-color: #79AAEB; + color: white; +} + +popover.emoji-picker emoji:disabled:focus, popover.emoji-picker emoji:disabled:hover, +calendar > grid > label.day-number:disabled:selected, columnview.view:disabled:selected, +treeview.view:disabled:selected, +entry > text > selection:disabled, gridview > child:disabled:selected, flowbox > flowboxchild:disabled:selected, textview > text selection:disabled, iconview:disabled:selected:focus, .view:disabled:selected:focus { + color: #bcd5f5; +} + +row:selected label, label:selected { + color: white; +} + +row:selected label:disabled, label:disabled:selected { + color: #bcd5f5; +} + +.linked:not(.vertical) > dropdown > box > button.combo:dir(ltr), .linked:not(.vertical) > dropdown > box > button.combo:dir(rtl), .linked:not(.vertical) > combobox > box > button.combo:dir(ltr), .linked:not(.vertical) > combobox > box > button.combo:dir(rtl), .linked > menubutton:not(:only-child) > button { + border-radius: 0; + border-right-style: none; +} + +spinbutton:not(.vertical) > button, spinbutton:not(.vertical) > text, .linked:not(.vertical) > button, .linked:not(.vertical) > entry, .linked:not(.vertical) > entry:focus-within { + border-radius: 0; + border-right-style: none; +} + +spinbutton:not(.vertical) > button:first-child, spinbutton:not(.vertical) > text:first-child, .linked:not(.vertical) > button:first-child, .linked:not(.vertical) > entry:first-child, .linked:not(.vertical) > entry:first-child:focus-within { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +spinbutton:not(.vertical) > button:last-child, spinbutton:not(.vertical) > text:last-child, .linked:not(.vertical) > button:last-child, .linked:not(.vertical) > entry:last-child, .linked:not(.vertical) > entry:last-child:focus-within { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + border-right-style: solid; +} + +spinbutton:not(.vertical) > button:only-child, spinbutton:not(.vertical) > text:only-child, .linked:not(.vertical) > button:only-child, .linked:not(.vertical) > entry:only-child, .linked:not(.vertical) > entry:only-child:focus-within { + border-radius: 6px; + border-style: solid; +} + +spinbutton.vertical > button, spinbutton.vertical > text, .linked.vertical > button, .linked.vertical > entry, .linked.vertical > entry:focus-within { + border-radius: 0; + border-bottom-style: none; +} + +spinbutton.vertical > button:first-child, spinbutton.vertical > text:first-child, .linked.vertical > button:first-child, .linked.vertical > entry:first-child, .linked.vertical > entry:first-child:focus-within { + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} + +spinbutton.vertical > button:last-child, spinbutton.vertical > text:last-child, .linked.vertical > button:last-child, .linked.vertical > entry:last-child, .linked.vertical > entry:last-child:focus-within { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + border-bottom-style: solid; +} + +spinbutton.vertical > button:only-child, spinbutton.vertical > text:only-child, .linked.vertical > button:only-child, .linked.vertical > entry:only-child, .linked.vertical > entry:only-child:focus-within { + border-radius: 6px; + border-style: solid; +} + +.app-notification button, notebook > header > tabs > tab button.flat:active, +notebook > header > tabs > tab button.close-button:active, +notebook > header > tabs > tab button.image-button.flat:active, notebook > header > tabs > tab button.flat:hover, +notebook > header > tabs > tab button.close-button:hover, +notebook > header > tabs > tab button.image-button.flat:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, +list > row button.image-button:not(.flat), modelbutton.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; +} + +infobar.info > revealer > box button, infobar.info:hover > revealer > box button, infobar.info:backdrop > revealer > box button, infobar.question > revealer > box button, infobar.question:hover > revealer > box button, infobar.question:backdrop > revealer > box button, infobar.warning > revealer > box button, infobar.warning:hover > revealer > box button, infobar.warning:backdrop > revealer > box button, infobar.error > revealer > box button, infobar.error:hover > revealer > box button, infobar.error:backdrop > revealer > box button, .selection-mode headerbar button, headerbar.selection-mode button { + color: white; + background-color: rgba(255, 255, 255, 0); + border-color: rgba(255, 255, 255, 0.5); + background-image: none; + box-shadow: none; +} + +infobar.info > revealer > box button.flat, infobar.question > revealer > box button.flat, infobar.warning > revealer > box button.flat, infobar.error > revealer > box button.flat, .selection-mode headerbar button.flat, headerbar.selection-mode button.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: white; + background-color: rgba(255, 255, 255, 0); + background-image: none; +} + +infobar.info > revealer > box button.flat:disabled, infobar.question > revealer > box button.flat:disabled, infobar.warning > revealer > box button.flat:disabled, infobar.error > revealer > box button.flat:disabled, .selection-mode headerbar button.flat:disabled, headerbar.selection-mode button.flat:disabled, infobar.info > revealer > box button.flat:disabled label, infobar.question > revealer > box button.flat:disabled label, infobar.warning > revealer > box button.flat:disabled label, infobar.error > revealer > box button.flat:disabled label, .selection-mode headerbar button.flat:disabled label, headerbar.selection-mode button.flat:disabled label { + color: rgba(255, 255, 255, 0.4); +} + +infobar.info > revealer > box button:hover, infobar.question > revealer > box button:hover, infobar.warning > revealer > box button:hover, infobar.error > revealer > box button:hover, .selection-mode headerbar button:hover, headerbar.selection-mode button:hover { + color: white; + background-color: rgba(255, 255, 255, 0.2); + border-color: rgba(255, 255, 255, 0.5); + box-shadow: none; +} + +infobar.info > revealer > box button:active, infobar.question > revealer > box button:active, infobar.warning > revealer > box button:active, infobar.error > revealer > box button:active, .selection-mode headerbar button:active, headerbar.selection-mode button:active, infobar.info > revealer > box button:checked, infobar.question > revealer > box button:checked, infobar.warning > revealer > box button:checked, infobar.error > revealer > box button:checked, .selection-mode headerbar button:checked, headerbar.selection-mode button:checked { + color: white; + background-color: rgba(255, 255, 255, 0.4); + border-color: rgba(255, 255, 255, 0.5); + box-shadow: none; +} + +infobar.info > revealer > box button:disabled, infobar.question > revealer > box button:disabled, infobar.warning > revealer > box button:disabled, infobar.error > revealer > box button:disabled, .selection-mode headerbar button:disabled, headerbar.selection-mode button:disabled { + background-color: rgba(255, 255, 255, 0); + border-color: rgba(255, 255, 255, 0.4); + box-shadow: none; +} + +infobar.info > revealer > box button:disabled, infobar.question > revealer > box button:disabled, infobar.warning > revealer > box button:disabled, infobar.error > revealer > box button:disabled, .selection-mode headerbar button:disabled, headerbar.selection-mode button:disabled, infobar.info > revealer > box button:disabled label, infobar.question > revealer > box button:disabled label, infobar.warning > revealer > box button:disabled label, infobar.error > revealer > box button:disabled label, .selection-mode headerbar button:disabled label, headerbar.selection-mode button:disabled label { + color: rgba(255, 255, 255, 0.5); +} + +infobar.info > revealer > box button:disabled:active, infobar.question > revealer > box button:disabled:active, infobar.warning > revealer > box button:disabled:active, infobar.error > revealer > box button:disabled:active, .selection-mode headerbar button:disabled:active, headerbar.selection-mode button:disabled:active, infobar.info > revealer > box button:disabled:checked, infobar.question > revealer > box button:disabled:checked, infobar.warning > revealer > box button:disabled:checked, infobar.error > revealer > box button:disabled:checked, .selection-mode headerbar button:disabled:checked, headerbar.selection-mode button:disabled:checked { + color: #79AAEB; + background-color: rgba(255, 255, 255, 0.5); + border-color: rgba(255, 255, 255, 0.4); +} + +.background { + color: #dedede; + background-color: #0d181c; +} + +.background.csd { + border-radius: 12px; +} + +.background.csd.maximized, .background.csd.tiled, .background.csd.fullscreen { + border-radius: 12px; +} + +.background.solid-csd { + border-radius: 0; +} + +dnd { + color: #dedede; +} + +.normal-icons { + -gtk-icon-size: 16px; +} + +.large-icons { + -gtk-icon-size: 32px; +} + +spinner:disabled, +arrow:disabled, +scrollbar:disabled, +check:disabled, +radio:disabled, +treeview.expander:disabled { + -gtk-icon-filter: opacity(0.5); +} + +iconview, .view { + color: #dadada; + background-color: #061115; + transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +iconview:selected, .view:selected { + color: white; + background-color: #79AAEB; + transition: all 350ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +textview { + background-color: #061115; +} + +textview > text { + background-color: #061115; +} + +textview border { + background-color: #0a1519; +} + +textview:drop(active) { + caret-color: #E9967E; +} + +iconview, iconview:hover, iconview:selected { + border-radius: 6px; +} + +.content-view > rubberband, columnview.view > rubberband, +treeview.view > rubberband, flowbox > rubberband, +rubberband, +gridview > rubberband { + border: 1px solid #4d8ee4; + background-color: rgba(77, 142, 228, 0.2); +} + +flowbox > flowboxchild { + padding: 3px; + border-radius: 6px; +} + +flowbox > flowboxchild:selected { + outline-offset: -2px; +} + +flowbox.search-bar { + border-bottom: 1px solid #000304; +} + +gridview > child { + padding: 3px; +} + +gridview > child:selected { + outline-color: #3680e1; +} + +gridview > child box { + border-spacing: 8px; + margin: 12px; +} + +coverflow cover { + color: #dadada; + background-color: #061115; + border: 1px solid black; +} + +headerbar .subtitle, label.separator, .dim-label, row label.subtitle, +entry > text > placeholder { + opacity: 0.55; + text-shadow: none; +} + +label.separator { + color: #dedede; +} + +label > selection { + color: white; + background-color: #79AAEB; +} + +label:disabled { + color: rgba(222, 222, 222, 0.35); +} + +label:disabled selection { + color: #bcd5f5; +} + +.accent { + color: #79AAEB; +} + +.success { + color: #8CD7AA; +} + +.warning { + color: #E9967E; +} + +.error { + color: #F16269; +} + +window.assistant .sidebar { + background-color: #061115; +} + +window.assistant.csd .sidebar { + border-top-style: none; +} + +window.assistant .sidebar > label { + padding: 6px 12px; +} + +window.assistant .sidebar > label.highlight { + background-color: #79AAEB; + color: white; +} + +toast, .osd popover > arrow, +.osd popover > contents, popover.touch-selection > arrow, +popover.touch-selection > contents, popover.magnifier > arrow, +popover.magnifier > contents, .osd { + color: #d3d7df; + border: none; + background-color: #1a1a1a; + background-clip: padding-box; + border-radius: 6px; +} + +.osd { + padding: 6px; + margin: 6px; + box-shadow: 0 3px 8px rgba(0, 0, 0, 0.35); +} + +.osd.circular { + border-radius: 100%; +} + +@keyframes spin { + to { + transform: rotate(1turn); + } +} + +spinner { + background: none; + opacity: 0; + -gtk-icon-source: -gtk-icontheme("process-working-symbolic"); +} + +spinner:checked { + opacity: 1; + animation: spin 1s linear infinite; +} + +spinner:checked:disabled { + opacity: 0.5; +} + +.large-title { + font-weight: 300; + font-size: 24pt; +} + +.title-1 { + font-weight: 800; + font-size: 20pt; +} + +.title-2 { + font-weight: 800; + font-size: 15pt; +} + +.title-3 { + font-weight: 700; + font-size: 15pt; +} + +.title-4 { + font-weight: 700; + font-size: 13pt; +} + +.heading { + font-weight: 700; + font-size: 11pt; +} + +.body { + font-weight: 400; + font-size: 11pt; +} + +.caption { + font-weight: 400; + font-size: 9pt; +} + +.caption-heading { + font-weight: 700; + font-size: 9pt; +} + +.monospace { + font-family: monospace; +} + +.numeric { + font-feature-settings: "tnum"; +} + +spinbutton > text, .linked > entry:not(:only-child) { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; + border: none; +} + +spinbutton > text:focus, .linked > entry:focus:not(:only-child) { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); + transition-duration: 300ms; +} + +spinbutton > text:disabled, .linked > entry:disabled:not(:only-child) { + color: rgba(222, 222, 222, 0.35); + background-color: rgba(255, 255, 255, 0.02); +} + + +entry { + min-height: 24px; + border: none; + padding: 2px 8px; + border-radius: 6px; + caret-color: currentColor; + transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + animation-timing-function: ease-in-out; + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; +} + + +entry.search { + border-radius: 6px; +} + + +entry > image { + color: #b3b5b6; +} + + +entry > image.left { + padding-left: 0; + padding-right: 5px; +} + + +entry > image.right { + padding-right: 0; + padding-left: 5px; +} + + +entry.flat:focus-within, +entry.flat:backdrop, +entry.flat:disabled, +entry.flat:backdrop:disabled, +entry.flat { + min-height: 0; + background-image: none; + border-color: transparent; + border-radius: 0; +} + + +entry:hover { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05), inset 0 0 0 2px transparent; + transition-duration: 200ms; +} + + +entry:focus-within { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); + transition-duration: 300ms; +} + + +entry:focus-within > placeholder { + opacity: 0; +} + + +entry:disabled { + color: rgba(222, 222, 222, 0.35); + background-color: rgba(255, 255, 255, 0.02); +} + + +entry.warning { + color: white; + background-color: #8e6154; + border-image: none; +} + + +entry.warning image { + color: white; +} + + +entry.warning:focus-within { + color: white; + background-color: #E9967E; + box-shadow: none; +} + + +entry.warning > selection { + background-color: white; + color: #E9967E; +} + + +entry.error { + color: white; + background-color: #934247; + border-image: none; +} + + +entry.error image { + color: white; +} + + +entry.error:focus-within { + color: white; + background-color: #F16269; + box-shadow: none; +} + + +entry.error > selection { + background-color: white; + color: #F16269; +} + + +entry.search-missing { + color: white; + background-color: #934247; + border-image: none; +} + + +entry.search-missing image { + color: white; +} + + +entry.search-missing:focus-within { + color: white; + background-color: #F16269; + box-shadow: none; +} + + +entry.search-missing > selection { + background-color: white; + color: #F16269; +} + + +entry:drop(active):focus, +entry:drop(active) { + border-color: #E9967E; + box-shadow: none; + border-image: none; +} + +.osd entry { + color: #d3d7df; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(82, 82, 82, 0.96); + border-image: none; +} + +.osd entry image, .osd entry image:hover { + color: inherit; +} + +.osd entry:focus { + color: white; + border-color: #a5c6f2; + background-color: #79AAEB; + border-image: none; +} + +.osd entry:disabled { + color: rgba(211, 215, 223, 0.35); + background-color: rgba(82, 82, 82, 0.81); + border-image: none; +} + +.osd entry selection:focus, .osd entry selection { + color: #79AAEB; + background-color: white; +} + + +entry > progress { + margin: 0 -6px; + border-radius: 0; + border-width: 0 0 2px; + border-color: #79AAEB; + border-style: solid; + background-image: none; + background-color: transparent; + box-shadow: none; +} + + +entry progress > trough > progress { + background-color: transparent; + background-image: none; + border-radius: 0; + border-width: 0 0 2px; + border-color: #79AAEB; + border-style: solid; + box-shadow: none; +} + +.linked:not(.vertical) > entry, .linked:not(.vertical) > entry:focus-within { + min-height: 20px; +} + +.linked:not(.vertical) > entry + button.combo { + padding-left: 0; +} + +.linked.vertical > entry + button.combo { + padding: 0; +} + +.entry-tag { + margin: 8px; + border-radius: 50px; + box-shadow: none; + background-color: #F16269; + color: white; + border: none; +} + +.entry-tag:hover { + box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12); +} + +:dir(ltr) .entry-tag { + margin-left: 8px; + margin-right: 0px; + padding-left: 8px; + padding-right: 4px; +} + +:dir(rtl) .entry-tag { + margin-left: 0px; + margin-right: 8px; + padding-left: 4px; + padding-right: 8px; +} + +.entry-tag.button { + box-shadow: none; + border: none; + background-color: transparent; +} + +.entry-tag.button:not(:hover):not(:active) { + color: rgba(222, 222, 222, 0.35); +} + +treeview entry:focus-within:dir(rtl), treeview entry:focus-within:dir(ltr) { + background-color: #061115; + transition-property: color, background; +} + +treeview entry.flat, treeview entry { + border-radius: 0; + background-image: none; + background-color: #061115; +} + +treeview entry.flat:focus-within, treeview entry:focus-within { + border-color: #79AAEB; +} + +editablelabel > stack > text { + color: #dadada; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; +} + +@keyframes needs_attention { + from { + background-image: radial-gradient(farthest-side, #bcd4f5 0%, rgba(188, 212, 245, 0) 0%); + } + to { + background-image: radial-gradient(farthest-side, #bcd4f5 95%, rgba(188, 212, 245, 0)); + } +} + +stacksidebar row.needs-attention > label, stackswitcher > button.needs-attention > label, stackswitcher > button.needs-attention > image { + animation: needs_attention 150ms ease-in; + background-image: radial-gradient(farthest-side, #bcd4f5 96%, rgba(188, 212, 245, 0)); + background-size: 6px 6px, 6px 6px; + background-repeat: no-repeat; + background-position: right 3px, right 2px; +} + +stacksidebar row.needs-attention > label:backdrop, stackswitcher > button.needs-attention > label:backdrop, stackswitcher > button.needs-attention > image:backdrop { + background-size: 6px 6px, 0 0; +} + +stacksidebar row.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > image:dir(rtl) { + background-position: left 3px, left 2px; +} + +.scale-popup button, tabbox > tab button.tab-close-button, .toolbar button, splitbutton.suggested-action > button, splitbutton.suggested-action > menubutton > button, splitbutton.destructive-action > button, splitbutton.destructive-action > menubutton > button, splitbutton.opaque > button, splitbutton.opaque > menubutton > button, splitbutton.flat > button, +splitbutton.flat > menubutton > button, menubutton.suggested-action > button, menubutton.destructive-action > button, menubutton.opaque > button, menubutton.flat > button, +button.flat { + border: none; + background-color: transparent; + box-shadow: none; + background-clip: padding-box; +} + +.scale-popup button:hover, tabbox > tab button.tab-close-button:hover, .toolbar button:hover, splitbutton.suggested-action > button:hover, splitbutton.suggested-action > menubutton > button:hover, splitbutton.destructive-action > button:hover, splitbutton.destructive-action > menubutton > button:hover, splitbutton.opaque > button:hover, splitbutton.opaque > menubutton > button:hover, splitbutton.flat > button:hover, +splitbutton.flat > menubutton > button:hover, menubutton.suggested-action > button:hover, menubutton.destructive-action > button:hover, menubutton.opaque > button:hover, menubutton.flat > button:hover, +button.flat:hover { + color: #c5c5c5; + background-color: rgba(255, 255, 255, 0.15); + background-image: none; + box-shadow: none; +} + +.scale-popup button:active, tabbox > tab button.tab-close-button:active, .toolbar button:active, splitbutton.suggested-action > button:active, splitbutton.suggested-action > menubutton > button:active, splitbutton.destructive-action > button:active, splitbutton.destructive-action > menubutton > button:active, splitbutton.opaque > button:active, splitbutton.opaque > menubutton > button:active, splitbutton.flat > button:active, +splitbutton.flat > menubutton > button:active, menubutton.suggested-action > button:active, menubutton.destructive-action > button:active, menubutton.opaque > button:active, menubutton.flat > button:active, +button.flat:active { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.25); +} + +.scale-popup button:checked, tabbox > tab button.tab-close-button:checked, .toolbar button:checked, splitbutton.suggested-action > button:checked, splitbutton.suggested-action > menubutton > button:checked, splitbutton.destructive-action > button:checked, splitbutton.destructive-action > menubutton > button:checked, splitbutton.opaque > button:checked, splitbutton.opaque > menubutton > button:checked, splitbutton.flat > button:checked, +splitbutton.flat > menubutton > button:checked, menubutton.suggested-action > button:checked, menubutton.destructive-action > button:checked, menubutton.opaque > button:checked, menubutton.flat > button:checked, +button.flat:checked { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.35); +} + +.scale-popup button:disabled, tabbox > tab button.tab-close-button:disabled, .toolbar button:disabled, splitbutton.suggested-action > button:disabled, splitbutton.suggested-action > menubutton > button:disabled, splitbutton.destructive-action > button:disabled, splitbutton.destructive-action > menubutton > button:disabled, splitbutton.opaque > button:disabled, splitbutton.opaque > menubutton > button:disabled, splitbutton.flat > button:disabled, +splitbutton.flat > menubutton > button:disabled, menubutton.suggested-action > button:disabled, menubutton.destructive-action > button:disabled, menubutton.opaque > button:disabled, menubutton.flat > button:disabled, +button.flat:disabled { + background-color: transparent; +} + +.scale-popup button:disabled label, tabbox > tab button.tab-close-button:disabled label, .toolbar button:disabled label, splitbutton.suggested-action > button:disabled label, splitbutton.destructive-action > button:disabled label, splitbutton.opaque > button:disabled label, splitbutton.flat > button:disabled label, menubutton.suggested-action > button:disabled label, menubutton.destructive-action > button:disabled label, menubutton.opaque > button:disabled label, menubutton.flat > button:disabled label, +button.flat:disabled label, .scale-popup button:disabled, tabbox > tab button.tab-close-button:disabled, .toolbar button:disabled, splitbutton.suggested-action > button:disabled, splitbutton.suggested-action > menubutton > button:disabled, splitbutton.destructive-action > button:disabled, splitbutton.destructive-action > menubutton > button:disabled, splitbutton.opaque > button:disabled, splitbutton.opaque > menubutton > button:disabled, splitbutton.flat > button:disabled, +splitbutton.flat > menubutton > button:disabled, menubutton.suggested-action > button:disabled, menubutton.destructive-action > button:disabled, menubutton.opaque > button:disabled, menubutton.flat > button:disabled, +button.flat:disabled { + color: rgba(222, 222, 222, 0.35); +} + + +button.opaque { + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + + +.osd button.opaque:focus:focus-visible { + outline-color: rgba(255, 255, 255, 0.15); +} + + +button.opaque:hover { + background-image: image(alpha(currentColor,0.1)); +} + + +button.keyboard-activating.opaque, +button.opaque:active { + background-image: image(rgba(0, 0, 0, 0.2)); +} + + +button.opaque:checked { + background-image: image(rgba(0, 0, 0, 0.15)); +} + + +button.opaque:checked:hover { + background-image: image(rgba(0, 0, 0, 0.05)); +} + + +button.opaque:checked.keyboard-activating, +button.opaque:checked:active { + background-image: image(rgba(0, 0, 0, 0.3)); +} + + +button { + min-height: 24px; + min-width: 18px; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + border: 1px solid; + border-radius: 6px; + padding: 0 8px; + background-clip: padding-box; + color: #dedede; + border-color: rgba(0, 0, 0, 0.15); + background-color: #1C252C; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px rgba(255, 255, 255, 0.02), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + + +button separator { + margin: 4px 1px; +} + + +button.flat { + min-height: 24px; + transition: none; +} + + +button.flat:hover { + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-duration: 350ms; +} + + +button.flat:hover:active { + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + + +button.flat:checked:hover { + background-image: none; +} + + +button.flat.toggle.popup { + min-width: 20px; +} + + +button.opaque { + background-color: #374043; + color: #dedede; +} + + +button:hover { + color: #f8f8f8; + border-color: rgba(0, 0, 0, 0.15); + background-color: #222d35; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); + background-clip: padding-box; + -gtk-icon-filter: brightness(1.2); +} + + +button.keyboard-activating, +button:active, +button:checked { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); + background-clip: padding-box; + transition-duration: 200ms; +} + + +button.keyboard-activating:not(:disabled) label:disabled, +button:active:not(:disabled) label:disabled, +button:checked:not(:disabled) label:disabled { + color: inherit; + opacity: 0.6; +} + + +button:disabled { + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(28, 37, 44, 0.55); + box-shadow: none; + background-clip: padding-box; +} + + +button:disabled label, +button:disabled { + color: rgba(222, 222, 222, 0.35); +} + + +button:disabled:active, +button:disabled:checked { + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(121, 170, 235, 0.55); + opacity: 0.6; + background-clip: padding-box; +} + + +button:disabled:active label, +button:disabled:active, +button:disabled:checked label, +button:disabled:checked { + color: rgba(255, 255, 255, 0.55); +} + + +button.image-button { + min-height: 24px; + padding-left: 6px; + padding-right: 6px; +} + + +button.text-button { + min-height: 24px; + padding-left: 12px; + padding-right: 12px; +} + + +button.text-button.image-button, +button.image-text-button { + min-height: 24px; + padding-left: 6px; + padding-right: 6px; +} + + +button.text-button.image-button > box, +button.text-button.image-button > box > box, +button.image-text-button > box, +button.image-text-button > box > box { + border-spacing: 4px; +} + + +button.text-button.image-button > box > label, +button.text-button.image-button > box > box > label, +button.image-text-button > box > label, +button.image-text-button > box > box > label { + padding-left: 2px; + padding-right: 2px; +} + + +button.text-button.image-button label:first-child, +button.image-text-button label:first-child { + padding-left: 8px; + padding-right: 3px; +} + + +button.text-button.image-button label:last-child, +button.image-text-button label:last-child { + padding-right: 8px; + padding-left: 3px; +} + + +button.text-button.image-button label:only-child, +button.image-text-button label:only-child { + padding-left: 8px; + padding-right: 8px; +} + + +button.text-button.image-button.popup, +button.image-text-button.popup { + padding-right: 6px; + padding-left: 6px; +} + + +button.arrow-button { + padding-left: 9px; + padding-right: 9px; +} + + +button.arrow-button > box { + border-spacing: 4px; +} + + +button.arrow-button.text-button > box { + border-spacing: 4px; +} + + +button.font separator { + background-color: transparent; + background-image: none; +} + + +button.font > box { + border-spacing: 6px; +} + + +button.font > box > box > label { + font-weight: bold; +} + +stackswitcher button.circular, .app-notification button.image-button:not(.text-button), row button.circular, searchbar > revealer > box .close, searchbar button.flat, menubutton.circular > button, +button.circular, +button.close { + border-radius: 9999px; + padding: 0; + min-height: 28px; + min-width: 28px; +} + +.app-notification button.image-button:not(.text-button) label, searchbar > revealer > box .close label, searchbar button.flat label, menubutton.circular > button label, +button.circular label, +button.close label { + padding: 0; +} + +menubutton.pill > button, +button.pill { + padding: 9px 30px; + border-radius: 9999px; +} + + +button.card { + background-color: rgba(255, 255, 255, 0.05); + background-clip: padding-box; + font-weight: inherit; + padding: 6px; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + + +button.card:hover { + background-image: image(alpha(currentColor,0.03)); +} + + +button.card.keyboard-activating, +button.card:active { + background-image: image(alpha(currentColor,0.08)); +} + + +button.card:checked { + background-color: rgba(255, 255, 255, 0.05); + background-image: image(alpha(currentColor,0.1)); +} + + +button.card:checked:hover { + background-image: image(alpha(currentColor,0.13)); +} + + +button.card:checked.keyboard-activating, +button.card:checked:active { + background-image: image(alpha(currentColor,0.19)); +} + + +button.card:checked.has-open-popup { + background-image: image(alpha(currentColor,0.13)); +} + + +button.card:drop(active) { + color: #E9967E; + box-shadow: inset 0 0 0 1px #E9967E; +} + + +button:drop(active) { + color: #E9967E; + border-color: #E9967E; + box-shadow: inset 0 0 0 1px #E9967E; +} + + +button.osd { + color: #d3d7df; + background-color: #1a1a1a; + border-color: #060606; + box-shadow: none; +} + + +button.osd.image-button { + padding: 0; + min-height: 42px; + min-width: 42px; +} + + +button.osd:hover { + color: #79AAEB; + box-shadow: none; + background-color: rgba(82, 82, 82, 0.96); +} + + +button.osd.keyboard-activating, +button.osd:active, +button.osd:checked { + color: white; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.25); + background-image: none; + box-shadow: none; + background-clip: padding-box; +} + + +button.osd:disabled { + color: rgba(211, 215, 223, 0.35); + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.03); + box-shadow: none; +} + +toast button, popover.touch-selection button, popover.magnifier button, menubutton.osd > button, .osd button { + color: #d3d7df; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.08); + box-shadow: none; +} + +toast button:hover, popover.touch-selection button:hover, popover.magnifier button:hover, .osd button:hover { + color: #d3d7df; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.16); + box-shadow: none; +} + +toast button.keyboard-activating, popover.touch-selection button.keyboard-activating, popover.magnifier button.keyboard-activating, toast button:active, popover.touch-selection button:active, popover.magnifier button:active, toast button:checked, popover.touch-selection button:checked, popover.magnifier button:checked, .osd button.keyboard-activating, .osd button:active, .osd button:checked { + color: white; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.25); + background-image: none; + box-shadow: none; + background-clip: padding-box; +} + +toast button:disabled, popover.touch-selection button:disabled, popover.magnifier button:disabled, .osd button:disabled { + color: rgba(211, 215, 223, 0.35); + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.03); + box-shadow: none; +} + +toast button.flat, popover.touch-selection button.flat, popover.magnifier button.flat, .osd button.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + box-shadow: none; +} + +toast button.flat:hover, popover.touch-selection button.flat:hover, popover.magnifier button.flat:hover, .osd button.flat:hover { + color: #d3d7df; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.16); + box-shadow: none; +} + +toast button.flat:disabled, popover.touch-selection button.flat:disabled, popover.magnifier button.flat:disabled, .osd button.flat:disabled { + color: rgba(211, 215, 223, 0.35); + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.03); + box-shadow: none; + background-image: none; +} + +toast button.flat:active, popover.touch-selection button.flat:active, popover.magnifier button.flat:active, toast button.flat:checked, popover.touch-selection button.flat:checked, popover.magnifier button.flat:checked, .osd button.flat:active, .osd button.flat:checked { + color: white; + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(255, 255, 255, 0.25); + background-image: none; + box-shadow: none; + background-clip: padding-box; +} + +.osd .linked:not(.vertical):not(.path-bar) > button:hover:not(:checked):not(:active):not(:only-child), .osd .linked:not(.vertical):not(.path-bar) > button:hover:not(:checked):not(:active) + button:not(:checked):not(:active) { + box-shadow: none; +} + + +button.suggested-action { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + + +button.suggested-action.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: #79AAEB; +} + + +button.suggested-action:hover { + color: white; + background-color: #8fb8ee; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + + +button.suggested-action:active, +button.suggested-action:checked { + color: white; + background-color: #639ce8; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); + box-shadow: none; +} + + +button.suggested-action.flat:disabled { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: rgba(222, 222, 222, 0.35); +} + + +button.suggested-action:disabled { + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(28, 37, 44, 0.55); + box-shadow: none; +} + + +button.suggested-action:disabled label, +button.suggested-action:disabled { + color: rgba(222, 222, 222, 0.35); +} + + +button.destructive-action { + color: white; + background-color: #F16269; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + + +button.destructive-action.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: #F16269; +} + + +button.destructive-action:hover { + color: white; + background-color: #f3797f; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + + +button.destructive-action:active, +button.destructive-action:checked { + color: white; + background-color: #ef4b53; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); + box-shadow: none; +} + + +button.destructive-action.flat:disabled { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: rgba(222, 222, 222, 0.35); +} + + +button.destructive-action:disabled { + border-color: rgba(0, 0, 0, 0.15); + background-color: rgba(28, 37, 44, 0.55); + box-shadow: none; +} + + +button.destructive-action:disabled label, +button.destructive-action:disabled { + color: rgba(222, 222, 222, 0.35); +} + +stackswitcher > button { + outline-offset: -3px; +} + +stackswitcher > button > label { + padding-left: 6px; + padding-right: 6px; +} + +stackswitcher > button > image { + padding-left: 6px; + padding-right: 6px; +} + +stackswitcher > button.text-button { + padding-left: 10px; + padding-right: 10px; +} + +stackswitcher > button.image-button { + padding-left: 2px; + padding-right: 2px; +} + +stackswitcher > button.needs-attention:active > label, stackswitcher > button.needs-attention:active > image, stackswitcher > button.needs-attention:checked > label, stackswitcher > button.needs-attention:checked > image { + animation: none; + background-image: none; +} + + +button.font separator, +button.file separator { + background-color: transparent; +} + +menubutton { + margin: 0; +} + +menubutton.osd { + background: none; + color: inherit; +} + +menubutton.suggested-action { + background-color: #79AAEB; + color: white; +} + +menubutton.destructive-action { + background-color: #F16269; + color: white; +} + +menubutton.opaque { + background-color: #374043; + color: #dedede; +} + +menubutton.suggested-action, menubutton.destructive-action, menubutton.opaque { + border-radius: 6px; +} + +menubutton.suggested-action.circular, menubutton.suggested-action.pill, menubutton.destructive-action.circular, menubutton.destructive-action.pill, menubutton.opaque.circular, menubutton.opaque.pill { + border-radius: 9999px; +} + +menubutton.suggested-action > button, menubutton.suggested-action > button:checked, menubutton.destructive-action > button, menubutton.destructive-action > button:checked, menubutton.opaque > button, menubutton.opaque > button:checked { + background-color: transparent; + color: inherit; +} + +menubutton.image-button > button { + min-width: 24px; + padding-left: 5px; + padding-right: 5px; +} + +menubutton arrow { + min-height: 16px; + min-width: 16px; +} + +menubutton arrow.none { + -gtk-icon-source: -gtk-icontheme("open-menu-symbolic"); +} + +menubutton arrow.down { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +menubutton arrow.up { + -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); +} + +menubutton arrow.left { + -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); +} + +menubutton arrow.right { + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); +} + +.linked > menubutton:first-child > button { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.linked > menubutton:last-child > button { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +splitbutton { + border-radius: 6px; +} + +splitbutton, splitbutton > separator { + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-property: background; +} + +splitbutton > separator { + margin-top: 6px; + margin-bottom: 6px; + background: none; +} + +splitbutton > menubutton > button { + padding-left: 4px; + padding-right: 4px; +} + +splitbutton.image-button > button { + min-width: 24px; + padding-left: 6px; + padding-right: 6px; +} + +splitbutton.text-button.image-button > button, splitbutton.image-text-button > button { + padding-left: 9px; + padding-right: 9px; +} + +splitbutton.text-button.image-button > button > box, splitbutton.image-text-button > button > box { + border-spacing: 6px; +} + +splitbutton > button:dir(ltr), +splitbutton > menubutton > button:dir(rtl) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + margin-right: -1px; +} + +splitbutton > button:dir(rtl), +splitbutton > menubutton > button:dir(ltr) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; +} + +splitbutton.flat > separator { + background: rgba(255, 255, 255, 0.12); +} + +splitbutton.flat:hover, splitbutton.flat:active, splitbutton.flat:checked { + background: alpha(currentColor,0.07); +} + +splitbutton.flat:hover > separator, splitbutton.flat:active > separator, splitbutton.flat:checked > separator { + background: none; +} + +splitbutton.flat:focus-within:focus-visible > separator { + background: none; +} + +splitbutton.flat > button, +splitbutton.flat > menubutton > button { + border-radius: 6px; +} + +splitbutton.suggested-action { + background-color: #79AAEB; + color: white; +} + +splitbutton.destructive-action { + background-color: #F16269; + color: white; +} + +splitbutton.opaque { + background-color: #374043; + color: #dedede; +} + +splitbutton.suggested-action > button, splitbutton.suggested-action > button:checked, splitbutton.suggested-action > menubutton > button, splitbutton.suggested-action > menubutton > button:checked, splitbutton.destructive-action > button, splitbutton.destructive-action > button:checked, splitbutton.destructive-action > menubutton > button, splitbutton.destructive-action > menubutton > button:checked, splitbutton.opaque > button, splitbutton.opaque > button:checked, splitbutton.opaque > menubutton > button, splitbutton.opaque > menubutton > button:checked { + color: inherit; + background-color: transparent; +} + +splitbutton.suggested-action > menubutton > button:dir(ltr), splitbutton.destructive-action > menubutton > button:dir(ltr), splitbutton.opaque > menubutton > button:dir(ltr) { + box-shadow: inset 1px 0 rgba(255, 255, 255, 0.12); +} + +splitbutton.suggested-action > menubutton > button:dir(rtl), splitbutton.destructive-action > menubutton > button:dir(rtl), splitbutton.opaque > menubutton > button:dir(rtl) { + box-shadow: inset -1px 0 rgba(255, 255, 255, 0.12); +} + +splitbutton > menubutton > button > arrow.none { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +buttoncontent { + border-spacing: 6px; +} + +buttoncontent > label { + font-weight: bold; +} + +buttoncontent > label:dir(ltr) { + padding-right: 2px; +} + +buttoncontent > label:dir(rtl) { + padding-left: 2px; +} + +.arrow-button > box > buttoncontent > label:dir(ltr), splitbutton > button > buttoncontent > label:dir(ltr) { + padding-right: 0; +} + +.arrow-button > box > buttoncontent > label:dir(rtl), splitbutton > button > buttoncontent > label:dir(rtl) { + padding-left: 0; +} + +.linked:not(.vertical):not(.path-bar) > entry:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); +} + +.linked:not(.vertical):not(.path-bar) > entry:drop(active):not(:only-child) { + box-shadow: inset 0 0 0 2px #E9967E; +} + +.linked:not(.vertical):not(.path-bar) > entry.warning:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px #E9967E; +} + +.linked:not(.vertical):not(.path-bar) > entry.error:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px #F16269; +} + +.linked:not(.vertical):not(.path-bar) > button + button { + border-left-style: none; +} + +.linked:not(.vertical).path-bar > button + button { + border-left-style: none; +} + +.linked.vertical > entry:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); +} + +.linked.vertical > entry:drop(active):not(:only-child) { + box-shadow: inset 0 0 0 2px #E9967E; +} + +.linked.vertical > entry.warning:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px #E9967E; +} + +.linked.vertical > entry.error:focus-within:not(:only-child) { + box-shadow: inset 0 0 0 2px #F16269; +} + +.linked.vertical > button + button { + border-top-style: none; +} + +modelbutton.flat { + transition: all 100ms cubic-bezier(0, 0, 0.2, 1); + min-height: 26px; + padding-left: 8px; + padding-right: 8px; + outline-offset: -3px; + border-radius: 6px; +} + +modelbutton.flat:hover { + background-color: #222c2f; + transition-duration: 50ms; +} + +modelbutton.flat:active, modelbutton.flat:active arrow, modelbutton.flat:selected, modelbutton.flat:selected arrow { + background-color: #79AAEB; + color: white; + transition: none; + animation: none; +} + +modelbutton.flat:checked { + color: #dedede; +} + +modelbutton.flat:disabled { + color: rgba(222, 222, 222, 0.35); +} + +modelbutton.flat check:last-child, +modelbutton.flat radio:last-child { + margin-left: 8px; +} + +modelbutton.flat check:first-child, +modelbutton.flat radio:first-child { + margin-right: 8px; +} + +modelbutton.flat arrow.left, modelbutton.flat arrow.right { + background-color: transparent; + background-image: none; + min-width: 16px; + min-height: 16px; + transition: none; + color: #afafaf; + opacity: 1; +} + +modelbutton.flat arrow.left:hover, modelbutton.flat arrow.left:selected, modelbutton.flat arrow.left:focus, modelbutton.flat arrow.right:hover, modelbutton.flat arrow.right:selected, modelbutton.flat arrow.right:focus { + background-color: transparent; + background-image: none; + transition: none; + color: white; +} + +modelbutton.flat arrow.left.left, modelbutton.flat arrow.right.left { + -gtk-icon-source: -gtk-icontheme("go-previous-symbolic"); +} + +modelbutton.flat arrow.left.right, modelbutton.flat arrow.right.right { + -gtk-icon-source: -gtk-icontheme("go-next-symbolic"); +} + +popover.menu box.circular-buttons button.circular.image-button.model, +list > row button.image-button:not(.flat) { + border: 1px solid rgba(255, 255, 255, 0); +} + +popover.menu box.circular-buttons button.circular.image-button.model:hover, +list > row button.image-button:not(.flat):hover { + color: #f8f8f8; + border-color: rgba(0, 0, 0, 0.15); + background-color: #222d35; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +popover.menu box.circular-buttons button.circular.image-button.model:active, popover.menu box.circular-buttons button.circular.image-button.model:checked, +list > row button.image-button:not(.flat):active, +list > row button.image-button:not(.flat):checked { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); +} + +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, +list > row button.image-button:not(.flat).suggested-action { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, +list > row button.image-button:not(.flat).destructive-action { + color: white; + background-color: #F16269; + border-color: rgba(0, 0, 0, 0.15); + background-image: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.15), inset 0 -1px rgba(255, 255, 255, 0.03); +} + +link, button.link { + color: #79AAEB; +} + +link:visited, button.link:visited { + color: #b4b4b4; +} + +*:selected link:visited, *:selected button.link:visited { + color: #c9ddf7; +} + +link:hover, button.link:hover { + color: #a5c6f2; +} + +*:selected link:hover, *:selected button.link:hover { + color: #f2f7fd; +} + +link:active, button.link:active { + color: #79AAEB; +} + +*:selected link:active, *:selected button.link:active { + color: #e4eefb; +} + +infobar.info > revealer > box link, infobar.info:hover > revealer > box link, infobar.info:backdrop > revealer > box link, infobar.question > revealer > box link, infobar.question:hover > revealer > box link, infobar.question:backdrop > revealer > box link, infobar.warning > revealer > box link, infobar.warning:hover > revealer > box link, infobar.warning:backdrop > revealer > box link, infobar.error > revealer > box link, infobar.error:hover > revealer > box link, infobar.error:backdrop > revealer > box link, .selection-mode headerbar .subtitle:link, headerbar.selection-mode .subtitle:link, link:selected, *:selected link, button.link:selected, *:selected button.link { + color: #e4eefb; +} + +button.link > label { + text-decoration-line: underline; +} + +spinbutton { + font-feature-settings: "tnum"; +} + +spinbutton:drop(active) { + box-shadow: none; +} + +spinbutton button:active { + color: white; +} + +spinbutton:disabled { + color: rgba(222, 222, 222, 0.35); +} + +spinbutton > text { + padding: 6px; + border: 1px solid rgba(0, 0, 0, 0.15); +} + +spinbutton > text:focus-within { + border-color: rgba(188, 212, 245, 0.75); + box-shadow: inset 0 0 0 1px rgba(188, 212, 245, 0.75); +} + +spinbutton > text:drop(active) { + border-color: #E9967E; + box-shadow: inset 0 0 0 1px #E9967E; +} + +spinbutton:not(.vertical) { + padding: 0; + border-spacing: 0; +} + +spinbutton:not(.vertical) > text { + padding-top: 2px; + padding-bottom: 2px; + min-width: 28px; +} + +spinbutton:not(.vertical) > button, spinbutton:not(.vertical) > text { + min-height: 20px; +} + +spinbutton:not(.vertical):dir(ltr) > text, spinbutton:not(.vertical):dir(rtl) > button.up { + border-radius: 6px 0 0 6px; +} + +spinbutton:not(.vertical) > button + button { + border-left-style: none; +} + +spinbutton:not(.vertical) > button:hover:not(:active), +spinbutton:not(.vertical) > button:hover + button { + box-shadow: inset 1px 0 rgba(255, 255, 255, 0.12); +} + +spinbutton:not(.vertical) > button:disabled + button:not(:disabled):not(:active):not(:checked):not(:hover), +spinbutton:not(.vertical) > button:not(:disabled):not(:active):not(:checked):not(:hover) + button:disabled { + box-shadow: inset 1px 0 rgba(255, 255, 255, 0); +} + +spinbutton:not(.vertical) > button:first-child:hover:not(:active), +spinbutton:not(.vertical) > button.up:dir(rtl):hover:not(:active), +spinbutton:not(.vertical) > text + button:not(:active):hover { + box-shadow: none; +} + +spinbutton:not(.vertical) > text:focus-within + button { + border-left-color: rgba(188, 212, 245, 0.75); +} + +spinbutton:not(.vertical) > text:drop(active) + button { + border-left-color: #E9967E; +} + +.osd spinbutton:not(.vertical), .osd spinbutton:not(.vertical):focus-within, .osd spinbutton:not(.vertical):drop(active) { + border-image: none; +} + +.osd spinbutton:not(.vertical) > button:hover:not(:active), +.osd spinbutton:not(.vertical) > button:hover + button { + box-shadow: inset 1px 0 rgba(0, 0, 0, 0.15); +} + +.osd spinbutton:not(.vertical) > button:first-child:hover:not(:active), +.osd spinbutton:not(.vertical) > button.up:dir(rtl):hover:not(:active), +.osd spinbutton:not(.vertical) > text + button:not(:active):hover { + box-shadow: none; +} + +.osd spinbutton:not(.vertical) > text:focus-within + button { + border-left-color: rgba(188, 212, 245, 0.75); +} + +spinbutton.vertical > button, spinbutton.vertical > text { + padding-left: 4px; + padding-right: 4px; + min-width: 0; +} + +spinbutton.vertical > button.up { + border-radius: 6px 6px 0 0; +} + +spinbutton.vertical > text:focus-within + button { + border-top-color: rgba(188, 212, 245, 0.75); +} + +spinbutton.vertical > text:drop(active) + button { + border-top-color: #E9967E; +} + +treeview spinbutton:not(.vertical), row spinbutton:not(.vertical) { + min-height: 0; + padding: 0 3px; + border-style: none; + border-radius: 6px; + background-color: rgba(222, 222, 222, 0.08); +} + +treeview spinbutton:not(.vertical):focus, treeview spinbutton:not(.vertical):hover, treeview spinbutton:not(.vertical):selected, row spinbutton:not(.vertical):focus, row spinbutton:not(.vertical):hover, row spinbutton:not(.vertical):selected { + background-color: rgba(222, 222, 222, 0.12); +} + +treeview spinbutton:not(.vertical):focus-within, row spinbutton:not(.vertical):focus-within { + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); + transition: box-shadow 150ms cubic-bezier(0, 0, 0.2, 1); +} + +treeview spinbutton:not(.vertical) > text, treeview spinbutton:not(.vertical) > text:hover, treeview spinbutton:not(.vertical) > text:focus, row spinbutton:not(.vertical) > text, row spinbutton:not(.vertical) > text:hover, row spinbutton:not(.vertical) > text:focus { + background: none; + border: none; + box-shadow: none; +} + +treeview spinbutton:not(.vertical) > button.up, +treeview spinbutton:not(.vertical) > button.down, row spinbutton:not(.vertical) > button.up, +row spinbutton:not(.vertical) > button.down { + border: none; + border-color: transparent; + box-shadow: none; + border-radius: 100px; + min-height: 22px; + min-width: 22px; + padding: 0; + margin: 4px 2px; + background-color: transparent; +} + +treeview spinbutton:not(.vertical) > button.up:hover, +treeview spinbutton:not(.vertical) > button.down:hover, row spinbutton:not(.vertical) > button.up:hover, +row spinbutton:not(.vertical) > button.down:hover { + background-color: rgba(222, 222, 222, 0.1); +} + +treeview spinbutton:not(.vertical) > button.up:active, +treeview spinbutton:not(.vertical) > button.down:active, row spinbutton:not(.vertical) > button.up:active, +row spinbutton:not(.vertical) > button.down:active { + background-color: rgba(222, 222, 222, 0.15); + color: #dedede; +} + +treeview spinbutton:not(.vertical) > button:hover:not(:active), +treeview spinbutton:not(.vertical) > button:hover + button, row spinbutton:not(.vertical) > button:hover:not(:active), +row spinbutton:not(.vertical) > button:hover + button { + box-shadow: none; +} + +treeview spinbutton:not(.vertical) > button:disabled + button:not(:disabled):not(:active):not(:checked):not(:hover), +treeview spinbutton:not(.vertical) > button:not(:disabled):not(:active):not(:checked):not(:hover) + button:disabled, row spinbutton:not(.vertical) > button:disabled + button:not(:disabled):not(:active):not(:checked):not(:hover), +row spinbutton:not(.vertical) > button:not(:disabled):not(:active):not(:checked):not(:hover) + button:disabled { + box-shadow: none; +} + +treeview spinbutton:not(.vertical) > text:focus + button, row spinbutton:not(.vertical) > text:focus + button { + border-left-color: transparent; +} + +treeview spinbutton:not(.vertical) > text:drop(active) + button, row spinbutton:not(.vertical) > text:drop(active) + button { + border-left-color: transparent; +} + +dropdown > popover.menu.background > contents { + padding: 0; +} + +dropdown > button > box { + border-spacing: 6px; +} + +dropdown, +combobox { + min-height: 24px; +} + +dropdown button.combo, +combobox button.combo { + min-width: 0; + min-height: 24px; + padding-left: 12px; + padding-right: 12px; +} + +dropdown > popover.menu > contents modelbutton, +combobox > popover.menu > contents modelbutton { + padding-left: 10px; + padding-right: 10px; +} + +dropdown button.combo arrow, +combobox button.combo arrow { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); + -gtk-icon-source: -gtk-scaled(url("assets/combobox-arrow-dark.png"), url("assets/combobox-arrow-dark@2.png")); + min-height: 16px; + min-width: 18px; + padding: 0; + margin: 2px -10px 2px 0; + border-radius: 5px; + border: none; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.15), 0 1px 2px 0 rgba(0, 0, 0, 0.05); +} + +.background dropdown button.combo:disabled arrow, .background dropdown button.combo:backdrop arrow, .background combobox button.combo:disabled arrow, .background combobox button.combo:backdrop arrow { + background-color: rgba(255, 255, 255, 0.25); +} + +dropdown button.combo:checked, .background dropdown button.combo:checked, +combobox button.combo:checked, .background combobox button.combo:checked { + transition: none; +} + +dropdown:drop(active) button.combo, +combobox:drop(active) button.combo { + color: #E9967E; + border-color: #E9967E; + box-shadow: none; +} + +dropdown popover, +combobox popover { + margin-top: 3px; + padding: 0; +} + +dropdown popover listview, +combobox popover listview { + margin: 6px 0; +} + +dropdown popover listview > row, +combobox popover listview > row { + padding: 6px; +} + +dropdown popover listview > row:selected, +combobox popover listview > row:selected { + color: white; + background-color: #79AAEB; +} + +dropdown popover .dropdown-searchbar, +combobox popover .dropdown-searchbar { + padding: 6px; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +dropdown .linked:not(.vertical) > entry + button.combo arrow, .linked:not(.vertical) > dropdown > box > button.combo arrow, +combobox .linked:not(.vertical) > entry + button.combo arrow, .linked:not(.vertical) > combobox > box > button.combo arrow { + background-color: transparent; + box-shadow: none; + -gtk-icon-source: -gtk-scaled(url("assets/combobox-arrow-dark.png"), url("assets/combobox-arrow-dark@2.png")); +} + +dropdown .linked:not(.vertical) > entry + button.combo:checked arrow, dropdown .linked:not(.vertical) > entry + button.combo:active arrow, .linked:not(.vertical) > dropdown > box > button.combo:checked arrow, .linked:not(.vertical) > dropdown > box > button.combo:active arrow, +combobox .linked:not(.vertical) > entry + button.combo:checked arrow, +combobox .linked:not(.vertical) > entry + button.combo:active arrow, .linked:not(.vertical) > combobox > box > button.combo:checked arrow, .linked:not(.vertical) > combobox > box > button.combo:active arrow { + border-radius: 0; + background-color: transparent; + -gtk-icon-source: -gtk-scaled(url("assets/combobox-arrow-dark.png"), url("assets/combobox-arrow-dark@2.png")); +} + +.linked:not(.vertical) > dropdown:first-child > box > button.combo, .linked:not(.vertical) > combobox:first-child > box > button.combo { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.linked:not(.vertical) > dropdown:last-child > box > button.combo, .linked:not(.vertical) > combobox:last-child > box > button.combo { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + border-right: 1px solid rgba(0, 0, 0, 0.15); +} + +.linked:not(.vertical) > dropdown:only-child > box > button.combo, .linked:not(.vertical) > combobox:only-child > box > button.combo { + border-radius: 6px; +} + +.linked.vertical > dropdown:first-child > box > button.combo, .linked.vertical > combobox:first-child > box > button.combo { + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} + +.linked.vertical > dropdown:last-child > box > button.combo, .linked.vertical > combobox:last-child > box > button.combo { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; +} + +.linked.vertical > dropdown:only-child > box > button.combo, .linked.vertical > combobox:only-child > box > button.combo { + border-radius: 6px; +} + +searchbar > revealer > box, .toolbar { + padding: 3px 6px; + border-spacing: 6px; +} + +.toolbar separator { + background: none; +} + +.toolbar.horizontal separator { + margin: 0 6px; +} + +.toolbar.vertical separator { + margin: 6px 0; +} + +.toolbar button { + margin: 1px; +} + +.osd .toolbar { + background-color: transparent; +} + +.toolbar.osd { + padding: 6px; + border: none; + border-radius: 10px; + background-color: #1a1a1a; + box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.2), 0 3px 5px 0 rgba(0, 0, 0, 0.15); +} + +.toolbar.osd scalebutton { + margin: 0; +} + +.toolbar.osd.left, .toolbar.osd.right, .toolbar.osd.top, .toolbar.osd.bottom { + border-radius: 0; +} + +.toolbar.osd.top { + border-width: 0 0 1px 0; +} + +.toolbar.osd.bottom { + border-width: 1px 0 0 0; +} + +.toolbar.osd.left { + border-width: 0 1px 0 0; +} + +.toolbar.osd.right { + border-width: 0 0 0 1px; +} + +searchbar:not(.inline) > revealer > box { + border-style: solid; + border-color: #242e31; + background-color: #000a0e; + border-width: 0 0 1px; + box-shadow: none; + color: #FDFDFD; +} + +searchbar > revealer > box { + padding: 6px; + border-spacing: 6px; +} + +searchbar > revealer > box entry { + margin: 0; +} + +searchbar > revealer > box .close { + min-width: 18px; + min-height: 18px; + padding: 4px; + border-radius: 50%; +} + +actionbar > revealer > box { + padding: 6px; + border-spacing: 6px; + border-top: 1px solid rgba(255, 255, 255, 0.12); + background-color: #080f12; + box-shadow: none; +} + +actionbar > revealer > box entry, actionbar > revealer > box button { + margin: 0; +} + +actionbar > revealer > box, actionbar > revealer > box > box.start, actionbar > revealer > box > box.end { + border-spacing: 6px; +} + +headerbar separator.titlebutton { + min-width: 0; + min-height: 0; + background-color: transparent; + border: none; +} + +headerbar separator.titlebutton:backdrop { + opacity: 0.65; +} + +headerbar entry { + color: #FDFDFD; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; +} + +headerbar entry image, headerbar entry image:hover { + color: inherit; +} + +headerbar entry:backdrop { + opacity: 0.65; + background-image: none; +} + +headerbar entry:hover { + color: #FDFDFD; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05), inset 0 0 0 2px transparent; + transition-duration: 200ms; +} + +headerbar entry:focus { + background-image: none; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); +} + +headerbar entry:disabled { + color: rgba(253, 253, 253, 0.35); + background-color: rgba(255, 255, 255, 0.02); +} + +headerbar entry selection:focus { + background-color: #79AAEB; + color: white; +} + +headerbar entry progress { + border-color: #79AAEB; + background-image: none; + background-color: transparent; +} + +headerbar entry.warning { + color: white; + border-color: rgba(255, 255, 255, 0.12); + background-color: #8c5e51; +} + +headerbar entry.warning:focus { + color: white; + background-color: #E9967E; +} + +headerbar entry.warning selection { + background-color: white; + color: #E9967E; +} + +headerbar entry.error { + color: white; + border-color: rgba(255, 255, 255, 0.12); + background-color: #913f45; +} + +headerbar entry.error:focus { + color: white; + background-color: #F16269; +} + +headerbar entry.error selection { + background-color: white; + color: #F16269; +} + +headerbar button { + color: #FDFDFD; + background-color: transparent; + background-image: none; + border: none; + box-shadow: none; +} + +headerbar button:backdrop { + opacity: 0.65; + background-image: none; +} + +headerbar button:hover { + color: #f8f8f8; + background-color: rgba(253, 253, 253, 0.1); + background-image: none; + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +headerbar button:active { + color: #FDFDFD; + background-color: rgba(253, 253, 253, 0.25); + background-image: none; + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-duration: 300ms; +} + +headerbar button:checked { + color: #FDFDFD; + background-color: rgba(253, 253, 253, 0.12); + background-image: none; + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-duration: 300ms; +} + +headerbar button:checked:hover { + background-image: none; +} + +headerbar button:disabled { + background-image: none; + background-color: transparent; + box-shadow: none; +} + +headerbar button:disabled label, headerbar button:disabled { + color: rgba(253, 253, 253, 0.35); +} + +headerbar button.flat { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; +} + +headerbar { + min-height: 42px; + padding: 0 16px; + color: #FDFDFD; + background-color: #000a0e; + border-bottom: 1px solid #000304; + box-shadow: none; + margin: 0; +} + +headerbar:backdrop { + transition: 150ms ease-out; + color: rgba(253, 253, 253, 0.7); + background-color: #000a0e; + border-color: black; + box-shadow: none; +} + +headerbar .title { + padding-left: 12px; + padding-right: 12px; +} + +headerbar .subtitle { + font-size: smaller; + padding-left: 12px; + padding-right: 12px; + margin-top: -3px; +} + +headerbar > windowhandle > box { + padding: 0; +} + +headerbar > windowhandle > box, +headerbar > windowhandle > box > box.start, +headerbar > windowhandle > box > box.end { + border-spacing: 6px; +} + +headerbar button, headerbar spinbutton, headerbar entry, headerbar stackswitcher { + margin-top: 8px; + margin-bottom: 8px; +} + +headerbar menubutton.popup { + margin-top: 0; + margin-bottom: 0; +} + +.linked.raised > headerbar { + border-radius: 6px; + border: none; + box-shadow: none; +} + +.linked.raised > headerbar:disabled { + background: none; +} + +headerbar stackswitcher.linked:not(.vertical) > button { + min-width: 24px; + border-radius: 6px; +} + +headerbar .linked:not(.vertical) > entry { + color: #FDFDFD; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px transparent; + margin: 8px 4px; + padding: 0 12px; + border-radius: 6px; + border: none; +} + +headerbar .linked:not(.vertical) > entry image, headerbar .linked:not(.vertical) > entry image:hover { + color: inherit; +} + +headerbar .linked:not(.vertical) > entry:focus { + border-radius: 6px; + background-image: none; + background-color: rgba(255, 255, 255, 0.05); + box-shadow: inset 0 0 0 2px rgba(188, 212, 245, 0.75); +} + +headerbar .linked:not(.vertical) > entry:disabled { + border-radius: 6px; + color: rgba(253, 253, 253, 0.35); + background-color: rgba(255, 255, 255, 0.02); +} + +headerbar .linked:not(.vertical) > entry:backdrop { + opacity: 0.65; + background-image: none; +} + +headerbar stackswitcher { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); + border-radius: 6px; + padding: 0; +} + +headerbar stackswitcher > button { + margin: 0; + font-weight: 500; +} + +headerbar stackswitcher > button:not(:first-child) { + border-width: 0 0 0 1px; + border-style: none solid none none; + border-radius: 0; + border-image: linear-gradient(to bottom, transparent 16%, rgba(255, 255, 255, 0.1) 16%, rgba(255, 255, 255, 0.1) 84%, transparent 84%) 0 0 0 1/0 0 0 1px stretch; +} + +headerbar stackswitcher > button:checked { + border-image: none; +} + +headerbar stackswitcher button:checked + button { + border-image: none; +} + +headerbar switch { + margin-top: 0; + margin-bottom: 0; +} + +headerbar switch:backdrop { + opacity: 0.75; +} + +headerbar.titlebar headerbar:not(.titlebar) { + background: none; + box-shadow: none; +} + +headerbar windowhandle box.linked > button { + background-color: rgba(255, 255, 255, 0.05); +} + +headerbar windowhandle box.linked > button:hover { + background-color: rgba(255, 255, 255, 0.1); +} + +headerbar windowhandle box.linked > button:active { + background-color: rgba(255, 255, 255, 0.16); +} + +headerbar windowhandle box.linked > button:checked { + background-color: rgba(255, 255, 255, 0.12); +} + +.selection-mode headerbar, headerbar.selection-mode { + color: white; + background-color: #bcd4f5; + border-color: #aac9f2; + box-shadow: none; + background-image: none; + text-shadow: none; +} + +.selection-mode headerbar:backdrop, headerbar.selection-mode:backdrop { + background-color: #bcd4f5; + color: rgba(255, 255, 255, 0.6); + border-color: #aac9f2; +} + +.selection-mode headerbar button, headerbar.selection-mode button { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; +} + +.selection-mode headerbar .selection-menu, headerbar.selection-mode .selection-menu { + box-shadow: none; + padding-left: 10px; + padding-right: 10px; +} + +.selection-mode headerbar .selection-menu .arrow, headerbar.selection-mode .selection-menu .arrow { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +.maximized .selection-mode headerbar, .maximized headerbar.selection-mode { + background-color: #bcd4f5; +} + +.tiled headerbar, .tiled headerbar:backdrop, .maximized headerbar, .maximized headerbar:backdrop { + border-radius: 12px 12px 0 0; + box-shadow: none; +} + +.maximized headerbar { + background-color: #000a0e; + border-color: #000304; + box-shadow: none; +} + +.maximized headerbar:backdrop { + background-color: #000a0e; + border-color: black; +} + +headerbar.default-decoration { + min-height: 32px; + padding: 0 12px; + background-color: #000a0e; +} + +.tiled headerbar.default-decoration, .maximized headerbar.default-decoration, .fullscreen headerbar.default-decoration { + box-shadow: none; +} + +headerbar.default-decoration windowcontrols button, +headerbar.default-decoration windowcontrols menubutton { + border: none; + min-width: 16px; + min-height: 16px; + margin: 0; + padding: 0; +} + +headerbar.default-decoration windowcontrols menubutton button { + min-height: 20px; + min-width: 20px; + margin: 0; + padding: 4px; +} + +.titlebar > box.left.horizontal, +.titlebar > box.right.horizontal { + padding: 0 6px; +} + +window > .titlebar:not(headerbar), window > .titlebar:not(headerbar):backdrop, window.csd > .titlebar:not(headerbar), window.csd > .titlebar:not(headerbar):backdrop { + padding: 0; + background: none; + border: none; + box-shadow: none; +} + +.titlebar:not(headerbar) > separator { + min-width: 1px; +} + +pathbar > button { + min-width: 12px; + min-height: 26px; +} + +pathbar > button.text-button, pathbar > button.image-button, pathbar > button { + padding-left: 6px; + padding-right: 6px; +} + +pathbar > button:hover { + box-shadow: none; +} + +pathbar > button:active, pathbar > button:checked { + background-color: #b8b8b8; + color: rgba(0, 0, 0, 0.75); + border-color: rgba(0, 0, 0, 0.15); +} + +pathbar > button:disabled { + border-color: rgba(0, 0, 0, 0.15); +} + +pathbar > button.text-button.image-button label { + padding-left: 0; + padding-right: 0; +} + +pathbar > button.text-button.image-button label:last-child, pathbar > button label:last-child { + padding-right: 10px; +} + +pathbar > button.text-button.image-button label:first-child, pathbar > button label:first-child { + padding-left: 10px; +} + +pathbar > button.slider-button, pathbar > button:not(.image-button):not(.text-button) { + padding-left: 1px; + padding-right: 1px; +} + +pathbar > button image { + padding-left: 6px; + padding-right: 6px; +} + +columnview.view, +treeview.view { + border-left-color: #242e31; + border-top-color: #242e31; +} + +columnview.view acceleditor > label, +treeview.view acceleditor > label { + background-color: #79AAEB; +} + +columnview.view:selected, columnview.view:selected:focus, +treeview.view:selected, +treeview.view:selected:focus { + border-radius: 0; + border-left-color: #bcd5f5; + border-top-color: rgba(222, 222, 222, 0.15); +} + +columnview.view:disabled, +treeview.view:disabled { + color: rgba(222, 222, 222, 0.35); +} + +columnview.view:disabled:selected, +treeview.view:disabled:selected { + color: #afccf3; +} + +columnview.view.separator, +treeview.view.separator { + min-height: 2px; + color: rgba(255, 255, 255, 0.12); +} + +columnview.view > dndtarget:drop(active), +treeview.view > dndtarget:drop(active) { + border-style: solid none; + border-width: 1px; + border-color: #acc4e5; +} + +columnview.view > dndtarget:drop(active).after, +treeview.view > dndtarget:drop(active).after { + border-top-style: none; +} + +columnview.view > dndtarget:drop(active).before, +treeview.view > dndtarget:drop(active).before { + border-bottom-style: none; +} + +columnview.view.expander, +treeview.view.expander { + min-width: 16px; + min-height: 16px; + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); + color: #72787a; +} + +columnview.view.expander:dir(rtl), +treeview.view.expander:dir(rtl) { + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); +} + +columnview.view.expander:hover, +treeview.view.expander:hover { + color: #dedede; +} + +columnview.view.expander:selected, +treeview.view.expander:selected { + color: #d7e6f9; +} + +columnview.view.expander:selected:hover, +treeview.view.expander:selected:hover { + color: white; +} + +columnview.view.expander:checked, +treeview.view.expander:checked { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +columnview.view.progressbar, +treeview.view.progressbar { + color: white; + border-radius: 6px; + background-color: #79AAEB; +} + +columnview.view.progressbar:selected, columnview.view.progressbar:selected:focus, +treeview.view.progressbar:selected, +treeview.view.progressbar:selected:focus { + color: #79AAEB; + box-shadow: none; + background-color: white; +} + +columnview.view.trough, +treeview.view.trough { + color: #dedede; + background-color: rgba(255, 255, 255, 0.12); + border-radius: 6px; + border-width: 0; +} + +columnview.view.trough:selected, columnview.view.trough:selected:focus, +treeview.view.trough:selected, +treeview.view.trough:selected:focus { + color: white; + background-color: rgba(0, 0, 0, 0.2); + border-radius: 6px; + border-width: 0; +} + +columnview.view > header > button, +treeview.view > header > button { + min-height: 26px; + min-width: 38px; + padding: 0 6px; + font-weight: bold; + color: #b3b5b6; + background-color: #061115; + background-image: none; + box-shadow: none; + border-style: none solid none none; + border-radius: 0; + border-image: linear-gradient(to bottom, #061115 20%, rgba(255, 255, 255, 0.11) 20%, rgba(255, 255, 255, 0.11) 80%, #061115 80%) 0 1 0 0/0 1px 0 0 stretch; +} + +columnview.view > header > button:hover, +treeview.view > header > button:hover { + color: #79AAEB; +} + +columnview.view > header > button:active, +treeview.view > header > button:active { + color: #dedede; +} + +columnview.view > header > button:active, columnview.view > header > button:hover, +treeview.view > header > button:active, +treeview.view > header > button:hover { + background-color: #061115; +} + +columnview.view > header > button:disabled, +treeview.view > header > button:disabled { + border-color: #0d181c; + background-image: none; +} + +columnview.view > header > button:last-child, +treeview.view > header > button:last-child { + border-right-style: none; + border-image: none; +} + +columnview.view button.dnd, columnview.view button.dnd:selected, columnview.view button.dnd:hover, columnview.view button.dnd:active, +columnview.view header.button.dnd, +columnview.view header.button.dnd:selected, +columnview.view header.button.dnd:hover, +columnview.view header.button.dnd:active, +treeview.view button.dnd, +treeview.view button.dnd:selected, +treeview.view button.dnd:hover, +treeview.view button.dnd:active, +treeview.view header.button.dnd, +treeview.view header.button.dnd:selected, +treeview.view header.button.dnd:hover, +treeview.view header.button.dnd:active { + padding: 0 6px; + transition: none; + color: white; + background-color: #79AAEB; + border-radius: 0; + border-style: none; +} + +menubar { + padding: 0; + background-color: #000a0e; + color: #FDFDFD; + box-shadow: inset 0 -1px rgba(255, 255, 255, 0.12); +} + +menubar:backdrop { + color: rgba(253, 253, 253, 0.8); +} + +menubar > item { + transition: all 0.2s cubic-bezier(0, 0, 0.2, 1); + padding: 4px 6px; + border: none; + border-radius: 3px; +} + +menubar > item:hover { + transition: none; + color: #f8f8f8; + background-color: rgba(253, 253, 253, 0.1); + background-image: none; + box-shadow: none; +} + +menubar > item:disabled { + color: rgba(253, 253, 253, 0.4); +} + +menubar > item popover.menu.background > contents { + padding: 6px; + border-radius: 10px; +} + +menubar > item popover.menu popover.menu { + padding: 0 0 6px 0; +} + +menubar > item popover.menu.background popover.menu.background > contents { + margin: 0; + border-radius: 10px; +} + +popover.background { + background-color: transparent; + font: initial; +} + +popover > arrow, +popover > contents { + color: #dedede; + background-clip: border-box; + background-color: #162026; + box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.55); + border: 1px solid #213039; +} + +popover, popover:backdrop { + background-color: transparent; +} + +popover > contents { + padding: 6px; + border-radius: 12px; +} + +popover > contents > list, +popover > contents > .view, +popover > contents > toolbar { + border-style: none; + background-color: transparent; +} + +popover > contents separator { + background-color: rgba(255, 255, 255, 0.08); + margin: 3px; +} + +popover > contents > scrolledwindow > viewport > stack > box { + padding: 0; +} + +popover > contents listview.view { + padding: 0; + margin: 0; +} + +popover > contents listview.view > row { + margin: 0; + padding: 3px 6px; +} + +popover entry { + background-color: #202a2f; +} + +.osd popover, popover.touch-selection, popover.magnifier { + background-color: transparent; +} + +.osd popover > arrow, +.osd popover > contents, popover.touch-selection > arrow, +popover.touch-selection > contents, popover.magnifier > arrow, +popover.magnifier > contents { + border: none; + box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.35); +} + +cursor-handle { + background-color: transparent; + background-image: none; + box-shadow: none; + border-style: none; +} + +cursor-handle.top { + -gtk-icon-source: -gtk-icontheme("selection-start-symbolic"); +} + +cursor-handle.bottom { + -gtk-icon-source: -gtk-icontheme("selection-end-symbolic"); +} + +popover.menu { + padding: 0; +} + +popover.menu box.inline-buttons { + padding: 0 6px; +} + +popover.menu box.inline-buttons button.image-button.model { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + min-height: 28px; + min-width: 28px; + padding: 0; + border: none; + outline: none; + transition: none; +} + +popover.menu box.inline-buttons button.image-button.model:selected { + color: white; + background-image: image(#79AAEB); +} + +popover.menu box.circular-buttons { + padding: 6px; +} + +popover.menu box.circular-buttons button.circular.image-button.model { + padding: 6px; + border: none; +} + +popover.menu box.circular-buttons button.circular.image-button.model:focus { + background-color: rgba(255, 255, 255, 0.1); +} + +popover.menu box.circular-buttons button.circular.image-button.model:active:focus { + color: white; + background-color: #79AAEB; +} + +popover.menu > arrow, popover.menu.background > contents { + background-color: #162026; + color: #dedede; +} + +popover.menu.background separator { + margin: 6px 0; +} + +popover.menu accelerator { + color: alpha(currentColor,0.55); +} + +popover.menu accelerator:dir(ltr) { + margin-left: 6px; +} + +popover.menu accelerator:dir(rtl) { + margin-right: 6px; +} + +popover.menu arrow.left, +popover.menu radio.left, +popover.menu check.left { + margin-left: -2px; + margin-right: 6px; +} + +popover.menu arrow.right, +popover.menu radio.right, +popover.menu check.right { + margin-left: 6px; + margin-right: -2px; +} + +popover.menu modelbutton { + min-height: 22px; + min-width: 88px; + padding: 2px 6px; + border-radius: 7px; + transition: none; + color: #dadada; +} + +popover.menu modelbutton:focus { + background-color: transparent; + color: #dedede; + box-shadow: inset 0 0 0 2px rgba(222, 222, 222, 0.06); + transition: none; +} + +popover.menu modelbutton:hover { + color: white; + background-color: #79AAEB; + transition: background-color 100ms cubic-bezier(0, 0, 0.2, 1); +} + +popover.menu modelbutton:hover:focus { + color: white; + background-color: #79AAEB; + box-shadow: none; +} + +popover.menu modelbutton:selected:active { + color: white; + background-color: #639ce8; + transition: background-color 100ms cubic-bezier(0, 0, 0.2, 1); +} + +popover.menu label.title { + font-weight: bold; + padding: 3px 26px; +} + +tabbar tab, +dnd tab, tabbox > tab, notebook > header > tabs > tab { + color: rgba(222, 222, 222, 0.35); + background-color: rgba(6, 17, 21, 0); + border: none; + transition: all 150ms ease-out; + border-radius: 6px; + padding: 2px 10px; + margin: 0; + box-shadow: none; +} + +tabbar tab:hover:not(:checked), +dnd tab:hover:not(:checked), tabbox > tab:hover:not(:checked), notebook > header > tabs > tab:hover:not(:checked) { + color: rgba(222, 222, 222, 0.675); + background-color: rgba(222, 222, 222, 0.06); + box-shadow: none; +} + +tabbar tab:checked, +dnd tab:checked, tabbox > tab:checked, notebook > header > tabs > tab:checked { + color: #dedede; + background-color: rgba(222, 222, 222, 0.12); + box-shadow: none; +} + +notebook { + padding: 0; +} + +notebook.frame { + border: 1px solid #242e31; +} + +notebook > stack:not(:only-child) { + background-color: #061115; +} + +notebook > header.top { + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +notebook > header.bottom { + border-top: 1px solid rgba(255, 255, 255, 0.12); +} + +notebook > header.right { + border-left: 1px solid rgba(255, 255, 255, 0.12); +} + +notebook > header.left { + border-right: 1px solid rgba(255, 255, 255, 0.12); +} + +notebook > header button.flat.toggle.popup { + min-width: 32px; + border: none; + box-shadow: none; + border-radius: 6px; + padding: 0 3px; + margin-top: -2px; + margin-bottom: -2px; + margin-left: 3px; +} + +notebook > header button.flat.toggle.popup:active, notebook > header button.flat.toggle.popup:checked { + color: #dedede; + background-color: rgba(255, 255, 255, 0.15); +} + +notebook > header.top { + padding: 3px; +} + +notebook > header.top > tabs { + margin: 0; +} + +notebook > header.top > tabs > tab { + outline-offset: -4px; + min-width: 24px; + min-height: 24px; +} + +notebook > header.top > tabs > tab + tab { + margin-left: 3px; +} + +notebook > header.bottom { + padding: 3px; +} + +notebook > header.bottom > tabs { + margin: 0; +} + +notebook > header.bottom > tabs > tab { + outline-offset: -4px; + min-width: 24px; + min-height: 24px; +} + +notebook > header.bottom > tabs > tab + tab { + margin-left: 3px; +} + +notebook > header.right { + padding: 3px; +} + +notebook > header.right > tabs { + margin: 0; +} + +notebook > header.right > tabs > tab { + outline-offset: -4px; + min-width: 24px; + min-height: 24px; +} + +notebook > header.right > tabs > tab + tab { + margin-top: 3px; +} + +notebook > header.left { + padding: 3px; +} + +notebook > header.left > tabs { + margin: 0; +} + +notebook > header.left > tabs > tab { + outline-offset: -4px; + min-width: 24px; + min-height: 24px; +} + +notebook > header.left > tabs > tab + tab { + margin-top: 3px; +} + +notebook > header.top > tabs > arrow.up, notebook > header.bottom > tabs > arrow.up { + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); +} + +notebook > header.top > tabs > arrow.up:last-child, notebook > header.bottom > tabs > arrow.up:last-child { + margin-left: 2px; +} + +notebook > header.top > tabs > arrow.down, notebook > header.bottom > tabs > arrow.down { + -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); +} + +notebook > header.top > tabs > arrow.down:first-child, notebook > header.bottom > tabs > arrow.down:first-child { + margin-right: 2px; +} + +notebook > header.left > tabs > arrow.up, notebook > header.right > tabs > arrow.up { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +notebook > header.left > tabs > arrow.up:last-child, notebook > header.right > tabs > arrow.up:last-child { + margin-top: 2px; +} + +notebook > header.left > tabs > arrow.down, notebook > header.right > tabs > arrow.down { + -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); +} + +notebook > header.left > tabs > arrow.down:first-child, notebook > header.right > tabs > arrow.down:first-child { + margin-bottom: 2px; +} + +notebook > header > tabs > arrow { + color: rgba(222, 222, 222, 0.35); +} + +notebook > header > tabs > arrow:hover { + color: rgba(222, 222, 222, 0.675); +} + +notebook > header > tabs > arrow:active { + color: #dedede; +} + +notebook > header > tabs > arrow:disabled { + color: rgba(222, 222, 222, 0.05); +} + +notebook > header > tabs > tab button.flat, +notebook > header > tabs > tab button.close-button, +notebook > header > tabs > tab button.image-button.flat { + border-radius: 3px; + padding: 0; + color: #95999a; + margin-left: 3px; + margin-right: -6px; + min-height: 16px; + min-width: 16px; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 3px; + margin-right: -3px; +} + +notebook > header > tabs > tab button.flat:hover, +notebook > header > tabs > tab button.close-button:hover, +notebook > header > tabs > tab button.image-button.flat:hover { + color: #dedede; + background-color: rgba(255, 255, 255, 0.1); +} + +notebook > header > tabs > tab button.flat:active, +notebook > header > tabs > tab button.close-button:active, +notebook > header > tabs > tab button.image-button.flat:active { + color: #f8f8f8; + background-color: rgba(255, 255, 255, 0.2); +} + +tabbox { + background-color: #000a0e; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); + padding: 0 3px 3px; +} + +tabbox > tab + tab { + margin-left: 3px; +} + +tabbox > tab button.tab-close-button { + border-radius: 3px; + border: none; + padding: 0; + min-height: 16px; + min-width: 16px; + margin-top: 4px; + margin-bottom: 4px; + margin-right: -6px; +} + +tabbox > tab button.tab-close-button:hover { + color: #dedede; + background-color: rgba(255, 255, 255, 0.1); +} + +tabbox > tab button.tab-close-button:active, tabbox > tab button.tab-close-button:active:hover { + color: #f8f8f8; + background-color: rgba(255, 255, 255, 0.2); +} + +scrollbar { + background-color: transparent; + transition: 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + outline: none; +} + +scrollbar, scrollbar button { + border: none; +} + +scrollbar.vertical button.down { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +scrollbar.vertical button.up { + -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); +} + +scrollbar.horizontal button.down { + -gtk-icon-source: -gtk-icontheme("pan-right-symbolic"); +} + +scrollbar.horizontal button.up { + -gtk-icon-source: -gtk-icontheme("pan-left-symbolic"); +} + +scrollbar > range > trough { + background: none; + padding: 0; + margin: 0; + border: none; + outline: none; + transition: none; +} + +scrollbar > range > trough > slider { + min-width: 4px; + min-height: 4px; + margin: -1px; + border: 4px solid transparent; + border-radius: 12px; + background-clip: padding-box; + background-color: #61676a; + box-shadow: none; + outline: none; + transition: all 200ms linear; +} + +scrollbar > range > trough > slider:hover { + background-color: #4c5356; +} + +scrollbar > range > trough > slider:hover:active { + background-color: #767b7d; +} + +scrollbar > range > trough > slider:disabled { + background-color: transparent; +} + +scrollbar > range.fine-tune > trough > slider { + min-width: 4px; + min-height: 4px; +} + +scrollbar > range.fine-tune.horizontal > trough > slider { + border-width: 5px 4px; +} + +scrollbar > range.fine-tune.vertical > trough > slider { + border-width: 4px 5px; +} + +scrollbar.overlay-indicator { + background: none; + color: inherit; + box-shadow: none; + padding: 0; +} + +scrollbar.overlay-indicator > range > trough { + outline: none; + background: none; +} + +scrollbar.overlay-indicator > range > trough > slider { + outline: none; +} + +scrollbar.overlay-indicator:not(.dragging):not(.hovering) { + opacity: 0.4; + border-color: transparent; + background-color: transparent; + box-shadow: none; +} + +scrollbar.overlay-indicator:not(.dragging):not(.hovering) > range > trough > slider { + margin: 0; + min-width: 4px; + min-height: 4px; + background-color: #9fa3a4; + border: none; +} + +scrollbar.overlay-indicator:not(.dragging):not(.hovering).horizontal > range > trough > slider { + margin: 0 3px; + min-width: 40px; +} + +scrollbar.overlay-indicator:not(.dragging):not(.hovering).vertical > range > trough > slider { + margin: 3px 0; + min-height: 40px; +} + +scrollbar.overlay-indicator.dragging, scrollbar.overlay-indicator.hovering { + opacity: 0.99; +} + +scrollbar.horizontal > range > trough > slider { + min-width: 40px; +} + +scrollbar.vertical > range > trough > slider { + min-height: 40px; +} + +@keyframes switch_ripple_effect { + from { + background-image: linear-gradient(0deg, rgba(222, 222, 222, 0.25) 0%, rgba(222, 222, 222, 0.35) 100%), radial-gradient(circle farthest-corner at center, transparent 0%, transparent 0%); + } + to { + background-image: linear-gradient(0deg, #a5c6f2 0%, #79AAEB 100%), radial-gradient(circle farthest-corner at center, rgba(121, 170, 235, 0.75) 100%, rgba(121, 170, 235, 0) 0%); + } +} + +switch { + transition: all 150ms cubic-bezier(0, 0, 0.2, 1); + border-radius: 9999px; + background-color: transparent; + background-clip: padding-box; + color: transparent; + min-width: 40px; + min-height: 24px; + font-size: 0; + padding: 0; + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + background-image: linear-gradient(0deg, rgba(222, 222, 222, 0.25) 0%, rgba(222, 222, 222, 0.35) 100%), radial-gradient(circle farthest-corner at center, transparent 0%, transparent 0%); +} + +switch:disabled { + color: transparent; + background-color: transparent; + background-image: linear-gradient(0deg, rgba(222, 222, 222, 0.1) 0%, rgba(222, 222, 222, 0.15) 100%); +} + +switch:checked { + animation: switch_ripple_effect 0.3s cubic-bezier(0, 0, 0.2, 1); + background-color: transparent; + color: transparent; + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); + transition: background-image 0.3s, box-shadow 0; + background-image: linear-gradient(0deg, #a5c6f2 0%, #79AAEB 100%), radial-gradient(circle farthest-corner at center, rgba(121, 170, 235, 0.75) 100%, transparent 0%); +} + +switch:checked:disabled { + background-color: transparent; + background-image: linear-gradient(0deg, white 0%, #e8f0fc 100%); + color: transparent; +} + +switch > slider { + transition: all 150ms cubic-bezier(0, 0, 0.2, 1), box-shadow 150ms cubic-bezier(0, 0, 0.2, 1), margin 0; + min-width: 22px; + min-height: 22px; + margin: 1px 0 1px 1px; + padding: 0; + border-radius: 9999px; + background-color: white; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); +} + +switch, switch > slider { + outline-color: transparent; + color: transparent; + border: none; +} + +switch:hover > slider { + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15), 0 2px 3px 0 rgba(0, 0, 0, 0.1); +} + +switch:checked > slider { + margin: 1px 1px 1px 0; + background-color: white; +} + +switch:checked:disabled > slider { + animation: none; +} + +.view.content-view.check:not(list), +.content-view .tile check:not(list) { + min-height: 40px; + min-width: 40px; + margin: 0; + padding: 0; +} + +checkbutton.text-button, radiobutton.text-button { + padding: 2px 0; + outline-offset: 0; +} + +checkbutton.text-button:hover, radiobutton.text-button:hover { + color: #b8b8b8; +} + +checkbutton.text-button:disabled, radiobutton.text-button:disabled { + color: rgba(222, 222, 222, 0.35); +} + +checkbutton label:not(:only-child):first-child, radiobutton label:not(:only-child):first-child { + margin-left: 4px; +} + +checkbutton label:not(:only-child):last-child, radiobutton label:not(:only-child):last-child { + margin-right: 4px; +} + +check, +radio { + min-width: 14px; + min-height: 14px; + margin: 3px; + padding: 0; + color: transparent; + background-color: #061115; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + background-clip: padding-box; + border: none; + -gtk-icon-size: 14px; + background-image: linear-gradient(0deg, #6a6a6a 0%, #545454 100%); + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 1px 2px rgba(0, 0, 0, 0.25); +} + +check:hover, +radio:hover { + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); +} + +check:active, +radio:active { + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); +} + +check:disabled, +radio:disabled { + background-image: none; + background-color: rgba(255, 255, 255, 0.08); + box-shadow: none; +} + +check:checked, check:indeterminate, +radio:checked, +radio:indeterminate { + color: white; + background-color: #79AAEB; + background-image: linear-gradient(0deg, #639ce8 0%, #8fb8ee 100%); +} + +check:checked:hover, check:indeterminate:hover, +radio:checked:hover, +radio:indeterminate:hover { + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); +} + +check:checked:active, check:indeterminate:active, +radio:checked:active, +radio:indeterminate:active { + background-color: #79AAEB; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); +} + +check:checked:disabled, check:indeterminate:disabled, +radio:checked:disabled, +radio:indeterminate:disabled { + color: rgba(175, 175, 175, 0.35); + background-image: none; + background-color: rgba(255, 255, 255, 0.08); + box-shadow: none; +} + + +check { + border-radius: 3px; +} + + +check:checked { + -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/scalable/checkbox-checked-symbolic.svg")), -gtk-recolor(url("assets/scalable/checkbox-checked-symbolic@2.svg"))); +} + + +check:indeterminate { + -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/scalable/checkbox-mixed-symbolic.svg")), -gtk-recolor(url("assets/scalable/checkbox-mixed-symbolic@2.svg"))); +} + + +radio { + border-radius: 9999px; +} + + +radio:checked { + -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/scalable/radio-checked-symbolic.svg")), -gtk-recolor(url("assets/scalable/radio-checked-symbolic@2.svg"))); +} + + +radio:indeterminate { + -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/scalable/radio-mixed-symbolic.svg")), -gtk-recolor(url("assets/scalable/radio-mixed-symbolic@2.svg"))); +} + +scale { + min-height: 15px; + min-width: 15px; + padding: 3px; +} + +scale > trough > slider { + min-height: 15px; + min-width: 15px; + margin: -7px; +} + +scale.fine-tune > trough > slider { + margin: -4px; +} + +scale.fine-tune > trough > fill, +scale.fine-tune > trough > highlight, +scale.fine-tune > trough { + border-radius: 5px; +} + +scale > trough { + outline-offset: 2px; + border-radius: 6px; + background-color: rgba(0, 0, 0, 0.2); +} + +scale > trough:disabled { + background-color: rgba(0, 0, 0, 0.12); +} + +.osd scale > trough { + background-color: rgba(0, 0, 0, 0.2); +} + +.osd scale > trough highlight { + background-color: #79AAEB; +} + +modelbutton:hover scale > trough, row:selected scale > trough, infobar scale > trough { + background-color: rgba(0, 0, 0, 0.2); +} + +modelbutton:hover scale > trough > trough > highlight, row:selected scale > trough > trough > highlight, infobar scale > trough > trough > highlight { + background-color: white; +} + +modelbutton:hover scale > trough > trough > highlight:disabled, row:selected scale > trough > trough > highlight:disabled, infobar scale > trough > trough > highlight:disabled { + background-color: #c3d9f6; +} + +modelbutton:hover scale > trough:disabled, row:selected scale > trough:disabled, infobar scale > trough:disabled { + background-color: rgba(0, 0, 0, 0.1); +} + +scale > trough > highlight { + border-radius: 6px; + background-color: #79AAEB; +} + +scale > trough > highlight:disabled { + background-color: rgba(121, 170, 235, 0.55); +} + +scale > trough > fill { + border-radius: 6px; + background-color: rgba(121, 170, 235, 0.5); +} + +scale > trough > fill:disabled { + background-color: transparent; +} + +scale > trough > slider { + background-color: white; + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 100%; + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.05); + background-clip: padding-box; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition-property: background, border; + outline: none; +} + +scale > trough > slider:hover { + background-color: white; + border-color: rgba(255, 255, 255, 0.12); + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1), 0 2px 2px 0 rgba(0, 0, 0, 0.05); +} + +scale > trough > slider:active { + background-color: white; + border-color: rgba(255, 255, 255, 0.12); + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +scale > trough > slider:disabled { + background-color: #f2f2f2; + border-color: rgba(242, 242, 242, 0.12); + box-shadow: none; +} + +modelbutton:hover scale > trough > slider, row:selected scale > trough > slider, infobar scale > trough > slider { + background-color: white; + border-color: white; +} + +modelbutton:hover scale > trough > slider:hover, row:selected scale > trough > slider:hover, infobar scale > trough > slider:hover { + background-color: #ebf2fc; + border-color: #ebf2fc; +} + +modelbutton:hover scale > trough > slider:active, row:selected scale > trough > slider:active, infobar scale > trough > slider:active { + background-color: #bcd5f5; + border-color: #bcd5f5; +} + +modelbutton:hover scale > trough > slider:disabled, row:selected scale > trough > slider:disabled, infobar scale > trough > slider:disabled { + background-color: #c3d9f6; + border-color: #c3d9f6; +} + +.osd scale > trough > slider { + background-color: white; + border-color: rgba(255, 255, 255, 0.12); +} + +.osd scale > trough > slider:hover { + background-color: white; + border-color: rgba(255, 255, 255, 0.12); + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1), 0 2px 2px 0 rgba(0, 0, 0, 0.05); +} + +.osd scale > trough > slider:active { + background-color: #f7f7f7; + border-color: rgba(255, 255, 255, 0.12); + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +scale > value { + color: alpha(currentColor,0.4); +} + +scale > marks { + color: alpha(currentColor,0.4); +} + +scale > marks.top { + margin-bottom: 1px; + margin-top: -4px; +} + +scale > marks.bottom { + margin-top: 1px; + margin-bottom: -4px; +} + +scale > marks.top { + margin-right: 1px; + margin-left: -4px; +} + +scale > marks.bottom { + margin-left: 1px; + margin-right: -4px; +} + +scale.fine-tune > marks.top { + margin-bottom: 0px; + margin-top: -2px; +} + +scale.fine-tune > marks.bottom { + margin-top: 0px; + margin-bottom: -2px; +} + +scale.fine-tune > marks.top { + margin-right: 0px; + margin-left: -2px; +} + +scale.fine-tune > marks.bottom { + margin-left: 0px; + margin-right: -2px; +} + +scale.horizontal indicator { + min-height: 3px; + min-width: 1px; +} + +scale.horizontal.fine-tune indicator { + min-height: 2px; +} + +scale.vertical indicator { + min-height: 1px; + min-width: 3px; +} + +scale.vertical.fine-tune indicator { + min-width: 2px; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above.png"), url("assets/slider-horz-scale-has-marks-above@2.png")); + min-height: 26px; + min-width: 24px; + margin-top: -14px; + background-position: top; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-top: -11px; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.horizontal.marks-before:not(.marks-after) slider:hover { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-hover.png"), url("assets/slider-horz-scale-has-marks-above-hover@2.png")); + min-height: 26px; + min-width: 24px; + margin-top: -14px; + background-position: top; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-top: -11px; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.horizontal.marks-before:not(.marks-after) slider:active { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-active.png"), url("assets/slider-horz-scale-has-marks-above-active@2.png")); + min-height: 26px; + min-width: 24px; + margin-top: -14px; + background-position: top; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-top: -11px; +} + +scale.horizontal.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.horizontal.marks-before:not(.marks-after) slider:disabled { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-insensitive.png"), url("assets/slider-horz-scale-has-marks-above-insensitive@2.png")); + min-height: 26px; + min-width: 24px; + margin-top: -14px; + background-position: top; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-top: -11px; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below.png"), url("assets/slider-horz-scale-has-marks-below@2.png")); + min-height: 26px; + min-width: 24px; + margin-bottom: -14px; + background-position: bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-bottom: -11px; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.horizontal.marks-after:not(.marks-before) slider:hover { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-hover.png"), url("assets/slider-horz-scale-has-marks-below-hover@2.png")); + min-height: 26px; + min-width: 24px; + margin-bottom: -14px; + background-position: bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-bottom: -11px; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.horizontal.marks-after:not(.marks-before) slider:active { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-active.png"), url("assets/slider-horz-scale-has-marks-below-active@2.png")); + min-height: 26px; + min-width: 24px; + margin-bottom: -14px; + background-position: bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-bottom: -11px; +} + +scale.horizontal.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.horizontal.marks-after:not(.marks-before) slider:disabled { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-insensitive.png"), url("assets/slider-horz-scale-has-marks-below-insensitive@2.png")); + min-height: 26px; + min-width: 24px; + margin-bottom: -14px; + background-position: bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.horizontal.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-bottom: -11px; +} + +scale.vertical.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.vertical.marks-before:not(.marks-after) slider { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above.png"), url("assets/slider-vert-scale-has-marks-above@2.png")); + min-height: 24px; + min-width: 26px; + margin-left: -14px; + background-position: left bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-left: -11px; +} + +scale.vertical.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.vertical.marks-before:not(.marks-after) slider:hover { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-hover.png"), url("assets/slider-vert-scale-has-marks-above-hover@2.png")); + min-height: 24px; + min-width: 26px; + margin-left: -14px; + background-position: left bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-left: -11px; +} + +scale.vertical.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.vertical.marks-before:not(.marks-after) slider:active { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-active.png"), url("assets/slider-vert-scale-has-marks-above-active@2.png")); + min-height: 24px; + min-width: 26px; + margin-left: -14px; + background-position: left bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-left: -11px; +} + +scale.vertical.marks-before:not(.marks-after) slider { + transform: none; +} + +scale.vertical.marks-before:not(.marks-after) slider:disabled { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-insensitive.png"), url("assets/slider-vert-scale-has-marks-above-insensitive@2.png")); + min-height: 24px; + min-width: 26px; + margin-left: -14px; + background-position: left bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-before:not(.marks-after).fine-tune slider { + margin: -7px; + margin-left: -11px; +} + +scale.vertical.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.vertical.marks-after:not(.marks-before) slider { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below.png"), url("assets/slider-vert-scale-has-marks-below@2.png")); + min-height: 24px; + min-width: 26px; + margin-right: -14px; + background-position: right bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-right: -11px; +} + +scale.vertical.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.vertical.marks-after:not(.marks-before) slider:hover { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-hover.png"), url("assets/slider-vert-scale-has-marks-below-hover@2.png")); + min-height: 24px; + min-width: 26px; + margin-right: -14px; + background-position: right bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-right: -11px; +} + +scale.vertical.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.vertical.marks-after:not(.marks-before) slider:active { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-active.png"), url("assets/slider-vert-scale-has-marks-below-active@2.png")); + min-height: 24px; + min-width: 26px; + margin-right: -14px; + background-position: right bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-right: -11px; +} + +scale.vertical.marks-after:not(.marks-before) slider { + transform: none; +} + +scale.vertical.marks-after:not(.marks-before) slider:disabled { + margin: -10px; + border-style: none; + border-radius: 0; + background-color: transparent; + background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-insensitive.png"), url("assets/slider-vert-scale-has-marks-below-insensitive@2.png")); + min-height: 24px; + min-width: 26px; + margin-right: -14px; + background-position: right bottom; + background-repeat: no-repeat; + box-shadow: none; +} + +scale.vertical.marks-after:not(.marks-before).fine-tune slider { + margin: -7px; + margin-right: -11px; +} + +progressbar { + padding: 0; + font-size: smaller; + color: rgba(222, 222, 222, 0.7); + font-feature-settings: "tnum"; +} + +progressbar.horizontal > trough { + min-width: 150px; +} + +progressbar.horizontal > trough, progressbar.horizontal > trough > progress { + min-height: 4px; + border-radius: 2px; +} + +progressbar.vertical > trough { + min-height: 80px; +} + +progressbar.vertical > trough, progressbar.vertical > trough > progress { + min-width: 4px; + border-radius: 2px; +} + +progressbar.osd { + min-width: 3px; + min-height: 3px; + background-color: transparent; +} + +progressbar.osd > trough { + border-style: none; + background-color: transparent; + box-shadow: none; +} + +progressbar.osd > progress { + border-style: none; + border-radius: 0; +} + +progressbar > trough > progress { + background-color: #79AAEB; + border: none; + border-radius: 6px; + box-shadow: none; +} + +row:selected progressbar > trough > progress, infobar progressbar > trough > progress { + background-color: white; +} + +progressbar > trough { + min-height: 4px; + min-width: 4px; + border: none; + border-radius: 6px; + background-color: #05090b; +} + +row:selected progressbar > trough, infobar progressbar > trough { + background-color: rgba(0, 0, 0, 0.2); +} + +levelbar block { + min-width: 32px; + min-height: 1px; +} + +levelbar.vertical block { + min-width: 1px; + min-height: 32px; +} + +levelbar trough { + border: none; + padding: 3px; + border-radius: 6px; + background-color: #05090b; +} + +levelbar.horizontal.discrete block { + margin: 0 1px; +} + +levelbar.vertical.discrete block { + margin: 1px 0; +} + +levelbar block:not(.empty) { + border: 1px solid #79AAEB; + background-color: #79AAEB; + border-radius: 6px; +} + +levelbar block.low { + border-color: #E9967E; + background-color: #E9967E; +} + +levelbar block.high { + border-color: #79AAEB; + background-color: #79AAEB; +} + +levelbar block.full { + border-color: #8CD7AA; + background-color: #8CD7AA; +} + +levelbar block.empty { + background-color: #061115; + border-color: #061115; +} + +window.dialog.print drawing { + color: #dedede; + background: none; + border: none; + padding: 0; +} + +window.dialog.print drawing paper { + border: 1px solid rgba(255, 255, 255, 0.12); + background: #061115; + padding: 0; +} + +window.dialog.print .dialog-action-box { + margin: 12px; +} + +frame, +.frame { + border: 1px solid rgba(255, 255, 255, 0.12); +} + +frame > list, +.frame > list { + border: none; +} + +frame { + border-radius: 12px; +} + +frame > label { + margin: 4px; +} + +frame > list { + border-radius: 10px; + box-shadow: inset 0 0 8px rgba(255, 255, 255, 0.03), inset 0 0 3px rgba(255, 255, 255, 0.02); +} + +scrolledwindow viewport.frame { + border: none; +} + +scrolledwindow viewport.frame .frame { + border: none; +} + +scrolledwindow viewport.frame .frame > textview { + border-radius: 6px; + background: none; +} + +scrolledwindow viewport.frame .frame > textview > text { + border-radius: 6px; + border: 1px solid rgba(255, 255, 255, 0.12); +} + +scrolledwindow viewport.frame > box.vertical list.content.view { + border-top-left-radius: 12px; + border-top-right-radius: 12px; +} + +scrolledwindow viewport.frame > box.vertical list.frame { + padding: 0; +} + +scrolledwindow viewport.frame > box.vertical list.frame list { + border: none; + box-shadow: none; + border-radius: 0; + margin: 0; + background: none; +} + +scrolledwindow viewport.frame > box.vertical list.frame list > row.activatable, scrolledwindow viewport.frame > box.vertical list.frame list > row.activatable:first-child, scrolledwindow viewport.frame > box.vertical list.frame list > row.activatable:last-child { + border-radius: 0; +} + +scrolledwindow > overshoot.top { + background-image: radial-gradient(farthest-side at top, alpha(currentColor,0.12) 85%, alpha(currentColor,0)), radial-gradient(farthest-side at top, alpha(currentColor,0.05), alpha(currentColor,0)); + background-size: 100% 3%, 100% 50%; + background-repeat: no-repeat; + background-position: top; + background-color: transparent; + border: none; + box-shadow: none; +} + +scrolledwindow > overshoot.bottom { + background-image: radial-gradient(farthest-side at bottom, alpha(currentColor,0.12) 85%, alpha(currentColor,0)), radial-gradient(farthest-side at bottom, alpha(currentColor,0.05), alpha(currentColor,0)); + background-size: 100% 3%, 100% 50%; + background-repeat: no-repeat; + background-position: bottom; + background-color: transparent; + border: none; + box-shadow: none; +} + +scrolledwindow > overshoot.left { + background-image: radial-gradient(farthest-side at left, alpha(currentColor,0.12) 85%, alpha(currentColor,0)), radial-gradient(farthest-side at left, alpha(currentColor,0.05), alpha(currentColor,0)); + background-size: 3% 100%, 50% 100%; + background-repeat: no-repeat; + background-position: left; + background-color: transparent; + border: none; + box-shadow: none; +} + +scrolledwindow > overshoot.right { + background-image: radial-gradient(farthest-side at right, alpha(currentColor,0.12) 85%, alpha(currentColor,0)), radial-gradient(farthest-side at right, alpha(currentColor,0.05), alpha(currentColor,0)); + background-size: 3% 100%, 50% 100%; + background-repeat: no-repeat; + background-position: right; + background-color: transparent; + border: none; + box-shadow: none; +} + +scrolledwindow > junction { + border-style: solid none none solid; + border-width: 1px; + border-color: rgba(255, 255, 255, 0.12); + background-color: #071419; +} + +scrolledwindow > junction:dir(rtl) { + border-style: solid solid none none; +} + +separator { + background-color: rgba(255, 255, 255, 0.12); + min-width: 1px; + min-height: 1px; +} + +separator.spacer { + background: none; +} + +separator.spacer.horizontal { + min-width: 12px; +} + +separator.spacer.vertical { + min-height: 12px; +} + +listview, +list { + background-color: #061115; + border-color: rgba(255, 255, 255, 0.12); + background-clip: padding-box; + color: #dedede; +} + +listview > row, +list > row { + background-clip: padding-box; +} + +listview > row.expander, +list > row.expander { + padding: 0; +} + +listview > row.expander .row-header, +list > row.expander .row-header { + padding: 3px; +} + +listview.horizontal row.separator, listview.separators.horizontal > row:not(.separator), +list.horizontal row.separator, +list.separators.horizontal > row:not(.separator) { + border-left: 1px solid rgba(255, 255, 255, 0.12); +} + +listview:not(.horizontal) row.separator, listview.separators:not(.horizontal) > row:not(.separator), +list:not(.horizontal) row.separator, +list.separators:not(.horizontal) > row:not(.separator) { + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +listview.boxed-list > row.expander list, +list.boxed-list > row.expander list { + background-color: transparent; + box-shadow: none; + border: none; +} + +listview.view { + color: #dedede; + background-color: transparent; +} + +row.has-open-popup.activatable, row.activatable:hover { + background-color: rgba(255, 255, 255, 0.05); +} + +row.activatable:active { + color: #dedede; + background-color: rgba(255, 255, 255, 0.2); + transition-duration: 200ms; +} + +row.activatable:disabled { + color: rgba(222, 222, 222, 0.35); +} + +row.activatable:disabled image { + color: inherit; +} + +row.activatable:selected { + color: #dedede; + background-color: rgba(255, 255, 255, 0.15); +} + +row.activatable:selected label { + color: #dedede; +} + +row.activatable:selected.has-open-popup, row.activatable:selected:hover { + background-color: rgba(255, 255, 255, 0.2); +} + +row { + background-clip: padding-box; +} + +row label.subtitle { + font-size: smaller; +} + +row > box.header { + margin-left: 12px; + margin-right: 12px; + min-height: 44px; +} + +row > box.header > .icon:disabled { + filter: opacity(0.45); +} + +row > box.header > box.title { + margin-top: 6px; + margin-bottom: 6px; + border-spacing: 3px; +} + +row:not(:hover) { + transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +row:selected { + color: #dedede; + background-color: rgba(255, 255, 255, 0.15); +} + +row:selected label { + color: #dedede; +} + +row.combo image.dropdown-arrow:disabled { + filter: opacity(0.45); +} + +row.combo listview.inline { + background: none; + border: none; + box-shadow: none; + color: inherit; +} + +row.combo listview.inline, row.combo listview.inline:disabled { + background: none; + color: inherit; +} + +row.combo popover > contents { + min-width: 120px; +} + +columnview > listview > row { + padding: 0; +} + +columnview > listview > row > cell { + padding: 8px 6px; +} + +columnview > listview > row > cell:not(:first-child) { + border-left: 1px solid transparent; +} + +columnview.column-separators > listview > row > cell { + border-left-color: rgba(255, 255, 255, 0.12); +} + +columnview.data-table > listview > row > cell { + padding-top: 2px; + padding-bottom: 2px; +} + +treeexpander { + border-spacing: 6px; +} + +columnview row:not(:selected) cell editablelabel:not(.editing):focus-within { + outline: 2px solid rgba(255, 255, 255, 0.12); +} + +columnview row:not(:selected) cell editablelabel.editing:focus-within { + outline: 2px solid #79AAEB; +} + +columnview row:not(:selected) cell editablelabel.editing text selection { + color: white; + background-color: #79AAEB; +} + +.rich-list { + /* rich lists usually containing other widgets than just labels/text */ +} + +.rich-list > row { + padding: 8px 12px; + min-height: 32px; + /* should be tall even when only containing a label */ +} + +.rich-list > row > box { + border-spacing: 12px; +} + +.app-notification { + padding: 6px; + margin: 6px 16px 16px 16px; + color: #dedede; + background-color: rgba(0, 10, 14, 0.85); + border-radius: 12px; + border: none; + box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.25), inset 0 0 0 1px rgba(255, 255, 255, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.75); +} + +.app-notification border { + border: none; +} + +.app-notification button { + min-height: 22px; + padding: 2px 8px; +} + +.app-notification button:hover { + color: #c5c5c5; + background-color: rgba(255, 255, 255, 0.15); + background-image: none; + box-shadow: none; +} + +.app-notification button:active, .app-notification button:checked { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.25); +} + +.app-notification button:disabled { + background-color: transparent; +} + +.app-notification button:disabled label, .app-notification button:disabled { + color: rgba(222, 222, 222, 0.35); +} + +expander { + min-width: 16px; + min-height: 16px; + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); +} + +expander:dir(rtl) { + -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); +} + +expander:hover { + color: white; +} + +expander:checked { + -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); +} + +expander:disabled { + filter: opacity(0.45); +} + +expander-widget > box > title { + border-radius: 6px; +} + +expander-widget > box > title > expander { + opacity: .7; +} + +expander-widget > box > title:hover > expander { + opacity: 1; +} + +.navigation-sidebar:not(decoration):not(window):drop(active):focus, .navigation-sidebar:not(decoration):not(window):drop(active), +placessidebar:not(decoration):not(window):drop(active):focus, +placessidebar:not(decoration):not(window):drop(active), +stackswitcher:not(decoration):not(window):drop(active):focus, +stackswitcher:not(decoration):not(window):drop(active), +expander-widget:not(decoration):not(window):drop(active):focus, +expander-widget:not(decoration):not(window):drop(active) { + box-shadow: none; +} + + +calendar { + color: #dedede; + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 6px; + padding: 2px 6px; + margin: 0; +} + + +calendar > header { + color: #dedede; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + + +calendar > header > button { + border: none; + box-shadow: none; + background: none; + border-radius: 0; +} + + +calendar > header > button:hover { + background-color: rgba(222, 222, 222, 0.1); +} + + +calendar > header > button:active { + background-color: #79AAEB; +} + + +calendar > header > button:backdrop { + background: none; +} + + +calendar > grid > label.today { + background-color: rgba(222, 222, 222, 0.15); + border-radius: 3px; +} + + +calendar > grid > label.today:selected { + box-shadow: none; +} + + +calendar > grid > label:focus { + outline-style: none; +} + + +calendar > grid > label.day-number { + padding: 4px; +} + + +calendar > grid > label.day-number:selected { + border-radius: 6px; +} + + +calendar > grid > label.day-number.other-month { + color: alpha(currentColor,0.3); +} + +window.dialog.message.background { + background-color: #0d181c; +} + +window.dialog.message .titlebar { + min-height: 28px; + background-color: #0d181c; + border: none; +} + +window.dialog.message box.dialog-vbox.vertical { + border-spacing: 10px; +} + +window.dialog.message label.title { + font-weight: 800; + font-size: 15pt; +} + +window.dialog.message .dialog-action-area { + padding: 6px; +} + +window.dialog.message .dialog-action-area > button { + min-height: 20px; + padding: 4px 8px; + box-shadow: none; + border-radius: 6px; + margin: 0 3px 3px 3px; + border: none; +} + +window.dialog.message .dialog-action-area > button:not(.suggested-action):not(.destructive-action) { + border-radius: 6px; + background-color: transparent; +} + +window.dialog.message .dialog-action-area > button:not(.suggested-action):not(.destructive-action):hover { + color: #c5c5c5; + background-color: rgba(255, 255, 255, 0.15); + background-image: none; + box-shadow: none; + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +window.dialog.message .dialog-action-area > button:not(.suggested-action):not(.destructive-action):active { + color: white; + background-color: #79AAEB; + border-color: rgba(0, 0, 0, 0.15); +} + +window.dialog.message .dialog-action-area > button.suggested-action, window.dialog.message .dialog-action-area > button.destructive-action { + border-radius: 6px; +} + +window.dialog.message.csd.background { + border-bottom-left-radius: 12px; + border-bottom-right-radius: 12px; + border: none; +} + +window.dialog.message.csd.background, window.dialog.message.csd .titlebar { + background-color: #0d181c; +} + +window.aboutdialog image.large-icons { + -gtk-icon-size: 128px; +} + +filechooser paned.horizontal > separator { + background-image: image(#000304); +} + +filechooser #pathbarbox { + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +filechooserbutton > button > box { + border-spacing: 6px; +} + +filechooserbutton:drop(active) { + box-shadow: none; + border-color: transparent; +} + +.sidebar:dir(ltr), .sidebar.left, .sidebar.left:dir(rtl) { + border-right: 1px solid #000304; + border-left-style: none; +} + +.sidebar:dir(rtl), .sidebar.right { + border-left: 1px solid #000304; + border-right-style: none; +} + +.sidebar { + border-style: none; + background-color: #0d181c; +} + +.sidebar list { + background-color: transparent; +} + +.sidebar list > separator { + min-height: 0; + background: none; + border: none; +} + +paned .sidebar.left, paned .sidebar.right, paned .sidebar.left:dir(rtl), paned .sidebar:dir(rtl), paned .sidebar:dir(ltr), paned .sidebar { + border: none; +} + +separator.sidebar { + background-color: #000304; + min-height: 1px; + min-width: 1px; +} + +separator.sidebar.left, separator.sidebar.right, separator.sidebar.left:dir(rtl), separator.sidebar:dir(rtl), separator.sidebar:dir(ltr), separator.sidebar { + border: none; +} + +stacksidebar list.separators:not(.horizontal) > row:not(.separator) { + border-bottom: none; +} + +stacksidebar row { + padding: 4px; +} + +stacksidebar row > label { + padding-left: 6px; + padding-right: 6px; +} + +stacksidebar row.needs-attention > label { + background-size: 6px 6px, 0 0; +} + +.navigation-sidebar { + padding: 6px 0; +} + +.navigation-sidebar > separator { + margin: 6px 0; +} + +.navigation-sidebar > row { + min-height: 36px; + padding: 0 8px; + border-radius: 6px; + margin: 0 6px 2px; +} + +.navigation-sidebar > row:hover, .navigation-sidebar > row:focus-visible:focus-within { + background-color: rgba(222, 222, 222, 0.1); +} + +.navigation-sidebar > row:active { + color: #dedede; + background-color: rgba(222, 222, 222, 0.2); +} + +.navigation-sidebar > row:selected { + color: #dedede; + background-color: rgba(222, 222, 222, 0.15); +} + +.navigation-sidebar > row:selected label { + color: #dedede; +} + +.navigation-sidebar > row:selected:hover { + background-color: rgba(222, 222, 222, 0.2); +} + +.navigation-sidebar > row:selected:focus-visible:focus-within { + outline-width: 0; + color: white; + background-color: #79AAEB; +} + +.navigation-sidebar > row:selected:focus-visible:focus-within:hover { + background-color: #4d8ee4; +} + +.navigation-sidebar > row:disabled { + color: rgba(222, 222, 222, 0.35); +} + +placessidebar > viewport.frame { + border-style: none; +} + +placessidebar .navigation-sidebar > row { + min-height: 24px; + padding: 2px 10px; +} + +placessidebar .navigation-sidebar > row > revealer { + padding: 0 10px; +} + +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(ltr) { + padding-right: 6px; +} + +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(rtl) { + padding-left: 6px; +} + +placessidebar .navigation-sidebar > row label.sidebar-label:dir(ltr) { + padding-right: 6px; +} + +placessidebar .navigation-sidebar > row label.sidebar-label:dir(rtl) { + padding-left: 6px; +} + +placessidebar .navigation-sidebar > row button.sidebar-button { + min-width: 22px; + min-height: 22px; + margin-top: 2px; + margin-bottom: 2px; + padding: 0; + border-radius: 9999px; +} + +placessidebar .navigation-sidebar > row button.sidebar-button > image { + opacity: 0.85; +} + +placessidebar .navigation-sidebar > row button.sidebar-button:active, placessidebar .navigation-sidebar > row button.sidebar-button:checked { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.25); + border-color: rgba(0, 0, 0, 0.15); +} + +placessidebar .navigation-sidebar > row button.sidebar-button:not(:hover):not(:active) > image { + opacity: 0.65; +} + +placessidebar .navigation-sidebar > row:selected button.sidebar-button { + color: #dedede; + border-color: rgba(0, 0, 0, 0.15); + background-color: #1C252C; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px rgba(255, 255, 255, 0.02), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +placessidebar .navigation-sidebar > row:selected button.sidebar-button:active, placessidebar .navigation-sidebar > row:selected button.sidebar-button:checked { + background-image: none; + color: white; + background-color: rgba(255, 255, 255, 0.25); + border-color: rgba(0, 0, 0, 0.15); +} + +placessidebar .navigation-sidebar > row.sidebar-placeholder-row { + padding: 0 8px; + min-height: 2px; + background-image: linear-gradient(to bottom, #E9967E, #E9967E); + background-clip: content-box; +} + +placessidebar .navigation-sidebar > row.sidebar-new-bookmark-row { + color: #79AAEB; +} + +placessidebar .navigation-sidebar > row:drop(active):not(:disabled) { + box-shadow: inset 0 1px #E9967E, inset 0 -1px #E9967E; +} + +placessidebar .navigation-sidebar > row:drop(active):not(:disabled), placessidebar .navigation-sidebar > row:drop(active):not(:disabled) label, placessidebar .navigation-sidebar > row:drop(active):not(:disabled) image { + color: #E9967E; +} + +placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected { + background-color: #E9967E; +} + +placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected, placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected label, placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected image { + color: #dadada; +} + +placesview .server-list-button > image { + -gtk-icon-transform: rotate(0turn); +} + +placesview .server-list-button:checked > image { + transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); + -gtk-icon-transform: rotate(-0.5turn); +} + +placesview > actionbar > revealer > box > label { + padding-left: 8px; + padding-right: 8px; +} + +paned > separator { + min-width: 1px; + min-height: 1px; + background: none; + background-size: 1px 1px; +} + +paned > separator.wide { + min-width: 5px; + min-height: 5px; +} + +paned.horizontal > separator:dir(ltr) { + margin: 0 -8px 0 0; + padding: 0 8px 0 0; + box-shadow: inset 1px 0 rgba(255, 255, 255, 0.12); +} + +paned.horizontal > separator:dir(rtl) { + margin: 0 0 0 -8px; + padding: 0 0 0 8px; + box-shadow: inset -1px 0 rgba(255, 255, 255, 0.12); +} + +paned.horizontal > separator.wide { + margin: 0; + padding: 0; + box-shadow: inset 1px 0 rgba(255, 255, 255, 0.12), inset -1px 0 rgba(255, 255, 255, 0.12); +} + +paned.vertical > separator { + margin: 0 0 -8px 0; + padding: 0 0 8px 0; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12); +} + +paned.vertical > separator.wide { + margin: 0; + padding: 0; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12), inset 0 -1px rgba(255, 255, 255, 0.12); +} + +video { + background: black; +} + +video image.osd { + min-width: 64px; + min-height: 64px; + border-radius: 32px; +} + +infobar { + border-style: none; +} + +infobar.info > revealer > box, infobar.info:backdrop > revealer > box { + background-color: #79AAEB; +} + +infobar.info > revealer > box selection, infobar.info:backdrop > revealer > box selection { + color: #79AAEB; +} + +infobar.question > revealer > box, infobar.question:backdrop > revealer > box { + background-color: #79AAEB; +} + +infobar.question > revealer > box selection, infobar.question:backdrop > revealer > box selection { + color: #79AAEB; +} + +infobar.warning > revealer > box, infobar.warning:backdrop > revealer > box { + background-color: #E9967E; +} + +infobar.warning > revealer > box selection, infobar.warning:backdrop > revealer > box selection { + color: #E9967E; +} + +infobar.error > revealer > box, infobar.error:backdrop > revealer > box { + background-color: #F16269; +} + +infobar.error > revealer > box selection, infobar.error:backdrop > revealer > box selection { + color: #F16269; +} + +infobar.info > revealer > box, infobar.info:hover > revealer > box, infobar.info:backdrop > revealer > box, infobar.question > revealer > box, infobar.question:hover > revealer > box, infobar.question:backdrop > revealer > box, infobar.warning > revealer > box, infobar.warning:hover > revealer > box, infobar.warning:backdrop > revealer > box, infobar.error > revealer > box, infobar.error:hover > revealer > box, infobar.error:backdrop > revealer > box { + color: white; + caret-color: currentColor; +} + +infobar.info > revealer > box button, infobar.info:hover > revealer > box button, infobar.info:backdrop > revealer > box button, infobar.question > revealer > box button, infobar.question:hover > revealer > box button, infobar.question:backdrop > revealer > box button, infobar.warning > revealer > box button, infobar.warning:hover > revealer > box button, infobar.warning:backdrop > revealer > box button, infobar.error > revealer > box button, infobar.error:hover > revealer > box button, infobar.error:backdrop > revealer > box button { + min-height: 28px; +} + +infobar.info > revealer > box selection, infobar.info:hover > revealer > box selection, infobar.info:backdrop > revealer > box selection, infobar.question > revealer > box selection, infobar.question:hover > revealer > box selection, infobar.question:backdrop > revealer > box selection, infobar.warning > revealer > box selection, infobar.warning:hover > revealer > box selection, infobar.warning:backdrop > revealer > box selection, infobar.error > revealer > box selection, infobar.error:hover > revealer > box selection, infobar.error:backdrop > revealer > box selection { + background-color: white; +} + +infobar .close, +searchbar .close { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + min-width: 16px; + min-height: 16px; + padding: 4px; + border-radius: 1000px; +} + +infobar .close:hover, +searchbar .close:hover { + color: #c5c5c5; + background-color: rgba(255, 255, 255, 0.15); + background-image: none; + box-shadow: none; +} + +tooltip { + border-radius: 6px; + box-shadow: none; +} + +tooltip.background { + background-color: #343434; + background-clip: padding-box; + border-radius: 6px; + color: #d3d7df; +} + +tooltip.background label { + padding: 6px; +} + +tooltip > box { + border-spacing: 6px; +} + +colorswatch, colorswatch:drop(active) { + border-style: none; +} + +colorswatch.top { + border-top-left-radius: 2.5px; + border-top-right-radius: 2.5px; +} + +colorswatch.top overlay { + border-top-left-radius: 2px; + border-top-right-radius: 2px; +} + +colorswatch.bottom { + border-bottom-left-radius: 2.5px; + border-bottom-right-radius: 2.5px; +} + +colorswatch.bottom overlay { + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; +} + +colorswatch.left, colorswatch:first-child:not(.top) { + border-top-left-radius: 2.5px; + border-bottom-left-radius: 2.5px; +} + +colorswatch.left overlay, colorswatch:first-child:not(.top) overlay { + border-top-left-radius: 2px; + border-bottom-left-radius: 2px; +} + +colorswatch.right, colorswatch:last-child:not(.bottom) { + border-top-right-radius: 2.5px; + border-bottom-right-radius: 2.5px; +} + +colorswatch.right overlay, colorswatch:last-child:not(.bottom) overlay { + border-top-right-radius: 2px; + border-bottom-right-radius: 2px; +} + +colorswatch.dark overlay { + color: rgba(255, 255, 255, 0.7); +} + +colorswatch.dark overlay:hover { + border-color: rgba(255, 255, 255, 0.12); +} + +colorswatch.light overlay { + color: rgba(0, 0, 0, 0.7); +} + +colorswatch.light overlay:hover { + border-color: rgba(255, 255, 255, 0.12); +} + +colorswatch overlay { + border: 1px solid rgba(255, 255, 255, 0.12); +} + +colorswatch overlay:hover { + background-color: rgba(255, 255, 255, 0.2); +} + +colorswatch:disabled { + opacity: 0.5; +} + +colorswatch:disabled overlay { + border-color: rgba(0, 0, 0, 0.6); + box-shadow: none; +} + +colorswatch#add-color-button { + border-style: solid; + border-width: 1px; + color: #dedede; + border-color: rgba(0, 0, 0, 0.15); + background-color: #1C252C; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), inset 0 -1px rgba(255, 255, 255, 0.02), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +colorswatch#add-color-button:hover { + color: #f8f8f8; + border-color: rgba(0, 0, 0, 0.15); + background-color: #222d35; + box-shadow: inset 0 1px rgba(255, 255, 255, 0.12), 0 1px 1px 0 rgba(0, 0, 0, 0.03), 0 1px 2px 0 rgba(0, 0, 0, 0.01); +} + +colorswatch#add-color-button overlay { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; +} + +button.color { + padding: 0; +} + +button.color > colorswatch:only-child { + border-radius: 3px; +} + +button.color > colorswatch:only-child > overlay { + border-radius: 2px; +} + +button.color > colorswatch:only-child:disabled { + filter: none; +} + +button.color > colorswatch:only-child.light > overlay { + border-color: rgba(255, 255, 255, 0.12); +} + +button.color colorswatch:first-child:last-child { + margin: 3px; +} + +button.color colorswatch:first-child:last-child, button.color colorswatch:first-child:last-child > overlay { + border-radius: 3px; +} + +colorchooser .popover.osd { + border-radius: 6px; +} + +.content-view { + background-color: #061115; +} + +.content-view:hover { + -gtk-icon-filter: brightness(1.2); +} + +.content-view .tile { + margin: 2px; + background-color: black; + border-radius: 0; + padding: 0; +} + +.content-view .tile:active, .content-view .tile:selected { + background-color: #79AAEB; +} + +.content-view .tile:disabled { + background-color: #0a1519; +} + +.osd .scale-popup button.flat { + border-style: none; + border-radius: 6px; +} + +.scale-popup button { + border: none; +} + +.context-menu { + font: initial; +} + +.monospace { + font-family: Monospace; +} + +.keycap { + min-width: 16px; + min-height: 20px; + padding: 3px 6px; + color: #dedede; + background-color: #061115; + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 6px; + box-shadow: inset 0px -2px 0px rgba(0, 0, 0, 0.15); +} + +stackswitcher button.text-button { + min-width: 80px; +} + +*:drop(active):focus, +*:drop(active) { + box-shadow: inset 0 0 0 1px #E9967E; +} + +window { + border-width: 0; + outline-color: rgba(255, 255, 255, 0.1); + outline-offset: -1px; + outline-style: solid; + outline-width: 1px; +} + +window.csd { + transition: box-shadow 150ms cubic-bezier(0, 0, 0.2, 1); + border-radius: 12px; + box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.35), 0 8px 8px 0 rgba(0, 0, 0, 0.35), 0 16px 16px 0 rgba(0, 0, 0, 0.35), 0 0 0 2px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.75); + margin: 0; +} + +window.csd:backdrop { + box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.35), 0 8px 8px 0 transparent, 0 16px 16px 0 transparent, 0 0 0 2px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.75); +} + +window.csd.popup { + border-radius: 10px; + box-shadow: 0 5px 8px rgba(0, 0, 0, 0.15), 0 8px 15px rgba(0, 0, 0, 0.08), 0 0 0 2px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.75); +} + +window.csd.dialog.message { + border-radius: 12px; +} + +.solid-csd window.csd { + border: 1px solid #000304; + border-radius: 0; + margin: 0; + background-color: #000a0e; + box-shadow: none; +} + +window.maximized, window.fullscreen, window:backdrop { + outline-width: 0; +} + +window.popup { + box-shadow: none; +} + +window.ssd { + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35); +} + +windowcontrols { + border-spacing: 6px; +} + +windowcontrols:not(.empty).start:dir(ltr), windowcontrols:not(.empty).end:dir(rtl) { + margin-right: 8px; +} + +windowcontrols:not(.empty).start:dir(rtl), windowcontrols:not(.empty).end:dir(ltr) { + margin-left: 8px; +} + +windowcontrols button { + margin: 0; + padding: 0; +} + +windowcontrols button.close, windowcontrols button.maximize, windowcontrols button.minimize { + min-width: 16px; + min-height: 16px; + margin: 0; + padding: 0; + background-position: center; + background-repeat: no-repeat; + background-size: 16px 16px; +} + +windowcontrols button.close, windowcontrols button.close:hover, windowcontrols button.close:focus, windowcontrols button.close:active, windowcontrols button.close:backdrop, windowcontrols button.maximize, windowcontrols button.maximize:hover, windowcontrols button.maximize:focus, windowcontrols button.maximize:active, windowcontrols button.maximize:backdrop, windowcontrols button.minimize, windowcontrols button.minimize:hover, windowcontrols button.minimize:focus, windowcontrols button.minimize:active, windowcontrols button.minimize:backdrop { + border-color: transparent; + background-color: transparent; + background-image: none; + box-shadow: none; + color: transparent; +} + +windowcontrols button.close:backdrop, windowcontrols button.maximize:backdrop, windowcontrols button.minimize:backdrop { + opacity: 1; +} + +windowcontrols button.close { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-dark.png"), url("windows-assets/titlebutton-close-dark@2.png")); +} + +windowcontrols button.close:backdrop { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-backdrop-dark.png"), url("windows-assets/titlebutton-close-backdrop-dark@2.png")); +} + +windowcontrols button.close:backdrop:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-backdrop-hover-dark.png"), url("windows-assets/titlebutton-close-backdrop-hover-dark@2.png")); +} + +windowcontrols button.close:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-hover-dark.png"), url("windows-assets/titlebutton-close-hover-dark@2.png")); +} + +windowcontrols button.close:active { + background-image: -gtk-scaled(url("windows-assets/titlebutton-close-active-dark.png"), url("windows-assets/titlebutton-close-active-dark@2.png")); +} + +windowcontrols button.maximize { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-dark.png"), url("windows-assets/titlebutton-maximize-dark@2.png")); +} + +windowcontrols button.maximize:backdrop { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-backdrop-dark.png"), url("windows-assets/titlebutton-maximize-backdrop-dark@2.png")); +} + +windowcontrols button.maximize:backdrop:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-backdrop-hover-dark.png"), url("windows-assets/titlebutton-maximize-backdrop-hover-dark@2.png")); +} + +windowcontrols button.maximize:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-hover-dark.png"), url("windows-assets/titlebutton-maximize-hover-dark@2.png")); +} + +windowcontrols button.maximize:active { + background-image: -gtk-scaled(url("windows-assets/titlebutton-maximize-active-dark.png"), url("windows-assets/titlebutton-maximize-active-dark@2.png")); +} + +windowcontrols button.minimize { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-dark.png"), url("windows-assets/titlebutton-minimize-dark@2.png")); +} + +windowcontrols button.minimize:backdrop { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-backdrop-dark.png"), url("windows-assets/titlebutton-minimize-backdrop-dark@2.png")); +} + +windowcontrols button.minimize:backdrop:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-backdrop-hover-dark.png"), url("windows-assets/titlebutton-minimize-backdrop-hover-dark@2.png")); +} + +windowcontrols button.minimize:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-hover-dark.png"), url("windows-assets/titlebutton-minimize-hover-dark@2.png")); +} + +windowcontrols button.minimize:active { + background-image: -gtk-scaled(url("windows-assets/titlebutton-minimize-active-dark.png"), url("windows-assets/titlebutton-minimize-active-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize, .maximized windowcontrols button.maximize { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-dark.png"), url("windows-assets/titlebutton-restore-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize:backdrop, .maximized windowcontrols button.maximize:backdrop { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-backdrop-dark.png"), url("windows-assets/titlebutton-restore-backdrop-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize:backdrop:hover, .maximized windowcontrols button.maximize:backdrop:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-backdrop-hover-dark.png"), url("windows-assets/titlebutton-restore-backdrop-hover-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize:hover, .maximized windowcontrols button.maximize:hover { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-hover-dark.png"), url("windows-assets/titlebutton-restore-hover-dark@2.png")); +} + +.fullscreen windowcontrols button.maximize:active, .maximized windowcontrols button.maximize:active { + background-image: -gtk-scaled(url("windows-assets/titlebutton-restore-active-dark.png"), url("windows-assets/titlebutton-restore-active-dark@2.png")); +} + +popover.emoji-picker { + padding: 0; + border-radius: 12px; +} + +popover.emoji-picker > contents { + padding: 0; +} + +.emoji-searchbar { + padding: 6px; + border-spacing: 6px; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); +} + +.emoji-toolbar { + padding: 2px; + border-spacing: 2px; + border-top: 1px solid rgba(255, 255, 255, 0.12); +} + +button.emoji-section { + margin: 3px 1px; + padding: 1px 12px; + border-radius: 6px; + border: none; + outline-offset: -2px; + box-shadow: none; + transition: none; + animation: none; +} + +button.emoji-section:first-child { + margin-left: 6px; +} + +button.emoji-section:last-child { + margin-right: 6px; +} + +popover.emoji-picker emoji { + font-size: x-large; + padding: 6px; + border-radius: 6px; +} + +emoji-completion-row > box { + border-spacing: 6px; + padding: 3px 10px; +} + +emoji-completion-row:focus, +emoji-completion-row:hover { + background-color: #79AAEB; + color: white; +} + +emoji-completion-row emoji:focus, +emoji-completion-row emoji:hover { + background-color: rgba(255, 255, 255, 0.12); +} + +popover.entry-completion > contents { + padding: 0; +} + +statusbar { + padding: 6px 12px; +} + +window.background.csd stack stack stack frame, +window.background.csd > stack > stack > box > frame, +window.background.csd > stack > stack > box > box > frame, +window.background.csd > stack > box > stack > box > frame, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame, +window.background.csd > stack > box > stack > box > scrolledwindow > viewport > frame, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame { + border: none; +} + +window.background.csd stack stack stack frame > border, +window.background.csd > stack > stack > box > frame > border, +window.background.csd > stack > stack > box > box > frame > border, +window.background.csd > stack > box > stack > box > frame > border, +window.background.csd > stack > box > stack > scrolledwindow > viewport frame > border, +window.background.csd > stack > box > stack > box > scrolledwindow > viewport > frame > border, +window.background.csd > stack > grid > scrolledwindow > viewport > box > frame > border { + border: none; +} + +window.background.csd > stack > box > box > list, +window.background.csd > stack > box > stack > scrolledwindow > viewport > list { + border-bottom-left-radius: 12px; +} + +window.background.csd.maximized > stack > box > box > list, +window.background.csd.maximized > stack > box > stack > scrolledwindow > viewport > list, window.background.csd.tiled > stack > box > box > list, +window.background.csd.tiled > stack > box > stack > scrolledwindow > viewport > list, window.background.csd.fullscreen > stack > box > box > list, +window.background.csd.fullscreen > stack > box > stack > scrolledwindow > viewport > list { + border-bottom-left-radius: 12px; +} + +window.nightthemeswitcher headerbar { + background: #000a0e; + color: #FDFDFD; +} + +window.background.csd > contents > leaflet.unfolded > box > scrolledwindow > viewport > widget > stack > list.navigation-sidebar { + background-color: #162026; +} + +window.background.csd > contents > leaflet.unfolded > box > scrolledwindow > viewport > widget > stack > list.navigation-sidebar > separator { + background-color: transparent; + margin: 0; + min-height: 0; +} + +window.background.csd > contents > leaflet.unfolded > box > scrolledwindow > viewport > widget > stack > box > list.navigation-sidebar { + background-color: #162026; +} + +window.background.csd > contents > leaflet.unfolded > box > stack.background { + background-color: #061115; +} + +avatar { + border-radius: 9999px; + font-weight: bold; +} + +avatar.color1 { + background-image: linear-gradient(#83b6ec, #337fdc); + color: #cfe1f5; +} + +avatar.color2 { + background-image: linear-gradient(#7ad9f1, #0f9ac8); + color: #caeaf2; +} + +avatar.color3 { + background-image: linear-gradient(#8de6b1, #29ae74); + color: #cef8d8; +} + +avatar.color4 { + background-image: linear-gradient(#b5e98a, #6ab85b); + color: #e6f9d7; +} + +avatar.color5 { + background-image: linear-gradient(#f8e359, #d29d09); + color: #f9f4e1; +} + +avatar.color6 { + background-image: linear-gradient(#ffcb62, #d68400); + color: #ffead1; +} + +avatar.color7 { + background-image: linear-gradient(#ffa95a, #ed5b00); + color: #ffe5c5; +} + +avatar.color8 { + background-image: linear-gradient(#f78773, #e62d42); + color: #f8d2ce; +} + +avatar.color9 { + background-image: linear-gradient(#e973ab, #e33b6a); + color: #fac7de; +} + +avatar.color10 { + background-image: linear-gradient(#cb78d4, #9945b5); + color: #e7c2e8; +} + +avatar.color11 { + background-image: linear-gradient(#9e91e8, #7a59ca); + color: #d5d2f5; +} + +avatar.color12 { + background-image: linear-gradient(#e3cf9c, #b08952); + color: #f2eade; +} + +avatar.color13 { + background-image: linear-gradient(#be916d, #785336); + color: #e5d6ca; +} + +avatar.color14 { + background-image: linear-gradient(#c0bfbc, #6e6d71); + color: #d8d7d3; +} + +avatar.contrasted { + color: white; +} + +avatar.image { + background: none; +} + +preferencespage > scrolledwindow > viewport > clamp > box { + margin: 24px 12px; + border-spacing: 24px; +} + +preferencesgroup > box, preferencesgroup > box .labels { + border-spacing: 6px; +} + +preferencesgroup > box > box.header:not(.single-line) { + margin-bottom: 6px; +} + +preferencesgroup > box > box.single-line { + min-height: 34px; +} + +preferencesgroup > box button.background-preview-button, preferencesgroup > box button.background-preview-button:hover, preferencesgroup > box button.background-preview-button:active, preferencesgroup > box button.background-preview-button:checked { + background: none; + border: none; + box-shadow: none; + padding: 3px; + border: 2px solid transparent; + border-radius: 9px; +} + +preferencesgroup > box button.background-preview-button:checked { + border: 2px solid #79AAEB; +} + +statuspage > scrolledwindow > viewport > box { + margin: 36px 12px; + border-spacing: 36px; +} + +statuspage > scrolledwindow > viewport > box > clamp > box { + border-spacing: 12px; +} + +statuspage > scrolledwindow > viewport > box > clamp > box > .icon { + -gtk-icon-size: 128px; + color: alpha(currentColor,0.55); +} + +statuspage > scrolledwindow > viewport > box > clamp > box > .icon:disabled { + opacity: 0.45; +} + +statuspage > scrolledwindow > viewport > box > clamp > box > .icon:not(:last-child) { + margin-bottom: 24px; +} + +statuspage.compact > scrolledwindow > viewport > box { + margin: 24px 12px; + border-spacing: 24px; +} + +statuspage.compact > scrolledwindow > viewport > box > clamp > box > .icon { + -gtk-icon-size: 96px; +} + +statuspage.compact > scrolledwindow > viewport > box > clamp > box > .icon:not(:last-child) { + margin-bottom: 12px; +} + +statuspage.compact > scrolledwindow > viewport > box > clamp > box > .title { + font-size: 18pt; +} + +.osd .card, .card.osd { + background-color: alpha(currentColor,0.1); + color: inherit; + box-shadow: none; +} + +.osd .card:focus:focus-visible, .card.osd:focus:focus-visible { + outline-color: rgba(255, 255, 255, 0.05); +} + +.card.activatable { + transition: all 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +.card.activatable:hover { + background-image: image(alpha(currentColor,0.03)); +} + +.card.activatable:active { + background-image: image(alpha(currentColor,0.08)); +} + +toast { + margin: 12px; + margin-bottom: 18px; + border-radius: 10px; + border-spacing: 6px; + padding: 6px; + box-shadow: 0 3px 8px rgba(0, 0, 0, 0.35); +} + +toast:dir(ltr) { + padding-left: 12px; +} + +toast:dir(rtl) { + padding-right: 12px; +} + +toast > widget { + margin: 0 6px; +} + +viewswitcher { + margin: 0; +} + +viewswitcher.wide { + border-spacing: 3px; +} + +viewswitcher.wide button.toggle { + margin: 8px 0; +} + +viewswitcher.narrow button.toggle { + border-radius: 0; + margin: 0; + min-height: 0; +} + +viewswitcher button.toggle { + font-weight: normal; + padding: 0; +} + +viewswitcher button.toggle > stack > box.narrow { + font-size: 0.75rem; + padding-top: 7px; + padding-bottom: 5px; + border-spacing: 4px; +} + +viewswitcher button.toggle > stack > box.narrow > stack > label { + padding-left: 8px; + padding-right: 8px; +} + +viewswitcher button.toggle > stack > box.wide { + padding: 0 12px; + border-spacing: 6px; +} + +viewswitcherbar actionbar > revealer > box { + padding: 0; +} + +viewswitchertitle viewswitcher { + margin-left: 12px; + margin-right: 12px; +} + +indicatorbin > indicator, indicatorbin > mask { + min-width: 12px; + min-height: 12px; + border-radius: 9999px; + margin: 0; +} + +indicatorbin > indicator { + margin: 1px; + background: alpha(currentColor,0.4); +} + +indicatorbin > indicator > label { + font-size: 0.6rem; + font-weight: normal; + padding: 1px 4px; + color: white; +} + +indicatorbin > mask { + padding: 0; + background: black; +} + +indicatorbin.needs-attention > indicator { + background: #79AAEB; +} + +indicatorbin.needs-attention > indicator > label { + color: white; +} + +tabbar .box { + min-height: 28px; +} + +tabbar tabbox > separator.hidden { + opacity: 0; +} + +tabbar tabbox > revealer > indicator { + min-width: 2px; + border-radius: 2px; + background: alpha(#79AAEB,0.5); +} + +tabbar .start-action, +tabbar .end-action { + padding: 6px; +} + +tabbar .start-action:dir(ltr), +tabbar .end-action:dir(rtl) { + padding-right: 0; +} + +tabbar .start-action:dir(rtl), +tabbar .end-action:dir(ltr) { + padding-left: 0; +} + +tabbar:not(.inline) .box { + background-color: #0d181c; + color: #dadada; + margin-top: -1px; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); + padding: 0 3px 3px; +} + +tabbar:not(.inline):backdrop .box > scrolledwindow, +tabbar:not(.inline):backdrop .box > .start-action, +tabbar:not(.inline):backdrop .box > .end-action { + filter: opacity(0.5); +} + +dnd tab { + background-color: #061115; + color: #dadada; + box-shadow: none; + margin: 24px; +} + +tabbar tab, +dnd tab { + padding-right: 3px; + margin: 0; +} + +tabbar tab + tab, +dnd tab + tab { + margin-left: 3px; +} + +tabbar tab button.tab-close-button, +dnd tab button.tab-close-button { + border-radius: 3px; + min-height: 20px; + min-width: 20px; + padding: 0; +} + +tabbar tab indicator, +dnd tab indicator { + min-height: 2px; + border-radius: 2px; + background: alpha(#79AAEB,0.5); +} + +tabview:drop(active), +tabbox:drop(active) { + box-shadow: none; +} + +.unfolded stacksidebar.sidebar { + border: none; +} + +@define-color theme_fg_color #dedede; +@define-color theme_text_color currentColor; +@define-color theme_bg_color #0d181c; +@define-color theme_base_color #061115; +@define-color theme_selected_bg_color #79AAEB; +@define-color theme_selected_fg_color white; +@define-color fg_color #dedede; +@define-color text_color currentColor; +@define-color bg_color #0d181c; +@define-color base_color #061115; +@define-color selected_bg_color #79AAEB; +@define-color selected_fg_color white; +@define-color insensitive_bg_color #0a1519; +@define-color insensitive_fg_color rgba(222, 222, 222, 0.35); +@define-color insensitive_base_color #061115; +@define-color theme_unfocused_fg_color #dedede; +@define-color theme_unfocused_text_color currentColor; +@define-color theme_unfocused_bg_color #0d181c; +@define-color theme_unfocused_base_color #061115; +@define-color unfocused_insensitive_color #565d60; +@define-color borders rgba(255, 255, 255, 0.12); +@define-color unfocused_borders rgba(255, 255, 255, 0.12); +@define-color warning_color #E9967E; +@define-color error_color #F16269; +@define-color success_color #8CD7AA; +@define-color placeholder_text_color #A8A8A8; +@define-color link_color #79AAEB; +@define-color content_view_bg #061115; +/* Very contrasty background for text views (@theme_text_color foreground) */ +@define-color text_view_bg black; +@define-color wm_title alpha(#fdfdfd, 0.8); +@define-color wm_unfocused_title alpha(#fdfdfd, 0.5); +@define-color wm_bg #000a0e; +@define-color wm_bg_unfocused #000a0e; +@define-color wm_border_focused black; +@define-color wm_border_unfocused black; +@define-color wm_highlight alpha(white, 0.12); +@define-color wm_shadow alpha(black, 0.75); +@define-color wm_button_close_bg #ff767d; +@define-color wm_button_close_hover_bg #fb6c73; +@define-color wm_button_close_active_bg #F16269; +@define-color wm_icon_close_bg #dd4e55; +@define-color wm_button_hover_bg #0d181c; +@define-color wm_button_active_bg #0d181c; +@define-color wm_button_hover_border #242e31; +@define-color wm_icon_bg #afafaf; +@define-color wm_icon_unfocused_bg rgba(175, 175, 175, 0.35); +@define-color wm_icon_hover_bg #dedede; +@define-color wm_icon_active_bg #dedede; +@define-color titlebar_gradient_a #000a0e; +@define-color titlebar_gradient_b #000a0e; +@define-color budgie_tasklist_indicator_color #dedede; +@define-color budgie_tasklist_indicator_color_active #79AAEB; +@define-color budgie_tasklist_indicator_color_active_window #2a425b; +@define-color budgie_tasklist_indicator_color_attention #E9967E; +@define-color STRAWBERRY_100 #FF9262; +@define-color STRAWBERRY_300 #FF793E; +@define-color STRAWBERRY_500 #F15D22; +@define-color STRAWBERRY_700 #CF3B00; +@define-color STRAWBERRY_900 #AC1800; +@define-color ORANGE_100 #FFDB91; +@define-color ORANGE_300 #FFCA40; +@define-color ORANGE_500 #FAA41A; +@define-color ORANGE_700 #DE8800; +@define-color ORANGE_900 #C26C00; +@define-color BANANA_100 #FFFFA8; +@define-color BANANA_300 #FFFA7D; +@define-color BANANA_500 #FFCE51; +@define-color BANANA_700 #D1A023; +@define-color BANANA_900 #A27100; +@define-color LIME_100 #A2F3BE; +@define-color LIME_300 #8ADBA6; +@define-color LIME_500 #73C48F; +@define-color LIME_700 #479863; +@define-color LIME_900 #1C6D38; +@define-color BLUEBERRY_100 #94A6FF; +@define-color BLUEBERRY_300 #6A7CE0; +@define-color BLUEBERRY_500 #3F51B5; +@define-color BLUEBERRY_700 #213397; +@define-color BLUEBERRY_900 #031579; +@define-color GRAPE_100 #D25DE6; +@define-color GRAPE_300 #B84ACB; +@define-color GRAPE_500 #9C27B0; +@define-color GRAPE_700 #830E97; +@define-color GRAPE_900 #6A007E; +@define-color COCOA_100 #9F9792; +@define-color COCOA_300 #7B736E; +@define-color COCOA_500 #574F4A; +@define-color COCOA_700 #463E39; +@define-color COCOA_900 #342C27; +@define-color SILVER_100 #EEE; +@define-color SILVER_300 #CCC; +@define-color SILVER_500 #AAA; +@define-color SILVER_700 #888; +@define-color SILVER_900 #666; +@define-color SLATE_100 #888; +@define-color SLATE_300 #666; +@define-color SLATE_500 #444; +@define-color SLATE_700 #222; +@define-color SLATE_900 #111; +@define-color BLACK_100 #474341; +@define-color BLACK_300 #403C3A; +@define-color BLACK_500 #393634; +@define-color BLACK_700 #33302F; +@define-color BLACK_900 #2B2928; diff --git a/config/gtk-4.0/settings.ini b/config/gtk-4.0/settings.ini new file mode 100755 index 0000000..7c6461a --- /dev/null +++ b/config/gtk-4.0/settings.ini @@ -0,0 +1,2 @@ +[Settings] +gtk-application-prefer-dark-theme=0 diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-active-dark.png b/config/gtk-4.0/windows-assets/titlebutton-close-active-dark.png new file mode 100755 index 0000000..d856635 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-active-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-active-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-close-active-dark@2.png new file mode 100755 index 0000000..9579997 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-active-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-active.png b/config/gtk-4.0/windows-assets/titlebutton-close-active.png new file mode 100755 index 0000000..d6876b9 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-active.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-active@2.png b/config/gtk-4.0/windows-assets/titlebutton-close-active@2.png new file mode 100755 index 0000000..61301e7 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-active@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-dark.png b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-dark.png new file mode 100755 index 0000000..d742347 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-dark@2.png new file mode 100755 index 0000000..5f0ff0b Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover-dark.png b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover-dark.png new file mode 100755 index 0000000..0ea4116 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover-dark@2.png new file mode 100755 index 0000000..3446c17 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover.png b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover.png new file mode 100755 index 0000000..f74eed4 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover@2.png b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover@2.png new file mode 100755 index 0000000..f84676f Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop-hover@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-backdrop.png b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop.png new file mode 100755 index 0000000..584c919 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-backdrop@2.png b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop@2.png new file mode 100755 index 0000000..b441d1c Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-backdrop@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-dark.png b/config/gtk-4.0/windows-assets/titlebutton-close-dark.png new file mode 100755 index 0000000..1244138 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-close-dark@2.png new file mode 100755 index 0000000..40eb7bd Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-hover-dark.png b/config/gtk-4.0/windows-assets/titlebutton-close-hover-dark.png new file mode 100755 index 0000000..1ebc67a Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-hover-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-hover-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-close-hover-dark@2.png new file mode 100755 index 0000000..c2394be Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-hover-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-hover.png b/config/gtk-4.0/windows-assets/titlebutton-close-hover.png new file mode 100755 index 0000000..b85b7e5 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-hover.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close-hover@2.png b/config/gtk-4.0/windows-assets/titlebutton-close-hover@2.png new file mode 100755 index 0000000..71c9c1b Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close-hover@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close.png b/config/gtk-4.0/windows-assets/titlebutton-close.png new file mode 100755 index 0000000..927f219 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-close@2.png b/config/gtk-4.0/windows-assets/titlebutton-close@2.png new file mode 100755 index 0000000..29adf8c Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-close@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-active-dark.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-active-dark.png new file mode 100755 index 0000000..6809168 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-active-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-active-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-active-dark@2.png new file mode 100755 index 0000000..e013022 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-active-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-active.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-active.png new file mode 100755 index 0000000..f8c180d Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-active.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-active@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-active@2.png new file mode 100755 index 0000000..4c2e418 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-active@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-dark.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-dark.png new file mode 100755 index 0000000..d742347 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-dark@2.png new file mode 100755 index 0000000..5f0ff0b Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover-dark.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover-dark.png new file mode 100755 index 0000000..1eeccf1 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover-dark@2.png new file mode 100755 index 0000000..4fe1bd1 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover.png new file mode 100755 index 0000000..edde9f3 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover@2.png new file mode 100755 index 0000000..c6f8745 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop-hover@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop.png new file mode 100755 index 0000000..584c919 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop@2.png new file mode 100755 index 0000000..b441d1c Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-backdrop@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-dark.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-dark.png new file mode 100755 index 0000000..72eb5b2 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-dark@2.png new file mode 100755 index 0000000..3b9aae2 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-hover-dark.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-hover-dark.png new file mode 100755 index 0000000..c1a5251 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-hover-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-hover-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-hover-dark@2.png new file mode 100755 index 0000000..f018e1b Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-hover-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-hover.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-hover.png new file mode 100755 index 0000000..527cd6a Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-hover.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize-hover@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize-hover@2.png new file mode 100755 index 0000000..d1217e6 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize-hover@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize.png b/config/gtk-4.0/windows-assets/titlebutton-maximize.png new file mode 100755 index 0000000..25c35ba Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-maximize@2.png b/config/gtk-4.0/windows-assets/titlebutton-maximize@2.png new file mode 100755 index 0000000..8e8ceb3 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-maximize@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-active-dark.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-active-dark.png new file mode 100755 index 0000000..fccbd9a Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-active-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-active-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-active-dark@2.png new file mode 100755 index 0000000..c8e64e0 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-active-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-active.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-active.png new file mode 100755 index 0000000..306eeb5 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-active.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-active@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-active@2.png new file mode 100755 index 0000000..94601fe Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-active@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-dark.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-dark.png new file mode 100755 index 0000000..d742347 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-dark@2.png new file mode 100755 index 0000000..5f0ff0b Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover-dark.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover-dark.png new file mode 100755 index 0000000..94f0214 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover-dark@2.png new file mode 100755 index 0000000..b10747e Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover.png new file mode 100755 index 0000000..7dbcab1 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover@2.png new file mode 100755 index 0000000..ef89c44 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop-hover@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop.png new file mode 100755 index 0000000..584c919 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop@2.png new file mode 100755 index 0000000..b441d1c Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-backdrop@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-dark.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-dark.png new file mode 100755 index 0000000..668368c Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-dark@2.png new file mode 100755 index 0000000..3d585cd Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-hover-dark.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-hover-dark.png new file mode 100755 index 0000000..5d5abc7 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-hover-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-hover-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-hover-dark@2.png new file mode 100755 index 0000000..c838a35 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-hover-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-hover.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-hover.png new file mode 100755 index 0000000..4e8fab9 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-hover.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize-hover@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize-hover@2.png new file mode 100755 index 0000000..7774194 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize-hover@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize.png b/config/gtk-4.0/windows-assets/titlebutton-minimize.png new file mode 100755 index 0000000..5f9fbc2 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-minimize@2.png b/config/gtk-4.0/windows-assets/titlebutton-minimize@2.png new file mode 100755 index 0000000..83c0b6b Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-minimize@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-active-dark.png b/config/gtk-4.0/windows-assets/titlebutton-restore-active-dark.png new file mode 100755 index 0000000..8309b87 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-active-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-active-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore-active-dark@2.png new file mode 100755 index 0000000..cfc5eef Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-active-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-active.png b/config/gtk-4.0/windows-assets/titlebutton-restore-active.png new file mode 100755 index 0000000..b84627b Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-active.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-active@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore-active@2.png new file mode 100755 index 0000000..023b9fc Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-active@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-dark.png b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-dark.png new file mode 100755 index 0000000..d742347 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-dark@2.png new file mode 100755 index 0000000..5f0ff0b Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover-dark.png b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover-dark.png new file mode 100755 index 0000000..dabf61e Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover-dark@2.png new file mode 100755 index 0000000..e5d1117 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover.png b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover.png new file mode 100755 index 0000000..ae82d54 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover@2.png new file mode 100755 index 0000000..8be10cd Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop-hover@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop.png b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop.png new file mode 100755 index 0000000..584c919 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop@2.png new file mode 100755 index 0000000..b441d1c Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-backdrop@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-dark.png b/config/gtk-4.0/windows-assets/titlebutton-restore-dark.png new file mode 100755 index 0000000..72eb5b2 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore-dark@2.png new file mode 100755 index 0000000..3b9aae2 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-hover-dark.png b/config/gtk-4.0/windows-assets/titlebutton-restore-hover-dark.png new file mode 100755 index 0000000..e79d41b Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-hover-dark.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-hover-dark@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore-hover-dark@2.png new file mode 100755 index 0000000..b9dc4a0 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-hover-dark@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-hover.png b/config/gtk-4.0/windows-assets/titlebutton-restore-hover.png new file mode 100755 index 0000000..788b6c6 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-hover.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore-hover@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore-hover@2.png new file mode 100755 index 0000000..5664843 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore-hover@2.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore.png b/config/gtk-4.0/windows-assets/titlebutton-restore.png new file mode 100755 index 0000000..25c35ba Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore.png differ diff --git a/config/gtk-4.0/windows-assets/titlebutton-restore@2.png b/config/gtk-4.0/windows-assets/titlebutton-restore@2.png new file mode 100755 index 0000000..8e8ceb3 Binary files /dev/null and b/config/gtk-4.0/windows-assets/titlebutton-restore@2.png differ diff --git a/config/neofetch/config.conf b/config/neofetch/config.conf new file mode 100644 index 0000000..6ac2491 --- /dev/null +++ b/config/neofetch/config.conf @@ -0,0 +1,838 @@ +# See this wiki page for more info: +# https://github.com/dylanaraps/neofetch/wiki/Customizing-Info +print_info() { + info title + info underline + + info "${c1} " distro + info "${c2} " model + info "${c3} " kernel + info "${c4} " uptime + info "${c5} " packages + info "${c6} " shell + info "${c1} " resolution + # info "DE" de + info "${c2} " wm + info "${c3} " wm_theme + info "${c4} " theme + info "${c5} " icons + info "${c6} " term + # info "Fonts" term_font + info "${c1} " cpu + info "${c2} " gpu + info "${c3} " memory + + # info "GPU Driver" gpu_driver # Linux/macOS only + # info "CPU Usage" cpu_usage + # info "Disk" disk + # info "Battery" battery + # info "Font" font + # info "Song" song + # [[ "$player" ]] && prin "Music Player" "$player" + # info "Local IP" local_ip + # info "Public IP" public_ip + # info "Users" users + # info "Locale" locale # This only works on glibc systems. + + info cols +} + +##--------- Title + +# Hide/Show Fully qualified domain name. +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --title_fqdn +title_fqdn="off" + + +##--------- Kernel + +# Shorten the output of the kernel function. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --kernel_shorthand +# Supports: Everything except *BSDs (except PacBSD and PC-BSD) +# +# Example: +# on: '4.8.9-1-ARCH' +# off: 'Linux 4.8.9-1-ARCH' +kernel_shorthand="on" + + +##--------- Distro + +# Shorten the output of the distro function +# +# Default: 'off' +# Values: 'on', 'tiny', 'off' +# Flag: --distro_shorthand +# Supports: Everything except Windows and Haiku +distro_shorthand="off" + +# Show/Hide OS Architecture. +# Show 'x86_64', 'x86' and etc in 'Distro:' output. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --os_arch +# +# Example: +# on: 'Arch Linux x86_64' +# off: 'Arch Linux' +os_arch="on" + + +##--------- Uptime + +# Shorten the output of the uptime function +# +# Default: 'on' +# Values: 'on', 'tiny', 'off' +# Flag: --uptime_shorthand +# +# Example: +# on: '2 days, 10 hours, 3 mins' +# tiny: '2d 10h 3m' +# off: '2 days, 10 hours, 3 minutes' +uptime_shorthand="on" + + +##--------- Memory + +# Show memory pecentage in output. +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --memory_percent +# +# Example: +# on: '1801MiB / 7881MiB (22%)' +# off: '1801MiB / 7881MiB' +memory_percent="off" + +# Change memory output unit. +# +# Default: 'mib' +# Values: 'kib', 'mib', 'gib' +# Flag: --memory_unit +# +# Example: +# kib '1020928KiB / 7117824KiB' +# mib '1042MiB / 6951MiB' +# gib: ' 0.98GiB / 6.79GiB' +memory_unit="mib" + + +##--------- Packages + +# Show/Hide Package Manager names. +# +# Default: 'tiny' +# Values: 'on', 'tiny' 'off' +# Flag: --package_managers +# +# Example: +# on: '998 (pacman), 8 (flatpak), 4 (snap)' +# tiny: '908 (pacman, flatpak, snap)' +# off: '908' +package_managers="on" + + +##--------- Shell + +# Show the path to $SHELL +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --shell_path +# +# Example: +# on: '/bin/bash' +# off: 'bash' +shell_path="off" + +# Show $SHELL version +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --shell_version +# +# Example: +# on: 'bash 4.4.5' +# off: 'bash' +shell_version="on" + + +##--------- CPU + +# CPU speed type +# +# Default: 'bios_limit' +# Values: 'scaling_cur_freq', 'scaling_min_freq', 'scaling_max_freq', 'bios_limit'. +# Flag: --speed_type +# Supports: Linux with 'cpufreq' +# NOTE: Any file in '/sys/devices/system/cpu/cpu0/cpufreq' can be used as a value. +speed_type="bios_limit" + +# CPU speed shorthand +# +# Default: 'off' +# Values: 'on', 'off'. +# Flag: --speed_shorthand +# NOTE: This flag is not supported in systems with CPU speed less than 1 GHz +# +# Example: +# on: 'i7-6500U (4) @ 3.1GHz' +# off: 'i7-6500U (4) @ 3.100GHz' +speed_shorthand="off" + +# Enable/Disable CPU brand in output. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --cpu_brand +# +# Example: +# on: 'Intel i7-6500U' +# off: 'i7-6500U (4)' +cpu_brand="on" + +# CPU Speed +# Hide/Show CPU speed. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --cpu_speed +# +# Example: +# on: 'Intel i7-6500U (4) @ 3.1GHz' +# off: 'Intel i7-6500U (4)' +cpu_speed="on" + +# CPU Cores +# Display CPU cores in output +# +# Default: 'logical' +# Values: 'logical', 'physical', 'off' +# Flag: --cpu_cores +# Support: 'physical' doesn't work on BSD. +# +# Example: +# logical: 'Intel i7-6500U (4) @ 3.1GHz' (All virtual cores) +# physical: 'Intel i7-6500U (2) @ 3.1GHz' (All physical cores) +# off: 'Intel i7-6500U @ 3.1GHz' +cpu_cores="logical" + +# CPU Temperature +# Hide/Show CPU temperature. +# Note the temperature is added to the regular CPU function. +# +# Default: 'off' +# Values: 'C', 'F', 'off' +# Flag: --cpu_temp +# Supports: Linux, BSD +# NOTE: For FreeBSD and NetBSD-based systems, you'll need to enable +# coretemp kernel module. This only supports newer Intel processors. +# +# Example: +# C: 'Intel i7-6500U (4) @ 3.1GHz [27.2°C]' +# F: 'Intel i7-6500U (4) @ 3.1GHz [82.0°F]' +# off: 'Intel i7-6500U (4) @ 3.1GHz' +cpu_temp="off" + + +##--------- GPU + +# Enable/Disable GPU Brand +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --gpu_brand +# +# Example: +# on: 'AMD HD 7950' +# off: 'HD 7950' +gpu_brand="on" + +# Which GPU to display +# +# Default: 'all' +# Values: 'all', 'dedicated', 'integrated' +# Flag: --gpu_type +# Supports: Linux +# +# Example: +# all: +# GPU1: AMD HD 7950 +# GPU2: Intel Integrated Graphics +# +# dedicated: +# GPU1: AMD HD 7950 +# +# integrated: +# GPU1: Intel Integrated Graphics +gpu_type="all" + + +##--------- Resolution + +# Display refresh rate next to each monitor +# Default: 'off' +# Values: 'on', 'off' +# Flag: --refresh_rate +# Supports: Doesn't work on Windows. +# +# Example: +# on: '1920x1080 @ 60Hz' +# off: '1920x1080' +refresh_rate="off" + + +##--------- Gtk Theme / Icons / Font + +# Shorten output of GTK Theme / Icons / Font +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --gtk_shorthand +# +# Example: +# on: 'Numix, Adwaita' +# off: 'Numix [GTK2], Adwaita [GTK3]' +gtk_shorthand="off" + +# Enable/Disable gtk2 Theme / Icons / Font +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --gtk2 +# +# Example: +# on: 'Numix [GTK2], Adwaita [GTK3]' +# off: 'Adwaita [GTK3]' +gtk2="on" + +# Enable/Disable gtk3 Theme / Icons / Font +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --gtk3 +# +# Example: +# on: 'Numix [GTK2], Adwaita [GTK3]' +# off: 'Numix [GTK2]' +gtk3="on" + + +##--------- IP Address + +# Website to ping for the public IP +# +# Default: 'http://ident.me' +# Values: 'url' +# Flag: --ip_host +public_ip_host="http://ident.me" + +# Public IP timeout. +# +# Default: '2' +# Values: 'int' +# Flag: --ip_timeout +public_ip_timeout=2 + +# Desktop Environment + +# Show Desktop Environment version +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --de_version +de_version="on" + + +##--------- Disk + +# Which disks to display. +# The values can be any /dev/sdXX, mount point or directory. +# NOTE: By default we only show the disk info for '/'. +# +# Default: '/' +# Values: '/', '/dev/sdXX', '/path/to/drive'. +# Flag: --disk_show +# +# Example: +# disk_show=('/' '/dev/sdb1'): +# 'Disk (/): 74G / 118G (66%)' +# 'Disk (/mnt/Videos): 823G / 893G (93%)' +# +# disk_show=('/'): +# 'Disk (/): 74G / 118G (66%)' +# +disk_show=('/') + +# Disk subtitle. +# What to append to the Disk subtitle. +# +# Default: 'mount' +# Values: 'mount', 'name', 'dir', 'none' +# Flag: --disk_subtitle +# +# Example: +# name: 'Disk (/dev/sda1): 74G / 118G (66%)' +# 'Disk (/dev/sdb2): 74G / 118G (66%)' +# +# mount: 'Disk (/): 74G / 118G (66%)' +# 'Disk (/mnt/Local Disk): 74G / 118G (66%)' +# 'Disk (/mnt/Videos): 74G / 118G (66%)' +# +# dir: 'Disk (/): 74G / 118G (66%)' +# 'Disk (Local Disk): 74G / 118G (66%)' +# 'Disk (Videos): 74G / 118G (66%)' +# +# none: 'Disk: 74G / 118G (66%)' +# 'Disk: 74G / 118G (66%)' +# 'Disk: 74G / 118G (66%)' +disk_subtitle="mount" + +# Disk percent. +# Show/Hide disk percent. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --disk_percent +# +# Example: +# on: 'Disk (/): 74G / 118G (66%)' +# off: 'Disk (/): 74G / 118G' +disk_percent="on" + + +##--------- Song + +# Manually specify a music player. +# +# Default: 'auto' +# Values: 'auto', 'player-name' +# Flag: --music_player +# +# Available values for 'player-name': +# +# amarok +# audacious +# banshee +# bluemindo +# clementine +# cmus +# deadbeef +# deepin-music +# dragon +# elisa +# exaile +# gnome-music +# gmusicbrowser +# gogglesmm +# guayadeque +# io.elementary.music +# iTunes +# juk +# lollypop +# mocp +# mopidy +# mpd +# muine +# netease-cloud-music +# olivia +# playerctl +# pogo +# pragha +# qmmp +# quodlibet +# rhythmbox +# sayonara +# smplayer +# spotify +# strawberry +# tauonmb +# tomahawk +# vlc +# xmms2d +# xnoise +# yarock +music_player="auto" + +# Format to display song information. +# +# Default: '%artist% - %album% - %title%' +# Values: '%artist%', '%album%', '%title%' +# Flag: --song_format +# +# Example: +# default: 'Song: Jet - Get Born - Sgt Major' +song_format="%artist% - %album% - %title%" + +# Print the Artist, Album and Title on separate lines +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --song_shorthand +# +# Example: +# on: 'Artist: The Fratellis' +# 'Album: Costello Music' +# 'Song: Chelsea Dagger' +# +# off: 'Song: The Fratellis - Costello Music - Chelsea Dagger' +song_shorthand="off" + +# 'mpc' arguments (specify a host, password etc). +# +# Default: '' +# Example: mpc_args=(-h HOST -P PASSWORD) +mpc_args=() + + +##--------- Text Colors + +# Text Colors +# +# Default: 'distro' +# Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num' +# Flag: --colors +# +# Each number represents a different part of the text in +# this order: 'title', '@', 'underline', 'subtitle', 'colon', 'info' +# +# Example: +# colors=(distro) - Text is colored based on Distro colors. +# colors=(4 6 1 8 8 6) - Text is colored in the order above. +colors=(distro) + + +##--------- Text Options + +# Toggle bold text +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --bold +bold="on" + +# Enable/Disable Underline +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --underline +underline_enabled="on" + +# Underline character +# +# Default: '-' +# Values: 'string' +# Flag: --underline_char +underline_char="" + +# Info Separator +# Replace the default separator with the specified string. +# +# Default: ':' +# Flag: --separator +# +# Example: +# separator="->": 'Shell-> bash' +# separator=" =": 'WM = dwm' +separator=" ·" + + +##--------- Color Blocks + +# Color block range +# The range of colors to print. +# +# Default: '0', '15' +# Values: 'num' +# Flag: --block_range +# +# Example: +# +# Display colors 0-7 in the blocks. (8 colors) +# neofetch --block_range 0 7 +# +# Display colors 0-15 in the blocks. (16 colors) +# neofetch --block_range 0 15 +block_range=(0 15) + +# Toggle color blocks +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --color_blocks +color_blocks="on" + +# Color block width in spaces +# +# Default: '3' +# Values: 'num' +# Flag: --block_width +block_width=3 + +# Color block height in lines +# +# Default: '1' +# Values: 'num' +# Flag: --block_height +block_height=1 + +# Color Alignment +# +# Default: 'auto' +# Values: 'auto', 'num' +# Flag: --col_offset +# +# Number specifies how far from the left side of the terminal (in spaces) to +# begin printing the columns, in case you want to e.g. center them under your +# text. +# Example: +# col_offset="auto" - Default behavior of neofetch +# col_offset=7 - Leave 7 spaces then print the colors +col_offset="auto" + +##--------- Progress Bars + +# Bar characters +# +# Default: '-', '=' +# Values: 'string', 'string' +# Flag: --bar_char +# +# Example: +# neofetch --bar_char 'elapsed' 'total' +# neofetch --bar_char '-' '=' +bar_char_elapsed="-" +bar_char_total="=" + +# Toggle Bar border +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --bar_border +bar_border="on" + +# Progress bar length in spaces +# Number of chars long to make the progress bars. +# +# Default: '15' +# Values: 'num' +# Flag: --bar_length +bar_length=15 + +# Progress bar colors +# When set to distro, uses your distro's logo colors. +# +# Default: 'distro', 'distro' +# Values: 'distro', 'num' +# Flag: --bar_colors +# +# Example: +# neofetch --bar_colors 3 4 +# neofetch --bar_colors distro 5 +bar_color_elapsed="distro" +bar_color_total="distro" + +# Info display +# Display a bar with the info. +# +# Default: 'off' +# Values: 'bar', 'infobar', 'barinfo', 'off' +# Flags: --cpu_display +# --memory_display +# --battery_display +# --disk_display +# +# Example: +# bar: '[---=======]' +# infobar: 'info [---=======]' +# barinfo: '[---=======] info' +# off: 'info' +cpu_display="off" +memory_display="off" +battery_display="off" +disk_display="off" + + +##--------- Backend Settings + +# Image backend. +# +# Default: 'ascii' +# Values: 'ascii', 'caca', 'chafa', 'jp2a', 'iterm2', 'off', +# 'pot', 'termpix', 'pixterm', 'tycat', 'w3m', 'kitty' +# Flag: --backend +image_backend="ascii" + +# Image Source +# +# Which image or ascii file to display. +# +# Default: 'auto' +# Values: 'auto', 'ascii', 'wallpaper', '/path/to/img', '/path/to/ascii', '/path/to/dir/' +# 'command output (neofetch --ascii "$(fortune | cowsay -W 30)")' +# Flag: --source +# +# NOTE: 'auto' will pick the best image source for whatever image backend is used. +# In ascii mode, distro ascii art will be used and in an image mode, your +# wallpaper will be used. +image_source="auto" + + +##--------- Ascii Options + +# Ascii distro +# Which distro's ascii art to display. +# +# Default: 'auto' +# Values: 'auto', 'distro_name' +# Flag: --ascii_distro +# NOTE: AIX, Alpine, Anarchy, Android, Antergos, antiX, "AOSC OS", +# "AOSC OS/Retro", Apricity, ArcoLinux, ArchBox, ARCHlabs, +# ArchStrike, XFerience, ArchMerge, Arch, Artix, Arya, Bedrock, +# Bitrig, BlackArch, BLAG, BlankOn, BlueLight, bonsai, BSD, +# BunsenLabs, Calculate, Carbs, CentOS, Chakra, ChaletOS, +# Chapeau, Chrom*, Cleanjaro, ClearOS, Clear_Linux, Clover, +# Condres, Container_Linux, CRUX, Cucumber, Debian, Deepin, +# DesaOS, Devuan, DracOS, DarkOs, DragonFly, Drauger, Elementary, +# EndeavourOS, Endless, EuroLinux, Exherbo, Fedora, Feren, FreeBSD, +# FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, Gentoo, Pentoo, +# gNewSense, GNOME, GNU, GoboLinux, Grombyang, Guix, Haiku, Huayra, +# Hyperbola, janus, Kali, KaOS, KDE_neon, Kibojoe, Kogaion, +# Korora, KSLinux, Kubuntu, LEDE, LFS, Linux_Lite, +# LMDE, Lubuntu, Lunar, macos, Mageia, MagpieOS, Mandriva, +# Manjaro, Maui, Mer, Minix, LinuxMint, MX_Linux, Namib, +# Neptune, NetBSD, Netrunner, Nitrux, NixOS, Nurunner, +# NuTyX, OBRevenge, OpenBSD, openEuler, OpenIndiana, openmamba, +# OpenMandriva, OpenStage, OpenWrt, osmc, Oracle, OS Elbrus, PacBSD, +# Parabola, Pardus, Parrot, Parsix, TrueOS, PCLinuxOS, Peppermint, +# popos, Porteus, PostMarketOS, Proxmox, Puppy, PureOS, Qubes, Radix, +# Raspbian, Reborn_OS, Redstar, Redcore, Redhat, Refracted_Devuan, +# Regata, Rosa, sabotage, Sabayon, Sailfish, SalentOS, Scientific, +# Septor, SereneLinux, SharkLinux, Siduction, Slackware, SliTaz, +# SmartOS, Solus, Source_Mage, Sparky, Star, SteamOS, SunOS, +# openSUSE_Leap, openSUSE_Tumbleweed, openSUSE, SwagArch, Tails, +# Trisquel, Ubuntu-Budgie, Ubuntu-GNOME, Ubuntu-MATE, Ubuntu-Studio, +# Ubuntu, Venom, Void, Obarun, windows10, Windows7, Xubuntu, Zorin, +# and IRIX have ascii logos +# NOTE: Arch, Ubuntu, Redhat, and Dragonfly have 'old' logo variants. +# Use '{distro name}_old' to use the old logos. +# NOTE: Ubuntu has flavor variants. +# Change this to Lubuntu, Kubuntu, Xubuntu, Ubuntu-GNOME, +# Ubuntu-Studio, Ubuntu-Mate or Ubuntu-Budgie to use the flavors. +# NOTE: Arcolinux, Dragonfly, Fedora, Alpine, Arch, Ubuntu, +# CRUX, Debian, Gentoo, FreeBSD, Mac, NixOS, OpenBSD, android, +# Antrix, CentOS, Cleanjaro, ElementaryOS, GUIX, Hyperbola, +# Manjaro, MXLinux, NetBSD, Parabola, POP_OS, PureOS, +# Slackware, SunOS, LinuxLite, OpenSUSE, Raspbian, +# postmarketOS, and Void have a smaller logo variant. +# Use '{distro name}_small' to use the small variants. +ascii_distro="auto" + +# Ascii Colors +# +# Default: 'distro' +# Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num' +# Flag: --ascii_colors +# +# Example: +# ascii_colors=(distro) - Ascii is colored based on Distro colors. +# ascii_colors=(4 6 1 8 8 6) - Ascii is colored using these colors. +ascii_colors=(distro) + +# Bold ascii logo +# Whether or not to bold the ascii logo. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --ascii_bold +ascii_bold="on" + + +##--------- Image Options + +# Image loop +# Setting this to on will make neofetch redraw the image constantly until +# Ctrl+C is pressed. This fixes display issues in some terminal emulators. +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --loop +image_loop="off" + +# Thumbnail directory +# +# Default: '~/.cache/thumbnails/neofetch' +# Values: 'dir' +thumbnail_dir="${XDG_CACHE_HOME:-${HOME}/.cache}/thumbnails/neofetch" + +# Crop mode +# +# Default: 'normal' +# Values: 'normal', 'fit', 'fill' +# Flag: --crop_mode +# +# See this wiki page to learn about the fit and fill options. +# https://github.com/dylanaraps/neofetch/wiki/What-is-Waifu-Crop%3F +crop_mode="normal" + +# Crop offset +# Note: Only affects 'normal' crop mode. +# +# Default: 'center' +# Values: 'northwest', 'north', 'northeast', 'west', 'center' +# 'east', 'southwest', 'south', 'southeast' +# Flag: --crop_offset +crop_offset="center" + +# Image size +# The image is half the terminal width by default. +# +# Default: 'auto' +# Values: 'auto', '00px', '00%', 'none' +# Flags: --image_size +# --size +image_size="auto" + +# Gap between image and text +# +# Default: '3' +# Values: 'num', '-num' +# Flag: --gap +gap=2 + +# Image offsets +# Only works with the w3m backend. +# +# Default: '0' +# Values: 'px' +# Flags: --xoffset +# --yoffset +yoffset=0 +xoffset=0 + +# Image background color +# Only works with the w3m backend. +# +# Default: '' +# Values: 'color', 'blue' +# Flag: --bg_color +background_color= + + +##--------- Misc Options + +# Stdout mode +# Turn off all colors and disables image backend (ASCII/Image). +# Useful for piping into another command. +# Default: 'off' +# Values: 'on', 'off' +stdout="off" diff --git a/config/nvim/.github/CONTRIBUTING.md b/config/nvim/.github/CONTRIBUTING.md new file mode 100644 index 0000000..12d436d --- /dev/null +++ b/config/nvim/.github/CONTRIBUTING.md @@ -0,0 +1,161 @@ +# [CONTRIBUTING](https://nvchad.github.io/contribute) + +## NvChad install for contributors + +If you wish to contribute to NvChad, you should: +1. [create a fork on GitHub](https://docs.github.com/en/get-started/quickstart/fork-a-repo) +2. clone your fork to your machine + - For ssh: + ```shell + $ git clone git@github.com:/NvChad.git ~/.config/nvim + ``` + - For https: + ```shell + $ git clone https://github.com//NvChad.git ~/.config/nvim + ``` +3. [add a new remote repo to track](https://www.atlassian.com/git/tutorials/git-forks-and-upstreams) + - this means you can push/pull as normal to your own repo, but also easily track & update from the NvChad repo + - for ssh: + ```shell + $ git remote add upstream git@github.com:NvChad/NvChad.git + ``` + - for https: + ```shell + $ git remote add upstream https://github.com/NvChad/NvChad.git + ``` +4. any time you create a branch to do some work, use + ```shell + $ git fetch upstream && git checkout -b dev-myFEAT upstream/main + ``` +5. only use the **--rebase** flag to update your dev branch + - this means that there are no `Merge NvChad/main into devBranch` commits, which are to be avoided + ```shell + $ git pull upstream --rebase + ``` + +## Things to know before contributing + +- When making a PR (pull request), please be very descriptive about what you've done! + +- PR titles should be formatted with 'fix', 'chore' or 'feat'. ex: `feat: add new plugin` + +- PRs should follow the pull request formats where applicable + +- We are open to all PRs, but may decline some for a myriad of reasons. Though don't be discouraged! We'll still be open to discussions. + +- PR's are always welcomed however NvChad aims to be less bloated. So PR's regarding existing plugin's enhancement and creating new features with existing plugins itself ( without adding a new plugin), bug fixes and corrections are more encouraged. + +- NvChad won't keep adding more and more features (like adding new plugins most likely) as requested if they feel unneeded and aren't usable by the majority!! If you think the plugin you want to be added is very useful and many NvChaders would find it useful, then such feature's PR is welcomed! + +- But adding specific features like adding config for [wakatime](https://github.com/wakatime/vim-wakatime) etc will be added in this [chad user configs](https://github.com/NvChad/NvChad/wiki/Chad-user-configs). This lets the user select the things only they want ( adding configs from extra configs ). + +## How to remove or edit commits from your PR +> You may have been directed here to remove a commit such as a merge commit: `Merge NvChad/main into devBranch` from your PR + +> As these commands edit your git history, you may need to **force push** with `git push origin --force` + +1. Run the following: + ``` + $ git rebase -i HEAD~ + ``` +
Example +

+ + ```shell + $ git rebase -i HEAD~4 + ``` + + ```shell + pick 28b2dcb statusline add lsp status + pick dad9a39 feat: Added lsp radial progress + pick 68f72f1 add clickable btn for exiting nvim + pick b281b53 avoid using q! for quitting vim + + # Rebase 52b655b..b281b53 onto 52b655b (4 commands) + # + # Commands: + # p, pick = use commit + # r, reword = use commit, but edit the commit message + # e, edit = use commit, but stop for amending + # s, squash = use commit, but meld into previous commit + # f, fixup = like "squash", but discard this commit's log message + # x, exec = run command (the rest of the line) using shell + # b, break = stop here (continue rebase later with 'git rebase --continue') + # d, drop = remove commit + # l, label

+
+ +2. Change the `pick` commands to whatever you wish, you may wish to `d` `drop` or `e` `edit` a commit. Then save & quit this git file to run it. + +
Example +

+ + ```shell {3,4} + pick 28b2dcb statusline add lsp status + pick dad9a39 feat: Added lsp radial progress + edit 68f72f1 add clickable btn for exiting nvim + d b281b53 avoid using q! for quitting vim + + # Rebase 52b655b..b281b53 onto 52b655b (4 commands) + # + # Commands: + # p, pick = use commit + # r, reword = use commit, but edit the commit message + # e, edit = use commit, but stop for amending + # s, squash = use commit, but meld into previous commit + # f, fixup = like "squash", but discard this commit's log message + # x, exec = run command (the rest of the line) using shell + # b, break = stop here (continue rebase later with 'git rebase --continue') + # d, drop = remove commit + # l, label

+
+ +3. If you picked `drop` you are done, if you picked `edit` then edit your files, then run: + ```shell + $ git add + ``` + +4. Once you have edited & added your files, run: + ```shell + $ git rebase --continue + ``` + +5. You will likely need to push using: + ```shell + $ git push origin --force + ``` + +## Help +For help with contributing and anything else nvChad related join the [discord](https://discord.gg/VyPxsGArXc) diff --git a/config/nvim/.github/FUNDING.yml b/config/nvim/.github/FUNDING.yml new file mode 100644 index 0000000..02611f2 --- /dev/null +++ b/config/nvim/.github/FUNDING.yml @@ -0,0 +1,3 @@ +patreon: siduck +ko_fi: siduck +custom: ["https://www.buymeacoffee.com/siduck", "https://www.paypal.com/paypalme/siduck76"] diff --git a/config/nvim/.github/ISSUE_TEMPLATE/bug_report.md b/config/nvim/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..470452f --- /dev/null +++ b/config/nvim/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,32 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - Operating System + - Terminal + - Version of Neovim + +**Additional context** +Add any other context about the problem here. diff --git a/config/nvim/.github/ISSUE_TEMPLATE/config.yml b/config/nvim/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3495e93 --- /dev/null +++ b/config/nvim/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Wiki + url: https://github.com/siduck76/NvChad/wiki + about: "Walks you through how to use and Configure NvChad." + - name: Visit our gitter chat + url: https://gitter.im/neovim-dotfiles/community + about: "A place where we dicuss NvChad related stuff." diff --git a/config/nvim/.github/ISSUE_TEMPLATE/feature_request.md b/config/nvim/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..24d2f24 --- /dev/null +++ b/config/nvim/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem was. + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. + +**Screenshot** +Maybe a screenshot of the feature diff --git a/config/nvim/.github/PULL_REQUEST_TEMPLATE/feature.md b/config/nvim/.github/PULL_REQUEST_TEMPLATE/feature.md new file mode 100644 index 0000000..a622846 --- /dev/null +++ b/config/nvim/.github/PULL_REQUEST_TEMPLATE/feature.md @@ -0,0 +1,14 @@ + +Fixes Issue # (If it doesn't fix an issue then delete this line) + +Features Added: +- Plugin Name (Add links if possible too) + +Reasoning: +List why the feature is needed + +Speed (If applicable): +Show the impact on the speed of nvChad + +Other: +Anything else relevant goes here diff --git a/config/nvim/.github/PULL_REQUEST_TEMPLATE/plugin.md b/config/nvim/.github/PULL_REQUEST_TEMPLATE/plugin.md new file mode 100644 index 0000000..28ae8d3 --- /dev/null +++ b/config/nvim/.github/PULL_REQUEST_TEMPLATE/plugin.md @@ -0,0 +1,16 @@ +(Make sure your title is either: 'fix', 'chore', or 'feat' then your title. ex: `fix: add new plugin`) + +Fixes Issue # (If it doesn't fix an issue then delete this line) + +Plugins Added: +- [Plugin Name](Plugin Link) +- [Plugin Name](Plugin Link) + +Reasoning: +List why the plugin(s) should be added + +Speed: +Show the impact on the speed of nvChad + +Other: +Anything else relevant goes here diff --git a/config/nvim/.github/README.md b/config/nvim/.github/README.md new file mode 100644 index 0000000..cbd6b83 --- /dev/null +++ b/config/nvim/.github/README.md @@ -0,0 +1,145 @@ +

NvChad

+ +
+ Home + + Install + + Contribute + + Support + + Features +

+
+ +
+ +[![Super Linter](https://img.shields.io/github/workflow/status/NvChad/NvChad/Super-Linter/main?style=flat-square&logo=github&label=Build&color=8DBBE9)]() +License +[![Neovim Minimum Version](https://img.shields.io/badge/Neovim-0.7.0-blueviolet.svg?style=flat-square&logo=Neovim&color=90E59A&logoColor=white)](https://github.com/neovim/neovim) +[![GitHub Issues](https://img.shields.io/github/issues/NvChad/NvChad.svg?style=flat-square&label=Issues&color=d77982)](https://github.com/NvChad/NvChad/issues) +[![Discord](https://img.shields.io/discord/869557815780470834?color=738adb&label=Discord&logo=discord&logoColor=white&style=flat-square)](https://discord.gg/gADmkJb9Fb) +[![Matrix](https://img.shields.io/badge/Matrix-40aa8b.svg?style=flat-square&logo=Matrix&logoColor=white)](https://matrix.to/#/#nvchad:matrix.org) +[![Telegram](https://img.shields.io/badge/Telegram-blue.svg?style=flat-square&logo=Telegram&logoColor=white)](https://t.me/DE_WM) + +
+ +## Showcase + + + + +( Zoom in the screenshot ) + + + + +## What is it? + +- NvChad is a neovim config written in lua aiming to provide a base configuration with very beautiful UI and blazing fast startuptime (around 0.02 secs ~ 0.07 secs). We tweak UI plugins such as telescope, nvim-tree, bufferline etc well to provide an aesthetic UI experience. + +- Lazy loading is done 93% of the time meaning that plugins will not be loaded by default, they will be loaded only when required also at specific commands, events etc. This lowers the startuptime and it was like 0.07~ secs tested on an old pentium machine 1.4ghz + 4gb ram & HDD. + +- NvChad isnt a framework! Its supposed to be used as a "base" config, so users could tweak the defaults well, can also remove the things they dont like in the default config and build their config on top of it. Users can tweak the entire default config while staying in their custom config (lua/custom dir). This is the control center of the user's config and gitignored so the users can stay update to-date with NvChad's latest config (main branch) while still controlling it with their chadrc (file that controls entire custom dir) + +## Theme Showcase + +
Images (Click to expand!) + +![main themes](https://github.com/NvChad/nvchad.github.io/blob/src/static/img/screenshots/four_Themes.png) +![radium](https://github.com/NvChad/nvchad.github.io/blob/src/static/img/screenshots/radium1.png) +![radium](https://github.com/NvChad/nvchad.github.io/blob/src/static/img/screenshots/radium2.png) +![radium](https://github.com/NvChad/nvchad.github.io/blob/src/static/img/screenshots/radium3.png) + +(Note: these are just 4-5 themes, NvChad has around 27+ themes) +
+ +## UI related plugins used + +
Images (Click to expand!) + +

Nvim-tree.lua

+ +Fast file tree: + +
+ +

Telescope-nvim

+ +A fuzzy file finder, picker, sorter, previewer and much more: + +
+ +

Indent-blankline.nvim

+ +Adds indentline: + +
+ +

Our own statusline written from scratch

+ +[link](https://github.com/NvChad/NvChad/blob/main/lua/ui/statusline.lua) + +
+
+ +

Tabufline (our own pertab bufferline)

+ +
+
+
+ +

Nvim-web-devicons

+ +Lua fork of Vim Devicons which offers more file icon customisability: + +
+ +

Nvim-treesitter

+ +## Plugins list + +- Many beautiful themes, theme toggler by [our base46 plugin](https://github.com/NvChad/base46) +- Inbuilt terminal toggling & management with [Nvterm](https://github.com/NvChad/nvterm) +- NvChad updater, hide & unhide terminal buffers with [NvChad extensions](https://github.com/NvChad/extensions) +- File navigation with [nvim-tree.lua](https://github.com/kyazdani42/nvim-tree.lua) +- Managing tabs, buffers with [bufferline.nvim](https://github.com/akinsho/bufferline.nvim) +- Beautiful and configurable icons with [nvim-web-devicons](https://github.com/kyazdani42/nvim-web-devicons) +- Git diffs and more with [gitsigns.nvim](https://github.com/lewis6991/gitsigns.nvim) +- NeoVim Lsp configuration with [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) and [lsp-installer](https://github.com/williamboman/nvim-lsp-installer/) +- Autocompletion with [nvim-cmp](https://github.com/hrsh7th/nvim-cmp) +- File searching, previewing image and text files and more with [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim). +- Syntax highlighting with [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) +- Autoclosing braces and html tags with [nvim-autopairs](https://github.com/windwp/nvim-autopairs) +- Indentlines with [indent-blankline.nvim](https://github.com/lukas-reineke/indent-blankline.nvim) +- Useful snippets with [friendly snippets](https://github.com/rafamadriz/friendly-snippets) + [LuaSnip](https://github.com/L3MON4D3/LuaSnip). +- Popup mappings keysheet [whichkey.nvim](https://github.com/folke/which-key.nvim) + +## History + +- I (@siduck i.e creator of NvChad) in my initial days of learning to program wanted a lightweight IDE for writing code, I had a very low end system which was like 1.4ghz pentium + 4gb ram & HDD. I was into web dev stuff so many suggested me to use vscode but that thing was very heavy on my system, It took more ram than my browser! ( minimal ungoogled chromium ) so I never tried it again, sublime text was nice but the fear of using proprietary software XD for a linux user bugged me a lot. Then I tried doom-emacs which looked pretty but it was slow and I was lost within its docs, I tried lunarvim but too lazy to read the docs. Doom-emacs and lunarvim inspired me to make a config which is the prettiest + very fast and simple. + +- I'm decent at ricing i.e customizing system and making it look pretty so I posted my neovim rice on [neovim subreddit](https://www.reddit.com/r/neovim/comments/m3xl4f/neovim_rice/), my neovim-dotfiles github repo blew up and then I had to come up with a name, I was amazed by the chad meme lol so I put NvChad as the name, the chad word in here doesnt literally mean the chad guy but in the sense such as chad linux vs windows i.e meaning superior, best etc. NvChad was made for my personal use but it gained some popularity which inspired me to make a public config i.e config usable by many and less hassle to update as everyone's going to use the same base config (NvChad) with their custom modifications (which are gitignored so that wont mess up), without the custom config stuff users would have to keep a track of every commit and copy paste git diffs to manually update nvchad. + +## :gift_heart: Support + +I'm (@siduck) really very sorry to remove the previous charity links but I had to do it for various reasons. A lot has been going here regarding financial issues and I do need some support if it's possible from your end. I haven't graduated yet and it would be great to earn some stuff as that'd help me with daily minor expenses. If you like NvChad and would like to support & appreciate it via donation then I'll gladly accept it. Dont worry! NvChad will still stay alive & active without your donations! I will remove the sponsor button and re-add the charity links once I get a job, probably a year or two. + +[![kofi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/siduck) +[![paypal](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white)](https://paypal.me/siduck76) +[![buymeacoffee](https://img.shields.io/badge/Buy_Me_A_Coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/siduck) +[![patreon](https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://www.patreon.com/siduck) + +## Credits + +- [Elianiva](https://github.com/elianiva) helped me with NeoVim Lua related issues many times, NvChad wouldn't exist without his help at all as he helped me in my initial neovim journey! +- @lorvethe for making the beautiful NvChad logo. diff --git a/config/nvim/.github/workflows/stale.yml b/config/nvim/.github/workflows/stale.yml new file mode 100644 index 0000000..1f16ea2 --- /dev/null +++ b/config/nvim/.github/workflows/stale.yml @@ -0,0 +1,22 @@ +name: 'Close stale issues and PRs' +on: + schedule: + - cron: '30 1 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.' + stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.' + close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.' + exempt-all-issue-assignees: true # doesn't close an issue if someone was assigned to it. + close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.' + exempt-all-pr-assignees: true # doesn't close a pr if someone was assigned to it. + days-before-issue-stale: 30 + days-before-pr-stale: 45 + days-before-issue-close: 5 + days-before-pr-close: 10 diff --git a/config/nvim/.gitignore b/config/nvim/.gitignore new file mode 100644 index 0000000..db7df8e --- /dev/null +++ b/config/nvim/.gitignore @@ -0,0 +1,3 @@ +plugin +custom +spell diff --git a/config/nvim/.stylua.toml b/config/nvim/.stylua.toml index e9bf648..f4c1cee 100644 --- a/config/nvim/.stylua.toml +++ b/config/nvim/.stylua.toml @@ -3,4 +3,4 @@ line_endings = "Unix" indent_type = "Spaces" indent_width = 3 quote_style = "AutoPreferDouble" -no_call_parentheses = true +call_parentheses = "None" diff --git a/config/nvim/examples/init.lua b/config/nvim/examples/init.lua index a6b3d5c..809432d 100644 --- a/config/nvim/examples/init.lua +++ b/config/nvim/examples/init.lua @@ -1,11 +1,3 @@ --- Please check NvChad docs if you're totally new to nvchad + dont know lua!! --- This is an example init file in /lua/custom/ --- this init.lua can load stuffs etc too so treat it like your ~/.config/nvim/ +-- example file i.e lua/custom/init.lua --- MAPPINGS -local map = require("core.utils").map - -map("n", "cc", ":Telescope ") -map("n", "q", ":q ") - --- NOTE: the 4th argument in the map function is be a table i.e options but its most likely un-needed so dont worry about it +-- load your globals, autocmds here or anything .__. diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 22177d0..2237c5c 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -1,31 +1,12 @@ -local present, impatient = pcall(require, "impatient") +require "core" +require "core.options" -if present then - impatient.enable_profile() -end +vim.defer_fn(function() + require("core.utils").load_mappings() +end, 0) -local core_modules = { - "core.options", - "core.autocmds", - "core.mappings", -} +-- setup packer + plugins +require("core.packer").bootstrap() +require "plugins" -for _, module in ipairs(core_modules) do - local ok, err = pcall(require, module) - if not ok then - error("Error loading " .. module .. "\n\n" .. err) - end -end - --- non plugin mappings -require("core.mappings").misc() - --- check if custom init.lua file exists -if vim.fn.filereadable(vim.fn.stdpath "config" .. "/lua/custom/init.lua") == 1 then - -- try to call custom init, if not successful, show error - local ok, err = pcall(require, "custom") - if not ok then - vim.notify("Error loading custom/init.lua\n\n" .. err) - end - return -end +pcall(require, "custom") diff --git a/config/nvim/lua/core/default_config.lua b/config/nvim/lua/core/default_config.lua index 4123f4b..98ecbb6 100644 --- a/config/nvim/lua/core/default_config.lua +++ b/config/nvim/lua/core/default_config.lua @@ -1,279 +1,52 @@ --- IMPORTANT NOTE : This is default config, so dont change anything here. --- use custom/chadrc.lua instead +-- Chadrc overrides this file local M = {} M.options = { - -- custom = {} - -- general nvim/vim options , check :h optionname to know more about an option + -- load your options here or load module with options + user = function() end, - clipboard = "unnamedplus", - cmdheight = 1, - ruler = false, - hidden = true, - ignorecase = true, - smartcase = true, - mapleader = " ", - mouse = "a", - number = true, - numberwidth = 2, - relativenumber = false, - expandtab = true, - shiftwidth = 2, - smartindent = true, - tabstop = 8, - timeoutlen = 400, - updatetime = 250, - undofile = true, - fillchars = { eob = " " }, - shadafile = vim.opt.shadafile, - - -- NvChad options nvChad = { - copy_cut = true, -- copy cut text ( x key ), visual and normal mode - copy_del = true, -- copy deleted text ( dd key ), visual and normal mode - insert_nav = true, -- navigation in insertmode - window_nav = true, - terminal_numbers = false, - - -- updater update_url = "https://github.com/NvChad/NvChad", update_branch = "main", }, - terminal = { - behavior = { - close_on_exit = true, - }, - window = { - vsplit_ratio = 0.5, - split_ratio = 0.4, - }, - location = { - horizontal = "rightbelow", - vertical = "rightbelow", - float = { - relative = 'editor', - row = 0.3, - col = 0.25, - width = 0.5, - height = 0.4, - border = "single", - } - }, - }, } ----- UI ----- - M.ui = { - hl_override = "", -- path of your file that contains highlights - colors = "", -- path of your file that contains colors - italic_comments = false, + -- hl = highlights + hl_add = {}, + hl_override = {}, + changed_themes = {}, + theme_toggle = { "onedark", "one_light" }, theme = "onedark", -- default theme - - -- Change terminal bg to nvim theme's bg color so it'll match well - -- For Ex : if you have onedark set in nvchad, set onedark's bg color on your terminal transparency = false, -} ----- PLUGIN OPTIONS ---- + statusline = { + separator_style = "default", -- default/round/block/arrow + config = "%!v:lua.require('ui.statusline').run()", + override = {}, + }, + + -- lazyload it when there are 1+ buffers + tabufline = { + enabled = true, + lazyload = true, + override = {}, + }, +} M.plugins = { - - -- builtin nvim plugins are disabled - builtins = { - "2html_plugin", - "getscript", - "getscriptPlugin", - "gzip", - "logipat", - "netrw", - "netrwPlugin", - "netrwSettings", - "netrwFileHandlers", - "matchit", - "tar", - "tarPlugin", - "rrhelper", - "spellfile_plugin", - "vimball", - "vimballPlugin", - "zip", - "zipPlugin", - }, - - -- enable/disable plugins (false for disable) - status = { - blankline = true, -- indentline stuff - bufferline = true, -- manage and preview opened buffers - colorizer = false, -- color RGB, HEX, CSS, NAME color codes - comment = true, -- easily (un)comment code, language aware - alpha = false, -- dashboard - better_escape = true, -- map to with no lag - feline = true, -- statusline - gitsigns = true, - lspsignature = true, -- lsp enhancements - vim_matchup = true, -- improved matchit - cmp = true, - nvimtree = true, - autopairs = true, - }, + override = {}, + remove = {}, + user = {}, options = { - packer = { - init_file = "plugins.packerInit", - }, - autopairs = { loadAfter = "nvim-cmp" }, - cmp = { - lazy_load = true, - }, lspconfig = { - setup_lspconf = "", -- path of file containing setups of different lsps + setup_lspconf = "", -- path of lspconfig file }, - nvimtree = { - -- packerCompile required after changing lazy_load - lazy_load = true, - }, - luasnip = { - snippet_path = {}, - }, - statusline = { - hide_disable = false, - -- hide, show on specific filetypes - hidden = { - "help", - "NvimTree", - "terminal", - "alpha", - }, - shown = {}, - - -- truncate statusline on small screens - shortline = true, - style = "default", -- default, round , slant , block , arrow - }, - esc_insertmode_timeout = 300, - }, - default_plugin_config_replace = {}, - default_plugin_remove = {}, - install = nil, -} - --- Don't use a single keymap twice - ---- MAPPINGS ---- - --- non plugin -M.mappings = { - -- custom = {}, -- custom user mappings - - misc = { - cheatsheet = "ch", - close_buffer = "x", - cp_whole_file = "", -- copy all contents of current buffer - lineNR_toggle = "n", -- toggle line number - lineNR_rel_toggle = "rn", - update_nvchad = "uu", - new_buffer = "", - new_tab = "b", - save_file = "", -- save file using :w - }, - - -- navigation in insert mode, only if enabled in options - - insert_nav = { - backward = "", - end_of_line = "", - forward = "", - next_line = "", - prev_line = "", - beginning_of_line = "", - }, - - -- better window movement - window_nav = { - moveLeft = "", - moveRight = "", - moveUp = "", - moveDown = "", - }, - - -- terminal related mappings - terminal = { - -- multiple mappings can be given for esc_termmode, esc_hide_termmode - - -- get out of terminal mode - esc_termmode = { "jk" }, - - -- get out of terminal mode and hide it - esc_hide_termmode = { "JK" }, - -- show & recover hidden terminal buffers in a telescope picker - pick_term = "W", - - -- spawn a single terminal and toggle it - -- this just works like toggleterm kinda - new_horizontal = "h", - new_vertical = "v", - new_float = "", - - -- spawn new terminals - spawn_horizontal = "", - spawn_vertical = "", - spawn_window = "w", }, } --- plugins related mappings --- To disable a mapping, equate the variable to "" or false or nil in chadrc -M.mappings.plugins = { - bufferline = { - next_buffer = "", - prev_buffer = "", - }, - comment = { - toggle = "/", - }, - - -- map to with no lag - better_escape = { -- will still work - esc_insertmode = { "jk" }, -- multiple mappings allowed - }, - - lspconfig = { - declaration = "gD", - definition = "gd", - hover = "K", - implementation = "gi", - signature_help = "gk", - add_workspace_folder = "wa", - remove_workspace_folder = "wr", - list_workspace_folders = "wl", - type_definition = "D", - rename = "ra", - code_action = "ca", - references = "gr", - float_diagnostics = "ge", - goto_prev = "[d", - goto_next = "]d", - set_loclist = "q", - formatting = "fm", - }, - - nvimtree = { - toggle = "", - focus = "e", - }, - - telescope = { - buffers = "fb", - find_files = "ff", - find_hiddenfiles = "fa", - git_commits = "cm", - git_status = "gt", - help_tags = "fh", - live_grep = "fw", - oldfiles = "fo", - themes = "th", -- NvChad theme picker - }, -} +-- check core.mappings for table structure +M.mappings = require "core.mappings" return M diff --git a/config/nvim/lua/core/init.lua b/config/nvim/lua/core/init.lua new file mode 100644 index 0000000..7e98731 --- /dev/null +++ b/config/nvim/lua/core/init.lua @@ -0,0 +1,82 @@ +-- commands +vim.cmd "silent! command! NvChadUpdate lua require('nvchad').update_nvchad()" +vim.cmd "silent! command! NvChadSnapshotCreate lua require('nvchad').snap_create()" +vim.cmd "silent! command! NvChadSnapshotDelete lua require('nvchad').snap_delete()" +vim.cmd "silent! command! NvChadSnapshotCheckout lua require('nvchad').snap_checkout()" + +-- autocmds +local autocmd = vim.api.nvim_create_autocmd +local api = vim.api + +-- wrap the PackerSync command to warn people before using it in NvChadSnapshots +autocmd("VimEnter", { + callback = function() + vim.cmd "command! -nargs=* -complete=customlist,v:lua.require'packer'.plugin_complete PackerSync lua require('core.utils').packer_sync()" + end, +}) + +-- Disable statusline in dashboard +autocmd("FileType", { + pattern = "alpha", + callback = function() + vim.opt.laststatus = 0 + end, +}) + +autocmd("BufUnload", { + buffer = 0, + callback = function() + vim.opt.laststatus = 3 + end, +}) + +-- Don't auto commenting new lines +autocmd("BufEnter", { + pattern = "*", + command = "set fo-=c fo-=r fo-=o", +}) + +vim.t.bufs = vim.api.nvim_list_bufs() + +-- thx to https://github.com/ii14 & stores buffer per tab -> table +autocmd({ "BufAdd", "BufEnter" }, { + callback = function(args) + if vim.t.bufs == nil then + vim.t.bufs = { args.buf } + else + local bufs = vim.t.bufs + + -- check for duplicates + if not vim.tbl_contains(bufs, args.buf) and (args.event == "BufAdd" or vim.bo[args.buf].buflisted) then + table.insert(bufs, args.buf) + vim.t.bufs = bufs + end + end + end, +}) + +autocmd("BufDelete", { + callback = function(args) + for _, tab in ipairs(api.nvim_list_tabpages()) do + local bufs = vim.t[tab].bufs + if bufs then + for i, bufnr in ipairs(bufs) do + if bufnr == args.buf then + table.remove(bufs, i) + vim.t[tab].bufs = bufs + break + end + end + end + end + end, +}) + +local tabufline_opts = require("core.utils").load_config().ui.tabufline + +if tabufline_opts.enabled and tabufline_opts.lazyload then + require("core.lazy_load").tabufline() +elseif tabufline_opts.enabled then + vim.opt.showtabline = 2 + vim.opt.tabline = "%!v:lua.require'ui.tabline'.run()" +end diff --git a/config/nvim/lua/core/lazy_load.lua b/config/nvim/lua/core/lazy_load.lua new file mode 100644 index 0000000..b5458e3 --- /dev/null +++ b/config/nvim/lua/core/lazy_load.lua @@ -0,0 +1,124 @@ +local M = {} +local autocmd = vim.api.nvim_create_autocmd + +M.lazy_load = function(tb) + autocmd(tb.events, { + pattern = "*", + group = vim.api.nvim_create_augroup(tb.augroup_name, {}), + callback = function() + if tb.condition() then + vim.api.nvim_del_augroup_by_name(tb.augroup_name) + + -- dont defer for treesitter as it will show slow highlighting + -- This deferring only happens only when we do "nvim filename" + if tb.plugins ~= "nvim-treesitter" then + vim.defer_fn(function() + vim.cmd("PackerLoad " .. tb.plugins) + end, 0) + else + vim.cmd("PackerLoad " .. tb.plugins) + end + end + end, + }) +end + +M.colorizer = function() + M.lazy_load { + events = { "BufRead", "BufNewFile" }, + augroup_name = "ColorizerLazy", + plugins = "nvim-colorizer.lua", + + condition = function() + local items = { "#", "rgb", "hsl", "rgba", "hsla" } + + for _, val in ipairs(items) do + if vim.fn.search(val) ~= 0 then + return true + end + end + end, + } +end + +-- load certain plugins only when there's a file opened in the buffer +-- if "nvim filename" is executed -> load the plugin after nvim gui loads +-- This gives an instant preview of nvim with the file opened + +M.on_file_open = function(plugin_name) + M.lazy_load { + events = { "BufRead", "BufWinEnter", "BufNewFile" }, + augroup_name = "BeLazyOnFileOpen" .. plugin_name, + plugins = plugin_name, + condition = function() + local file = vim.fn.expand "%" + return file ~= "NvimTree_1" and file ~= "[packer]" and file ~= "" + end, + } +end + +-- lspinstaller & lspconfig cmds for lazyloading +M.lsp_cmds = { + "LspInfo", + "LspStart", + "LspRestart", + "LspStop", + "LspInstall", + "LspUnInstall", + "LspUnInstallAll", + "LspInstall", + "LspInstallInfo", + "LspInstallLog", + "LspLog", + "LspPrintInstalled", +} + +M.treesitter_cmds = { + "TSInstall", + "TSBufEnable", + "TSBufDisable", + "TSEnable", + "TSDisable", + "TSModuleInfo", +} + +M.gitsigns = function() + -- taken from https://github.com/max397574 + autocmd({ "BufRead" }, { + callback = function() + local function onexit(code, _) + if code == 0 then + vim.schedule(function() + require("packer").loader "gitsigns.nvim" + end) + end + end + local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) + if lines ~= { "" } then + vim.loop.spawn("git", { + args = { + "ls-files", + "--error-unmatch", + vim.fn.expand "%:p:h", + }, + }, onexit) + end + end, + }) +end + +M.tabufline = function() + autocmd({ "BufNewFile", "BufRead", "TabEnter" }, { + pattern = "*", + group = vim.api.nvim_create_augroup("TabuflineLazyLoad", {}), + callback = function() + if #vim.fn.getbufinfo { buflisted = 1 } >= 2 then + vim.opt.showtabline = 2 + vim.opt.tabline = "%!v:lua.require'ui.tabline'.run()" + vim.api.nvim_del_augroup_by_name "TabuflineLazyLoad" + end + end, + }) +end + +return M diff --git a/config/nvim/lua/core/mappings.lua b/config/nvim/lua/core/mappings.lua index d310f2e..5638d38 100644 --- a/config/nvim/lua/core/mappings.lua +++ b/config/nvim/lua/core/mappings.lua @@ -1,207 +1,369 @@ -local utils = require "core.utils" +-- n, v, i, t = mode names -local config = utils.load_config() -local map_wrapper = utils.map - -local maps = config.mappings -local plugin_maps = maps.plugins -local nvChad_options = config.options.nvChad -local terminal_options = config.options.terminal - -local cmd = vim.cmd - --- This is a wrapper function made to disable a plugin mapping from chadrc --- If keys are nil, false or empty string, then the mapping will be not applied --- Useful when one wants to use that keymap for any other purpose -local map = function(...) - local keys = select(2, ...) - if not keys or keys == "" then - return - end - map_wrapper(...) +local function termcodes(str) + return vim.api.nvim_replace_termcodes(str, true, true, true) end local M = {} --- these mappings will only be called during initialization -M.misc = function() - local function non_config_mappings() - -- Don't copy the replaced text after pasting in visual mode - map_wrapper("v", "p", "p:let @+=@0") +M.general = { - -- Allow moving the cursor through wrapped lines with j, k, and - -- http://www.reddit.com/r/vim/comments/2k4cbr/problem_with_gj_and_gk/ - -- empty mode is same as using :map - -- also don't use g[j|k] when in operator pending mode, so it doesn't alter d, y or c behaviour - map_wrapper({ "n", "x", "o" }, "j", 'v:count || mode(1)[0:1] == "no" ? "j" : "gj"', { expr = true }) - map_wrapper({ "n", "x", "o" }, "k", 'v:count || mode(1)[0:1] == "no" ? "k" : "gk"', { expr = true }) - map_wrapper("", "", 'v:count || mode(1)[0:1] == "no" ? "j" : "gj"', { expr = true }) - map_wrapper("", "", 'v:count || mode(1)[0:1] == "no" ? "k" : "gk"', { expr = true }) + i = { - -- use ESC to turn off search highlighting - map_wrapper("n", "", ":noh ") + -- go to beginning and end + [""] = { "^i", "論 beginning of line" }, + [""] = { "", "壟 end of line" }, - -- center cursor when moving (goto_definition) - end + -- navigate within insert mode + [""] = { "", " move left" }, + [""] = { "", " move right" }, + [""] = { "", " move down" }, + [""] = { "", " move up" }, + }, - local function optional_mappings() - -- don't yank text on cut ( x ) - if not nvChad_options.copy_cut then - map_wrapper({ "n", "v" }, "x", '"_x') - end + n = { - -- don't yank text on delete ( dd ) - if not nvChad_options.copy_del then - map_wrapper({ "n", "v" }, "d", '"_d') - end + [""] = { " noh ", " no highlight" }, - -- navigation within insert mode - if nvChad_options.insert_nav then - local inav = maps.insert_nav + -- switch between windows + [""] = { "h", " window left" }, + [""] = { "l", " window right" }, + [""] = { "j", " window down" }, + [""] = { "k", " window up" }, - map("i", inav.backward, "") - map("i", inav.end_of_line, "") - map("i", inav.forward, "") - map("i", inav.next_line, "") - map("i", inav.prev_line, "") - map("i", inav.beginning_of_line, "^i") - end + -- save + [""] = { " w ", "﬚ save file" }, - -- easier navigation between windows - if nvChad_options.window_nav then - local wnav = maps.window_nav + -- Copy all + [""] = { " %y+ ", " copy whole file" }, - map("n", wnav.moveLeft, "h") - map("n", wnav.moveRight, "l") - map("n", wnav.moveUp, "k") - map("n", wnav.moveDown, "j") - end - end + -- line numbers + ["n"] = { " set nu! ", " toggle line number" }, + ["rn"] = { " set rnu! ", " toggle relative number" }, - local function required_mappings() - map("n", maps.misc.cheatsheet, ":lua require('nvchad.cheatsheet').show() ") -- show keybinds - map("n", maps.misc.close_buffer, ":lua require('core.utils').close_buffer() ") -- close buffer - map("n", maps.misc.cp_whole_file, ":%y+ ") -- copy whole file content - map("n", maps.misc.new_buffer, ":enew ") -- new buffer - map("n", maps.misc.new_tab, ":tabnew ") -- new tabs - map("n", maps.misc.lineNR_toggle, ":set nu! ") - map("n", maps.misc.lineNR_rel_toggle, ":set rnu! ") -- relative line numbers - map("n", maps.misc.save_file, ":w ") -- ctrl + s to save file + -- update nvchad + ["uu"] = { " :NvChadUpdate ", " update nvchad" }, + + ["tt"] = { + function() + require("base46").toggle_theme() + end, + + " toggle theme", + }, + }, + + t = { + [""] = { termcodes "", " escape terminal mode" }, + }, +} + +M.tabufline = { + + n = { + -- new buffer + [""] = { " enew ", "烙 new buffer" }, + + -- cycle through buffers + [""] = { " Tbufnext ", " goto next buffer" }, + [""] = { " Tbufprev ", " goto prev buffer" }, + + -- cycle through tabs + ["tp"] = { " tabprevious ", " goto next tab" }, + ["tn"] = { " tabnext ", " goto prev tab" }, + + -- close buffer + hide terminal buffer + ["x"] = { + function() + require("core.utils").close_buffer() + end, + " close buffer", + }, + }, +} + +M.comment = { + + -- toggle comment in both modes + n = { + ["/"] = { + function() + require("Comment.api").toggle_current_linewise() + end, + + "蘒 toggle comment", + }, + }, + + v = { + ["/"] = { + "lua require('Comment.api').toggle_linewise_op(vim.fn.visualmode())", + "蘒 toggle comment", + }, + }, +} + +M.lspconfig = { + -- See ` :help vim.lsp.*` for documentation on any of the below functions + + n = { + ["gD"] = { + function() + vim.lsp.buf.declaration() + end, + " lsp declaration", + }, + + ["gd"] = { + function() + vim.lsp.buf.definition() + end, + " lsp definition", + }, + + ["K"] = { + function() + vim.lsp.buf.hover() + end, + " lsp hover", + }, + + ["gi"] = { + function() + vim.lsp.buf.implementation() + end, + " lsp implementation", + }, + + ["ls"] = { + function() + vim.lsp.buf.signature_help() + end, + " lsp signature_help", + }, + + ["D"] = { + function() + vim.lsp.buf.type_definition() + end, + " lsp definition type", + }, + + ["ra"] = { + function() + require("nvchad.ui.renamer").open() + end, + " lsp rename", + }, + + ["ca"] = { + function() + vim.lsp.buf.code_action() + end, + " lsp code_action", + }, + + ["gr"] = { + function() + vim.lsp.buf.references() + end, + " lsp references", + }, + + ["f"] = { + function() + vim.diagnostic.open_float() + end, + " floating diagnostic", + }, + + ["[d"] = { + function() + vim.diagnostic.goto_prev() + end, + " goto prev", + }, + + ["d]"] = { + function() + vim.diagnostic.goto_next() + end, + " goto_next", + }, + + ["q"] = { + function() + vim.diagnostic.setloclist() + end, + " diagnostic setloclist", + }, + + ["fm"] = { + function() + vim.lsp.buf.formatting() + end, + " lsp formatting", + }, + + ["wa"] = { + function() + vim.lsp.buf.add_workspace_folder() + end, + " add workspace folder", + }, + + ["wr"] = { + function() + vim.lsp.buf.remove_workspace_folder() + end, + " remove workspace folder", + }, + + ["wl"] = { + function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, + " list workspace folders", + }, + }, +} + +M.nvimtree = { + + n = { + -- toggle + [""] = { " NvimTreeToggle ", " toggle nvimtree" }, + + -- focus + ["e"] = { " NvimTreeFocus ", " focus nvimtree" }, + }, +} + +M.telescope = { + n = { + -- find + ["ff"] = { " Telescope find_files ", " find files" }, + ["fa"] = { " Telescope find_files follow=true no_ignore=true hidden=true ", " find all" }, + ["fw"] = { " Telescope live_grep ", " live grep" }, + ["fb"] = { " Telescope buffers ", " find buffers" }, + ["fh"] = { " Telescope help_tags ", " help page" }, + ["fo"] = { " Telescope oldfiles ", " find oldfiles" }, + ["tk"] = { " Telescope keymaps ", " show keys" }, + + -- git + ["cm"] = { " Telescope git_commits ", " git commits" }, + ["gt"] = { " Telescope git_status ", " git status" }, - -- terminal mappings -- - local term_maps = maps.terminal - -- get out of terminal mode - map("t", term_maps.esc_termmode, "") - -- hide a term from within terminal mode - map("t", term_maps.esc_hide_termmode, "lua require('nvchad.terminal').hide() ") -- pick a hidden term - map("n", term_maps.pick_term, ":Telescope terms ") - -- Open terminals - -- TODO this opens on top of an existing vert/hori term, fixme - map( - { "n", "t" }, - term_maps.new_horizontal, - "lua require('nvchad.terminal').new_or_toggle('horizontal', " - .. tostring(terminal_options.window.split_height) - .. ")" - ) - map( - { "n", "t" }, - term_maps.new_vertical, - "lua require('nvchad.terminal').new_or_toggle('vertical', " - .. tostring(terminal_options.window.vsplit_width) - .. ")" - ) - map( - { "n", "t" }, - term_maps.new_float, - "lua require('nvchad.terminal').new_or_toggle('float')" - ) + ["pt"] = { " Telescope terms ", " pick hidden term" }, - -- spawns terminals - map( - "n", - term_maps.spawn_horizontal, - ":execute 15 .. 'new +terminal' | let b:term_type = 'hori' | startinsert " - ) - map("n", term_maps.spawn_vertical, ":execute 'vnew +terminal' | let b:term_type = 'vert' | startinsert ") - map("n", term_maps.spawn_window, ":execute 'terminal' | let b:term_type = 'wind' | startinsert ") + -- theme switcher + ["th"] = { " Telescope themes ", " nvchad themes" }, + }, +} - -- terminal mappings end -- +M.nvterm = { + t = { + -- toggle in terminal mode + [""] = { + function() + require("nvterm.terminal").toggle "float" + end, + " toggle floating term", + }, - -- Add Packer commands because we are not loading it at startup - cmd "silent! command PackerClean lua require 'plugins' require('packer').clean()" - cmd "silent! command PackerCompile lua require 'plugins' require('packer').compile()" - cmd "silent! command PackerInstall lua require 'plugins' require('packer').install()" - cmd "silent! command PackerStatus lua require 'plugins' require('packer').status()" - cmd "silent! command PackerSync lua require 'plugins' require('packer').sync()" - cmd "silent! command PackerUpdate lua require 'plugins' require('packer').update()" + [""] = { + function() + require("nvterm.terminal").toggle "horizontal" + end, + " toggle horizontal term", + }, - -- add NvChadUpdate command and mapping - cmd "silent! command! NvChadUpdate lua require('nvchad').update_nvchad()" - map("n", maps.misc.update_nvchad, ":NvChadUpdate ") - end + [""] = { + function() + require("nvterm.terminal").toggle "vertical" + end, + " toggle vertical term", + }, + }, - non_config_mappings() - optional_mappings() - required_mappings() -end + n = { + -- toggle in normal mode + [""] = { + function() + require("nvterm.terminal").toggle "float" + end, + " toggle floating term", + }, --- below are all plugin related mappings + [""] = { + function() + require("nvterm.terminal").toggle "horizontal" + end, + " toggle horizontal term", + }, -M.bufferline = function() - local m = plugin_maps.bufferline + [""] = { + function() + require("nvterm.terminal").toggle "vertical" + end, + " toggle vertical term", + }, - map("n", m.next_buffer, ":BufferLineCycleNext ") - map("n", m.prev_buffer, ":BufferLineCyclePrev ") -end + -- new -M.comment = function() - local m = plugin_maps.comment.toggle - map("n", m, ":lua require('Comment.api').toggle_current_linewise()") - map("v", m, ":lua require('Comment.api').toggle_linewise_op(vim.fn.visualmode())") -end + ["h"] = { + function() + require("nvterm.terminal").new "horizontal" + end, + " new horizontal term", + }, -M.lspconfig = function() - local m = plugin_maps.lspconfig + ["v"] = { + function() + require("nvterm.terminal").new "vertical" + end, + " new vertical term", + }, + }, +} - -- See `:help vim.lsp.*` for documentation on any of the below functions - map("n", m.declaration, "lua vim.lsp.buf.declaration()") - map("n", m.definition, "lua vim.lsp.buf.definition()") - map("n", m.hover, "lua vim.lsp.buf.hover()") - map("n", m.implementation, "lua vim.lsp.buf.implementation()") - map("n", m.signature_help, "lua vim.lsp.buf.signature_help()") - map("n", m.add_workspace_folder, "lua vim.lsp.buf.add_workspace_folder()") - map("n", m.remove_workspace_folder, "lua vim.lsp.buf.remove_workspace_folder()") - map("n", m.list_workspace_folders, "lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))") - map("n", m.type_definition, "lua vim.lsp.buf.type_definition()") - map("n", m.rename, "lua vim.lsp.buf.rename()") - map("n", m.code_action, "lua vim.lsp.buf.code_action()") - map("n", m.references, "lua vim.lsp.buf.references()") - map("n", m.float_diagnostics, "lua vim.diagnostic.open_float()") - map("n", m.goto_prev, "lua vim.diagnostic.goto_prev()") - map("n", m.goto_next, "lua vim.diagnostic.goto_next()") - map("n", m.set_loclist, "lua vim.diagnostic.setloclist()") - map("n", m.formatting, "lua vim.lsp.buf.formatting()") -end +M.whichkey = { + n = { + ["wK"] = { + function() + vim.cmd "WhichKey" + end, + " which-key all keymaps", + }, + ["wk"] = { + function() + local input = vim.fn.input "WhichKey: " + vim.cmd("WhichKey " .. input) + end, + " which-key query lookup", + }, + }, +} -M.nvimtree = function() - map("n", plugin_maps.nvimtree.toggle, ":NvimTreeToggle ") - map("n", plugin_maps.nvimtree.focus, ":NvimTreeFocus ") -end +M.blankline = { + n = { + ["bc"] = { + function() + local ok, start = require("indent_blankline.utils").get_current_context( + vim.g.indent_blankline_context_patterns, + vim.g.indent_blankline_use_treesitter_scope + ) -M.telescope = function() - local m = plugin_maps.telescope + if ok then + vim.api.nvim_win_set_cursor(vim.api.nvim_get_current_win(), { start, 0 }) + vim.cmd [[normal! _]] + end + end, - map("n", m.buffers, ":Telescope buffers ") - map("n", m.find_files, ":Telescope find_files ") - map("n", m.find_hiddenfiles, ":Telescope find_files follow=true no_ignore=true hidden=true ") - map("n", m.git_commits, ":Telescope git_commits ") - map("n", m.git_status, ":Telescope git_status ") - map("n", m.help_tags, ":Telescope help_tags ") - map("n", m.live_grep, ":Telescope live_grep ") - map("n", m.oldfiles, ":Telescope oldfiles ") - map("n", m.themes, ":Telescope themes ") -end + " Jump to current_context", + }, + }, +} return M diff --git a/config/nvim/lua/core/options.lua b/config/nvim/lua/core/options.lua index 06f669c..9df3027 100644 --- a/config/nvim/lua/core/options.lua +++ b/config/nvim/lua/core/options.lua @@ -1,31 +1,38 @@ local opt = vim.opt local g = vim.g +local config = require("core.utils").load_config() -local options = require("core.utils").load_config().options +g.nvchad_theme = config.ui.theme +g.toggle_theme_icon = "  " +g.transparency = config.ui.transparency +g.theme_switcher_loaded = false + +-- use filetype.lua instead of filetype.vim +g.did_load_filetypes = 0 +g.do_filetype_lua = 1 + +opt.laststatus = 3 -- global statusline +opt.statusline = config.ui.statusline.config +opt.showmode = false opt.title = true -opt.clipboard = options.clipboard -opt.cmdheight = options.cmdheight +opt.clipboard = "unnamedplus" opt.cul = true -- cursor line --- Indentline -opt.expandtab = options.expandtab -opt.shiftwidth = options.shiftwidth -opt.smartindent = options.smartindent +-- Indenting +opt.expandtab = true +opt.shiftwidth = 2 +opt.smartindent = true --- disable tilde on end of buffer: https://github.com/neovim/neovim/pull/8546#issuecomment-643643758 -opt.fillchars = options.fillchars - -opt.hidden = options.hidden -opt.ignorecase = options.ignorecase -opt.smartcase = options.smartcase -opt.mouse = options.mouse +opt.fillchars = { eob = " " } +opt.ignorecase = true +opt.smartcase = true +opt.mouse = "a" -- Numbers -opt.number = options.number -opt.numberwidth = options.numberwidth -opt.relativenumber = options.relativenumber -opt.ruler = options.ruler +opt.number = true +opt.numberwidth = 2 +opt.ruler = false -- disable nvim intro opt.shortmess:append "sI" @@ -33,31 +40,70 @@ opt.shortmess:append "sI" opt.signcolumn = "yes" opt.splitbelow = true opt.splitright = true -opt.tabstop = options.tabstop +opt.tabstop = 8 opt.termguicolors = true -opt.timeoutlen = options.timeoutlen -opt.undofile = options.undofile +opt.timeoutlen = 400 +opt.undofile = true -- interval for writing swap file to disk, also used by gitsigns -opt.updatetime = options.updatetime +opt.updatetime = 250 -- go to previous/next line with h,l,left arrow and right arrow -- when cursor reaches end/beginning of line opt.whichwrap:append "<>[]hl" -g.mapleader = options.mapleader +g.mapleader = " " -- disable some builtin vim plugins -local disabled_built_ins = require("core.utils").load_config().plugins.builtins +local default_plugins = { + "2html_plugin", + "getscript", + "getscriptPlugin", + "gzip", + "logipat", + "netrw", + "netrwPlugin", + "netrwSettings", + "netrwFileHandlers", + "matchit", + "tar", + "tarPlugin", + "rrhelper", + "spellfile_plugin", + "vimball", + "vimballPlugin", + "zip", + "zipPlugin", + "tutor", + "rplugin", + "syntax", + "synmenu", + "optwin", + "compiler", + "bugreport", + "ftplugin", +} -for _, plugin in pairs(disabled_built_ins) do +for _, plugin in pairs(default_plugins) do g["loaded_" .. plugin] = 1 end ---Defer loading shada until after startup_ -vim.opt.shadafile = "NONE" +local default_providers = { + "node", + "perl", + "python3", + "ruby", +} +for _, provider in ipairs(default_providers) do + vim.g["loaded_" .. provider .. "_provider"] = 0 +end + +-- set shada path vim.schedule(function() - vim.opt.shadafile = require("core.utils").load_config().options.shadafile + vim.opt.shadafile = vim.fn.expand "$HOME" .. "/.local/share/nvim/shada/main.shada" vim.cmd [[ silent! rsh ]] end) + +-- load user options +config.options.user() diff --git a/config/nvim/lua/core/packer.lua b/config/nvim/lua/core/packer.lua new file mode 100644 index 0000000..575cefc --- /dev/null +++ b/config/nvim/lua/core/packer.lua @@ -0,0 +1,59 @@ +local M = {} + +M.bootstrap = function() + local fn = vim.fn + local install_path = fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim" + + vim.api.nvim_set_hl(0, "NormalFloat", { bg = "#1e222a" }) + + if fn.empty(fn.glob(install_path)) > 0 then + print "Cloning packer .." + fn.system { "git", "clone", "--depth", "1", "https://github.com/wbthomason/packer.nvim", install_path } + + -- install plugins + compile their configs + vim.cmd "packadd packer.nvim" + require "plugins" + vim.cmd "PackerSync" + end +end + +M.options = { + auto_clean = true, + compile_on_sync = true, + git = { clone_timeout = 6000 }, + display = { + working_sym = "ﲊ", + error_sym = "✗ ", + done_sym = " ", + removed_sym = " ", + moved_sym = "", + open_fn = function() + return require("packer.util").float { border = "single" } + end, + }, +} + +-- merge overrides if there are any +M.options = require("core.utils").load_override(M.options, "wbthomason/packer.nvim") + +M.run = function(plugins) + local present, packer = pcall(require, "packer") + + if not present then + return + end + + -- Override with chadrc values + plugins = require("core.utils").remove_default_plugins(plugins) + plugins = require("core.utils").merge_plugins(plugins) + + packer.init(M.options) + + packer.startup(function(use) + for _, v in pairs(plugins) do + use(v) + end + end) +end + +return M diff --git a/config/nvim/lua/core/utils.lua b/config/nvim/lua/core/utils.lua index bfda660..6a57d26 100644 --- a/config/nvim/lua/core/utils.lua +++ b/config/nvim/lua/core/utils.lua @@ -1,321 +1,231 @@ local M = {} +local api = vim.api -local cmd = vim.cmd -M.close_buffer = function(force) - -- This is a modification of a NeoVim plugin from - -- Author: ojroques - Olivier Roques - -- Src: https://github.com/ojroques/nvim-bufdel - -- (Author has okayed copy-paste) +local merge_tb = vim.tbl_deep_extend - -- Options - local opts = { - next = "cycle", -- how to retrieve the next buffer - quit = false, -- exit when last buffer is deleted - --TODO make this a chadrc flag/option - } - - -- ---------------- - -- Helper functions - -- ---------------- - - -- Switch to buffer 'buf' on each window from list 'windows' - local function switch_buffer(windows, buf) - local cur_win = vim.fn.winnr() - for _, winid in ipairs(windows) do - winid = tonumber(winid) or 0 - vim.cmd(string.format("%d wincmd w", vim.fn.win_id2win(winid))) - vim.cmd(string.format("buffer %d", buf)) - end - vim.cmd(string.format("%d wincmd w", cur_win)) -- return to original window - end - - -- Select the first buffer with a number greater than given buffer - local function get_next_buf(buf) - local next = vim.fn.bufnr "#" - if opts.next == "alternate" and vim.fn.buflisted(next) == 1 then - return next - end - for i = 0, vim.fn.bufnr "$" - 1 do - next = (buf + i) % vim.fn.bufnr "$" + 1 -- will loop back to 1 - if vim.fn.buflisted(next) == 1 then - return next - end - end - end - - -- ---------------- - -- End helper functions - -- ---------------- - - local buf = vim.fn.bufnr() - if vim.fn.buflisted(buf) == 0 then -- exit if buffer number is invalid - vim.cmd "close" - return - end - - if #vim.fn.getbufinfo { buflisted = 1 } < 2 then - if opts.quit then - -- exit when there is only one buffer left - if force then - vim.cmd "qall!" - else - vim.cmd "confirm qall" - end - return - end - - local chad_term, _ = pcall(function() - return vim.api.nvim_buf_get_var(buf, "term_type") - end) - - if chad_term then - -- Must be a window type - vim.cmd(string.format("setlocal nobl", buf)) - vim.cmd "enew" - return - end - -- don't exit and create a new empty buffer - vim.cmd "enew" - vim.cmd "bp" - end - - local next_buf = get_next_buf(buf) - local windows = vim.fn.getbufinfo(buf)[1].windows - - -- force deletion of terminal buffers to avoid the prompt - if force or vim.fn.getbufvar(buf, "&buftype") == "terminal" then - local chad_term, type = pcall(function() - return vim.api.nvim_buf_get_var(buf, "term_type") - end) - - -- TODO this scope is error prone, make resilient - if chad_term then - if type == "wind" then - -- hide from bufferline - vim.cmd(string.format("%d bufdo setlocal nobl", buf)) - -- switch to another buff - -- TODO switch to next buffer, this works too - vim.cmd "BufferLineCycleNext" - else - local cur_win = vim.fn.winnr() - -- we can close this window - vim.cmd(string.format("%d wincmd c", cur_win)) - return - end - else - switch_buffer(windows, next_buf) - vim.cmd(string.format("bd! %d", buf)) - end +M.close_buffer = function(bufnr) + if vim.bo.buftype == "terminal" then + vim.cmd(vim.bo.buflisted and "set nobl | enew" or "hide") + elseif vim.bo.modified then + print "save the file bruh" else - switch_buffer(windows, next_buf) - vim.cmd(string.format("silent! confirm bd %d", buf)) + bufnr = bufnr or api.nvim_get_current_buf() + require("core.utils").tabuflinePrev() + vim.cmd("bd" .. bufnr) end - -- revert buffer switches if user has canceled deletion - if vim.fn.buflisted(buf) == 1 then - switch_buffer(windows, buf) - end -end - --- hide statusline --- tables fetched from load_config function -M.hide_statusline = function() - local hidden = require("core.utils").load_config().plugins.options.statusline.hidden - local shown = require("core.utils").load_config().plugins.options.statusline.shown - local api = vim.api - local buftype = api.nvim_buf_get_option(0, "ft") - - -- shown table from config has the highest priority - if vim.tbl_contains(shown, buftype) then - api.nvim_set_option("laststatus", 2) - return - end - - if vim.tbl_contains(hidden, buftype) then - api.nvim_set_option("laststatus", 0) - return - end - - api.nvim_set_option("laststatus", 2) end M.load_config = function() - local conf = require "core.default_config" + local config = require "core.default_config" + local chadrc_exists, chadrc = pcall(require, "custom.chadrc") - -- attempt to load and merge a user config - local chadrc_exists = vim.fn.filereadable(vim.fn.stdpath "config" .. "/lua/custom/chadrc.lua") == 1 if chadrc_exists then -- merge user config if it exists and is a table; otherwise display an error - local user_config = require "custom.chadrc" - if type(user_config) == 'table' then - conf = vim.tbl_deep_extend("force", conf, user_config) + if type(chadrc) == "table" then + M.remove_default_keys() + config = merge_tb("force", config, chadrc) else - error("User config (chadrc.lua) *must* return a table!") + error "chadrc must return a table!" end end - return conf + config.mappings.disabled = nil + return config end -M.map = function(mode, keys, command, opt) - local options = { noremap = true, silent = true } - if opt then - options = vim.tbl_extend("force", options, opt) +M.remove_default_keys = function() + local chadrc = require "custom.chadrc" + local user_mappings = chadrc.mappings or {} + local user_keys = {} + local user_sections = vim.tbl_keys(user_mappings) + + -- push user_map keys in user_keys table + for _, section in ipairs(user_sections) do + user_keys = vim.tbl_deep_extend("force", user_keys, user_mappings[section]) end - -- all valid modes allowed for mappings - -- :h map-modes - local valid_modes = { - [""] = true, - ["n"] = true, - ["v"] = true, - ["s"] = true, - ["x"] = true, - ["o"] = true, - ["!"] = true, - ["i"] = true, - ["l"] = true, - ["c"] = true, - ["t"] = true, - } + local function disable_key(mode, keybind, mode_mapping) + local keys_in_mode = vim.tbl_keys(user_keys[mode] or {}) - -- helper function for M.map - -- can gives multiple modes and keys - local function map_wrapper(sub_mode, lhs, rhs, sub_options) - if type(lhs) == "table" then - for _, key in ipairs(lhs) do - map_wrapper(sub_mode, key, rhs, sub_options) - end - else - if type(sub_mode) == "table" then - for _, m in ipairs(sub_mode) do - map_wrapper(m, lhs, rhs, sub_options) - end - else - if valid_modes[sub_mode] and lhs and rhs then - vim.api.nvim_set_keymap(sub_mode, lhs, rhs, sub_options) - else - sub_mode, lhs, rhs = sub_mode or "", lhs or "", rhs or "" - print( - "Cannot set mapping [ mode = '" .. sub_mode .. "' | key = '" .. lhs .. "' | cmd = '" .. rhs .. "' ]" - ) - end - end + if vim.tbl_contains(keys_in_mode, keybind) then + mode_mapping[keybind] = nil end end - map_wrapper(mode, keys, command, options) -end + local default_mappings = require("core.default_config").mappings --- load plugin after entering vim ui -M.packer_lazy_load = function(plugin, timer) - if plugin then - timer = timer or 0 - vim.defer_fn(function() - require("packer").loader(plugin) - end, timer) + -- remove user_maps from default mapping table + for _, section_mappings in pairs(default_mappings) do + for mode, mode_mapping in pairs(section_mappings) do + for keybind, _ in pairs(mode_mapping) do + disable_key(mode, keybind, mode_mapping) + end + end end end --- Highlights functions +M.load_mappings = function(mappings, mapping_opt) + -- set mapping function with/without whichkey + local map_func + local whichkey_exists, wk = pcall(require, "which-key") --- Define bg color --- @param group Group --- @param color Color - -M.bg = function(group, col) - cmd("hi " .. group .. " guibg=" .. col) -end - --- Define fg color --- @param group Group --- @param color Color -M.fg = function(group, col) - cmd("hi " .. group .. " guifg=" .. col) -end - --- Define bg and fg color --- @param group Group --- @param fgcol Fg Color --- @param bgcol Bg Color -M.fg_bg = function(group, fgcol, bgcol) - cmd("hi " .. group .. " guifg=" .. fgcol .. " guibg=" .. bgcol) -end - --- Override default config of a plugin based on the path provided in the chadrc --- Arguments: --- 1st - name of plugin --- 2nd - default config path --- 3rd - optional function name which will called from default_config path --- e.g: if given args - "telescope", "plugins.configs.telescope", "setup" --- then return "require('plugins.configs.telescope').setup()" --- if 3rd arg not given, then return "require('plugins.configs.telescope')" --- if override is a table, mark set the override flag for the default config to true --- override flag being true tells the plugin to call tbl_override_req as part of configuration - -M.override_req = function(name, default_config, config_function) - local override, apply_table_override = - require("core.utils").load_config().plugins.default_plugin_config_replace[name], "false" - local result = default_config - if type(override) == "string" and override ~= "" then - return "require('" .. override .. "')" - elseif type(override) == "table" then - apply_table_override = "true" - elseif type(override) == "function" then - return override + if whichkey_exists then + map_func = function(keybind, mapping_info, opts) + wk.register({ [keybind] = mapping_info }, opts) + end + else + map_func = function(keybind, mapping_info, opts) + local mode = opts.mode + opts.mode = nil + vim.keymap.set(mode, keybind, mapping_info[1], opts) + end end - result = "('" .. result .. "')" - if type(config_function) == "string" and config_function ~= "" then - -- add the . to call the functions and concatenate true or false as argument - result = result .. "." .. config_function .. "(" .. apply_table_override .. ")" + mappings = mappings or vim.deepcopy(M.load_config().mappings) + mappings.lspconfig = nil + + for _, section_mappings in pairs(mappings) do + -- skip mapping this as its mapppings are loaded in lspconfig + for mode, mode_mappings in pairs(section_mappings) do + for keybind, mapping_info in pairs(mode_mappings) do + -- merge default + user opts + + local default_opts = merge_tb("force", { mode = mode }, mapping_opt or {}) + local opts = merge_tb("force", default_opts, mapping_info.opts or {}) + + if mapping_info.opts then + mapping_info.opts = nil + end + + map_func(keybind, mapping_info, opts) + end + end end - - return "require" .. result end --- Override parts of default config of a plugin based on the table provided in the chadrc - --- FUNCTION: tbl_override_req, use `chadrc` plugin config override to modify default config if present --- name = name inside `default_config` / `chadrc` --- default_table = the default configuration table of the plugin --- returns the modified configuration table -M.tbl_override_req = function(name, default_table) - local override = require("core.utils").load_config().plugins.default_plugin_config_replace[name] or {} - return vim.tbl_deep_extend("force", default_table, override) -end - ---provide labels to plugins instead of integers -M.label_plugins = function(plugins) - local plugins_labeled = {} - for _, plugin in ipairs(plugins) do - plugins_labeled[plugin[1]] = plugin - end - return plugins_labeled -end - --- remove plugins specified by user from the plugins table +-- remove plugins defined in chadrc M.remove_default_plugins = function(plugins) - local removals = require("core.utils").load_config().plugins.default_plugin_remove or {} + local removals = M.load_config().plugins.remove or {} + if not vim.tbl_isempty(removals) then for _, plugin in pairs(removals) do plugins[plugin] = nil end end + return plugins end --- append user plugins to default plugins -M.add_user_plugins = function(plugins) - local user_Plugins = require("core.utils").load_config().plugins.install or {} - if type(user_Plugins) == "string" - then user_Plugins=require(user_Plugins) +-- merge default/user plugin tables +M.merge_plugins = function(default_plugins) + local user_plugins = M.load_config().plugins.user + + -- merge default + user plugin table + default_plugins = merge_tb("force", default_plugins, user_plugins) + + local final_table = {} + + for key, _ in pairs(default_plugins) do + default_plugins[key][1] = key + + final_table[#final_table + 1] = default_plugins[key] end - if not vim.tbl_isempty(user_Plugins) then - for _, v in pairs(user_Plugins) do - plugins[v[1]] = v + + return final_table +end + +M.load_override = function(default_table, plugin_name) + local user_table = M.load_config().plugins.override[plugin_name] or {} + user_table = type(user_table) == "table" and user_table or user_table() + return merge_tb("force", default_table, user_table) +end + +M.packer_sync = function(...) + local git_exists, git = pcall(require, "nvchad.utils.git") + local defaults_exists, defaults = pcall(require, "nvchad.utils.config") + local packer_exists, packer = pcall(require, "packer") + + if git_exists and defaults_exists then + local current_branch_name = git.get_current_branch_name() + + -- warn the user if we are on a snapshot branch + if current_branch_name:match(defaults.snaps.base_snap_branch_name .. "(.+)" .. "$") then + vim.api.nvim_echo({ + { "WARNING: You are trying to use ", "WarningMsg" }, + { "PackerSync" }, + { + " on a NvChadSnapshot. This will cause issues if NvChad dependencies contain " + .. "any breaking changes! Plugin updates will not be included in this " + .. "snapshot, so they will be lost after switching between snapshots! Would " + .. "you still like to continue? [y/N]\n", + "WarningMsg", + }, + }, false, {}) + + local ans = vim.trim(string.lower(vim.fn.input "-> ")) + + if ans ~= "y" then + return + end end end - return plugins + + if packer_exists then + packer.sync(...) + else + error "Packer could not be loaded!" + end +end + +M.bufilter = function() + local bufs = vim.t.bufs + + for i = #bufs, 1, -1 do + if not vim.api.nvim_buf_is_valid(bufs[i]) then + table.remove(bufs, i) + end + end + + return bufs +end + +M.tabuflineNext = function() + local bufs = M.bufilter() or {} + + for i, v in ipairs(bufs) do + if api.nvim_get_current_buf() == v then + vim.cmd(i == #bufs and "b" .. bufs[1] or "b" .. bufs[i + 1]) + break + end + end +end + +M.tabuflinePrev = function() + local bufs = M.bufilter() or {} + + for i, v in ipairs(bufs) do + if api.nvim_get_current_buf() == v then + vim.cmd(i == 1 and "b" .. bufs[#bufs] or "b" .. bufs[i - 1]) + break + end + end +end + +-- closes tab + all of its buffers +M.closeAllBufs = function(action) + local bufs = vim.t.bufs + + if action == "closeTab" then + vim.cmd "tabclose" + end + + for _, buf in ipairs(bufs) do + M.close_buffer(buf) + end + + if action ~= "closeTab" then + vim.cmd "enew" + end end return M diff --git a/config/nvim/lua/custom/chadrc.lua b/config/nvim/lua/custom/chadrc.lua index b2aaa45..3078ccf 100644 --- a/config/nvim/lua/custom/chadrc.lua +++ b/config/nvim/lua/custom/chadrc.lua @@ -2,16 +2,11 @@ local M = {} -local userPlugins = require "custom.plugins" -- make sure you maintain the structure of `core/default_config.lua` here, -- example of changing theme: M.ui = { - theme = "tokyonight", -} --- /lua/custom/chadrc.lualocal userPlugins = require "custom.plugins" -- path to table -M.plugins = { - install = userPlugins + theme = "rxyhn", } return M diff --git a/config/nvim/lua/plugins/configs/alpha.lua b/config/nvim/lua/plugins/configs/alpha.lua index 573bbca..319ea50 100644 --- a/config/nvim/lua/plugins/configs/alpha.lua +++ b/config/nvim/lua/plugins/configs/alpha.lua @@ -4,6 +4,8 @@ if not present then return end +require("base46").load_highlight "alpha" + local function button(sc, txt, keybind) local sc_ = sc:gsub("%s", ""):gsub("SPC", "") @@ -32,9 +34,9 @@ local function button(sc, txt, keybind) } end -local default = {} +local options = {} -default.ascii = { +local ascii = { " ⣴⣶⣤⡤⠦⣤⣀⣤⠆ ⣈⣭⣿⣶⣿⣦⣼⣆ ", " ⠉⠻⢿⣿⠿⣿⣿⣶⣦⠤⠄⡠⢾⣿⣿⡿⠋⠉⠉⠻⣿⣿⡛⣦ ", " ⠈⢿⣿⣟⠦ ⣾⣿⣿⣷ ⠻⠿⢿⣿⣧⣄ ", @@ -48,16 +50,16 @@ default.ascii = { " ⠻⣿⣿⣿⣿⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⡟⢀⣀⣤⣾⡿⠃ ", } -default.header = { +options.header = { type = "text", - val = default.ascii, + val = ascii, opts = { position = "center", hl = "AlphaHeader", }, } -default.buttons = { +options.buttons = { type = "group", val = { button("SPC f f", " Find File ", ":Telescope find_files"), @@ -72,21 +74,19 @@ default.buttons = { }, } -local M = {} +options = require("core.utils").load_override(options, "goolord/alpha-nvim") -M.setup = function(override_flag) - if override_flag then - default = require("core.utils").tbl_override_req("alpha", default) - end - alpha.setup { - layout = { - { type = "padding", val = 9 }, - default.header, - { type = "padding", val = 2 }, - default.buttons, - }, - opts = {}, - } -end +-- dynamic header padding +local fn = vim.fn +local marginTopPercent = 0.3 +local headerPadding = fn.max { 2, fn.floor(fn.winheight(0) * marginTopPercent) } -return M +alpha.setup { + layout = { + { type = "padding", val = headerPadding }, + options.header, + { type = "padding", val = 2 }, + options.buttons, + }, + opts = {}, +} diff --git a/config/nvim/lua/plugins/configs/cmp.lua b/config/nvim/lua/plugins/configs/cmp.lua index 02b77e9..3433fdb 100644 --- a/config/nvim/lua/plugins/configs/cmp.lua +++ b/config/nvim/lua/plugins/configs/cmp.lua @@ -4,25 +4,51 @@ if not present then return end +require("base46").load_highlight "cmp" + vim.opt.completeopt = "menuone,noselect" -local default = { +local function border(hl_name) + return { + { "╭", hl_name }, + { "─", hl_name }, + { "╮", hl_name }, + { "│", hl_name }, + { "╯", hl_name }, + { "─", hl_name }, + { "╰", hl_name }, + { "│", hl_name }, + } +end + +local cmp_window = require "cmp.utils.window" + +cmp_window.info_ = cmp_window.info +cmp_window.info = function(self) + local info = self:info_() + info.scrollable = false + return info +end + +local options = { + window = { + completion = { + border = border "CmpBorder", + winhighlight = "Normal:CmpPmenu,CursorLine:PmenuSel,Search:None", + }, + documentation = { + border = border "CmpDocBorder", + }, + }, snippet = { expand = function(args) require("luasnip").lsp_expand(args.body) end, }, formatting = { - format = function(entry, vim_item) - local icons = require "plugins.configs.lspkind_icons" + format = function(_, vim_item) + local icons = require("ui.icons").lspkind vim_item.kind = string.format("%s %s", icons[vim_item.kind], vim_item.kind) - - vim_item.menu = ({ - nvim_lsp = "[LSP]", - nvim_lua = "[Lua]", - buffer = "[BUF]", - })[entry.source.name] - return vim_item end, }, @@ -35,7 +61,7 @@ local default = { [""] = cmp.mapping.close(), [""] = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace, - select = true, + select = false, }, [""] = cmp.mapping(function(fallback) if cmp.visible() then @@ -45,7 +71,10 @@ local default = { else fallback() end - end, { "i", "s" }), + end, { + "i", + "s", + }), [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() @@ -54,23 +83,21 @@ local default = { else fallback() end - end, { "i", "s" }), + end, { + "i", + "s", + }), }, sources = { - { name = "nvim_lsp" }, { name = "luasnip" }, + { name = "nvim_lsp" }, { name = "buffer" }, { name = "nvim_lua" }, { name = "path" }, }, } -local M = {} -M.setup = function(override_flag) - if override_flag then - default = require("core.utils").tbl_override_req("nvim_cmp", default) - end - cmp.setup(default) -end +-- check for any override +options = require("core.utils").load_override(options, "hrsh7th/nvim-cmp") -return M +cmp.setup(options) diff --git a/config/nvim/lua/plugins/configs/lsp_installer.lua b/config/nvim/lua/plugins/configs/lsp_installer.lua new file mode 100644 index 0000000..4a78c3d --- /dev/null +++ b/config/nvim/lua/plugins/configs/lsp_installer.lua @@ -0,0 +1,36 @@ +local present, lsp_installer = pcall(require, "nvim-lsp-installer") + +if not present then + return +end + +local options = { + -- ensure_installed is not needed as automatic_installation is enabled + -- then any lsp server you setup by lspconfig is going to get installed automatically! + + -- ensure_installed = { "lua" }, + automatic_installation = true, + + ui = { + icons = { + server_installed = " ", + server_pending = " ", + server_uninstalled = " ﮊ", + }, + keymaps = { + toggle_server_expand = "", + install_server = "i", + update_server = "u", + check_server_version = "c", + update_all_servers = "U", + check_outdated_servers = "C", + uninstall_server = "X", + }, + }, + + max_concurrent_installers = 10, +} + +options = require("core.utils").load_override(options, "williamboman/nvim-lsp-installer") + +lsp_installer.setup(options) diff --git a/config/nvim/lua/plugins/configs/lspconfig.lua b/config/nvim/lua/plugins/configs/lspconfig.lua index 962cfeb..9a62a3e 100644 --- a/config/nvim/lua/plugins/configs/lspconfig.lua +++ b/config/nvim/lua/plugins/configs/lspconfig.lua @@ -1,38 +1,71 @@ +local present, lspconfig = pcall(require, "lspconfig") + +if not present then + return +end + +require("base46").load_highlight "lsp" + local M = {} -require("plugins.configs.others").lsp_handlers() +local utils = require "core.utils" -function M.on_attach(client, bufnr) - local function buf_set_option(...) - vim.api.nvim_buf_set_option(bufnr, ...) - end +require "ui.lsp" +M.on_attach = function(client, bufnr) client.resolved_capabilities.document_formatting = false client.resolved_capabilities.document_range_formatting = false - -- Enable completion triggered by - buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc") - require("core.mappings").lspconfig() + local lsp_mappings = utils.load_config().mappings.lspconfig + utils.load_mappings({ lsp_mappings }, { buffer = bufnr }) + + if client.server_capabilities.signatureHelpProvider then + require("nvchad.ui.signature").setup(client) + end end local capabilities = vim.lsp.protocol.make_client_capabilities() -capabilities.textDocument.completion.completionItem.documentationFormat = { "markdown", "plaintext" } -capabilities.textDocument.completion.completionItem.snippetSupport = true -capabilities.textDocument.completion.completionItem.preselectSupport = true -capabilities.textDocument.completion.completionItem.insertReplaceSupport = true -capabilities.textDocument.completion.completionItem.labelDetailsSupport = true -capabilities.textDocument.completion.completionItem.deprecatedSupport = true -capabilities.textDocument.completion.completionItem.commitCharactersSupport = true -capabilities.textDocument.completion.completionItem.tagSupport = { valueSet = { 1 } } -capabilities.textDocument.completion.completionItem.resolveSupport = { - properties = { - "documentation", - "detail", - "additionalTextEdits", + +capabilities.textDocument.completion.completionItem = { + documentationFormat = { "markdown", "plaintext" }, + snippetSupport = true, + preselectSupport = true, + insertReplaceSupport = true, + labelDetailsSupport = true, + deprecatedSupport = true, + commitCharactersSupport = true, + tagSupport = { valueSet = { 1 } }, + resolveSupport = { + properties = { + "documentation", + "detail", + "additionalTextEdits", + }, + }, +} + +lspconfig.sumneko_lua.setup { + on_attach = M.on_attach, + capabilities = capabilities, + + settings = { + Lua = { + diagnostics = { + globals = { "vim" }, + }, + workspace = { + library = { + [vim.fn.expand "$VIMRUNTIME/lua"] = true, + [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true, + }, + maxPreload = 100000, + preloadFileSize = 10000, + }, + }, }, } -- requires a file containing user's lspconfigs -local addlsp_confs = require("core.utils").load_config().plugins.options.lspconfig.setup_lspconf +local addlsp_confs = utils.load_config().plugins.options.lspconfig.setup_lspconf if #addlsp_confs ~= 0 then require(addlsp_confs).setup_lsp(M.on_attach, capabilities) diff --git a/config/nvim/lua/plugins/configs/nvimtree.lua b/config/nvim/lua/plugins/configs/nvimtree.lua index a93a102..5a75101 100644 --- a/config/nvim/lua/plugins/configs/nvimtree.lua +++ b/config/nvim/lua/plugins/configs/nvimtree.lua @@ -1,54 +1,20 @@ --- globals must be set prior to requiring nvim-tree to function -local g = vim.g - -g.nvim_tree_add_trailing = 0 -- append a trailing slash to folder names -g.nvim_tree_git_hl = 0 -g.nvim_tree_highlight_opened_files = 0 -g.nvim_tree_root_folder_modifier = table.concat { ":t:gs?$?/..", string.rep(" ", 1000), "?:gs?^??" } - -g.nvim_tree_show_icons = { - folders = 1, - files = 1, - git = 1, -} - -g.nvim_tree_icons = { - default = "", - symlink = "", - git = { - deleted = "", - ignored = "◌", - renamed = "➜", - staged = "✓", - unmerged = "", - unstaged = "✗", - untracked = "★", - }, - folder = { - default = "", - empty = "", - empty_open = "", - open = "", - symlink = "", - symlink_open = "", - }, -} - local present, nvimtree = pcall(require, "nvim-tree") if not present then return end -local default = { +require("base46").load_highlight "nvimtree" + +local options = { filters = { dotfiles = false, + exclude = { vim.fn.stdpath "config" .. "/lua/custom" }, }, disable_netrw = true, hijack_netrw = true, - ignore_ft_on_setup = { "dashboard" }, - auto_close = false, - open_on_tab = false, + open_on_setup = false, + ignore_ft_on_setup = { "alpha" }, hijack_cursor = true, hijack_unnamed_buffer_when_opening = false, update_cwd = true, @@ -57,34 +23,67 @@ local default = { update_cwd = false, }, view = { - allow_resize = true, + adaptive_size = true, side = "left", width = 25, hide_root_folder = true, }, git = { enable = false, - ignore = false, + ignore = true, }, + filesystem_watchers = { + enable = true, + }, actions = { open_file = { resize_window = true, }, }, renderer = { + highlight_git = false, + highlight_opened_files = "none", + indent_markers = { - enable = true, - } - } + enable = false, + }, + + icons = { + show = { + file = true, + folder = true, + folder_arrow = true, + git = false, + }, + + glyphs = { + default = "", + symlink = "", + folder = { + default = "", + empty = "", + empty_open = "", + open = "", + symlink = "", + symlink_open = "", + arrow_open = "", + arrow_closed = "", + }, + git = { + unstaged = "✗", + staged = "✓", + unmerged = "", + renamed = "➜", + untracked = "★", + deleted = "", + ignored = "◌", + }, + }, + }, + }, } -local M = {} +-- check for any override +options = require("core.utils").load_override(options, "kyazdani42/nvim-tree.lua") -M.setup = function(override_flag) - if override_flag then - default = require("core.utils").tbl_override_req("nvim_tree", default) - end - nvimtree.setup(default) -end - -return M +nvimtree.setup(options) diff --git a/config/nvim/lua/plugins/configs/nvterm.lua b/config/nvim/lua/plugins/configs/nvterm.lua new file mode 100644 index 0000000..d0580eb --- /dev/null +++ b/config/nvim/lua/plugins/configs/nvterm.lua @@ -0,0 +1,34 @@ +local present, nvterm = pcall(require, "nvterm") + +if not present then + return +end + +require "base46.term" + +local options = { + terminals = { + list = {}, + type_opts = { + float = { + relative = "editor", + row = 0.3, + col = 0.25, + width = 0.5, + height = 0.4, + border = "single", + }, + horizontal = { location = "rightbelow", split_ratio = 0.3 }, + vertical = { location = "rightbelow", split_ratio = 0.5 }, + }, + }, + behavior = { + close_on_exit = true, + auto_insert = true, + }, + enable_new_mappings = true, +} + +options = require("core.utils").load_override(options, "NvChad/nvterm") + +nvterm.setup(options) diff --git a/config/nvim/lua/plugins/configs/others.lua b/config/nvim/lua/plugins/configs/others.lua index 3a86715..a78c71e 100644 --- a/config/nvim/lua/plugins/configs/others.lua +++ b/config/nvim/lua/plugins/configs/others.lua @@ -1,36 +1,37 @@ local M = {} -local chadrc_config = require("core.utils").load_config() +local load_override = require("core.utils").load_override -M.autopairs = function(override_flag) +M.autopairs = function() local present1, autopairs = pcall(require, "nvim-autopairs") - local present2, cmp_autopairs = pcall(require, "nvim-autopairs.completion.cmp") + local present2, cmp = pcall(require, "cmp") - if present1 and present2 then - local default = { fast_wrap = {} } - if override_flag then - default = require("core.utils").tbl_override_req("nvim_autopairs", default) - end - autopairs.setup(default) - - local cmp = require "cmp" - cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done()) + if not (present1 and present2) then + return end -end -M.better_escape = function(override_flag) - local default = { - mapping = chadrc_config.mappings.plugins.better_escape.esc_insertmode, - timeout = chadrc_config.plugins.options.esc_insertmode_timeout, + local options = { + fast_wrap = {}, + disable_filetype = { "TelescopePrompt", "vim" }, } - if override_flag then - default = require("core.utils").tbl_override_req("better_escape", default) - end - require("better_escape").setup(default) + + options = load_override(options, "windwp/nvim-autopairs") + autopairs.setup(options) + + local cmp_autopairs = require "nvim-autopairs.completion.cmp" + cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done()) end -M.blankline = function(override_flag) - local default = { +M.blankline = function() + local present, blankline = pcall(require, "indent_blankline") + + if not present then + return + end + + require("base46").load_highlight "blankline" + + local options = { indentLine_enabled = 1, char = "▏", filetype_exclude = { @@ -41,159 +42,124 @@ M.blankline = function(override_flag) "lspinfo", "TelescopePrompt", "TelescopeResults", - "nvchad_cheatsheet", "lsp-installer", "", }, buftype_exclude = { "terminal" }, show_trailing_blankline_indent = false, show_first_indent_level = false, + show_current_context = true, + show_current_context_start = true, } - if override_flag then - default = require("core.utils").tbl_override_req("indent_blankline", default) - end - require("indent_blankline").setup(default) + + options = load_override(options, "lukas-reineke/indent-blankline.nvim") + blankline.setup(options) end -M.colorizer = function(override_flag) +M.colorizer = function() local present, colorizer = pcall(require, "colorizer") - if present then - local default = { - filetypes = { - "*", - }, - user_default_options = { - RGB = true, -- #RGB hex codes - RRGGBB = true, -- #RRGGBB hex codes - names = false, -- "Name" codes like Blue - RRGGBBAA = false, -- #RRGGBBAA hex codes - rgb_fn = false, -- CSS rgb() and rgba() functions - hsl_fn = false, -- CSS hsl() and hsla() functions - css = false, -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB - css_fn = false, -- Enable all CSS *functions*: rgb_fn, hsl_fn - -- Available modes: foreground, background - mode = "background", -- Set the display mode. - }, - } - if override_flag then - default = require("core.utils").tbl_override_req("nvim_colorizer", default) - end - colorizer.setup(default["filetypes"], default["user_default_options"]) - vim.cmd "ColorizerReloadAllBuffers" - end -end - -M.comment = function(override_flag) - local present, nvim_comment = pcall(require, "Comment") - if present then - local default = {} - if override_flag then - default = require("core.utils").tbl_override_req("nvim_comment", default) - end - nvim_comment.setup(default) - end -end - -M.luasnip = function(override_flag) - local present, luasnip = pcall(require, "luasnip") - if present then - local default = { - history = true, - updateevents = "TextChanged,TextChangedI", - } - if override_flag then - default = require("core.utils").tbl_override_req("luasnip", default) - end - luasnip.config.set_config(default) - require("luasnip/loaders/from_vscode").load { paths = chadrc_config.plugins.options.luasnip.snippet_path } - require("luasnip/loaders/from_vscode").load() - end -end - -M.signature = function(override_flag) - local present, lspsignature = pcall(require, "lsp_signature") - if present then - local default = { - bind = true, - doc_lines = 0, - floating_window = true, - fix_pos = true, - hint_enable = true, - hint_prefix = " ", - hint_scheme = "String", - hi_parameter = "Search", - max_height = 22, - max_width = 120, -- max_width of signature floating_window, line will be wrapped if exceed max_width - handler_opts = { - border = "single", -- double, single, shadow, none - }, - zindex = 200, -- by default it will be on top of all floating windows, set to 50 send it to bottom - padding = "", -- character to pad on left and right of signature can be ' ', or '|' etc - } - if override_flag then - default = require("core.utils").tbl_override_req("signature", default) - end - lspsignature.setup(default) - end -end - -M.lsp_handlers = function() - local function lspSymbol(name, icon) - local hl = "DiagnosticSign" .. name - vim.fn.sign_define(hl, { text = icon, numhl = hl, texthl = hl }) + if not present then + return end - lspSymbol("Error", "") - lspSymbol("Info", "") - lspSymbol("Hint", "") - lspSymbol("Warn", "") - - vim.diagnostic.config { - virtual_text = { - prefix = "", + local options = { + filetypes = { + "*", + }, + user_default_options = { + RGB = true, -- #RGB hex codes + RRGGBB = true, -- #RRGGBB hex codes + names = false, -- "Name" codes like Blue + RRGGBBAA = false, -- #RRGGBBAA hex codes + rgb_fn = false, -- CSS rgb() and rgba() functions + hsl_fn = false, -- CSS hsl() and hsla() functions + css = false, -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB + css_fn = false, -- Enable all CSS *functions*: rgb_fn, hsl_fn + mode = "background", -- Set the display mode. }, - signs = true, - underline = true, - update_in_insert = false, } - vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { - border = "single", - }) - vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { - border = "single", - }) + options = load_override(options, "NvChad/nvim-colorizer.lua") + colorizer.setup(options["filetypes"], options["user_default_options"]) - -- suppress error messages from lang servers - vim.notify = function(msg, log_level) - if msg:match "exit code" then - return - end - if log_level == vim.log.levels.ERROR then - vim.api.nvim_err_writeln(msg) - else - vim.api.nvim_echo({ { msg } }, true, {}) - end - end + vim.cmd "ColorizerAttachToBuffer" end -M.gitsigns = function(override_flag) +M.comment = function() + local present, nvim_comment = pcall(require, "Comment") + + if not present then + return + end + + local options = {} + options = load_override(options, "numToStr/Comment.nvim") + nvim_comment.setup(options) +end + +M.luasnip = function() + local present, luasnip = pcall(require, "luasnip") + + if not present then + return + end + + local options = { + history = true, + updateevents = "TextChanged,TextChangedI", + } + + options = load_override(options, "L3MON4D3/LuaSnip") + luasnip.config.set_config(options) + require("luasnip.loaders.from_vscode").lazy_load() + require("luasnip.loaders.from_vscode").lazy_load({ paths = vim.g.luasnippets_path or "" }) + + vim.api.nvim_create_autocmd("InsertLeave", { + callback = function() + if + require("luasnip").session.current_nodes[vim.api.nvim_get_current_buf()] + and not require("luasnip").session.jump_active + then + require("luasnip").unlink_current() + end + end, + }) +end + +M.gitsigns = function() local present, gitsigns = pcall(require, "gitsigns") + + if not present then + return + end + + require("base46").load_highlight "git" + + local options = { + signs = { + add = { hl = "DiffAdd", text = "│", numhl = "GitSignsAddNr" }, + change = { hl = "DiffChange", text = "│", numhl = "GitSignsChangeNr" }, + delete = { hl = "DiffDelete", text = "", numhl = "GitSignsDeleteNr" }, + topdelete = { hl = "DiffDelete", text = "‾", numhl = "GitSignsDeleteNr" }, + changedelete = { hl = "DiffChangeDelete", text = "~", numhl = "GitSignsChangeNr" }, + }, + } + + options = load_override(options, "lewis6991/gitsigns.nvim") + gitsigns.setup(options) +end + +M.devicons = function() + local present, devicons = pcall(require, "nvim-web-devicons") + if present then - local default = { - signs = { - add = { hl = "DiffAdd", text = "│", numhl = "GitSignsAddNr" }, - change = { hl = "DiffChange", text = "│", numhl = "GitSignsChangeNr" }, - delete = { hl = "DiffDelete", text = "", numhl = "GitSignsDeleteNr" }, - topdelete = { hl = "DiffDelete", text = "‾", numhl = "GitSignsDeleteNr" }, - changedelete = { hl = "DiffChangeDelete", text = "~", numhl = "GitSignsChangeNr" }, - }, - } - if override_flag then - default = require("core.utils").tbl_override_req("gitsigns", default) - end - gitsigns.setup(default) + require("base46").load_highlight "devicons" + + local options = { override = require("ui.icons").devicons } + options = require("core.utils").load_override(options, "kyazdani42/nvim-web-devicons") + + devicons.setup(options) end end diff --git a/config/nvim/lua/plugins/configs/telescope.lua b/config/nvim/lua/plugins/configs/telescope.lua index 7a5af67..f0e27cc 100644 --- a/config/nvim/lua/plugins/configs/telescope.lua +++ b/config/nvim/lua/plugins/configs/telescope.lua @@ -4,7 +4,11 @@ if not present then return end -local default = { +vim.g.theme_switcher_loaded = true + +require("base46").load_highlight "telescope" + +local options = { defaults = { vimgrep_arguments = { "rg", @@ -43,31 +47,27 @@ local default = { border = {}, borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }, color_devicons = true, - use_less = true, set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil, file_previewer = require("telescope.previewers").vim_buffer_cat.new, grep_previewer = require("telescope.previewers").vim_buffer_vimgrep.new, qflist_previewer = require("telescope.previewers").vim_buffer_qflist.new, -- Developer configurations: Not meant for general override buffer_previewer_maker = require("telescope.previewers").buffer_previewer_maker, + mappings = { + n = { ["q"] = require("telescope.actions").close }, + }, }, + + extensions_list = { "themes", "terms" }, } -local M = {} -M.setup = function(override_flag) - if override_flag then - default = require("core.utils").tbl_override_req("telescope", default) +-- check for any override +options = require("core.utils").load_override(options, "nvim-telescope/telescope.nvim") +telescope.setup(options) + +-- load extensions +pcall(function() + for _, ext in ipairs(options.extensions_list) do + telescope.load_extension(ext) end - - telescope.setup(default) - - local extensions = { "themes", "terms" } - - pcall(function() - for _, ext in ipairs(extensions) do - telescope.load_extension(ext) - end - end) -end - -return M +end) diff --git a/config/nvim/lua/plugins/configs/treesitter.lua b/config/nvim/lua/plugins/configs/treesitter.lua index 777b907..8c0717f 100644 --- a/config/nvim/lua/plugins/configs/treesitter.lua +++ b/config/nvim/lua/plugins/configs/treesitter.lua @@ -1,10 +1,13 @@ -local present, ts_config = pcall(require, "nvim-treesitter.configs") +local present, treesitter = pcall(require, "nvim-treesitter.configs") if not present then return end -local default = { +require("base46").load_highlight "syntax" +require("base46").load_highlight "treesitter" + +local options = { ensure_installed = { "lua", "vim", @@ -15,12 +18,7 @@ local default = { }, } -local M = {} -M.setup = function(override_flag) - if override_flag then - default = require("core.utils").tbl_override_req("nvim_treesitter", default) - end - ts_config.setup(default) -end +-- check for any override +options = require("core.utils").load_override(options, "nvim-treesitter/nvim-treesitter") -return M +treesitter.setup(options) diff --git a/config/nvim/lua/plugins/configs/whichkey.lua b/config/nvim/lua/plugins/configs/whichkey.lua new file mode 100644 index 0000000..e29e385 --- /dev/null +++ b/config/nvim/lua/plugins/configs/whichkey.lua @@ -0,0 +1,51 @@ +local present, wk = pcall(require, "which-key") + +if not present then + return +end + +require("base46").load_highlight "whichkey" + +local options = { + + icons = { + breadcrumb = "»", -- symbol used in the command line area that shows your active key combo + separator = "  ", -- symbol used between a key and it's label + group = "+", -- symbol prepended to a group + }, + + popup_mappings = { + scroll_down = "", -- binding to scroll down inside the popup + scroll_up = "", -- binding to scroll up inside the popup + }, + + window = { + border = "none", -- none/single/double/shadow + }, + + layout = { + spacing = 6, -- spacing between columns + }, + + hidden = { "", "", "", "", "call", "lua", "^:", "^ " }, + + triggers_blacklist = { + -- list of mode / prefixes that should never be hooked by WhichKey + i = { "j", "k" }, + v = { "j", "k" }, + }, +} + +options = require("core.utils").load_override(options, "folke/which-key.nvim") + +local utils = require "core.utils" + +local mappings = utils.load_config().mappings +local mapping_groups = { groups = vim.deepcopy(mappings.groups) } + +mappings.disabled = nil +mappings.groups = nil + +utils.load_mappings(mapping_groups) + +wk.setup(options) diff --git a/config/nvim/lua/plugins/init.lua b/config/nvim/lua/plugins/init.lua index 80bdcf3..5237e7e 100644 --- a/config/nvim/lua/plugins/init.lua +++ b/config/nvim/lua/plugins/init.lua @@ -1,244 +1,187 @@ -local plugin_settings = require("core.utils").load_config().plugins -local present, packer = pcall(require, plugin_settings.options.packer.init_file) - -if not present then - return false -end - -local override_req = require("core.utils").override_req +vim.cmd "packadd packer.nvim" local plugins = { - { "nvim-lua/plenary.nvim" }, - { "lewis6991/impatient.nvim" }, - { "nathom/filetype.nvim" }, - { - "wbthomason/packer.nvim", - event = "VimEnter", - }, + ["nvim-lua/plenary.nvim"] = { module = "plenary" }, + ["wbthomason/packer.nvim"] = {}, + ["NvChad/extensions"] = { module = { "telescope", "nvchad" } }, - { - "NvChad/extensions", - config = function () - vim.schedule_wrap(require("nvchad.terminal").init()) - end - }, - - { - "NvChad/nvim-base16.lua", - after = "packer.nvim", + ["NvChad/base46"] = { config = function() - require("colors").init() + local ok, base46 = pcall(require, "base46") + + if ok then + base46.load_theme() + end end, }, - { - "kyazdani42/nvim-web-devicons", - after = "nvim-base16.lua", - config = override_req("nvim_web_devicons", "plugins.configs.icons", "setup"), + ["NvChad/nvterm"] = { + module = "nvterm", + config = function() + require "plugins.configs.nvterm" + end, }, - { - "feline-nvim/feline.nvim", - disable = not plugin_settings.status.feline, - after = "nvim-web-devicons", - config = override_req("feline", "plugins.configs.statusline", "setup"), + ["kyazdani42/nvim-web-devicons"] = { + module = "nvim-web-devicons", + config = function() + require("plugins.configs.others").devicons() + end, }, - { - "akinsho/bufferline.nvim", - branch = "main", - disable = not plugin_settings.status.bufferline, - after = "nvim-web-devicons", - config = override_req("bufferline", "plugins.configs.bufferline", "setup"), + ["lukas-reineke/indent-blankline.nvim"] = { + opt = true, setup = function() - require("core.mappings").bufferline() + require("core.lazy_load").on_file_open "indent-blankline.nvim" + end, + config = function() + require("plugins.configs.others").blankline() end, }, - { - "lukas-reineke/indent-blankline.nvim", - disable = not plugin_settings.status.blankline, - event = "BufRead", - config = override_req("indent_blankline", "plugins.configs.others", "blankline"), + ["NvChad/nvim-colorizer.lua"] = { + opt = true, + setup = function() + require("core.lazy_load").colorizer() + end, + config = function() + require("plugins.configs.others").colorizer() + end, }, - { - "NvChad/nvim-colorizer.lua", - disable = not plugin_settings.status.colorizer, - event = "BufRead", - config = override_req("nvim_colorizer", "plugins.configs.others", "colorizer"), - }, - - { - "nvim-treesitter/nvim-treesitter", - event = { "BufRead", "BufNewFile" }, - config = override_req("nvim_treesitter", "plugins.configs.treesitter", "setup"), + ["nvim-treesitter/nvim-treesitter"] = { + module = "nvim-treesitter", + setup = function() + require("core.lazy_load").on_file_open "nvim-treesitter" + end, + cmd = require("core.lazy_load").treesitter_cmds, run = ":TSUpdate", + config = function() + require "plugins.configs.treesitter" + end, }, -- git stuff - { - "lewis6991/gitsigns.nvim", - disable = not plugin_settings.status.gitsigns, + ["lewis6991/gitsigns.nvim"] = { opt = true, - config = override_req("gitsigns", "plugins.configs.others", "gitsigns"), setup = function() - require("core.utils").packer_lazy_load "gitsigns.nvim" + require("core.lazy_load").gitsigns() + end, + config = function() + require("plugins.configs.others").gitsigns() end, }, -- lsp stuff - { - "neovim/nvim-lspconfig", + ["williamboman/nvim-lsp-installer"] = { + opt = true, + cmd = require("core.lazy_load").lsp_cmds, + setup = function() + require("core.lazy_load").on_file_open "nvim-lsp-installer" + end, + }, + + ["neovim/nvim-lspconfig"] = { + after = "nvim-lsp-installer", module = "lspconfig", - opt = true, - setup = function() - require("core.utils").packer_lazy_load "nvim-lspconfig" - -- reload the current file so lsp actually starts for it - vim.defer_fn(function() - vim.cmd 'if &ft == "packer" | echo "" | else | silent! e %' - end, 0) + config = function() + require "plugins.configs.lsp_installer" + require "plugins.configs.lspconfig" end, - config = override_req("lspconfig", "plugins.configs.lspconfig"), - }, - - { - "ray-x/lsp_signature.nvim", - disable = not plugin_settings.status.lspsignature, - after = "nvim-lspconfig", - config = override_req("signature", "plugins.configs.others", "signature"), - }, - - { - "andymass/vim-matchup", - disable = not plugin_settings.status.vim_matchup, - opt = true, - setup = function() - require("core.utils").packer_lazy_load "vim-matchup" - end, - }, - - { - "max397574/better-escape.nvim", - disable = not plugin_settings.status.better_escape, - event = "InsertCharPre", - config = override_req("better_escape", "plugins.configs.others", "better_escape"), }, -- load luasnips + cmp related in insert mode only - { - "rafamadriz/friendly-snippets", + ["rafamadriz/friendly-snippets"] = { module = "cmp_nvim_lsp", - disable = not plugin_settings.status.cmp, event = "InsertEnter", }, - { - "hrsh7th/nvim-cmp", - disable = not plugin_settings.status.cmp, + ["hrsh7th/nvim-cmp"] = { after = "friendly-snippets", - config = override_req("nvim_cmp", "plugins.configs.cmp", "setup"), + config = function() + require "plugins.configs.cmp" + end, }, - { - "L3MON4D3/LuaSnip", - disable = not plugin_settings.status.cmp, + ["L3MON4D3/LuaSnip"] = { wants = "friendly-snippets", after = "nvim-cmp", - config = override_req("luasnip", "plugins.configs.others", "luasnip"), + config = function() + require("plugins.configs.others").luasnip() + end, }, - { - "saadparwaiz1/cmp_luasnip", - disable = not plugin_settings.status.cmp, - after = plugin_settings.options.cmp.lazy_load and "LuaSnip", + ["saadparwaiz1/cmp_luasnip"] = { + after = "LuaSnip", }, - { - "hrsh7th/cmp-nvim-lua", - disable = not plugin_settings.status.cmp, + ["hrsh7th/cmp-nvim-lua"] = { after = "cmp_luasnip", }, - { - "hrsh7th/cmp-nvim-lsp", - disable = not plugin_settings.status.cmp, + ["hrsh7th/cmp-nvim-lsp"] = { after = "cmp-nvim-lua", }, - { - "hrsh7th/cmp-buffer", - disable = not plugin_settings.status.cmp, + ["hrsh7th/cmp-buffer"] = { after = "cmp-nvim-lsp", }, - { - "hrsh7th/cmp-path", - disable = not plugin_settings.status.cmp, + ["hrsh7th/cmp-path"] = { after = "cmp-buffer", }, -- misc plugins - { - "windwp/nvim-autopairs", - disable = not plugin_settings.status.autopairs, - after = plugin_settings.options.autopairs.loadAfter, - config = override_req("nvim_autopairs", "plugins.configs.others", "autopairs"), + ["windwp/nvim-autopairs"] = { + after = "nvim-cmp", + config = function() + require("plugins.configs.others").autopairs() + end, }, - { - disable = not plugin_settings.status.alpha, - "goolord/alpha-nvim", - config = override_req("alpha", "plugins.configs.alpha", "setup"), + ["goolord/alpha-nvim"] = { + after = "base46", + disable = true, + config = function() + require "plugins.configs.alpha" + end, }, - { - "numToStr/Comment.nvim", - disable = not plugin_settings.status.comment, + ["numToStr/Comment.nvim"] = { module = "Comment", - keys = { "gcc" }, - config = override_req("nvim_comment", "plugins.configs.others", "comment"), - setup = function() - require("core.mappings").comment() + keys = { "gc", "gb" }, + config = function() + require("plugins.configs.others").comment() end, }, -- file managing , picker etc - { - "kyazdani42/nvim-tree.lua", - disable = not plugin_settings.status.nvimtree, - -- only set "after" if lazy load is disabled and vice versa for "cmd" - after = not plugin_settings.options.nvimtree.lazy_load and "nvim-web-devicons", - cmd = plugin_settings.options.nvimtree.lazy_load and { "NvimTreeToggle", "NvimTreeFocus" }, - config = override_req("nvim_tree", "plugins.configs.nvimtree", "setup"), - setup = function() - require("core.mappings").nvimtree() + ["kyazdani42/nvim-tree.lua"] = { + ft = "alpha", + cmd = { "NvimTreeToggle", "NvimTreeFocus" }, + config = function() + require "plugins.configs.nvimtree" end, }, - { - "nvim-telescope/telescope.nvim", - module = "telescope", + ["nvim-telescope/telescope.nvim"] = { cmd = "Telescope", - config = override_req("telescope", "plugins.configs.telescope", "setup"), - setup = function() - require("core.mappings").telescope() + config = function() + require "plugins.configs.telescope" end, - }, + }, + + -- Only load whichkey after all the gui + ["folke/which-key.nvim"] = { + module = "which-key", + config = function() + require "plugins.configs.whichkey" + end, + }, + ["xiyaowong/nvim-transparent"] = {}, } ---label plugins for operational assistance -plugins = require("core.utils").label_plugins(plugins) ---remove plugins specified in chadrc -plugins = require("core.utils").remove_default_plugins(plugins) ---add plugins specified in chadrc -plugins = require("core.utils").add_user_plugins(plugins) - -return packer.startup(function(use) - for _, v in pairs(plugins) do - use(v) - end -end) +require("core.packer").run(plugins) diff --git a/config/nvim/lua/ui/icons.lua b/config/nvim/lua/ui/icons.lua new file mode 100644 index 0000000..ee0b09c --- /dev/null +++ b/config/nvim/lua/ui/icons.lua @@ -0,0 +1,207 @@ +local M = {} + +M.lspkind = { + Namespace = "", + Text = " ", + Method = " ", + Function = " ", + Constructor = " ", + Field = "ﰠ ", + Variable = " ", + Class = "ﴯ ", + Interface = " ", + Module = " ", + Property = "ﰠ ", + Unit = "塞 ", + Value = " ", + Enum = " ", + Keyword = " ", + Snippet = " ", + Color = " ", + File = " ", + Reference = " ", + Folder = " ", + EnumMember = " ", + Constant = " ", + Struct = "פּ ", + Event = " ", + Operator = " ", + TypeParameter = " ", + Table = "", + Object = " ", + Tag = "", + Array = "[]", + Boolean = " ", + Number = " ", + Null = "ﳠ", + String = " ", + Calendar = "", + Watch = " ", + Package = "", +} + +M.statusline_separators = { + default = { + left = "", + right = " ", + }, + + round = { + left = "", + right = "", + }, + + block = { + left = "█", + right = "█", + }, + + arrow = { + left = "", + right = "", + }, +} + +M.devicons = { + default_icon = { + icon = "", + name = "Default", + }, + + c = { + icon = "", + name = "c", + }, + + css = { + icon = "", + name = "css", + }, + + deb = { + icon = "", + name = "deb", + }, + + Dockerfile = { + icon = "", + name = "Dockerfile", + }, + + html = { + icon = "", + name = "html", + }, + + jpeg = { + icon = "", + name = "jpeg", + }, + + jpg = { + icon = "", + name = "jpg", + }, + + js = { + icon = "", + name = "js", + }, + + kt = { + icon = "󱈙", + name = "kt", + }, + + lock = { + icon = "", + name = "lock", + }, + + lua = { + icon = "", + name = "lua", + }, + + mp3 = { + icon = "", + name = "mp3", + }, + + mp4 = { + icon = "", + name = "mp4", + }, + + out = { + icon = "", + name = "out", + }, + + png = { + icon = "", + name = "png", + }, + + py = { + icon = "", + name = "py", + }, + + ["robots.txt"] = { + icon = "ﮧ", + name = "robots", + }, + + toml = { + icon = "", + name = "toml", + }, + + ts = { + icon = "ﯤ", + name = "ts", + }, + + ttf = { + icon = "", + name = "TrueTypeFont", + }, + + rb = { + icon = "", + name = "rb", + }, + + rpm = { + icon = "", + name = "rpm", + }, + + vue = { + icon = "﵂", + name = "vue", + }, + + woff = { + icon = "", + name = "WebOpenFontFormat", + }, + + woff2 = { + icon = "", + name = "WebOpenFontFormat2", + }, + + xz = { + icon = "", + name = "xz", + }, + + zip = { + icon = "", + name = "zip", + }, +} + +return M diff --git a/config/nvim/lua/ui/lsp.lua b/config/nvim/lua/ui/lsp.lua new file mode 100644 index 0000000..cb7b67f --- /dev/null +++ b/config/nvim/lua/ui/lsp.lua @@ -0,0 +1,49 @@ +local function lspSymbol(name, icon) + local hl = "DiagnosticSign" .. name + vim.fn.sign_define(hl, { text = icon, numhl = hl, texthl = hl }) +end + +lspSymbol("Error", "") +lspSymbol("Info", "") +lspSymbol("Hint", "") +lspSymbol("Warn", "") + +vim.diagnostic.config { + virtual_text = { + prefix = "", + }, + signs = true, + underline = true, + update_in_insert = false, +} + +vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { + border = "single", +}) +vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { + border = "single", + focusable = false, + relative = "cursor", +}) + +-- suppress error messages from lang servers +vim.notify = function(msg, log_level) + if msg:match "exit code" then + return + end + if log_level == vim.log.levels.ERROR then + vim.api.nvim_err_writeln(msg) + else + vim.api.nvim_echo({ { msg } }, true, {}) + end +end + +-- Borders for LspInfo winodw +local win = require "lspconfig.ui.windows" +local _default_opts = win.default_opts + +win.default_opts = function(options) + local opts = _default_opts(options) + opts.border = "single" + return opts +end diff --git a/config/nvim/lua/ui/statusline/init.lua b/config/nvim/lua/ui/statusline/init.lua new file mode 100644 index 0000000..76c9416 --- /dev/null +++ b/config/nvim/lua/ui/statusline/init.lua @@ -0,0 +1,22 @@ +local modules = require "ui.statusline.modules" +local user_override = require("core.utils").load_config().ui.statusline.override +modules = vim.tbl_deep_extend("force", modules, user_override) + +return { + run = function() + return table.concat { + modules.mode(), + modules.fileInfo(), + modules.git(), + + "%=", + modules.LSP_progress(), + "%=", + + modules.LSP_Diagnostics(), + modules.LSP_status() or "", + modules.cwd(), + modules.cursor_position(), + } + end, +} diff --git a/config/nvim/lua/ui/statusline/modules.lua b/config/nvim/lua/ui/statusline/modules.lua new file mode 100644 index 0000000..3b1f517 --- /dev/null +++ b/config/nvim/lua/ui/statusline/modules.lua @@ -0,0 +1,138 @@ +local fn = vim.fn +local sep_style = require("ui.icons").statusline_separators +local user_sep = require("core.utils").load_config().ui.statusline.separator_style +local sep_l = sep_style[user_sep]["left"] +local sep_r = sep_style[user_sep]["right"] + +local modes = { + ["n"] = { "NORMAL", "St_NormalMode" }, + ["niI"] = { "NORMAL i", "St_NormalMode" }, + ["niR"] = { "NORMAL r", "St_NormalMode" }, + ["niV"] = { "NORMAL v", "St_NormalMode" }, + ["no"] = { "N-PENDING", "St_NormalMode" }, + ["i"] = { "INSERT", "St_InsertMode" }, + ["ic"] = { "INSERT", "St_InsertMode" }, + ["ix"] = { "INSERT completion", "St_InsertMode" }, + ["t"] = { "TERMINAL", "St_TerminalMode" }, + ["nt"] = { "NTERMINAL", "St_NTerminalMode" }, + ["v"] = { "VISUAL", "St_VisualMode" }, + ["V"] = { "V-LINE", "St_VisualMode" }, + [""] = { "V-BLOCK", "St_VisualMode" }, + ["R"] = { "REPLACE", "St_ReplaceMode" }, + ["Rv"] = { "V-REPLACE", "St_ReplaceMode" }, + ["s"] = { "SELECT", "St_SelectMode" }, + ["S"] = { "S-LINE", "St_SelectMode" }, + [""] = { "S-BLOCK", "St_SelectMode" }, + ["c"] = { "COMMAND", "St_CommandMode" }, + ["cv"] = { "COMMAND", "St_CommandMode" }, + ["ce"] = { "COMMAND", "St_CommandMode" }, + ["r"] = { "PROMPT", "St_ConfirmMode" }, + ["rm"] = { "MORE", "St_ConfirmMode" }, + ["r?"] = { "CONFIRM", "St_ConfirmMode" }, + ["!"] = { "SHELL", "St_TerminalMode" }, +} + +local M = {} + +M.mode = function() + local m = vim.api.nvim_get_mode().mode + local current_mode = "%#" .. modes[m][2] .. "#" .. "  " .. modes[m][1] + local mode_sep1 = "%#" .. modes[m][2] .. "Sep" .. "#" .. sep_r + + return current_mode .. mode_sep1 .. "%#ST_EmptySpace#" .. sep_r +end + +M.fileInfo = function() + local icon = "  " + local filename = (fn.expand "%" == "" and "Empty ") or fn.expand "%:t" + + if filename ~= "Empty " then + local devicons_present, devicons = pcall(require, "nvim-web-devicons") + + if devicons_present then + local ft_icon = devicons.get_icon(filename) + icon = (ft_icon ~= nil and " " .. ft_icon) or "" + end + + filename = " " .. filename .. " " + end + + return "%#St_file_info#" .. icon .. filename .. "%#St_file_sep#" .. sep_r +end + +M.git = function() + if not vim.b.gitsigns_head or vim.b.gitsigns_git_status then + return "" + end + + local git_status = vim.b.gitsigns_status_dict + + local added = (git_status.added and git_status.added ~= 0) and ("  " .. git_status.added) or "" + local changed = (git_status.changed and git_status.changed ~= 0) and ("  " .. git_status.changed) or "" + local removed = (git_status.removed and git_status.removed ~= 0) and ("  " .. git_status.removed) or "" + local branch_name = "  " .. git_status.head .. " " + + return "%#St_gitIcons#" .. branch_name .. added .. changed .. removed +end + +-- LSP STUFF +M.LSP_progress = function() + local Lsp = vim.lsp.util.get_progress_messages()[1] + + if vim.o.columns < 120 or not Lsp then + return "" + end + + local msg = Lsp.message or "" + local percentage = Lsp.percentage or 0 + local title = Lsp.title or "" + local spinners = { "", "" } + local ms = vim.loop.hrtime() / 1000000 + local frame = math.floor(ms / 120) % #spinners + local content = string.format(" %%<%s %s %s (%s%%%%) ", spinners[frame + 1], title, msg, percentage) + + return ("%#St_LspProgress#" .. content) or "" +end + +M.LSP_Diagnostics = function() + local errors = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR }) + local warnings = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN }) + local hints = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.HINT }) + local info = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.INFO }) + + errors = (errors and errors > 0) and ("%#St_lspError#" .. " " .. errors .. " ") or "" + warnings = (warnings and warnings > 0) and ("%#St_lspWarning#" .. " " .. warnings .. " ") or "" + hints = (hints and hints > 0) and ("%#St_lspHints#" .. "ﯧ " .. hints .. " ") or "" + info = (info and info > 0) and ("%#St_lspInfo#" .. " " .. info .. " ") or "" + + return errors .. warnings .. hints .. info +end + +M.LSP_status = function() + for _, client in ipairs(vim.lsp.get_active_clients()) do + if client.attached_buffers[vim.api.nvim_get_current_buf()] then + return (vim.o.columns > 70 and "%#St_LspStatus#" .. "  LSP ~ " .. client.name .. " ") or "  LSP " + end + end +end + +M.cwd = function() + local dir_icon = "%#St_cwd_icon#" .. " " + local dir_name = "%#St_cwd_text#" .. " " .. fn.fnamemodify(fn.getcwd(), ":t") .. " " + return (vim.o.columns > 120 and ("%#St_cwd_sep#" .. sep_l .. dir_icon .. dir_name)) or "" +end + +M.cursor_position = function() + local left_sep = "%#St_pos_sep#" .. sep_l .. "%#St_pos_icon#" .. " " + + local current_line = fn.line "." + local total_line = fn.line "$" + local text = math.modf((current_line / total_line) * 100) .. tostring "%%" + + text = (current_line == 1 and "Top") or text + text = (current_line == total_line and "Bot") or text + + return left_sep .. "%#St_pos_text#" .. " " .. text .. " " +end + +return M diff --git a/config/nvim/lua/ui/tabline.lua b/config/nvim/lua/ui/tabline.lua new file mode 100644 index 0000000..ec68b6c --- /dev/null +++ b/config/nvim/lua/ui/tabline.lua @@ -0,0 +1,169 @@ +local api = vim.api +local devicons_present, devicons = pcall(require, "nvim-web-devicons") +local fn = vim.fn +local new_cmd = api.nvim_create_user_command + +require("base46").load_highlight "tbline" + +---------------------------------------------------------- btn onclick functions ---------------------------------------------- + +vim.cmd "function! TbGoToBuf(bufnr,b,c,d) \n execute 'b'..a:bufnr \n endfunction" + +vim.cmd [[ + function! TbKillBuf(bufnr,b,c,d) + call luaeval('require("core.utils").close_buffer(_A)', a:bufnr) + endfunction]] + +vim.cmd "function! TbNewTab(a,b,c,d) \n tabnew \n endfunction" +vim.cmd "function! TbGotoTab(tabnr,b,c,d) \n execute a:tabnr ..'tabnext' \n endfunction" +vim.cmd "function! TbTabClose(a,b,c,d) \n lua require('core.utils').closeAllBufs('closeTab') \n endfunction" +vim.cmd "function! TbCloseAllBufs(a,b,c,d) \n lua require('core.utils').closeAllBufs() \n endfunction" +vim.cmd "function! TbToggle_theme(a,b,c,d) \n lua require('base46').toggle_theme() \n endfunction" +vim.cmd "function! TbToggleTabs(a,b,c,d) \n let g:TbTabsToggled = !g:TbTabsToggled | redrawtabline \n endfunction" + +---------------------------------------------------------- commands ------------------------------------------------------------ +new_cmd("Tbufnext", function() + require("core.utils").tabuflineNext() +end, {}) + +new_cmd("Tbufprev", function() + require("core.utils").tabuflinePrev() +end, {}) + +new_cmd("Tbufclose", function() + require("core.utils").close_buffer() +end, {}) + +-------------------------------------------------------- functions ------------------------------------------------------------ +local function new_hl(group1, group2) + local fg = fn.synIDattr(fn.synIDtrans(fn.hlID(group1)), "fg#") + local bg = fn.synIDattr(fn.synIDtrans(fn.hlID(group2)), "bg#") + api.nvim_set_hl(0, "Tbline" .. group1 .. group2, { fg = fg, bg = bg }) + return "%#" .. "Tbline" .. group1 .. group2 .. "#" +end + +local function getNvimTreeWidth() + for _, win in pairs(api.nvim_tabpage_list_wins(0)) do + if vim.bo[api.nvim_win_get_buf(win)].ft == "NvimTree" then + return api.nvim_win_get_width(win) + 1 + end + end + return 0 +end + +local function getBtnsWidth() + local width = 6 + if fn.tabpagenr "$" ~= 1 then + width = width + ((3 * fn.tabpagenr "$") + 2) + 10 + width = not vim.g.TbTabsToggled and 8 or width + end + return width +end + +local function add_fileInfo(name, bufnr) + if devicons_present then + local icon, icon_hl = devicons.get_icon(name, string.match(name, "%a+$")) + + if not icon then + icon, icon_hl = devicons.get_icon "default_icon" + end + + local fileInfo = " " .. icon .. " " .. name .. " " -- initial value + local pad = (24 - #fileInfo) / 2 + + icon = ( + api.nvim_get_current_buf() == bufnr and new_hl(icon_hl, "TbLineBufOn") .. " " .. icon + or new_hl(icon_hl, "TbLineBufOff") .. " " .. icon + ) + + name = (#name > 15 and string.sub(name, 1, 13) .. "..") or name + name = (api.nvim_get_current_buf() == bufnr and "%#TbLineBufOn# " .. name .. " ") + or ("%#TbLineBufOff# " .. name .. " ") + + return string.rep(" ", pad) .. icon .. name .. string.rep(" ", pad - 1) + end +end + +local function styleBufferTab(nr) + local close_btn = "%" .. nr .. "@TbKillBuf@ %X" + local name = (#api.nvim_buf_get_name(nr) ~= 0) and fn.fnamemodify(api.nvim_buf_get_name(nr), ":t") or " No Name " + name = "%" .. nr .. "@TbGoToBuf@" .. add_fileInfo(name, nr) .. "%X" + + -- color close btn for focused / hidden buffers + if nr == api.nvim_get_current_buf() then + close_btn = (vim.bo[0].modified and "%" .. nr .. "@TbKillBuf@%#TbLineBufOnModified# ") + or ("%#TbLineBufOnClose#" .. close_btn) + name = "%#TbLineBufOn#" .. name .. close_btn + else + close_btn = (vim.bo[nr].modified and "%" .. nr .. "@TbKillBuf@%#TbBufLineBufOffModified# ") + or ("%#TbLineBufOffClose#" .. close_btn) + name = "%#TbLineBufOff#" .. name .. close_btn + end + + return name +end + +---------------------------------------------------------- components ------------------------------------------------------------ +local M = {} + +M.CoverNvimTree = function() + return "%#NvimTreeNormal#" .. string.rep(" ", getNvimTreeWidth()) +end + +M.bufferlist = function() + local buffers = {} -- buffersults + local available_space = vim.o.columns - getNvimTreeWidth() - getBtnsWidth() + local current_buf = api.nvim_get_current_buf() + local has_current = false -- have we seen current buffer yet? + + for _, bufnr in ipairs(vim.t.bufs) do + if api.nvim_buf_is_valid(bufnr) then + if ((#buffers + 1) * 21) > available_space then + if has_current then + break + end + + table.remove(buffers, 1) + end + + has_current = (bufnr == current_buf and true) or has_current + table.insert(buffers, styleBufferTab(bufnr)) + end + end + + return table.concat(buffers) .. "%#TblineFill#" .. "%=" -- buffers + empty space +end + +vim.g.TbTabsToggled = 0 + +M.tablist = function() + local result, number_of_tabs = "", fn.tabpagenr "$" + + if number_of_tabs > 1 then + for i = 1, number_of_tabs, 1 do + local tab_hl = ((i == fn.tabpagenr()) and "%#TbLineTabOn# ") or "%#TbLineTabOff# " + result = result .. ("%" .. i .. "@TbGotoTab@" .. tab_hl .. i .. " ") + result = (i == fn.tabpagenr() and result .. "%#TbLineTabCloseBtn#" .. "%@TbTabClose@ %X") or result + end + + local new_tabtn = "%#TblineTabNewBtn#" .. "%@TbNewTab@  %X" + local tabstoggleBtn = "%@TbToggleTabs@ %#TBTabTitle# TABS %X" + + return vim.g.TbTabsToggled == 1 and tabstoggleBtn:gsub("()", { [36] = " " }) + or new_tabtn .. tabstoggleBtn .. result + end +end + +M.buttons = function() + local toggle_themeBtn = "%@TbToggle_theme@%#TbLineThemeToggleBtn#" .. vim.g.toggle_theme_icon .. "%X" + local CloseAllBufsBtn = "%@TbCloseAllBufs@%#TbLineCloseAllBufsBtn#" .. "  " .. "%X" + return toggle_themeBtn .. CloseAllBufsBtn +end + +M.run = function() + return M.CoverNvimTree() .. M.bufferlist() .. (M.tablist() or "") .. M.buttons() +end + +M = vim.tbl_deep_extend("force", M, require("core.utils").load_config().ui.tabufline.override) + +return M diff --git a/config/nvim/plugin/packer_compiled.lua b/config/nvim/plugin/packer_compiled.lua index f634f3a..1ef384a 100644 --- a/config/nvim/plugin/packer_compiled.lua +++ b/config/nvim/plugin/packer_compiled.lua @@ -71,8 +71,8 @@ time([[Defining packer_plugins]], true) _G.packer_plugins = { ["Comment.nvim"] = { after_files = { "/home/gallant/.local/share/nvim/site/pack/packer/opt/Comment.nvim/after/plugin/Comment.lua" }, - config = { "require('plugins.configs.others').comment(false)" }, - keys = { { "", "gcc" } }, + config = { "\27LJ\2\nF\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\fcomment\27plugins.configs.others\frequire\0" }, + keys = { { "", "gc" }, { "", "gb" } }, loaded = false, needs_bufread = false, only_cond = false, @@ -81,7 +81,7 @@ _G.packer_plugins = { }, LuaSnip = { after = { "cmp_luasnip" }, - config = { "require('plugins.configs.others').luasnip(false)" }, + config = { "\27LJ\2\nF\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\fluasnip\27plugins.configs.others\frequire\0" }, load_after = { ["nvim-cmp"] = true }, @@ -91,23 +91,11 @@ _G.packer_plugins = { url = "https://github.com/L3MON4D3/LuaSnip", wants = { "friendly-snippets" } }, - ["better-escape.nvim"] = { - config = { "require('plugins.configs.others').better_escape(false)" }, - loaded = false, - needs_bufread = false, - only_cond = false, - path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/better-escape.nvim", - url = "https://github.com/max397574/better-escape.nvim" - }, - ["bufferline.nvim"] = { - config = { "require('plugins.configs.bufferline').setup(false)" }, - load_after = { - ["nvim-web-devicons"] = true - }, - loaded = false, - needs_bufread = false, - path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/bufferline.nvim", - url = "https://github.com/akinsho/bufferline.nvim" + base46 = { + config = { "\27LJ\2\nK\0\0\4\0\4\0\t6\0\0\0006\2\1\0'\3\2\0B\0\3\3\15\0\0\0X\2\29\2\3\1B\2\1\1K\0\1\0\15load_theme\vbase46\frequire\npcall\0" }, + loaded = true, + path = "/home/gallant/.local/share/nvim/site/pack/packer/start/base46", + url = "https://github.com/NvChad/base46" }, ["cmp-buffer"] = { after = { "cmp-path" }, @@ -164,25 +152,11 @@ _G.packer_plugins = { url = "https://github.com/saadparwaiz1/cmp_luasnip" }, extensions = { - config = { "\27LJ\2\nZ\0\0\5\0\5\0\t6\0\0\0009\0\1\0006\2\2\0'\4\3\0B\2\2\0029\2\4\2B\2\1\0A\0\0\1K\0\1\0\tinit\20nvchad.terminal\frequire\18schedule_wrap\bvim\0" }, - loaded = true, - path = "/home/gallant/.local/share/nvim/site/pack/packer/start/extensions", - url = "https://github.com/NvChad/extensions" - }, - ["feline.nvim"] = { - config = { "require('plugins.configs.statusline').setup(false)" }, - load_after = { - ["nvim-web-devicons"] = true - }, loaded = false, needs_bufread = false, - path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/feline.nvim", - url = "https://github.com/feline-nvim/feline.nvim" - }, - ["filetype.nvim"] = { - loaded = true, - path = "/home/gallant/.local/share/nvim/site/pack/packer/start/filetype.nvim", - url = "https://github.com/nathom/filetype.nvim" + only_cond = false, + path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/extensions", + url = "https://github.com/NvChad/extensions" }, ["friendly-snippets"] = { after = { "nvim-cmp" }, @@ -193,37 +167,21 @@ _G.packer_plugins = { url = "https://github.com/rafamadriz/friendly-snippets" }, ["gitsigns.nvim"] = { - config = { "require('plugins.configs.others').gitsigns(false)" }, + config = { "\27LJ\2\nG\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\rgitsigns\27plugins.configs.others\frequire\0" }, loaded = false, needs_bufread = false, path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/gitsigns.nvim", url = "https://github.com/lewis6991/gitsigns.nvim" }, - ["impatient.nvim"] = { - loaded = true, - path = "/home/gallant/.local/share/nvim/site/pack/packer/start/impatient.nvim", - url = "https://github.com/lewis6991/impatient.nvim" - }, ["indent-blankline.nvim"] = { - config = { "require('plugins.configs.others').blankline(false)" }, + config = { "\27LJ\2\nH\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\14blankline\27plugins.configs.others\frequire\0" }, loaded = false, needs_bufread = false, - only_cond = false, path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/indent-blankline.nvim", url = "https://github.com/lukas-reineke/indent-blankline.nvim" }, - ["lsp_signature.nvim"] = { - config = { "require('plugins.configs.others').signature(false)" }, - load_after = { - ["nvim-lspconfig"] = true - }, - loaded = false, - needs_bufread = false, - path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/lsp_signature.nvim", - url = "https://github.com/ray-x/lsp_signature.nvim" - }, ["nvim-autopairs"] = { - config = { "require('plugins.configs.others').autopairs(false)" }, + config = { "\27LJ\2\nH\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\14autopairs\27plugins.configs.others\frequire\0" }, load_after = { ["nvim-cmp"] = true }, @@ -232,20 +190,9 @@ _G.packer_plugins = { path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/nvim-autopairs", url = "https://github.com/windwp/nvim-autopairs" }, - ["nvim-base16.lua"] = { - after = { "nvim-web-devicons" }, - config = { "\27LJ\2\n3\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\tinit\vcolors\frequire\0" }, - load_after = { - ["packer.nvim"] = true - }, - loaded = false, - needs_bufread = false, - path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/nvim-base16.lua", - url = "https://github.com/NvChad/nvim-base16.lua" - }, ["nvim-cmp"] = { after = { "LuaSnip", "nvim-autopairs" }, - config = { "require('plugins.configs.cmp').setup(false)" }, + config = { "\27LJ\2\n3\0\0\3\0\2\0\0046\0\0\0'\2\1\0B\0\2\1K\0\1\0\24plugins.configs.cmp\frequire\0" }, load_after = { ["friendly-snippets"] = true }, @@ -254,18 +201,41 @@ _G.packer_plugins = { path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/nvim-cmp", url = "https://github.com/hrsh7th/nvim-cmp" }, + ["nvim-colorizer.lua"] = { + config = { "\27LJ\2\nH\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\14colorizer\27plugins.configs.others\frequire\0" }, + loaded = false, + needs_bufread = false, + path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/nvim-colorizer.lua", + url = "https://github.com/NvChad/nvim-colorizer.lua" + }, + ["nvim-lsp-installer"] = { + after = { "nvim-lspconfig" }, + commands = { "LspInfo", "LspStart", "LspRestart", "LspStop", "LspInstall", "LspUnInstall", "LspUnInstallAll", "LspInstall", "LspInstallInfo", "LspInstallLog", "LspLog", "LspPrintInstalled" }, + loaded = false, + needs_bufread = true, + only_cond = false, + path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/nvim-lsp-installer", + url = "https://github.com/williamboman/nvim-lsp-installer" + }, ["nvim-lspconfig"] = { - after = { "lsp_signature.nvim" }, - config = { "require('plugins.configs.lspconfig')" }, + config = { "\27LJ\2\nc\0\0\3\0\3\0\a6\0\0\0'\2\1\0B\0\2\0016\0\0\0'\2\2\0B\0\2\1K\0\1\0\30plugins.configs.lspconfig\"plugins.configs.lsp_installer\frequire\0" }, + load_after = { + ["nvim-lsp-installer"] = true + }, loaded = false, needs_bufread = false, only_cond = false, path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/nvim-lspconfig", url = "https://github.com/neovim/nvim-lspconfig" }, + ["nvim-transparent"] = { + loaded = true, + path = "/home/gallant/.local/share/nvim/site/pack/packer/start/nvim-transparent", + url = "https://github.com/xiyaowong/nvim-transparent" + }, ["nvim-tree.lua"] = { commands = { "NvimTreeToggle", "NvimTreeFocus" }, - config = { "require('plugins.configs.nvimtree').setup(false)" }, + config = { "\27LJ\2\n8\0\0\3\0\2\0\0046\0\0\0'\2\1\0B\0\2\1K\0\1\0\29plugins.configs.nvimtree\frequire\0" }, loaded = false, needs_bufread = false, only_cond = false, @@ -273,7 +243,8 @@ _G.packer_plugins = { url = "https://github.com/kyazdani42/nvim-tree.lua" }, ["nvim-treesitter"] = { - config = { "require('plugins.configs.treesitter').setup(false)" }, + commands = { "TSInstall", "TSBufEnable", "TSBufDisable", "TSEnable", "TSDisable", "TSModuleInfo" }, + config = { "\27LJ\2\n:\0\0\3\0\2\0\0046\0\0\0'\2\1\0B\0\2\1K\0\1\0\31plugins.configs.treesitter\frequire\0" }, loaded = false, needs_bufread = false, only_cond = false, @@ -281,59 +252,48 @@ _G.packer_plugins = { url = "https://github.com/nvim-treesitter/nvim-treesitter" }, ["nvim-web-devicons"] = { - after = { "bufferline.nvim", "feline.nvim" }, - config = { "require('plugins.configs.icons').setup(false)" }, - load_after = { - ["nvim-base16.lua"] = true - }, - loaded = false, - needs_bufread = false, - path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/nvim-web-devicons", - url = "https://github.com/kyazdani42/nvim-web-devicons" - }, - ["packer.nvim"] = { - after = { "nvim-base16.lua" }, + config = { "\27LJ\2\nG\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\rdevicons\27plugins.configs.others\frequire\0" }, loaded = false, needs_bufread = false, only_cond = false, - path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/packer.nvim", + path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/nvim-web-devicons", + url = "https://github.com/kyazdani42/nvim-web-devicons" + }, + nvterm = { + config = { "\27LJ\2\n6\0\0\3\0\2\0\0046\0\0\0'\2\1\0B\0\2\1K\0\1\0\27plugins.configs.nvterm\frequire\0" }, + loaded = false, + needs_bufread = false, + only_cond = false, + path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/nvterm", + url = "https://github.com/NvChad/nvterm" + }, + ["packer.nvim"] = { + loaded = true, + path = "/home/gallant/.local/share/nvim/site/pack/packer/start/packer.nvim", url = "https://github.com/wbthomason/packer.nvim" }, ["plenary.nvim"] = { - loaded = true, - path = "/home/gallant/.local/share/nvim/site/pack/packer/start/plenary.nvim", + loaded = false, + needs_bufread = false, + only_cond = false, + path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/plenary.nvim", url = "https://github.com/nvim-lua/plenary.nvim" }, ["telescope.nvim"] = { commands = { "Telescope" }, - config = { "require('plugins.configs.telescope').setup(false)" }, + config = { "\27LJ\2\n9\0\0\3\0\2\0\0046\0\0\0'\2\1\0B\0\2\1K\0\1\0\30plugins.configs.telescope\frequire\0" }, loaded = false, needs_bufread = true, only_cond = false, path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/telescope.nvim", url = "https://github.com/nvim-telescope/telescope.nvim" }, - ["vim-cargo"] = { - loaded = true, - path = "/home/gallant/.local/share/nvim/site/pack/packer/start/vim-cargo", - url = "https://github.com/timonv/vim-cargo" - }, - ["vim-matchup"] = { - after_files = { "/home/gallant/.local/share/nvim/site/pack/packer/opt/vim-matchup/after/plugin/matchit.vim" }, - loaded = false, - needs_bufread = true, - path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/vim-matchup", - url = "https://github.com/andymass/vim-matchup" - }, - ["vim-transparent"] = { - loaded = true, - path = "/home/gallant/.local/share/nvim/site/pack/packer/start/vim-transparent", - url = "https://github.com/tribela/vim-transparent" - }, ["which-key.nvim"] = { - config = { "\27LJ\2\n;\0\0\3\0\3\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0004\2\0\0B\0\2\1K\0\1\0\nsetup\14which-key\frequire\0" }, - loaded = true, - path = "/home/gallant/.local/share/nvim/site/pack/packer/start/which-key.nvim", + config = { "\27LJ\2\n8\0\0\3\0\2\0\0046\0\0\0'\2\1\0B\0\2\1K\0\1\0\29plugins.configs.whichkey\frequire\0" }, + loaded = false, + needs_bufread = false, + only_cond = false, + path = "/home/gallant/.local/share/nvim/site/pack/packer/opt/which-key.nvim", url = "https://github.com/folke/which-key.nvim" } } @@ -343,7 +303,13 @@ local module_lazy_loads = { ["^Comment"] = "Comment.nvim", ["^cmp_nvim_lsp"] = "friendly-snippets", ["^lspconfig"] = "nvim-lspconfig", - ["^telescope"] = "telescope.nvim" + ["^nvchad"] = "extensions", + ["^nvim%-treesitter"] = "nvim-treesitter", + ["^nvim%-web%-devicons"] = "nvim-web-devicons", + ["^nvterm"] = "nvterm", + ["^plenary"] = "plenary.nvim", + ["^telescope"] = "extensions", + ["^which%-key"] = "which-key.nvim" } local lazy_load_called = {['packer.load'] = true} local function lazy_load_module(module_name) @@ -370,63 +336,69 @@ if not vim.g.packer_custom_loader_enabled then vim.g.packer_custom_loader_enabled = true end --- Setup for: nvim-lspconfig -time([[Setup for nvim-lspconfig]], true) -try_loadstring("\27LJ\2\nU\0\0\3\0\3\0\0056\0\0\0009\0\1\0'\2\2\0B\0\2\1K\0\1\0006if &ft == \"packer\" | echo \"\" | else | silent! e %\bcmd\bvimx\1\0\4\0\a\0\f6\0\0\0'\2\1\0B\0\2\0029\0\2\0'\2\3\0B\0\2\0016\0\4\0009\0\5\0003\2\6\0)\3\0\0B\0\3\1K\0\1\0\0\rdefer_fn\bvim\19nvim-lspconfig\21packer_lazy_load\15core.utils\frequire\0", "setup", "nvim-lspconfig") -time([[Setup for nvim-lspconfig]], false) -- Setup for: gitsigns.nvim time([[Setup for gitsigns.nvim]], true) -try_loadstring("\27LJ\2\nU\0\0\3\0\4\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0'\2\3\0B\0\2\1K\0\1\0\18gitsigns.nvim\21packer_lazy_load\15core.utils\frequire\0", "setup", "gitsigns.nvim") +try_loadstring("\27LJ\2\n?\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\rgitsigns\19core.lazy_load\frequire\0", "setup", "gitsigns.nvim") time([[Setup for gitsigns.nvim]], false) --- Setup for: nvim-tree.lua -time([[Setup for nvim-tree.lua]], true) -try_loadstring("\27LJ\2\n>\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\rnvimtree\18core.mappings\frequire\0", "setup", "nvim-tree.lua") -time([[Setup for nvim-tree.lua]], false) --- Setup for: vim-matchup -time([[Setup for vim-matchup]], true) -try_loadstring("\27LJ\2\nS\0\0\3\0\4\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0'\2\3\0B\0\2\1K\0\1\0\16vim-matchup\21packer_lazy_load\15core.utils\frequire\0", "setup", "vim-matchup") -time([[Setup for vim-matchup]], false) --- Setup for: telescope.nvim -time([[Setup for telescope.nvim]], true) -try_loadstring("\27LJ\2\n?\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\14telescope\18core.mappings\frequire\0", "setup", "telescope.nvim") -time([[Setup for telescope.nvim]], false) --- Setup for: bufferline.nvim -time([[Setup for bufferline.nvim]], true) -try_loadstring("\27LJ\2\n@\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\15bufferline\18core.mappings\frequire\0", "setup", "bufferline.nvim") -time([[Setup for bufferline.nvim]], false) --- Setup for: Comment.nvim -time([[Setup for Comment.nvim]], true) -try_loadstring("\27LJ\2\n=\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\fcomment\18core.mappings\frequire\0", "setup", "Comment.nvim") -time([[Setup for Comment.nvim]], false) --- Config for: which-key.nvim -time([[Config for which-key.nvim]], true) -try_loadstring("\27LJ\2\n;\0\0\3\0\3\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0004\2\0\0B\0\2\1K\0\1\0\nsetup\14which-key\frequire\0", "config", "which-key.nvim") -time([[Config for which-key.nvim]], false) --- Config for: extensions -time([[Config for extensions]], true) -try_loadstring("\27LJ\2\nZ\0\0\5\0\5\0\t6\0\0\0009\0\1\0006\2\2\0'\4\3\0B\2\2\0029\2\4\2B\2\1\0A\0\0\1K\0\1\0\tinit\20nvchad.terminal\frequire\18schedule_wrap\bvim\0", "config", "extensions") -time([[Config for extensions]], false) +-- Setup for: nvim-lsp-installer +time([[Setup for nvim-lsp-installer]], true) +try_loadstring("\27LJ\2\nZ\0\0\3\0\4\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0'\2\3\0B\0\2\1K\0\1\0\23nvim-lsp-installer\17on_file_open\19core.lazy_load\frequire\0", "setup", "nvim-lsp-installer") +time([[Setup for nvim-lsp-installer]], false) +-- Setup for: nvim-treesitter +time([[Setup for nvim-treesitter]], true) +try_loadstring("\27LJ\2\nW\0\0\3\0\4\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0'\2\3\0B\0\2\1K\0\1\0\20nvim-treesitter\17on_file_open\19core.lazy_load\frequire\0", "setup", "nvim-treesitter") +time([[Setup for nvim-treesitter]], false) +-- Setup for: indent-blankline.nvim +time([[Setup for indent-blankline.nvim]], true) +try_loadstring("\27LJ\2\n]\0\0\3\0\4\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0'\2\3\0B\0\2\1K\0\1\0\26indent-blankline.nvim\17on_file_open\19core.lazy_load\frequire\0", "setup", "indent-blankline.nvim") +time([[Setup for indent-blankline.nvim]], false) +-- Setup for: nvim-colorizer.lua +time([[Setup for nvim-colorizer.lua]], true) +try_loadstring("\27LJ\2\n@\0\0\3\0\3\0\0066\0\0\0'\2\1\0B\0\2\0029\0\2\0B\0\1\1K\0\1\0\14colorizer\19core.lazy_load\frequire\0", "setup", "nvim-colorizer.lua") +time([[Setup for nvim-colorizer.lua]], false) +-- Config for: base46 +time([[Config for base46]], true) +try_loadstring("\27LJ\2\nK\0\0\4\0\4\0\t6\0\0\0006\2\1\0'\3\2\0B\0\3\3\15\0\0\0X\2\29\2\3\1B\2\1\1K\0\1\0\15load_theme\vbase46\frequire\npcall\0", "config", "base46") +time([[Config for base46]], false) -- Command lazy-loads time([[Defining lazy-load commands]], true) -pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file NvimTreeToggle lua require("packer.load")({'nvim-tree.lua'}, { cmd = "NvimTreeToggle", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file Telescope lua require("packer.load")({'telescope.nvim'}, { cmd = "Telescope", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspInfo lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspInfo", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspStart lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspStart", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspRestart lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspRestart", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspStop lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspStop", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspInstall lua require("packer.load")({'nvim-lsp-installer', 'nvim-lsp-installer'}, { cmd = "LspInstall", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspUnInstall lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspUnInstall", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspUnInstallAll lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspUnInstallAll", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspInstallInfo lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspInstallInfo", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspInstallLog lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspInstallLog", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspLog lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspLog", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file LspPrintInstalled lua require("packer.load")({'nvim-lsp-installer'}, { cmd = "LspPrintInstalled", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file TSInstall lua require("packer.load")({'nvim-treesitter'}, { cmd = "TSInstall", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file TSBufEnable lua require("packer.load")({'nvim-treesitter'}, { cmd = "TSBufEnable", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file TSBufDisable lua require("packer.load")({'nvim-treesitter'}, { cmd = "TSBufDisable", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file TSEnable lua require("packer.load")({'nvim-treesitter'}, { cmd = "TSEnable", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file TSDisable lua require("packer.load")({'nvim-treesitter'}, { cmd = "TSDisable", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file TSModuleInfo lua require("packer.load")({'nvim-treesitter'}, { cmd = "TSModuleInfo", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) +pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file NvimTreeToggle lua require("packer.load")({'nvim-tree.lua'}, { cmd = "NvimTreeToggle", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) pcall(vim.cmd, [[command -nargs=* -range -bang -complete=file NvimTreeFocus lua require("packer.load")({'nvim-tree.lua'}, { cmd = "NvimTreeFocus", l1 = , l2 = , bang = , args = , mods = "" }, _G.packer_plugins)]]) time([[Defining lazy-load commands]], false) -- Keymap lazy-loads time([[Defining lazy-load keymaps]], true) -vim.cmd [[noremap gcc lua require("packer.load")({'Comment.nvim'}, { keys = "gcc", prefix = "" }, _G.packer_plugins)]] +vim.cmd [[noremap gb lua require("packer.load")({'Comment.nvim'}, { keys = "gb", prefix = "" }, _G.packer_plugins)]] +vim.cmd [[noremap gc lua require("packer.load")({'Comment.nvim'}, { keys = "gc", prefix = "" }, _G.packer_plugins)]] time([[Defining lazy-load keymaps]], false) vim.cmd [[augroup packer_load_aucmds]] vim.cmd [[au!]] + -- Filetype lazy-loads +time([[Defining lazy-load filetype autocommands]], true) +vim.cmd [[au FileType alpha ++once lua require("packer.load")({'nvim-tree.lua'}, { ft = "alpha" }, _G.packer_plugins)]] +time([[Defining lazy-load filetype autocommands]], false) -- Event lazy-loads time([[Defining lazy-load event autocommands]], true) -vim.cmd [[au BufRead * ++once lua require("packer.load")({'nvim-treesitter', 'indent-blankline.nvim'}, { event = "BufRead *" }, _G.packer_plugins)]] -vim.cmd [[au BufNewFile * ++once lua require("packer.load")({'nvim-treesitter'}, { event = "BufNewFile *" }, _G.packer_plugins)]] -vim.cmd [[au VimEnter * ++once lua require("packer.load")({'packer.nvim'}, { event = "VimEnter *" }, _G.packer_plugins)]] -vim.cmd [[au InsertCharPre * ++once lua require("packer.load")({'better-escape.nvim'}, { event = "InsertCharPre *" }, _G.packer_plugins)]] vim.cmd [[au InsertEnter * ++once lua require("packer.load")({'friendly-snippets'}, { event = "InsertEnter *" }, _G.packer_plugins)]] time([[Defining lazy-load event autocommands]], false) vim.cmd("augroup END") diff --git a/config/picom/picom.conf b/config/picom/picom.conf new file mode 100755 index 0000000..e9e8656 --- /dev/null +++ b/config/picom/picom.conf @@ -0,0 +1,513 @@ +################################# +# Animations # +################################# +# requires https://github.com/jonaburg/picom +# (These are also the default values) +transition-length = 300 +transition-pow-x = 0.1 +transition-pow-y = 0.1 +transition-pow-w = 0.1 +transition-pow-h = 0.1 +size-transition = true + + +################################# +# Corners # +################################# +# requires: https://github.com/sdhand/compton or https://github.com/jonaburg/picom +corner-radius = 9 +rounded-corners-exclude = [ + # "class_g = 'dmenu'", + "QTILE_INTERNAL:32c = 1", + "class_g = 'dwm'", + "class_g = 'i3bar'", + "class_g = 'awesome'", + "class_g = 'URxvt'", + "class_g = 'XTerm'", + "class_g = 'Polybar'", + "class_g = 'code-oss'", + "class_g = 'Thunderbird'", + "class_g = 'xmobar'" +]; +round-borders = 1; +round-borders-exclude = [ + #"class_g = 'TelegramDesktop'", +]; + +################################# +# Shadows # +################################# + + +# Enabled client-side shadows on windows. Note desktop windows +# (windows with '_NET_WM_WINDOW_TYPE_DESKTOP') never get shadow, +# unless explicitly requested using the wintypes option. +# +# shadow = false +shadow = true; + +# The blur radius for shadows, in pixels. (defaults to 12) +# shadow-radius = 12 +shadow-radius = 17; + +# The opacity of shadows. (0.0 - 1.0, defaults to 0.75) + +# The left offset for shadows, in pixels. (defaults to -15) +# shadow-offset-x = -15 +shadow-offset-x = -17; + +# The top offset for shadows, in pixels. (defaults to -15) +# shadow-offset-y = -15 +shadow-offset-y = -10; + +# Avoid drawing shadows on dock/panel windows. This option is deprecated, +# you should use the *wintypes* option in your config file instead. +# +# no-dock-shadow = false + +# Don't draw shadows on drag-and-drop windows. This option is deprecated, +# you should use the *wintypes* option in your config file instead. +# +# no-dnd-shadow = false + +# Red color value of shadow (0.0 - 1.0, defaults to 0). +# shadow-red = 0 + +# Green color value of shadow (0.0 - 1.0, defaults to 0). +# shadow-green = 0 + +# Blue color value of shadow (0.0 - 1.0, defaults to 0). +# shadow-blue = 0 + +# Do not paint shadows on shaped windows. Note shaped windows +# here means windows setting its shape through X Shape extension. +# Those using ARGB background is beyond our control. +# Deprecated, use +# shadow-exclude = 'bounding_shaped' +# or +# shadow-exclude = 'bounding_shaped && !rounded_corners' +# instead. +# +# shadow-ignore-shaped = '' + +# Specify a list of conditions of windows that should have no shadow. +# +# examples: +# shadow-exclude = "n:e:Notification"; +# +# shadow-exclude = [] +shadow-exclude = [ + "!focused", + # "QTILE_INTERNAL:32c = 1", + "name = 'Notification'", + "class_g = 'Conky'", + "class_g ?= 'Notify-osd'", + "class_g = 'Cairo-clock'", + "class_g = 'slop'", + "class_g = 'Polybar'", + "_GTK_FRAME_EXTENTS@:c" +]; + +# Specify a X geometry that describes the region in which shadow should not +# be painted in, such as a dock window region. Use +# shadow-exclude-reg = "x10+0+0" +# for example, if the 10 pixels on the bottom of the screen should not have shadows painted on. +# +# shadow-exclude-reg = "" + +# Crop shadow of a window fully on a particular Xinerama screen to the screen. +# xinerama-shadow-crop = false + + +################################# +# Fading # +################################# + + +# Fade windows in/out when opening/closing and when opacity changes, +# unless no-fading-openclose is used. +# fading = false +fading = true; + +# Opacity change between steps while fading in. (0.01 - 1.0, defaults to 0.028) +# fade-in-step = 0.028 +fade-in-step = 0.03; + +# Opacity change between steps while fading out. (0.01 - 1.0, defaults to 0.03) +# fade-out-step = 0.03 +fade-out-step = 0.03; + +# The time between steps in fade step, in milliseconds. (> 0, defaults to 10) +# fade-delta = 10 + +# Specify a list of conditions of windows that should not be faded. +# don't need this, we disable fading for all normal windows with wintypes: {} +fade-exclude = [ + "class_g = 'slop'" # maim +] + +# Do not fade on window open/close. +# no-fading-openclose = false + +# Do not fade destroyed ARGB windows with WM frame. Workaround of bugs in Openbox, Fluxbox, etc. +# no-fading-destroyed-argb = false + + +################################# +# Transparency / Opacity # +################################# + + +# Opacity of inactive windows. (0.1 - 1.0, defaults to 1.0) +# inactive-opacity = 1 +inactive-opacity = 0.8; + +# Opacity of window titlebars and borders. (0.1 - 1.0, disabled by default) +# frame-opacity = 1.0 +frame-opacity = 0.7; + +# Default opacity for dropdown menus and popup menus. (0.0 - 1.0, defaults to 1.0) +# menu-opacity = 1.0 +# menu-opacity is depreciated use dropdown-menu and popup-menu instead. + +#If using these 2 below change their values in line 510 & 511 aswell +popup_menu = { opacity = 0.8; } +dropdown_menu = { opacity = 0.8; } + + +# Let inactive opacity set by -i override the '_NET_WM_OPACITY' values of windows. +# inactive-opacity-override = true +inactive-opacity-override = false; + +# Default opacity for active windows. (0.0 - 1.0, defaults to 1.0) +active-opacity = 1.0; + +# Dim inactive windows. (0.0 - 1.0, defaults to 0.0) +# inactive-dim = 0.0 + +# Specify a list of conditions of windows that should always be considered focused. +# focus-exclude = [] +focus-exclude = [ + "class_g = 'Cairo-clock'", + "class_g = 'Bar'", # lemonbar + "class_g = 'slop'" # maim +]; + +# Use fixed inactive dim value, instead of adjusting according to window opacity. +# inactive-dim-fixed = 1.0 + +# Specify a list of opacity rules, in the format `PERCENT:PATTERN`, +# like `50:name *= "Firefox"`. picom-trans is recommended over this. +# Note we don't make any guarantee about possible conflicts with other +# programs that set '_NET_WM_WINDOW_OPACITY' on frame or client windows. +# example: +# opacity-rule = [ "80:class_g = 'URxvt'" ]; +# +# opacity-rule = [] +opacity-rule = [ + "100:QTILE_INTERNAL:32c = 1", + "90:class_g = 'dmenu'", + "100:class_g = 'i3lock'", + "100:class_g = 'Polybar'", + # "80:!focused", + "100:class_g = 'dmenu'", # lemonbar + "100:class_g = 'slop'", # maim + "100:class_g = 'XTerm'", + "100:class_g = 'URxvt'", + "100:class_g = 'code-oss'", + "100:class_g = 'Meld'", + "70:class_g = 'TelegramDesktop'", + "90:class_g = 'Joplin'", +]; + + +################################# +# Background-Blurring # +################################# + + +# Parameters for background blurring, see the *BLUR* section for more information. +# blur-method = +# blur-size = 12 +# +# blur-deviation = false + +# Blur background of semi-transparent / ARGB windows. +# Bad in performance, with driver-dependent behavior. +# The name of the switch may change without prior notifications. +# +# blur-background = true; + +# Blur background of windows when the window frame is not opaque. +# Implies: +# blur-background +# Bad in performance, with driver-dependent behavior. The name may change. +# +# blur-background-frame = false; + + +# Use fixed blur strength rather than adjusting according to window opacity. +# blur-background-fixed = false; + + +# Specify the blur convolution kernel, with the following format: +# example: +# blur-kern = "5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"; +# +# blur-kern = '' +# blur-kern = "3x3box"; + +blur: { + method = "dual_kawase"; + # method = "none"; + strength = 2.5; + # deviation = 1.0; + # kernel = "11x11gaussian"; + background = false; + background-frame = false; + background-fixed = false; + kern = "3x3box"; +} + +# Exclude conditions for background blur. +blur-background-exclude = [ + #"window_type = 'dock'", + #"window_type = 'desktop'", + "QTILE_INTERNAL:32c = 1", + # "class_g = 'QTILE_INTERNAL:32c = 1'", + "class_g = 'Polybar'", + # + # prevents picom from blurring the background + # when taking selection screenshot with `main` + # https://github.com/naelstrof/maim/issues/130 + "class_g = 'slop'", + "_GTK_FRAME_EXTENTS@:c" +]; + + +################################# +# General Settings # +################################# + +# Daemonize process. Fork to background after initialization. Causes issues with certain (badly-written) drivers. +# daemon = false + +# Specify the backend to use: `xrender`, `glx`, or `xr_glx_hybrid`. +# `xrender` is the default one. +# +experimental-backends = true; +backend = "glx"; +# backend = "xrender"; + + +# Enable/disable VSync. +# vsync = false +vsync = true + +# Enable remote control via D-Bus. See the *D-BUS API* section below for more details. +# dbus = false + +# Try to detect WM windows (a non-override-redirect window with no +# child that has 'WM_STATE') and mark them as active. +# +# mark-wmwin-focused = false +mark-wmwin-focused = true; + +# Mark override-redirect windows that doesn't have a child window with 'WM_STATE' focused. +# mark-ovredir-focused = false +mark-ovredir-focused = true; + +# Try to detect windows with rounded corners and don't consider them +# shaped windows. The accuracy is not very high, unfortunately. +# +# detect-rounded-corners = false +detect-rounded-corners = true; + +# Detect '_NET_WM_OPACITY' on client windows, useful for window managers +# not passing '_NET_WM_OPACITY' of client windows to frame windows. +# +# detect-client-opacity = false +detect-client-opacity = true; +# Specify refresh rate of the screen. If not specified or 0, picom will +# try detecting this with X RandR extension. +# +# refresh-rate = 60 +refresh-rate = 0 + +# Limit picom to repaint at most once every 1 / 'refresh_rate' second to +# boost performance. This should not be used with +# vsync drm/opengl/opengl-oml +# as they essentially does sw-opti's job already, +# unless you wish to specify a lower refresh rate than the actual value. +# +# sw-opti = + +# Use EWMH '_NET_ACTIVE_WINDOW' to determine currently focused window, +# rather than listening to 'FocusIn'/'FocusOut' event. Might have more accuracy, +# provided that the WM supports it. +# +# use-ewmh-active-win = false + +# Unredirect all windows if a full-screen opaque window is detected, +# to maximize performance for full-screen windows. Known to cause flickering +# when redirecting/unredirecting windows. paint-on-overlay may make the flickering less obvious. +# +# unredir-if-possible = false + +# Delay before unredirecting the window, in milliseconds. Defaults to 0. +# unredir-if-possible-delay = 0 + +# Conditions of windows that shouldn't be considered full-screen for unredirecting screen. +# unredir-if-possible-exclude = [] + +# Use 'WM_TRANSIENT_FOR' to group windows, and consider windows +# in the same group focused at the same time. +# +# detect-transient = false +detect-transient = true + +# Use 'WM_CLIENT_LEADER' to group windows, and consider windows in the same +# group focused at the same time. 'WM_TRANSIENT_FOR' has higher priority if +# detect-transient is enabled, too. +# +# detect-client-leader = false +detect-client-leader = true + +# Resize damaged region by a specific number of pixels. +# A positive value enlarges it while a negative one shrinks it. +# If the value is positive, those additional pixels will not be actually painted +# to screen, only used in blur calculation, and such. (Due to technical limitations, +# with use-damage, those pixels will still be incorrectly painted to screen.) +# Primarily used to fix the line corruption issues of blur, +# in which case you should use the blur radius value here +# (e.g. with a 3x3 kernel, you should use `--resize-damage 1`, +# with a 5x5 one you use `--resize-damage 2`, and so on). +# May or may not work with *--glx-no-stencil*. Shrinking doesn't function correctly. +# +# resize-damage = 1 + +# Specify a list of conditions of windows that should be painted with inverted color. +# Resource-hogging, and is not well tested. +# +# invert-color-include = [] + +# GLX backend: Avoid using stencil buffer, useful if you don't have a stencil buffer. +# Might cause incorrect opacity when rendering transparent content (but never +# practically happened) and may not work with blur-background. +# My tests show a 15% performance boost. Recommended. +# +# glx-no-stencil = false + +# GLX backend: Avoid rebinding pixmap on window damage. +# Probably could improve performance on rapid window content changes, +# but is known to break things on some drivers (LLVMpipe, xf86-video-intel, etc.). +# Recommended if it works. +# +# glx-no-rebind-pixmap = false + +# Disable the use of damage information. +# This cause the whole screen to be redrawn everytime, instead of the part of the screen +# has actually changed. Potentially degrades the performance, but might fix some artifacts. +# The opposing option is use-damage +# +# no-use-damage = false +#use-damage = true (Causing Weird Black semi opaque rectangles when terminal is opened) +#Changing use-damage to false fixes the problem +use-damage = false + +# Use X Sync fence to sync clients' draw calls, to make sure all draw +# calls are finished before picom starts drawing. Needed on nvidia-drivers +# with GLX backend for some users. +# +# xrender-sync-fence = false + +# GLX backend: Use specified GLSL fragment shader for rendering window contents. +# See `compton-default-fshader-win.glsl` and `compton-fake-transparency-fshader-win.glsl` +# in the source tree for examples. +# +# glx-fshader-win = '' + +# Force all windows to be painted with blending. Useful if you +# have a glx-fshader-win that could turn opaque pixels transparent. +# +# force-win-blend = false + +# Do not use EWMH to detect fullscreen windows. +# Reverts to checking if a window is fullscreen based only on its size and coordinates. +# +# no-ewmh-fullscreen = false + +# Dimming bright windows so their brightness doesn't exceed this set value. +# Brightness of a window is estimated by averaging all pixels in the window, +# so this could comes with a performance hit. +# Setting this to 1.0 disables this behaviour. Requires --use-damage to be disabled. (default: 1.0) +# +# max-brightness = 1.0 + +# Make transparent windows clip other windows like non-transparent windows do, +# instead of blending on top of them. +# +# transparent-clipping = false + +# Set the log level. Possible values are: +# "trace", "debug", "info", "warn", "error" +# in increasing level of importance. Case doesn't matter. +# If using the "TRACE" log level, it's better to log into a file +# using *--log-file*, since it can generate a huge stream of logs. +# +# log-level = "debug" +log-level = "info"; + +# Set the log file. +# If *--log-file* is never specified, logs will be written to stderr. +# Otherwise, logs will to written to the given file, though some of the early +# logs might still be written to the stderr. +# When setting this option from the config file, it is recommended to use an absolute path. +# +# log-file = '/path/to/your/log/file' + +# Show all X errors (for debugging) +# show-all-xerrors = false + +# Write process ID to a file. +# write-pid-path = '/path/to/your/log/file' + +# Window type settings +# +# 'WINDOW_TYPE' is one of the 15 window types defined in EWMH standard: +# "unknown", "desktop", "dock", "toolbar", "menu", "utility", +# "splash", "dialog", "normal", "dropdown_menu", "popup_menu", +# "tooltip", "notification", "combo", and "dnd". +# +# Following per window-type options are available: :: +# +# fade, shadow::: +# Controls window-type-specific shadow and fade settings. +# +# opacity::: +# Controls default opacity of the window type. +# +# focus::: +# Controls whether the window of this type is to be always considered focused. +# (By default, all window types except "normal" and "dialog" has this on.) +# +# full-shadow::: +# Controls whether shadow is drawn under the parts of the window that you +# normally won't be able to see. Useful when the window has parts of it +# transparent, and you want shadows in those areas. +# +# redir-ignore::: +# Controls whether this type of windows should cause screen to become +# redirected again after been unredirected. If you have unredir-if-possible +# set, and doesn't want certain window to cause unnecessary screen redirection, +# you can set this to `true`. +# +wintypes: +{ + normal = { fade = false; shadow = true; } + tooltip = { fade = true; shadow = true; opacity = 0.75; focus = true; full-shadow = true; }; + dock = { shadow = true; } + dnd = { shadow = true; } + popup_menu = { opacity = 0.8; } + dropdown_menu = { opacity = 0.8; } +}; diff --git a/config/rofi/config.rasi b/config/rofi/config.rasi new file mode 100644 index 0000000..5281a22 --- /dev/null +++ b/config/rofi/config.rasi @@ -0,0 +1,8 @@ +configuration { + show-icons: true; + icon-theme: "Zafiro"; + terminal: "alacritty"; + cycle: false; + hide-scrollbar: true; + disable-history: false; +} diff --git a/config/wezterm/wezterm.lua b/config/wezterm/wezterm.lua old mode 100644 new mode 100755 index 7b3d2ff..b01cbb5 --- a/config/wezterm/wezterm.lua +++ b/config/wezterm/wezterm.lua @@ -1,42 +1,255 @@ ---[[ - _ _ _ _____ _____ _____ _____ _____ _____ -| | | | __|__ |_ _| __| __ | | -| | | | __| __| | | | __| -| | | | -|_____|_____|_____| |_| |_____|__|__|_|_|_| - ~ Aesthetic Wezterm ~ - rxyhn ---]] +-- ------------------------------------------------------------------- +-- rxyhn's aesthetic wezterm configuration +-- A GPU-accelerated cross-platform terminal emulator and multiplexer +-- +-- https://github.com/rxyhn +-- ------------------------------------------------------------------- -local wezterm = require 'wezterm'; +local wezterm = require("wezterm") + +local function font_with_fallback(name, params) + local names = { name, "Apple Color Emoji", "azuki_font" } + return wezterm.font_with_fallback(names, params) +end + +local font_name = "FiraCode Nerd Font" + +local colors = { + -- special + foreground = "#d9d7d6", + darker_background = "#000a0e", + background = "rgba(6,17,21,0.5)", + lighter_background = "#0d181c", + + -- black + color0 = "#1c252c", + color8 = "#484e5b", + + -- red + color1 = "#df5b61", + color9 = "#f16269", + + -- green + color2 = "#78b892", + color10 = "#8cd7aa", + + -- yellow + color3 = "#de8f78", + color11 = "#e9967e", + + -- blue + color4 = "#6791c9", + color12 = "#79aaeb", + + -- magenta + color5 = "#bc83e3", + color13 = "#c488ec", + + -- cyan + color6 = "#67afc1", + color14 = "#7acfe4", + + -- white + color7 = "#d9d7d6", + color15 = "#e5e5e5", +} return { - font_dirs = {"/home/gallant/.fonts"}, - front_end = "OpenGL", - font = wezterm.font("Iosevka", {weight = "Regular", italic = false}), - harfbuzz_features = {"calt=0", "clig=0", "liga=0"}, - font_size = 11, - colors = { -- aesthetic night colorscheme - foreground = "#d9d7d6", - background = "#061115", - cursor_bg = "#d9d7d6", - cursor_fg = "#d9d7d6", - cursor_border = "#d9d7d6", - selection_fg = "#061115", - selection_bg = "#d9d7d6", - scrollbar_thumb = "#d9d7d6", - split = "#16161a", - ansi = {"#061115", "#df5b61", "#78b892", "#de8f78", "#6791c9", "#bc83e3", "#67afc1", "#d9d7d6"}, - brights = {"#484e5b", "#f16269", "#8cd7aa", "#e9967e", "#79aaeb", "#c488ec", "#7acfe4", "#e5e5e5"}, - indexed = {[136] = "#d9d7d6"}, - }, - window_padding = { - left = 25, - right = 25, - top = 25, - bottom = 25, - }, - enable_tab_bar = false, - default_cursor_style = "BlinkingUnderline", - exit_behavior = "CloseOnCleanExit", - window_background_opacity = 0.20 + -- OpenGL for GPU acceleration, Software for CPU + front_end = "OpenGL", + + -- Font config + font = font_with_fallback(font_name), + font_rules = { + { italic = true, font = font_with_fallback(font_name, { italic = true }) }, + { + italic = true, + intensity = "Bold", + font = font_with_fallback(font_name, { bold = true, italic = true }), + }, + { + intensity = "Bold", + font = font_with_fallback(font_name, { bold = true }), + }, + { intensity = "Half", font = font_with_fallback(font_name .. " Light") }, + }, + font_size = 11, + line_height = 1.0, + + -- Cursor style + default_cursor_style = "BlinkingUnderline", + + -- X11 + enable_wayland = false, + + -- Keybinds + disable_default_key_bindings = true, + keys = { + { + key = [[\]], + mods = "CTRL|SHIFT", + action = wezterm.action({ + SplitHorizontal = { domain = "CurrentPaneDomain" }, + }), + }, + { + key = [[\]], + mods = "CTRL", + action = wezterm.action({ + SplitVertical = { domain = "CurrentPaneDomain" }, + }), + }, + { + key = "q", + mods = "CTRL", + action = wezterm.action({ CloseCurrentPane = { confirm = false } }), + }, + { + key = "h", + mods = "CTRL|SHIFT", + action = wezterm.action({ ActivatePaneDirection = "Left" }), + }, + { + key = "l", + mods = "CTRL|SHIFT", + action = wezterm.action({ ActivatePaneDirection = "Right" }), + }, + { + key = "k", + mods = "CTRL|SHIFT", + action = wezterm.action({ ActivatePaneDirection = "Up" }), + }, + { + key = "j", + mods = "CTRL|SHIFT", + action = wezterm.action({ ActivatePaneDirection = "Down" }), + }, + { + key = "h", + mods = "CTRL|SHIFT|ALT", + action = wezterm.action({ AdjustPaneSize = { "Left", 1 } }), + }, + { + key = "l", + mods = "CTRL|SHIFT|ALT", + action = wezterm.action({ AdjustPaneSize = { "Right", 1 } }), + }, + { + key = "k", + mods = "CTRL|SHIFT|ALT", + action = wezterm.action({ AdjustPaneSize = { "Up", 1 } }), + }, + { + key = "j", + mods = "CTRL|SHIFT|ALT", + action = wezterm.action({ AdjustPaneSize = { "Down", 1 } }), + }, + { -- browser-like bindings for tabbing + key = "t", + mods = "CTRL", + action = wezterm.action({ SpawnTab = "CurrentPaneDomain" }), + }, + { + key = "w", + mods = "CTRL", + action = wezterm.action({ CloseCurrentTab = { confirm = false } }), + }, + { + key = "Tab", + mods = "CTRL", + action = wezterm.action({ ActivateTabRelative = 1 }), + }, + { + key = "Tab", + mods = "CTRL|SHIFT", + action = wezterm.action({ ActivateTabRelative = -1 }), + }, -- standard copy/paste bindings + { + key = "x", + mods = "CTRL", + action = "ActivateCopyMode", + }, + { + key = "v", + mods = "CTRL|SHIFT", + action = wezterm.action({ PasteFrom = "Clipboard" }), + }, + { + key = "c", + mods = "CTRL|SHIFT", + action = wezterm.action({ CopyTo = "ClipboardAndPrimarySelection" }), + }, + }, + + -- Aesthetic Night Colorscheme + bold_brightens_ansi_colors = false, + colors = { + background = colors.background, + foreground = colors.foreground, + + cursor_bg = colors.foreground, + cursor_fg = colors.foreground, + cursor_border = colors.foreground, + + selection_fg = colors.background, + selection_bg = colors.color4, + + scrollbar_thumb = colors.foreground, + + split = colors.lighter_background, + + ansi = { + colors.color0, + colors.color1, + colors.color2, + colors.color3, + colors.color4, + colors.color5, + colors.color6, + colors.color7, + }, + + brights = { + colors.color8, + colors.color9, + colors.color10, + colors.color11, + colors.color12, + colors.color13, + colors.color14, + colors.color15, + }, + + tab_bar = { + active_tab = { + bg_color = colors.background, + fg_color = colors.color8, + italic = true, + }, + inactive_tab = { bg_color = colors.darker_background, fg_color = colors.color8 }, + inactive_tab_hover = { bg_color = colors.color0, fg_color = colors.background }, + }, + }, + + -- Padding + window_padding = { + left = 25, + right = 25, + top = 25, + bottom = 25, + }, + + -- Tab Bar + enable_tab_bar = true, + hide_tab_bar_if_only_one_tab = true, + show_tab_index_in_tab_bar = false, + tab_bar_at_bottom = true, + + -- General + automatically_reload_config = true, + inactive_pane_hsb = { saturation = 1.0, brightness = 1.0 }, + window_frame = { active_titlebar_bg = colors.darker_background }, + exit_behavior = "CloseOnCleanExit", + window_decorations = "RESIZE", + selection_word_boundary = " \t\n{}[]()\"'`,;:", } diff --git a/misc/.zshrc b/misc/.zshrc old mode 100644 new mode 100755 index 6951b19..be958ae --- a/misc/.zshrc +++ b/misc/.zshrc @@ -1,109 +1,52 @@ -# If you come from bash you might have to change your $PATH. -export PATH=$HOME/bin:/usr/local/bin:$PATH:$HOME/.yarn/bin/:$HOME/.local/bin:$HOME/.emacs.d/bin:$HOME/.cargo/bin -export RUST_SRC_PATH=$(rustc --print sysroot)/lib/rustlib/src/rust/library -# Path to your oh-my-zsh installation. -export ZSH="$HOME/.oh-my-zsh" +# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc. +# Initialization code that may require console input (password prompts, [y/n] +# confirmations, etc.) must go above this block; everything else may go below. +if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then + source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" +fi -# Set name of the theme to load --- if set to "random", it will -# load a random theme each time oh-my-zsh is loaded, in which case, -# to know which specific one was loaded, run: echo $RANDOM_THEME -# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes -ZSH_THEME="robbyrussell" +source ~/bin/antigen.zsh -# Set list of themes to pick from when loading at random -# Setting this variable when ZSH_THEME=random will cause zsh to load -# a theme from this variable instead of looking in $ZSH/themes/ -# If set to an empty array, this variable will have no effect. -# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) +antigen use oh-my-zsh -# Uncomment the following line to use case-sensitive completion. -# CASE_SENSITIVE="true" +antigen bundle git +# antigen bundle asdf -# Uncomment the following line to use hyphen-insensitive completion. -# Case-sensitive completion must be off. _ and - will be interchangeable. -# HYPHEN_INSENSITIVE="true" +antigen bundle zsh-users/zsh-syntax-highlighting +antigen bundle zsh-users/zsh-autosuggestions -# Uncomment one of the following lines to change the auto-update behavior -# zstyle ':omz:update' mode disabled # disable automatic updates -# zstyle ':omz:update' mode auto # update automatically without asking -# zstyle ':omz:update' mode reminder # just remind me to update when it's time +# antigen theme PsychoPatate/chill.zsh-theme chill +# antigen theme afowler +# antigen theme awesomepanda +antigen theme romkatv/powerlevel10k -# Uncomment the following line to change how often to auto-update (in days). -# zstyle ':omz:update' frequency 13 +antigen apply +# PATH=~/bin:~/.asdf/installs/rust/1.49.0/bin:$PATH +PATH=~/bin:$PATH:~/.local/bin:~/.yarn/bin/ -# Uncomment the following line if pasting URLs and other text is messed up. -# DISABLE_MAGIC_FUNCTIONS="true" - -# Uncomment the following line to disable colors in ls. -# DISABLE_LS_COLORS="true" - -# Uncomment the following line to disable auto-setting terminal title. -# DISABLE_AUTO_TITLE="true" - -# Uncomment the following line to enable command auto-correction. -# ENABLE_CORRECTION="true" - -# Uncomment the following line to display red dots whilst waiting for completion. -# You can also set it to another string to have that shown instead of the default red dots. -# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" -# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) -# COMPLETION_WAITING_DOTS="true" - -# Uncomment the following line if you want to disable marking untracked files -# under VCS as dirty. This makes repository status check for large repositories -# much, much faster. -# DISABLE_UNTRACKED_FILES_DIRTY="true" - -# Uncomment the following line if you want to change the command execution time -# stamp shown in the history command output. -# You can set one of the optional three formats: -# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" -# or set a custom format using the strftime function format specifications, -# see 'man strftime' for details. -# HIST_STAMPS="mm/dd/yyyy" - -# Would you like to use another custom folder than $ZSH/custom? -# ZSH_CUSTOM=/path/to/new-custom-folder - -# Which plugins would you like to load? -# Standard plugins can be found in $ZSH/plugins/ -# Custom plugins may be added to $ZSH_CUSTOM/plugins/ -# Example format: plugins=(rails git textmate ruby lighthouse) -# Add wisely, as too many plugins slow down shell startup. -plugins=(git zsh-autosuggestions) - -source $ZSH/oh-my-zsh.sh - -# User configuration - -# export MANPATH="/usr/local/man:$MANPATH" - -# You may need to manually set your language environment -# export LANG=en_US.UTF-8 - -# Preferred editor for local and remote sessions -# if [[ -n $SSH_CONNECTION ]]; then -# export EDITOR='vim' -# else -# export EDITOR='mvim' -# fi - -# Compilation flags -# export ARCHFLAGS="-arch x86_64" - -# Set personal aliases, overriding those provided by oh-my-zsh libs, -# plugins, and themes. Aliases can be placed here, though oh-my-zsh -# users are encouraged to define aliases within the ZSH_CUSTOM folder. -# For a full list of active aliases, run `alias`. -# -# Example aliases -# alias zshconfig="mate ~/.zshrc" -# alias ohmyzsh="mate ~/.oh-my-zsh" -export EDITOR='emacs -nw' +autoload -Uz compinit && compinit alias discord='discord --no-sandbox' -alias em='emacs -nw' -alias ssh="kitty +kitten ssh" +#alias ssh="kitty +kitten ssh" alias icat="kitty +kitten icat" alias cat="bat" -alias ls='ls -a --color=auto' +alias ls='lsd -a' + +setopt correct + + +export EDITOR='emacs -nw' + +# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh. +[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh +autoload -U +X bashcompinit && bashcompinit +complete -o nospace -C /home/gallantcrusader/bin/bit bit + + +export TZ="/usr/share/zoneinfo/America/Chicago" + +# eval "$(starship init zsh)" + +unalias grm +hash -rf + diff --git a/misc/nasa.png b/misc/nasa.png new file mode 100644 index 0000000..f2cbddc Binary files /dev/null and b/misc/nasa.png differ diff --git a/misc/wack.json b/misc/wack.json new file mode 100644 index 0000000..cbd8bf1 --- /dev/null +++ b/misc/wack.json @@ -0,0 +1,28 @@ +{ + "wallpaper": "/home/gallant/.config/wpg/wallpapers/city-topview.png", + "alpha": "100", + + "special": { + "background": "#0b0f11", + "foreground": "#aabcc2", + "cursor": "#aabcc2" + }, + "colors": { + "color0": "#0b0f11", + "color1": "#1C4452", + "color2": "#294753", + "color3": "#2E5766", + "color4": "#346472", + "color5": "#525C61", + "color6": "#4F7885", + "color7": "#aabcc2", + "color8": "#768387", + "color9": "#1C4452", + "color10": "#294753", + "color11": "#2E5766", + "color12": "#346472", + "color13": "#525C61", + "color14": "#4F7885", + "color15": "#aabcc2" + } +}