├── config ├── nvim │ ├── .gitignore │ ├── stylua.toml │ ├── lua │ │ ├── plugins │ │ │ ├── telescope.lua │ │ │ ├── git.lua │ │ │ ├── neotree.lua │ │ │ ├── vimtex.lua │ │ │ ├── terminal.lua │ │ │ ├── lines.lua │ │ │ ├── startup.lua │ │ │ ├── misc.lua │ │ │ ├── nvim-cmp.lua │ │ │ ├── editing.lua │ │ │ ├── treesitter.lua │ │ │ ├── dev.lua │ │ │ └── lsp.lua │ │ ├── misc.lua │ │ ├── options.lua │ │ └── remaps.lua │ ├── init.lua │ ├── ftplugin │ │ └── java.lua │ └── lazy-lock.json ├── ags │ ├── .gitignore │ ├── package.json │ ├── scss │ │ ├── _colors.scss │ │ ├── _animations.scss │ │ ├── powermenu.scss │ │ ├── mpris.scss │ │ ├── replaymenu.scss │ │ ├── media.scss │ │ ├── notifications.scss │ │ ├── bar.scss │ │ └── glance.scss │ ├── tsconfig.json │ ├── env.d.ts │ ├── eslint.config.mjs │ ├── style.scss │ ├── components │ │ ├── MenuList.tsx │ │ ├── EndpointSlider.tsx │ │ ├── StreamSlider.tsx │ │ └── Notification.tsx │ ├── utils │ │ ├── window.ts │ │ └── helpers.ts │ ├── windows │ │ ├── Notifications.tsx │ │ ├── PowerMenu.tsx │ │ ├── ReplayMenu.tsx │ │ └── Media.tsx │ ├── services │ │ ├── activeplayer.ts │ │ ├── brightness.ts │ │ ├── notifications.ts │ │ ├── recorder.ts │ │ └── weather.ts │ └── app.ts ├── hypr │ ├── hyprexpo.conf │ ├── pyprland.toml │ ├── hyprlandd.conf │ ├── animations.conf │ ├── scripts.conf │ ├── environment.conf │ ├── hypridle.conf │ ├── rules.conf │ ├── hyprgrass.conf │ ├── keybinds.conf │ └── hyprlock.conf ├── cava │ └── config └── rofi │ ├── colors.rasi │ └── theme.rasi ├── .gitignore ├── screenshots ├── 1.png ├── 2.png └── 3.png ├── assets ├── playerart.png └── launcher-symbolic.svg ├── nix ├── core │ ├── asus │ │ ├── services.nix │ │ ├── packages.nix │ │ ├── default.nix │ │ ├── iio.nix │ │ └── hardware-configuration.nix │ ├── lenovo │ │ ├── services.nix │ │ ├── packages.nix │ │ ├── shell.nix │ │ ├── default.nix │ │ ├── boot.nix │ │ └── hardware-configuration.nix │ └── common │ │ ├── boot.nix │ │ ├── default.nix │ │ ├── users.nix │ │ ├── networking.nix │ │ ├── security.nix │ │ ├── locale.nix │ │ ├── shell.nix │ │ ├── system.nix │ │ ├── services.nix │ │ └── packages.nix ├── home │ ├── files │ │ └── matlab.nix │ ├── home.nix │ ├── packages │ │ ├── cli.nix │ │ ├── dev.nix │ │ ├── hyprland.nix │ │ └── desktop.nix │ └── scripts.nix └── switch-theme │ ├── flake.nix │ ├── flake.lock │ └── switch-theme.py ├── LICENSE ├── justfile ├── README.md └── flake.nix /config/nvim/.gitignore: -------------------------------------------------------------------------------- 1 | .luarc.json 2 | -------------------------------------------------------------------------------- /config/ags/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | @girs/ 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # env variables 2 | .env 3 | 4 | # cache 5 | data/ 6 | log/ 7 | -------------------------------------------------------------------------------- /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abaan404/dotfiles/HEAD/screenshots/1.png -------------------------------------------------------------------------------- /screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abaan404/dotfiles/HEAD/screenshots/2.png -------------------------------------------------------------------------------- /screenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abaan404/dotfiles/HEAD/screenshots/3.png -------------------------------------------------------------------------------- /assets/playerart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abaan404/dotfiles/HEAD/assets/playerart.png -------------------------------------------------------------------------------- /config/nvim/stylua.toml: -------------------------------------------------------------------------------- 1 | indent_type = "Spaces" 2 | collapse_simple_statement = "Always" 3 | -------------------------------------------------------------------------------- /config/ags/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "ags": "*" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /nix/core/asus/services.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | services.xserver.videoDrivers = [ 5 | "amdgpu" 6 | ]; 7 | } 8 | -------------------------------------------------------------------------------- /nix/core/asus/packages.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | environment.systemPackages = [ 5 | pkgs.nvtopPackages.amd 6 | ]; 7 | } 8 | -------------------------------------------------------------------------------- /nix/core/lenovo/services.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | services.xserver.videoDrivers = [ 5 | "amdgpu" 6 | "nvidia" 7 | ]; 8 | } 9 | -------------------------------------------------------------------------------- /nix/core/lenovo/packages.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | environment.systemPackages = [ 5 | pkgs.nvtopPackages.amd 6 | pkgs.nvtopPackages.nvidia 7 | ]; 8 | } 9 | -------------------------------------------------------------------------------- /nix/core/common/boot.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | boot = { 5 | loader = { 6 | systemd-boot.enable = true; 7 | efi.canTouchEfiVariables = true; 8 | }; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /config/hypr/hyprexpo.conf: -------------------------------------------------------------------------------- 1 | plugin { 2 | hyprexpo { 3 | columns = 2 4 | gap_size = 4 5 | bg_col = rgba(!!{primary}ff) 6 | 7 | workspace_method = first 1 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nix/home/files/matlab.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | # https://gitlab.com/doronbehar/nix-matlab 5 | xdg.configFile."matlab/nix.sh".text = '' 6 | INSTALL_DIR=$HOME/downloads/software/matlab/installation 7 | ''; 8 | } 9 | -------------------------------------------------------------------------------- /nix/core/asus/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | # Shared config for an asus laptop 5 | imports = [ 6 | ./hardware-configuration.nix 7 | ./services.nix 8 | ./packages.nix 9 | ./iio.nix 10 | ]; 11 | } 12 | -------------------------------------------------------------------------------- /nix/core/lenovo/shell.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | environment.variables = { 5 | # https://wiki.archlinux.org/title/Hardware_video_acceleration 6 | "VDPAU_DRIVER" = "radeonsi"; 7 | "LIBVA_DRIVER_NAME" = "radeonsi"; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /nix/core/lenovo/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | # Shared config for a lenovo laptop 5 | imports = [ 6 | ./hardware-configuration.nix 7 | ./services.nix 8 | ./packages.nix 9 | ./shell.nix 10 | ./boot.nix 11 | ]; 12 | } 13 | -------------------------------------------------------------------------------- /config/ags/scss/_colors.scss: -------------------------------------------------------------------------------- 1 | @forward "!!HOME/.cache/wal/colors.scss"; 2 | 3 | $primary: #!!primary; 4 | $secondary: #!!secondary; 5 | $accent: #!!accent; 6 | $good: #!!good; 7 | $bad: #!!bad; 8 | $text: #!!text; 9 | $bluetooth: #!!bluetooth; 10 | $warning: #!!warning; 11 | -------------------------------------------------------------------------------- /config/hypr/pyprland.toml: -------------------------------------------------------------------------------- 1 | [pyprland] 2 | plugins = [ 3 | "scratchpads", 4 | ] 5 | 6 | [scratchpads.term] 7 | animation = "fromTop" 8 | command = "kitty --class kitty-dropterm" 9 | class = "kitty-dropterm" 10 | size = "75% 60%" 11 | max_size = "1920px 100%" 12 | margin = 50 13 | -------------------------------------------------------------------------------- /nix/core/lenovo/boot.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | boot = { 5 | # https://github.com/NixOS/nixpkgs/issues/286028 fix 6 | kernelModules = [ "nvidia-uvm" ]; 7 | 8 | blacklistedKernelModules = [ "ntfs3" ]; 9 | supportedFilesystems = [ "ntfs" ]; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /config/ags/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react-jsx", 4 | "jsxImportSource": "ags/gtk4", 5 | "module": "ES2022", 6 | "moduleResolution": "Bundler", 7 | "strict": true, 8 | "target": "ES2020" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /config/cava/config: -------------------------------------------------------------------------------- 1 | [color] 2 | 3 | gradient = 1 4 | gradient_count = 6 5 | gradient_color_1 = '#!!colors_color1' 6 | gradient_color_2 = '#!!colors_color2' 7 | gradient_color_3 = '#!!colors_color3' 8 | gradient_color_4 = '#!!colors_color4' 9 | gradient_color_5 = '#!!colors_color5' 10 | gradient_color_6 = '#!!colors_color6' 11 | -------------------------------------------------------------------------------- /nix/core/common/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | # Shared config for every system 5 | imports = [ 6 | ./boot.nix 7 | ./shell.nix 8 | ./locale.nix 9 | ./packages.nix 10 | ./security.nix 11 | ./services.nix 12 | ./networking.nix 13 | ./system.nix 14 | ./users.nix 15 | ]; 16 | } 17 | -------------------------------------------------------------------------------- /nix/core/common/users.nix: -------------------------------------------------------------------------------- 1 | { username, ... }: 2 | 3 | { 4 | # Define a user account. Don't forget to set a password with ‘passwd’. 5 | users.users.${username} = { 6 | isNormalUser = true; 7 | description = username; 8 | extraGroups = [ 9 | "networkmanager" 10 | "wheel" 11 | "docker" 12 | "wireshark" 13 | ]; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /config/hypr/hyprlandd.conf: -------------------------------------------------------------------------------- 1 | monitor=WL-1,1920x1080,0x0,1 2 | $mainMod=ALT 3 | 4 | source=~/.config/hypr/environment.conf 5 | source=~/.config/hypr/keybinds.conf 6 | source=~/.config/hypr/rules.conf 7 | source=~/.config/hypr/animations.conf 8 | 9 | misc { 10 | disable_hyprland_logo = false # im sorry :( 11 | disable_splash_rendering = false 12 | enable_anr_dialog = false 13 | } 14 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/telescope.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "nvim-telescope/telescope.nvim", 4 | dependencies = { 5 | "nvim-lua/plenary.nvim", 6 | }, 7 | opts = { 8 | defaults = { 9 | layout_config = { 10 | scroll_speed = 2, 11 | }, 12 | }, 13 | }, 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /config/hypr/animations.conf: -------------------------------------------------------------------------------- 1 | # curvies 2 | bezier=easeOutBack,0.34, 1.3, 0.64, 1 3 | bezier=easeOutExpo,0.16, 1, 0.3, 1 4 | bezier=linear,0, 0, 1, 1 5 | 6 | # animationies 7 | animation=windowsOut, 1, 3, easeOutExpo, popin 80% 8 | animation=workspaces, 1, 6, easeOutExpo, slide 9 | animation=windows, 1, 4, easeOutBack, slide 10 | animation=border, 1, 1, linear 11 | animation=borderangle, 1, 30, linear, loop 12 | -------------------------------------------------------------------------------- /config/ags/env.d.ts: -------------------------------------------------------------------------------- 1 | declare const SRC: string; 2 | 3 | declare module "inline:*" { 4 | const content: string; 5 | export default content; 6 | } 7 | 8 | declare module "*.scss" { 9 | const content: string; 10 | export default content; 11 | } 12 | 13 | declare module "*.blp" { 14 | const content: string; 15 | export default content; 16 | } 17 | 18 | declare module "*.css" { 19 | const content: string; 20 | export default content; 21 | } 22 | -------------------------------------------------------------------------------- /config/hypr/scripts.conf: -------------------------------------------------------------------------------- 1 | # polkit 2 | exec-once=systemctl --user start hyprpolkitagent 3 | 4 | # idle/sleep 5 | exec-once=hypridle 6 | 7 | # iio 8 | exec-once=iio-hyprland 9 | 10 | # mouse settings 11 | exec-once=hyprctl setcursor Bibata-Modern-Ice 24 12 | 13 | # theme setup 14 | exec-once=swww-daemon && swww clear 111111 # clear background on launch 15 | exec-once=switch-theme 16 | 17 | # playerctl 18 | exec-once=playerctld daemon 19 | 20 | # pyprland 21 | exec-once=pypr 22 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/git.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "tpope/vim-fugitive", 4 | event = "CmdlineEnter", 5 | lazy = false, 6 | }, 7 | { 8 | "lewis6991/gitsigns.nvim", 9 | event = "VeryLazy", 10 | config = function() 11 | require("gitsigns").setup({ 12 | current_line_blame_opts = { 13 | -- disappears on insert mode anyways 14 | delay = 0, 15 | }, 16 | }) 17 | end, 18 | }, 19 | } 20 | -------------------------------------------------------------------------------- /nix/core/common/networking.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | networking = { 5 | hostName = "nixos"; 6 | 7 | networkmanager = { 8 | enable = true; 9 | }; 10 | 11 | wireless.iwd = { 12 | enable = true; 13 | }; 14 | }; 15 | 16 | hardware.bluetooth = { 17 | enable = true; 18 | settings = { 19 | General = { 20 | ControllerMode = "dual"; 21 | FastConnectable = true; 22 | Experimental = true; 23 | Enable = "Source,Sink,Media,Socket"; 24 | }; 25 | }; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /config/ags/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslint from "@eslint/js"; 2 | import stylistic from "@stylistic/eslint-plugin"; 3 | import tseslint from "typescript-eslint"; 4 | 5 | export default tseslint.config({ 6 | extends: [ 7 | eslint.configs.recommended, 8 | stylistic.configs.customize({ 9 | indent: 4, 10 | quotes: "double", 11 | semi: true, 12 | }), 13 | ...tseslint.configs.stylistic, 14 | ], 15 | 16 | rules: { 17 | "@stylistic/jsx-closing-bracket-location": [1, "after-props"], 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /config/nvim/lua/misc.lua: -------------------------------------------------------------------------------- 1 | -- fix nvim not recognising common glsl filetypes 2 | vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, { 3 | pattern = { "*.glsl", "*.vert", "*.tesc", "*.tese", "*.frag", "*.geom", "*.comp" }, 4 | callback = function() vim.bo.filetype = "glsl" end, 5 | }) 6 | 7 | -- open all folds before opening 8 | vim.api.nvim_create_autocmd({ "BufReadPost", "FileReadPost" }, { command = "normal zR" }) 9 | 10 | -- Usercommand to trim trailing whitespaces (if lsp.format isnt supproted) 11 | vim.api.nvim_create_user_command("TrimWhitespace", "%s/\\s\\+$//e", {}) 12 | -------------------------------------------------------------------------------- /nix/core/common/security.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | security = { 5 | polkit.enable = true; 6 | rtkit.enable = true; 7 | }; 8 | 9 | networking.firewall = { 10 | enable = true; 11 | 12 | allowedTCPPorts = [ 13 | 22 14 | 8080 15 | 8000 16 | ]; 17 | 18 | allowedTCPPortRanges = [ 19 | # KDE Connect 20 | { 21 | from = 1714; 22 | to = 1764; 23 | } 24 | ]; 25 | allowedUDPPortRanges = [ 26 | # KDE Connect 27 | { 28 | from = 1714; 29 | to = 1764; 30 | } 31 | ]; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /nix/core/common/locale.nix: -------------------------------------------------------------------------------- 1 | { pkgs, pkgs-unstable, ... }: 2 | 3 | { 4 | # Add fonts 5 | fonts = { 6 | fontDir.enable = true; 7 | packages = [ 8 | pkgs.liberation_ttf 9 | pkgs.roboto 10 | pkgs.source-sans 11 | pkgs.nerd-fonts.jetbrains-mono 12 | pkgs-unstable.font-awesome 13 | ]; 14 | }; 15 | 16 | # Select internationalisation properties. 17 | i18n.defaultLocale = "en_GB.UTF-8"; 18 | 19 | # Configure keymap in X11 20 | services.xserver.xkb = { 21 | layout = "us"; 22 | variant = ""; 23 | }; 24 | 25 | # Configure console keymap 26 | console.keyMap = "us"; 27 | } 28 | -------------------------------------------------------------------------------- /config/ags/style.scss: -------------------------------------------------------------------------------- 1 | @use "scss/colors"; 2 | 3 | // window stuff 4 | @use "scss/bar"; 5 | @use "scss/mpris"; 6 | @use "scss/glance"; 7 | @use "scss/powermenu"; 8 | @use "scss/media"; 9 | @use "scss/replaymenu"; 10 | @use "scss/notifications"; 11 | 12 | * { 13 | all: initial; 14 | font: { 15 | family: JetBrainsMono NF; 16 | size: 14px; 17 | weight: bold; 18 | } 19 | 20 | label { 21 | color: colors.$text; 22 | } 23 | 24 | image { 25 | color: colors.$text; 26 | } 27 | } 28 | 29 | tooltip label { 30 | background-color: colors.$primary; 31 | padding: 5px 15px; 32 | border-radius: 20px; 33 | } 34 | -------------------------------------------------------------------------------- /nix/core/common/shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | # set zsh as default 5 | environment.shells = [ pkgs.zsh ]; 6 | users.defaultUserShell = pkgs.zsh; 7 | 8 | # enable git 9 | programs.git.enable = true; 10 | 11 | programs.appimage = { 12 | enable = true; 13 | binfmt = true; 14 | }; 15 | 16 | programs.nix-ld.enable = true; 17 | 18 | programs.zsh = { 19 | enable = true; 20 | autosuggestions.enable = true; 21 | syntaxHighlighting.enable = true; 22 | 23 | ohMyZsh = { 24 | enable = true; 25 | theme = "juanghurtado"; 26 | plugins = [ 27 | "git" 28 | "sudo" 29 | ]; 30 | }; 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /nix/core/common/system.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | # This value determines the NixOS release from which the default 5 | # settings for stateful data, like file locations and database versions 6 | # on your system were taken. It‘s perfectly fine and recommended to leave 7 | # this value at the release version of the first install of this system. 8 | # Before changing this value read the documentation for this option 9 | # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 10 | system.stateVersion = "24.05"; # Did you read the comment? 11 | 12 | nix.settings.experimental-features = [ 13 | "nix-command" 14 | "flakes" 15 | ]; 16 | } 17 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/neotree.lua: -------------------------------------------------------------------------------- 1 | return { 2 | "nvim-neo-tree/neo-tree.nvim", 3 | branch = "v3.x", 4 | lazy = false, 5 | dependencies = { 6 | "nvim-lua/plenary.nvim", 7 | "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended 8 | "MunifTanjim/nui.nvim", 9 | }, 10 | config = function() 11 | require("neo-tree").setup({ 12 | window = { 13 | width = 30, 14 | }, 15 | filesystem = { 16 | group_empty_dirs = true, 17 | }, 18 | }) 19 | end, 20 | -- Ensure the plugin is only configured after the dependencies are loaded 21 | } 22 | -------------------------------------------------------------------------------- /nix/core/asus/iio.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | hardware.sensor.iio = { 4 | enable = true; 5 | }; 6 | 7 | programs.iio-hyprland = { 8 | enable = true; 9 | }; 10 | 11 | # accel_3d stops updating after a suspend, forcing a read causes it to update and work.. weird fix but ok 12 | systemd.services.iio-poller = { 13 | description = "Polls IIO accelerometer to force updates for auto-rotation"; 14 | wantedBy = [ "multi-user.target" ]; 15 | serviceConfig = { 16 | Type = "simple"; 17 | ExecStart = "/bin/sh -c 'while true; do cat /sys/bus/iio/devices/iio:device*/in_accel_x_raw > /dev/null; sleep 2; done'"; 18 | Restart = "always"; 19 | }; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /nix/core/common/services.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | services = { 5 | pipewire = { 6 | enable = true; 7 | pulse.enable = true; 8 | jack.enable = true; 9 | alsa = { 10 | enable = true; 11 | support32Bit = true; 12 | }; 13 | }; 14 | 15 | automatic-timezoned.enable = true; 16 | gvfs.enable = true; 17 | dbus.enable = true; 18 | upower.enable = true; 19 | power-profiles-daemon.enable = true; 20 | accounts-daemon.enable = true; 21 | input-remapper.enable = true; 22 | udisks2.enable = true; 23 | openssh.enable = true; 24 | flatpak.enable = true; 25 | }; 26 | 27 | virtualisation = { 28 | libvirtd = { 29 | enable = true; 30 | qemu.vhostUserPackages = [ pkgs.virtiofsd ]; 31 | }; 32 | docker = { 33 | enable = true; 34 | }; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /config/nvim/lua/options.lua: -------------------------------------------------------------------------------- 1 | local opt = vim.opt 2 | 3 | opt.laststatus = 3 4 | opt.showmode = false 5 | 6 | opt.clipboard = "unnamedplus" 7 | opt.cursorline = true 8 | 9 | opt.expandtab = true 10 | opt.smartindent = true 11 | opt.shiftwidth = 4 12 | opt.tabstop = 4 13 | opt.softtabstop = 4 14 | opt.scrolloff = 8 15 | 16 | opt.fillchars = { eob = " " } 17 | opt.ignorecase = true 18 | opt.smartcase = true 19 | opt.mouse = "a" 20 | 21 | opt.number = true 22 | opt.numberwidth = 2 23 | opt.relativenumber = true 24 | 25 | opt.signcolumn = "yes" 26 | opt.splitbelow = true 27 | opt.splitright = true 28 | opt.termguicolors = true 29 | opt.timeoutlen = 400 30 | 31 | opt.undofile = true 32 | opt.undodir = os.getenv("HOME") .. "/.vim/undodir" 33 | opt.swapfile = false 34 | 35 | opt.updatetime = 250 36 | opt.timeoutlen = 2000 37 | 38 | opt.foldlevel = 99 39 | opt.foldlevelstart = 99 40 | opt.foldenable = true 41 | -------------------------------------------------------------------------------- /config/nvim/init.lua: -------------------------------------------------------------------------------- 1 | -- Install lazy.nvim if not already installed 2 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 3 | if not vim.loop.fs_stat(lazypath) then 4 | vim.fn.system({ 5 | "git", 6 | "clone", 7 | "--filter=blob:none", 8 | "https://github.com/folke/lazy.nvim.git", 9 | "--branch=stable", -- latest stable release 10 | lazypath, 11 | }) 12 | end 13 | vim.opt.rtp:prepend(lazypath) 14 | 15 | -- Use a protected call so we don't error out on first use 16 | local ok, lazy = pcall(require, "lazy") 17 | if not ok then 18 | return 19 | end 20 | 21 | -- set leader before lazy 22 | vim.g.mapleader = " " 23 | 24 | -- Example using a list of specs with the default options 25 | lazy.setup("plugins", { 26 | lazy = true, 27 | change_detection = { notify = false }, 28 | }) 29 | 30 | require("options") 31 | require("remaps") 32 | require("misc") 33 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/vimtex.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "lervag/vimtex", 4 | dependencies = { 5 | { 6 | "iurimateus/luasnip-latex-snippets.nvim", 7 | config = function() 8 | require("luasnip-latex-snippets").setup({ 9 | use_treesitter = true, 10 | }) 11 | end, 12 | }, 13 | }, 14 | event = "BufReadPre", 15 | config = function() 16 | vim.cmd("filetype plugin on") 17 | 18 | local g = vim.g 19 | g.localleader = "," 20 | 21 | g.vimtex_quickfix_open_on_warning = false 22 | 23 | -- treesitter handles highlights 24 | g.vimtex_syntax_enabled = false 25 | 26 | -- compilation handled by LSP (texlab) 27 | g.vimtex_compiler_enabled = false 28 | end, 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/terminal.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "akinsho/toggleterm.nvim", 4 | version = "*", 5 | config = function() 6 | -- ugly way to allow :wqa without neovim getting angry 7 | vim.api.nvim_create_autocmd({ "TermEnter" }, { 8 | callback = function() 9 | for _, buffers in ipairs(vim.fn.getbufinfo()) do 10 | local filetype = vim.api.nvim_buf_get_option(buffers.bufnr, "filetype") 11 | if filetype == "toggleterm" then 12 | vim.api.nvim_create_autocmd({ "BufWriteCmd", "FileWriteCmd", "FileAppendCmd" }, { 13 | buffer = buffers.bufnr, 14 | command = "q!", 15 | }) 16 | end 17 | end 18 | end, 19 | }) 20 | 21 | require("toggleterm").setup() 22 | end, 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /config/ags/components/MenuList.tsx: -------------------------------------------------------------------------------- 1 | import GObject from "ags/gobject"; 2 | import { FCProps } from "ags"; 3 | import { Gtk } from "ags/gtk4"; 4 | 5 | type MenuListProps = FCProps< 6 | Gtk.Box, 7 | { 8 | label: string; 9 | class: string; 10 | align: "left" | "right"; 11 | children: GObject.Object; 12 | } 13 | >; 14 | 15 | export function MenuList({ 16 | label, 17 | class: className, 18 | align, 19 | children, 20 | }: MenuListProps) { 21 | const halign = align === "left" ? Gtk.Align.START : Gtk.Align.END; 22 | 23 | return ( 24 | 25 | 26 | {align === "left" && children} 27 | 28 | 30 | {align === "right" && children} 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /nix/home/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | flake-overlays, 3 | username, 4 | ... 5 | }: 6 | 7 | { 8 | imports = [ 9 | ./packages/hyprland.nix 10 | ./packages/desktop.nix 11 | ./packages/cli.nix 12 | ./packages/dev.nix 13 | ./files/matlab.nix 14 | ./scripts.nix 15 | ]; 16 | 17 | nixpkgs.overlays = [ 18 | (final: prev: { 19 | # Your own overlays... 20 | }) 21 | ] ++ flake-overlays; 22 | 23 | home.username = username; 24 | home.homeDirectory = "/home/${username}"; 25 | home.stateVersion = "24.05"; 26 | 27 | home.sessionVariables = { 28 | EDITOR = "nvim"; 29 | CMAKE_GENERATOR = "Ninja Multi-Config"; 30 | NIXOS_OZONE_WL = "1"; 31 | # NIX_BUILD_SHELL = "zsh"; # messes up nix-shell environments 32 | }; 33 | 34 | programs.git = { 35 | enable = true; 36 | lfs.enable = true; 37 | 38 | extraConfig = { 39 | init.defaultBranch = "main"; 40 | url = { 41 | "git@github.com:" = { 42 | insteadOf = "gh:"; 43 | }; 44 | }; 45 | }; 46 | }; 47 | 48 | programs.home-manager.enable = true; 49 | } 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Abaan404 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /config/rofi/colors.rasi: -------------------------------------------------------------------------------- 1 | // @import "~/.cache/wal/colors-rofi-dark" 2 | 3 | * { 4 | background-color: @background; 5 | power-colors: @background; 6 | background: #!!primary; 7 | foreground: #!!text; 8 | border-color: #!!primary; 9 | spacing: 2; 10 | 11 | text-color: #!!text; 12 | message-background: #!!{primary}dd; 13 | active-background: #!!primary; 14 | active-foreground: @foreground; 15 | normal-background: @background; 16 | normal-foreground: @foreground; 17 | urgent-background: #!!bad; 18 | urgent-foreground: @foreground; 19 | 20 | alternate-active-background: @background; 21 | alternate-active-foreground: @foreground; 22 | alternate-normal-background: @background; 23 | alternate-normal-foreground: @foreground; 24 | alternate-urgent-background: @background; 25 | alternate-urgent-foreground: @foreground; 26 | 27 | selected-active-background: #!!accent; 28 | selected-active-foreground: @foreground; 29 | selected-normal-background: #!!accent; 30 | selected-normal-foreground: @foreground; 31 | selected-urgent-background: #!!accent; 32 | selected-urgent-foreground: @foreground; 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /config/hypr/environment.conf: -------------------------------------------------------------------------------- 1 | general { 2 | gaps_in = 5 3 | gaps_out = 10 4 | border_size = 5 5 | col.active_border = rgba(!!{colors_color5}ee) rgba(!!{colors_color6}ee) rgba(!!{colors_color7}ee) 45deg 6 | col.inactive_border = rgba(595959aa) 7 | no_focus_fallback = true 8 | resize_on_border = true 9 | 10 | layout = dwindle 11 | } 12 | 13 | decoration { 14 | rounding = 5 15 | 16 | blur { 17 | size = 10 18 | passes = 3 19 | } 20 | } 21 | 22 | input { 23 | follow_mouse = 1 24 | sensitivity = 0 25 | 26 | touchpad { 27 | disable_while_typing = false 28 | natural_scroll = true 29 | } 30 | 31 | } 32 | 33 | dwindle { 34 | pseudotile = true 35 | preserve_split = true 36 | } 37 | 38 | gestures { 39 | workspace_swipe = true 40 | workspace_swipe_touch = true 41 | workspace_swipe_cancel_ratio = 0.1 42 | workspace_swipe_forever = true 43 | } 44 | 45 | binds { 46 | focus_preferred_method = 0 # doesnt work on fullscreen 47 | } 48 | 49 | misc { 50 | disable_hyprland_logo = true # im sorry :( 51 | disable_splash_rendering = true 52 | disable_autoreload = true 53 | enable_anr_dialog = false 54 | } 55 | -------------------------------------------------------------------------------- /config/nvim/ftplugin/java.lua: -------------------------------------------------------------------------------- 1 | if not vim.g.JAVA_DEBUG_PATH then 2 | local Job = require("plenary.job") 3 | 4 | local result = Job:new({ 5 | command = "nix-instantiate", 6 | args = { 7 | "--eval-only", 8 | "--expr", 9 | "(import {}).vscode-extensions.vscjava.vscode-java-debug.outPath", 10 | }, 11 | }):sync() 12 | 13 | if result and result[1] then 14 | local outPath = string.sub(result[1], 2, string.len(result[1]) - 1) 15 | vim.g.JAVA_DEBUG_PATH = vim.fn.glob( 16 | outPath .. "/share/vscode/extensions/vscjava.vscode-java-debug/server/com.microsoft.java.debug.plugin-*.jar" 17 | ) 18 | else 19 | vim.g.JAVA_DEBUG_PATH = "" 20 | end 21 | end 22 | 23 | -- attach jdtls 24 | local config = { 25 | cmd = { 26 | "jdtls", 27 | "--data", 28 | vim.fn.stdpath("data") .. "/jdtls/" .. vim.fn.getcwd():gsub("/", "."), 29 | }, 30 | root_dir = vim.fs.dirname(vim.fs.find({ "gradlew", ".git", "mvnw" }, { upward = true })[1]), 31 | 32 | init_options = { 33 | bundles = { 34 | vim.g.JAVA_DEBUG_PATH, 35 | }, 36 | }, 37 | } 38 | 39 | require("jdtls").start_or_attach(config) 40 | -------------------------------------------------------------------------------- /nix/core/common/packages.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | # Allow unfree packages 5 | nixpkgs.config.allowUnfree = true; 6 | 7 | # List packages installed in system profile. To search, run: 8 | # $ nix search wget 9 | environment.systemPackages = [ 10 | pkgs.vim 11 | 12 | # hardware 13 | pkgs.lshw 14 | pkgs.usbutils 15 | pkgs.pciutils 16 | ]; 17 | 18 | programs.dconf = { 19 | enable = true; 20 | }; 21 | 22 | programs.hyprland = { 23 | enable = true; 24 | }; 25 | 26 | # Some programs need SUID wrappers, can be configured further or are 27 | # started in user sessions. 28 | programs.mtr = { 29 | enable = true; 30 | }; 31 | 32 | programs.gnupg.agent = { 33 | enable = true; 34 | enableSSHSupport = true; 35 | }; 36 | 37 | programs.steam = { 38 | enable = true; 39 | remotePlay.openFirewall = true; 40 | dedicatedServer.openFirewall = true; 41 | localNetworkGameTransfers.openFirewall = true; 42 | }; 43 | 44 | programs.gpu-screen-recorder = { 45 | enable = true; 46 | }; 47 | 48 | programs.virt-manager = { 49 | enable = true; 50 | }; 51 | 52 | programs.ydotool = { 53 | enable = true; 54 | }; 55 | 56 | programs.wireshark = { 57 | enable = true; 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /config/ags/scss/_animations.scss: -------------------------------------------------------------------------------- 1 | @use "sass:string"; 2 | 3 | @mixin kf-flyin($direction, $offset, $push, $id) { 4 | @keyframes flyin-#{$id} { 5 | 0% { 6 | margin-#{$direction}: -$offset; 7 | } 8 | 50% { 9 | margin-#{$direction}: 0px; 10 | } 11 | 12 | 75% { 13 | margin-#{$direction}: $offset * $push; 14 | } 15 | 16 | 100% { 17 | margin-#{$direction}: 0px; 18 | } 19 | } 20 | } 21 | 22 | @mixin kf-fade($value, $property, $id) { 23 | @keyframes fade-#{$id} { 24 | 100% { 25 | #{$property}: $value; 26 | } 27 | } 28 | } 29 | 30 | @mixin flyin( 31 | $selector, 32 | $direction, 33 | $offset: 80px, 34 | $push: 0.1, 35 | $duration: 500ms 36 | ) { 37 | #{$selector} { 38 | $unique: string.unique-id(); 39 | animation: $duration flyin-#{$unique}; // bezier is kinda buggy? 40 | 41 | @include kf-flyin($direction, $offset, $push, $id: $unique); 42 | } 43 | } 44 | 45 | @mixin fade( 46 | $selector, 47 | $color, 48 | $duration: 200ms, 49 | $property: "background-color" 50 | ) { 51 | #{$selector} { 52 | $unique: string.unique-id(); 53 | animation: $duration fade-#{$unique} forwards; 54 | 55 | @include kf-fade($color, $property, $id: $unique); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /nix/switch-theme/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "theme switcher"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | }; 8 | 9 | outputs = 10 | { 11 | nixpkgs, 12 | flake-utils, 13 | ... 14 | }: 15 | flake-utils.lib.eachDefaultSystem ( 16 | system: 17 | let 18 | pkgs = import nixpkgs { inherit system; }; 19 | pyPkgs = pkgs.python312Packages; 20 | in 21 | { 22 | devShells.${system}.default = pkgs.mkShell { 23 | buildInputs = [ 24 | pyPkgs.python-dotenv 25 | pyPkgs.requests 26 | pyPkgs.pywal 27 | pyPkgs.pillow 28 | ]; 29 | }; 30 | packages.default = pyPkgs.buildPythonApplication { 31 | pname = "switch-theme"; 32 | version = "1.0.0"; 33 | src = ./.; 34 | 35 | format = "other"; 36 | 37 | propagatedBuildInputs = [ 38 | pyPkgs.python-dotenv 39 | pyPkgs.requests 40 | pyPkgs.pywal 41 | pyPkgs.pillow 42 | ]; 43 | 44 | installPhase = '' 45 | mkdir -p $out/bin 46 | cp switch-theme.py $out/bin/switch-theme 47 | chmod +x $out/bin/switch-theme 48 | ''; 49 | }; 50 | } 51 | ); 52 | } 53 | -------------------------------------------------------------------------------- /nix/home/packages/cli.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | home.packages = [ 5 | pkgs.gpu-screen-recorder 6 | pkgs.brightnessctl 7 | pkgs.wl-clipboard 8 | pkgs.ffmpeg-full 9 | pkgs.xdg-utils 10 | pkgs.playerctl 11 | pkgs.quickemu 12 | pkgs.killall 13 | pkgs.glxinfo 14 | pkgs.ripgrep 15 | pkgs.unzip 16 | pkgs.p7zip 17 | pkgs.cava 18 | pkgs.wget 19 | pkgs.qemu 20 | pkgs.file 21 | pkgs.curl 22 | pkgs.tree 23 | pkgs.bat 24 | pkgs.fzf 25 | pkgs.jq 26 | pkgs.fd 27 | pkgs.bc 28 | ]; 29 | 30 | programs.fastfetch = { 31 | enable = true; 32 | }; 33 | 34 | services.playerctld = { 35 | enable = true; 36 | }; 37 | 38 | programs.btop = { 39 | enable = true; 40 | settings = { 41 | color_theme = "tokyo-night"; 42 | theme_background = false; 43 | graph_symbol = "block"; 44 | }; 45 | }; 46 | 47 | programs.zsh = { 48 | enable = true; 49 | autosuggestion.enable = true; 50 | syntaxHighlighting.enable = true; 51 | 52 | oh-my-zsh = { 53 | enable = true; 54 | theme = "fox"; 55 | plugins = [ 56 | "git" 57 | "sudo" 58 | ]; 59 | }; 60 | 61 | shellAliases = { 62 | vim = "nvim"; 63 | nivm = "nvim"; 64 | nvmi = "nvim"; 65 | vnim = "nvim"; 66 | 67 | lla = "ls -la"; 68 | }; 69 | }; 70 | } 71 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/lines.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "romgrk/barbar.nvim", 4 | event = "BufReadPre", 5 | dependencies = { 6 | "lewis6991/gitsigns.nvim", -- OPTIONAL: for git status 7 | "nvim-tree/nvim-web-devicons", -- OPTIONAL: for file icons 8 | }, 9 | version = "^1.0.0", -- optional: only update when a new 1.x version is released 10 | opts = { 11 | highlight_visible = false, 12 | sidebar_filetypes = { 13 | NvimTree = true, 14 | }, 15 | icons = { 16 | separator = { 17 | left = "│", 18 | }, 19 | pinned = { 20 | button = "", 21 | filename = true, 22 | }, 23 | inactive = { 24 | separator = { 25 | left = "│", 26 | }, 27 | }, 28 | }, 29 | }, 30 | }, 31 | { 32 | "nvim-lualine/lualine.nvim", 33 | lazy = false, 34 | config = function() 35 | require("lualine").setup({ 36 | options = { 37 | icons_enabled = true, 38 | component_separators = "|", 39 | section_separators = "", 40 | }, 41 | }) 42 | end, 43 | }, 44 | } 45 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/startup.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "goolord/alpha-nvim", 4 | requires = { "nvim-tree/nvim-web-devicons" }, 5 | config = function() 6 | local startify = require("alpha.themes.startify") 7 | 8 | -- ok i gotta do atleast some ricing 9 | startify.section.header.val = { 10 | " ", 11 | " ███╗ ██╗███████╗ ██████╗ ██╗ ██╗██╗███╗ ███╗ ", 12 | " ████╗ ██║██╔════╝██╔═══██╗██║ ██║██║████╗ ████║ ", 13 | " ██╔██╗ ██║█████╗ ██║ ██║██║ ██║██║██╔████╔██║ ", 14 | " ██║╚██╗██║██╔══╝ ██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║ ", 15 | " ██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ ", 16 | " ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═══╝ ╚═╝╚═╝ ╚═╝ ", 17 | " ", 18 | } 19 | require("alpha").setup(startify.config) 20 | end, 21 | }, 22 | { 23 | "projekt0n/github-nvim-theme", 24 | config = function() vim.cmd("colorscheme github_dark_dimmed") end, 25 | }, 26 | { 27 | "rmagatti/auto-session", 28 | config = function() 29 | vim.o.sessionoptions = "curdir,folds,help,tabpages,terminal,localoptions" 30 | 31 | require("auto-session").setup({ 32 | auto_restore = false, 33 | }) 34 | end, 35 | }, 36 | } 37 | -------------------------------------------------------------------------------- /nix/core/asus/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ (modulesPath + "/installer/scan/not-detected.nix") 9 | ]; 10 | 11 | boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usb_storage" "sd_mod" ]; 12 | boot.initrd.kernelModules = [ ]; 13 | boot.kernelModules = [ "kvm-amd" ]; 14 | boot.extraModulePackages = [ ]; 15 | 16 | fileSystems."/" = 17 | { device = "/dev/disk/by-uuid/0558de2c-e98c-42cd-af47-8fa0daf832b0"; 18 | fsType = "ext4"; 19 | }; 20 | 21 | fileSystems."/boot" = 22 | { device = "/dev/disk/by-uuid/325B-95BD"; 23 | fsType = "vfat"; 24 | options = [ "fmask=0077" "dmask=0077" ]; 25 | }; 26 | 27 | swapDevices = 28 | [ { device = "/dev/disk/by-uuid/4f2dd1db-539b-4283-a585-3c60c54275cf"; } 29 | ]; 30 | 31 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 32 | # (the default) this is the recommended approach. When using systemd-networkd it's 33 | # still possible to use this option, but it's recommended to use it in conjunction 34 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 35 | networking.useDHCP = lib.mkDefault true; 36 | # networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true; 37 | 38 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 39 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 40 | } 41 | -------------------------------------------------------------------------------- /config/ags/utils/window.ts: -------------------------------------------------------------------------------- 1 | import { createRoot } from "ags"; 2 | import { Gtk, Gdk } from "ags/gtk4"; 3 | 4 | export class WindowHandler { 5 | private registry = new Map Gtk.Window>(); 6 | private windows = new Map void>(); 7 | 8 | spawn_window(name: string, gdkmonitor: Gdk.Monitor) { 9 | if (this.windows.has(name)) { 10 | return; 11 | } 12 | 13 | const window_factory = this.registry.get(name); 14 | if (!window_factory) { 15 | throw Error(`Could not find window "${name}"`); 16 | } 17 | 18 | createRoot((dispose) => { 19 | const window = window_factory(gdkmonitor); 20 | const remove = () => { 21 | window.destroy(); 22 | dispose(); 23 | }; 24 | 25 | this.windows.set(name, remove); 26 | }); 27 | } 28 | 29 | destroy_window(name: string) { 30 | if (!this.windows.has(name)) { 31 | return; 32 | } 33 | 34 | const dispose = this.windows.get(name)!; 35 | dispose(); 36 | this.windows.delete(name); 37 | } 38 | 39 | toggle_window(name: string, gdkmonitor: Gdk.Monitor) { 40 | if (this.windows.has(name)) { 41 | this.destroy_window(name); 42 | } 43 | else { 44 | this.spawn_window(name, gdkmonitor); 45 | } 46 | } 47 | 48 | register_window(name: string, window_factory: (gdkmonitor: Gdk.Monitor) => Gtk.Window) { 49 | this.registry.set(name, window_factory); 50 | } 51 | } 52 | 53 | const window_handler = new WindowHandler(); 54 | export default window_handler; 55 | -------------------------------------------------------------------------------- /config/hypr/hypridle.conf: -------------------------------------------------------------------------------- 1 | general { 2 | lock_cmd = pidof hyprlock || hyprlock # avoid starting multiple hyprlock instances. 3 | before_sleep_cmd = playerctl pause; loginctl lock-session # lock and pause before suspend. 4 | after_sleep_cmd = hyprctl dispatch dpms on # to avoid having to press a key twice to turn on the display. 5 | } 6 | 7 | listener { 8 | timeout = 150 # 2.5min. 9 | on-timeout = brightnessctl -s set 10 # set monitor backlight to minimum, avoid 0 on OLED monitor. 10 | on-resume = brightnessctl -r # monitor backlight restore. 11 | } 12 | 13 | # turn off keyboard backlight, comment out this section if you dont have a keyboard backlight. 14 | listener { 15 | timeout = 150 # 2.5min. 16 | on-timeout = brightnessctl -sd platform::kbd_backlight set 0 # turn off keyboard backlight. 17 | on-resume = brightnessctl -rd platform::kbd_backlight # turn on keyboard backlight. 18 | } 19 | 20 | listener { 21 | timeout = 300 # 5min 22 | on-timeout = loginctl lock-session # lock screen when timeout has passed 23 | } 24 | 25 | listener { 26 | timeout = 330 # 5.5min 27 | on-timeout = hyprctl dispatch dpms off # screen off when timeout has passed 28 | on-resume = hyprctl dispatch dpms on # screen on when activity is detected after timeout has fired. 29 | } 30 | 31 | # TODO add a toggle to suspend on powermenu 32 | listener { 33 | timeout = 1800 # 30min 34 | on-timeout = systemctl suspend # suspend pc 35 | } 36 | -------------------------------------------------------------------------------- /nix/core/lenovo/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ (modulesPath + "/installer/scan/not-detected.nix") 9 | ]; 10 | 11 | boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "sd_mod" ]; 12 | boot.initrd.kernelModules = [ ]; 13 | boot.kernelModules = [ "kvm-amd" ]; 14 | boot.extraModulePackages = [ ]; 15 | 16 | fileSystems."/" = 17 | { device = "/dev/disk/by-uuid/abf7d3a2-6010-4be0-8f74-9ca18a1570a0"; 18 | fsType = "ext4"; 19 | }; 20 | 21 | fileSystems."/boot" = 22 | { device = "/dev/disk/by-uuid/E1DE-A98A"; 23 | fsType = "vfat"; 24 | options = [ "fmask=0077" "dmask=0077" ]; 25 | }; 26 | 27 | swapDevices = 28 | [ { device = "/dev/disk/by-uuid/f7d7d552-588d-4301-a025-5a706041d9f0"; } 29 | ]; 30 | 31 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 32 | # (the default) this is the recommended approach. When using systemd-networkd it's 33 | # still possible to use this option, but it's recommended to use it in conjunction 34 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 35 | networking.useDHCP = lib.mkDefault true; 36 | # networking.interfaces.eno1.useDHCP = lib.mkDefault true; 37 | # networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true; 38 | 39 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 40 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 41 | } 42 | -------------------------------------------------------------------------------- /nix/switch-theme/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1752436162, 24 | "narHash": "sha256-Kt1UIPi7kZqkSc5HVj6UY5YLHHEzPBkgpNUByuyxtlw=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "dfcd5b901dbab46c9c6e80b265648481aafb01f8", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixos-25.05", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "root": { 38 | "inputs": { 39 | "flake-utils": "flake-utils", 40 | "nixpkgs": "nixpkgs" 41 | } 42 | }, 43 | "systems": { 44 | "locked": { 45 | "lastModified": 1681028828, 46 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 47 | "owner": "nix-systems", 48 | "repo": "default", 49 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 50 | "type": "github" 51 | }, 52 | "original": { 53 | "owner": "nix-systems", 54 | "repo": "default", 55 | "type": "github" 56 | } 57 | } 58 | }, 59 | "root": "root", 60 | "version": 7 61 | } 62 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/misc.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "lukas-reineke/indent-blankline.nvim", 4 | main = "ibl", 5 | event = "BufReadPre", 6 | opts = {}, 7 | }, 8 | { 9 | "NvChad/nvim-colorizer.lua", 10 | event = "BufReadPre", 11 | config = function() require("colorizer").setup({}) end, 12 | }, 13 | { 14 | "koenverburg/peepsight.nvim", 15 | opts = { 16 | -- go 17 | "function_declaration", 18 | "method_declaration", 19 | "func_literal", 20 | 21 | -- typescript 22 | "class_declaration", 23 | "method_definition", 24 | "arrow_function", 25 | "function_declaration", 26 | "generator_function_declaration", 27 | "object", 28 | 29 | -- c/c++/python 30 | "class_definition", 31 | "function_definition", 32 | 33 | -- LaTeX 34 | "math_environment", 35 | "generic_environment", 36 | "section", 37 | }, 38 | }, 39 | { 40 | "0x00-ketsu/autosave.nvim", 41 | event = "InsertEnter", 42 | }, 43 | { 44 | "mbbill/undotree", 45 | event = "VeryLazy", 46 | }, 47 | { 48 | "echasnovski/mini.nvim", 49 | event = "VeryLazy", 50 | version = "*", 51 | config = function() 52 | require("mini.align").setup() 53 | require("mini.animate").setup({ 54 | cursor = { timing = function(_, n) return 100 / n end }, 55 | scroll = { enable = false }, 56 | resize = { enable = false }, 57 | open = { enable = false }, 58 | close = { enable = false }, 59 | }) 60 | end, 61 | }, 62 | } 63 | -------------------------------------------------------------------------------- /config/ags/windows/Notifications.tsx: -------------------------------------------------------------------------------- 1 | import App from "ags/gtk4/app"; 2 | import { createBinding, For } from "ags"; 3 | import { Astal, Gtk, Gdk } from "ags/gtk4"; 4 | 5 | import AstalNotifd from "gi://AstalNotifd"; 6 | import NotificationQueue, { NotificationData } from "../services/notifications"; 7 | 8 | import { Notification } from "../components/Notification"; 9 | 10 | export default function (gdkmonitor: Gdk.Monitor) { 11 | const notifd = AstalNotifd.get_default(); 12 | const notifs = NotificationQueue.get_default(); 13 | 14 | return ( 15 | self.set_default_size(-1, -1)} 17 | name="notifications" 18 | gdkmonitor={gdkmonitor} 19 | visible={createBinding(notifd, "dont_disturb").as(dont_disturb => !dont_disturb)} 20 | anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT} 21 | application={App}> 22 | 23 | 28 | 29 | {(notification: NotificationData) => ( 30 | 31 | notification.hide()} 34 | progress={createBinding(notification, "progress").as(progress => progress / notification.duration)} /> 35 | 36 | )} 37 | 38 | 39 | 40 | 41 | ) as Astal.Window; 42 | } 43 | -------------------------------------------------------------------------------- /nix/home/packages/dev.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | home.packages = [ 5 | # editors 6 | pkgs.jetbrains.idea-community 7 | pkgs.quartus-prime-lite 8 | pkgs.kdePackages.kate 9 | pkgs.neovim 10 | pkgs.vscodium 11 | pkgs.octave 12 | pkgs.matlab 13 | 14 | # debugging 15 | pkgs.vscode-extensions.vadimcn.vscode-lldb.adapter 16 | pkgs.vscode-extensions.vscjava.vscode-java-debug 17 | pkgs.gdb 18 | pkgs.lldb 19 | 20 | # lsp 21 | pkgs.vala-language-server 22 | pkgs.typescript-language-server 23 | pkgs.bash-language-server 24 | pkgs.mesonlsp 25 | pkgs.jdt-language-server 26 | pkgs.dockerfile-language-server-nodejs 27 | pkgs.docker-compose-language-service 28 | pkgs.vscode-langservers-extracted 29 | pkgs.tailwindcss-language-server 30 | pkgs.kotlin-language-server 31 | pkgs.matlab-language-server 32 | pkgs.cmake-language-server 33 | pkgs.yaml-language-server 34 | pkgs.vim-language-server 35 | pkgs.lua-language-server 36 | pkgs.glsl_analyzer 37 | pkgs.shader-slang 38 | pkgs.clang-tools 39 | pkgs.tinymist 40 | pkgs.asm-lsp 41 | pkgs.verible 42 | pkgs.pyright 43 | pkgs.hyprls 44 | pkgs.texlab 45 | pkgs.nixd 46 | 47 | # formatters 48 | pkgs.nodePackages.prettier 49 | pkgs.typstyle 50 | pkgs.eslint_d 51 | pkgs.nixfmt-rfc-style 52 | pkgs.stylua 53 | pkgs.black 54 | 55 | # treesitter 56 | pkgs.tree-sitter 57 | ]; 58 | 59 | programs.kitty = { 60 | enable = true; 61 | 62 | shellIntegration.enableZshIntegration = true; 63 | 64 | font = { 65 | name = "JetBrainsMono Nerd Font"; 66 | size = 11; 67 | }; 68 | 69 | settings = { 70 | scrollback_lines = 10000; 71 | enable_audio_bell = false; 72 | update_check_interval = 0; 73 | window_margin_width = 10; 74 | background_opacity = "0.5"; 75 | term = "xterm-256color"; 76 | }; 77 | }; 78 | } 79 | -------------------------------------------------------------------------------- /config/ags/scss/powermenu.scss: -------------------------------------------------------------------------------- 1 | @use "animations"; 2 | @use "colors"; 3 | 4 | $button-open-height: 40px; 5 | $button-highlight-height: 30px; 6 | 7 | .powermenu { 8 | margin-right: 40px; 9 | 10 | .layout-box { 11 | min-width: 300px; 12 | 13 | button { 14 | padding: $button-open-height $button-open-height; 15 | border-radius: 10px; 16 | background-color: colors.$primary; 17 | min-width: 50px; 18 | min-height: 60px; 19 | 20 | image { 21 | color: colors.$accent; 22 | } 23 | } 24 | 25 | .power button image { 26 | color: colors.$bad; 27 | } 28 | 29 | .transition-text { 30 | font-weight: bolder; 31 | font-size: 16px; 32 | color: transparent; 33 | min-width: 100px; 34 | } 35 | 36 | @each $selector in "power", "reboot", "suspend", "hibernate" { 37 | .#{$selector}:hover button { 38 | transition: 100ms linear padding; 39 | padding-top: $button-highlight-height; 40 | padding-bottom: $button-highlight-height; 41 | } 42 | 43 | .#{$selector}:not(:hover) button { 44 | transition: 100ms linear padding; 45 | padding-top: $button-open-height; 46 | padding-bottom: $button-open-height; 47 | } 48 | 49 | .#{$selector}:hover .transition-text { 50 | transition: 200ms linear color; 51 | color: colors.$accent; 52 | 53 | @include animations.flyin("&", "right"); 54 | } 55 | 56 | .#{$selector}:not(:hover) .transition-text { 57 | transition: 200ms linear color; 58 | color: transparent; 59 | } 60 | } 61 | 62 | @include animations.flyin("&", "right"); 63 | @include animations.fade("button:hover", colors.$secondary); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/nvim-cmp.lua: -------------------------------------------------------------------------------- 1 | -- Autocompletion 2 | return { 3 | { 4 | "saghen/blink.cmp", 5 | dependencies = { 6 | "L3MON4D3/LuaSnip", 7 | "xzbdmw/colorful-menu.nvim", 8 | "rafamadriz/friendly-snippets", 9 | }, 10 | version = "1.*", 11 | opts = { 12 | keymap = { 13 | preset = "default", 14 | [""] = { 'select_and_accept', 'fallback' }, 15 | [""] = { "select_next", "fallback" }, 16 | [""] = { "select_prev", "fallback" }, 17 | }, 18 | signature = { enabled = true }, 19 | appearance = { 20 | nerd_font_variant = "mono", 21 | }, 22 | completion = { 23 | documentation = { 24 | auto_show = true, 25 | }, 26 | list = { 27 | selection = { 28 | preselect = false, 29 | }, 30 | }, 31 | menu = { 32 | draw = { 33 | columns = { { "kind_icon" }, { "label", gap = 1 } }, 34 | components = { 35 | label = { 36 | text = function(ctx) return require("colorful-menu").blink_components_text(ctx) end, 37 | highlight = function(ctx) 38 | return require("colorful-menu").blink_components_highlight(ctx) 39 | end, 40 | }, 41 | }, 42 | }, 43 | }, 44 | }, 45 | sources = { 46 | default = { "lsp", "path", "snippets", "buffer" }, 47 | }, 48 | fuzzy = { implementation = "lua" }, 49 | }, 50 | opts_extend = { 51 | "sources.default", 52 | }, 53 | }, 54 | } 55 | -------------------------------------------------------------------------------- /config/hypr/rules.conf: -------------------------------------------------------------------------------- 1 | # workspaces: (1 Main) (2 Dev) (3 Games) (4 Media) 2 | 3 | # floating rules 4 | windowrulev2=float, class:vlc 5 | windowrulev2=float, class:qt5ct 6 | windowrulev2=float, class:lutris 7 | windowrulev2=float, class:zenity 8 | windowrulev2=float, class:swayimg.+ 9 | windowrulev2=float, class:nwg-look 10 | windowrulev2=float, class:pavucontrol 11 | windowrulev2=float, class:kvantummanager 12 | windowrulev2=float, class:blueman-manager 13 | windowrulev2=float, class:org.kde.kate 14 | windowrulev2=float, class:org.kde.dolphin 15 | windowrulev2=float, class:org.kde.polkit-kde-authentication-agent-1 16 | windowrulev2=float, class:org.prismlauncher.PrismLauncher 17 | windowrulev2=float, title:Picture-in-Picture 18 | windowrulev2=float, title:DevTools 19 | windowrulev2=float, title:gjs 20 | 21 | # wlroots 22 | windowrulev2=workspace 5, class:wlroots 23 | windowrulev2=fullscreen, class:wlroots 24 | 25 | # swayimg rules 26 | windowrulev2=size 60% 60%, class:swayimg.+ 27 | 28 | # octave 29 | windowrulev2=float, class:octave-gui 30 | windowrulev2=size 60% 80%, class:octave-gui 31 | windowrulev2=center, class:octave-gui 32 | 33 | # firefox rules 34 | windowrulev2=move 65% 10%, title:Picture-in-Picture 35 | windowrulev2=pin, title:Picture-in-Picture 36 | 37 | # dolphin window rule 38 | windowrulev2=size 80% 80%, title:Home — Dolphin 39 | 40 | # amongus 41 | windowrulev2=workspace 3, class:org.prismlauncher.PrismLauncher 42 | windowrulev2=workspace 3, class:lutris 43 | 44 | # media 45 | windowrulev2=workspace 4, class:Spotify 46 | windowrulev2=workspace 4, title:Spotify Premium 47 | windowrulev2=workspace 4, class:vesktop 48 | 49 | # pyprland stuff 50 | windowrulev2=float, class:kitty-dropterm 51 | windowrulev2=workspace special silent, class:kitty-dropterm 52 | windowrulev2=size 75% 60%, class:kitty-dropterm 53 | 54 | # center rules 55 | windowrulev2=center, class:org.kde.dolphin 56 | 57 | # misc 58 | windowrulev2=float, title:PhysBuzz Engine 59 | 60 | # blur uwu 61 | layerrule=blur, wvkbd 62 | layerrule=ignorezero, wvkbd 63 | -------------------------------------------------------------------------------- /config/hypr/hyprgrass.conf: -------------------------------------------------------------------------------- 1 | plugin { 2 | touch_gestures { 3 | # The default sensitivity is probably too low on tablet screens, 4 | # I recommend turning it up to 4.0 5 | sensitivity = 4.0 6 | 7 | # must be >= 3 8 | # workspace_swipe_fingers = 3 9 | 10 | # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers 11 | # and can be used at the same time 12 | # possible values: l, r, u, or d 13 | # to disable it set it to anything else 14 | # workspace_swipe_edge = d 15 | 16 | # in milliseconds 17 | long_press_delay = 400 18 | 19 | # resize windows by long-pressing on window borders and gaps. 20 | # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating 21 | # windows 22 | resize_on_border_long_press = true 23 | 24 | # in pixels, the distance from the edge that is considered an edge 25 | edge_margin = 10 26 | 27 | experimental { 28 | # send proper cancel events to windows instead of hacky touch_up events, 29 | # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default 30 | send_cancel = 0 31 | } 32 | 33 | # swipe left from right edge 34 | # hyprgrass-bind = , edge:r:l, workspace, +1 35 | # hyprgrass-bind = , edge:l:r, workspace, -1 36 | 37 | # swipe up from bottom edge 38 | # TODO: mkderivation for mvkbd and customize it 39 | hyprgrass-bind = , edge:d:u, exec, pkill wvkbd -SIGRTMIN 40 | 41 | # swipe down with 4 fingers 42 | # NOTE: swipe events only trigger for finger count of >= 3 43 | hyprgrass-bind = , swipe:4:d, killactive 44 | 45 | # tap with 3 fingers 46 | # NOTE: tap events only trigger for finger count of >= 3 47 | hyprgrass-bind = , tap:3, fullscreen 48 | 49 | # longpress can trigger mouse binds: 50 | hyprgrass-bindm = , longpress:2, movewindow 51 | hyprgrass-bindm = , longpress:3, resizewindow 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /justfile: -------------------------------------------------------------------------------- 1 | set dotenv-load 2 | 3 | install system: 4 | # create system-specific config 5 | mkdir -p ./nix/core/{{system}} 6 | echo -e '{ ... }:\n\n{\n imports = [\n ./hardware-configuration.nix\n ];\n}' > ./nix/core/{{system}}/default.nix 7 | cp /etc/nixos/hardware-configuration.nix ./nix/core/{{system}} 8 | 9 | # add a nixosConfigurations entry into flake.nix 10 | grep -q "{{system}} =" ./flake.nix && exit 0 || awk -v conf={{system}} '1; /nixosConfigurations = {/ {print " " conf " = nixpkgs.lib.nixosSystem {\n inherit system;\n\n specialArgs = {\n username = \"abaan404\";\n\n inherit inputs;\n inherit pkgs-unstable;\n };\n\n modules = [\n ./nix/core/common\n ./nix/core/" conf "\n ];\n };\n"}' ./flake.nix > tmp && mv tmp ./flake.nix 11 | 12 | # add to git bc nix doesnt like it when you dont 13 | git add ./nix/core/{{system}}/* 14 | git add ./flake.nix 15 | 16 | # save the current system 17 | echo "SYSTEM={{system}}" >> ./.env 18 | 19 | # switch to new dots 20 | just switch 21 | 22 | # copy default wallpapers 23 | install -m 644 -v -D $(readlink -f $(which Hyprland) | cut -c-59)/share/hypr/wall* -t ~/Pictures/wallpapers/ 24 | 25 | # load configs 26 | switch-theme 27 | 28 | echo "Installation Completed. Run 'Hyprland' as a command to begin" 29 | 30 | switch-nixos: 31 | @if [[ -z "${SYSTEM-}" ]]; then \ 32 | echo "No system configuration found, either rerun \`just install\` or add your \$SYSTEM into your .env that matches your nixosConfigurations system"; \ 33 | exit 1; \ 34 | fi 35 | 36 | sudo nixos-rebuild switch --flake .#"$SYSTEM" 37 | 38 | switch-hm: 39 | home-manager switch --flake ~/.dotfiles 40 | 41 | switch: 42 | just switch-nixos 43 | just switch-hm 44 | 45 | rollback: 46 | sudo nixos-rebuild switch --rollback 47 | 48 | update: 49 | nix flake update 50 | just switch 51 | 52 | gc: 53 | # why cant both be one command? 54 | sudo nix-collect-garbage -d 55 | nix-collect-garbage -d 56 | 57 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/editing.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "windwp/nvim-autopairs", 4 | event = "InsertEnter", 5 | opts = {}, 6 | }, 7 | { 8 | "kylechui/nvim-surround", 9 | version = "*", -- Use for stability; omit to use `main` branch for the latest features 10 | event = "VeryLazy", 11 | config = function() 12 | require("nvim-surround").setup({ 13 | -- Configuration here, or leave empty to use defaults 14 | }) 15 | end, 16 | }, 17 | { 18 | "Wansmer/treesj", 19 | keys = { "m", "j", "s" }, 20 | dependencies = { "nvim-treesitter/nvim-treesitter" }, 21 | config = function() 22 | require("treesj").setup({ 23 | use_default_keymaps = false, 24 | max_join_length = 1200, -- gotta love js/ts lambdas 25 | }) 26 | end, 27 | }, 28 | { 29 | "danymat/neogen", 30 | dependencies = "nvim-treesitter/nvim-treesitter", 31 | config = function() 32 | require("neogen").setup({ 33 | languages = { 34 | ["c.doxygen"] = require("neogen.configurations.c"), 35 | ["cpp.doxygen"] = require("neogen.configurations.cpp"), 36 | ["python.google_docstrings"] = require("neogen.configurations.python"), 37 | ["javascript.jsdoc"] = require("neogen.configurations.javascript"), 38 | ["javascriptreact.jsdoc"] = require("neogen.configurations.javascriptreact"), 39 | }, 40 | snippet_engine = "luasnip", 41 | }) 42 | end, 43 | }, 44 | { 45 | "kevinhwang91/nvim-ufo", 46 | dependencies = { 47 | "nvim-treesitter/nvim-treesitter", 48 | "kevinhwang91/promise-async", 49 | }, 50 | config = function() 51 | require("ufo").setup({ 52 | provider_selector = function(_) return { "treesitter", "indent" } end, 53 | }) 54 | end, 55 | }, 56 | { 57 | "windwp/nvim-ts-autotag", 58 | event = "BufReadPre", 59 | }, 60 | } 61 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/treesitter.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "nvim-treesitter/playground", 4 | }, 5 | { 6 | "nvim-treesitter/nvim-treesitter", 7 | config = function() 8 | ---@diagnostic disable-next-line: missing-fields 9 | require("nvim-treesitter.configs").setup({ 10 | ensure_installed = { 11 | "vim", 12 | "vimdoc", 13 | "bash", 14 | 15 | "lua", 16 | 17 | "html", 18 | "css", 19 | "scss", 20 | "java", 21 | "javascript", 22 | "typescript", 23 | "tsx", 24 | "svelte", 25 | 26 | "c", 27 | "cpp", 28 | "glsl", 29 | "cmake", 30 | "meson", 31 | "typst", 32 | 33 | "markdown", 34 | "markdown_inline", 35 | 36 | "python", 37 | "dockerfile", 38 | 39 | "ini", 40 | "json", 41 | "toml", 42 | "yuck", 43 | 44 | "latex", 45 | "matlab", 46 | }, 47 | 48 | sync_install = false, 49 | auto_install = true, 50 | 51 | highlight = { 52 | enable = true, 53 | additional_vim_regex_highlighting = false, 54 | }, 55 | }) 56 | 57 | -- attach ts to typst ft 58 | -- vim.treesitter.language.register("typst", "typ") 59 | vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, { 60 | pattern = { "*.typ" }, 61 | callback = function() vim.opt.filetype = "typst" end, 62 | }) 63 | 64 | -- attach ts to glsl ft 65 | for _, value in ipairs({ "glsl", "vert", "tesc", "tese", "frag", "geom", "comp" }) do 66 | vim.treesitter.language.register("glsl", value) 67 | end 68 | end, 69 | }, 70 | } 71 | -------------------------------------------------------------------------------- /config/ags/scss/mpris.scss: -------------------------------------------------------------------------------- 1 | @use "animations"; 2 | @use "colors"; 3 | 4 | .mpris { 5 | .layout-box { 6 | margin: 20px; 7 | background-color: colors.$primary; 8 | border-radius: 10px; 9 | 10 | .left { 11 | border-radius: 10px; 12 | background-color: colors.$secondary; 13 | 14 | picture { 15 | border-radius: 10px; 16 | } 17 | 18 | .controls { 19 | padding: 10px 20px; 20 | 21 | @include animations.fade( 22 | "button:hover image", 23 | white, 24 | $property: "color" 25 | ); 26 | @include animations.fade( 27 | "button:active image", 28 | colors.$text, 29 | $property: "color" 30 | ); 31 | } 32 | } 33 | 34 | .right { 35 | padding: 10px; 36 | padding-left: 20px; 37 | padding-right: 40px; 38 | 39 | .duration { 40 | font-size: 1em; 41 | } 42 | 43 | .title { 44 | font-size: 2.5em; 45 | font-weight: bolder; 46 | } 47 | 48 | .artist { 49 | font-size: 1.5em; 50 | font-weight: bold; 51 | } 52 | 53 | .active-player-control { 54 | @include animations.fade( 55 | "&:hover label", 56 | colors.$accent, 57 | $property: "color" 58 | ); 59 | @include animations.fade( 60 | "&:active label", 61 | colors.$text, 62 | $property: "color" 63 | ); 64 | } 65 | 66 | scale { 67 | background-color: colors.$secondary; 68 | margin: 10px 0px; 69 | border-radius: 10px; 70 | 71 | slider { 72 | min-height: 6px; 73 | } 74 | 75 | highlight { 76 | background-color: colors.$text; 77 | border-radius: 10px; 78 | } 79 | } 80 | } 81 | } 82 | 83 | @include animations.flyin("&", "top"); 84 | } 85 | -------------------------------------------------------------------------------- /config/ags/scss/replaymenu.scss: -------------------------------------------------------------------------------- 1 | @use "animations"; 2 | @use "colors"; 3 | 4 | $button-open-height: 40px; 5 | $button-highlight-height: 30px; 6 | 7 | .replaymenu { 8 | margin-left: 40px; 9 | 10 | .layout-box { 11 | min-width: 450px; 12 | 13 | button { 14 | padding: $button-open-height $button-open-height; 15 | border-radius: 10px; 16 | background-color: colors.$primary; 17 | min-width: 50px; 18 | min-height: 60px; 19 | 20 | image { 21 | color: colors.$accent; 22 | } 23 | } 24 | 25 | .transition-text { 26 | font-weight: bolder; 27 | font-size: 16px; 28 | color: transparent; 29 | min-width: 100px; 30 | } 31 | 32 | .record { 33 | .pause { 34 | margin-left: 20px; 35 | } 36 | 37 | @include animations.fade(".recording", colors.$good); 38 | @include animations.fade(".paused", colors.$warning); 39 | } 40 | 41 | .replay { 42 | @include animations.fade(".disabled", colors.$bad); 43 | } 44 | 45 | .microphone { 46 | @include animations.fade(".disabled", colors.$bad); 47 | } 48 | 49 | @each $selector in "replay", "record", "microphone" { 50 | .#{$selector}:hover button { 51 | transition: 100ms linear padding; 52 | padding-top: $button-highlight-height; 53 | padding-bottom: $button-highlight-height; 54 | } 55 | 56 | .#{$selector}:not(:hover) button { 57 | transition: 100ms linear padding; 58 | padding-top: $button-open-height; 59 | padding-bottom: $button-open-height; 60 | } 61 | 62 | .#{$selector}:hover .transition-text { 63 | transition: 200ms linear color; 64 | color: colors.$accent; 65 | 66 | @include animations.flyin("&", "left"); 67 | } 68 | 69 | .#{$selector}:not(:hover) .transition-text { 70 | transition: 200ms linear color; 71 | color: transparent; 72 | } 73 | } 74 | 75 | @include animations.flyin("&", "left"); 76 | @include animations.fade("button:hover", colors.$secondary); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Hyprland w/ pywal

