!qol(restructure): heavy restructure
4
modules/blender/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
38
modules/blender/home.nix
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
pkgs,
|
||||
home,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
let
|
||||
blenderPkgs = inputs.nix-warez.packages.${system};
|
||||
cfg = config.modules.blender;
|
||||
blender_4_5 = pkgs.blender.overrideAttrs (
|
||||
final: prev: {
|
||||
pname = "blender";
|
||||
version = "4.5.0";
|
||||
src = pkgs.fetchzip {
|
||||
name = "source";
|
||||
url = "https://download.blender.org/source/blender-${final.version}.tar.xz";
|
||||
hash = "sha256-DNVZUZpysCyB/Xt8yB352gO+UK8Cd4aDFGYuUDKyIrs=";
|
||||
};
|
||||
patches = [ ];
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
options.modules.blender = {
|
||||
enable = lib.mkEnableOption "Blender configuration module";
|
||||
};
|
||||
# whole blender config including addons is too fat to include here
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [
|
||||
blender_4_5
|
||||
];
|
||||
};
|
||||
# nix'ing a blender config is most likely not possible
|
||||
# could probs install blender addons through nix since they are fat fat mega fat to install TODO
|
||||
}
|
||||
4
modules/bottles/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
25
modules/bottles/home.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
pkgs,
|
||||
home,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.bottles;
|
||||
in
|
||||
{
|
||||
options.modules.bottles = {
|
||||
enable = lib.mkEnableOption "Blender configuration module";
|
||||
};
|
||||
# whole bottles config including addons is too fat to include here
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [
|
||||
pkgs.bottles
|
||||
];
|
||||
};
|
||||
# nix'ing a bottles config is most likely not possible
|
||||
# could probs install bottles addons through nix since they are fat fat mega fat to install TODO
|
||||
}
|
||||
4
modules/chromium/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
38
modules/chromium/home.nix
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
pkgs,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.chromium;
|
||||
in
|
||||
{
|
||||
options.modules.chromium = {
|
||||
enable = lib.mkEnableOption "Chromium";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.chromium = {
|
||||
enable = true;
|
||||
extensions = [
|
||||
{ id = "ghmbeldphafepmbegfdlkpapadhbakde"; } # ProtonPass
|
||||
#{ id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } # Ublok
|
||||
{ id = "ddkjiahejlhfcafbddmgiahcphecmpfh"; } # Ublock lite
|
||||
{ id = "kpmjjdhbcfebfjgdnpjagcndoelnidfj"; } # Control panel for twitter
|
||||
{ id = "aighbdamfnndbemigjcbkdklkegkgmpl"; } # Better twitter embeds
|
||||
{ id = "enamippconapkdmgfgjchkhakpfinmaj"; } # DeArrow
|
||||
{ id = "bjcnpgekponkjpincbcoflgkdomldlnl"; } # Website Blocker
|
||||
];
|
||||
package = pkgs.chromium.override { enableWideVine = true; };
|
||||
};
|
||||
xdg.mimeApps.defaultApplications = {
|
||||
"text/html" = "chromium.desktop";
|
||||
"x-scheme-handler/http" = "chromium.desktop";
|
||||
"x-scheme-handler/https" = "chromium.desktop";
|
||||
"x-scheme-handler/about" = "chromium.desktop";
|
||||
"x-scheme-handler/unknown" = "chromium.desktop";
|
||||
};
|
||||
};
|
||||
}
|
||||
7
modules/default.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
_:
|
||||
builtins.listToAttrs (
|
||||
map (fn: {
|
||||
name = fn;
|
||||
value = import ./${fn} { };
|
||||
}) (builtins.filter (fn: fn != "default.nix") (builtins.attrNames (builtins.readDir ./.)))
|
||||
)
|
||||
3
modules/direnv/default.nix
Normal file
@@ -0,0 +1,3 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
}
|
||||
21
modules/direnv/home.nix
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.direnv;
|
||||
in
|
||||
{
|
||||
options.modules.direnv = {
|
||||
enable = lib.mkEnableOption "direnv";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
# enableBashIntegration = true; # see note on other shells below
|
||||
nix-direnv.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
4
modules/fish/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
nixos = ./nixos.nix;
|
||||
}
|
||||
48
modules/fish/home.nix
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
fetchFromGitHub,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.fish;
|
||||
in
|
||||
{
|
||||
options.modules.fish = {
|
||||
enable = lib.mkEnableOption "Fish";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.shell.enableFishIntegration = true;
|
||||
programs = {
|
||||
fish = {
|
||||
enable = true;
|
||||
shellInit = ''
|
||||
set -g theme_nerd_fonts yes
|
||||
set -g theme_color_scheme nord
|
||||
set -g theme_display_user yes
|
||||
set -g fish_color_autosuggestion 6F6578
|
||||
alias nik 'nix'
|
||||
'';
|
||||
plugins = [
|
||||
{
|
||||
name = "bobthefish";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "oh-my-fish";
|
||||
repo = "theme-bobthefish";
|
||||
rev = "e3b4d4eafc23516e35f162686f08a42edf844e40";
|
||||
sha256 = "sha256-cXOYvdn74H4rkMWSC7G6bT4wa9d3/3vRnKed2ixRnuA=";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
eza = {
|
||||
enable = true;
|
||||
enableFishIntegration = true;
|
||||
icons = "auto";
|
||||
git = true;
|
||||
extraOptions = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
20
modules/fish/nixos.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.fish;
|
||||
in
|
||||
{
|
||||
options.modules.fish = {
|
||||
enable = lib.mkEnableOption "Fish";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.defaultUserShell = pkgs.fish;
|
||||
programs.fish = {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
3
modules/git/default.nix
Normal file
@@ -0,0 +1,3 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
}
|
||||
31
modules/git/home.nix
Normal file
@@ -0,0 +1,31 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.modules.git;
|
||||
in
|
||||
{
|
||||
|
||||
options.modules.git = {
|
||||
enable = lib.mkEnableOption "git";
|
||||
};
|
||||
config.programs = lib.mkIf cfg.enable {
|
||||
git = {
|
||||
enable = true;
|
||||
settings = {
|
||||
user = {
|
||||
name = "Doloro1978";
|
||||
email = "doloroo@proton.me";
|
||||
signingKey = "089B373588540877";
|
||||
};
|
||||
commit = {
|
||||
gpgSign = true;
|
||||
};
|
||||
pull = {
|
||||
rebase = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
gpg = {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
4
modules/greetd/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
# home = ./home.nix;
|
||||
nixos = ./nixos.nix;
|
||||
}
|
||||
36
modules/greetd/nixos.nix
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.greetd;
|
||||
tuigreet = "${pkgs.tuigreet}/bin/tuigreet";
|
||||
in
|
||||
{
|
||||
options.modules.greetd = {
|
||||
enable = lib.mkEnableOption "Greetd configuration module";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
settings = {
|
||||
default_session = {
|
||||
command = "${tuigreet} --time --remember --cmd Hyprland";
|
||||
user = "greeter";
|
||||
};
|
||||
};
|
||||
};
|
||||
systemd.services.greetd.serviceConfig = {
|
||||
Type = "idle";
|
||||
StandardInput = "tty";
|
||||
StandardOutput = "tty";
|
||||
StandardError = "journal";
|
||||
|
||||
TTYReset = true;
|
||||
TTYVHangup = true;
|
||||
TTYVTDisallocate = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
3
modules/helium/default.nix
Normal file
@@ -0,0 +1,3 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
}
|
||||
30
modules/helium/home.nix
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
pkgs,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.helium;
|
||||
# packageNix = "${inputs.nixpkgs-gamescope}/pkgs/by-name/he/helium-browser/package.nix";
|
||||
# helium = inputs.nikkuss-pkgs.callPackage packageNix { };
|
||||
in
|
||||
{
|
||||
options.modules.helium = {
|
||||
enable = lib.mkEnableOption "helium";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [
|
||||
inputs.nikkuss-pkgs.packages.x86_64-linux.helium-browser
|
||||
];
|
||||
# xdg.mimeApps.defaultApplications = {
|
||||
# "text/html" = "chromium.desktop";
|
||||
# "x-scheme-handler/http" = "chromium.desktop";
|
||||
# "x-scheme-handler/https" = "chromium.desktop";
|
||||
# "x-scheme-handler/about" = "chromium.desktop";
|
||||
# "x-scheme-handler/unknown" = "chromium.desktop";
|
||||
# };
|
||||
};
|
||||
}
|
||||
4
modules/helix/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
25
modules/helix/home.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
pkgs,
|
||||
home,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.helix;
|
||||
in
|
||||
{
|
||||
options.modules.helix = {
|
||||
enable = lib.mkEnableOption "Blender configuration module";
|
||||
};
|
||||
# whole bottles config including addons is too fat to include here
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.helix = {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
# nix'ing a bottles config is most likely not possible
|
||||
# could probs install bottles addons through nix since they are fat fat mega fat to install TODO
|
||||
}
|
||||
4
modules/hyprland/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
nixos = ./nixos.nix;
|
||||
}
|
||||
104
modules/hyprland/home.nix
Normal file
@@ -0,0 +1,104 @@
|
||||
{
|
||||
inputs,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.Hyprland;
|
||||
suspend = pkgs.writeShellScript "hyprland_suspend" ''
|
||||
#!/bin/bash
|
||||
|
||||
case "$1" in
|
||||
suspend)
|
||||
killall -STOP Hyprland
|
||||
;;
|
||||
resume)
|
||||
killall -CONT Hyprland
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./settings.nix
|
||||
./runner.nix
|
||||
./screenshot.nix
|
||||
];
|
||||
options.modules.Hyprland = {
|
||||
enable = lib.mkEnableOption "Hyprland";
|
||||
};
|
||||
# TODO, split this into its own module;
|
||||
config = lib.mkIf cfg.enable {
|
||||
wayland.windowManager.hyprland = {
|
||||
enable = true;
|
||||
# set the flake package
|
||||
# settings = { };
|
||||
systemd.variables = [ "--all" ];
|
||||
package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland;
|
||||
portalPackage =
|
||||
inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.xdg-desktop-portal-hyprland;
|
||||
};
|
||||
programs = {
|
||||
wlogout = {
|
||||
enable = true;
|
||||
};
|
||||
foot = {
|
||||
enable = true;
|
||||
settings = {
|
||||
main = {
|
||||
term = "xterm-256color";
|
||||
|
||||
font = "CaskaydiaCove Nerd Font Mono:size=12";
|
||||
};
|
||||
|
||||
mouse = {
|
||||
hide-when-typing = "yes";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
systemd.user.services."hyprland_suspend" = {
|
||||
Unit = {
|
||||
Description = "Suspend hyprland";
|
||||
Before = [
|
||||
"systemd-suspend.service"
|
||||
"systemd-hibernate.service"
|
||||
"nvidia-suspend.service"
|
||||
"nvidia-hibernate.service"
|
||||
];
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [
|
||||
"systemd-suspend.service"
|
||||
"systemd-hibernate.service"
|
||||
];
|
||||
};
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${suspend} suspend";
|
||||
};
|
||||
};
|
||||
systemd.user.services."hyprland_resume" = {
|
||||
Unit = {
|
||||
Description = "Resume hyprland";
|
||||
After = [
|
||||
"systemd-suspend.service"
|
||||
"systemd-hibernate.service"
|
||||
"nvidia-resume.service"
|
||||
];
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [
|
||||
"systemd-suspend.service"
|
||||
"systemd-hibernate.service"
|
||||
];
|
||||
};
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${suspend} resume";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
48
modules/hyprland/nixos.nix
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.Hyprland;
|
||||
in
|
||||
{
|
||||
options.modules.Hyprland = {
|
||||
enable = lib.mkEnableOption "Hyprland";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.xwayland.enable = true;
|
||||
boot.kernelParams = [
|
||||
"resume=UUID=d9b81619-5772-4ac4-bcd5-552e1e784f9e"
|
||||
"resume_offset=141042944"
|
||||
];
|
||||
boot.resumeDevice = "/dev/disk/by-uuid/d9b81619-5772-4ac4-bcd5-552e1e784f9e";
|
||||
powerManagement.enable = true;
|
||||
swapDevices = [
|
||||
# [[ Hibernate ]]
|
||||
{
|
||||
device = "/var/lib/swapfile";
|
||||
size = 48 * 1024; # 48GB in MB
|
||||
}
|
||||
];
|
||||
programs.hyprland = {
|
||||
enable = true;
|
||||
# set the flake package
|
||||
package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland;
|
||||
# make sure to also set the portal package, so that they are in sync
|
||||
portalPackage =
|
||||
inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.xdg-desktop-portal-hyprland;
|
||||
};
|
||||
xdg.portal = {
|
||||
enable = true;
|
||||
extraPortals = with pkgs; [ xdg-desktop-portal-gtk ];
|
||||
};
|
||||
environment.sessionVariables.NIXOS_OZONE_WL = "1";
|
||||
nix.settings = {
|
||||
substituters = [ "https://hyprland.cachix.org" ];
|
||||
trusted-public-keys = [ "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
16
modules/hyprland/runner.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{ inputs, pkgs, ... }:
|
||||
{
|
||||
home.packages = [
|
||||
pkgs.walker
|
||||
];
|
||||
systemd.user.services.walker-deamon = {
|
||||
Install = {
|
||||
WantedBy = [ "hyprland-session.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${pkgs.writeShellScript "watch-store" ''
|
||||
walker --gapplication-service
|
||||
''}";
|
||||
};
|
||||
};
|
||||
}
|
||||
12
modules/hyprland/screenshot.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ inputs, pkgs, ... }:
|
||||
let
|
||||
|
||||
in
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
wl-clipboard
|
||||
wayfreeze
|
||||
grim
|
||||
slurp
|
||||
];
|
||||
}
|
||||
163
modules/hyprland/settings.nix
Normal file
@@ -0,0 +1,163 @@
|
||||
{ inputs, pkgs, ... }:
|
||||
{
|
||||
home.packages = [
|
||||
pkgs.hyprcursor
|
||||
pkgs.rose-pine-cursor
|
||||
];
|
||||
home.pointerCursor = {
|
||||
enable = true;
|
||||
name = "rose-pine-hyprcursor";
|
||||
package = pkgs.rose-pine-hyprcursor;
|
||||
hyprcursor.enable = true;
|
||||
};
|
||||
wayland.windowManager.hyprland.settings = {
|
||||
monitor = [
|
||||
"HDMI-A-1, 1920x1080@60, 0x0, 1"
|
||||
"DP-3, 1920x1080@144, 1920x0, 1"
|
||||
];
|
||||
exec-once = [
|
||||
"hyprctl dispatch workspace 2" # shit solution to get quickshell on the right monitor
|
||||
];
|
||||
env = [
|
||||
"XCURSOR_THEME,BreezeX-RosePine-Linux"
|
||||
"XCURSOR_SIZE,24"
|
||||
"HYPRCURSOR_SIZE,24"
|
||||
"LIBVA_DRIVER_NAME,nvidia"
|
||||
"__GLX_VENDOR_LIBRARY_NAME,nvidia"
|
||||
"WEBKIT_DISABLE_DMABUF_RENDERER,1" # maybe disable if nixos fixes alcom
|
||||
];
|
||||
general = {
|
||||
gaps_in = 1;
|
||||
gaps_out = 1;
|
||||
border_size = 1;
|
||||
# col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
|
||||
# col.inactive_border = rgba(595959aa)
|
||||
resize_on_border = false;
|
||||
allow_tearing = true;
|
||||
layout = "dwindle";
|
||||
};
|
||||
decoration = {
|
||||
rounding = 0;
|
||||
rounding_power = 1;
|
||||
active_opacity = 1.0;
|
||||
inactive_opacity = 1.0;
|
||||
|
||||
shadow = {
|
||||
enabled = false;
|
||||
};
|
||||
|
||||
blur = {
|
||||
enabled = false;
|
||||
};
|
||||
};
|
||||
animations = {
|
||||
enabled = true;
|
||||
bezier = [
|
||||
"easeOutQuint,0.23,1,0.32,1"
|
||||
"easeInOutCubic,0.65,0.05,0.36,1"
|
||||
"linear,0,0,1,1"
|
||||
"almostLinear,0.5,0.5,0.75,1.0"
|
||||
"quick,0.15,0,0.1,1"
|
||||
];
|
||||
animation = [
|
||||
"global, 1, 10, default"
|
||||
"border, 1, 5.39, easeOutQuint"
|
||||
"windows, 1, 2.79, easeOutQuint"
|
||||
"windowsIn, 1, 1.1, easeOutQuint, popin 87%"
|
||||
"windowsOut, 1, 1.49, linear, popin 87%"
|
||||
"fadeIn, 1, 1.73, almostLinear"
|
||||
"fadeOut, 1, 1.46, almostLinear"
|
||||
"fade, 1, 2.03, quick"
|
||||
"layers, 1, 3.81, easeOutQuint"
|
||||
"layersIn, 1, 4, easeOutQuint, fade"
|
||||
"layersOut, 1, 1.5, linear, fade"
|
||||
"fadeLayersIn, 1, 1.79, almostLinear"
|
||||
"fadeLayersOut, 1, 1.39, almostLinear"
|
||||
"workspaces, 1, 1.94, almostLinear, fade"
|
||||
"workspacesIn, 1, 1.21, almostLinear, fade"
|
||||
"workspacesOut, 1, 1.94, almostLinear, fade"
|
||||
"zoomFactor, 1, 7, quick"
|
||||
];
|
||||
};
|
||||
dwindle = {
|
||||
pseudotile = true;
|
||||
preserve_split = true;
|
||||
};
|
||||
# master = {
|
||||
# new_status = master;
|
||||
# };
|
||||
misc = {
|
||||
force_default_wallpaper = -1;
|
||||
disable_hyprland_logo = false;
|
||||
enable_anr_dialog = false;
|
||||
vfr = true;
|
||||
};
|
||||
input = {
|
||||
kb_layout = "gb";
|
||||
follow_mouse = 2;
|
||||
sensitivity = -0.5;
|
||||
};
|
||||
"$mainMod" = "SUPER";
|
||||
bind = [
|
||||
"$mainMod, Q, exec, foot"
|
||||
"$mainMod, C, killactive"
|
||||
"$mainMod, M, exit"
|
||||
"$mainMod, E, exec, $fileManager"
|
||||
"$mainMod, V, togglefloating,"
|
||||
"$mainMod, R, exec, walker"
|
||||
"$mainMod, P, pseudo, # dwindle"
|
||||
"$mainMod, J, togglesplit, # dwindle"
|
||||
"$mainMod, left, movefocus, l"
|
||||
"$mainMod, right, movefocus, r"
|
||||
"$mainMod, up, movefocus, u"
|
||||
"$mainMod, down, movefocus, d"
|
||||
"$mainMod, L, exec, wlogout"
|
||||
(
|
||||
"$mainMod, S, exec, "
|
||||
+ ''wayfreeze --after-freeze-cmd 'grim -g "$(slurp -d)" - | wl-copy -t image/png;killall wayfreeze' --hide-cursor''
|
||||
)
|
||||
"$mainMod, F, fullscreen"
|
||||
"$mainMod, mouse_down, workspace, e+1"
|
||||
"$mainMod, mouse_up, workspace, e-1"
|
||||
", home, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
|
||||
", end, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
|
||||
", F8, pass, class:^(com\.obsproject\.Studio)$"
|
||||
"$mainMod, 0, workspace, 10"
|
||||
"$mainMod SHIFT, 0, movetoworkspace, 10"
|
||||
]
|
||||
++ (builtins.concatLists (
|
||||
builtins.genList (
|
||||
i:
|
||||
let
|
||||
ws = i + 1;
|
||||
in
|
||||
[
|
||||
"$mainMod, ${toString ws}, workspace, ${toString ws}"
|
||||
"$mainMod SHIFT, ${toString ws}, movetoworkspace, ${toString ws}"
|
||||
]
|
||||
) 9
|
||||
));
|
||||
bindm = [
|
||||
"$mainMod, mouse:272, movewindow"
|
||||
"$mainMod, mouse:273, resizewindow"
|
||||
];
|
||||
workspace = [
|
||||
"name:2, monitor:DP-3"
|
||||
];
|
||||
windowrule = [
|
||||
"match:class .*, suppress_event maximize"
|
||||
"match:class ^(gamescope)$, workspace 5"
|
||||
"match:class ^(gamescope)$, fullscreen true"
|
||||
"match:class ^(gamescope)$, immediate true"
|
||||
"match:class ^(steam)$, workspace 6 silent"
|
||||
"match:class ^(vesktop)$, workspace 8 silent"
|
||||
"match:class ^(org.telegram.desktop)$, workspace 8 silent"
|
||||
"match:class ^(com.obsproject.Studio)$, workspace 10 silent"
|
||||
"match:initial_title ^(OBS Studio Crash Detected)$, pin true"
|
||||
"match:initial_title ^(Discord Popout)$, workspace 1 silent"
|
||||
];
|
||||
# exec-once = [
|
||||
# ];
|
||||
# we need to auto launch: quickshell, steam, ar_rpc (maybe), vesktop, telegram, qbit, and obs
|
||||
};
|
||||
}
|
||||
4
modules/nixvim/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos = ./nixos.nix;
|
||||
}
|
||||
226
modules/nixvim/home.nix
Normal file
@@ -0,0 +1,226 @@
|
||||
{
|
||||
config,
|
||||
inputs,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.nixvim;
|
||||
in
|
||||
{
|
||||
options.modules.nixvim = {
|
||||
enable = lib.mkEnableOption "Nixvim";
|
||||
};
|
||||
imports = [
|
||||
inputs.nixvim.homeModules.nixvim
|
||||
./plugins
|
||||
];
|
||||
config.home.packages = with pkgs; [
|
||||
# formatters
|
||||
nixfmt
|
||||
rustfmt
|
||||
# misc
|
||||
ripgrep
|
||||
# misc
|
||||
nixd
|
||||
];
|
||||
config.programs.nixvim = lib.mkIf cfg.enable {
|
||||
enable = true;
|
||||
defaultEditor = true;
|
||||
colorschemes.tokyonight.enable = true;
|
||||
performance.byteCompileLua = {
|
||||
enable = true;
|
||||
plugins = true;
|
||||
nvimRuntime = true;
|
||||
luaLib = true;
|
||||
configs = true;
|
||||
};
|
||||
plugins = {
|
||||
lsp-status.enable = true;
|
||||
lsp = {
|
||||
enable = true;
|
||||
servers = {
|
||||
rust_analyzer = {
|
||||
enable = true;
|
||||
installCargo = false;
|
||||
installRustc = false;
|
||||
};
|
||||
nixd = {
|
||||
enable = true;
|
||||
};
|
||||
astro = {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
notify.enable = true;
|
||||
mini-cursorword.enable = true;
|
||||
# mini-statusline.enable = true;
|
||||
lualine = {
|
||||
enable = true;
|
||||
settings = {
|
||||
sections = {
|
||||
lualine_a = [ "mode" ];
|
||||
lualine_b = [
|
||||
"branch"
|
||||
"diff"
|
||||
"diagnostics"
|
||||
];
|
||||
lualine_c = [ "filename" ];
|
||||
lualine_x = [
|
||||
"encoding"
|
||||
"fileformat"
|
||||
"filetype"
|
||||
];
|
||||
lualine_y = [ "lsp_status" ];
|
||||
lualine_z = [ "location" ];
|
||||
};
|
||||
inactive_sections = {
|
||||
lualine_a = [ ];
|
||||
lualine_b = [ ];
|
||||
lualine_c = [ "filename" ];
|
||||
lualine_x = [ "location" ];
|
||||
lualine_y = [ ];
|
||||
lualine_z = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
web-devicons.enable = true;
|
||||
vim-dadbod-completion.enable = true;
|
||||
telescope.enable = true;
|
||||
lazygit.enable = true;
|
||||
mini-indentscope = {
|
||||
enable = true;
|
||||
settings = {
|
||||
draw = {
|
||||
delay = 10;
|
||||
};
|
||||
};
|
||||
};
|
||||
mini-files = {
|
||||
enable = true;
|
||||
};
|
||||
trouble.enable = true;
|
||||
cmp = {
|
||||
enable = true;
|
||||
autoEnableSources = true;
|
||||
settings = {
|
||||
sources = [
|
||||
{ name = "nvim_lsp"; }
|
||||
{ name = "path"; }
|
||||
{ name = "buffer"; }
|
||||
];
|
||||
mapping = {
|
||||
"<C-Space>" = "cmp.mapping.complete()";
|
||||
"<C-d>" = "cmp.mapping.scroll_docs(-4)";
|
||||
"<C-e>" = "cmp.mapping.close()";
|
||||
"<C-f>" = "cmp.mapping.scroll_docs(4)";
|
||||
"<CR>" = "cmp.mapping.confirm({ select = true })";
|
||||
"<S-Tab>" = "cmp.mapping(cmp.mapping.select_prev_item(), {'i', 's'})";
|
||||
"<Tab>" = "cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'})";
|
||||
};
|
||||
};
|
||||
};
|
||||
lspkind.enable = true;
|
||||
# persisted.enable = true;
|
||||
auto-session = {
|
||||
enable = true;
|
||||
settings = {
|
||||
enabled = true;
|
||||
auto_save = true;
|
||||
auto_restore = true;
|
||||
};
|
||||
};
|
||||
wakatime.enable = true;
|
||||
treesitter = {
|
||||
enable = true;
|
||||
grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [
|
||||
bash
|
||||
json
|
||||
lua
|
||||
make
|
||||
markdown
|
||||
nix
|
||||
regex
|
||||
toml
|
||||
vim
|
||||
vimdoc
|
||||
xml
|
||||
yaml
|
||||
];
|
||||
settings = {
|
||||
highlight.enable = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
extraPlugins = with pkgs; [
|
||||
# vimPlugins.mini-completion
|
||||
vimPlugins.mini-comment
|
||||
vimPlugins.melange-nvim
|
||||
vimPlugins.telescope-file-browser-nvim
|
||||
vimPlugins.lsp-progress-nvim
|
||||
];
|
||||
opts = {
|
||||
number = true;
|
||||
bg = "dark";
|
||||
tabstop = 2;
|
||||
shiftwidth = 2;
|
||||
termguicolors = true;
|
||||
};
|
||||
globals = {
|
||||
mapleader = " ";
|
||||
};
|
||||
keymaps = [
|
||||
{
|
||||
action = "<cmd>Telescope persisted<cr>";
|
||||
key = "<leader>fs";
|
||||
options = {
|
||||
silent = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
action = "<cmd>Telescope find_files<cr>";
|
||||
key = "<leader>ff";
|
||||
options = {
|
||||
silent = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
action = "<cmd>:lua MiniFiles.open()<cr>";
|
||||
key = "<leader>fv";
|
||||
options = {
|
||||
silent = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
action = "<cmd>LazyGit<cr>";
|
||||
key = "<leader>lg";
|
||||
options = {
|
||||
silent = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
action = "<cmd>Telescope buffers<cr>";
|
||||
key = "<leader>fb";
|
||||
options = {
|
||||
silent = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
action = "<cmd>Telescope live_grep<cr>";
|
||||
key = "<leader>fg";
|
||||
options = {
|
||||
silent = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
action = "<cmd>Trouble diagnostics toggle<cr>";
|
||||
key = "<leader>fd";
|
||||
options = {
|
||||
silent = true;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
25
modules/nixvim/plugins/conform.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{ ... }:
|
||||
{
|
||||
programs.nixvim = {
|
||||
plugins = {
|
||||
conform-nvim = {
|
||||
enable = true;
|
||||
settings = {
|
||||
formatters_by_ft = {
|
||||
nix = [ "nixfmt" ];
|
||||
rust = [ "rustfmt" ];
|
||||
"_" = [
|
||||
"squeeze_blanks"
|
||||
"trim_whitespace"
|
||||
"trim_newlines"
|
||||
];
|
||||
};
|
||||
format_on_save = {
|
||||
timeout_ms = 500;
|
||||
lsp_format = "fallback";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
5
modules/nixvim/plugins/default.nix
Normal file
@@ -0,0 +1,5 @@
|
||||
_: {
|
||||
imports = [
|
||||
./conform.nix
|
||||
];
|
||||
}
|
||||
4
modules/nixvim/plugins/mini/notify.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
|
||||
}
|
||||
4
modules/obs/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
68
modules/obs/home.nix
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
inputs,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.obs;
|
||||
in
|
||||
{
|
||||
options.modules.obs = {
|
||||
enable = lib.mkEnableOption "obs";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs = {
|
||||
obs-studio = {
|
||||
enable = true;
|
||||
package = (
|
||||
pkgs.obs-studio.override {
|
||||
cudaSupport = true;
|
||||
}
|
||||
);
|
||||
plugins = with pkgs.obs-studio-plugins; [
|
||||
obs-pipewire-audio-capture
|
||||
obs-vkcapture
|
||||
];
|
||||
};
|
||||
};
|
||||
systemd.user.services.pw-discordaudio-virtual-device = {
|
||||
Install = {
|
||||
WantedBy = [ "hyprland-session.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${pkgs.writeShellScript "discord_audio_virt_device" ''
|
||||
#!/run/current-system/sw/bin/bash
|
||||
pw-loopback -m '[ FL FR]' --capture-props='media.class=Audio/Sink node.name=DiscordSink' -n DiscordSink
|
||||
''}";
|
||||
};
|
||||
};
|
||||
systemd.user.services.pw-gameaudio-virtual-device = {
|
||||
Install = {
|
||||
WantedBy = [ "hyprland-session.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${pkgs.writeShellScript "game_audio_virt_device" ''
|
||||
#!/run/current-system/sw/bin/bash
|
||||
pw-loopback -m '[ FL FR]' --capture-props='media.class=Audio/Sink node.name=GameAudioSink' -n GameAudioSink
|
||||
''}";
|
||||
};
|
||||
};
|
||||
systemd.user.services.obs-autostart = lib.mkIf cfg.enable {
|
||||
Unit = {
|
||||
Description = "OBS daemon";
|
||||
After = [ "hyprland-session.target" ];
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
Service = {
|
||||
# wait for hyprland to start
|
||||
ExecStart = "${config.programs.obs-studio.finalPackage}/bin/obs --startreplaybuffer";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5s";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
4
modules/quickshell/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
35
modules/quickshell/home.nix
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
inputs,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
let
|
||||
pkg = inputs.quickshell.packages.${system}.quickshell;
|
||||
cfg = config.modules.quickshell;
|
||||
in
|
||||
{
|
||||
options.modules.quickshell = {
|
||||
enable = lib.mkEnableOption "quickshell configuration module";
|
||||
};
|
||||
config.xdg.configFile."quickshell" = lib.mkIf cfg.enable {
|
||||
recursive = true;
|
||||
source = config.lib.file.mkOutOfStoreSymlink "./quickshell";
|
||||
};
|
||||
config.systemd.user.services.quickshell = lib.mkIf cfg.enable {
|
||||
Unit = {
|
||||
Description = "Quickshell daemon";
|
||||
After = [ "hyprland-session.target" ];
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${pkg}/bin/quickshell";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5s";
|
||||
};
|
||||
};
|
||||
}
|
||||
1
modules/quickshell/quickshell/assets/bar/Mic.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M480-420q-41.92 0-70.96-29.04Q380-478.08 380-520v-240q0-41.92 29.04-70.96Q438.08-860 480-860q41.92 0 70.96 29.04Q580-801.92 580-760v240q0 41.92-29.04 70.96Q521.92-420 480-420Zm-30 290v-131.85q-99-11.31-164.5-84.92Q220-420.39 220-520h60q0 83 58.5 141.5T480-320q83 0 141.5-58.5T680-520h60q0 99.61-65.5 173.23Q609-273.16 510-261.85V-130h-60Z"/></svg>
|
||||
|
After Width: | Height: | Size: 463 B |
1
modules/quickshell/quickshell/assets/bar/MutedMic.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#EA3323"><path d="m710-362-58-58q14-23 21-48t7-52h80q0 44-13 83.5T710-362ZM592-482 360-714v-46q0-50 35-85t85-35q50 0 85 35t35 85v240q0 11-2.5 20t-5.5 18ZM440-120v-124q-104-14-172-92.5T200-520h80q0 83 58.5 141.5T480-320q34 0 64.5-10.5T600-360l57 57q-29 23-63.5 38.5T520-244v124h-80Zm352 64L56-792l56-56 736 736-56 56Z"/></svg>
|
||||
|
After Width: | Height: | Size: 424 B |
1
modules/quickshell/quickshell/assets/bar/MutedSpeaker.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#EA3323"><path d="M792-56 671-177q-25 16-53 27.5T560-131v-82q14-5 27.5-10t25.5-12L480-368v208L280-360H120v-240h128L56-792l56-56 736 736-56 56Zm-8-232-58-58q17-31 25.5-65t8.5-70q0-94-55-168T560-749v-82q124 28 202 125.5T840-481q0 53-14.5 102T784-288ZM650-422l-90-90v-130q47 22 73.5 66t26.5 96q0 15-2.5 29.5T650-422ZM480-592 376-696l104-104v208Z"/></svg>
|
||||
|
After Width: | Height: | Size: 450 B |
1
modules/quickshell/quickshell/assets/bar/Speaker.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M561.54-155.62v-62q86.54-27.53 139.42-100 52.89-72.46 52.89-163.38t-52.89-163.38q-52.88-72.47-139.42-100v-62q111.69 29.92 182 119.92 70.3 90 70.3 205.46 0 115.46-70.3 205.46-70.31 90-182 119.92ZM146.16-380v-200h148.46l171.53-171.53v543.06L294.62-380H146.16Zm415.38 46.15v-294.3q40.46 22 62.54 61.96 22.07 39.96 22.07 86.19 0 45.61-22.27 84.88-22.27 39.27-62.34 61.27Z"/></svg>
|
||||
|
After Width: | Height: | Size: 492 B |
1
modules/quickshell/quickshell/assets/media_player/pausebutton.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M560-200v-560h160v560H560Zm-320 0v-560h160v560H240Z"/></svg>
|
||||
|
After Width: | Height: | Size: 176 B |
1
modules/quickshell/quickshell/assets/media_player/playbutton.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M320-200v-560l440 280-440 280Z"/></svg>
|
||||
|
After Width: | Height: | Size: 155 B |
1
modules/quickshell/quickshell/assets/media_player/skip_next.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M660-240v-480h80v480h-80Zm-440 0v-480l360 240-360 240Z"/></svg>
|
||||
|
After Width: | Height: | Size: 179 B |
1
modules/quickshell/quickshell/assets/media_player/skip_previous.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M220-240v-480h80v480h-80Zm520 0L380-480l360-240v480Z"/></svg>
|
||||
|
After Width: | Height: | Size: 177 B |
76
modules/quickshell/quickshell/bar/Bar.qml
Executable file
@@ -0,0 +1,76 @@
|
||||
//@ pragma UseQApplication
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Hyprland
|
||||
|
||||
import "widgets" as Widgets
|
||||
import "widgets/player" as Player
|
||||
import "widgets/common" as Common
|
||||
import "widgets/clock" as Clock
|
||||
import "widgets/workspace" as Workspace
|
||||
|
||||
// Tako kindly threatened you to sort the naming schema and to put all the svg's in an asset folder, so please do that
|
||||
|
||||
PanelWindow {
|
||||
property var modelData
|
||||
screen: modelData.values[0];
|
||||
|
||||
color: '#20ffffff'
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
implicitHeight: 32
|
||||
RowLayout {
|
||||
height: 28
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
// bottomMargin: 2
|
||||
leftMargin: 10
|
||||
rightMargin: 10
|
||||
}
|
||||
RowLayout { // Left
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Clock.Date {}
|
||||
Clock.Clock {}
|
||||
Workspace.WorkspaceWidget {}
|
||||
}
|
||||
RowLayout { // Center
|
||||
// TODO: add icons of the active window per workspace in the workspace tab
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
RowLayout { // Right
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Loader {
|
||||
sourceComponent: Widgets.Audio {}
|
||||
}
|
||||
RowLayout {
|
||||
Text {
|
||||
text: HyprlandWindowTracker.HyprlandWindowTracker.aaaa
|
||||
}
|
||||
visible: Player.activePlayer.isPlaying()
|
||||
Player.PlayerWidgetV2 {
|
||||
}
|
||||
}
|
||||
Widgets.SystemTray {
|
||||
id: systemTray
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: 1
|
||||
color: "#8d8d8d"
|
||||
}
|
||||
}
|
||||
60
modules/quickshell/quickshell/bar/widgets/Audio.qml
Executable file
@@ -0,0 +1,60 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Pipewire
|
||||
import "common" as Common
|
||||
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property PwNode speakerNode: Pipewire.defaultAudioSink
|
||||
property PwNode microphoneNode: Pipewire.defaultAudioSource
|
||||
PwObjectTracker { objects: [ root.microphoneNode, root.speakerNode ] }
|
||||
|
||||
width: row.width
|
||||
height: row.height
|
||||
|
||||
// console.log("a");
|
||||
|
||||
RowLayout {
|
||||
id: row
|
||||
Item {
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
radius: 7
|
||||
color: "black"
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
// implicitSize: 25
|
||||
font.pixelSize: 28
|
||||
color: root.speakerNode.audio.muted ? "#FF474C" : "white"
|
||||
font.family: "CaskaydiaCove Nerd Font Mono"
|
||||
text: root.speakerNode.audio.muted ? Common.Icons.audioIcons.speakerMuted : Common.Icons.audioIcons.speaker
|
||||
}
|
||||
}
|
||||
Item {
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
radius: 7
|
||||
color: "black"
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
// implicitSize: 25
|
||||
font.pixelSize: 34
|
||||
color: root.microphoneNode.audio.muted ? "#FF474C" : "white"
|
||||
font.family: "CaskaydiaCove Nerd Font Mono"
|
||||
text: root.microphoneNode.audio.muted ? Common.Icons.audioIcons.microphoneMuted : Common.Icons.audioIcons.microphone
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
modules/quickshell/quickshell/bar/widgets/SystemTray.qml
Executable file
@@ -0,0 +1,63 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
import QtQuick.Effects
|
||||
|
||||
import Quickshell.Services.SystemTray
|
||||
|
||||
Item {
|
||||
id: root
|
||||
Layout.preferredHeight: 30
|
||||
Layout.preferredWidth: layout.implicitWidth
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
id: layout
|
||||
Repeater {
|
||||
model: SystemTray.items
|
||||
delegate: Item {
|
||||
required property SystemTrayItem modelData
|
||||
id: item
|
||||
Layout.preferredHeight: 30
|
||||
Layout.preferredWidth: 30
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
onPressed: event => {
|
||||
item.modelData.display(trayItemPopupWindow, mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
IconImage {
|
||||
anchors.centerIn: parent
|
||||
implicitSize: 20
|
||||
source: modelData.icon
|
||||
}
|
||||
PopupWindow {
|
||||
// hacky ass way to get a tray item popup window
|
||||
implicitHeight: 1
|
||||
implicitWidth: 1
|
||||
color: "transparent"
|
||||
id: trayItemPopupWindow
|
||||
anchor.item: item
|
||||
visible: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
z: -1
|
||||
anchors {
|
||||
left: root.left
|
||||
right: root.right
|
||||
verticalCenter: root.verticalCenter
|
||||
}
|
||||
height: root.height - 5
|
||||
radius: 6
|
||||
color: "black"
|
||||
}
|
||||
}
|
||||
45
modules/quickshell/quickshell/bar/widgets/Workspaces.qml
Executable file
@@ -0,0 +1,45 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Hyprland
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
spacing: 3
|
||||
|
||||
Repeater {
|
||||
model: Hyprland.workspaces
|
||||
delegate: Item {
|
||||
required property int index
|
||||
property HyprlandWorkspace index_workspace: Hyprland.workspaces.values[index]
|
||||
width: 25
|
||||
height: 30
|
||||
MouseArea {
|
||||
Rectangle {
|
||||
id: reg
|
||||
anchors.fill: parent
|
||||
color: index_workspace.focused ? "#3B3B3B" : "#808080"
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: index_workspace.id
|
||||
color: "#FFFFFF"
|
||||
font.pointSize: 10.75
|
||||
}
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onPressed: event => {
|
||||
if (event.button === Qt.LeftButton) {
|
||||
Hyprland.dispatch('workspace ' + index_workspace.id);
|
||||
}
|
||||
for (x in index_workspace.toplevels.values) {
|
||||
console.log(index_workspace.toplevels.values[x].title)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
modules/quickshell/quickshell/bar/widgets/clock/Clock.qml
Executable file
@@ -0,0 +1,19 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
import "../common" as Common
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: text.width + 15
|
||||
height: text.height
|
||||
Common.Container {}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
id: text
|
||||
text: ClockData.time
|
||||
font.pointSize: 10.25
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
22
modules/quickshell/quickshell/bar/widgets/clock/ClockData.qml
Executable file
@@ -0,0 +1,22 @@
|
||||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
readonly property string time: {
|
||||
// Qt.formatDateTime(clock.date, "ddd d MMM [hh:mm]")
|
||||
Qt.formatDateTime(clock.date, "hh:mm")
|
||||
}
|
||||
readonly property string date: {
|
||||
Qt.formatDateTime(clock.date, "d MMM")
|
||||
// Qt.formatDateTime(clock.date, "hh:mm")
|
||||
}
|
||||
|
||||
SystemClock {
|
||||
id: clock
|
||||
precision: SystemClock.Minutes
|
||||
}
|
||||
}
|
||||
19
modules/quickshell/quickshell/bar/widgets/clock/Date.qml
Executable file
@@ -0,0 +1,19 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
import "../common" as Common
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: text.width + 15
|
||||
height: text.height
|
||||
Common.Container {}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
id: text
|
||||
text: ClockData.date
|
||||
font.pointSize: 10.25
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
12
modules/quickshell/quickshell/bar/widgets/common/Colors.qml
Executable file
@@ -0,0 +1,12 @@
|
||||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property var colors: ({
|
||||
"primary": "",
|
||||
})
|
||||
}
|
||||
13
modules/quickshell/quickshell/bar/widgets/common/Container.qml
Executable file
@@ -0,0 +1,13 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
|
||||
Rectangle {
|
||||
z: -1
|
||||
color: "black"
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
height: 25
|
||||
width: parent.width
|
||||
radius: 7
|
||||
}
|
||||
8
modules/quickshell/quickshell/bar/widgets/common/Dot.qml
Executable file
@@ -0,0 +1,8 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
|
||||
Text {
|
||||
text: "•"
|
||||
color: "white"
|
||||
font.pointSize: 12.5
|
||||
}
|
||||
30
modules/quickshell/quickshell/bar/widgets/common/Icons.qml
Executable file
@@ -0,0 +1,30 @@
|
||||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property var audioIcons: ({
|
||||
microphone: "",
|
||||
microphoneMuted: "",
|
||||
speaker: "",
|
||||
speakerMuted: "",
|
||||
})
|
||||
|
||||
// {class}: {icon}
|
||||
readonly property var appIcons: ({
|
||||
"vesktop": "",
|
||||
"steam": "",
|
||||
"org.telegram.desktop": "",
|
||||
"chromium": "",
|
||||
"dev.zed.Zed": "",
|
||||
"foot": "",
|
||||
"gamescope": "",
|
||||
"blender": "",
|
||||
"Spotify": "",
|
||||
"Unity": "",
|
||||
"fallback": ""
|
||||
})
|
||||
}
|
||||
17
modules/quickshell/quickshell/bar/widgets/common/MaterialIcon.qml
Executable file
@@ -0,0 +1,17 @@
|
||||
// import qs.services
|
||||
// import qs.config
|
||||
import "text" as Text
|
||||
|
||||
Text.StyledText {
|
||||
property real fill
|
||||
property int grade: Colours.light ? 0 : -25
|
||||
|
||||
font.family: Appearance.font.family.material
|
||||
font.pointSize: Appearance.font.size.larger
|
||||
font.variableAxes: ({
|
||||
FILL: fill.toFixed(1),
|
||||
GRAD: grade,
|
||||
opsz: fontInfo.pixelSize,
|
||||
wght: fontInfo.weight
|
||||
})
|
||||
}
|
||||
9
modules/quickshell/quickshell/bar/widgets/common/Meow.qml
Executable file
@@ -0,0 +1,9 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
function iconFromDesktopfile(location): String { // testing // serves no purpose atm
|
||||
return "/usr/share/pixmaps/spotify-client.png"
|
||||
return "/usr/share/pixmaps/" + DesktopEntries.byId(location).icon + ".png"
|
||||
}
|
||||
}
|
||||
13
modules/quickshell/quickshell/bar/widgets/common/VerticalSeprator.qml
Executable file
@@ -0,0 +1,13 @@
|
||||
import Quickshell
|
||||
import QtQml
|
||||
import QtQuick
|
||||
|
||||
Rectangle {
|
||||
id: a
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
width: 2
|
||||
color: "#8d8d8d"
|
||||
}
|
||||
54
modules/quickshell/quickshell/bar/widgets/common/text/StyledText.qml
Executable file
@@ -0,0 +1,54 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
// https://github.com/caelestia-dots/shell/blob/a23bb48c243348096b27f5f4ac94f663271ece10/widgets/StyledText.qml
|
||||
|
||||
// import qs.services
|
||||
// import qs.config
|
||||
import QtQuick
|
||||
|
||||
Text {
|
||||
id: root
|
||||
|
||||
property bool animate: false
|
||||
property string animateProp: "scale"
|
||||
property real animateFrom: 0
|
||||
property real animateTo: 1
|
||||
property int animateDuration: Appearance.anim.durations.normal
|
||||
|
||||
renderType: Text.NativeRendering
|
||||
textFormat: Text.PlainText
|
||||
color: Colours.palette.m3onSurface
|
||||
font.family: Appearance.font.family.sans
|
||||
font.pointSize: Appearance.font.size.smaller
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Appearance.anim.durations.normal
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Appearance.anim.curves.standard
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on text {
|
||||
enabled: root.animate
|
||||
|
||||
SequentialAnimation {
|
||||
Anim {
|
||||
to: root.animateFrom
|
||||
easing.bezierCurve: Appearance.anim.curves.standardAccel
|
||||
}
|
||||
PropertyAction {}
|
||||
Anim {
|
||||
to: root.animateTo
|
||||
easing.bezierCurve: Appearance.anim.curves.standardDecel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component Anim: NumberAnimation {
|
||||
target: root
|
||||
property: root.animateProp
|
||||
duration: root.animateDuration / 2
|
||||
easing.type: Easing.BezierSpline
|
||||
}
|
||||
}
|
||||
173
modules/quickshell/quickshell/bar/widgets/player/PlayerController.qml
Executable file
@@ -0,0 +1,173 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQml.Models
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Services.Mpris
|
||||
// import qs
|
||||
|
||||
Singleton {
|
||||
id: root;
|
||||
property MprisPlayer trackedPlayer: null;
|
||||
property MprisPlayer activePlayer: findSpotify();
|
||||
|
||||
|
||||
signal trackChanged(reverse: bool);
|
||||
|
||||
property bool __reverse: false;
|
||||
|
||||
property var activeTrack;
|
||||
|
||||
Instantiator {
|
||||
model: Mpris.players;
|
||||
|
||||
Connections {
|
||||
required property MprisPlayer modelData;
|
||||
target: modelData;
|
||||
|
||||
Component.onCompleted: {
|
||||
if (root.trackedPlayer == null || modelData.isPlaying) {
|
||||
root.trackedPlayer = modelData;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (root.trackedPlayer == null || !root.trackedPlayer.isPlaying) {
|
||||
for (const player of Mpris.players.values) {
|
||||
if (player.playbackState.isPlaying) {
|
||||
root.trackedPlayer = player;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (trackedPlayer == null && Mpris.players.values.length != 0) {
|
||||
trackedPlayer = Mpris.players.values[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onPlaybackStateChanged() {
|
||||
if (root.trackedPlayer !== modelData) root.trackedPlayer = modelData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: activePlayer
|
||||
|
||||
function onPostTrackChanged() {
|
||||
root.updateTrack();
|
||||
}
|
||||
|
||||
function onTrackArtUrlChanged() {
|
||||
console.log("arturl:", activePlayer.trackArtUrl)
|
||||
//root.updateTrack();
|
||||
if (root.activePlayer.uniqueId == root.activeTrack.uniqueId && root.activePlayer.trackArtUrl != root.activeTrack.artUrl) {
|
||||
// cantata likes to send cover updates *BEFORE* updating the track info.
|
||||
// as such, art url changes shouldn't be able to break the reverse animation
|
||||
const r = root.__reverse;
|
||||
root.updateTrack();
|
||||
root.__reverse = r;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onActivePlayerChanged: this.updateTrack();
|
||||
|
||||
function updateTrack() {
|
||||
//console.log(`update: ${this.activePlayer?.trackTitle ?? ""} : ${this.activePlayer?.trackArtists}`)
|
||||
this.activeTrack = {
|
||||
uniqueId: this.activePlayer?.uniqueId ?? 0,
|
||||
artUrl: this.activePlayer?.trackArtUrl ?? "",
|
||||
title: this.activePlayer?.trackTitle || "Unknown Title",
|
||||
artist: this.activePlayer?.trackArtist || "Unknown Artist",
|
||||
album: this.activePlayer?.trackAlbum || "Unknown Album",
|
||||
};
|
||||
|
||||
this.trackChanged(__reverse);
|
||||
this.__reverse = false;
|
||||
}
|
||||
|
||||
property bool isPlaying: this.activePlayer && this.activePlayer.isPlaying;
|
||||
property bool canTogglePlaying: this.activePlayer?.canTogglePlaying ?? false;
|
||||
function togglePlaying() {
|
||||
if (this.canTogglePlaying) this.activePlayer.togglePlaying();
|
||||
}
|
||||
|
||||
property bool canGoPrevious: this.activePlayer?.canGoPrevious ?? false;
|
||||
function previous() {
|
||||
if (this.canGoPrevious) {
|
||||
this.__reverse = true;
|
||||
this.activePlayer.previous();
|
||||
}
|
||||
}
|
||||
|
||||
property bool canGoNext: this.activePlayer?.canGoNext ?? false;
|
||||
function next() {
|
||||
if (this.canGoNext) {
|
||||
this.__reverse = false;
|
||||
this.activePlayer.next();
|
||||
}
|
||||
}
|
||||
|
||||
property bool canChangeVolume: this.activePlayer && this.activePlayer.volumeSupported && this.activePlayer.canControl;
|
||||
|
||||
property bool loopSupported: this.activePlayer && this.activePlayer.loopSupported && this.activePlayer.canControl;
|
||||
property var loopState: this.activePlayer?.loopState ?? MprisLoopState.None;
|
||||
function setLoopState(loopState: var) {
|
||||
if (this.loopSupported) {
|
||||
this.activePlayer.loopState = loopState;
|
||||
}
|
||||
}
|
||||
|
||||
property bool shuffleSupported: this.activePlayer && this.activePlayer.shuffleSupported && this.activePlayer.canControl;
|
||||
property bool hasShuffle: this.activePlayer?.shuffle ?? false;
|
||||
function setShuffle(shuffle: bool) {
|
||||
if (this.shuffleSupported) {
|
||||
this.activePlayer.shuffle = shuffle;
|
||||
}
|
||||
}
|
||||
|
||||
function setActivePlayer(player: MprisPlayer) {
|
||||
const targetPlayer = player ?? Mpris.players[0];
|
||||
console.log(`setactive: ${targetPlayer} from ${activePlayer}`)
|
||||
|
||||
if (targetPlayer && this.activePlayer) {
|
||||
this.__reverse = Mpris.players.indexOf(targetPlayer) < Mpris.players.indexOf(this.activePlayer);
|
||||
} else {
|
||||
// always animate forward if going to null
|
||||
this.__reverse = false;
|
||||
}
|
||||
|
||||
this.trackedPlayer = targetPlayer;
|
||||
}
|
||||
|
||||
function findSpotify(): MprisPlayer {
|
||||
const players = Mpris.players
|
||||
for (const player of players.values) {
|
||||
if (player.identity == "Spotify") {
|
||||
return player
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
console.log("");
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "mpris"
|
||||
|
||||
function pauseAll(): void {
|
||||
for (const player of Mpris.players.values) {
|
||||
if (player.canPause) player.pause();
|
||||
}
|
||||
}
|
||||
|
||||
function playPause(): void { root.togglePlaying(); }
|
||||
function previous(): void { root.previous(); }
|
||||
function next(): void { root.next(); }
|
||||
}
|
||||
}
|
||||
227
modules/quickshell/quickshell/bar/widgets/player/PlayerControllerV2.qml
Executable file
@@ -0,0 +1,227 @@
|
||||
// Reworked the PlayerController a bit
|
||||
|
||||
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQml.Models
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Services.Mpris
|
||||
// import qs
|
||||
|
||||
Singleton {
|
||||
id: root;
|
||||
property Mpris mpris: Mpris;
|
||||
property MprisPlayer activePlayer: findSpotify();
|
||||
|
||||
signal trackChanged(reverse: bool);
|
||||
|
||||
property bool __reverse: false;
|
||||
|
||||
property var activeTrack;
|
||||
|
||||
property string activeTrackPositionFormated: "0:00";
|
||||
property string activeTrackLengthFormated: "0:00";
|
||||
|
||||
PersistentProperties {
|
||||
id: persist
|
||||
reloadableId: "MusicWidget";
|
||||
property string lastActivePlayerIdentify: "";
|
||||
|
||||
onReloaded: {
|
||||
root.setActivePlayerFromIdentity(lastActivePlayerIdentify)
|
||||
root.updateActiveTrackPosition()
|
||||
}
|
||||
onLoaded: {
|
||||
root.setActivePlayerFromIdentity(lastActivePlayerIdentify)
|
||||
root.updateActiveTrackPosition()
|
||||
}
|
||||
}
|
||||
|
||||
Instantiator {
|
||||
model: Mpris.players;
|
||||
|
||||
Connections {
|
||||
required property MprisPlayer modelData;
|
||||
target: modelData;
|
||||
|
||||
Component.onCompleted: {
|
||||
if (root.trackedPlayer == null || modelData.isPlaying) {
|
||||
root.trackedPlayer = modelData;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (root.trackedPlayer == null || !root.trackedPlayer.isPlaying) {
|
||||
for (const player of Mpris.players.values) {
|
||||
if (player.playbackState.isPlaying) {
|
||||
root.trackedPlayer = player;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (trackedPlayer == null && Mpris.players.values.length != 0) {
|
||||
trackedPlayer = Mpris.players.values[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onPlaybackStateChanged() {
|
||||
console.log("Playback state has been changed")
|
||||
// if (root.trackedPlayer !== modelData) root.trackedPlayer = modelData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: activePlayer
|
||||
|
||||
function onPostTrackChanged() {
|
||||
root.updateTrack();
|
||||
}
|
||||
|
||||
function onTrackArtUrlChanged() {
|
||||
console.log("arturl:", activePlayer.trackArtUrl)
|
||||
//root.updateTrack();
|
||||
if (root.activePlayer.uniqueId == root.activeTrack.uniqueId && root.activePlayer.trackArtUrl != root.activeTrack.artUrl) {
|
||||
// cantata likes to send cover updates *BEFORE* updating the track info.
|
||||
// as such, art url changes shouldn't be able to break the reverse animation
|
||||
const r = root.__reverse;
|
||||
root.updateTrack();
|
||||
root.__reverse = r;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onActivePlayerChanged: this.updateTrack();
|
||||
|
||||
function setPlayerByIdentity(id: string) {
|
||||
for (var i = 0; i < 9; i++) {
|
||||
console.log(i)
|
||||
}
|
||||
mpris.players
|
||||
}
|
||||
|
||||
function updateTrack() {
|
||||
this.activeTrack = {
|
||||
uniqueId: this.activePlayer?.uniqueId ?? 0,
|
||||
artUrl: this.activePlayer?.trackArtUrl ?? "",
|
||||
title: this.activePlayer?.trackTitle || "Unknown Title",
|
||||
artist: this.activePlayer?.trackArtist || "Unknown Artist",
|
||||
album: this.activePlayer?.trackAlbum || "Unknown Album",
|
||||
};
|
||||
|
||||
this.trackChanged(__reverse);
|
||||
this.__reverse = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
property bool isPlaying: this.activePlayer && this.activePlayer.isPlaying;
|
||||
property bool canTogglePlaying: this.activePlayer?.canTogglePlaying ?? false;
|
||||
function togglePlaying() {
|
||||
if (this.canTogglePlaying) this.activePlayer.togglePlaying();
|
||||
}
|
||||
|
||||
property bool canGoPrevious: this.activePlayer?.canGoPrevious ?? false;
|
||||
function previous() {
|
||||
if (this.canGoPrevious) {
|
||||
this.__reverse = true;
|
||||
this.activePlayer.previous();
|
||||
}
|
||||
}
|
||||
|
||||
property bool canGoNext: this.activePlayer?.canGoNext ?? false;
|
||||
function next() {
|
||||
if (this.canGoNext) {
|
||||
this.__reverse = false;
|
||||
this.activePlayer.next();
|
||||
}
|
||||
}
|
||||
|
||||
property bool canChangeVolume: this.activePlayer && this.activePlayer.volumeSupported && this.activePlayer.canControl;
|
||||
|
||||
property bool loopSupported: this.activePlayer && this.activePlayer.loopSupported && this.activePlayer.canControl;
|
||||
property var loopState: this.activePlayer?.loopState ?? MprisLoopState.None;
|
||||
function setLoopState(loopState: var) {
|
||||
if (this.loopSupported) {
|
||||
this.activePlayer.loopState = loopState;
|
||||
}
|
||||
}
|
||||
|
||||
property bool shuffleSupported: this.activePlayer && this.activePlayer.shuffleSupported && this.activePlayer.canControl;
|
||||
property bool hasShuffle: this.activePlayer?.shuffle ?? false;
|
||||
function setShuffle(shuffle: bool) {
|
||||
if (this.shuffleSupported) {
|
||||
this.activePlayer.shuffle = shuffle;
|
||||
}
|
||||
}
|
||||
|
||||
function setActivePlayer(player: MprisPlayer) {
|
||||
const targetPlayer = player;
|
||||
console.log(`setactive: ${targetPlayer} from ${activePlayer}`)
|
||||
|
||||
persist.lastActivePlayerIdentify = targetPlayer.identity
|
||||
this.activePlayer = player;
|
||||
}
|
||||
|
||||
function setActivePlayerFromIdentity(identify: string) {
|
||||
for (x in root.mpris.players) {
|
||||
if (x.identify == identify) {
|
||||
this.activePlayer = x
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
// only emit the signal when the position is actually changing.
|
||||
running: root.activePlayer.playbackState == MprisPlaybackState.Playing
|
||||
// Make sure the position updates at least once per second.
|
||||
interval: 1000
|
||||
repeat: true
|
||||
// emit the positionChanged signal every second.
|
||||
onTriggered: root.updateActiveTrackPosition()
|
||||
}
|
||||
|
||||
function updateActiveTrackPosition() {
|
||||
activeTrackPositionFormated = Math.floor(root.activePlayer.position / 60) + ":" + ("0" + Math.floor(root.activePlayer.position % 60)).slice(-2)
|
||||
activeTrackLengthFormated = Math.floor(root.activePlayer.length / 60) + ":" + ("0" + Math.floor(root.activePlayer.length % 60)).slice(-2)
|
||||
}
|
||||
|
||||
function update() {
|
||||
updateActiveTrackPosition()
|
||||
}
|
||||
|
||||
function trackPositionFormatter(position: double): string {
|
||||
return Math.floor(position / 60) + ":" + ("0" + Math.floor(position % 60)).slice(-2)
|
||||
}
|
||||
|
||||
function findSpotify(): MprisPlayer {
|
||||
const players = Mpris.players
|
||||
for (const player of players.values) {
|
||||
if (player.identity == "Spotify") {
|
||||
return player
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
console.log("");
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "mpris"
|
||||
|
||||
function pauseAll(): void {
|
||||
for (const player of Mpris.players.values) {
|
||||
if (player.canPause) player.pause();
|
||||
}
|
||||
}
|
||||
|
||||
function playPause(): void { root.togglePlaying(); }
|
||||
function previous(): void { root.previous(); }
|
||||
function next(): void { root.next(); }
|
||||
}
|
||||
}
|
||||
46
modules/quickshell/quickshell/bar/widgets/player/PlayerPopup.qml
Executable file
@@ -0,0 +1,46 @@
|
||||
import QtQml
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import QtQuick.Layouts
|
||||
|
||||
PopupWindow {
|
||||
property PlayerControllerV2 player: PlayerControllerV2;
|
||||
|
||||
id: audioPopup
|
||||
anchor {
|
||||
item: root
|
||||
}
|
||||
anchor.rect.x: root.width / 2 - width / 2
|
||||
anchor.rect.y: root.height * 1.2
|
||||
height: 350
|
||||
width: 300
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#919191"
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
Item {
|
||||
width: coverImg.width
|
||||
height: coverImg.height
|
||||
Image {
|
||||
id: coverImg
|
||||
anchors.fill: parent
|
||||
source: player.activePlayer.trackArtUrl;
|
||||
width: 275
|
||||
height: 275
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: player.activePlayer.trackTitle
|
||||
color: "white"
|
||||
font.pointSize: 10.75
|
||||
}
|
||||
Text {
|
||||
text: player.activePlayer.trackArtist
|
||||
color: "white"
|
||||
font.pointSize: 10.75
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
254
modules/quickshell/quickshell/bar/widgets/player/PlayerPopupV2.qml
Executable file
@@ -0,0 +1,254 @@
|
||||
import QtQml
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Mpris
|
||||
|
||||
PopupWindow {
|
||||
property PlayerControllerV2 player: PlayerControllerV2;
|
||||
|
||||
readonly property string elementBackgroundColor : "#323232"
|
||||
readonly property string elementButtonBaseColor : "#515151"
|
||||
readonly property string elementButtonHoverColor : "#737373"
|
||||
|
||||
id: audioPopup
|
||||
anchor {
|
||||
item: root
|
||||
}
|
||||
anchor.rect.x: root.width / 2 - width / 2
|
||||
anchor.rect.y: root.height * 1.2
|
||||
height: columnContainer.height + 5
|
||||
width: 425
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#919191"
|
||||
ColumnLayout {
|
||||
id: columnContainer
|
||||
anchors.centerIn: parent
|
||||
Repeater {
|
||||
model: player.mpris.players
|
||||
Item {
|
||||
id: root
|
||||
width: 375
|
||||
height: 110
|
||||
required property MprisPlayer modelData
|
||||
property string trackPosition: PlayerControllerV2.trackPositionFormatter(root.modelData.position)
|
||||
property string trackLength: "0:00"
|
||||
Rectangle {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
color: audioPopup.elementBackgroundColor
|
||||
radius: 7
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: event => {
|
||||
audioPopup.player.setActivePlayer(root.modelData);
|
||||
audioPopup.player.update();
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
width:root.width - 15
|
||||
RowLayout {
|
||||
implicitWidth: root.width - 15
|
||||
ClippingWrapperRectangle {
|
||||
implicitWidth: 75
|
||||
implicitHeight: 75
|
||||
radius: 7
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
mipmap: true
|
||||
source: root.modelData.trackArtUrl
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: 2
|
||||
ScrollView {
|
||||
implicitWidth: 180
|
||||
height: parent.height
|
||||
|
||||
Text {
|
||||
text: root.modelData.trackTitle
|
||||
color: "white"
|
||||
font.pointSize: 11
|
||||
antialiasing: true
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: root.modelData.trackArtist
|
||||
color: "white"
|
||||
font.pointSize: 8
|
||||
antialiasing: true
|
||||
}
|
||||
}
|
||||
Rectangle { // Spacer
|
||||
color: "transparent"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
// Layout.
|
||||
spacing: 0
|
||||
// buttons
|
||||
Item {
|
||||
implicitWidth: 30
|
||||
implicitHeight: 25
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Rectangle {
|
||||
id: gobackButton
|
||||
width: 30
|
||||
height: 25
|
||||
topLeftRadius: 7
|
||||
bottomLeftRadius: 7
|
||||
color: audioPopup.elementButtonBaseColor
|
||||
}
|
||||
IconImage {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
implicitSize: 25
|
||||
source: "root:/assets/media_player/skip_previous.svg"
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: event => {
|
||||
gobackButton.color = audioPopup.elementButtonHoverColor
|
||||
}
|
||||
onExited: event => {
|
||||
gobackButton.color = audioPopup.elementButtonBaseColor
|
||||
}
|
||||
onClicked: event => {
|
||||
root.modelData.previous();
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
width: 30
|
||||
height: 25
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
width: 30
|
||||
height: 25
|
||||
Rectangle {
|
||||
id: pauseButton
|
||||
width: 30
|
||||
height: 25
|
||||
// topLeftRadius: 7
|
||||
// bottomLeftRadius: 7
|
||||
color: audioPopup.elementButtonBaseColor
|
||||
}
|
||||
IconImage {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
anchors.centerIn: parent
|
||||
implicitSize: 25
|
||||
source: root.modelData.isPlaying ? "root:/assets/media_player/pausebutton.svg" : "root:/assets/media_player/playbutton.svg"
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
// id: pauseButton
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: event => {
|
||||
pauseButton.color = audioPopup.elementButtonHoverColor
|
||||
}
|
||||
onExited: event => {
|
||||
pauseButton.color = audioPopup.elementButtonBaseColor
|
||||
}
|
||||
onClicked: event => {
|
||||
root.modelData.togglePlaying();
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
width: 30
|
||||
height: 25
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Rectangle {
|
||||
id: gonextButton
|
||||
width: 30
|
||||
height: 25
|
||||
topRightRadius: 7
|
||||
bottomRightRadius: 7
|
||||
color: audioPopup.elementButtonBaseColor
|
||||
}
|
||||
IconImage {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
implicitSize: 25
|
||||
source: "root:/assets/media_player/skip_next.svg"
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: event => {
|
||||
gonextButton.color = audioPopup.elementButtonHoverColor
|
||||
}
|
||||
onExited: event => {
|
||||
gonextButton.color = audioPopup.elementButtonBaseColor
|
||||
}
|
||||
onClicked: event => {
|
||||
root.modelData.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Slider {
|
||||
id: slider
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
value: root.modelData.position
|
||||
to: root.modelData.length
|
||||
property double lastPosition;
|
||||
property bool debounceValue: false;
|
||||
onMoved: event => {
|
||||
debounceValue = true; // there is insane lag if we put the move logic here, so its better to trigger a time with the logic instead
|
||||
}
|
||||
Timer {
|
||||
running: slider.debounceValue
|
||||
interval: 250
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
root.modelData.position = slider.value
|
||||
slider.debounceValue = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: positionText
|
||||
text: trackPosition + "/" + trackLength // returns float of seconds of length
|
||||
color: "white"
|
||||
font.pointSize: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: updateTimer
|
||||
property bool tempOneshot: false;
|
||||
running: root.modelData.isPlaying || (root.modelData.position != slider.lastPosition)
|
||||
interval: 750
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
trackPosition = PlayerControllerV2.trackPositionFormatter(root.modelData.position)
|
||||
trackLength = PlayerControllerV2.trackPositionFormatter(root.modelData.length)
|
||||
updateTimer.tempOneshot = false;
|
||||
slider.lastPosition = slider.value
|
||||
slider.value = root.modelData.position
|
||||
// root.audioPopup.player.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
88
modules/quickshell/quickshell/bar/widgets/player/PlayerWidget.qml
Executable file
@@ -0,0 +1,88 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
import QtQuick.Effects
|
||||
// import playbutton.svg
|
||||
|
||||
Item {
|
||||
id: root
|
||||
Layout.fillHeight: true
|
||||
implicitWidth: hi.width
|
||||
property PlayerControllerV2 player: PlayerControllerV2;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: event => {
|
||||
audioPopup.visible = true;
|
||||
}
|
||||
onExited: event => {
|
||||
audioPopup.visible = false;
|
||||
}
|
||||
}
|
||||
Image {
|
||||
source: player.activePlayer.trackArtUrl;
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: MultiEffect {
|
||||
blur: 0.3
|
||||
blurEnabled: true
|
||||
}
|
||||
}
|
||||
// parent.aaaaa: false
|
||||
RowLayout {
|
||||
id: hi
|
||||
Item {
|
||||
implicitHeight: 30;
|
||||
implicitWidth: 30;
|
||||
IconImage {
|
||||
implicitSize: 30;
|
||||
source: "root:assets/media_player/skip_next.svg";
|
||||
scale: -1
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: event => {
|
||||
player.activePlayer.previous();
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
implicitHeight: 30;
|
||||
implicitWidth: 30;
|
||||
IconImage {
|
||||
implicitSize: 30;
|
||||
source: !player.activePlayer.isPlaying ? "root:/assets/media_player/playbutton.svg" : "root:/assets/media_player/pausebutton.svg";
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: false
|
||||
onPressed: event => {
|
||||
player.activePlayer.togglePlaying();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
implicitHeight: 30;
|
||||
implicitWidth: 30;
|
||||
IconImage {
|
||||
implicitSize: 30;
|
||||
source: "root:assets/media_player/skip_next.svg";
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: event => {
|
||||
player.activePlayer.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PlayerPopup {
|
||||
id: audioPopup
|
||||
}
|
||||
}
|
||||
151
modules/quickshell/quickshell/bar/widgets/player/PlayerWidgetV2.qml
Executable file
@@ -0,0 +1,151 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
import QtQuick.Effects
|
||||
import "../common" as Common
|
||||
|
||||
// import playbutton.svg
|
||||
|
||||
Item {
|
||||
property PlayerControllerV2 player: PlayerControllerV2;
|
||||
id: root
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: mainLayout.width + 10
|
||||
Loader {
|
||||
id: audioPopupLoader
|
||||
active: true
|
||||
sourceComponent: PlayerPopupV2 {
|
||||
id: audioPopup
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
id: mainLayout
|
||||
Layout.fillHeight: true
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
Common.Meow {
|
||||
id: commons
|
||||
}
|
||||
Item {
|
||||
implicitWidth: text.width
|
||||
implicitHeight: text.height
|
||||
Rectangle {
|
||||
id: hoverColor
|
||||
anchors.centerIn: parent
|
||||
visible: false
|
||||
radius: 7
|
||||
width: parent.width + 5
|
||||
height: parent.height + 2.5
|
||||
color: "grey"
|
||||
}
|
||||
Text {
|
||||
id: text
|
||||
text: (root.player.activePlayer == undefined) ? "Nothing" : player.activePlayer.trackTitle
|
||||
color: "white"
|
||||
font.pointSize: 10
|
||||
font.italic: (root.player.activePlayer == undefined) ? true : false
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onEntered: event => {
|
||||
hoverColor.visible = true
|
||||
}
|
||||
onExited: event => {
|
||||
hoverColor.visible = false
|
||||
}
|
||||
onClicked: event => {
|
||||
audioPopupLoader.item.visible = !audioPopupLoader.item.visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
Common.Dot {}
|
||||
Item {
|
||||
id: mediaPositionControls
|
||||
implicitWidth: positionText.width
|
||||
implicitHeight: positionText.height
|
||||
Text {
|
||||
id: positionText
|
||||
text: root.player.activeTrackPositionFormated + "/" + player.activeTrackLengthFormated // returns float of seconds of length
|
||||
color: "white"
|
||||
font.pointSize: 10
|
||||
}
|
||||
RowLayout {
|
||||
visible: !positionText.visible
|
||||
// enable: !positionText.visible
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Item {
|
||||
width: 20
|
||||
height: 20
|
||||
IconImage {
|
||||
anchors.fill: parent
|
||||
implicitSize: 20
|
||||
source: "root:/assets/media_player/skip_previous.svg"
|
||||
}
|
||||
}
|
||||
Item {
|
||||
width: 20
|
||||
height: 20
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
width: 20
|
||||
height: 20
|
||||
hoverEnabled: true
|
||||
onClicked: event => {
|
||||
root.player.activePlayer.togglePlaying()
|
||||
}
|
||||
}
|
||||
IconImage {
|
||||
anchors.fill: parent
|
||||
implicitSize: 20
|
||||
source: (root.player.activePlayer.isPlaying) ? "root:/assets/media_player/pausebutton.svg" : "root:/assets/media_player/playbutton.svg"
|
||||
}
|
||||
}
|
||||
Item {
|
||||
width: 20
|
||||
height: 20
|
||||
IconImage {
|
||||
anchors.fill: parent
|
||||
implicitSize: 20
|
||||
source: "root:/assets/media_player/skip_next.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
z: 1
|
||||
id: mouseAreaMediaButtons
|
||||
height: parent.height + 15
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
propagateComposedEvents: true // allows events to transparently go through to an overlapping mouseArea
|
||||
|
||||
onEntered: event => {
|
||||
positionText.visible = false;
|
||||
}
|
||||
onExited: event => {
|
||||
positionText.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
z: -1
|
||||
color: "black"
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
height: 25
|
||||
width: parent.width
|
||||
radius: 7
|
||||
}
|
||||
}
|
||||
7
modules/quickshell/quickshell/bar/widgets/workspace/HyprlandClient.qml
Executable file
@@ -0,0 +1,7 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
property string initialClass: "";
|
||||
property string initialTitle: "";
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
// property string aaaa: "";
|
||||
property list<HyprlandClient> meow;
|
||||
property Hyprland hyprland: Hyprland;
|
||||
|
||||
Process {
|
||||
id: dateProc
|
||||
|
||||
command: ["hyprctl", "clients"]
|
||||
running: true
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: parseClients(this.text)
|
||||
}
|
||||
}
|
||||
function parseClients(text) {
|
||||
hyprland.refreshToplevels();
|
||||
var meow = hyprland.activeToplevel.lastIpcObject;
|
||||
console.log(meow.class);
|
||||
}
|
||||
}
|
||||
91
modules/quickshell/quickshell/bar/widgets/workspace/WorkspaceWidget.qml
Executable file
@@ -0,0 +1,91 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Hyprland
|
||||
import "root:/bar/widgets/common" as Common
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
spacing: 10
|
||||
Layout.fillHeight: true
|
||||
|
||||
Repeater {
|
||||
model: Hyprland.workspaces
|
||||
delegate: Item {
|
||||
id: root2
|
||||
required property HyprlandWorkspace modelData
|
||||
implicitWidth: 35 + appIconContainer.implicitWidth
|
||||
Layout.fillHeight: true
|
||||
Item {
|
||||
visible: root2.modelData.toplevels.values[0] != undefined
|
||||
id: appIconContainer
|
||||
implicitWidth: row.implicitWidth
|
||||
implicitHeight: 25
|
||||
x: 30
|
||||
anchors.verticalCenter: root2.verticalCenter
|
||||
Rectangle {
|
||||
x: -10
|
||||
radius: 7
|
||||
color: "black"
|
||||
implicitWidth: row.width + 20
|
||||
implicitHeight: 25
|
||||
}
|
||||
RowLayout {
|
||||
x: 5
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
id: row
|
||||
spacing: 15
|
||||
Repeater {
|
||||
model: root2.modelData.toplevels
|
||||
delegate: Item {
|
||||
required property HyprlandToplevel modelData
|
||||
width: icon.implicitWidth
|
||||
height: icon.implicitHeight
|
||||
Text {
|
||||
id: icon
|
||||
color: "white"
|
||||
font.family: "CaskaydiaCove Nerd Font Mono" // https://www.reddit.com/r/Polybar/comments/sh8krs/comment/hv3lykm/
|
||||
font.pointSize: 13
|
||||
// long-ass oneliner for "if there is no class icon, go to fallback"
|
||||
text: (Common.Icons.appIcons[(modelData.lastIpcObject.class)] != undefined ) ? Common.Icons.appIcons[(modelData.lastIpcObject.class)] : Common.Icons.appIcons["fallback"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
width: 30
|
||||
height: 30
|
||||
MouseArea {
|
||||
width: 30
|
||||
height: 30
|
||||
onPressed: event => {
|
||||
modelData.activate();
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: 30
|
||||
height: 30
|
||||
radius: 10
|
||||
color: modelData.focused ? "grey" : "black"
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: modelData.id
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: updateTimer
|
||||
running: true
|
||||
interval: 1000 // 10secs
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
Hyprland.refreshToplevels()
|
||||
}
|
||||
}
|
||||
}
|
||||
8
modules/quickshell/quickshell/shell.qml
Executable file
@@ -0,0 +1,8 @@
|
||||
//@ pragma UseQApplication
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import "bar" as Bar
|
||||
|
||||
Scope {
|
||||
Bar.Bar {}
|
||||
}
|
||||
4
modules/spicetify/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
39
modules/spicetify/home.nix
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
inputs,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
spicePkgs = inputs.spicetify-nix.legacyPackages.${pkgs.stdenv.hostPlatform.system};
|
||||
cfg = config.modules.spicetify;
|
||||
in
|
||||
{
|
||||
options.modules.spicetify = {
|
||||
enable = lib.mkEnableOption "spicetify configuration module";
|
||||
};
|
||||
imports = [
|
||||
inputs.spicetify-nix.homeManagerModules.default
|
||||
];
|
||||
config.programs.spicetify = lib.mkIf cfg.enable {
|
||||
enable = true;
|
||||
|
||||
enabledExtensions = with spicePkgs.extensions; [
|
||||
adblock
|
||||
hidePodcasts
|
||||
shuffle # shuffle+ (special characters are sanitized out of extension names)
|
||||
];
|
||||
enabledCustomApps = with spicePkgs.apps; [
|
||||
newReleases
|
||||
# ncsVisualizer
|
||||
];
|
||||
enabledSnippets = with spicePkgs.snippets; [
|
||||
# rotatingCoverart
|
||||
pointer
|
||||
];
|
||||
|
||||
theme = spicePkgs.themes.catppuccin;
|
||||
colorScheme = "mocha";
|
||||
};
|
||||
}
|
||||
4
modules/steam/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
# home: ./home.nix;
|
||||
nixos = ./nixos.nix;
|
||||
}
|
||||
47
modules/steam/nixos.nix
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.steam;
|
||||
in
|
||||
{
|
||||
options.modules.steam = {
|
||||
enable = lib.mkEnableOption "steam";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.steam = {
|
||||
enable = true;
|
||||
remotePlay.openFirewall = true;
|
||||
dedicatedServer.openFirewall = true;
|
||||
localNetworkGameTransfers.openFirewall = true;
|
||||
# Ensure gamescope is inside the steam "fhs"
|
||||
package = pkgs.steam.override {
|
||||
extraLibraries = pkgs: [ pkgs.xorg.libxcb ];
|
||||
extraPkgs =
|
||||
pkgs: with pkgs; [
|
||||
attr
|
||||
xorg.libXcursor
|
||||
xorg.libXi
|
||||
xorg.libXinerama
|
||||
xorg.libXScrnSaver
|
||||
libpng
|
||||
libpulseaudio
|
||||
libvorbis
|
||||
stdenv.cc.cc.lib
|
||||
libkrb5
|
||||
keyutils
|
||||
mangohud
|
||||
gamemode
|
||||
lsof
|
||||
(gamescope.overrideAttrs {
|
||||
enableWsi = true;
|
||||
NIX_CFLAGS_COMPILE = [ "-fno-fast-math" ];
|
||||
})
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
4
modules/stylix/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
nixos = ./nixos.nix;
|
||||
}
|
||||
13
modules/stylix/fonts.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
stylix.fonts = {
|
||||
monospace = {
|
||||
name = "CaskaydiaCove Nerd Font Mono";
|
||||
package = pkgs.nerd-fonts.caskaydia-cove;
|
||||
};
|
||||
};
|
||||
}
|
||||
26
modules/stylix/home.nix
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.stylix;
|
||||
in
|
||||
{
|
||||
options.modules.stylix = {
|
||||
enable = lib.mkEnableOption "stylix configuration module";
|
||||
};
|
||||
imports = [
|
||||
./shared.nix
|
||||
inputs.stylix.homeModules.stylix
|
||||
];
|
||||
config = lib.mkIf cfg.enable {
|
||||
stylix.enable = true;
|
||||
stylix.autoEnable = false; # honestly, fuck stylix;
|
||||
stylix.targets.gtk.enable = true;
|
||||
stylix.targets.qt.enable = true;
|
||||
stylix.targets.tmux.enable = false;
|
||||
};
|
||||
}
|
||||
25
modules/stylix/nixos.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.stylix;
|
||||
in
|
||||
{
|
||||
options.modules.stylix = {
|
||||
enable = lib.mkEnableOption "stylix configuration module";
|
||||
};
|
||||
imports = [
|
||||
./shared.nix
|
||||
inputs.stylix.nixosModules.stylix
|
||||
];
|
||||
config = lib.mkIf cfg.enable {
|
||||
stylix.enable = true;
|
||||
stylix.autoEnable = false; # honestly, fuck stylix;
|
||||
# stylix.targets.tmux.enable = false;
|
||||
};
|
||||
|
||||
}
|
||||
18
modules/stylix/shared.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
./fonts.nix
|
||||
];
|
||||
stylix = {
|
||||
enable = true;
|
||||
polarity = "dark";
|
||||
base16Scheme = ./theme.yml;
|
||||
};
|
||||
# stylix.override = {
|
||||
# base00 = "000000"; # make background completely black
|
||||
# };
|
||||
}
|
||||
35
modules/stylix/theme.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
scheme: "Generated Scheme"
|
||||
author: "The Robots"
|
||||
base00: "#000000"
|
||||
base01: "#000000"
|
||||
# base01: "#202020"
|
||||
base02: "#303030"
|
||||
base03: "#505050"
|
||||
base04: "#b0b0b0"
|
||||
base05: "#d0d0d0"
|
||||
base06: "#e0e0e0"
|
||||
base07: "#ffffff"
|
||||
base08: "#f5708a"
|
||||
base09: "#ee8122"
|
||||
base0A: "#b8a300"
|
||||
base0B: "#54bc5c"
|
||||
base0C: "#00bab3"
|
||||
base0D: "#00aff2"
|
||||
base0E: "#9095ff"
|
||||
base0F: "#d47ada"
|
||||
|
||||
# base01: "#000000"
|
||||
# base02: "#2e0a45"
|
||||
# base03: "#571880"
|
||||
# base04: "#7c2bb1"
|
||||
# base05: "#9d41d8"
|
||||
# base06: "#b95cf5"
|
||||
# base07: "#d17bff"
|
||||
# base08: "#e49dff"
|
||||
# base09: "#ffa190"
|
||||
# base0A: "#dcc264"
|
||||
# base0B: "#9be16e"
|
||||
# base0C: "#6feda7"
|
||||
# base0D: "#72deee"
|
||||
# base0E: "#a2bdff"
|
||||
# base0F: "#e49dff"
|
||||
4
modules/theme/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
21
modules/theme/home.nix
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
inputs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.theme;
|
||||
in
|
||||
{
|
||||
options.modules.theme = {
|
||||
enable = lib.mkEnableOption "theme";
|
||||
};
|
||||
config.services.dunst = lib.mkIf cfg.enable {
|
||||
settings = {
|
||||
global = {
|
||||
font = "Noto Nerd Font 8";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
4
modules/tmux/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
29
modules/tmux/home.nix
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
inputs,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
fetchFromGitHub,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.tmux;
|
||||
in
|
||||
{
|
||||
options.modules.tmux = {
|
||||
enable = lib.mkEnableOption "tmux";
|
||||
};
|
||||
config.programs.tmux = lib.mkIf cfg.enable {
|
||||
enable = true;
|
||||
plugins = with pkgs.tmuxPlugins; [
|
||||
sensible
|
||||
minimal-tmux-status
|
||||
];
|
||||
extraConfig = ''
|
||||
set-option -g default-terminal "xterm-256color"
|
||||
set -a terminal-features "xterm-256color:RGB"
|
||||
set -g status-bg black
|
||||
set -g status-fg white
|
||||
'';
|
||||
};
|
||||
}
|
||||
3
modules/unityhub/default.nix
Normal file
@@ -0,0 +1,3 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
}
|
||||
21
modules/unityhub/home.nix
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.unityhub;
|
||||
in
|
||||
{
|
||||
options.modules.unityhub = {
|
||||
enable = lib.mkEnableOption "unity";
|
||||
};
|
||||
config.home = lib.mkIf cfg.enable {
|
||||
packages = with pkgs; [
|
||||
unityhub
|
||||
];
|
||||
# so alcom can use it
|
||||
file.".local/bin/unityhub".source = "${pkgs.unityhub}/bin/unityhub";
|
||||
};
|
||||
}
|
||||
4
modules/wivrn/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
nixos = ./nixos.nix;
|
||||
home = ./home.nix;
|
||||
}
|
||||
25
modules/wivrn/home.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
pkgs,
|
||||
home,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.wivrn;
|
||||
in
|
||||
{
|
||||
options.modules.wivrn = {
|
||||
enable = lib.mkEnableOption "Blender configuration module";
|
||||
};
|
||||
# whole blender config including addons is too fat to include here
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = with pkgs; [
|
||||
wlx-overlay-s
|
||||
];
|
||||
};
|
||||
# nix'ing a blender config is most likely not possible
|
||||
# could probs install blender addons through nix since they are fat fat mega fat to install TODO
|
||||
}
|
||||
59
modules/wivrn/nixos.nix
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
pkgs,
|
||||
home,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.wivrn;
|
||||
wivrn_override = pkgs.wivrn.overrideAttrs (
|
||||
final: prev: {
|
||||
pname = "wivrn";
|
||||
version = "25.11.1";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "wivrn";
|
||||
repo = "wivrn";
|
||||
rev = "v25.11.1";
|
||||
hash = "sha256-pEKMeRdI9UhdZ+NksRBcF7yPC7Ys2haE+B4PPGQ4beE=";
|
||||
};
|
||||
monado = pkgs.applyPatches {
|
||||
src = pkgs.fetchFromGitLab {
|
||||
domain = "gitlab.freedesktop.org";
|
||||
owner = "monado";
|
||||
repo = "monado";
|
||||
rev = "06e62fc7d9c5cbcbc43405bb86dfde3bf01ce043";
|
||||
hash = "sha256-0ALB9eLY4NAUqNOYZMwpvYnLxVpHsQDJc1er8Txdezs=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
${final.src}/patches/apply.sh ${final.src}/patches/monado/*
|
||||
'';
|
||||
};
|
||||
patches = [ ];
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
options.modules.wivrn = {
|
||||
enable = lib.mkEnableOption "Wivrn configuration module";
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
services = {
|
||||
wivrn = {
|
||||
enable = true;
|
||||
package = wivrn_override;
|
||||
openFirewall = true;
|
||||
defaultRuntime = true;
|
||||
};
|
||||
avahi = {
|
||||
enable = true;
|
||||
publish.enable = true;
|
||||
publish.userServices = true;
|
||||
};
|
||||
};
|
||||
programs.adb.enable = true;
|
||||
};
|
||||
}
|
||||
0
modules/ytm/a
Normal file
4
modules/ytm/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
_: {
|
||||
home = ./home.nix;
|
||||
# nixos: ./nixos.nix;
|
||||
}
|
||||
17
modules/ytm/home.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.youtube-music;
|
||||
in
|
||||
{
|
||||
options.modules.youtube-music = {
|
||||
enable = lib.mkEnableOption "youtube music";
|
||||
};
|
||||
config.home.packages = with pkgs; [
|
||||
youtube-music
|
||||
];
|
||||
}
|
||||