mess around
281
flake.lock
generated
@ -256,7 +256,234 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprcursor": {
|
||||
"inputs": {
|
||||
"hyprlang": [
|
||||
"hyprland",
|
||||
"hyprlang"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720108799,
|
||||
"narHash": "sha256-AxRkTJlbB8r7aG6gvc7IaLhc2T9TO4/8uqanKRxukBQ=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprcursor",
|
||||
"rev": "a5c0d57325c5f0814c39110a70ca19c070ae9486",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprcursor",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland": {
|
||||
"inputs": {
|
||||
"hyprcursor": "hyprcursor",
|
||||
"hyprlang": "hyprlang",
|
||||
"hyprutils": "hyprutils",
|
||||
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"systems": "systems",
|
||||
"xdph": "xdph"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720731503,
|
||||
"narHash": "sha256-Qlm0IRnOrI64RW/SEvW9rA1ytVvPS1CsVvRataNvStI=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "e728e56cbc6af0a9be1276b2cf8e019a894016e7",
|
||||
"revCount": 4917,
|
||||
"submodules": true,
|
||||
"type": "git",
|
||||
"url": "https://github.com/hyprwm/Hyprland"
|
||||
},
|
||||
"original": {
|
||||
"submodules": true,
|
||||
"type": "git",
|
||||
"url": "https://github.com/hyprwm/Hyprland"
|
||||
}
|
||||
},
|
||||
"hyprland-hyprspace": {
|
||||
"inputs": {
|
||||
"hyprland": [
|
||||
"hyprland"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720553729,
|
||||
"narHash": "sha256-9aM4MCBJn4UstcsSdukOFTxg79keUMTw9Kmqr7Wsfmw=",
|
||||
"owner": "KZDKM",
|
||||
"repo": "Hyprspace",
|
||||
"rev": "e8662093ae5b6e13a3cf1145d21d4804a3e84aeb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "KZDKM",
|
||||
"repo": "Hyprspace",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-plugins": {
|
||||
"inputs": {
|
||||
"hyprland": [
|
||||
"hyprland"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"hyprland-plugins",
|
||||
"hyprland",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland-plugins",
|
||||
"hyprland",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719784423,
|
||||
"narHash": "sha256-D7O5+nh2Wn9tQPJArWHrDSZeEfBCtj5zTGd86701LPE=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-plugins",
|
||||
"rev": "98cb18c6fcfe8196ef4150d09fbae305b7bb2954",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-plugins",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-protocols": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"xdph",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland",
|
||||
"xdph",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1718746314,
|
||||
"narHash": "sha256-HUklK5u86w2Yh9dOkk4FdsL8eehcOZ95jPhLixGDRQY=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"rev": "1b61f0093afff20ab44d88ad707aed8bf2215290",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprlang": {
|
||||
"inputs": {
|
||||
"hyprutils": [
|
||||
"hyprland",
|
||||
"hyprutils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720381373,
|
||||
"narHash": "sha256-lyC/EZdHULsaAKVryK11lgHY9u6pXr7qR4irnxNWC7k=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"rev": "5df0174fd09de4ac5475233d65ffc703e89b82eb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprutils": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720545076,
|
||||
"narHash": "sha256-Pxacc2uoxI00koXp5+CyNqHOTQlqNlK0rlRHDBHX4+g=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "6174a2a25f4e216c0f1d0c4278adc23c476b1d09",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprwayland-scanner": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720215857,
|
||||
"narHash": "sha256-JPdL+Qul+jEueAn8CARfcWP83eJgwkhMejQYfDvrgvU=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwayland-scanner",
|
||||
"rev": "d5fa094ca27e0039be5e94c0a80ae433145af8bb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwayland-scanner",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1720542800,
|
||||
"narHash": "sha256-ZgnNHuKV6h2+fQ5LuqnUaqZey1Lqqt5dTUAiAnqH0QQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "feb2849fdeb70028c70d73b848214b00d324a497",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1719690277,
|
||||
"narHash": "sha256-0xSej1g7eP2kaUF+JQp8jdyNmpmCJKRpO12mKl/36Kc=",
|
||||
@ -272,7 +499,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1714912032,
|
||||
"narHash": "sha256-clkcOIkg8G4xuJh+1onLG4HPMpbtzdLv4rHxFzgsH9c=",
|
||||
@ -293,7 +520,10 @@
|
||||
"aagl": "aagl",
|
||||
"catppuccin": "catppuccin",
|
||||
"home-manager": "home-manager",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"hyprland": "hyprland",
|
||||
"hyprland-hyprspace": "hyprland-hyprspace",
|
||||
"hyprland-plugins": "hyprland-plugins",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"stylix": "stylix"
|
||||
}
|
||||
},
|
||||
@ -309,7 +539,7 @@
|
||||
"flake-compat": "flake-compat_2",
|
||||
"gnome-shell": "gnome-shell",
|
||||
"home-manager": "home-manager_2",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719525570,
|
||||
@ -324,6 +554,51 @@
|
||||
"repo": "stylix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1689347949,
|
||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"xdph": {
|
||||
"inputs": {
|
||||
"hyprland-protocols": "hyprland-protocols",
|
||||
"hyprlang": [
|
||||
"hyprland",
|
||||
"hyprlang"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720194466,
|
||||
"narHash": "sha256-Rizg9efi6ue95zOp0MeIV2ZedNo+5U9G2l6yirgBUnA=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "xdg-desktop-portal-hyprland",
|
||||
"rev": "b9b97e5ba23fe7bd5fa4df54696102e8aa863cf6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "xdg-desktop-portal-hyprland",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
||||
12
flake.nix
@ -17,6 +17,18 @@
|
||||
url = "github:ezKEa/aagl-gtk-on-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
hyprland.url = "git+https://github.com/hyprwm/Hyprland?submodules=1";
|
||||
|
||||
hyprland-plugins = {
|
||||
url = "github:hyprwm/hyprland-plugins";
|
||||
inputs.hyprland.follows = "hyprland";
|
||||
};
|
||||
|
||||
hyprland-hyprspace = {
|
||||
url = "github:KZDKM/Hyprspace";
|
||||
inputs.hyprland.follows = "hyprland";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, ... }@inputs:
|
||||
|
||||
@ -82,7 +82,7 @@
|
||||
users.users.shoi = {
|
||||
isNormalUser = true;
|
||||
description = "Sho Ishida";
|
||||
extraGroups = [ "networkmanager" "wheel" "input" ];
|
||||
extraGroups = [ "networkmanager" "wheel" "input" "audio" ];
|
||||
shell = pkgs.zsh;
|
||||
};
|
||||
|
||||
@ -105,6 +105,8 @@
|
||||
environment.systemPackages = with pkgs; [
|
||||
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
|
||||
lm_sensors
|
||||
brightnessctl
|
||||
inotify-tools
|
||||
];
|
||||
|
||||
# Some programs need SUID wrappers, can be configured further or are
|
||||
|
||||
@ -22,16 +22,22 @@
|
||||
# For funsies
|
||||
spotify
|
||||
vesktop
|
||||
ncmpcpp
|
||||
mpd
|
||||
mpdris2
|
||||
|
||||
# Other utility
|
||||
mullvad-vpn
|
||||
transmission_4-gtk
|
||||
imagemagick
|
||||
neofetch
|
||||
];
|
||||
|
||||
# Enable sound control
|
||||
services.easyeffects.enable = true;
|
||||
|
||||
services.playerctld.enable = true;
|
||||
|
||||
# Home Manager is pretty good at managing dotfiles. The primary way to manage
|
||||
# plain files is through 'home.file'.
|
||||
home.file = {
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
# Utils
|
||||
corefonts
|
||||
noto-fonts
|
||||
flameshot
|
||||
];
|
||||
|
||||
programs.firefox.enable = true;
|
||||
|
||||
8
modules/home-manager/ricing/awesomewm/default.nix
Normal file
@ -0,0 +1,8 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
home.file.".config/awesome" = {
|
||||
recursive = true;
|
||||
source = ./dotfiles;
|
||||
};
|
||||
}
|
||||
230
modules/home-manager/ricing/awesomewm/dotfiles/helpers.lua
Normal file
@ -0,0 +1,230 @@
|
||||
local helpers = {}
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local gears = require("gears")
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
local cairo = require("lgi").cairo
|
||||
local gmatrix = require("gears.matrix")
|
||||
local json = require("mods.json")
|
||||
|
||||
helpers.rrect = function(radius)
|
||||
radius = radius or dpi(4)
|
||||
return function(cr, width, height)
|
||||
gears.shape.rounded_rect(cr, width, height, radius)
|
||||
end
|
||||
end
|
||||
|
||||
helpers.addHover = function(element, bg, hbg)
|
||||
element:connect_signal('mouse::enter', function(self)
|
||||
self.bg = hbg
|
||||
end)
|
||||
element:connect_signal('mouse::leave', function(self)
|
||||
self.bg = bg
|
||||
end)
|
||||
end
|
||||
|
||||
helpers.placeWidget = function(widget)
|
||||
if beautiful.barDir == 'left' then
|
||||
awful.placement.bottom_left(widget, { honor_workarea = true, margins = beautiful.useless_gap * 2 })
|
||||
elseif beautiful.barDir == 'right' then
|
||||
awful.placement.bottom_right(widget, { honor_workarea = true, margins = beautiful.useless_gap * 2 })
|
||||
elseif beautiful.barDir == 'bottom' then
|
||||
awful.placement.bottom(widget, { honor_workarea = true, margins = beautiful.useless_gap * 2 })
|
||||
elseif beautiful.barDir == 'top' then
|
||||
awful.placement.top(widget, { honor_workarea = true, margins = beautiful.useless_gap * 2 })
|
||||
end
|
||||
end
|
||||
|
||||
helpers.prect = function(tl, tr, br, bl, radius)
|
||||
radius = radius or dpi(4)
|
||||
return function(cr, width, height)
|
||||
gears.shape.partially_rounded_rect(cr, width, height, tl, tr, br, bl, radius)
|
||||
end
|
||||
end
|
||||
|
||||
helpers.clickKey = function(c, key)
|
||||
awful.spawn.with_shell("xdotool type --window " .. tostring(c.window) .. " '" .. key .. "'")
|
||||
end
|
||||
|
||||
helpers.colorizeText = function(txt, fg)
|
||||
if fg == "" then
|
||||
fg = "#ffffff"
|
||||
end
|
||||
|
||||
return "<span foreground='" .. fg .. "'>" .. txt .. "</span>"
|
||||
end
|
||||
|
||||
helpers.cropSurface = function(ratio, surf)
|
||||
local old_w, old_h = gears.surface.get_size(surf)
|
||||
local old_ratio = old_w / old_h
|
||||
if old_ratio == ratio then return surf end
|
||||
|
||||
local new_h = old_h
|
||||
local new_w = old_w
|
||||
local offset_h, offset_w = 0, 0
|
||||
-- quick mafs
|
||||
if (old_ratio < ratio) then
|
||||
new_h = math.ceil(old_w * (1 / ratio))
|
||||
offset_h = math.ceil((old_h - new_h) / 2)
|
||||
else
|
||||
new_w = math.ceil(old_h * ratio)
|
||||
offset_w = math.ceil((old_w - new_w) / 2)
|
||||
end
|
||||
|
||||
local out_surf = cairo.ImageSurface(cairo.Format.ARGB32, new_w, new_h)
|
||||
local cr = cairo.Context(out_surf)
|
||||
cr:set_source_surface(surf, -offset_w, -offset_h)
|
||||
cr.operator = cairo.Operator.SOURCE
|
||||
cr:paint()
|
||||
|
||||
return out_surf
|
||||
end
|
||||
|
||||
helpers.inTable = function(t, v)
|
||||
for _, value in ipairs(t) do
|
||||
if value == v then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
helpers.generateId = function()
|
||||
local template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
||||
return string.gsub(template, '[xy]', function(c)
|
||||
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
|
||||
return string.format('%x', v)
|
||||
end)
|
||||
end
|
||||
|
||||
helpers.find_last = function(haystack, needle)
|
||||
-- Set the third arg to false to allow pattern matching
|
||||
local found = haystack:reverse():find(needle:reverse(), nil, true)
|
||||
if found then
|
||||
return haystack:len() - needle:len() - found + 2
|
||||
else
|
||||
return found
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
helpers.addTables = function(a, b)
|
||||
local result = {}
|
||||
for _, v in pairs(a) do
|
||||
table.insert(result, v)
|
||||
end
|
||||
for _, v in pairs(b) do
|
||||
table.insert(result, v)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
helpers.hasKey = function(set, key)
|
||||
return set[key] ~= nil
|
||||
end
|
||||
|
||||
helpers.trim = function(string)
|
||||
return string:gsub("^%s*(.-)%s*$", "%1")
|
||||
end
|
||||
helpers.indexOf = function(array, value)
|
||||
for i, v in ipairs(array) do
|
||||
if v == value then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
helpers.split = function(inputstr, sep)
|
||||
if sep == nil then
|
||||
sep = "%s"
|
||||
end
|
||||
local t = {}
|
||||
for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
|
||||
table.insert(t, str)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
helpers.readFile = function(file)
|
||||
local f = assert(io.open(file, "rb"))
|
||||
local content = f:read("*all")
|
||||
f:close()
|
||||
return content
|
||||
end
|
||||
|
||||
helpers.file_exists = function(name)
|
||||
local f = io.open(name, "r")
|
||||
if f ~= nil then
|
||||
io.close(f)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
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 helpers.get_widget_geometry(wibox, widget)
|
||||
return get_widget_geometry(wibox._drawable._widget_hierarchy, widget)
|
||||
end
|
||||
|
||||
function helpers.randomColor()
|
||||
local accents = {
|
||||
beautiful.magenta,
|
||||
beautiful.yellow,
|
||||
beautiful.green,
|
||||
beautiful.red,
|
||||
beautiful.blue,
|
||||
}
|
||||
|
||||
local i = math.random(1, #accents)
|
||||
return accents[i]
|
||||
end
|
||||
|
||||
helpers.readJson = function(DATA)
|
||||
if helpers.file_exists(DATA) then
|
||||
local f = assert(io.open(DATA, "rb"))
|
||||
local lines = f:read("*all")
|
||||
f:close()
|
||||
local data = json.decode(lines)
|
||||
return data
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
helpers.writeJson = function(PATH, DATA)
|
||||
local w = assert(io.open(PATH, "w"))
|
||||
w:write(json.encode(DATA, nil, { pretty = true, indent = " ", align_keys = false, array_newline = true }))
|
||||
w:close()
|
||||
end
|
||||
|
||||
-- this stands for :get_children_by_id
|
||||
helpers.gc = function(widget, id)
|
||||
return widget:get_children_by_id(id)[1]
|
||||
end
|
||||
|
||||
helpers.beginsWith = function(str, pattern)
|
||||
return str:find('^' .. pattern) ~= nil
|
||||
end
|
||||
|
||||
|
||||
return helpers
|
||||
@ -0,0 +1,21 @@
|
||||
local awful = require "awful"
|
||||
|
||||
local brightness = {}
|
||||
|
||||
brightness.increase = function()
|
||||
local script = [[
|
||||
brightnessctl set 3%+
|
||||
]]
|
||||
|
||||
awful.spawn.with_shell(script)
|
||||
end
|
||||
|
||||
brightness.decrease = function()
|
||||
local script = [[
|
||||
brightnessctl set 3%-
|
||||
]]
|
||||
|
||||
awful.spawn.with_shell(script)
|
||||
end
|
||||
|
||||
return brightness
|
||||
@ -0,0 +1,29 @@
|
||||
local awful = require "awful"
|
||||
|
||||
local volume = {}
|
||||
|
||||
volume.increase = function()
|
||||
local script = [[
|
||||
pamixer -i 3
|
||||
]]
|
||||
|
||||
awful.spawn.with_shell(script)
|
||||
end
|
||||
|
||||
volume.decrease = function()
|
||||
local script = [[
|
||||
pamixer -d 3
|
||||
]]
|
||||
|
||||
awful.spawn.with_shell(script)
|
||||
end
|
||||
|
||||
volume.mute = function()
|
||||
local script = [[
|
||||
pamixer -t
|
||||
]]
|
||||
|
||||
awful.spawn.with_shell(script)
|
||||
end
|
||||
|
||||
return volume
|
||||
BIN
modules/home-manager/ricing/awesomewm/dotfiles/liblua_pam.so
Normal file
@ -0,0 +1,8 @@
|
||||
local apps = {
|
||||
terminal = "wezterm",
|
||||
launcher = "rofi -show drun",
|
||||
browser = "firefox",
|
||||
fileManager = "thunar",
|
||||
}
|
||||
|
||||
return apps
|
||||
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
mpDris2 &
|
||||
xrdb -merge ~/.Xresources
|
||||
picom --config $HOME/.config/picom/picom.conf
|
||||
xss-lock lock
|
||||
mkdir -p ~/.cache/awesome/json/
|
||||
@ -0,0 +1,230 @@
|
||||
local awful = require "awful"
|
||||
local gears = require "gears"
|
||||
local naughty = require "naughty"
|
||||
local beautiful = require "beautiful"
|
||||
|
||||
local apps = require "main.apps"
|
||||
|
||||
modkey = "Mod4"
|
||||
|
||||
-- General awesome keybindings
|
||||
awful.keyboard.append_global_keybindings({
|
||||
awful.key({ modkey, "Control" }, "r", awesome.restart,
|
||||
{ description = "reload awesome", group = "awesome" }),
|
||||
awful.key({ modkey, "Shift" }, "q", awesome.quit,
|
||||
{ description = "quit awesome", group = "awesome" }),
|
||||
awful.key({ modkey, }, "Return", function() awful.spawn(apps.terminal) end,
|
||||
{ description = "open a terminal", group = "launcher" }),
|
||||
})
|
||||
|
||||
-- Tag bindings
|
||||
awful.keyboard.append_global_keybindings({
|
||||
awful.key({ modkey, }, "Left", awful.tag.viewprev,
|
||||
{ description = "view previous", group = "tag" }),
|
||||
awful.key({ modkey, }, "Right", awful.tag.viewnext,
|
||||
{ description = "view next", group = "tag" }),
|
||||
awful.key({ modkey, }, "Escape", awful.tag.history.restore,
|
||||
{ description = "go back", group = "tag" }),
|
||||
})
|
||||
|
||||
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,
|
||||
},
|
||||
awful.key {
|
||||
modifiers = { modkey },
|
||||
keygroup = "numpad",
|
||||
description = "select layout directly",
|
||||
group = "layout",
|
||||
on_press = function(index)
|
||||
local t = awful.screen.focused().selected_tag
|
||||
if t then
|
||||
t.layout = t.layouts[index] or t.layout
|
||||
end
|
||||
end,
|
||||
}
|
||||
})
|
||||
|
||||
-- Focus bindings
|
||||
awful.keyboard.append_global_keybindings({
|
||||
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, }, "Tab",
|
||||
function()
|
||||
awful.client.focus.history.previous()
|
||||
if client.focus then
|
||||
client.focus:raise()
|
||||
end
|
||||
end,
|
||||
{ description = "go back", group = "client" }),
|
||||
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" }),
|
||||
awful.key({ modkey, "Control" }, "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" }),
|
||||
})
|
||||
|
||||
-- Layout bindings
|
||||
awful.keyboard.append_global_keybindings({
|
||||
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({ 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", group = "layout" }),
|
||||
awful.key({ modkey, "Shift" }, "space", function() awful.layout.inc(-1) end,
|
||||
{ description = "select previous", group = "layout" }),
|
||||
})
|
||||
|
||||
-- Client bindings
|
||||
client.connect_signal("request::default_keybindings", function()
|
||||
awful.keyboard.append_client_keybindings({
|
||||
awful.key({ modkey, }, "f",
|
||||
function(c)
|
||||
c.fullscreen = not c.fullscreen
|
||||
c:raise()
|
||||
end,
|
||||
{ description = "toggle fullscreen", group = "client" }),
|
||||
awful.key({ modkey, "Shift" }, "c", 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, }, "t", function(c) c.ontop = not c.ontop end,
|
||||
{ description = "toggle keep on top", group = "client" }),
|
||||
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" }),
|
||||
})
|
||||
end)
|
||||
|
||||
-- Mouse bindings
|
||||
local menu = require("ui.rightclick")
|
||||
awful.mouse.append_global_mousebindings({
|
||||
awful.button({}, 3, function()
|
||||
menu.desktop:toggle()
|
||||
return
|
||||
end),
|
||||
})
|
||||
|
||||
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),
|
||||
})
|
||||
end)
|
||||
@ -0,0 +1,45 @@
|
||||
local awful = require "awful"
|
||||
|
||||
local volume = require "lib.volume"
|
||||
local brightness = require "lib.brightness"
|
||||
|
||||
-- Volume
|
||||
awful.keyboard.append_global_keybindings({
|
||||
awful.key({}, "XF86AudioRaiseVolume", function()
|
||||
volume.increase()
|
||||
awesome.emit_signal("open::osd")
|
||||
end),
|
||||
awful.key({}, "XF86AudioLowerVolume", function()
|
||||
volume.decrease()
|
||||
awesome.emit_signal("open::osd")
|
||||
end),
|
||||
awful.key({}, "XF86AudioMute", function()
|
||||
volume.mute()
|
||||
awesome.emit_signal("open::osd")
|
||||
end)
|
||||
})
|
||||
|
||||
-- Brightness
|
||||
awful.keyboard.append_global_keybindings({
|
||||
awful.key({}, "XF86MonBrightnessUp", function()
|
||||
brightness.increase()
|
||||
awesome.emit_signal("open::osdb")
|
||||
end),
|
||||
|
||||
awful.key({}, "XF86MonBrightnessDown", function()
|
||||
brightness.decrease()
|
||||
awesome.emit_signal("open::osdb")
|
||||
end),
|
||||
awful.key({ modkey, }, "a",
|
||||
function(c)
|
||||
awesome.emit_signal("toggle::launcher")
|
||||
end),
|
||||
awful.key({ modkey, }, "x",
|
||||
function(c)
|
||||
awesome.emit_signal("toggle::exit")
|
||||
end),
|
||||
awful.key({ modkey, }, "q",
|
||||
function(c)
|
||||
awesome.emit_signal("toggle::scrotter")
|
||||
end),
|
||||
})
|
||||
@ -0,0 +1,9 @@
|
||||
local naughty = require "naughty"
|
||||
|
||||
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)
|
||||
10
modules/home-manager/ricing/awesomewm/dotfiles/main/init.lua
Normal file
@ -0,0 +1,10 @@
|
||||
-- init config
|
||||
require "main.wallpaper"
|
||||
require "main.layout"
|
||||
require "main.rules"
|
||||
require "main.bindings.bindings"
|
||||
require "main.bindings.custom_bindings"
|
||||
require "main.tags"
|
||||
require "main.swallow"
|
||||
require "main.error_handling"
|
||||
require "main.scratch"
|
||||
@ -0,0 +1,16 @@
|
||||
local awful = require "awful"
|
||||
local gears = require "gears"
|
||||
local beautiful = require "beautiful"
|
||||
|
||||
awful.layout.layouts = {
|
||||
awful.layout.suit.tile,
|
||||
awful.layout.suit.floating,
|
||||
}
|
||||
|
||||
client.connect_signal("mouse::enter", function(c)
|
||||
c:activate { context = "mouse_enter", raise = false }
|
||||
end)
|
||||
|
||||
client.connect_signal("manage", function(c)
|
||||
if awesome.startup then awful.client.setslave(c) end
|
||||
end)
|
||||
@ -0,0 +1,35 @@
|
||||
local awful = require "awful"
|
||||
local gears = require "gears"
|
||||
local ruled = require "ruled"
|
||||
|
||||
ruled.client.connect_signal("request::rules", function()
|
||||
ruled.client.append_rule {
|
||||
id = "global",
|
||||
rule = {},
|
||||
properties = {
|
||||
focus = awful.client.focus.filter,
|
||||
raise = true,
|
||||
screen = awful.screen.preferred,
|
||||
placement = awful.placement.no_overlap + awful.placement.no_offscreen,
|
||||
},
|
||||
}
|
||||
|
||||
ruled.client.append_rule {
|
||||
id = "titlebars",
|
||||
rule_any = {
|
||||
type = { "normal", "dialog" },
|
||||
},
|
||||
properties = {
|
||||
titlebars_enabled = true
|
||||
}
|
||||
}
|
||||
ruled.client.append_rule {
|
||||
id = "desktop",
|
||||
rule_any = {
|
||||
class = {
|
||||
"Nemo-desktop"
|
||||
}
|
||||
},
|
||||
properties = { sticky = true, tag = " " }
|
||||
}
|
||||
end)
|
||||
162
modules/home-manager/ricing/awesomewm/dotfiles/main/scratch.lua
Normal file
@ -0,0 +1,162 @@
|
||||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local beautiful = require("beautiful")
|
||||
local ruled = require("ruled")
|
||||
|
||||
|
||||
local Scratchpad = { mt = {} } -- scratch init
|
||||
|
||||
-- make a new instance of scratchpad
|
||||
function Scratchpad:new(args)
|
||||
local ret = gears.object {}
|
||||
gears.table.crush(ret, Scratchpad)
|
||||
gears.table.crush(ret, args)
|
||||
return ret
|
||||
end
|
||||
|
||||
local findClient = function(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
|
||||
|
||||
function Scratchpad:find()
|
||||
return findClient(self.rule)
|
||||
end
|
||||
|
||||
function Scratchpad:become(c)
|
||||
if not c or not c.valid then return end
|
||||
c.floating = true
|
||||
c.sticky = false
|
||||
c.fullscreen = false
|
||||
c.maximised = false
|
||||
c:geometry({
|
||||
x = (1920 - self.width) / 2,
|
||||
y = (1080 - self.height) / 2,
|
||||
width = self.width,
|
||||
height = self.height
|
||||
})
|
||||
end
|
||||
|
||||
function on(c)
|
||||
local current_tag = c.screen.selected_tag
|
||||
ctags = { current_tag }
|
||||
for k, tag in pairs(c:tags()) do
|
||||
if tag ~= current_tag then
|
||||
table.insert(ctags, tag)
|
||||
end
|
||||
end
|
||||
c:tags(ctags)
|
||||
c:raise()
|
||||
client.focus = c
|
||||
end
|
||||
|
||||
function Scratchpad:on()
|
||||
self.client = self:find()[1]
|
||||
if not self.client then
|
||||
local pid = awful.spawn.with_shell(self.command)
|
||||
ruled.client.append_rule({
|
||||
id = "scratch",
|
||||
rule = self.rule,
|
||||
properties = {
|
||||
tag = awful.screen.focused().selected_tag,
|
||||
switch_to_tags = false,
|
||||
hidden = true,
|
||||
minimized = true,
|
||||
},
|
||||
callback = function(c)
|
||||
gears.timer({
|
||||
timeout = 0.1,
|
||||
autostart = true,
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
self.client = c
|
||||
self:become(c)
|
||||
c.hidden = false
|
||||
c.minimized = false
|
||||
|
||||
c:activate({})
|
||||
self:emit_signal("inital_apply", c)
|
||||
if c.name ~= "Discord Updater" then
|
||||
ruled.client.remove_rule("scratch")
|
||||
end
|
||||
c:connect_signal("request::unmanage", function()
|
||||
ruled.client.remove_rule("scratch")
|
||||
end)
|
||||
end
|
||||
})
|
||||
end
|
||||
})
|
||||
else
|
||||
self.client:raise()
|
||||
client.focus = self.client
|
||||
on(self.client)
|
||||
self:become(self.client)
|
||||
end
|
||||
end
|
||||
|
||||
function turn_off(c)
|
||||
current_tag = c.screen.selected_tag
|
||||
local ctags = {}
|
||||
for k, tag in pairs(c:tags()) do
|
||||
if tag ~= current_tag then
|
||||
table.insert(ctags, tag)
|
||||
end
|
||||
end
|
||||
c:tags(ctags)
|
||||
c.sticky = false
|
||||
end
|
||||
|
||||
function Scratchpad:off()
|
||||
self.client = self:find()[1]
|
||||
turn_off(self.client)
|
||||
end
|
||||
|
||||
function Scratchpad:toggle()
|
||||
local is_turn_off = client.focus and awful.rules.match(client.focus, self.rule)
|
||||
if is_turn_off then
|
||||
self:off()
|
||||
else
|
||||
self:on()
|
||||
end
|
||||
end
|
||||
|
||||
function Scratchpad.mt:__call(...)
|
||||
return Scratchpad:new(...)
|
||||
end
|
||||
|
||||
local createScratch = function(command, width, height, k)
|
||||
local scratch = Scratchpad:new {
|
||||
--command = 'kitty' .. ' --class "' .. command .. 'pad" -e sh -c "' .. command .. '; $SHELL"',
|
||||
command = 'wezterm start --class ' .. command .. 'pad -e sh -c "' .. command .. '; $SHELL"',
|
||||
rule = { class = command .. 'pad' },
|
||||
height = height,
|
||||
width = width,
|
||||
}
|
||||
awful.keyboard.append_global_keybindings {
|
||||
awful.key {
|
||||
modifiers = { "Mod4" },
|
||||
key = k,
|
||||
description = 'show help',
|
||||
group = 'awesome',
|
||||
on_press = function() scratch:toggle() end,
|
||||
},
|
||||
}
|
||||
awesome.connect_signal("toggle::" .. command .. "pad", function()
|
||||
scratch:toggle()
|
||||
end)
|
||||
return scratch
|
||||
end
|
||||
|
||||
local default = createScratch("clear", 1000, 650, 'v')
|
||||
local ncmpcpp = createScratch("ncmpcpp", 800, 500, 'z')
|
||||
@ -0,0 +1,83 @@
|
||||
-- documenting my shit because someone thought i write good code
|
||||
local awful = require("awful")
|
||||
local helpers = require("helpers")
|
||||
local dontSuckMe = {} -- this is for classes that you dont want to be swallowed
|
||||
-- eg local dontSuckMe = {"nemo", "firefox"}
|
||||
|
||||
local checkForSucc = function(child, parent)
|
||||
local canSuc = false
|
||||
if not helpers.inTable(dontSuckMe, child) and parent == "org.wezfurlong.wezterm" and child ~= "org.wezfurlong.wezterm" then -- write the class of your terminal here
|
||||
canSuc = true
|
||||
end
|
||||
return canSuc
|
||||
end
|
||||
|
||||
-- get the terminal window that executed the command maybe
|
||||
local getDaddy = function(child, cb)
|
||||
awful.spawn.easy_async(string.format("pstree -p %s", child), function(output, _, _, _)
|
||||
cb(nil, output)
|
||||
end)
|
||||
end
|
||||
|
||||
-- this function was straight out ripped from bling
|
||||
-- from what i understand this basically makes the window focused and on top
|
||||
function on(c)
|
||||
local current_tag = c.screen.selected_tag
|
||||
ctags = { current_tag }
|
||||
for k, tag in pairs(c:tags()) do
|
||||
if tag ~= current_tag then
|
||||
table.insert(ctags, tag)
|
||||
end
|
||||
end
|
||||
c:tags(ctags)
|
||||
c:raise()
|
||||
client.focus = c
|
||||
end
|
||||
|
||||
-- move the parent with the child
|
||||
local sync = function(c, p)
|
||||
if not c.valid or not p.valid then
|
||||
return
|
||||
end
|
||||
if p.modal then
|
||||
return
|
||||
end
|
||||
c.floating = p.floating
|
||||
c.maximized = p.maximized
|
||||
c.above = p.above
|
||||
c.below = p.below
|
||||
c:geometry(p:geometry())
|
||||
end
|
||||
|
||||
-- this does the opposite off on() and you guessed it, also copied from bling
|
||||
function off(c)
|
||||
current_tag = c.screen.selected_tag
|
||||
local ctags = {}
|
||||
for k, tag in pairs(c:tags()) do
|
||||
if tag ~= current_tag then
|
||||
table.insert(ctags, tag)
|
||||
end
|
||||
end
|
||||
c:tags(ctags)
|
||||
c.sticky = false
|
||||
end
|
||||
|
||||
-- the main implementation
|
||||
local handle = function(c)
|
||||
local daddy = awful.client.focus.history.get(c.screen, 1) -- read the history to get the parent terminal
|
||||
if not daddy or daddy.type == "dialog" or daddy.type == "splash" then return end
|
||||
getDaddy(c.pid, function(e, pid)
|
||||
if (tostring(pid):find("(" .. tostring(daddy.pid) .. ")")) and checkForSucc(c.class, daddy.class) then -- check if the parent exists and the window can be swallowed
|
||||
c:connect_signal("unmanage", function()
|
||||
if daddy then
|
||||
on(daddy)
|
||||
sync(c, daddy)
|
||||
end
|
||||
end)
|
||||
|
||||
sync(c, daddy)
|
||||
off(daddy)
|
||||
end
|
||||
end)
|
||||
end
|
||||
client.connect_signal("manage", handle) -- executing it
|
||||
@ -0,0 +1,5 @@
|
||||
local awful = require "awful"
|
||||
|
||||
screen.connect_signal("request::desktop_decoration", function(s)
|
||||
awful.tag({ "1", "2", "3", " " }, s, awful.layout.layouts[1])
|
||||
end)
|
||||
@ -0,0 +1,17 @@
|
||||
local gears = require "gears"
|
||||
local beautiful = require "beautiful"
|
||||
local helpeers = require "helpers"
|
||||
|
||||
|
||||
local function set_wall(s)
|
||||
local d = helpeers.readJson(gears.filesystem.get_cache_dir() .. 'json/settings.json')
|
||||
if d.wallpaper == "colorful" then
|
||||
gears.wallpaper.maximized(beautiful.wallpaper, s, beautiful.mbg)
|
||||
else
|
||||
gears.wallpaper.set(beautiful.bg3)
|
||||
end
|
||||
end
|
||||
|
||||
screen.connect_signal("request::wallpaper", function(s)
|
||||
set_wall(s)
|
||||
end)
|
||||
@ -0,0 +1,285 @@
|
||||
-- Copyleft © 2022 Saimoomedits
|
||||
--most stuff copied from guy above
|
||||
|
||||
|
||||
local naughty = require("naughty")
|
||||
local beautiful = require("beautiful")
|
||||
local wibox = require("wibox")
|
||||
local awful = require("awful")
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
local helpers = require("helpers")
|
||||
local ruled = require("ruled")
|
||||
local menubar = require("menubar")
|
||||
local animation = require("mods.animation")
|
||||
local gears = require("gears")
|
||||
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
-- naughty config
|
||||
naughty.config.defaults.ontop = true
|
||||
naughty.config.defaults.screen = awful.screen.focused()
|
||||
naughty.config.defaults.timeout = 10
|
||||
naughty.config.defaults.title = "Ding!"
|
||||
naughty.config.defaults.position = "top_right"
|
||||
|
||||
|
||||
-- Timeouts
|
||||
naughty.config.presets.low.timeout = 10
|
||||
naughty.config.presets.critical.timeout = 0
|
||||
|
||||
-- ruled notification
|
||||
ruled.notification.connect_signal("request::rules", function()
|
||||
ruled.notification.append_rule {
|
||||
rule = {},
|
||||
properties = { screen = awful.screen.preferred, implicit_timeout = 6 }
|
||||
}
|
||||
end)
|
||||
|
||||
|
||||
|
||||
-- connect to each display
|
||||
--------------------------
|
||||
naughty.connect_signal("request::display", function(n)
|
||||
-- action widget
|
||||
local action_widget = {
|
||||
{
|
||||
{
|
||||
id = "text_role",
|
||||
align = "center",
|
||||
valign = "center",
|
||||
font = beautiful.sans .. " 10",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
left = dpi(6),
|
||||
right = dpi(6),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = beautiful.mbg,
|
||||
forced_height = dpi(30),
|
||||
shape = helpers.rrect(2),
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
|
||||
-- actions
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- image
|
||||
local image_n = wibox.widget {
|
||||
{
|
||||
{
|
||||
opacity = 0.9,
|
||||
image = n.icon and helpers.cropSurface(1, gears.surface.load_uncached(n.icon)) or
|
||||
gears.filesystem.get_configuration_dir() .. "theme/assets/" .. "bell.png",
|
||||
resize = true,
|
||||
halign = "center",
|
||||
valign = "center",
|
||||
clip_shape = helpers.rrect(50),
|
||||
widget = wibox.widget.imagebox,
|
||||
},
|
||||
strategy = "exact",
|
||||
height = dpi(50),
|
||||
width = dpi(50),
|
||||
widget = wibox.container.constraint,
|
||||
},
|
||||
id = "arc",
|
||||
widget = wibox.container.arcchart,
|
||||
max_value = 100,
|
||||
min_value = 0,
|
||||
value = 100,
|
||||
rounded_edge = true,
|
||||
thickness = dpi(4),
|
||||
start_angle = 4.71238898,
|
||||
bg = beautiful.blue,
|
||||
colors = { beautiful.fg },
|
||||
forced_width = dpi(80),
|
||||
forced_height = dpi(80)
|
||||
}
|
||||
local anim = animation:new {
|
||||
duration = 6,
|
||||
target = 100,
|
||||
reset_on_stop = false,
|
||||
easing = animation.easing.linear,
|
||||
update = function(_, pos)
|
||||
image_n:get_children_by_id('arc')[1].value = pos
|
||||
end,
|
||||
}
|
||||
anim:connect_signal("ended", function()
|
||||
n:destroy()
|
||||
end)
|
||||
|
||||
-- title
|
||||
local title_n = wibox.widget {
|
||||
{
|
||||
{
|
||||
markup = n.title,
|
||||
font = beautiful.sans .. " 12",
|
||||
align = "right",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
forced_width = dpi(240),
|
||||
widget = wibox.container.scroll.horizontal,
|
||||
step_function = wibox.container.scroll.step_functions.waiting_nonlinear_back_and_forth,
|
||||
speed = 50
|
||||
},
|
||||
margins = { right = 15 },
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
|
||||
local message_n = wibox.widget {
|
||||
{
|
||||
{
|
||||
markup = helpers.colorizeText("<span weight='normal'>" .. n.message .. "</span>", beautiful.fg .. "BF"),
|
||||
font = beautiful.sans .. " 12",
|
||||
align = "left",
|
||||
valign = "center",
|
||||
wrap = "char",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
forced_width = dpi(240),
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
margins = { right = 15 },
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
|
||||
-- app name
|
||||
local aname = ''
|
||||
if n.app_name ~= '' then
|
||||
aname = n.app_name
|
||||
else
|
||||
aname = 'naughty'
|
||||
end
|
||||
local app_name_n = wibox.widget {
|
||||
markup = helpers.colorizeText(aname, beautiful.fg .. "BF"),
|
||||
font = beautiful.sans .. " 10",
|
||||
align = "left",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
local time_n = wibox.widget {
|
||||
{
|
||||
markup = helpers.colorizeText("now", beautiful.fg .. "BF"),
|
||||
font = beautiful.sans .. " 10",
|
||||
align = "right",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
margins = { right = 20 },
|
||||
widget = wibox.container.margin
|
||||
}
|
||||
|
||||
local close = wibox.widget {
|
||||
markup = helpers.colorizeText('', beautiful.red),
|
||||
font = beautiful.icon .. " 12",
|
||||
align = "ceneter",
|
||||
valign = "center",
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
|
||||
close:buttons(gears.table.join(
|
||||
awful.button({}, 1, function() n:destroy(naughty.notification_closed_reason.dismissed_by_user) end)))
|
||||
|
||||
|
||||
-- extra info
|
||||
local notif_info = wibox.widget {
|
||||
app_name_n,
|
||||
{
|
||||
widget = wibox.widget.separator,
|
||||
shape = gears.shape.circle,
|
||||
forced_height = dpi(4),
|
||||
forced_width = dpi(4),
|
||||
color = beautiful.fg .. "BF"
|
||||
},
|
||||
time_n,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
spacing = dpi(7)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
local widget = naughty.layout.box {
|
||||
notification = n,
|
||||
bg = beautiful.bg,
|
||||
shape = helpers.rrect(8),
|
||||
widget_template = {
|
||||
{
|
||||
{
|
||||
-- top bit
|
||||
{
|
||||
{
|
||||
{
|
||||
close,
|
||||
nil,
|
||||
notif_info,
|
||||
layout = wibox.layout.align.horizontal,
|
||||
expand = "none"
|
||||
},
|
||||
margins = { left = dpi(15), right = dpi(15), top = dpi(10), bottom = dpi(10) },
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
bg = beautiful.mbg,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
{
|
||||
-- body
|
||||
{
|
||||
{
|
||||
title_n,
|
||||
message_n,
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
spacing = dpi(3)
|
||||
},
|
||||
nil,
|
||||
image_n,
|
||||
layout = wibox.layout.align.horizontal,
|
||||
expand = "none"
|
||||
},
|
||||
margins = { left = dpi(15), top = dpi(10), right = dpi(10) },
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
{
|
||||
-- foot
|
||||
actions,
|
||||
margins = dpi(10),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
spacing = dpi(10)
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
shape = helpers.rrect(8),
|
||||
bg = beautiful.bg,
|
||||
}
|
||||
}
|
||||
|
||||
widget.buttons = {}
|
||||
anim:start()
|
||||
end)
|
||||
@ -0,0 +1 @@
|
||||
require("misc.dings.base")
|
||||
@ -0,0 +1,10 @@
|
||||
local naughty = require("naughty")
|
||||
local bling = require("mods.playerctl")
|
||||
local playerctl = bling.lib()
|
||||
|
||||
playerctl:connect_signal("metadata",
|
||||
function(_, title, artist, album_path, album, new, player_name)
|
||||
if new == true then
|
||||
naughty.notify({ title = 'New Song', text = title .. " by " .. artist, image = album_path })
|
||||
end
|
||||
end)
|
||||
@ -0,0 +1,3 @@
|
||||
require "misc.titlebar"
|
||||
require "misc.music"
|
||||
require "misc.dings"
|
||||
304
modules/home-manager/ricing/awesomewm/dotfiles/misc/music.lua
Normal file
@ -0,0 +1,304 @@
|
||||
local awful = require 'awful'
|
||||
require 'awful.autofocus'
|
||||
local wibox = require 'wibox'
|
||||
local gears = require 'gears'
|
||||
local beautiful = require("beautiful")
|
||||
local ruled = require("ruled")
|
||||
local helpers = require("helpers")
|
||||
local playerctl = require("mods.playerctl").lib()
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
|
||||
local art = wibox.widget {
|
||||
image = helpers.cropSurface(1, gears.surface.load_uncached(beautiful.songdefpicture)),
|
||||
clip_shape = helpers.rrect(10),
|
||||
opacity = 0.75,
|
||||
resize = true,
|
||||
forced_height = dpi(60),
|
||||
forced_width = dpi(60),
|
||||
valign = 'center',
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
local leftart = wibox.widget {
|
||||
image = beautiful.songdefpicture,
|
||||
clip_shape = helpers.rrect(10),
|
||||
opacity = 0.75,
|
||||
resize = true,
|
||||
forced_height = dpi(250),
|
||||
forced_width = dpi(250),
|
||||
valign = 'center',
|
||||
widget = wibox.widget.imagebox
|
||||
}
|
||||
local prev = wibox.widget {
|
||||
align = 'center',
|
||||
font = beautiful.icon .. " 24",
|
||||
markup = helpers.colorizeText('', beautiful.fg),
|
||||
widget = wibox.widget.textbox,
|
||||
buttons = {
|
||||
awful.button({}, 1, function()
|
||||
playerctl:previous()
|
||||
end)
|
||||
},
|
||||
}
|
||||
local next = wibox.widget {
|
||||
align = 'center',
|
||||
font = beautiful.icon .. " 24",
|
||||
markup = helpers.colorizeText('', beautiful.fg),
|
||||
widget = wibox.widget.textbox,
|
||||
buttons = {
|
||||
awful.button({}, 1, function()
|
||||
playerctl:next()
|
||||
end)
|
||||
},
|
||||
}
|
||||
|
||||
local play = wibox.widget {
|
||||
align = 'center',
|
||||
font = beautiful.icon .. " 24",
|
||||
markup = helpers.colorizeText('', beautiful.blue),
|
||||
widget = wibox.widget.textbox,
|
||||
buttons = {
|
||||
awful.button({}, 1, function()
|
||||
playerctl:play_pause()
|
||||
end)
|
||||
},
|
||||
}
|
||||
local shufflebtn = wibox.widget {
|
||||
align = 'center',
|
||||
font = beautiful.icon .. " 13",
|
||||
markup = helpers.colorizeText('', beautiful.fg),
|
||||
widget = wibox.widget.textbox,
|
||||
buttons = {
|
||||
awful.button({}, 1, function()
|
||||
playerctl:cycle_shuffle()
|
||||
end)
|
||||
}
|
||||
}
|
||||
playerctl:connect_signal("shuffle", function(_, shuffle)
|
||||
shufflebtn.markup = shuffle and helpers.colorizeText('', beautiful.blue) or helpers.colorizeText('',
|
||||
beautiful.fg)
|
||||
end)
|
||||
local repeatt = wibox.widget {
|
||||
align = 'center',
|
||||
font = beautiful.icon .. " 13",
|
||||
markup = helpers.colorizeText('', beautiful.fg),
|
||||
widget = wibox.widget.textbox,
|
||||
buttons = {
|
||||
awful.button({}, 1, function()
|
||||
playerctl:cycle_loop_status()
|
||||
end)
|
||||
}
|
||||
}
|
||||
playerctl:connect_signal("loop_status", function(_, loop_status)
|
||||
if loop_status:match('none') then
|
||||
repeatt.markup = helpers.colorizeText('', beautiful.fg)
|
||||
elseif loop_status:match('track') then
|
||||
repeatt.markup = helpers.colorizeText('', beautiful.magenta)
|
||||
else
|
||||
repeatt.markup = helpers.colorizeText('', beautiful.magenta)
|
||||
end
|
||||
end)
|
||||
|
||||
local createHandle = function(width, height, tl, tr, br, bl, radius)
|
||||
return function(cr)
|
||||
gears.shape.partially_rounded_rect(cr, width, height, tl, tr, br, bl, radius)
|
||||
end
|
||||
end
|
||||
local slider = wibox.widget {
|
||||
bar_shape = helpers.rrect(0),
|
||||
bar_height = 3,
|
||||
handle_color = beautiful.blue,
|
||||
bar_color = beautiful.blue .. '33',
|
||||
bar_active_color = beautiful.blue,
|
||||
handle_shape = createHandle(18, 3, false, false, false, false, 0),
|
||||
handle_margins = { top = 3 },
|
||||
handle_width = 18,
|
||||
forced_height = 10,
|
||||
maximum = 100,
|
||||
widget = wibox.widget.slider,
|
||||
}
|
||||
|
||||
local songname = wibox.widget {
|
||||
markup = helpers.colorizeText('Nothing Playing', beautiful.fg),
|
||||
align = 'left',
|
||||
valign = 'center',
|
||||
forced_width = dpi(40),
|
||||
font = beautiful.sans .. " 12",
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
local leftname = wibox.widget {
|
||||
markup = helpers.colorizeText('Nothing Playing', beautiful.fg),
|
||||
valign = 'center',
|
||||
align = 'center',
|
||||
font = beautiful.sans .. " 16",
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
local artistname = wibox.widget {
|
||||
markup = helpers.colorizeText('None', beautiful.fg),
|
||||
align = 'left',
|
||||
valign = 'center',
|
||||
forced_height = dpi(20),
|
||||
font = beautiful.sans .. " 11",
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
local leftartist = wibox.widget {
|
||||
markup = helpers.colorizeText('None', beautiful.fg),
|
||||
align = 'center',
|
||||
valign = 'center',
|
||||
forced_height = dpi(20),
|
||||
font = beautiful.sans .. " 11",
|
||||
widget = wibox.widget.textbox
|
||||
}
|
||||
local is_prog_hovered = false
|
||||
slider:connect_signal('mouse::enter', function()
|
||||
is_prog_hovered = true
|
||||
end)
|
||||
slider:connect_signal('mouse::leave', function()
|
||||
is_prog_hovered = false
|
||||
end)
|
||||
slider:connect_signal('property::value', function(_, value)
|
||||
if is_prog_hovered then
|
||||
playerctl:set_position(value)
|
||||
end
|
||||
end)
|
||||
playerctl:connect_signal("position", function(_, interval_sec, length_sec)
|
||||
slider.maximum = length_sec or 100
|
||||
slider.value = interval_sec or 0
|
||||
end)
|
||||
|
||||
playerctl:connect_signal("metadata", function(_, title, artist, album_path, album, new, player_name)
|
||||
if player_name == "mpd" then
|
||||
if album_path == "" then
|
||||
album_path = beautiful.songdefpicture
|
||||
end
|
||||
if string.len(title) > 30 then
|
||||
title = string.sub(title, 0, 30) .. "..."
|
||||
end
|
||||
if string.len(artist) > 22 then
|
||||
artist = string.sub(artist, 0, 22) .. "..."
|
||||
end
|
||||
songname:set_markup_silently(helpers.colorizeText(title or "NO", beautiful.fg))
|
||||
leftname:set_markup_silently(helpers.colorizeText(title or "NO", beautiful.fg))
|
||||
leftartist:set_markup_silently(helpers.colorizeText(' ' .. artist or "WT" .. ' ', beautiful.fg))
|
||||
artistname:set_markup_silently(helpers.colorizeText(artist or "HM", beautiful.fg))
|
||||
art:set_image(gears.surface.load_uncached(album_path))
|
||||
leftart:set_image(gears.surface.load_uncached(album_path))
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
playerctl:connect_signal("playback_status", function(_, playing)
|
||||
play.markup = playing and helpers.colorizeText("", beautiful.blue) or helpers.colorizeText("", beautiful.blue)
|
||||
end)
|
||||
local createTopButton = function(c, icon, click, color)
|
||||
local widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
markup = helpers.colorizeText(icon, color),
|
||||
valign = 'center',
|
||||
forced_height = dpi(20),
|
||||
font = beautiful.icon .. " 18",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
margins = {
|
||||
left = 8,
|
||||
right = 8
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
buttons = awful.button({}, 1, function()
|
||||
helpers.clickKey(c, click)
|
||||
end),
|
||||
bg = beautiful.mbg,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
return widget
|
||||
end
|
||||
|
||||
local bottom = function(c)
|
||||
local playtab = createTopButton(c, '', '1', beautiful.blue)
|
||||
local vistab = createTopButton(c, '', '8', beautiful.blue)
|
||||
vistab:add_button(awful.button({}, 3, function()
|
||||
helpers.clickKey(c, '8 ')
|
||||
end))
|
||||
awful.titlebar(c, { position = "bottom", size = dpi(100), bg = beautiful.mbg }):setup {
|
||||
slider,
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
art,
|
||||
{
|
||||
{
|
||||
songname,
|
||||
artistname,
|
||||
forced_width = 400,
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
},
|
||||
align = 'center',
|
||||
widget = wibox.container.place
|
||||
},
|
||||
spacing = 13,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
margins = {
|
||||
top = 15,
|
||||
bottom = 15,
|
||||
left = 10,
|
||||
right = 10,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
{
|
||||
{
|
||||
shufflebtn,
|
||||
prev,
|
||||
{
|
||||
{
|
||||
play,
|
||||
margins = 4,
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
shape = helpers.rrect(3),
|
||||
bg = beautiful.blue .. '11',
|
||||
widget = wibox.container.background
|
||||
},
|
||||
next,
|
||||
repeatt,
|
||||
spacing = 15,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
align = 'center',
|
||||
widget = wibox.container.place,
|
||||
},
|
||||
{
|
||||
playtab,
|
||||
vistab,
|
||||
spacing = 10,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
expand = 'none',
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
left = 15,
|
||||
right = 15
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical,
|
||||
}
|
||||
end
|
||||
|
||||
local final = function(c)
|
||||
bottom(c)
|
||||
end
|
||||
|
||||
|
||||
ruled.client.connect_signal("request::rules", function()
|
||||
ruled.client.append_rule {
|
||||
id = "music",
|
||||
rule_any = {
|
||||
class = { "ncmpcpppad" },
|
||||
role = { "pop-up" },
|
||||
},
|
||||
callback = final
|
||||
}
|
||||
end)
|
||||
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
STATUS="$(rfkill list | sed -n 2p | awk '{print $3}')"
|
||||
|
||||
|
||||
toggle() {
|
||||
if [[ $STATUS == "no" ]]; then
|
||||
getroot 'pkexec rfkill block all'
|
||||
notify-send --urgency=normal "Airplane Mode" "Airplane mode has been turned on!"
|
||||
else
|
||||
getroot 'pkexec rfkill unblock all'
|
||||
notify-send --urgency=normal "Airplane Mode" "Airplane mode has been turned off!"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [[ $1 == "--toggle" ]]; then
|
||||
toggle
|
||||
fi
|
||||
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
toggle() {
|
||||
STATUS="$(bluetoothctl show | grep Powered | awk '{print $2}')"
|
||||
if [ $STATUS == "yes" ]; then
|
||||
bluetoothctl power off
|
||||
notify-send -a "Bluetooth" --urgency=normal "Bluetooth" "Bluetooth has been turned off."
|
||||
else
|
||||
bluetoothctl power on
|
||||
notify-send -a "Bluetooth" --urgency=normal "Bluetooth" "Bluetooth has been turned on."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [[ $1 == "--toggle" ]]; then
|
||||
toggle
|
||||
fi
|
||||
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
toggle(){
|
||||
if [[ ! `pidof picom` ]]; then
|
||||
picom &
|
||||
else
|
||||
pkill -9 picom
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ $1 == "--toggle" ]]; then
|
||||
toggle
|
||||
fi
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
is_active=$(cat ~/.cache/redshift)
|
||||
|
||||
toggle() {
|
||||
if [[ $is_active == *"true"* ]]; then
|
||||
redshift -x && echo false > ~/.cache/redshift
|
||||
else
|
||||
redshift -O 4000 && echo true > ~/.cache/redshift
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ $1 == "--toggle" ]]; then
|
||||
toggle
|
||||
fi
|
||||
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
STATUS=$(nmcli | grep wlan0 | awk 'FNR == 1 {print $2}')
|
||||
SSID=$(iwgetid -r)
|
||||
STRENGTH=$(awk 'NR==3 {printf("%.0f",$3*10/7)}' /proc/net/wireless)
|
||||
|
||||
toggle() {
|
||||
if [[ $STATUS == "connected" ]]; then
|
||||
nmcli radio wifi off
|
||||
notify-send -a "wifi" --urgency=normal "Wi-Fi" "Wi-Fi has been turned off!"
|
||||
else
|
||||
nmcli radio wifi on
|
||||
notify-send -a "wifi" --urgency=normal "Wi-Fi" "Wi-Fi has been turned on, you are back online!"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [[ $1 == "--toggle" ]]; then
|
||||
toggle
|
||||
fi
|
||||
103
modules/home-manager/ricing/awesomewm/dotfiles/misc/titlebar.lua
Normal file
@ -0,0 +1,103 @@
|
||||
local awful = require "awful"
|
||||
local gears = require "gears"
|
||||
local wibox = require "wibox"
|
||||
local beautiful = require "beautiful"
|
||||
local helpers = require "helpers"
|
||||
local getIcon = require "mods.getIcon"
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
|
||||
----- Titlebar
|
||||
local get_titlebar = function(c)
|
||||
-- Button
|
||||
local buttons = gears.table.join({
|
||||
awful.button({}, 1, function()
|
||||
c:activate { context = "titlebar", action = "mouse_move" }
|
||||
end),
|
||||
awful.button({}, 3, function()
|
||||
c:activate { context = "titlebar", action = "mouse_resize" }
|
||||
end)
|
||||
})
|
||||
|
||||
-- Titlebar's decorations
|
||||
local left = wibox.widget {
|
||||
{
|
||||
{
|
||||
awful.titlebar.widget.closebutton(c),
|
||||
awful.titlebar.widget.maximizedbutton(c),
|
||||
awful.titlebar.widget.minimizebutton(c),
|
||||
spacing = dpi(5),
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = 8
|
||||
},
|
||||
shape = helpers.rrect(5),
|
||||
widget = wibox.container.background,
|
||||
bg = beautiful.mbg
|
||||
}
|
||||
|
||||
local middle = wibox.widget {
|
||||
buttons = buttons,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
}
|
||||
|
||||
local right = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
image = getIcon(c, c.class, c.class),
|
||||
forced_width = 30,
|
||||
clip_shape = helpers.rrect(100),
|
||||
resize = true,
|
||||
},
|
||||
widget = wibox.container.place,
|
||||
halign = "center",
|
||||
},
|
||||
margins = dpi(5),
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
bg = beautiful.mbg,
|
||||
shape = helpers.rrect(5),
|
||||
widget = wibox.container.background
|
||||
}
|
||||
|
||||
local container = wibox.widget {
|
||||
bg = beautiful.bar,
|
||||
shape = function(cr, w, h) gears.shape.partially_rounded_rect(cr, w, h, true, true, false, false, 0) end,
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
|
||||
c:connect_signal("focus", function() container.bg = beautiful.bg end)
|
||||
c:connect_signal("unfocus", function() container.bg = beautiful.bg end)
|
||||
|
||||
return wibox.widget {
|
||||
{
|
||||
{
|
||||
left,
|
||||
middle,
|
||||
right,
|
||||
layout = wibox.layout.align.horizontal,
|
||||
},
|
||||
margins = { top = dpi(5), bottom = dpi(5), left = dpi(5), right = dpi(5) },
|
||||
widget = wibox.container.margin,
|
||||
},
|
||||
widget = container,
|
||||
}
|
||||
end
|
||||
|
||||
local function top(c)
|
||||
local titlebar = awful.titlebar(c, {
|
||||
position = 'top',
|
||||
size = dpi(50),
|
||||
bg = beautiful.transparent
|
||||
})
|
||||
|
||||
titlebar:setup {
|
||||
widget = get_titlebar(c)
|
||||
}
|
||||
end
|
||||
|
||||
client.connect_signal("request::titlebars", function(c)
|
||||
top(c)
|
||||
end)
|
||||
@ -0,0 +1,239 @@
|
||||
-------------------------------------------
|
||||
-- @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("mods.animation.subscribable")
|
||||
local tween = require("mods.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
|
||||
@ -0,0 +1,41 @@
|
||||
-------------------------------------------
|
||||
-- @author https://github.com/Kasper24
|
||||
-- @copyright 2021-2022 Kasper24
|
||||
-- Adopted from rubato
|
||||
-------------------------------------------
|
||||
|
||||
|
||||
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
|
||||
@ -0,0 +1,527 @@
|
||||
-------------------------------------------
|
||||
-- @author https://github.com/Kasper24
|
||||
-- @copyright 2021-2022 Kasper24
|
||||
-------------------------------------------
|
||||
|
||||
-- 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
|
||||
103
modules/home-manager/ricing/awesomewm/dotfiles/mods/getIcon.lua
Normal file
@ -0,0 +1,103 @@
|
||||
local gfs = require("gears.filesystem")
|
||||
local gears = require("gears")
|
||||
local theme_path = gfs.get_configuration_dir() .. "/theme/"
|
||||
local icon_cache = {}
|
||||
local helpers = require("helpers")
|
||||
local t = helpers.readJson(gears.filesystem.get_cache_dir() .. "json/settings.json").iconTheme
|
||||
|
||||
|
||||
local custom = {
|
||||
{
|
||||
name = "clearpad",
|
||||
to = "terminal"
|
||||
},
|
||||
{
|
||||
name = "ncmpcpppad",
|
||||
to = "deepin-music-player"
|
||||
},
|
||||
}
|
||||
|
||||
local function hasValue(str)
|
||||
local f = false
|
||||
local ind = 0
|
||||
for i, j in ipairs(custom) do
|
||||
if j.name == str then
|
||||
f = true
|
||||
ind = i
|
||||
break
|
||||
end
|
||||
end
|
||||
return f, ind
|
||||
end
|
||||
|
||||
|
||||
local function Get_icon(client, program_string, class_string)
|
||||
client = client or nil
|
||||
program_string = program_string or nil
|
||||
class_string = class_string or nil
|
||||
|
||||
if (client or program_string or class_string) then
|
||||
local clientName
|
||||
local isCustom, pos = hasValue(class_string)
|
||||
if isCustom == true then
|
||||
clientName = custom[pos].to .. ".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 t .. "/apps/default-application.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 iconDir = t .. "/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 = t .. "/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 t .. "/apps/default-application.svg"
|
||||
else
|
||||
clientName = class_string .. ".svg"
|
||||
iconDir = t .. "/apps/"
|
||||
ioStream = io.open(iconDir .. clientName, "r")
|
||||
if ioStream ~= nil then
|
||||
icon_cache[#icon_cache + 1] = iconDir .. clientName
|
||||
return iconDir .. clientName
|
||||
else
|
||||
return t .. "/apps/default-application.svg"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if client then
|
||||
return t .. "/apps/default-application.svg"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return Get_icon
|
||||
344
modules/home-manager/ricing/awesomewm/dotfiles/mods/inspect.lua
Normal file
@ -0,0 +1,344 @@
|
||||
local inspect = {
|
||||
_VERSION = 'inspect.lua 3.1.0',
|
||||
_URL = 'http://github.com/kikito/inspect.lua',
|
||||
_DESCRIPTION = 'human-readable representations of tables',
|
||||
_LICENSE = [[
|
||||
MIT LICENSE
|
||||
Copyright (c) 2013 Enrique García Cota
|
||||
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 tostring = tostring
|
||||
|
||||
inspect.KEY = setmetatable({}, { __tostring = function() return 'inspect.KEY' end })
|
||||
inspect.METATABLE = setmetatable({}, { __tostring = function() return 'inspect.METATABLE' end })
|
||||
|
||||
local function rawpairs(t)
|
||||
return next, t, nil
|
||||
end
|
||||
|
||||
-- Apostrophizes the string if it has quotes, but not aphostrophes
|
||||
-- Otherwise, it returns a regular quoted string
|
||||
local function smartQuote(str)
|
||||
if str:match('"') and not str:match("'") then
|
||||
return "'" .. str .. "'"
|
||||
end
|
||||
return '"' .. str:gsub('"', '\\"') .. '"'
|
||||
end
|
||||
|
||||
-- \a => '\\a', \0 => nil
|
||||
local shortControlCharEscapes = {
|
||||
["\a"] = "\\a",
|
||||
["\b"] = "\\b",
|
||||
["\f"] = "\\f",
|
||||
["\n"] = "\\n",
|
||||
["\r"] = "\\r",
|
||||
["\t"] = "\\t",
|
||||
["\v"] = "\\v",
|
||||
["\127"] = "\\127",
|
||||
}
|
||||
local longControlCharEscapes = { ["\127"] = "\127" } -- \a => nil, \0 => \000, 31 => \031
|
||||
for i = 0, 31 do
|
||||
local ch = string.char(i)
|
||||
if not shortControlCharEscapes[ch] then
|
||||
shortControlCharEscapes[ch] = "\\" .. i
|
||||
longControlCharEscapes[ch] = string.format("\\%03d", i)
|
||||
end
|
||||
end
|
||||
--longControlCharEscapes["\127"]="\\127"
|
||||
|
||||
local function escape(str)
|
||||
return (str:gsub("\\", "\\\\")
|
||||
:gsub("(%c)%f[0-9]", longControlCharEscapes)
|
||||
:gsub("%c", shortControlCharEscapes))
|
||||
end
|
||||
|
||||
local function isIdentifier(str)
|
||||
return type(str) == 'string' and str:match("^[_%a][_%a%d]*$")
|
||||
end
|
||||
|
||||
local function isSequenceKey(k, sequenceLength)
|
||||
return type(k) == 'number'
|
||||
and 1 <= k
|
||||
and k <= sequenceLength
|
||||
and math.floor(k) == k
|
||||
end
|
||||
|
||||
local defaultTypeOrders = {
|
||||
['number'] = 1,
|
||||
['boolean'] = 2,
|
||||
['string'] = 3,
|
||||
['table'] = 4,
|
||||
['function'] = 5,
|
||||
['userdata'] = 6,
|
||||
['thread'] = 7
|
||||
}
|
||||
|
||||
local function sortKeys(a, b)
|
||||
local ta, tb = type(a), type(b)
|
||||
|
||||
-- strings and numbers are sorted numerically/alphabetically
|
||||
if ta == tb and (ta == 'string' or ta == 'number') then return a < b end
|
||||
|
||||
local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb]
|
||||
-- Two default types are compared according to the defaultTypeOrders table
|
||||
if dta and dtb then
|
||||
return defaultTypeOrders[ta] < defaultTypeOrders[tb]
|
||||
elseif dta then
|
||||
return true -- default types before custom ones
|
||||
elseif dtb then
|
||||
return false -- custom types after default ones
|
||||
end
|
||||
|
||||
-- custom types are sorted out alphabetically
|
||||
return ta < tb
|
||||
end
|
||||
|
||||
-- For implementation reasons, the behavior of rawlen & # is "undefined" when
|
||||
-- tables aren't pure sequences. So we implement our own # operator.
|
||||
local function getSequenceLength(t)
|
||||
local len = 1
|
||||
local v = rawget(t, len)
|
||||
while v ~= nil do
|
||||
len = len + 1
|
||||
v = rawget(t, len)
|
||||
end
|
||||
return len - 1
|
||||
end
|
||||
|
||||
local function getNonSequentialKeys(t)
|
||||
local keys, keysLength = {}, 0
|
||||
local sequenceLength = getSequenceLength(t)
|
||||
for k, _ in rawpairs(t) do
|
||||
if not isSequenceKey(k, sequenceLength) then
|
||||
keysLength = keysLength + 1
|
||||
keys[keysLength] = k
|
||||
end
|
||||
end
|
||||
table.sort(keys, sortKeys)
|
||||
return keys, keysLength, sequenceLength
|
||||
end
|
||||
|
||||
local function countTableAppearances(t, tableAppearances)
|
||||
tableAppearances = tableAppearances or {}
|
||||
|
||||
if type(t) == 'table' then
|
||||
if not tableAppearances[t] then
|
||||
tableAppearances[t] = 1
|
||||
for k, v in rawpairs(t) do
|
||||
countTableAppearances(k, tableAppearances)
|
||||
countTableAppearances(v, tableAppearances)
|
||||
end
|
||||
countTableAppearances(getmetatable(t), tableAppearances)
|
||||
else
|
||||
tableAppearances[t] = tableAppearances[t] + 1
|
||||
end
|
||||
end
|
||||
|
||||
return tableAppearances
|
||||
end
|
||||
|
||||
local copySequence = function(s)
|
||||
local copy, len = {}, #s
|
||||
for i = 1, len do copy[i] = s[i] end
|
||||
return copy, len
|
||||
end
|
||||
|
||||
local function makePath(path, ...)
|
||||
local keys = { ... }
|
||||
local newPath, len = copySequence(path)
|
||||
for i = 1, #keys do
|
||||
newPath[len + i] = keys[i]
|
||||
end
|
||||
return newPath
|
||||
end
|
||||
|
||||
local function processRecursive(process, item, path, visited)
|
||||
if item == nil then return nil end
|
||||
if visited[item] then return visited[item] end
|
||||
|
||||
local processed = process(item, path)
|
||||
if type(processed) == 'table' then
|
||||
local processedCopy = {}
|
||||
visited[item] = processedCopy
|
||||
local processedKey
|
||||
|
||||
for k, v in rawpairs(processed) do
|
||||
processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited)
|
||||
if processedKey ~= nil then
|
||||
processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited)
|
||||
end
|
||||
end
|
||||
|
||||
local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited)
|
||||
if type(mt) ~= 'table' then mt = nil end -- ignore not nil/table __metatable field
|
||||
setmetatable(processedCopy, mt)
|
||||
processed = processedCopy
|
||||
end
|
||||
return processed
|
||||
end
|
||||
|
||||
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
local Inspector = {}
|
||||
local Inspector_mt = { __index = Inspector }
|
||||
|
||||
function Inspector:puts(...)
|
||||
local args = { ... }
|
||||
local buffer = self.buffer
|
||||
local len = #buffer
|
||||
for i = 1, #args do
|
||||
len = len + 1
|
||||
buffer[len] = args[i]
|
||||
end
|
||||
end
|
||||
|
||||
function Inspector:down(f)
|
||||
self.level = self.level + 1
|
||||
f()
|
||||
self.level = self.level - 1
|
||||
end
|
||||
|
||||
function Inspector:tabify()
|
||||
self:puts(self.newline, string.rep(self.indent, self.level))
|
||||
end
|
||||
|
||||
function Inspector:alreadyVisited(v)
|
||||
return self.ids[v] ~= nil
|
||||
end
|
||||
|
||||
function Inspector:getId(v)
|
||||
local id = self.ids[v]
|
||||
if not id then
|
||||
local tv = type(v)
|
||||
id = (self.maxIds[tv] or 0) + 1
|
||||
self.maxIds[tv] = id
|
||||
self.ids[v] = id
|
||||
end
|
||||
return tostring(id)
|
||||
end
|
||||
|
||||
function Inspector:putKey(k)
|
||||
if isIdentifier(k) then return self:puts(k) end
|
||||
self:puts("[")
|
||||
self:putValue(k)
|
||||
self:puts("]")
|
||||
end
|
||||
|
||||
function Inspector:putTable(t)
|
||||
if t == inspect.KEY or t == inspect.METATABLE then
|
||||
self:puts(tostring(t))
|
||||
elseif self:alreadyVisited(t) then
|
||||
self:puts('<table ', self:getId(t), '>')
|
||||
elseif self.level >= self.depth then
|
||||
self:puts('{...}')
|
||||
else
|
||||
if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end
|
||||
|
||||
local nonSequentialKeys, nonSequentialKeysLength, sequenceLength = getNonSequentialKeys(t)
|
||||
local mt = getmetatable(t)
|
||||
|
||||
self:puts('{')
|
||||
self:down(function()
|
||||
local count = 0
|
||||
for i = 1, sequenceLength do
|
||||
if count > 0 then self:puts(',') end
|
||||
self:puts(' ')
|
||||
self:putValue(t[i])
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
for i = 1, nonSequentialKeysLength do
|
||||
local k = nonSequentialKeys[i]
|
||||
if count > 0 then self:puts(',') end
|
||||
self:tabify()
|
||||
self:putKey(k)
|
||||
self:puts(' = ')
|
||||
self:putValue(t[k])
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
if type(mt) == 'table' then
|
||||
if count > 0 then self:puts(',') end
|
||||
self:tabify()
|
||||
self:puts('<metatable> = ')
|
||||
self:putValue(mt)
|
||||
end
|
||||
end)
|
||||
|
||||
if nonSequentialKeysLength > 0 or type(mt) == 'table' then -- result is multi-lined. Justify closing }
|
||||
self:tabify()
|
||||
elseif sequenceLength > 0 then -- array tables have one extra space before closing }
|
||||
self:puts(' ')
|
||||
end
|
||||
|
||||
self:puts('}')
|
||||
end
|
||||
end
|
||||
|
||||
function Inspector:putValue(v)
|
||||
local tv = type(v)
|
||||
|
||||
if tv == 'string' then
|
||||
self:puts(smartQuote(escape(v)))
|
||||
elseif tv == 'number' or tv == 'boolean' or tv == 'nil' or
|
||||
tv == 'cdata' or tv == 'ctype' then
|
||||
self:puts(tostring(v))
|
||||
elseif tv == 'table' then
|
||||
self:putTable(v)
|
||||
else
|
||||
self:puts('<', tv, ' ', self:getId(v), '>')
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
function inspect.inspect(root, options)
|
||||
options = options or {}
|
||||
|
||||
local depth = options.depth or math.huge
|
||||
local newline = options.newline or '\n'
|
||||
local indent = options.indent or ' '
|
||||
local process = options.process
|
||||
|
||||
if process then
|
||||
root = processRecursive(process, root, {}, {})
|
||||
end
|
||||
|
||||
local inspector = setmetatable({
|
||||
depth = depth,
|
||||
level = 0,
|
||||
buffer = {},
|
||||
ids = {},
|
||||
maxIds = {},
|
||||
newline = newline,
|
||||
indent = indent,
|
||||
tableAppearances = countTableAppearances(root)
|
||||
}, Inspector_mt)
|
||||
|
||||
inspector:putValue(root)
|
||||
|
||||
return table.concat(inspector.buffer)
|
||||
end
|
||||
|
||||
setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end })
|
||||
|
||||
return inspect
|
||||
383
modules/home-manager/ricing/awesomewm/dotfiles/mods/json.lua
Normal file
@ -0,0 +1,383 @@
|
||||
--
|
||||
-- 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
|
||||
342
modules/home-manager/ricing/awesomewm/dotfiles/mods/menu.lua
Normal file
@ -0,0 +1,342 @@
|
||||
local awful = require("awful")
|
||||
local gtable = require("gears.table")
|
||||
local gtimer = require("gears.timer")
|
||||
local wibox = require("wibox")
|
||||
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.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()
|
||||
if self.widget then
|
||||
for _, button in ipairs(self.widget.children) do
|
||||
if button.sub_menu ~= nil then
|
||||
button.sub_menu:hide()
|
||||
end
|
||||
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()
|
||||
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.rrect(9),
|
||||
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 16
|
||||
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 wibox.widget {
|
||||
font = args.icon.font .. " " .. args.icon_size,
|
||||
markup = helpers.colorizeText(args.icon.icon, helpers.randomColor()),
|
||||
widget = wibox.widget.textbox,
|
||||
halign = "start",
|
||||
forced_width = 40,
|
||||
} or nil
|
||||
|
||||
local widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
layout = wibox.layout.align.horizontal,
|
||||
forced_width = dpi(270),
|
||||
{
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
spacing = dpi(10),
|
||||
icon,
|
||||
{
|
||||
font = beautiful.sans .. " " .. args.text_size,
|
||||
markup = args.text,
|
||||
widget = wibox.widget.textbox,
|
||||
halign = "start"
|
||||
},
|
||||
},
|
||||
nil,
|
||||
{
|
||||
font = beautiful.icon .. " " .. "18",
|
||||
markup = "",
|
||||
widget = wibox.widget.textbox,
|
||||
halign = "start"
|
||||
},
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = 10
|
||||
},
|
||||
bg = beautiful.bg,
|
||||
forced_height = 48,
|
||||
shape = helpers.rrect(9),
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
widget:connect_signal("mouse::enter", function(self)
|
||||
local coords = helpers.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 } })
|
||||
end)
|
||||
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 16
|
||||
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 = wibox.widget {
|
||||
font = args.icon.font .. " " .. args.icon_size,
|
||||
markup = helpers.colorizeText(args.icon.icon, helpers.randomColor()),
|
||||
widget = wibox.widget.textbox,
|
||||
halign = "start"
|
||||
}
|
||||
elseif args.image ~= nil then
|
||||
icon = wibox.widget({
|
||||
widget = wibox.widget.imagebox,
|
||||
image = args.image,
|
||||
})
|
||||
end
|
||||
|
||||
local text_widget = wibox.widget {
|
||||
font = beautiful.sans .. " " .. args.text_size,
|
||||
markup = args.text,
|
||||
widget = wibox.widget.textbox,
|
||||
halign = "start"
|
||||
}
|
||||
|
||||
local widget = wibox.widget {
|
||||
{
|
||||
{
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
spacing = dpi(15),
|
||||
icon,
|
||||
text_widget,
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = 10
|
||||
},
|
||||
bg = beautiful.bg,
|
||||
forced_height = 48,
|
||||
shape = helpers.rrect(9),
|
||||
buttons = {
|
||||
awful.button({}, 1, function()
|
||||
args.on_press(menu, text_widget)
|
||||
menu:hide(true)
|
||||
end)
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
}
|
||||
widget:connect_signal("mouse::enter", function(self)
|
||||
if self.menu.widget then self.menu:hide_children_menus() end
|
||||
end)
|
||||
return widget
|
||||
end
|
||||
|
||||
function menu.separator()
|
||||
return wibox.widget({
|
||||
widget = wibox.container.margin,
|
||||
top = 10,
|
||||
bottom = 10,
|
||||
left = 40,
|
||||
right = 40,
|
||||
{
|
||||
widget = wibox.widget.separator,
|
||||
forced_height = dpi(2),
|
||||
orientation = "horizontal",
|
||||
thickness = dpi(1),
|
||||
color = beautiful.fg .. "29",
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
function menu.mt:__call(...)
|
||||
return menu.menu(...)
|
||||
end
|
||||
|
||||
return setmetatable(menu, menu.mt)
|
||||
534
modules/home-manager/ricing/awesomewm/dotfiles/mods/overflow.lua
Normal file
@ -0,0 +1,534 @@
|
||||
-------------------------------------------
|
||||
-- @author https://github.com/Kasper24
|
||||
-- @copyright 2021-2022 Kasper24
|
||||
-------------------------------------------
|
||||
---------------------------------------------------------------------------
|
||||
-- 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 beautiful = require('beautiful')
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
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,
|
||||
need_scrollbar and width - self._private.scrollbar_spacing or 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(need_scrollbar and content_w - self._private.scrollbar_spacing or 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 y or x
|
||||
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
|
||||
|
||||
function overflow:set_scrollbar_spacing(spacing)
|
||||
self._private.scrollbar_spacing = spacing
|
||||
|
||||
self:emit_signal("widget::layout_changed")
|
||||
self:emit_signal("property::scrollbar_spacing", spacing)
|
||||
end
|
||||
|
||||
function overflow:get_scrollbar_spacing()
|
||||
return self._private.scrollbar_spacing
|
||||
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"
|
||||
ret._private.scrollbar_spacing = dpi(15)
|
||||
|
||||
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)
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
local awful = require("awful")
|
||||
local gtimer = require("gears.timer")
|
||||
local beautiful = require("beautiful")
|
||||
local naughty = require("naughty")
|
||||
|
||||
-- Use CLI backend as default as it is supported on most if not all systems
|
||||
local backend_config = beautiful.playerctl_backend or "playerctl_cli"
|
||||
local backends = {
|
||||
playerctl_cli = require(... .. ".playerctl_cli"),
|
||||
playerctl_lib = require(... .. ".playerctl_lib"),
|
||||
}
|
||||
|
||||
local backend = nil
|
||||
|
||||
local function enable_wrapper(args)
|
||||
local open = naughty.action { name = "Open" }
|
||||
|
||||
open:connect_signal("invoked", function()
|
||||
awful.spawn("xdg-open https://blingcorp.github.io/bling/#/signals/pctl")
|
||||
end)
|
||||
|
||||
gtimer.delayed_call(function()
|
||||
naughty.notify({
|
||||
title = "Bling Error",
|
||||
text = "Global signals are deprecated! Please take a look at the playerctl documentation.",
|
||||
app_name = "Bling Error",
|
||||
app_icon = "system-error",
|
||||
actions = { open }
|
||||
})
|
||||
end)
|
||||
|
||||
backend_config = (args and args.backend) or backend_config
|
||||
backend = backends[backend_config](args)
|
||||
return backend
|
||||
end
|
||||
|
||||
local function disable_wrapper()
|
||||
backend:disable()
|
||||
end
|
||||
|
||||
return {
|
||||
lib = backends.playerctl_lib,
|
||||
cli = backends.playerctl_cli,
|
||||
enable = enable_wrapper,
|
||||
disable = disable_wrapper
|
||||
}
|
||||
@ -0,0 +1,355 @@
|
||||
-- Playerctl signals
|
||||
--
|
||||
-- Provides:
|
||||
-- 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)
|
||||
|
||||
local awful = require("awful")
|
||||
local gobject = require("gears.object")
|
||||
local gtable = require("gears.table")
|
||||
local gtimer = require("gears.timer")
|
||||
local gstring = require("gears.string")
|
||||
local beautiful = require("beautiful")
|
||||
local setmetatable = setmetatable
|
||||
local tonumber = tonumber
|
||||
local ipairs = ipairs
|
||||
local type = type
|
||||
local capi = { awesome = awesome }
|
||||
|
||||
local playerctl = { mt = {} }
|
||||
|
||||
local function save_image_async_curl(url, filepath, callback)
|
||||
awful.spawn.with_line_callback(string.format("curl -L -s %s -o %s", url, filepath),
|
||||
{
|
||||
exit = callback
|
||||
})
|
||||
end
|
||||
|
||||
function playerctl:disable()
|
||||
self._private.metadata_timer:stop()
|
||||
self._private.metadata_timer = nil
|
||||
awful.spawn.with_shell("killall playerctl")
|
||||
end
|
||||
|
||||
function playerctl:pause(player)
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " pause")
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "pause")
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:play(player)
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " play")
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "play")
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:stop(player)
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " stop")
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "stop")
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:play_pause(player)
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " play-pause")
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "play-pause")
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:previous(player)
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " previous")
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "previous")
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:next(player)
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " next")
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "next")
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:set_loop_status(loop_status, player)
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " loop " .. loop_status)
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "loop " .. loop_status)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:cycle_loop_status(player)
|
||||
local function set_loop_status(loop_status)
|
||||
if loop_status == "None" then
|
||||
self:set_loop_status("Track")
|
||||
elseif loop_status == "Track" then
|
||||
self:set_loop_status("Playlist")
|
||||
elseif loop_status == "Playlist" then
|
||||
self:set_loop_status("None")
|
||||
end
|
||||
end
|
||||
|
||||
if player ~= nil then
|
||||
awful.spawn.easy_async_with_shell("playerctl --player=" .. player .. " loop", function(stdout)
|
||||
set_loop_status(stdout)
|
||||
end)
|
||||
else
|
||||
set_loop_status(self._private.loop_status)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:set_position(position, player)
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " position " .. position)
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "position " .. position)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:set_shuffle(shuffle, player)
|
||||
shuffle = shuffle and "on" or "off"
|
||||
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " shuffle " .. shuffle)
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "shuffle " .. shuffle)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:cycle_shuffle(player)
|
||||
if player ~= nil then
|
||||
awful.spawn.easy_async_with_shell("playerctl --player=" .. player .. " shuffle", function(stdout)
|
||||
local shuffle = stdout == "on" and true or false
|
||||
self:set_shuffle(not self._private.shuffle)
|
||||
end)
|
||||
else
|
||||
self:set_shuffle(not self._private.shuffle)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:set_volume(volume, player)
|
||||
if player ~= nil then
|
||||
awful.spawn.with_shell("playerctl --player=" .. player .. " volume " .. volume)
|
||||
else
|
||||
awful.spawn.with_shell(self._private.cmd .. "volume " .. volume)
|
||||
end
|
||||
end
|
||||
|
||||
local function emit_player_metadata(self)
|
||||
local metadata_cmd = self._private.cmd ..
|
||||
"metadata --format 'title_{{title}}artist_{{artist}}art_url_{{mpris:artUrl}}player_name_{{playerName}}album_{{album}}' -F"
|
||||
|
||||
awful.spawn.with_line_callback(metadata_cmd, {
|
||||
stdout = function(line)
|
||||
local title = gstring.xml_escape(line:match('title_(.*)artist_')) or ""
|
||||
local artist = gstring.xml_escape(line:match('artist_(.*)art_url_')) or ""
|
||||
local art_url = line:match('art_url_(.*)player_name_') or ""
|
||||
local player_name = line:match('player_name_(.*)album_') or ""
|
||||
local album = gstring.xml_escape(line:match('album_(.*)')) or ""
|
||||
|
||||
art_url = art_url:gsub('%\n', '')
|
||||
if player_name == "spotify" then
|
||||
art_url = art_url:gsub("open.spotify.com", "i.scdn.co")
|
||||
end
|
||||
|
||||
if self._private.metadata_timer
|
||||
and self._private.metadata_timer.started
|
||||
then
|
||||
self._private.metadata_timer:stop()
|
||||
end
|
||||
|
||||
self._private.metadata_timer = gtimer {
|
||||
timeout = self.debounce_delay,
|
||||
autostart = true,
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
if title and title ~= "" then
|
||||
if art_url ~= "" then
|
||||
local art_path = os.tmpname()
|
||||
save_image_async_curl(art_url, art_path, function()
|
||||
self:emit_signal("metadata", title, artist, art_path, album, player_name)
|
||||
capi.awesome.emit_signal("bling::playerctl::title_artist_album", title, artist, art_path)
|
||||
end)
|
||||
else
|
||||
self:emit_signal("metadata", title, artist, "", album, player_name)
|
||||
capi.awesome.emit_signal("bling::playerctl::title_artist_album", title, artist, "")
|
||||
end
|
||||
else
|
||||
self:emit_signal("no_players")
|
||||
capi.awesome.emit_signal("bling::playerctl::no_players")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
collectgarbage("collect")
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local function emit_player_position(self)
|
||||
local position_cmd = self._private.cmd .. "position"
|
||||
local length_cmd = self._private.cmd .. "metadata mpris:length"
|
||||
|
||||
awful.widget.watch(position_cmd, self.interval, function(_, interval)
|
||||
awful.spawn.easy_async_with_shell(length_cmd, function(length)
|
||||
local length_sec = tonumber(length) -- in microseconds
|
||||
local interval_sec = tonumber(interval) -- in seconds
|
||||
if length_sec and interval_sec then
|
||||
if interval_sec >= 0 and length_sec > 0 then
|
||||
self:emit_signal("position", interval_sec, length_sec / 1000000)
|
||||
capi.awesome.emit_signal("bling::playerctl::position", interval_sec, length_sec / 1000000)
|
||||
end
|
||||
end
|
||||
end)
|
||||
collectgarbage("collect")
|
||||
end)
|
||||
end
|
||||
|
||||
local function emit_player_playback_status(self)
|
||||
local status_cmd = self._private.cmd .. "status -F"
|
||||
|
||||
awful.spawn.with_line_callback(status_cmd, {
|
||||
stdout = function(line)
|
||||
if line:find("Playing") then
|
||||
self:emit_signal("playback_status", true)
|
||||
capi.awesome.emit_signal("bling::playerctl::status", true)
|
||||
else
|
||||
self:emit_signal("playback_status", false)
|
||||
capi.awesome.emit_signal("bling::playerctl::status", false)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local function emit_player_volume(self)
|
||||
local volume_cmd = self._private.cmd .. "volume -F"
|
||||
|
||||
awful.spawn.with_line_callback(volume_cmd, {
|
||||
stdout = function(line)
|
||||
self:emit_signal("volume", tonumber(line))
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local function emit_player_loop_status(self)
|
||||
local loop_status_cmd = self._private.cmd .. "loop -F"
|
||||
|
||||
awful.spawn.with_line_callback(loop_status_cmd, {
|
||||
stdout = function(line)
|
||||
self._private.loop_status = line
|
||||
self:emit_signal("loop_status", line:lower())
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local function emit_player_shuffle(self)
|
||||
local shuffle_cmd = self._private.cmd .. "shuffle -F"
|
||||
|
||||
awful.spawn.with_line_callback(shuffle_cmd, {
|
||||
stdout = function(line)
|
||||
if line:find("On") then
|
||||
self._private.shuffle = true
|
||||
self:emit_signal("shuffle", true)
|
||||
else
|
||||
self._private.shuffle = false
|
||||
self:emit_signal("shuffle", false)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local function parse_args(self, args)
|
||||
if args.player then
|
||||
self._private.cmd = self._private.cmd .. "--player="
|
||||
|
||||
if type(args.player) == "string" then
|
||||
self._private.cmd = self._private.cmd .. args.player .. " "
|
||||
elseif type(args.player) == "table" then
|
||||
for index, player in ipairs(args.player) do
|
||||
self._private.cmd = self._private.cmd .. player
|
||||
if index < #args.player then
|
||||
self._private.cmd = self._private.cmd .. ","
|
||||
else
|
||||
self._private.cmd = self._private.cmd .. " "
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if args.ignore then
|
||||
self._private.cmd = self._private.cmd .. "--ignore-player="
|
||||
|
||||
if type(args.ignore) == "string" then
|
||||
self._private.cmd = self._private.cmd .. args.ignore .. " "
|
||||
elseif type(args.ignore) == "table" then
|
||||
for index, player in ipairs(args.ignore) do
|
||||
self._private.cmd = self._private.cmd .. player
|
||||
if index < #args.ignore then
|
||||
self._private.cmd = self._private.cmd .. ","
|
||||
else
|
||||
self._private.cmd = self._private.cmd .. " "
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function new(args)
|
||||
args = args or {}
|
||||
|
||||
local ret = gobject {}
|
||||
gtable.crush(ret, playerctl, true)
|
||||
|
||||
ret.interval = args.interval or beautiful.playerctl_position_update_interval or 1
|
||||
ret.debounce_delay = args.debounce_delay or beautiful.playerctl_debounce_delay or 0.35
|
||||
|
||||
ret._private = {}
|
||||
ret._private.metadata_timer = nil
|
||||
ret._private.cmd = "playerctl "
|
||||
parse_args(ret, args)
|
||||
|
||||
emit_player_metadata(ret)
|
||||
emit_player_position(ret)
|
||||
emit_player_playback_status(ret)
|
||||
emit_player_volume(ret)
|
||||
emit_player_loop_status(ret)
|
||||
emit_player_shuffle(ret)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function playerctl.mt:__call(...)
|
||||
return new(...)
|
||||
end
|
||||
|
||||
-- On startup instead of on playerctl object init to make it
|
||||
-- possible to have more than one of these running
|
||||
awful.spawn.with_shell("killall playerctl")
|
||||
|
||||
return setmetatable(playerctl, playerctl.mt)
|
||||
@ -0,0 +1,569 @@
|
||||
-- Playerctl signals
|
||||
--
|
||||
-- Provides:
|
||||
-- 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)
|
||||
|
||||
local awful = require("awful")
|
||||
local gobject = require("gears.object")
|
||||
local gtable = require("gears.table")
|
||||
local gtimer = require("gears.timer")
|
||||
local gstring = require("gears.string")
|
||||
local beautiful = require("beautiful")
|
||||
local setmetatable = setmetatable
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
local type = type
|
||||
local capi = { awesome = awesome }
|
||||
|
||||
local playerctl = { mt = {} }
|
||||
|
||||
|
||||
local function save_image_async_curl(url, filepath, callback)
|
||||
awful.spawn.with_line_callback(string.format("curl -L -s %s -o %s", url, filepath),
|
||||
{
|
||||
exit = callback
|
||||
})
|
||||
end
|
||||
|
||||
function playerctl:disable()
|
||||
-- Restore default settings
|
||||
self.ignore = {}
|
||||
self.priority = {}
|
||||
self.update_on_activity = true
|
||||
self.interval = 1
|
||||
self.debounce_delay = 0.35
|
||||
|
||||
-- Reset timers
|
||||
self._private.manager = nil
|
||||
self._private.metadata_timer:stop()
|
||||
self._private.metadata_timer = nil
|
||||
self._private.position_timer:stop()
|
||||
self._private.position_timer = nil
|
||||
|
||||
-- Reset default values
|
||||
self._private.last_position = -1
|
||||
self._private.last_length = -1
|
||||
self._private.last_player = nil
|
||||
self._private.last_title = ""
|
||||
self._private.last_artist = ""
|
||||
self._private.last_artUrl = ""
|
||||
end
|
||||
|
||||
function playerctl:pause(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:pause()
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:play(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:play()
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:stop(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:stop()
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:play_pause(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:play_pause()
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:previous(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:previous()
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:next(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:next()
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:set_loop_status(loop_status, player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:set_loop_status(loop_status)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:cycle_loop_status(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
if player.loop_status == "NONE" then
|
||||
player:set_loop_status("TRACK")
|
||||
elseif player.loop_status == "TRACK" then
|
||||
player:set_loop_status("PLAYLIST")
|
||||
elseif player.loop_status == "PLAYLIST" then
|
||||
player:set_loop_status("NONE")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:set_position(position, player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:set_position(position * 1000000)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:set_shuffle(shuffle, player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:set_shuffle(shuffle)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:cycle_shuffle(player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:set_shuffle(not player.shuffle)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:set_volume(volume, player)
|
||||
player = player or self._private.manager.players[1]
|
||||
if player then
|
||||
player:set_volume(volume)
|
||||
end
|
||||
end
|
||||
|
||||
function playerctl:get_manager()
|
||||
return self._private.manager
|
||||
end
|
||||
|
||||
function playerctl:get_active_player()
|
||||
return self._private.manager.players[1]
|
||||
end
|
||||
|
||||
function playerctl:get_player_of_name(name)
|
||||
for _, player in ipairs(self._private.manager.players) do
|
||||
if player.player_name == name then
|
||||
return player
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local function emit_metadata_signal(self, title, artist, artUrl, album, new, player_name)
|
||||
title = gstring.xml_escape(title)
|
||||
artist = gstring.xml_escape(artist)
|
||||
album = gstring.xml_escape(album)
|
||||
|
||||
-- Spotify client doesn't report its art URL's correctly...
|
||||
if player_name == "spotify" then
|
||||
artUrl = artUrl:gsub("open.spotify.com", "i.scdn.co")
|
||||
end
|
||||
|
||||
if artUrl ~= "" then
|
||||
local art_path = os.tmpname()
|
||||
save_image_async_curl(artUrl, art_path, function()
|
||||
self:emit_signal("metadata", title, artist, art_path, album, new, player_name)
|
||||
capi.awesome.emit_signal("bling::playerctl::title_artist_album", title, artist, art_path, player_name)
|
||||
end)
|
||||
else
|
||||
capi.awesome.emit_signal("bling::playerctl::title_artist_album", title, artist, "", player_name)
|
||||
self:emit_signal("metadata", title, artist, "", album, new, player_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function metadata_cb(self, player, metadata)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:move_player_to_top(player)
|
||||
end
|
||||
|
||||
local data = metadata.value
|
||||
|
||||
local title = data["xesam:title"] or ""
|
||||
local artist = data["xesam:artist"][1] or ""
|
||||
for i = 2, #data["xesam:artist"] do
|
||||
artist = artist .. ", " .. data["xesam:artist"][i]
|
||||
end
|
||||
local artUrl = data["mpris:artUrl"] or ""
|
||||
local album = data["xesam:album"] or ""
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
self._private.active_player = player
|
||||
|
||||
-- Callback can be called even though values we care about haven't
|
||||
-- changed, so check to see if they have
|
||||
if
|
||||
player ~= self._private.last_player
|
||||
or title ~= self._private.last_title
|
||||
or artist ~= self._private.last_artist
|
||||
or artUrl ~= self._private.last_artUrl
|
||||
then
|
||||
if (title == "" and artist == "" and artUrl == "") then return end
|
||||
|
||||
if self._private.metadata_timer ~= nil and self._private.metadata_timer.started then
|
||||
self._private.metadata_timer:stop()
|
||||
end
|
||||
|
||||
self._private.metadata_timer = gtimer {
|
||||
timeout = self.debounce_delay,
|
||||
autostart = true,
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
emit_metadata_signal(self, title, artist, artUrl, album, true, player.player_name)
|
||||
end
|
||||
}
|
||||
|
||||
-- Re-sync with position timer when track changes
|
||||
self._private.position_timer:again()
|
||||
self._private.last_player = player
|
||||
self._private.last_title = title
|
||||
self._private.last_artist = artist
|
||||
self._private.last_artUrl = artUrl
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function position_cb(self)
|
||||
local player = self._private.manager.players[1]
|
||||
if player then
|
||||
local position = player:get_position() / 1000000
|
||||
local length = (player.metadata.value["mpris:length"] or 0) / 1000000
|
||||
if position ~= self._private.last_position or length ~= self._private.last_length then
|
||||
capi.awesome.emit_signal("bling::playerctl::position", position, length, player.player_name)
|
||||
self:emit_signal("position", position, length, player.player_name)
|
||||
self._private.last_position = position
|
||||
self._private.last_length = length
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function playback_status_cb(self, player, status)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:move_player_to_top(player)
|
||||
end
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
self._private.active_player = player
|
||||
|
||||
-- Reported as PLAYING, PAUSED, or STOPPED
|
||||
if status == "PLAYING" then
|
||||
self:emit_signal("playback_status", true, player.player_name)
|
||||
capi.awesome.emit_signal("bling::playerctl::status", true, player.player_name)
|
||||
else
|
||||
self:emit_signal("playback_status", false, player.player_name)
|
||||
capi.awesome.emit_signal("bling::playerctl::status", false, player.player_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function seeked_cb(self, player, position)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:move_player_to_top(player)
|
||||
end
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
self._private.active_player = player
|
||||
self:emit_signal("seeked", position / 1000000, player.player_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function volume_cb(self, player, volume)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:move_player_to_top(player)
|
||||
end
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
self._private.active_player = player
|
||||
self:emit_signal("volume", volume, player.player_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function loop_status_cb(self, player, loop_status)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:move_player_to_top(player)
|
||||
end
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
self._private.active_player = player
|
||||
self:emit_signal("loop_status", loop_status:lower(), player.player_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function shuffle_cb(self, player, shuffle)
|
||||
if self.update_on_activity then
|
||||
self._private.manager:move_player_to_top(player)
|
||||
end
|
||||
|
||||
if player == self._private.manager.players[1] then
|
||||
self._private.active_player = player
|
||||
self:emit_signal("shuffle", shuffle, player.player_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function exit_cb(self, player)
|
||||
if player == self._private.manager.players[1] then
|
||||
self:emit_signal("exit", player.player_name)
|
||||
end
|
||||
end
|
||||
|
||||
-- Determine if player should be managed
|
||||
local function name_is_selected(self, name)
|
||||
if self.ignore[name.name] then
|
||||
return false
|
||||
end
|
||||
|
||||
if #self.priority > 0 then
|
||||
for _, arg in pairs(self.priority) do
|
||||
if arg == name.name or arg == "%any" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Create new player and connect it to callbacks
|
||||
local function init_player(self, name)
|
||||
if name_is_selected(self, name) then
|
||||
local player = self._private.lgi_Playerctl.Player.new_from_name(name)
|
||||
self._private.manager:manage_player(player)
|
||||
player.on_metadata = function(player, metadata)
|
||||
metadata_cb(self, player, metadata)
|
||||
end
|
||||
player.on_playback_status = function(player, playback_status)
|
||||
playback_status_cb(self, player, playback_status)
|
||||
end
|
||||
player.on_seeked = function(player, position)
|
||||
seeked_cb(self, player, position)
|
||||
end
|
||||
player.on_volume = function(player, volume)
|
||||
volume_cb(self, player, volume)
|
||||
end
|
||||
player.on_loop_status = function(player, loop_status)
|
||||
loop_status_cb(self, player, loop_status)
|
||||
end
|
||||
player.on_shuffle = function(player, shuffle_status)
|
||||
shuffle_cb(self, player, shuffle_status)
|
||||
end
|
||||
player.on_exit = function(player, shuffle_status)
|
||||
exit_cb(self, player)
|
||||
end
|
||||
|
||||
-- Start position timer if its not already running
|
||||
if not self._private.position_timer.started then
|
||||
self._private.position_timer:again()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Determine if a player name comes before or after another according to the
|
||||
-- priority order
|
||||
local function player_compare_name(self, name_a, name_b)
|
||||
local any_index = math.huge
|
||||
local a_match_index = nil
|
||||
local b_match_index = nil
|
||||
|
||||
if name_a == name_b then
|
||||
return 0
|
||||
end
|
||||
|
||||
for index, name in ipairs(self.priority) do
|
||||
if name == "%any" then
|
||||
any_index = (any_index == math.huge) and index or any_index
|
||||
elseif name == name_a then
|
||||
a_match_index = a_match_index or index
|
||||
elseif name == name_b then
|
||||
b_match_index = b_match_index or index
|
||||
end
|
||||
end
|
||||
|
||||
if not a_match_index and not b_match_index then
|
||||
return 0
|
||||
elseif not a_match_index then
|
||||
return (b_match_index < any_index) and 1 or -1
|
||||
elseif not b_match_index then
|
||||
return (a_match_index < any_index) and -1 or 1
|
||||
elseif a_match_index == b_match_index then
|
||||
return 0
|
||||
else
|
||||
return (a_match_index < b_match_index) and -1 or 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Sorting function used by manager if a priority order is specified
|
||||
local function player_compare(self, a, b)
|
||||
local player_a = self._private.lgi_Playerctl.Player(a)
|
||||
local player_b = self._private.lgi_Playerctl.Player(b)
|
||||
return player_compare_name(self, player_a.player_name, player_b.player_name)
|
||||
end
|
||||
|
||||
local function get_current_player_info(self, player)
|
||||
local title = player:get_title() or ""
|
||||
local artist = player:get_artist() or ""
|
||||
local artUrl = player:print_metadata_prop("mpris:artUrl") or ""
|
||||
local album = player:get_album() or ""
|
||||
|
||||
emit_metadata_signal(self, title, artist, artUrl, album, false, player.player_name)
|
||||
playback_status_cb(self, player, player.playback_status)
|
||||
volume_cb(self, player, player.volume)
|
||||
loop_status_cb(self, player, player.loop_status)
|
||||
shuffle_cb(self, player, player.shuffle)
|
||||
end
|
||||
|
||||
local function start_manager(self)
|
||||
self._private.manager = self._private.lgi_Playerctl.PlayerManager()
|
||||
|
||||
if #self.priority > 0 then
|
||||
self._private.manager:set_sort_func(function(a, b)
|
||||
return player_compare(self, a, b)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Timer to update track position at specified interval
|
||||
self._private.position_timer = gtimer {
|
||||
timeout = self.interval,
|
||||
callback = function()
|
||||
position_cb(self)
|
||||
end,
|
||||
}
|
||||
|
||||
-- Manage existing players on startup
|
||||
for _, name in ipairs(self._private.manager.player_names) do
|
||||
init_player(self, name)
|
||||
end
|
||||
|
||||
if self._private.manager.players[1] then
|
||||
get_current_player_info(self, self._private.manager.players[1])
|
||||
end
|
||||
|
||||
local _self = self
|
||||
|
||||
-- Callback to manage new players
|
||||
function self._private.manager:on_name_appeared(name)
|
||||
init_player(_self, name)
|
||||
end
|
||||
|
||||
function self._private.manager:on_player_appeared(player)
|
||||
if player == self.players[1] then
|
||||
_self._private.active_player = player
|
||||
end
|
||||
end
|
||||
|
||||
function self._private.manager:on_player_vanished(player)
|
||||
if #self.players == 0 then
|
||||
_self._private.metadata_timer:stop()
|
||||
_self._private.position_timer:stop()
|
||||
_self:emit_signal("no_players")
|
||||
capi.awesome.emit_signal("bling::playerctl::no_players")
|
||||
elseif player == _self._private.active_player then
|
||||
_self._private.active_player = self.players[1]
|
||||
get_current_player_info(_self, self.players[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function parse_args(self, args)
|
||||
self.ignore = {}
|
||||
if type(args.ignore) == "string" then
|
||||
self.ignore[args.ignore] = true
|
||||
elseif type(args.ignore) == "table" then
|
||||
for _, name in pairs(args.ignore) do
|
||||
self.ignore[name] = true
|
||||
end
|
||||
end
|
||||
|
||||
self.priority = {}
|
||||
if type(args.player) == "string" then
|
||||
self.priority[1] = args.player
|
||||
elseif type(args.player) == "table" then
|
||||
self.priority = args.player
|
||||
end
|
||||
end
|
||||
|
||||
local function new(args)
|
||||
args = args or {}
|
||||
|
||||
local ret = gobject {}
|
||||
gtable.crush(ret, playerctl, true)
|
||||
|
||||
-- Grab settings from beautiful variables if not set explicitly
|
||||
args.ignore = args.ignore or beautiful.playerctl_ignore
|
||||
args.player = args.player or beautiful.playerctl_player
|
||||
if args.update_on_activity ~= nil then
|
||||
ret.update_on_activity = args.update_on_activity
|
||||
else
|
||||
ret.update_on_activity = beautiful.playerctl_update_on_activity ~= false
|
||||
end
|
||||
ret.interval = args.interval or beautiful.playerctl_position_update_interval or 1
|
||||
ret.debounce_delay = args.debounce_delay or beautiful.playerctl_debounce_delay or 0.35
|
||||
parse_args(ret, args)
|
||||
|
||||
ret._private = {}
|
||||
|
||||
-- Metadata callback for title, artist, and album art
|
||||
ret._private.last_player = nil
|
||||
ret._private.last_title = ""
|
||||
ret._private.last_artist = ""
|
||||
ret._private.last_artUrl = ""
|
||||
|
||||
-- Track position callback
|
||||
ret._private.last_position = -1
|
||||
ret._private.last_length = -1
|
||||
|
||||
-- Grab playerctl library
|
||||
ret._private.lgi_Playerctl = require("lgi").Playerctl
|
||||
ret._private.manager = nil
|
||||
ret._private.metadata_timer = nil
|
||||
ret._private.position_timer = nil
|
||||
|
||||
-- Ensure main event loop has started before starting player manager
|
||||
gtimer.delayed_call(function()
|
||||
start_manager(ret)
|
||||
end)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function playerctl.mt:__call(...)
|
||||
return new(...)
|
||||
end
|
||||
|
||||
return setmetatable(playerctl, playerctl.mt)
|
||||
29
modules/home-manager/ricing/awesomewm/dotfiles/rc.lua
Normal file
@ -0,0 +1,29 @@
|
||||
local awful = require "awful"
|
||||
local gears = require "gears"
|
||||
local beautiful = require "beautiful"
|
||||
|
||||
awful.spawn.with_shell("bash ~/.config/awesome/main/autorun.sh")
|
||||
require "setup":generate()
|
||||
|
||||
beautiful.init(gears.filesystem.get_configuration_dir() .. "theme/init.lua")
|
||||
|
||||
require "main"
|
||||
require "awful.autofocus"
|
||||
|
||||
-- init widget
|
||||
require "misc"
|
||||
require "ui"
|
||||
require "signal"
|
||||
|
||||
|
||||
gears.timer {
|
||||
timeout = 5,
|
||||
autostart = true,
|
||||
call_now = true,
|
||||
callback = function()
|
||||
collectgarbage "collect"
|
||||
end,
|
||||
}
|
||||
|
||||
collectgarbage("setpause", 110)
|
||||
collectgarbage("setstepmul", 1000)
|
||||
@ -0,0 +1,38 @@
|
||||
local json = require("mods.json")
|
||||
local helpers = require("helpers")
|
||||
local gfs = require("gears.filesystem")
|
||||
|
||||
local M = {}
|
||||
|
||||
M.defaultData = {
|
||||
colorscheme = "cat",
|
||||
gaps = 10,
|
||||
iconTheme = "~/.local/share/icons/hicolor/",
|
||||
openWeatherApi = "KEY_HERE",
|
||||
showDesktopIcons = true,
|
||||
pfp = "/home/" .. string.gsub(os.getenv('USER'), '^%l', string.lower) .. "/.config/awesome/theme/assets/pfp.png",
|
||||
wallpaper = "colorful",
|
||||
}
|
||||
|
||||
M.path = gfs.get_cache_dir() .. "json/settings.json"
|
||||
|
||||
function M:generate()
|
||||
if not helpers.file_exists(self.path) then
|
||||
local w = assert(io.open(self.path, "w"))
|
||||
w:write(json.encode(self.defaultData, nil, { pretty = true, indent = " ", align_keys = false, array_newline = true }))
|
||||
w:close()
|
||||
M.settings = self.defaultData
|
||||
else
|
||||
local r = assert(io.open(self.path, "rb"))
|
||||
local t = r:read("*all")
|
||||
r:close()
|
||||
local settings = json.decode(t)
|
||||
M.settings = settings
|
||||
end
|
||||
|
||||
if not helpers.file_exists(gfs.get_cache_dir() .. "lock/lock.jpg") then
|
||||
os.execute("mkdir -p ~/.cache/awesome/lock")
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,20 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
local naughty = require("naughty")
|
||||
|
||||
local function emit_airplane_status()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c \"rfkill list | sed -n 2p | awk '{print $3}'\" ", function(stdout)
|
||||
local status = stdout:match("yes") -- boolean
|
||||
awesome.emit_signal('signal::airplane', status)
|
||||
end)
|
||||
end
|
||||
|
||||
gears.timer {
|
||||
timeout = 2,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
emit_airplane_status()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
|
||||
local function emit_bluetooth_status()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c 'bluetoothctl show | grep -i powered:'", function(stdout)
|
||||
local status = stdout:match("yes") -- boolean
|
||||
awesome.emit_signal('signal::bluetooth', status)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Refreshing
|
||||
-------------
|
||||
gears.timer {
|
||||
timeout = 2,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
emit_bluetooth_status()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
require("signal.connection.wifi")
|
||||
require("signal.connection.bluetooth")
|
||||
require("signal.connection.airplane")
|
||||
@ -0,0 +1,23 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
|
||||
-- Network Fetching and Signal Emitting
|
||||
---------------------------------------
|
||||
local function emit_network_status()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c 'nmcli networking connectivity check'", function(stdout)
|
||||
local status = not stdout:match("none") -- boolean
|
||||
awesome.emit_signal('signal::network', status)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Refreshing
|
||||
-------------
|
||||
gears.timer {
|
||||
timeout = 2,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
emit_network_status()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
require("signal.system")
|
||||
require("signal.connection")
|
||||
require("signal.stats")
|
||||
@ -0,0 +1,20 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
local function emit_cpu_status()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c \"roundvalue $(grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage}')\""
|
||||
,
|
||||
function(stdout)
|
||||
stdout = tonumber(stdout)
|
||||
awesome.emit_signal('signal::cpu', stdout)
|
||||
end)
|
||||
end
|
||||
|
||||
gears.timer {
|
||||
timeout = 60,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
emit_cpu_status()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
local function emit_disk_status()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c \"df --output=pcent / | sed '1d;s/^ //;s/%//'\""
|
||||
,
|
||||
function(stdout)
|
||||
stdout = stdout:gsub("%s+", "")
|
||||
stdout = tonumber(stdout)
|
||||
awesome.emit_signal('signal::disk', stdout)
|
||||
end)
|
||||
end
|
||||
|
||||
gears.timer {
|
||||
timeout = 600,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
emit_disk_status()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
require("signal.stats.weather")
|
||||
require("signal.stats.uptime")
|
||||
require("signal.stats.cpu")
|
||||
require("signal.stats.disk")
|
||||
require("signal.stats.memory")
|
||||
@ -0,0 +1,20 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
local function emit_mem_status()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c \"roundvalue $(free | grep Mem | awk '{print $3/$2 * 100.0}')\""
|
||||
,
|
||||
function(stdout)
|
||||
stdout = tonumber(stdout)
|
||||
awesome.emit_signal('signal::memory', stdout)
|
||||
end)
|
||||
end
|
||||
|
||||
gears.timer {
|
||||
timeout = 60,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
emit_mem_status()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
local function emit_uptime_status()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c \"uptime --pretty | sed 's/up\\s*//g' | sed 's/\\s*days/d/g' | sed 's/\\s*hours/h/g' | sed 's/\\s*minutes/m/g'\""
|
||||
,
|
||||
function(stdout)
|
||||
stdout = stdout:gsub("%s+", "")
|
||||
awesome.emit_signal('signal::uptime', stdout)
|
||||
end)
|
||||
end
|
||||
|
||||
gears.timer {
|
||||
timeout = 60,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
emit_uptime_status()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,107 @@
|
||||
local awful = require("awful")
|
||||
local gears = require("gears")
|
||||
local filesystem = gears.filesystem
|
||||
local json = require("mods.json")
|
||||
local helpers = require("helpers")
|
||||
local icon_dir = filesystem.get_configuration_dir() .. "theme/assets/weather/icons/"
|
||||
local thumb_dir = filesystem.get_configuration_dir() .. "theme/assets/weather/images/"
|
||||
|
||||
local GET_FORECAST_CMD = [[bash -c "curl -s --show-error -X GET '%s'"]]
|
||||
|
||||
local icon_map = {
|
||||
["01d"] = "weather-clear-sky",
|
||||
["02d"] = "weather-few-clouds",
|
||||
["04d"] = "weather-few-clouds",
|
||||
["03d"] = "weather-clouds",
|
||||
["09d"] = "weather-showers-scattered",
|
||||
["09n"] = "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",
|
||||
["10n"] = "weather-showers",
|
||||
["11n"] = "weather-strom",
|
||||
["13n"] = "weather-snow",
|
||||
["50n"] = "weather-fog",
|
||||
}
|
||||
|
||||
|
||||
local image_map = {
|
||||
["01d"] = "weather-clear-sky",
|
||||
["02d"] = "weather-clouds",
|
||||
["04d"] = "weather-clouds",
|
||||
["03d"] = "weather-clouds",
|
||||
["09d"] = "weather-showers-scattered",
|
||||
["09n"] = "weather-showers-scattered",
|
||||
["10d"] = "weather-showers",
|
||||
["11d"] = "weather-strom",
|
||||
["13d"] = "weather-snow",
|
||||
["50d"] = "weather-fog",
|
||||
["01n"] = "weather-clear-night",
|
||||
["02n"] = "weather-clouds-night",
|
||||
["03n"] = "weather-clouds-night",
|
||||
["04n"] = "weather-clouds-night",
|
||||
["10n"] = "weather-showers",
|
||||
["11n"] = "weather-strom",
|
||||
["13n"] = "weather-snow",
|
||||
["50n"] = "weather-fog",
|
||||
}
|
||||
|
||||
local api_key = helpers.readJson(gears.filesystem.get_cache_dir() .. "json/settings.json").openWeatherApi
|
||||
local coordinates = { "28.6446772", "77.320955" }
|
||||
|
||||
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)
|
||||
local result = json.decode(stdout)
|
||||
-- Current weather setup
|
||||
local out = {
|
||||
desc = result.current.weather[1].description:gsub("^%l", string.upper),
|
||||
humidity = result.current.humidity,
|
||||
temp = math.floor(result.current.temp),
|
||||
feelsLike = math.floor(result.current.feels_like),
|
||||
image = icon_dir .. icon_map[result.current.weather[1].icon] .. ".svg",
|
||||
thumb = thumb_dir .. image_map[result.current.weather[1].icon] .. ".jpg",
|
||||
hourly = {
|
||||
result.hourly[1],
|
||||
result.hourly[2],
|
||||
result.hourly[3],
|
||||
result.hourly[4],
|
||||
result.hourly[5],
|
||||
result.hourly[6],
|
||||
},
|
||||
daily = {
|
||||
result.daily[1],
|
||||
result.daily[2],
|
||||
result.daily[3],
|
||||
result.daily[4],
|
||||
result.daily[5],
|
||||
result.daily[6],
|
||||
}
|
||||
}
|
||||
awesome.emit_signal("signal::weather", out)
|
||||
end)
|
||||
@ -0,0 +1,34 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
local gfs = gears.filesystem
|
||||
|
||||
-- Battery Fetching and Signal Emitting
|
||||
---------------------------------------
|
||||
-- Battery information script
|
||||
local battery_script =
|
||||
"bash -c 'echo $(cat /sys/class/power_supply/BAT0/capacity) echo $(cat /sys/class/power_supply/BAT0/status)'"
|
||||
|
||||
local function battery_emit()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
battery_script, function(stdout)
|
||||
-- The battery level and status are saved as a string. Then the level
|
||||
-- is stored separately as a string, then converted to int. The status
|
||||
-- is stored as a bool, and also as an int for registering changes in
|
||||
-- battery status.
|
||||
local level = string.match(stdout:match('(%d+)'), '(%d+)')
|
||||
local level_int = tonumber(level) -- integer
|
||||
local power = not stdout:match('Discharging') -- boolean
|
||||
awesome.emit_signal('signal::battery', level_int, power)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Refreshing
|
||||
-------------
|
||||
gears.timer {
|
||||
timeout = 20,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
battery_emit()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
|
||||
local brightness_script =
|
||||
"bash -c 'echo $(($(cat /sys/class/backlight/*/brightness) * 100 / $(cat /sys/class/backlight/*/max_brightness)))'"
|
||||
|
||||
local function emit_brightness()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
brightness_script, function(stdout)
|
||||
local level_cur = tonumber(stdout)
|
||||
awesome.emit_signal('signal::brightness', level_cur)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Refreshing
|
||||
-------------
|
||||
gears.timer {
|
||||
timeout = 1,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
emit_brightness()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
local gears = require('gears')
|
||||
local naughty = require("naughty")
|
||||
-- Network Fetching and Signal Emitting
|
||||
---------------------------------------
|
||||
local function emit_dnd_status()
|
||||
local status = naughty.is_suspended()
|
||||
awesome.emit_signal('signal::dnd', status)
|
||||
end
|
||||
|
||||
-- Refreshing
|
||||
-------------
|
||||
gears.timer {
|
||||
timeout = 2,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
emit_dnd_status()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
require("signal.system.dnd")
|
||||
require("signal.system.brightness")
|
||||
require("signal.system.volume")
|
||||
require("signal.system.battery")
|
||||
require("signal.system.redshift")
|
||||
@ -0,0 +1,21 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
|
||||
local function mic_emit()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c 'pamixer --source 1 --get-mute'", function(value)
|
||||
local stringtoboolean = { ["true"] = false, ["false"] = true }
|
||||
value = value:gsub("%s+", "")
|
||||
value = stringtoboolean[value]
|
||||
awesome.emit_signal('signal::mic', value) -- integer
|
||||
end)
|
||||
end
|
||||
|
||||
gears.timer {
|
||||
timeout = 1,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
mic_emit()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
|
||||
local function light_emit()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c 'cat ~/.cache/redshift'", function(stdout)
|
||||
local status = stdout:match("true") -- boolean
|
||||
awesome.emit_signal('signal::redshift', status)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Microphone Fetching and Signal Emitting
|
||||
-- Refreshing
|
||||
-------------
|
||||
gears.timer {
|
||||
timeout = 2,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
light_emit()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
local awful = require('awful')
|
||||
local gears = require('gears')
|
||||
|
||||
local function volume_emit()
|
||||
awful.spawn.easy_async_with_shell(
|
||||
"bash -c 'pamixer --get-volume'", function(stdout)
|
||||
local volume_int = tonumber(stdout) -- integer
|
||||
awesome.emit_signal('signal::volume', volume_int) -- integer
|
||||
end)
|
||||
end
|
||||
|
||||
-- Microphone Fetching and Signal Emitting
|
||||
-- Refreshing
|
||||
-------------
|
||||
gears.timer {
|
||||
timeout = 1,
|
||||
call_now = true,
|
||||
autostart = true,
|
||||
callback = function()
|
||||
volume_emit()
|
||||
end
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
|
||||
<svg
|
||||
fill="#000000"
|
||||
width="800px"
|
||||
height="800px"
|
||||
viewBox="0 0 24 24"
|
||||
role="img"
|
||||
version="1.1"
|
||||
id="svg67"
|
||||
sodipodi:docname="awesomewm-svgrepo-com.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs71" />
|
||||
<sodipodi:namedview
|
||||
id="namedview69"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
inkscape:deskcolor="#505050"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.76976952"
|
||||
inkscape:cx="387.12886"
|
||||
inkscape:cy="419.60612"
|
||||
inkscape:window-width="1904"
|
||||
inkscape:window-height="970"
|
||||
inkscape:window-x="8"
|
||||
inkscape:window-y="35"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg67" />
|
||||
<path
|
||||
d="M0 24V8.25h16.5V7.5H0V0h24v24h-7.5v-8.25h-9v.75h8.25V24z"
|
||||
id="path65"
|
||||
style="fill:#ffffff" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 707 KiB |
@ -0,0 +1,513 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="141.5919mm"
|
||||
height="122.80626mm"
|
||||
viewBox="0 0 501.70361 435.14028"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.0 r15299"
|
||||
sodipodi:docname="nix-snowflake.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient5562">
|
||||
<stop
|
||||
style="stop-color:#699ad7;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop5564" />
|
||||
<stop
|
||||
id="stop5566"
|
||||
offset="0.24345198"
|
||||
style="stop-color:#7eb1dd;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#7ebae4;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop5568" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient5053">
|
||||
<stop
|
||||
style="stop-color:#415e9a;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop5055" />
|
||||
<stop
|
||||
id="stop5057"
|
||||
offset="0.23168644"
|
||||
style="stop-color:#4a6baf;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#5277c3;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop5059" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5960"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop5962"
|
||||
offset="0"
|
||||
style="stop-color:#637ddf;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#649afa;stop-opacity:1"
|
||||
offset="0.23168644"
|
||||
id="stop5964" />
|
||||
<stop
|
||||
id="stop5966"
|
||||
offset="1"
|
||||
style="stop-color:#719efa;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient5867">
|
||||
<stop
|
||||
style="stop-color:#7363df;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop5869" />
|
||||
<stop
|
||||
id="stop5871"
|
||||
offset="0.23168644"
|
||||
style="stop-color:#6478fa;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#719efa;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop5873" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="515.97058"
|
||||
x2="282.26105"
|
||||
y1="338.62445"
|
||||
x1="213.95642"
|
||||
gradientTransform="translate(983.36076,601.38885)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient5855"
|
||||
xlink:href="#linearGradient5960"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="515.97058"
|
||||
x2="282.26105"
|
||||
y1="338.62445"
|
||||
x1="213.95642"
|
||||
gradientTransform="translate(-197.75174,-337.1451)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient5855-8"
|
||||
xlink:href="#linearGradient5867"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="247.58188"
|
||||
x2="-702.75317"
|
||||
y1="102.74675"
|
||||
x1="-775.20807"
|
||||
gradientTransform="translate(983.36076,601.38885)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient4544"
|
||||
xlink:href="#linearGradient5960"
|
||||
inkscape:collect="always" />
|
||||
<clipPath
|
||||
id="clipPath4501"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<circle
|
||||
r="241.06563"
|
||||
cy="686.09473"
|
||||
cx="335.13995"
|
||||
id="circle4503"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#adadad;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath5410"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<circle
|
||||
r="241.13741"
|
||||
cy="340.98975"
|
||||
cx="335.98114"
|
||||
id="circle5412"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5053"
|
||||
id="linearGradient5137"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(864.55062,-2197.497)"
|
||||
x1="-584.19934"
|
||||
y1="782.33563"
|
||||
x2="-496.29703"
|
||||
y2="937.71399" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5053"
|
||||
id="linearGradient5147"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(864.55062,-2197.497)"
|
||||
x1="-584.19934"
|
||||
y1="782.33563"
|
||||
x2="-496.29703"
|
||||
y2="937.71399" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5562"
|
||||
id="linearGradient5162"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(70.505061,-1761.3076)"
|
||||
x1="200.59668"
|
||||
y1="351.41116"
|
||||
x2="290.08701"
|
||||
y2="506.18814" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5562"
|
||||
id="linearGradient5172"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(70.505061,-1761.3076)"
|
||||
x1="200.59668"
|
||||
y1="351.41116"
|
||||
x2="290.08701"
|
||||
y2="506.18814" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5562"
|
||||
id="linearGradient5182"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(70.505061,-1761.3076)"
|
||||
x1="200.59668"
|
||||
y1="351.41116"
|
||||
x2="290.08701"
|
||||
y2="506.18814" />
|
||||
<linearGradient
|
||||
y2="506.18814"
|
||||
x2="290.08701"
|
||||
y1="351.41116"
|
||||
x1="200.59668"
|
||||
gradientTransform="translate(70.505061,-1761.3076)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient5201"
|
||||
xlink:href="#linearGradient5562"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="937.71399"
|
||||
x2="-496.29703"
|
||||
y1="782.33563"
|
||||
x1="-584.19934"
|
||||
gradientTransform="translate(864.55062,-2197.497)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient5205"
|
||||
xlink:href="#linearGradient5053"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5562"
|
||||
id="linearGradient4328"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(70.650339,-1055.1511)"
|
||||
x1="200.59668"
|
||||
y1="351.41116"
|
||||
x2="290.08701"
|
||||
y2="506.18814" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5053"
|
||||
id="linearGradient4330"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(864.69589,-1491.3405)"
|
||||
x1="-584.19934"
|
||||
y1="782.33563"
|
||||
x2="-496.29703"
|
||||
y2="937.71399" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98318225"
|
||||
inkscape:cx="113.58176"
|
||||
inkscape:cy="-45.193301"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer3"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1577"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-global="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer7"
|
||||
inkscape:label="bg"
|
||||
style="display:none"
|
||||
transform="translate(-23.75651,-24.84972)">
|
||||
<rect
|
||||
transform="translate(-132.5822,958.04022)"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect5389"
|
||||
width="1543.4283"
|
||||
height="483.7439"
|
||||
x="132.5822"
|
||||
y="-957.77832" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer6"
|
||||
inkscape:label="logo-guide"
|
||||
style="display:none"
|
||||
transform="translate(-156.33871,933.1905)">
|
||||
<rect
|
||||
y="-958.02759"
|
||||
x="132.65129"
|
||||
height="484.30399"
|
||||
width="550.41602"
|
||||
id="rect5379"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#5c201e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
inkscape:export-filename="/home/tim/dev/nix/homepage/logo/nix-wiki.png"
|
||||
inkscape:export-xdpi="22.07"
|
||||
inkscape:export-ydpi="22.07" />
|
||||
<rect
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c24a46;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect5372"
|
||||
width="501.94415"
|
||||
height="434.30405"
|
||||
x="156.12303"
|
||||
y="-933.02759"
|
||||
inkscape:export-filename="/home/tim/dev/nix/homepage/logo/nixos-logo-only-hires-print.png"
|
||||
inkscape:export-xdpi="212.2"
|
||||
inkscape:export-ydpi="212.2" />
|
||||
<rect
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d98d8a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect5381"
|
||||
width="24.939611"
|
||||
height="24.939611"
|
||||
x="658.02826"
|
||||
y="-958.04022" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="print-logo"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:inline"
|
||||
transform="translate(-156.33871,933.1905)"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#5277c3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 309.40365,-710.2521 122.19683,211.6751 -56.15706,0.5268 -32.6236,-56.8692 -32.85645,56.5653 -27.90237,-0.011 -14.29086,-24.6896 46.81047,-80.4902 -33.22946,-57.8256 z"
|
||||
id="path4861"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#7ebae4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 353.50926,-797.4433 -122.21756,211.6631 -28.53477,-48.37 32.93839,-56.6875 -65.41521,-0.1719 -13.9414,-24.1698 14.23637,-24.721 93.11177,0.2939 33.46371,-57.6903 z"
|
||||
id="use4863"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#7ebae4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 362.88537,-628.243 244.41439,0.012 -27.62229,48.8968 -65.56199,-0.1817 32.55876,56.7371 -13.96098,24.1585 -28.52722,0.032 -46.3013,-80.7841 -66.69317,-0.1353 z"
|
||||
id="use4865"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#7ebae4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 505.14318,-720.9886 -122.19683,-211.6751 56.15706,-0.5268 32.6236,56.8692 32.85645,-56.5653 27.90237,0.011 14.29086,24.6896 -46.81047,80.4902 33.22946,57.8256 z"
|
||||
id="use4867"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4873"
|
||||
d="m 309.40365,-710.2521 122.19683,211.6751 -56.15706,0.5268 -32.6236,-56.8692 -32.85645,56.5653 -27.90237,-0.011 -14.29086,-24.6896 46.81047,-80.4902 -33.22946,-57.8256 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#5277c3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="use4875"
|
||||
d="m 451.3364,-803.53264 -244.4144,-0.012 27.62229,-48.89685 65.56199,0.18175 -32.55875,-56.73717 13.96097,-24.15851 28.52722,-0.0315 46.3013,80.78414 66.69317,0.13524 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#5277c3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="use4877"
|
||||
d="m 460.87178,-633.8425 122.21757,-211.66304 28.53477,48.37003 -32.93839,56.68751 65.4152,0.1718 13.9414,24.1698 -14.23636,24.7211 -93.11177,-0.294 -33.46371,57.6904 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#5277c3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<g
|
||||
id="layer2"
|
||||
inkscape:label="guides"
|
||||
style="display:none"
|
||||
transform="translate(72.039038,-1799.4476)">
|
||||
<path
|
||||
d="M 460.60629,594.72881 209.74183,594.7288 84.309616,377.4738 209.74185,160.21882 l 250.86446,1e-5 125.43222,217.255 z"
|
||||
inkscape:randomized="0"
|
||||
inkscape:rounded="0"
|
||||
inkscape:flatsided="true"
|
||||
sodipodi:arg2="1.5707963"
|
||||
sodipodi:arg1="1.0471976"
|
||||
sodipodi:r2="217.25499"
|
||||
sodipodi:r1="250.86446"
|
||||
sodipodi:cy="377.47382"
|
||||
sodipodi:cx="335.17407"
|
||||
sodipodi:sides="6"
|
||||
id="path6032"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.23600003;fill:#4e4d52;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
sodipodi:type="star" />
|
||||
<path
|
||||
transform="translate(0,-308.26772)"
|
||||
sodipodi:type="star"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#4e4d52;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="path5875"
|
||||
sodipodi:sides="6"
|
||||
sodipodi:cx="335.17407"
|
||||
sodipodi:cy="685.74158"
|
||||
sodipodi:r1="100.83495"
|
||||
sodipodi:r2="87.32563"
|
||||
sodipodi:arg1="1.0471976"
|
||||
sodipodi:arg2="1.5707963"
|
||||
inkscape:flatsided="true"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="m 385.59154,773.06721 -100.83495,0 -50.41747,-87.32564 50.41748,-87.32563 100.83495,10e-6 50.41748,87.32563 z" />
|
||||
<path
|
||||
transform="translate(0,-308.26772)"
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5851"
|
||||
d="m 1216.5591,938.53395 123.0545,228.14035 -42.6807,-1.2616 -43.4823,-79.7725 -39.6506,80.3267 -32.6875,-19.7984 53.4737,-100.2848 -37.1157,-73.88955 z"
|
||||
style="fill:url(#linearGradient5855);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.41499999;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c53a3a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect5884"
|
||||
width="48.834862"
|
||||
height="226.22897"
|
||||
x="-34.74221"
|
||||
y="446.17056"
|
||||
transform="rotate(-30)" />
|
||||
<path
|
||||
transform="translate(0,-308.26772)"
|
||||
sodipodi:type="star"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.50899999;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path3428"
|
||||
sodipodi:sides="6"
|
||||
sodipodi:cx="223.93674"
|
||||
sodipodi:cy="878.63831"
|
||||
sodipodi:r1="28.048939"
|
||||
sodipodi:r2="24.291094"
|
||||
sodipodi:arg1="0"
|
||||
sodipodi:arg2="0.52359878"
|
||||
inkscape:flatsided="true"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="m 251.98568,878.63831 -14.02447,24.29109 h -28.04894 l -14.02447,-24.29109 14.02447,-24.2911 h 28.04894 z" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#rect5884"
|
||||
id="use4252"
|
||||
transform="rotate(60,268.29786,489.4515)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<rect
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:0.6507937;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect4254"
|
||||
width="5.3947482"
|
||||
height="115.12564"
|
||||
x="545.71014"
|
||||
y="467.07007"
|
||||
transform="rotate(30,575.23539,-154.13386)" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="gradient-logo"
|
||||
style="display:inline;opacity:1"
|
||||
sodipodi:insensitive="true"
|
||||
transform="translate(-156.33871,933.1905)">
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3336-6"
|
||||
d="m 309.54892,-710.38827 122.19683,211.67512 -56.15706,0.5268 -32.6236,-56.8692 -32.85645,56.5653 -27.90237,-0.011 -14.29086,-24.6896 46.81047,-80.4901 -33.22946,-57.8257 z"
|
||||
style="opacity:1;fill:url(#linearGradient4328);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<use
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="rotate(60,407.11155,-715.78724)"
|
||||
id="use3439-6"
|
||||
inkscape:transform-center-y="151.59082"
|
||||
inkscape:transform-center-x="124.43045"
|
||||
xlink:href="#path3336-6"
|
||||
y="0"
|
||||
x="0" />
|
||||
<use
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="rotate(-60,407.31177,-715.70016)"
|
||||
id="use3445-0"
|
||||
inkscape:transform-center-y="75.573958"
|
||||
inkscape:transform-center-x="-168.20651"
|
||||
xlink:href="#path3336-6"
|
||||
y="0"
|
||||
x="0" />
|
||||
<use
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="rotate(180,407.41868,-715.7565)"
|
||||
id="use3449-5"
|
||||
inkscape:transform-center-y="-139.94592"
|
||||
inkscape:transform-center-x="59.669705"
|
||||
xlink:href="#path3336-6"
|
||||
y="0"
|
||||
x="0" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4330);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 309.54892,-710.38827 122.19683,211.67512 -56.15706,0.5268 -32.6236,-56.8692 -32.85645,56.5653 -27.90237,-0.011 -14.29086,-24.6896 46.81047,-80.4901 -33.22946,-57.8256 z"
|
||||
id="path4260-0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<use
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="rotate(120,407.33916,-716.08356)"
|
||||
id="use4354-5"
|
||||
xlink:href="#path4260-0"
|
||||
y="0"
|
||||
x="0"
|
||||
style="display:inline" />
|
||||
<use
|
||||
height="100%"
|
||||
width="100%"
|
||||
transform="rotate(-120,407.28823,-715.86995)"
|
||||
id="use4362-2"
|
||||
xlink:href="#path4260-0"
|
||||
y="0"
|
||||
x="0"
|
||||
style="display:inline" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1 @@
|
||||
<svg height="16" width="16"><path d="M4.003 4h1 .031a1.04 1.04 0 0 1 .687.312l2.28 2.281 2.312-2.281c.266-.23.446-.305.687-.312h1v1c0 .286-.034.551-.25.75l-2.28 2.281 2.249 2.25c.188.188.281.453.281.719v1h-1c-.265 0-.53-.093-.718-.281l-2.28-2.281-2.28 2.281c-.188.188-.453.281-.718.281h-1v-1c0-.265.093-.531.281-.719l2.28-2.25-2.28-2.281c-.211-.195-.303-.469-.281-.75z" fill="#363636"/></svg>
|
||||
|
After Width: | Height: | Size: 393 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1 @@
|
||||
<svg height="16" width="16"><path d="M4 7v3h8V7z" fill="#363636"/></svg>
|
||||
|
After Width: | Height: | Size: 73 B |
|
After Width: | Height: | Size: 202 KiB |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="fill:#dfdfdf" d="M 1,8 C 1,11.866 4.134,15 8,15 9.9252,15 11.68,14.117 13,12.715 12.482,12.847 12.034,13 11.5,13 7.9101,13 5,10.09 5,6.5 5,4.267 6.1294,2.19 8,1 4.1145,1 1,4.134 1,8 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 286 B |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="fill:#dfdfdf" d="M 6.9999991,-6.4999999e-8 V 2.085937 a 6,6 0 0 1 1,-0.085937 6,6 0 0 1 1,0.08984 V -6.4999999e-8 Z M 3.0507801,1.6367189 1.6367181,3.050781 3.1132801,4.527344 a 6,6 0 0 1 1.416016,-1.41211 z m 9.8984379,0 -1.476563,1.4765621 a 6,6 0 0 1 1.41211,1.416016 L 14.36328,3.050781 Z M 7.9999991,3 a 5,5 0 0 0 -5,5 5,5 0 0 0 5,5 A 5,5 0 0 0 12.999999,8 5,5 0 0 0 7.9999991,3 Z m -8,4 v 2 h 2.085937 a 6,6 0 0 1 -0.08594,-1 6,6 0 0 1 0.08984,-1 z M 13.914061,7 a 6,6 0 0 1 0.08594,1 6,6 0 0 1 -0.08984,1 h 2.08984 V 7 Z m -10.7988279,4.470703 -1.478515,1.478516 1.414062,1.414062 1.476563,-1.476562 a 6,6 0 0 1 -1.41211,-1.416016 z m 9.7714849,0.002 a 6,6 0 0 1 -1.416016,1.41211 l 1.478516,1.478515 1.414062,-1.414062 z M 6.9999991,13.910156 V 16 h 2 v -2.085938 a 6,6 0 0 1 -1,0.08594 6,6 0 0 1 -1,-0.08984 z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 921 B |
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<defs>
|
||||
<style id="current-color-scheme" type="text/css">
|
||||
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor" class="ColorScheme-Text" d="M 7.736,0.9962 C 4.9732,1.0977 2.4273,2.8008 1.4235,5.5587 0.89934,6.999 0.87974,8.501 1.2653,9.875 1.669,8.557 2.7497,7.542 4.1032,7.192 4.2732,6.9013 4.4747,6.6319 4.693,6.3791 4.7035,5.6688 4.8234,4.9505 5.0797,4.2462 5.5939,2.8336 6.5542,1.7379 7.736,0.9962 Z M 8.086,5.7502 C 6.5323,5.7502 5.2096,6.7011 4.6403,8.047 3.1944,8.262 2.0856,9.494 2.0856,11 2.0856,12.657 3.4287,14 5.0856,14 H 11.461 C 12.91,14 14.086,12.825 14.086,11.375 14.086,10.028 13.073,8.924 11.765,8.774 11.424,7.054 9.906,5.7502 8.086,5.7502 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 966 B |
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<defs>
|
||||
<style id="current-color-scheme" type="text/css">
|
||||
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor" class="ColorScheme-Text" d="M 7.736,0.9962 C 4.9732,1.0977 2.4273,2.8008 1.4235,5.5587 0.89934,6.999 0.87974,8.501 1.2653,9.875 1.669,8.557 2.7497,7.542 4.1032,7.192 4.2732,6.9013 4.4747,6.6319 4.693,6.3791 4.7035,5.6688 4.8234,4.9505 5.0797,4.2462 5.5939,2.8336 6.5542,1.7379 7.736,0.9962 Z M 8.086,5.7502 C 6.5323,5.7502 5.2096,6.7011 4.6403,8.047 3.1944,8.262 2.0856,9.494 2.0856,11 2.0856,12.657 3.4287,14 5.0856,14 H 11.461 C 12.91,14 14.086,12.825 14.086,11.375 14.086,10.028 13.073,8.924 11.765,8.774 11.424,7.054 9.906,5.7502 8.086,5.7502 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 966 B |
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="fill:#dfdfdf" d="M 13.5,16 C 14.88,16 16,14.88 16,13.5 16,12.23 15.04,11.19 13.81,11.03 13.41,9.86 12.31,9 11,9 9.69,9 8.6,9.86 8.19,11.03 6.96,11.19 6,12.23 6,13.5 6,14.88 7.12,16 8.5,16"/>
|
||||
<path style="fill:#dfdfdf" d="M 8,1 C 4.1145,0.999 1,4.134 1,8 1,10.841 2.6956,13.28 5.127,14.377 5.0526,14.095 5,13.804 5,13.5 5,12.309 5.6566,11.348 6.5957,10.758 5.6043,9.6168 5,8.1303 5,6.5 5.0014,4.267 6.1294,2.19 8,1 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 519 B |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="fill:#dfdfdf" d="M 7 0 L 7 2.0859375 A 6 6 0 0 1 8 2 A 6 6 0 0 1 9 2.0898438 L 9 0 L 7 0 z M 3.0507812 1.6367188 L 1.6367188 3.0507812 L 3.1132812 4.5273438 A 6 6 0 0 1 4.5292969 3.1152344 L 3.0507812 1.6367188 z M 12.949219 1.6367188 L 11.472656 3.1132812 A 6 6 0 0 1 12.884766 4.5292969 L 14.363281 3.0507812 L 12.949219 1.6367188 z M 8 3 A 5 5 0 0 0 3 8 A 5 5 0 0 0 5.2949219 12.205078 C 5.713317 11.305716 6.5416242 10.637052 7.5234375 10.322266 C 8.1696152 9.0017204 9.4227843 8 11 8 C 11.732994 8 12.393594 8.2229024 12.958984 8.5878906 A 5 5 0 0 0 13 8 A 5 5 0 0 0 8 3 z M 0 7 L 0 9 L 2.0859375 9 A 6 6 0 0 1 2 8 A 6 6 0 0 1 2.0898438 7 L 0 7 z M 13.914062 7 A 6 6 0 0 1 14 8 A 6 6 0 0 1 13.910156 9 L 16 9 L 16 7 L 13.914062 7 z M 11 9 C 9.69 9 8.5994531 9.8592969 8.1894531 11.029297 C 6.9594531 11.189297 6 12.23 6 13.5 C 6 14.88 7.12 16 8.5 16 L 13.5 16 C 14.88 16 16 14.88 16 13.5 C 16 12.23 15.040547 11.189297 13.810547 11.029297 C 13.410547 9.8592969 12.31 9 11 9 z M 3.1152344 11.470703 L 1.6367188 12.949219 L 3.0507812 14.363281 L 4.5273438 12.886719 A 6 6 0 0 1 3.1152344 11.470703 z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="opacity:0.3;fill:#dfdfdf" d="M 2 1 C 1.446 1 1 1.446 1 2 C 1 2.554 1.446 3 2 3 L 8 3 C 8.554 3 9 2.554 9 2 C 9 1.446 8.554 1 8 1 L 2 1 z M 5 5 C 4.446 5 4 5.446 4 6 C 4 6.554 4.446 7 5 7 L 15 7 C 15.554 7 16 6.554 16 6 C 16 5.446 15.554 5 15 5 L 5 5 z M 1 9 C 0.446 9 0 9.446 0 10 C 0 10.554 0.446 11 1 11 L 12 11 C 12.554 11 13 10.554 13 10 C 13 9.446 12.554 9 12 9 L 1 9 z M 3 13 C 2.446 13 2 13.446 2 14 C 2 14.554 2.446 15 3 15 L 15 15 C 15.554 15 16 14.554 16 14 C 16 13.446 15.554 13 15 13 L 3 13 z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 607 B |
@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<defs>
|
||||
<style id="current-color-scheme" type="text/css">
|
||||
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0 C 5.929,0 4.165,1.27 3.406,3.07 1.478,3.35 0,5 0,7 0,8.94 1.365,10.54 3.187,10.91 3.951,10.13 4.709,9.35 5.5,8.6 6.073,9.14 6.633,9.7 7.187,10.25 7.43,10.18 7.57,9.41 7.906,9.16 8.76,8.29 9.615,7.43 10.5,6.6 11.166,7.22 11.791,7.86 12.437,8.5 13.035,9.07 13.665,9.71 13.875,10.53 13.891,10.59 13.893,10.64 13.906,10.69 15.141,10.15 16,8.94 16,7.5 16,5.71 14.649,4.23 12.906,4.03 12.451,1.74 10.427,0 8,0 Z M 10.5,9.44 C 10.415,9.52 10.335,9.61 10.25,9.69 9.853,10.11 9.351,10.47 9.125,11 H 11.906 C 11.88,10.94 11.85,10.87 11.812,10.82 11.439,10.3 10.933,9.9 10.5,9.44 Z"/>
|
||||
<path style="fill:currentColor" class="ColorScheme-Highlight" d="M 10.5,8 10.156,8.34 8.75,9.75 C 8.297,10.2 8,10.81 8,11.5 8,12.87 9.125,14 10.5,14 11.875,14 13,12.87 13,11.5 13,10.81 12.703,10.2 12.25,9.75 L 10.844,8.34 Z M 5.5,10 5.156,10.34 3.75,11.75 C 3.297,12.2 3,12.81 3,13.5 3,14.87 4.125,16 5.5,16 6.875,16 8,14.87 8,13.5 8,12.81 7.703,12.2 7.25,11.75 L 5.844,10.34 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="fill:#fcc467" d="M 10,8 C 8.69,8 7.6,8.86 7.19,10.03 5.96,10.19 5,11.23 5,12.5 5,13.88 6.12,15 7.5,15 H 12.5 C 13.88,15 15,13.88 15,12.5 15,11.23 14.04,10.19 12.81,10.03 12.41,8.86 11.31,8 10,8 Z"/>
|
||||
<path style="fill:#dfdfdf" d="M 8,0 C 5.93,0 4.1702,1.2705 3.4102,3.0605 1.4802,3.3505 0,4.99 0,7 0,9.21 1.79,11 4,11 H 4.3945 C 4.8388,10.204 5.6169,9.6129 6.5234,9.3223 7.1696,8.0017 8.4228,7 10,7 11.573,7 12.83,7.9972 13.473,9.3203 13.983,9.4834 14.453,9.7437 14.848,10.08 15.551,9.4395 16,8.5242 16,7.5 16,5.7 14.65,4.2293 12.91,4.0293 12.45,1.7393 10.43,0 8,0 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 669 B |
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<defs>
|
||||
<style id="current-color-scheme" type="text/css">
|
||||
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,1 C 5.9289,1 4.1653,2.2679 3.4062,4.0625 1.4784,4.3491 0,5.9924 0,8 0,10.209 1.7909,12 4,12 H 4.4062 C 4.8601,11.199 5.6472,10.573 6.5312,10.313 7.151,8.99 8.506,7.974 10,8 11.908,7.969 13.582,9.485 13.875,11.344 14.018,11.389 14.144,11.435 14.281,11.5 15.312,10.891 16,9.784 16,8.5 16,6.7035 14.649,5.2313 12.906,5.0312 12.452,2.7379 10.427,1 8,1 Z M 10,9 C 8.688,9 7.595,9.858 7.188,11.031 5.9567,11.187 5,12.227 5,13.5 5,14.881 6.1193,16 7.5,16 H 13 C 14.105,16 15,15.105 15,14 15,12.895 14.105,12 13,12 13,10.343 11.657,9 10,9 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 982 B |
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="fill:#dfdfdf" d="M 8,0 C 5.93,0 4.17,1.27 3.41,3.06 1.48,3.35 0,4.99 0,7 0,7.73 0.2,8.41 0.54,9 H 0.52 C 1.08,9.97 2.04,10.68 3.17,10.91 L 5.5,8.58 7.25,10.33 C 7.43,9.84 7.69,9.39 8.04,9.04 L 10.5,6.58 12.96,9.04 C 13.4,9.48 13.73,10.05 13.89,10.69 H 13.91 V 10.69 L 13.92,10.68 H 13.93 L 13.94,10.67 C 15.16,10.12 16,8.92 16,7.5 16,5.7 14.65,4.23 12.91,4.03 12.45,1.74 10.43,0 8,0 Z"/>
|
||||
<path style="fill:#dfdfdf" d="M 10.5,8 8.75,9.75 C 8.3,10.2 8,10.81 8,11.5 8,12.87 9.13,14 10.5,14 11.87,14 13,12.87 13,11.5 13,10.81 12.7,10.2 12.25,9.75 Z M 5.5,10 3.75,11.75 C 3.3,12.2 3,12.81 3,13.5 3,14.87 4.13,16 5.5,16 6.87,16 8,14.87 8,13.5 8,12.81 7.7,12.2 7.25,11.75 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 770 B |
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="fill:#dfdfdf" d="M 8,0 C 5.93,0 4.17,1.27 3.41,3.06 1.48,3.35 0,4.99 0,7 0,9.21 1.79,11 4,11 H 12.5 C 14.43,11 16,9.43 16,7.5 16,5.7 14.65,4.23 12.91,4.03 12.45,1.74 10.43,0 8,0 Z"/>
|
||||
<path style="fill:#dfdfdf" d="M 2.9766,11.994 A 0.5,0.5 0 0 0 2.5527,12.277 L 1.5527,14.277 A 0.5,0.5 0 1 0 2.4473,14.723 L 3.4473,12.723 A 0.5,0.5 0 0 0 2.9766,11.994 Z M 5.4766,11.994 A 0.5,0.5 0 0 0 5.0527,12.277 L 4.0527,14.277 A 0.5,0.5 0 1 0 4.9473,14.723 L 5.9473,12.723 A 0.5,0.5 0 0 0 5.4766,11.994 Z M 7.9766,11.994 A 0.5,0.5 0 0 0 7.5527,12.277 L 6.5527,14.277 A 0.5,0.5 0 1 0 7.4473,14.723 L 8.4473,12.723 A 0.5,0.5 0 0 0 7.9766,11.994 Z M 10.477,11.994 A 0.5,0.5 0 0 0 10.053,12.277 L 9.0527,14.277 A 0.5,0.5 0 1 0 9.9473,14.723 L 10.947,12.723 A 0.5,0.5 0 0 0 10.477,11.994 Z M 12.977,11.994 A 0.5,0.5 0 0 0 12.553,12.277 L 11.553,14.277 A 0.5,0.5 0 1 0 12.447,14.723 L 13.447,12.723 A 0.5,0.5 0 0 0 12.977,11.994 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1016 B |
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<defs>
|
||||
<style id="current-color-scheme" type="text/css">
|
||||
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0.004 C 5.9289,0.004 4.1653,1.2719 3.4062,3.0665 1.4784,3.3531 0,4.9964 0,7.004 0,9.213 1.7909,11.004 4,11.004 H 12.5 C 14.433,11.004 16,9.437 16,7.504 16,5.7075 14.649,4.2353 12.906,4.0353 12.452,1.7419 10.427,0.004 8,0.004 Z M 3.4785,11.992 A 0.50005,0.50005 0 0 0 3.0527,12.275 L 2.0527,14.275 A 0.50025,0.50025 0 0 0 2.9473,14.723 L 3.9473,12.723 A 0.50005,0.50005 0 0 0 3.4785,11.992 Z M 6.4785,11.994 A 0.50005,0.50005 0 0 0 6.0527,12.277 L 5.0527,14.277 A 0.50025,0.50025 0 1 0 5.9473,14.725 L 6.9473,12.725 A 0.50005,0.50005 0 0 0 6.4785,11.994 Z M 11,12 A 1,1 0 0 0 10,13 1,1 0 0 0 11,14 1,1 0 0 0 12,13 1,1 0 0 0 11,12 Z M 9,14 A 1,1 0 0 0 8,15 1,1 0 0 0 9,16 1,1 0 0 0 10,15 1,1 0 0 0 9,14 Z M 13,14 A 1,1 0 0 0 12,15 1,1 0 0 0 13,16 1,1 0 0 0 14,15 1,1 0 0 0 13,14 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<defs>
|
||||
<style id="current-color-scheme" type="text/css">
|
||||
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0 C 5.9289,0 4.1653,1.2679 3.4062,3.0625 1.4784,3.3491 0,4.9924 0,7 0,9.209 1.7909,11 4,11 H 5.1855 C 5.6024,9.842 6.7062,9 8,9 9.294,9 10.398,9.842 10.814,11 H 12.5 C 14.433,11 16,9.433 16,7.5 16,5.7035 14.649,4.2313 12.906,4.0312 12.452,1.7379 10.427,0 8,0 Z M 8,10 A 2,2 0 0 0 6,12 2,2 0 0 0 8,14 2,2 0 0 0 10,12 2,2 0 0 0 8,10 Z M 3,12 A 2,2 0 0 0 1,14 2,2 0 0 0 3,16 2,2 0 0 0 5,14 2,2 0 0 0 3,12 Z M 13,12 A 2,2 0 0 0 11,14 2,2 0 0 0 13,16 2,2 0 0 0 15,14 2,2 0 0 0 13,12 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 929 B |
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<defs>
|
||||
<style id="current-color-scheme" type="text/css">
|
||||
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0.004 C 5.9289,0.004 4.1653,1.2719 3.4062,3.0665 1.4784,3.3531 0,4.9964 0,7.004 0,9.213 1.7909,11.004 4,11.004 H 12.5 C 14.433,11.004 16,9.437 16,7.504 16,5.7075 14.649,4.2353 12.906,4.0353 12.452,1.7419 10.427,0.004 8,0.004 Z M 4,12 A 1,1 0 0 0 3,13 1,1 0 0 0 4,14 1,1 0 0 0 5,13 1,1 0 0 0 4,12 Z M 8,12 A 1,1 0 0 0 7,13 1,1 0 0 0 8,14 1,1 0 0 0 9,13 1,1 0 0 0 8,12 Z M 12,12 A 1,1 0 0 0 11,13 1,1 0 0 0 12,14 1,1 0 0 0 13,13 1,1 0 0 0 12,12 Z M 2,14 A 1,1 0 0 0 1,15 1,1 0 0 0 2,16 1,1 0 0 0 3,15 1,1 0 0 0 2,14 Z M 6,14 A 1,1 0 0 0 5,15 1,1 0 0 0 6,16 1,1 0 0 0 7,15 1,1 0 0 0 6,14 Z M 10,14 A 1,1 0 0 0 9,15 1,1 0 0 0 10,16 1,1 0 0 0 11,15 1,1 0 0 0 10,14 Z M 14,14 A 1,1 0 0 0 13,15 1,1 0 0 0 14,16 1,1 0 0 0 15,15 1,1 0 0 0 14,14 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<defs>
|
||||
<style id="current-color-scheme" type="text/css">
|
||||
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-NeutralText { color:#ff9800; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NegativeText { color:#f44336; }
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor" class="ColorScheme-Text" d="M 8,0 C 5.93,0 4.17,1.27 3.41,3.07 1.48,3.35 0,5 0,7 0,9.21 1.79,11 4,11 L 6,11 6,8.5 C 6,7.67 6.67,7 7.5,7 8.33,7 9,7.67 9,8.5 l 0,2.5 3.5,0 C 14.43,11 16,9.44 16,7.5 16,5.71 14.65,4.23 12.91,4.03 12.45,1.74 10.43,0 8,0 Z"/>
|
||||
<path style="fill:currentColor" class="ColorScheme-Highlight" d="m 7.34,8.029287 c -0.2,0.07 -0.35,0.28 -0.34,0.5 l 0,3.78 -0.03,0.09 -0.63,0.63 -0.03,0 -1.81,0 -0.22,0 -0.12,0.16 -1,1 c -0.26,0.15 -0.31,0.56 -0.1,0.78 0.22,0.21 0.63,0.16 0.78,-0.1 l 0.85,-0.84 1.31,0 0,1.4 c 0,0.26 0.24,0.51 0.5,0.51 0.26,0 0.5,-0.25 0.5,-0.51 l 0,-1.71 0.69,-0.69 2.12,0 0.75,0.75 -1.4,1.31 c -0.26,0.15 -0.31,0.56 -0.1,0.78 0.22,0.21 0.63,0.16 0.78,-0.1 l 1.41,-1.3 1.41,1.3 c 0.15,0.26 0.56,0.31 0.78,0.1 0.21,-0.22 0.16,-0.63 -0.1,-0.78 l -3,-2.9 -0.12,-0.16 -0.22,0 -2,0 0,-3.5 c 0,-0.3 -0.3,-0.56 -0.59,-0.5 z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
|
||||
<path style="fill:#dfdfdf" d="M 8,16 C 8,16 7,16 7,15 7,14 8,14 8,14 8,14 9,14 9,13 9,12 8,12 8,12 H 1 C 1,12 0,12 0,11 0,10 1,10 1,10 H 8 C 8,10 11,10 11,13 11,16 8,16 8,16 Z M 13,3 C 13,3 12,3 12,4 12,5 13,5 13,5 13,5 14,5 14,6 14,7 13,7 13,7 H 5 C 5,7 4,7 4,8 4,9 5,9 5,9 H 13 C 13,9 16,9 16,6 16,3 13,3 13,3 Z M 8,0 C 8,0 7,0 7,1 7,2 8,2 8,2 8,2 9,2 9,3 9,4 8,4 8,4 H 1 C 1,4 0,4 0,5 0,6 1,6 1,6 H 8 C 8,6 11,6 11,3 11,0 8,0 8,0 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 524 B |