2 | 3 |
4 |

Now with unlimited color themes!

5 | 6 | 7 | 8 |
9 | 10 | > For a showcase video see [here](https://www.youtube.com/watch?v=nNvciN4sGKQ). 11 | 12 | ### Installation 13 | 14 | 1. Grab a [NixOS ISO](https://nixos.org/download/) iso and create a minimal install. 15 | 16 | 2. Clone the repository and run the install script. 17 | 18 | ```bash 19 | nix-shell -p git just home-manager 20 | 21 | git clone https://github.com/abaan404/dotfiles ~/.dotfiles 22 | cd ~/.dotfiles 23 | 24 | just install 25 | 26 | # run hyprland through the tty 27 | Hyprland 28 | ``` 29 | 30 | _Note: if something went wrong, run `git reset --hard origin/main` to revert to a base state, this will erase any changes made in ~/.dotfiles (but you can get it back from `git reflog`)_ 31 | 32 | 3. Add a `.env` file with the following entries for weather and unsplash support. 33 | 34 | ```sh 35 | OPENWEATHER_API_KEY= # https://openweathermap.org/api 36 | OPENWEATHER_LOCATION= # https://openweathermap.org/city 37 | UNSPLASH_ACCESS_KEY= # https://unsplash.com/developers 38 | ``` 39 | 40 | 4. Change any configs to your liking (i.e. username, git, etc). 41 | 42 | 5. Reboot (if needed) and simply run `Hyprland` from the tty. 43 | 44 | ### Notes 45 | 46 | - Switch theme with SUPER + H, see `./config/hypr/keybinds.conf` for all keybinds. 47 | - while nix is meant to manage your configs, `~/.dotfiles/nix/switch-theme/switch-theme.py` will also manage them by copying `~/.dotfiles/config` into `~/.config` while it overwrites certain keys for theming purposes. 48 | - The wallpaper path (`~/Pictures/wallpapers/`) and pywal backend (`colorthief`) can be modified within the `./nix/switch-theme/switch-theme.py` file. 49 | - The way this repo is setup, it expects that you have this repo cloned in `~/.dotfiles` exactly as is and with your `.env` variables defined in the same directory. 50 | 51 | ### Credits and Acknowledgements 52 | 53 | - [end-4/dots-hyprland](https://github.com/end-4/dots-hyprland)'s wonderful dots and [dharmax](https://dharmx.is-a.dev/eww-powermenu/)'s guide to get me started on eww. 54 | - Kvantum Theme (modified with pywal) by [vinceliuice/Layan-kde](https://github.com/vinceliuice/Layan-kde). 55 | - my sanity for keeping up with me (it didnt). 56 | -------------------------------------------------------------------------------- /config/ags/scss/media.scss: -------------------------------------------------------------------------------- 1 | @use "animations"; 2 | @use "colors"; 3 | 4 | .media { 5 | .layout-box { 6 | min-width: 480px; 7 | margin: 20px; 8 | background-color: colors.$color1; 9 | border-radius: 10px; 10 | padding: 15px; 11 | 12 | .endpoint-slider, 13 | .stream-slider { 14 | margin: 5px 0px; 15 | 16 | .mute, 17 | .list { 18 | @include animations.fade( 19 | "&:hover label", 20 | colors.$accent, 21 | $property: "color" 22 | ); 23 | @include animations.fade( 24 | "&:active label", 25 | colors.$text, 26 | $property: "color" 27 | ); 28 | } 29 | 30 | .mute label { 31 | font: { 32 | size: 1.25em; 33 | weight: bolder; 34 | } 35 | } 36 | 37 | scale { 38 | background-color: colors.$color2; 39 | border-radius: 10px; 40 | margin-top: 10px; 41 | 42 | slider { 43 | min-height: 10px; 44 | } 45 | 46 | highlight { 47 | background-color: colors.$accent; 48 | border-radius: 10px; 49 | } 50 | } 51 | 52 | .name { 53 | min-height: 2em; 54 | background-color: colors.$primary; 55 | padding: 0px 14px; 56 | border-radius: 10px; 57 | } 58 | 59 | .default { 60 | background-color: colors.$secondary; 61 | } 62 | 63 | .available { 64 | padding-top: 10px; 65 | 66 | .name { 67 | @include animations.fade("&:hover", colors.$accent); 68 | @include animations.fade("&:active", colors.$primary); 69 | } 70 | } 71 | } 72 | } 73 | 74 | .mixer { 75 | .show { 76 | background-color: colors.$primary; 77 | border-radius: 20px; 78 | 79 | label { 80 | padding: 10px; 81 | } 82 | 83 | @include animations.fade("&:hover", colors.$accent); 84 | @include animations.fade("&:active", colors.$primary); 85 | } 86 | 87 | .streams { 88 | padding-top: 10px; 89 | } 90 | } 91 | 92 | @include animations.flyin("&", "top"); 93 | } 94 | -------------------------------------------------------------------------------- /config/ags/services/activeplayer.ts: -------------------------------------------------------------------------------- 1 | import GObject, { register, getter } from "ags/gobject"; 2 | 3 | import AstalMpris from "gi://AstalMpris"; 4 | 5 | @register({ GTypeName: "ActivePlayer" }) 6 | export default class ActivePlayer extends GObject.Object { 7 | static instance: ActivePlayer; 8 | 9 | static get_default() { 10 | if (!this.instance) 11 | this.instance = new ActivePlayer(); 12 | 13 | return this.instance; 14 | } 15 | 16 | private mpris: AstalMpris.Mpris = AstalMpris.get_default(); 17 | private readonly ignored_bus_names: string[] = [ 18 | "org.mpris.MediaPlayer2.playerctld", 19 | ]; 20 | 21 | private _players: AstalMpris.Player[] = []; 22 | private _active_player = 0; 23 | 24 | @getter(AstalMpris.Player) get player() { 25 | return this._players[this._active_player] ?? null; 26 | } 27 | 28 | next_player() { 29 | this._active_player++; 30 | 31 | if (this._active_player >= this._players.length) { 32 | this._active_player = 0; 33 | } 34 | 35 | this.notify("player"); 36 | } 37 | 38 | prev_player() { 39 | this._active_player--; 40 | 41 | if (this._active_player < 0) { 42 | this._active_player = this._players.length - 1; 43 | } 44 | 45 | this.notify("player"); 46 | } 47 | 48 | constructor() { 49 | super(); 50 | 51 | this.mpris.get_players() 52 | .sort((p1, p2) => { 53 | // always keep spotify as the last element in the array 54 | if (p1.get_bus_name() === "org.mpris.MediaPlayer2.spotify") { 55 | return 1; 56 | } 57 | 58 | if (p2.get_bus_name() === "org.mpris.MediaPlayer2.spotify") { 59 | return -1; 60 | } 61 | 62 | return 0; 63 | }) 64 | .forEach((player) => { 65 | if (this.ignored_bus_names.includes(player.get_bus_name())) { 66 | return; 67 | } 68 | 69 | this._players.unshift(player); 70 | this.notify("player"); 71 | }); 72 | 73 | this.mpris.connect_after("player-added", (_, player) => { 74 | if (this.ignored_bus_names.includes(player.get_bus_name())) { 75 | return; 76 | } 77 | 78 | this._players.unshift(player); 79 | this.notify("player"); 80 | }); 81 | 82 | this.mpris.connect_after("player-closed", (_, player) => { 83 | const idx = this._players.findIndex(p => p.get_bus_name() === player.get_bus_name()); 84 | if (idx !== -1) { 85 | this._players.splice(idx, 1); 86 | this.notify("player"); 87 | } 88 | }); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /config/ags/utils/helpers.ts: -------------------------------------------------------------------------------- 1 | import AstalNetwork from "gi://AstalNetwork"; 2 | import AstalNotifd from "gi://AstalNotifd"; 3 | 4 | export function to_timestamp(value: number) { 5 | const hour = Math.round(value / 3600).toString().padStart(2, "0"); 6 | const minute = Math.round(value / 60 % 60).toString().padStart(2, "0"); 7 | const second = Math.round(value % 60).toString().padStart(2, "0"); 8 | 9 | if (value > 3600) 10 | return `${hour}:${minute}:${second}`; 11 | else 12 | return `${minute}:${second}`; 13 | } 14 | 15 | export function truncate(value: string, limit: number) { 16 | if (value.length < limit) 17 | return value; 18 | 19 | return `${value.slice(0, limit - 3)}...`; 20 | } 21 | 22 | export function get_player_name(name: string) { 23 | return name 24 | .replace(/org\.mpris\.MediaPlayer2\./, "") 25 | .replace(/\..*/, ""); 26 | } 27 | 28 | export function get_player_glyph(name: string) { 29 | switch (get_player_name(name)) { 30 | case "firefox": 31 | return ""; 32 | case "spotify": 33 | return ""; 34 | case "discord": 35 | return ""; 36 | default: 37 | return ""; 38 | } 39 | } 40 | 41 | export function get_active_profile_name(active_profile: string) { 42 | switch (active_profile) { 43 | case "power-saver": 44 | return "Power Saving"; 45 | 46 | case "balanced": 47 | return "Balanced"; 48 | 49 | case "performance": 50 | return "Performance"; 51 | 52 | default: 53 | return "Performance"; 54 | } 55 | } 56 | 57 | export function get_internet_name(internet: AstalNetwork.Internet) { 58 | switch (internet) { 59 | case AstalNetwork.Internet.DISCONNECTED: 60 | return "failed"; 61 | 62 | case AstalNetwork.Internet.CONNECTED: 63 | return "success"; 64 | 65 | case AstalNetwork.Internet.CONNECTING: 66 | return "waiting"; 67 | 68 | default: 69 | return "failed"; 70 | } 71 | } 72 | 73 | export function get_urgency_name(urgency: AstalNotifd.Urgency) { 74 | switch (urgency) { 75 | case AstalNotifd.Urgency.LOW: 76 | return "low"; 77 | 78 | case AstalNotifd.Urgency.NORMAL: 79 | return "normal"; 80 | 81 | case AstalNotifd.Urgency.CRITICAL: 82 | return "critical"; 83 | 84 | default: 85 | return "low"; 86 | } 87 | } 88 | 89 | export function symbolic_strength(value: number, array: string[], max: number) { 90 | const interp = Math.floor((value / max) * array.length); 91 | return array[Math.min(interp, array.length - 1)]; 92 | } 93 | 94 | export function clamp(value: number, min: number, max: number) { 95 | return Math.min(Math.max(value, min), max); 96 | } 97 | -------------------------------------------------------------------------------- /config/ags/scss/notifications.scss: -------------------------------------------------------------------------------- 1 | @use "animations"; 2 | @use "colors"; 3 | 4 | .notifications { 5 | .layout-box { 6 | margin: 20px; 7 | border-radius: 10px; 8 | } 9 | } 10 | 11 | .notification { 12 | background-color: colors.$primary; 13 | padding: 10px; 14 | border-radius: 10px; 15 | 16 | .header { 17 | .time, 18 | .app-name { 19 | min-height: 2em; 20 | background-color: colors.$secondary; 21 | padding: 0px 14px; 22 | border-radius: 10px; 23 | } 24 | 25 | .critical { 26 | background-color: colors.$bad; 27 | } 28 | 29 | .hide { 30 | min-height: 2em; 31 | background-color: colors.$accent; 32 | padding: 0px 8px; 33 | border-radius: 10px; 34 | 35 | @include animations.fade("&:hover", colors.$color6); 36 | @include animations.fade("&:active", colors.$accent); 37 | } 38 | 39 | .dismiss { 40 | min-height: 2em; 41 | background-color: colors.$accent; 42 | padding: 0px 8px; 43 | border-radius: 10px; 44 | 45 | @include animations.fade("&:hover", colors.$bad); 46 | @include animations.fade("&:active", colors.$accent); 47 | } 48 | } 49 | 50 | .data { 51 | background-color: colors.$secondary; 52 | border-radius: 10px; 53 | 54 | .image { 55 | min-height: 64px; 56 | min-width: 64px; 57 | } 58 | 59 | picture { 60 | min-height: 64px; 61 | border-radius: 10px; 62 | } 63 | 64 | .info { 65 | padding: 15px 10px; 66 | 67 | .summary { 68 | font-weight: bolder; 69 | font-size: 1.25em; 70 | } 71 | 72 | .body { 73 | font-size: 0.9em; 74 | } 75 | } 76 | } 77 | 78 | .actions { 79 | button { 80 | min-height: 2em; 81 | background-color: colors.$accent; 82 | padding: 0px 14px; 83 | border-radius: 10px; 84 | 85 | @include animations.fade("&:hover", colors.$good); 86 | @include animations.fade("&:active", colors.$accent); 87 | } 88 | } 89 | 90 | progressbar { 91 | trough { 92 | background-color: colors.$color2; 93 | min-height: 10px; 94 | border-radius: 10px; 95 | 96 | progress { 97 | background-color: colors.$accent; 98 | min-height: 10px; 99 | border-radius: 10px; 100 | } 101 | } 102 | } 103 | 104 | @include animations.flyin("&", "top"); 105 | } 106 | -------------------------------------------------------------------------------- /config/ags/windows/PowerMenu.tsx: -------------------------------------------------------------------------------- 1 | import App from "ags/gtk4/app"; 2 | import { execAsync } from "ags/process"; 3 | 4 | import { MenuList } from "../components/MenuList"; 5 | import { Astal, Gdk, Gtk } from "ags/gtk4"; 6 | 7 | export default function (gdkmonitor: Gdk.Monitor) { 8 | return ( 9 | self.set_default_size(1, 1)} 11 | name="powermenu" 12 | gdkmonitor={gdkmonitor} 13 | visible={true} 14 | anchor={Astal.WindowAnchor.RIGHT} 15 | application={App}> 16 | 17 | 22 | 26 | 32 | 33 | 37 | 43 | 44 | 48 | 54 | 55 | 59 | 65 | 66 | 67 | 68 | 69 | ) as Astal.Window; 70 | } 71 | -------------------------------------------------------------------------------- /config/ags/components/EndpointSlider.tsx: -------------------------------------------------------------------------------- 1 | import { Gtk } from "ags/gtk4"; 2 | import { createBinding, createState, Accessor, FCProps, For } from "ags"; 3 | 4 | import AstalWp from "gi://AstalWp"; 5 | 6 | import { truncate } from "../utils/helpers"; 7 | 8 | type EndpointSliderProps = FCProps< 9 | Gtk.Box, 10 | { 11 | name: Accessor; 12 | mute: Accessor; 13 | current_endpoint: AstalWp.Endpoint; 14 | endpoints: Accessor; 15 | } 16 | >; 17 | 18 | export function EndpointSlider({ name, mute, current_endpoint, endpoints }: EndpointSliderProps) { 19 | const [reveal_devices, set_reveal_devices] = createState(false); 20 | 21 | return ( 22 | 25 | 27 | 43 | 47 | 52 | endpoints.filter(endpoint => endpoint.get_id() !== current_endpoint.get_id()))}> 53 | {(endpoint: AstalWp.Endpoint) => ( 54 | 62 | )} 63 | 64 | 65 | 66 | current_endpoint.set_volume(self.get_value())} /> 72 | 73 | ); 74 | } 75 | -------------------------------------------------------------------------------- /config/ags/scss/bar.scss: -------------------------------------------------------------------------------- 1 | @use "sass:list"; 2 | @use "animations"; 3 | @use "colors"; 4 | 5 | .bar { 6 | $all-modules: "launcher", "workspaces", "sysinfo", "systray", "player", 7 | "info", "audio", "power"; 8 | @each $modules in $all-modules { 9 | .#{$modules} { 10 | border-radius: 10px; 11 | background-color: colors.$primary; 12 | padding: 0px 14px; 13 | 14 | @if not list.index("workspaces", $modules) { 15 | @include animations.fade("&:hover", colors.$accent); 16 | @include animations.fade("&:active", colors.$primary); 17 | } 18 | } 19 | } 20 | 21 | .launcher { 22 | revealer { 23 | label { 24 | padding-left: 10px; 25 | } 26 | } 27 | } 28 | 29 | .systray { 30 | popover { 31 | background-color: colors.$primary; 32 | padding: 12px; 33 | border-radius: 12px; 34 | 35 | modelbutton { 36 | border-radius: 10px; 37 | 38 | label { 39 | padding: 2px 8px; 40 | } 41 | 42 | @include animations.fade("&:hover", colors.$accent); 43 | } 44 | } 45 | } 46 | 47 | .workspaces { 48 | padding: 0px; 49 | 50 | .active label { 51 | color: white; 52 | } 53 | 54 | @include animations.fade( 55 | ".inactive:hover label", 56 | white, 57 | $property: "color" 58 | ); 59 | } 60 | 61 | .systray { 62 | padding: 2px { 63 | left: 8px; 64 | right: 8px; 65 | } 66 | 67 | button { 68 | padding: 0px { 69 | left: 5px; 70 | right: 5px; 71 | } 72 | } 73 | } 74 | 75 | // audio 76 | .bluetooth { 77 | background-color: colors.$bluetooth; 78 | } 79 | 80 | .muted { 81 | background-color: colors.$bad; 82 | } 83 | 84 | .info { 85 | .battery .glyph { 86 | min-width: 1.3em; 87 | } 88 | 89 | .connecting { 90 | color: colors.$warning; 91 | } 92 | .unknown { 93 | color: colors.$bad; 94 | } 95 | 96 | revealer { 97 | label { 98 | padding-left: 5px; 99 | } 100 | } 101 | } 102 | 103 | .power { 104 | revealer { 105 | label { 106 | padding-left: 5px; 107 | } 108 | } 109 | } 110 | } 111 | 112 | // i have no idea which scope TrayItem stays under 113 | menu { 114 | background-color: colors.$primary; 115 | padding: 10px; 116 | border-radius: 10px; 117 | 118 | menuitem { 119 | border-radius: 10px; 120 | 121 | label { 122 | padding: 2px 8px; 123 | } 124 | 125 | @include animations.fade("&:hover", colors.$accent); 126 | } 127 | } 128 | 129 | menubar { 130 | menuitem { 131 | padding: 4px; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /nix/home/scripts.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | home.packages = [ 5 | # launch a python3 shell 6 | (pkgs.writeShellScriptBin "py" '' 7 | nix-shell -p "python3.withPackages (pypkgs: with pypkgs; [ $* ])" --command python3 8 | '') 9 | 10 | # screenshots 11 | (pkgs.writeShellScriptBin "screenshot" '' 12 | FILENAME=~/Pictures/screenshots/$(date +'%Y%m%d-%H%M%S_screenshot.png') 13 | mkdir -p ~/Pictures/screenshots 14 | 15 | # grab res 16 | if [[ $1 == "region" ]]; then 17 | if ! size=$(slurp -b 111111AA -c 111111AA); then 18 | exit 1 19 | fi 20 | 21 | elif [[ $1 == "window" ]]; then 22 | size=$(hyprctl -j activewindow | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"') 23 | elif [[ $1 == "screen" ]]; then 24 | size=$(hyprctl -j monitors | jq -r '.[] | "\(.x),\(.y) \(.width)x\(.height)"') 25 | fi 26 | 27 | # capture screen 28 | grim -g "$size" "$FILENAME" 29 | 30 | # dropshadow 31 | # convert $FILENAME \( +clone -background black -shadow 75x10+0+0 \) +swap -background none -layers merge +repage $FILENAME 32 | 33 | # copy to clipboard 34 | wl-copy < "$FILENAME" 35 | 36 | action=$(notify-send "Screenshot Captured" --app-name="Screenshot" --action=edit=edit --hint=string:image-path:"$FILENAME") 37 | if [[ $action == "edit" ]]; then 38 | satty --filename $FILENAME \ 39 | --output-filename "$FILENAME-edit" \ 40 | --early-exit \ 41 | --action-on-enter save-to-clipboard \ 42 | --save-after-copy \ 43 | --copy-command 'wl-copy' 44 | fi 45 | '') 46 | 47 | # nowplaying (for hyprlock) 48 | (pkgs.writeShellScriptBin "nowplaying" '' 49 | status=$(playerctl status 2>/dev/null) 50 | 51 | # early exit 52 | if [[ "$status" == "No players found" ]]; then 53 | nowplaying="Nothing is playing right now." 54 | exit 55 | fi 56 | 57 | player=$(playerctl --list-all | head -n 1) 58 | 59 | # for each player 60 | if [[ "$player" == "spotify" ]]; then 61 | nowplaying="$(playerctl --player spotify metadata --format " {{xesam:artist}} - {{xesam:title}}")" 62 | elif [[ "$player" == "firefox" ]]; then 63 | nowplaying="$(playerctl --player firefox metadata --format " {{xesam:title}}")" 64 | else 65 | nowplaying="$(playerctl metadata --format " {{xesam:title}} - {{xesam:title}}")" 66 | fi 67 | 68 | # truncate 69 | size=$(printf "%s" "$nowplaying" | wc -m) 70 | if [[ -n "$1" && $size -gt "$1" ]]; then 71 | nowplaying="$(printf "%s" "$nowplaying" | awk -v len="$1" '{print substr($0, 1, len)}')..." 72 | fi 73 | 74 | echo "$nowplaying" 75 | '') 76 | 77 | # spawn a color picker 78 | (pkgs.writeShellScriptBin "colorpicker" '' 79 | color=$(hyprpicker) 80 | 81 | if [[ -z "$color" ]]; then 82 | exit 1 83 | fi 84 | 85 | magick -size 64x64 xc:"$color" /tmp/colorpicker.png 86 | echo "$color" | wl-copy 87 | 88 | notify-send "$color" "Saved to clipboard" --hint=string:image-path:/tmp/colorpicker.png 89 | '') 90 | ]; 91 | } 92 | -------------------------------------------------------------------------------- /config/nvim/lua/plugins/dev.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "mfussenegger/nvim-dap", 4 | dependencies = { 5 | "rcarriga/nvim-dap-ui", 6 | "neovim/nvim-lspconfig", 7 | }, 8 | event = "BufReadPre", 9 | config = function() 10 | local dap = require("dap") 11 | 12 | dap.adapters.codelldb = { 13 | type = "server", 14 | port = "${port}", 15 | executable = { 16 | command = "codelldb", 17 | args = { "--port", "${port}" }, 18 | }, 19 | } 20 | 21 | dap.configurations.cpp = { 22 | { 23 | name = "Launch file", 24 | type = "codelldb", 25 | request = "launch", 26 | program = function() 27 | ---@diagnostic disable-next-line: redundant-parameter 28 | return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file") 29 | end, 30 | cwd = "${workspaceFolder}", 31 | stopOnEntry = false, 32 | }, 33 | } 34 | 35 | -- If you want to use this for Rust and C, add something like this: 36 | dap.configurations.c = dap.configurations.cpp 37 | dap.configurations.rust = dap.configurations.cpp 38 | end, 39 | }, 40 | { 41 | "rcarriga/nvim-dap-ui", 42 | dependencies = { 43 | "mfussenegger/nvim-dap", 44 | "nvim-neotest/nvim-nio", 45 | }, 46 | config = function() 47 | require("dapui").setup({ 48 | layouts = { 49 | { 50 | elements = { 51 | { 52 | id = "repl", 53 | size = 0.5, 54 | }, 55 | { 56 | id = "console", 57 | size = 0.5, 58 | }, 59 | }, 60 | position = "bottom", 61 | size = 15, 62 | }, 63 | { 64 | elements = { 65 | { 66 | id = "scopes", 67 | size = 0.5, 68 | }, 69 | { 70 | id = "stacks", 71 | size = 0.5, 72 | }, 73 | }, 74 | position = "right", 75 | size = 60, 76 | }, 77 | }, 78 | }) 79 | end, 80 | }, 81 | { 82 | "Civitasv/cmake-tools.nvim", 83 | ft = { "c", "cpp" }, 84 | config = function() 85 | require("cmake-tools").setup({ 86 | cmake_build_directory = "build/${variant:buildType}", -- this is used to specify generate directory for cmake, allows macro expansion 87 | }) 88 | end, 89 | }, 90 | } 91 | -------------------------------------------------------------------------------- /config/ags/services/brightness.ts: -------------------------------------------------------------------------------- 1 | import GObject, { register, getter } from "ags/gobject"; 2 | import { monitorFile, readFileAsync } from "ags/file"; 3 | import { exec, execAsync } from "ags/process"; 4 | import { clamp } from "../utils/helpers"; 5 | 6 | @register({ GTypeName: "Brightness" }) 7 | export default class Brightness extends GObject.Object { 8 | static instance: Brightness; 9 | static get_default() { 10 | if (!this.instance) 11 | this.instance = new Brightness(); 12 | 13 | return this.instance; 14 | } 15 | 16 | private _devices = new Map(); 17 | 18 | @getter(Array) 19 | get devices() { 20 | return Array.from(this._devices.values()); 21 | } 22 | 23 | private update_devices() { 24 | const devices_str = exec("brightnessctl -lm"); 25 | const current_devices = []; 26 | 27 | for (const line of devices_str.split("\n")) { 28 | const [name, type, brightness, _, max_brightness] = line.split(","); 29 | current_devices.push(name); 30 | 31 | if (this._devices.has(name)) { 32 | continue; 33 | } 34 | 35 | if (!["leds", "backlight"].includes(type)) { 36 | continue; 37 | } 38 | 39 | const device = new BrightnessDevice(type, name, Number(brightness), Number(max_brightness)); 40 | 41 | this._devices.set(name, device); 42 | } 43 | 44 | for (const [name, _] of this._devices) { 45 | if (current_devices.includes(name)) { 46 | continue; 47 | } 48 | 49 | this._devices.delete(name); 50 | } 51 | } 52 | 53 | constructor() { 54 | super(); 55 | 56 | this.update_devices(); 57 | } 58 | } 59 | 60 | @register({ GTypeName: "BrightnessDevice" }) 61 | class BrightnessDevice extends GObject.Object { 62 | declare static $gtype: GObject.GType; 63 | 64 | @getter(String) 65 | get type(): string { 66 | return this._type; 67 | } 68 | 69 | @getter(String) 70 | get name(): string { 71 | return this._name; 72 | } 73 | 74 | @getter(Number) 75 | get percentage(): number { 76 | return this._brightness / this._max_brightness; 77 | } 78 | 79 | set percentage(percent: number) { 80 | percent = clamp(percent, 0, 1); 81 | 82 | execAsync(`brightnessctl set -d ${this._name} ${Math.floor(percent * 100)}% -q`) 83 | .then(() => this.notify("percentage")) 84 | .catch(console.error); 85 | } 86 | 87 | private _name: string; 88 | private _type: string; 89 | private _max_brightness: number; 90 | private _brightness: number; 91 | 92 | constructor(type: string, name: string, brightness: number, max_brightness: number) { 93 | super(); 94 | 95 | this._type = type; 96 | this._name = name; 97 | this._max_brightness = max_brightness; 98 | this._brightness = brightness; 99 | 100 | monitorFile(`/sys/class/${type}/${name}/brightness`, async (f) => { 101 | this._brightness = Number(await readFileAsync(f)); 102 | this.notify("percentage"); 103 | }); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /nix/home/packages/hyprland.nix: -------------------------------------------------------------------------------- 1 | { pkgs, inputs, ... }: 2 | 3 | { 4 | home.packages = [ 5 | # hyprutils 6 | pkgs.hyprpicker 7 | pkgs.hyprlock 8 | pkgs.hypridle 9 | pkgs.pyprland 10 | 11 | # screenshot 12 | pkgs.satty 13 | pkgs.slurp 14 | pkgs.grim 15 | 16 | # theming 17 | inputs.switch-theme.packages.${pkgs.system}.default 18 | 19 | # polkit 20 | pkgs.hyprpolkitagent 21 | 22 | # wallpaper 23 | inputs.swww.packages.${pkgs.system}.default 24 | 25 | # notifications 26 | pkgs.libnotify 27 | 28 | # onscreen keyboard 29 | (pkgs.wvkbd.overrideAttrs (old: { 30 | src = pkgs.fetchFromGitHub { 31 | owner = "abaan404"; 32 | repo = "wvkbd"; 33 | rev = "06ea8ee72a61ed216bcd8fa85cbe9a31d80ee0af"; 34 | hash = "sha256-9sHc7/zmlmXwn7m1uJrc9/BM+fSfmz/oFj0oEE5lTOg="; 35 | }; 36 | })) 37 | 38 | # misc 39 | pkgs.just 40 | pkgs.wev 41 | inputs.envycontrol.packages.${pkgs.system}.envycontrol 42 | ]; 43 | 44 | programs.rofi = { 45 | enable = true; 46 | package = pkgs.rofi-wayland; 47 | font = "JetBrainsMono NF Extra-Bold 12"; 48 | theme = "~/.config/rofi/theme.rasi"; 49 | extraConfig = { 50 | modes = "drun,window,calc"; 51 | 52 | show-icons = true; 53 | 54 | drun-display-format = "{name}"; 55 | hover-select = true; 56 | matching = "regex"; 57 | 58 | drun-use-desktop-cache = true; 59 | drun-reload-desktop-cache = true; 60 | 61 | kb-primary-paste = "Control+V,Shift+Insert"; 62 | kb-secondary-paste = "Control+v,Insert"; 63 | }; 64 | plugins = [ 65 | (pkgs.rofi-calc.override { rofi-unwrapped = pkgs.rofi-wayland-unwrapped; }) 66 | ]; 67 | }; 68 | 69 | programs.ags = { 70 | enable = true; 71 | 72 | extraPackages = [ 73 | pkgs.glib-networking 74 | pkgs.libadwaita 75 | inputs.astal.packages.${pkgs.system}.astal4 76 | inputs.astal.packages.${pkgs.system}.io 77 | inputs.astal.packages.${pkgs.system}.apps 78 | inputs.astal.packages.${pkgs.system}.auth 79 | inputs.astal.packages.${pkgs.system}.battery 80 | inputs.astal.packages.${pkgs.system}.hyprland 81 | inputs.astal.packages.${pkgs.system}.mpris 82 | inputs.astal.packages.${pkgs.system}.network 83 | inputs.astal.packages.${pkgs.system}.bluetooth 84 | inputs.astal.packages.${pkgs.system}.powerprofiles 85 | inputs.astal.packages.${pkgs.system}.tray 86 | inputs.astal.packages.${pkgs.system}.wireplumber 87 | inputs.astal.packages.${pkgs.system}.notifd 88 | ]; 89 | }; 90 | 91 | wayland.windowManager.hyprland = { 92 | enable = true; 93 | settings = { 94 | "$mainMod" = "SUPER"; 95 | }; 96 | 97 | extraConfig = '' 98 | monitor=,preferred,auto,1 99 | monitor=eDP-1,preferred,auto,1,transform,0 100 | 101 | source=~/.config/hypr/environment.conf 102 | source=~/.config/hypr/scripts.conf 103 | source=~/.config/hypr/keybinds.conf 104 | source=~/.config/hypr/rules.conf 105 | source=~/.config/hypr/animations.conf 106 | source=~/.config/hypr/hyprgrass.conf 107 | source=~/.config/hypr/hyprexpo.conf 108 | ''; 109 | 110 | plugins = [ 111 | pkgs.hyprlandPlugins.hyprgrass 112 | pkgs.hyprlandPlugins.hyprexpo 113 | ]; 114 | }; 115 | } 116 | -------------------------------------------------------------------------------- /config/ags/components/StreamSlider.tsx: -------------------------------------------------------------------------------- 1 | import { Gtk } from "ags/gtk4"; 2 | import { createBinding, createState, createComputed, Accessor, FCProps, For } from "ags"; 3 | 4 | import AstalWp from "gi://AstalWp"; 5 | 6 | import { truncate } from "../utils/helpers"; 7 | 8 | type StreamSliderProps = FCProps< 9 | Gtk.Box, 10 | { 11 | stream: AstalWp.Stream; 12 | endpoints: Accessor; 13 | } 14 | >; 15 | 16 | export function StreamSlider({ stream, endpoints }: StreamSliderProps) { 17 | const [reveal_targets, set_reveal_targets] = createState(false); 18 | 19 | const targettable_endpoints = createComputed( 20 | [endpoints, createBinding(stream, "description"), createBinding(stream, "target_endpoint")], 21 | () => endpoints.get().filter(endpoint => endpoint.get_id() !== stream.get_target_endpoint()?.get_id()), 22 | ); 23 | 24 | const label = createComputed( 25 | [createBinding(stream, "description"), createBinding(stream, "target_endpoint")], 26 | (description, target_endpoint) => { 27 | return target_endpoint 28 | ? `${description} (${stream.get_target_endpoint()?.get_description()})` 29 | : description; 30 | }, 31 | ); 32 | 33 | return ( 34 | 37 | 39 | 55 | 59 | 64 | 65 | {(endpoint: AstalWp.Endpoint) => ( 66 | 74 | )} 75 | 76 | 77 | 78 | stream.set_volume(self.get_value())} /> 84 | 85 | ); 86 | } 87 | -------------------------------------------------------------------------------- /nix/home/packages/desktop.nix: -------------------------------------------------------------------------------- 1 | { pkgs, inputs, ... }: 2 | 3 | { 4 | home.packages = [ 5 | # browser 6 | pkgs.firefox 7 | inputs.zen-browser.packages.${pkgs.system}.twilight-official 8 | 9 | # file manager 10 | pkgs.libsForQt5.dolphin 11 | pkgs.kdePackages.kdegraphics-thumbnailers 12 | pkgs.kdePackages.kio-extras-kf5 13 | pkgs.kdePackages.kio-fuse 14 | pkgs.kdePackages.qtsvg 15 | pkgs.kdePackages.qtimageformats 16 | pkgs.qdirstat 17 | pkgs.kdePackages.ark 18 | 19 | # media 20 | pkgs.pavucontrol 21 | pkgs.spotify 22 | pkgs.sonusmix 23 | pkgs.vlc 24 | pkgs.video-trimmer 25 | 26 | # notetaking 27 | pkgs.kdePackages.okular 28 | pkgs.styluslabs-write 29 | pkgs.tectonic 30 | pkgs.typst 31 | 32 | # word processing 33 | pkgs.libreoffice-fresh 34 | pkgs.hunspell 35 | pkgs.hunspellDicts.uk_UA 36 | pkgs.swayimg 37 | 38 | # gamging 39 | pkgs.tetrio-desktop 40 | pkgs.prismlauncher 41 | pkgs.mcpelauncher-ui-qt 42 | pkgs.r2modman 43 | pkgs.vesktop 44 | 45 | # wine 46 | pkgs.wineWowPackages.staging 47 | pkgs.bottles 48 | pkgs.lutris 49 | pkgs.mangohud 50 | 51 | # image/video editing 52 | pkgs.davinci-resolve 53 | pkgs.kdePackages.kolourpaint 54 | pkgs.kdePackages.kdenlive 55 | pkgs.inkscape 56 | pkgs.swappy 57 | pkgs.krita 58 | pkgs.gimp3 59 | 60 | # modeling 61 | pkgs.blender 62 | pkgs.blockbench 63 | 64 | # theming 65 | pkgs.kdePackages.qtstyleplugin-kvantum 66 | pkgs.libsForQt5.qtstyleplugin-kvantum 67 | pkgs.libsForQt5.qt5ct 68 | pkgs.qt6ct 69 | pkgs.zenity 70 | 71 | # networking 72 | pkgs.blueman 73 | pkgs.networkmanagerapplet 74 | pkgs.openconnect 75 | pkgs.networkmanager-openconnect 76 | pkgs.wireshark 77 | 78 | # vnc 79 | pkgs.tigervnc 80 | ]; 81 | 82 | services.kdeconnect = { 83 | enable = true; 84 | }; 85 | 86 | fonts.fontconfig = { 87 | enable = true; 88 | 89 | defaultFonts = { 90 | # monospace abuse 91 | serif = [ "JetBrainsMono Nerd Font" ]; 92 | sansSerif = [ "JetBrainsMono Nerd Font" ]; 93 | monospace = [ "JetBrainsMono Nerd Font" ]; 94 | }; 95 | }; 96 | 97 | home.pointerCursor = { 98 | gtk.enable = true; 99 | package = pkgs.bibata-cursors; 100 | name = "Bibata-Modern-Ice"; 101 | size = 24; 102 | }; 103 | 104 | gtk = { 105 | enable = true; 106 | 107 | font = { 108 | name = "JetBrainsMono Nerd Font"; 109 | size = 11; 110 | }; 111 | 112 | iconTheme = { 113 | package = pkgs.tela-icon-theme; 114 | name = "Tela-dark"; 115 | }; 116 | 117 | theme = { 118 | package = pkgs.orchis-theme; 119 | name = "Orchis-Dark"; 120 | }; 121 | }; 122 | 123 | qt = { 124 | enable = true; 125 | platformTheme.name = "qt5ct"; 126 | 127 | style = { 128 | name = "kvantum"; 129 | package = pkgs.utterly-nord-plasma; 130 | }; 131 | }; 132 | 133 | programs.obs-studio = { 134 | enable = true; 135 | plugins = [ 136 | pkgs.obs-studio-plugins.wlrobs 137 | pkgs.obs-studio-plugins.obs-backgroundremoval 138 | pkgs.obs-studio-plugins.obs-pipewire-audio-capture 139 | ]; 140 | }; 141 | 142 | programs.zathura = { 143 | enable = true; 144 | options = { 145 | selection-clipboard = "clipboard"; 146 | }; 147 | }; 148 | 149 | services.flatpak = { 150 | enable = true; 151 | uninstallUnmanaged = false; 152 | packages = [ 153 | "org.vinegarhq.Sober" 154 | ]; 155 | }; 156 | } 157 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "abaan404's NixOS dotfiles"; 3 | 4 | inputs = { 5 | # nixpkgs 6 | nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; 7 | nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; 8 | nix-flatpak.url = "github:gmodena/nix-flatpak/?ref=latest"; 9 | 10 | # astal/ags 11 | astal = { 12 | url = "github:aylur/astal"; 13 | inputs.nixpkgs.follows = "nixpkgs"; 14 | }; 15 | 16 | ags = { 17 | url = "github:aylur/ags"; 18 | inputs.nixpkgs.follows = "nixpkgs"; 19 | }; 20 | 21 | # matlab 22 | matlab = { 23 | url = "gitlab:doronbehar/nix-matlab"; 24 | inputs.nixpkgs.follows = "nixpkgs-unstable"; 25 | }; 26 | 27 | # HM config 28 | home-manager = { 29 | url = "github:nix-community/home-manager/release-25.05"; 30 | inputs.nixpkgs.follows = "nixpkgs"; 31 | }; 32 | 33 | # envycontrol (optimus PRIME) 34 | envycontrol = { 35 | url = "github:bayasdev/envycontrol"; 36 | inputs.nixpkgs.follows = "nixpkgs"; 37 | }; 38 | 39 | # swww-git (FIXME: remove when v0.9.6 has been released) 40 | swww = { 41 | url = "github:LGFae/swww"; 42 | inputs.nixpkgs.follows = "nixpkgs"; 43 | }; 44 | 45 | # zen-browser (see: https://github.com/NixOS/nixpkgs/pull/363992#pullrequestreview-2523997020) 46 | zen-browser = { 47 | url = "github:0xc000022070/zen-browser-flake"; 48 | inputs.nixpkgs.follows = "nixpkgs-unstable"; 49 | }; 50 | 51 | # switch-theme 52 | switch-theme = { 53 | url = "path:./nix/switch-theme"; 54 | inputs.nixpkgs.follows = "nixpkgs-unstable"; 55 | }; 56 | 57 | # preconfig hardware 58 | nixos-hardware.url = "github:NixOS/nixos-hardware/master"; 59 | }; 60 | 61 | outputs = 62 | { 63 | nixpkgs, 64 | nixpkgs-unstable, 65 | home-manager, 66 | matlab, 67 | ... 68 | }@inputs: 69 | let 70 | system = "x86_64-linux"; 71 | 72 | pkgs = import nixpkgs { 73 | inherit system; 74 | config.allowUnfree = true; 75 | }; 76 | 77 | pkgs-unstable = import nixpkgs-unstable { 78 | inherit system; 79 | config.allowUnfree = true; 80 | }; 81 | 82 | flake-overlays = [ matlab.overlay ]; 83 | in 84 | { 85 | nixosConfigurations = { 86 | asus = nixpkgs.lib.nixosSystem { 87 | inherit system; 88 | 89 | specialArgs = { 90 | username = "abaan404"; 91 | 92 | inherit inputs; 93 | inherit pkgs-unstable; 94 | }; 95 | 96 | modules = [ 97 | ./nix/core/common 98 | ./nix/core/asus 99 | ]; 100 | }; 101 | 102 | lenovo = nixpkgs.lib.nixosSystem { 103 | inherit system; 104 | 105 | specialArgs = { 106 | username = "abaan404"; 107 | 108 | inherit inputs; 109 | inherit pkgs-unstable; 110 | }; 111 | 112 | modules = [ 113 | inputs.nixos-hardware.nixosModules.lenovo-ideapad-15arh05 114 | ./nix/core/common 115 | ./nix/core/lenovo 116 | ]; 117 | }; 118 | }; 119 | 120 | homeConfigurations = { 121 | abaan404 = home-manager.lib.homeManagerConfiguration { 122 | inherit pkgs; 123 | 124 | extraSpecialArgs = { 125 | username = "abaan404"; 126 | 127 | inherit inputs; 128 | inherit pkgs-unstable; 129 | inherit flake-overlays; 130 | }; 131 | 132 | modules = [ 133 | inputs.ags.homeManagerModules.default 134 | inputs.nix-flatpak.homeManagerModules.nix-flatpak 135 | 136 | ./nix/home/home.nix 137 | { 138 | programs.git = { 139 | userName = "abaan404"; 140 | userEmail = "67100191+Abaan404@users.noreply.github.com"; 141 | }; 142 | } 143 | ]; 144 | }; 145 | }; 146 | }; 147 | } 148 | -------------------------------------------------------------------------------- /config/ags/windows/ReplayMenu.tsx: -------------------------------------------------------------------------------- 1 | import App from "ags/gtk4/app"; 2 | import { Gtk, Gdk, Astal } from "ags/gtk4"; 3 | import { createBinding } from "ags"; 4 | 5 | import Recorder from "../services/recorder"; 6 | 7 | import { MenuList } from "../components/MenuList"; 8 | 9 | function ReplayButton() { 10 | const recorder = Recorder.get_default(); 11 | 12 | return ( 13 | 17 | 29 | 30 | ); 31 | } 32 | 33 | function RecordButton() { 34 | const recorder = Recorder.get_default(); 35 | 36 | return ( 37 | 41 | 42 | 51 | 55 | 63 | 64 | 65 | 66 | ); 67 | } 68 | 69 | function MicButton() { 70 | const recorder = Recorder.get_default(); 71 | 72 | return ( 73 | 77 | 86 | 87 | ); 88 | } 89 | 90 | export default function (gdkmonitor: Gdk.Monitor) { 91 | return ( 92 | self.set_default_size(1, 1)} 94 | name="replaymenu" 95 | gdkmonitor={gdkmonitor} 96 | visible={true} 97 | anchor={Astal.WindowAnchor.LEFT} 98 | application={App}> 99 | 100 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | ) as Astal.Window; 112 | } 113 | -------------------------------------------------------------------------------- /config/ags/components/Notification.tsx: -------------------------------------------------------------------------------- 1 | import Gio from "gi://Gio"; 2 | import GLib from "gi://GLib"; 3 | import Adw from "gi://Adw"; 4 | import { Gtk } from "ags/gtk4"; 5 | import { createBinding, Accessor, FCProps } from "ags"; 6 | 7 | import Notifd from "gi://AstalNotifd"; 8 | 9 | import { get_urgency_name } from "../utils/helpers"; 10 | 11 | type NotificationProps = FCProps< 12 | Gtk.Box, 13 | { 14 | notification: Notifd.Notification; 15 | onHide?: () => void; 16 | progress?: Accessor; 17 | } 18 | >; 19 | 20 | export function Notification({ notification, onHide, progress }: NotificationProps) { 21 | let image_widget = <>; 22 | let summary_widget = <>; 23 | let body_widget = <>; 24 | 25 | if (notification.get_image()) { 26 | image_widget = ( 27 | 28 | 30 | Gio.File.new_for_path(img))} /> 33 | 34 | 35 | ); 36 | } 37 | 38 | if (notification.get_summary().length > 0) { 39 | summary_widget = ( 40 |