From 9fbf576165fdd75ddd8b7a8d2a9fb35cd1714e7d Mon Sep 17 00:00:00 2001 From: Youwen Wu Date: Wed, 21 Aug 2024 16:48:17 -0700 Subject: [PATCH] Squash merge asahi-fix into main --- flake.lock | 42 +- flake.nix | 156 +- hosts/adrastea/configuration.nix | 227 + hosts/adrastea/default.nix | 252 +- .../default.nix} | 0 hosts/callisto/asahi-fix.patch | 5062 +++++++++++++++++ hosts/callisto/configuration.nix | 212 + hosts/callisto/default.nix | 221 +- hosts/callisto/hardware-configuration.nix | 42 +- hosts/callisto/hardware-configuration.nix.old | 39 + hosts/demeter/configuration.nix | 210 + hosts/demeter/default.nix | 234 +- hosts/demeter/hardware-configuration.nix.old | 39 - hosts/demeter/home-manager/default.nix | 0 hosts/phobos/configuration.nix | 57 + hosts/phobos/default.nix | 77 +- users/youwen/linux/hyprland/common.nix | 12 +- .../youwen/linux/hyprland/laptop/default.nix | 2 +- .../youwen/linux/packages/common-packages.nix | 2 +- users/youwen/linux/programs/default.nix | 8 +- 20 files changed, 6015 insertions(+), 879 deletions(-) create mode 100755 hosts/adrastea/configuration.nix mode change 100755 => 100644 hosts/adrastea/default.nix rename hosts/adrastea/{home-manager-overrides.nix => home-manager-extras/default.nix} (100%) create mode 100644 hosts/callisto/asahi-fix.patch create mode 100755 hosts/callisto/configuration.nix mode change 100755 => 100644 hosts/callisto/default.nix mode change 100755 => 100644 hosts/callisto/hardware-configuration.nix create mode 100755 hosts/callisto/hardware-configuration.nix.old create mode 100755 hosts/demeter/configuration.nix mode change 100755 => 100644 hosts/demeter/default.nix delete mode 100755 hosts/demeter/hardware-configuration.nix.old create mode 100644 hosts/demeter/home-manager/default.nix create mode 100755 hosts/phobos/configuration.nix mode change 100755 => 100644 hosts/phobos/default.nix diff --git a/flake.lock b/flake.lock index 3386095..097a0ba 100755 --- a/flake.lock +++ b/flake.lock @@ -24,11 +24,11 @@ }, "bleedingpkgs": { "locked": { - "lastModified": 1724117083, - "narHash": "sha256-26Zgap4D9E8PRL9jvc4Df9POMNGFS9fMwKz+SiGrlXI=", + "lastModified": 1724277913, + "narHash": "sha256-88IaCyNgVQHq1WoyK1mSOzedz3UAfwhtDLUca7qGB3I=", "owner": "nixos", "repo": "nixpkgs", - "rev": "44f636f8cb95238dabd5f33d00557329c0681cd5", + "rev": "4c97b427ece2d45026ab6c5264adb67c763e7927", "type": "github" }, "original": { @@ -57,11 +57,11 @@ }, "catppuccin": { "locked": { - "lastModified": 1724048768, - "narHash": "sha256-OZ9OXsPQi+fNdMM7SBPtU8OB1ntLzOvUwA/3zYJY6Eo=", + "lastModified": 1724156255, + "narHash": "sha256-rpUCeS/QZwQdJmDrvCm0hRi8bFvQNQKAnIMK5ZDBfpM=", "owner": "catppuccin", "repo": "nix", - "rev": "ff4128f8ea57879050145cf077a27b9d3a9cbf33", + "rev": "8886a68edadb1d93c7101337f995ffce4b410ff2", "type": "github" }, "original": { @@ -404,11 +404,11 @@ "homebrew-cask": { "flake": false, "locked": { - "lastModified": 1724120139, - "narHash": "sha256-vVE53gBCJPc3/dj7OHvQ7mNuUk1bWVpNR4c0jKe+K9U=", + "lastModified": 1724279485, + "narHash": "sha256-izbAx5wx4QS332G9dJ/E1U/NA9nrUjS0qS6b1thPQuE=", "owner": "homebrew", "repo": "homebrew-cask", - "rev": "606d3429e6fae79849c0eaf4bbcf05ff1570051a", + "rev": "761ddda3d71597c6b594af9416492fbf67ec813e", "type": "github" }, "original": { @@ -420,11 +420,11 @@ "homebrew-core": { "flake": false, "locked": { - "lastModified": 1724119620, - "narHash": "sha256-p+M24z3IDeIJBppaWWTpaz63WMGvi3HGW/mQHQVYpgM=", + "lastModified": 1724279403, + "narHash": "sha256-k/OW0HDkdJHfo1E52PyfeEyBDH0LwXuM1VmmFxCvYk0=", "owner": "homebrew", "repo": "homebrew-core", - "rev": "cd06a79081ce6e08b475e01315cdf1cb51952d77", + "rev": "7270362c593e96b2368834f6a87cd0d904874eb9", "type": "github" }, "original": { @@ -502,11 +502,11 @@ ] }, "locked": { - "lastModified": 1723859949, - "narHash": "sha256-kiaGz4deGYKMjJPOji/JVvSP/eTefrIA3rAjOnOpXl4=", + "lastModified": 1724219898, + "narHash": "sha256-7PwlnEQDIbww8+nk0CHLeYTYMA23F/CkynHsX7Mxk+s=", "owner": "LnL7", "repo": "nix-darwin", - "rev": "076b9a905af8a52b866c8db068d6da475839d97b", + "rev": "d6703b988728b89456b32bac242c8689902e5a5b", "type": "github" }, "original": { @@ -651,11 +651,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1724118730, - "narHash": "sha256-UwtVD2FyD7FjfLLmqGLsCBCQgLC1Jj78e1PhiVb0MJk=", + "lastModified": 1724222231, + "narHash": "sha256-IFlMn1lgVsZQZC9WklY9YKcCdI0mUxSYZ7EfkaKCsQU=", "owner": "nix-community", "repo": "nixvim", - "rev": "39081a41067a7bdb66f6f85a3fee9693ff8a21b1", + "rev": "b7f419a759f70126e220533b724cc17e8528b184", "type": "github" }, "original": { @@ -773,11 +773,11 @@ }, "stablepkgs": { "locked": { - "lastModified": 1723938990, - "narHash": "sha256-9tUadhnZQbWIiYVXH8ncfGXGvkNq3Hag4RCBEMUk7MI=", + "lastModified": 1724098845, + "narHash": "sha256-D5HwjQw/02fuXbR4LCTo64koglP2j99hkDR79/3yLOE=", "owner": "nixos", "repo": "nixpkgs", - "rev": "c42fcfbdfeae23e68fc520f9182dde9f38ad1890", + "rev": "f1bad50880bae73ff2d82fafc22010b4fc097a9c", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 95eda5d..8282dc3 100755 --- a/flake.nix +++ b/flake.nix @@ -3,38 +3,52 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + home-manager = { url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; + stablepkgs.url = "github:nixos/nixpkgs/nixos-24.05"; + bleedingpkgs.url = "github:nixos/nixpkgs/master"; - nix-darwin.url = "github:LnL7/nix-darwin"; - nix-darwin.inputs.nixpkgs.follows = "nixpkgs"; + + nix-darwin = { + url = "github:LnL7/nix-darwin"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nix-homebrew.url = "github:zhaofengli-wip/nix-homebrew"; + homebrew-core = { url = "github:homebrew/homebrew-core"; flake = false; }; + homebrew-cask = { url = "github:homebrew/homebrew-cask"; flake = false; }; + catppuccin.url = "github:catppuccin/nix"; + lanzaboote = { url = "github:nix-community/lanzaboote/v0.4.1"; # Optional but recommended to limit the size of your system closure. inputs.nixpkgs.follows = "nixpkgs"; }; + lix-module = { url = "https://git.lix.systems/lix-project/nixos-module/archive/2.90.0.tar.gz"; inputs.nixpkgs.follows = "nixpkgs"; }; + apple-silicon = { url = "github:tpwrules/nixos-apple-silicon"; inputs.nixpkgs.follows = "nixpkgs"; }; + nixvim = { url = "github:nix-community/nixvim"; inputs.nixpkgs.follows = "nixpkgs"; @@ -54,85 +68,33 @@ nix-homebrew, apple-silicon, ... - } @ inputs: rec { - formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.alejandra; + } @ inputs: let + in rec { + formatter = with nixpkgs.legacyPackages; { + x86_64-linux = x86_64-linux.alejandra; + aarch64-linux = aarch64-linux.alejandra; + aarch64-darwin = aarch64-darwin.alejandra; + }; + nixosConfigurations = { demeter = nixpkgs.lib.nixosSystem { - specialArgs = {inherit inputs;}; system = "x86_64-linux"; + specialArgs = { + inherit inputs; + system = "x86_64-linux"; + }; modules = [ ./hosts/demeter - ./modules/nixos/gaming - ./modules/nixos/audio - ./modules/nixos/networking - ./modules/nixos/fonts - ./modules/nixos/greeter - ./modules/nixos/core - ./overlays - - catppuccin.nixosModules.catppuccin - lix-module.nixosModules.default - lanzaboote.nixosModules.lanzaboote - home-manager.nixosModules.home-manager - { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - home-manager.backupFileExtension = "backup"; - home-manager.users.youwen = { - imports = [ - ./users/youwen/linux/desktop - ./users/youwen/linux/packages/x86_64 - ./users/youwen/linux/programs - ./users/youwen/common/neofetch - ./users/youwen/common/neovim - ./users/youwen/common - inputs.catppuccin.homeManagerModules.catppuccin - inputs.nixvim.homeManagerModules.nixvim - ]; - }; - } ]; }; + callisto = nixpkgs.lib.nixosSystem { - specialArgs = {inherit inputs;}; - system = "aarch64-linux"; + specialArgs = { + inherit inputs; + system = "aarch64-linux"; + }; modules = [ ./hosts/callisto - ./modules/nixos/audio - ./modules/nixos/networking - ./modules/nixos/fonts - ./modules/nixos/greeter - ./modules/nixos/core - - apple-silicon.nixosModules.apple-silicon-support - catppuccin.nixosModules.catppuccin - lix-module.nixosModules.default - home-manager.nixosModules.home-manager - { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - home-manager.backupFileExtension = "backup"; - home-manager.users.youwen = { - imports = [ - ./users/youwen/common - ./users/youwen/common/neofetch/asahi-only.nix - ./users/youwen/linux/laptop - ./users/youwen/linux/packages/aarch-64 - ./users/youwen/common/neovim - - inputs.catppuccin.homeManagerModules.catppuccin - inputs.nixvim.homeManagerModules.nixvim - ]; - }; - } - { - nixpkgs.overlays = [ - (self: super: { - signal-desktop = - bleedingpkgs.legacyPackages.${self.system}.signal-desktop; - }) - ]; - } ]; }; adrastea = nixpkgs.lib.nixosSystem { @@ -140,65 +102,13 @@ system = "x86_64-linux"; modules = [ ./hosts/adrastea - ./modules/nixos/gaming - ./modules/nixos/audio - ./modules/nixos/networking - ./modules/nixos/fonts - ./modules/nixos/greeter - ./modules/nixos/core - - catppuccin.nixosModules.catppuccin - lix-module.nixosModules.default - # lanzaboote.nixosModules.lanzaboote - home-manager.nixosModules.home-manager - { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - home-manager.backupFileExtension = "backup"; - home-manager.users.youwen = { - imports = [ - ./users/youwen/linux/laptop - ./users/youwen/linux/packages/x86_64 - ./users/youwen/linux/programs - ./users/youwen/common/neovim - ./users/youwen/common - ./users/youwen/common/neofetch - ./hosts/adrastea/home-manager-overrides.nix - inputs.catppuccin.homeManagerModules.catppuccin - inputs.nixvim.homeManagerModules.nixvim - ]; - }; - } ]; }; }; - formatter.aarch64-darwin = nixpkgs.legacyPackages.aarch64-darwin.alejandra; - formatter.aarch64-linux = nixpkgs.legacyPackages.aarch64-linux.alejandra; - # Build darwin flake using: - # $ darwin-rebuild build --flake .#Youwens-MacBook-Pro darwinConfigurations.phobos = nix-darwin.lib.darwinSystem { specialArgs = {inherit inputs;}; modules = [ ./hosts/phobos - home-manager.darwinModules.home-manager - { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - home-manager.users.youwen.imports = [ - ./users/youwen/darwin/darwin-home.nix - ./users/youwen/common/core.nix - ./users/youwen/common/neofetch - ./users/youwen/common/neovim - ]; - home-manager.backupFileExtension = "backup"; - - # Optionally, use home-manager.extraSpecialArgs to pass - # arguments to home.nix - } - nix-homebrew.darwinModules.nix-homebrew - ./modules/darwin/homebrew.nix - ./modules/darwin/yabai.nix - ./modules/darwin/skhd.nix ]; }; }; diff --git a/hosts/adrastea/configuration.nix b/hosts/adrastea/configuration.nix new file mode 100755 index 0000000..be473ef --- /dev/null +++ b/hosts/adrastea/configuration.nix @@ -0,0 +1,227 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running ‘nixos-help’). +{ + config, + inputs, + pkgs, + lib, + ... +}: { + imports = [ + # Include the results of the hardware scan. + ./hardware-configuration.nix + ]; + + # Bootloader. + boot.loader = { + efi.canTouchEfiVariables = true; + timeout = 15; + # Lanzaboote currently replaces the systemd-boot module. + # This setting is usually set to true in configuration.nix + # generated at installation time. So we force it to false + # for now. + systemd-boot = { + enable = true; + consoleMode = "auto"; + }; + }; + + # boot.lanzaboote = { + # enable = false; + # pkiBundle = "/etc/secureboot"; + # }; + + services.keyd = { + enable = true; + keyboards = { + default = { + ids = ["*"]; + settings = { + main = { + capslock = "esc"; + leftalt = "leftcontrol"; + leftcontrol = "leftalt"; + }; + }; + }; + }; + }; + + boot.initrd.luks.devices."luks-52d1be6d-b32f-41e0-a6d7-2ff52599fe7c".device = "/dev/disk/by-uuid/52d1be6d-b32f-41e0-a6d7-2ff52599fe7c"; + + services.tlp.enable = true; + + networking.hostName = "adrastea"; # Define your hostname. + # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. + + # select kernel + boot.kernelPackages = pkgs.linuxPackages_zen; + + # Configure network proxy if necessary + # networking.proxy.default = "http://user:password@proxy:port/"; + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + + # Enable networking + networking.networkmanager.enable = true; + + # Set your time zone. + time.timeZone = "America/Los_Angeles"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; + + systemd.services = {NetworkManager-wait-online.enable = false;}; + + # Enable the X11 windowing system. + # You can disable this if you're only using the Wayland session. + services.xserver.enable = false; + + programs.nix-ld = { + enable = true; + libraries = with pkgs; [icu xorg.libXtst xorg.libXi]; + }; + + hardware.nvidia = { + modesetting.enable = true; + powerManagement.enable = true; + powerManagement.finegrained = false; + open = false; + nvidiaSettings = true; + prime = { + amdgpuBusId = "PCI:4:0:0"; + nvidiaBusId = "PCI:1:0:0"; + offload = { + enable = true; + enableOffloadCmd = true; + }; + }; + }; + + hardware.graphics.enable = true; + + hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.stable; + + services.xserver.videoDrivers = ["nvidia"]; + + # services.desktopManager.plasma6.enable = true; + + # Configure keymap in X11 + services.xserver = { + xkb.layout = "us"; + xkb.variant = ""; + }; + + # Enable CUPS to print documents. + services.printing.enable = true; + + # Enable touchpad support (enabled default in most desktopManager). + # services.xserver.libinput.enable = true; + + # Define a user account. Don't forget to set a password with ‘passwd’. + users.users.youwen = { + isNormalUser = true; + description = "Youwen Wu"; + extraGroups = ["networkmanager" "wheel" "nixos" "realtime"]; + }; + + users.groups.realtime = {}; + + nix.settings = { + trusted-users = ["root" "youwen"]; + experimental-features = ["nix-command" "flakes"]; + }; + + services.udev.extraRules = '' + KERNEL=="cpu_dma_latency", GROUP="realtime" + ''; + + security.pam.loginLimits = [ + { + domain = "@realtime"; + type = "-"; + item = "rtprio"; + value = 98; + } + { + domain = "@realtime"; + type = "-"; + item = "memlock"; + value = "unlimited"; + } + { + domain = "@realtime"; + type = "-"; + item = "nice"; + value = -11; + } + ]; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + neovim + wget + git + curl + librewolf + gnumake + gcc + cachix + gnupg + openssh + python3 + steam-run + + # deps for neovim compilation + lua51Packages.lua + lua51Packages.luarocks + tree-sitter + ]; + + environment.variables = { + EDITOR = "nvim"; + NIX_AUTO_RUN = 1; + }; + + # tells electron apps to use Wayland + environment.sessionVariables.NIXOS_OZONE_WL = "1"; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + + programs.dconf.enable = true; + + programs.hyprland.enable = true; + + programs.zsh.enable = false; + programs.fish.enable = true; + users.users.youwen.shell = pkgs.fish; + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "24.05"; # Did you read the comment? +} diff --git a/hosts/adrastea/default.nix b/hosts/adrastea/default.nix old mode 100755 new mode 100644 index be473ef..f7c9779 --- a/hosts/adrastea/default.nix +++ b/hosts/adrastea/default.nix @@ -1,227 +1,35 @@ -# Edit this configuration file to define what should be installed on -# your system. Help is available in the configuration.nix(5) man page -# and in the NixOS manual (accessible by running ‘nixos-help’). -{ - config, - inputs, - pkgs, - lib, - ... -}: { - imports = [ - # Include the results of the hardware scan. - ./hardware-configuration.nix - ]; +{inputs, ...}: { + imports = with inputs; [ + ./configuration.nix + ../../modules/nixos/gaming + ../../modules/nixos/audio + ../../modules/nixos/networking + ../../modules/nixos/fonts + ../../modules/nixos/greeter + ../../modules/nixos/core + ../../overlays - # Bootloader. - boot.loader = { - efi.canTouchEfiVariables = true; - timeout = 15; - # Lanzaboote currently replaces the systemd-boot module. - # This setting is usually set to true in configuration.nix - # generated at installation time. So we force it to false - # for now. - systemd-boot = { - enable = true; - consoleMode = "auto"; - }; - }; - - # boot.lanzaboote = { - # enable = false; - # pkiBundle = "/etc/secureboot"; - # }; - - services.keyd = { - enable = true; - keyboards = { - default = { - ids = ["*"]; - settings = { - main = { - capslock = "esc"; - leftalt = "leftcontrol"; - leftcontrol = "leftalt"; - }; - }; + catppuccin.nixosModules.catppuccin + lix-module.nixosModules.default + # lanzaboote.nixosModules.lanzaboote + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.backupFileExtension = "backup"; + home-manager.users.youwen = { + imports = [ + ./home-manager-extras + ../../users/youwen/linux/laptop + ../../users/youwen/linux/packages/x86_64 + ../../users/youwen/linux/programs + ../../users/youwen/common/neovim + ../../users/youwen/common + ../../users/youwen/common/neofetch + inputs.catppuccin.homeManagerModules.catppuccin + inputs.nixvim.homeManagerModules.nixvim + ]; }; - }; - }; - - boot.initrd.luks.devices."luks-52d1be6d-b32f-41e0-a6d7-2ff52599fe7c".device = "/dev/disk/by-uuid/52d1be6d-b32f-41e0-a6d7-2ff52599fe7c"; - - services.tlp.enable = true; - - networking.hostName = "adrastea"; # Define your hostname. - # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. - - # select kernel - boot.kernelPackages = pkgs.linuxPackages_zen; - - # Configure network proxy if necessary - # networking.proxy.default = "http://user:password@proxy:port/"; - # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; - - # Enable networking - networking.networkmanager.enable = true; - - # Set your time zone. - time.timeZone = "America/Los_Angeles"; - - # Select internationalisation properties. - i18n.defaultLocale = "en_US.UTF-8"; - - i18n.extraLocaleSettings = { - LC_ADDRESS = "en_US.UTF-8"; - LC_IDENTIFICATION = "en_US.UTF-8"; - LC_MEASUREMENT = "en_US.UTF-8"; - LC_MONETARY = "en_US.UTF-8"; - LC_NAME = "en_US.UTF-8"; - LC_NUMERIC = "en_US.UTF-8"; - LC_PAPER = "en_US.UTF-8"; - LC_TELEPHONE = "en_US.UTF-8"; - LC_TIME = "en_US.UTF-8"; - }; - - systemd.services = {NetworkManager-wait-online.enable = false;}; - - # Enable the X11 windowing system. - # You can disable this if you're only using the Wayland session. - services.xserver.enable = false; - - programs.nix-ld = { - enable = true; - libraries = with pkgs; [icu xorg.libXtst xorg.libXi]; - }; - - hardware.nvidia = { - modesetting.enable = true; - powerManagement.enable = true; - powerManagement.finegrained = false; - open = false; - nvidiaSettings = true; - prime = { - amdgpuBusId = "PCI:4:0:0"; - nvidiaBusId = "PCI:1:0:0"; - offload = { - enable = true; - enableOffloadCmd = true; - }; - }; - }; - - hardware.graphics.enable = true; - - hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.stable; - - services.xserver.videoDrivers = ["nvidia"]; - - # services.desktopManager.plasma6.enable = true; - - # Configure keymap in X11 - services.xserver = { - xkb.layout = "us"; - xkb.variant = ""; - }; - - # Enable CUPS to print documents. - services.printing.enable = true; - - # Enable touchpad support (enabled default in most desktopManager). - # services.xserver.libinput.enable = true; - - # Define a user account. Don't forget to set a password with ‘passwd’. - users.users.youwen = { - isNormalUser = true; - description = "Youwen Wu"; - extraGroups = ["networkmanager" "wheel" "nixos" "realtime"]; - }; - - users.groups.realtime = {}; - - nix.settings = { - trusted-users = ["root" "youwen"]; - experimental-features = ["nix-command" "flakes"]; - }; - - services.udev.extraRules = '' - KERNEL=="cpu_dma_latency", GROUP="realtime" - ''; - - security.pam.loginLimits = [ - { - domain = "@realtime"; - type = "-"; - item = "rtprio"; - value = 98; - } - { - domain = "@realtime"; - type = "-"; - item = "memlock"; - value = "unlimited"; - } - { - domain = "@realtime"; - type = "-"; - item = "nice"; - value = -11; } ]; - - # Allow unfree packages - nixpkgs.config.allowUnfree = true; - - # List packages installed in system profile. To search, run: - # $ nix search wget - environment.systemPackages = with pkgs; [ - neovim - wget - git - curl - librewolf - gnumake - gcc - cachix - gnupg - openssh - python3 - steam-run - - # deps for neovim compilation - lua51Packages.lua - lua51Packages.luarocks - tree-sitter - ]; - - environment.variables = { - EDITOR = "nvim"; - NIX_AUTO_RUN = 1; - }; - - # tells electron apps to use Wayland - environment.sessionVariables.NIXOS_OZONE_WL = "1"; - - # Some programs need SUID wrappers, can be configured further or are - # started in user sessions. - # programs.mtr.enable = true; - programs.gnupg.agent = { - enable = true; - enableSSHSupport = true; - }; - - programs.dconf.enable = true; - - programs.hyprland.enable = true; - - programs.zsh.enable = false; - programs.fish.enable = true; - users.users.youwen.shell = pkgs.fish; - # This value determines the NixOS release from which the default - # settings for stateful data, like file locations and database versions - # on your system were taken. It‘s perfectly fine and recommended to leave - # this value at the release version of the first install of this system. - # Before changing this value read the documentation for this option - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). - system.stateVersion = "24.05"; # Did you read the comment? } diff --git a/hosts/adrastea/home-manager-overrides.nix b/hosts/adrastea/home-manager-extras/default.nix similarity index 100% rename from hosts/adrastea/home-manager-overrides.nix rename to hosts/adrastea/home-manager-extras/default.nix diff --git a/hosts/callisto/asahi-fix.patch b/hosts/callisto/asahi-fix.patch new file mode 100644 index 0000000..03c87c8 --- /dev/null +++ b/hosts/callisto/asahi-fix.patch @@ -0,0 +1,5062 @@ +diff --git a/.gitignore b/.gitignore +index 78f794fc..2e158a4e 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -37,3 +37,5 @@ gmon.out + PKGBUILD + + src/version.h ++hyprpm/Makefile ++hyprctl/Makefile +diff --git a/CMakeLists.txt b/CMakeLists.txt +index fc8eafd5..f26a5c3c 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -62,7 +62,7 @@ else() + endif() + + include_directories(. "src/" "subprojects/udis86/" "protocols/") +-set(CMAKE_CXX_STANDARD 23) ++set(CMAKE_CXX_STANDARD 26) + add_compile_options( + -Wall + -Wextra +@@ -117,6 +117,7 @@ pkg_check_modules( + libliftoff + libudev + gbm ++ gio-2.0 + hyprlang>=0.3.2 + hyprcursor>=0.1.7 + hyprutils>=0.2.1) +@@ -329,7 +330,7 @@ install( + CODE "execute_process( \ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${CMAKE_INSTALL_FULL_BINDIR}/Hyprland \ +- ${CMAKE_INSTALL_FULL_BINDIR}/hyprland ++ \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/hyprland\" \ + )") + + # session file +diff --git a/README.md b/README.md +index fc2bd206..f271c29c 100644 +--- a/README.md ++++ b/README.md +@@ -1,6 +1,6 @@ +
+ +-banner ++banner + +
+ +@@ -125,7 +125,6 @@ easy IPC, much more QoL stuff than other compositors and more... + + + +-[Stars Preview]: https://starchart.cc/vaxerski/Hyprland.svg + [Preview A]: https://i.ibb.co/C1yTb0r/falf.png + [Preview B]: https://linfindel.github.io/cdn/hyprland-preview-b.png + [Preview C]: https://i.ibb.co/B3GJg28/20221126-20h53m26s-grim.png +diff --git a/flake.lock b/flake.lock +index 5c384d4d..c70d31d1 100644 +--- a/flake.lock ++++ b/flake.lock +@@ -16,11 +16,11 @@ + ] + }, + "locked": { +- "lastModified": 1722347739, +- "narHash": "sha256-rAoh+K6KG+b1DwSWtqRVocdojnH6nGk6q07mNltoUSM=", ++ "lastModified": 1723920171, ++ "narHash": "sha256-dVCMrAe+D/5S91erhwQj2DSzHOVzAanWqoy+vPWB9DY=", + "owner": "hyprwm", + "repo": "aquamarine", +- "rev": "7c3565f9bedc7cb601cc0baa14792247e4dc1d5a", ++ "rev": "71d49670fe246cdaff4860b0effba0ab9f163b72", + "type": "github" + }, + "original": { +@@ -42,11 +42,11 @@ + ] + }, + "locked": { +- "lastModified": 1721330371, +- "narHash": "sha256-aYlHTWylczLt6ERJyg6E66Y/XSCbVL7leVcRuJmVbpI=", ++ "lastModified": 1722623071, ++ "narHash": "sha256-sLADpVgebpCBFXkA1FlCXtvEPu1tdEsTfqK1hfeHySE=", + "owner": "hyprwm", + "repo": "hyprcursor", +- "rev": "4493a972b48f9c3014befbbf381ed5fff91a65dc", ++ "rev": "912d56025f03d41b1ad29510c423757b4379eb1c", + "type": "github" + }, + "original": { +@@ -116,11 +116,11 @@ + ] + }, + "locked": { +- "lastModified": 1722098849, +- "narHash": "sha256-D3wIZlBNh7LuZ0NaoCpY/Pvu+xHxIVtSN+KkWZYvvVs=", ++ "lastModified": 1722869141, ++ "narHash": "sha256-0KU4qhyMp441qfwbirNg3+wbm489KnEjXOz2I/RbeFs=", + "owner": "hyprwm", + "repo": "hyprutils", +- "rev": "5dcbbc1e3de40b2cecfd2007434d86e924468f1f", ++ "rev": "0252fd13e78e60fb0da512a212e56007515a49f7", + "type": "github" + }, + "original": { +@@ -154,11 +154,11 @@ + }, + "nixpkgs": { + "locked": { +- "lastModified": 1722185531, +- "narHash": "sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k=", ++ "lastModified": 1723637854, ++ "narHash": "sha256-med8+5DSWa2UnOqtdICndjDAEjxr5D7zaIiK4pn0Q7c=", + "owner": "NixOS", + "repo": "nixpkgs", +- "rev": "52ec9ac3b12395ad677e8b62106f0b98c1f8569d", ++ "rev": "c3aa7b8938b17aebd2deecf7be0636000d62a2b9", + "type": "github" + }, + "original": { +diff --git a/flake.nix b/flake.nix +index 9c20b3f5..9e1e3ab4 100644 +--- a/flake.nix ++++ b/flake.nix +@@ -95,7 +95,7 @@ + devShells = eachSystem (system: { + default = + pkgsFor.${system}.mkShell.override { +- stdenv = pkgsFor.${system}.gcc13Stdenv; ++ stdenv = pkgsFor.${system}.gcc14Stdenv; + } { + name = "hyprland-shell"; + nativeBuildInputs = with pkgsFor.${system}; [ +diff --git a/hyprctl/Makefile b/hyprctl/Makefile +deleted file mode 100644 +index 9798320c..00000000 +--- a/hyprctl/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-all: +- $(CXX) $(CXXFLAGS) -std=c++2b ./main.cpp -o ./hyprctl +-clean: +- rm ./hyprctl +diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp +index 336d479e..5d5113b8 100644 +--- a/hyprctl/main.cpp ++++ b/hyprctl/main.cpp +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + using namespace Hyprutils::String; + + #include "Strings.hpp" +@@ -113,7 +114,7 @@ int rollingRead(const int socket) { + + constexpr size_t BUFFER_SIZE = 8192; + std::array buffer = {0}; +- int sizeWritten = 0; ++ long sizeWritten = 0; + std::cout << "[hyprctl] reading from socket following up log:" << std::endl; + while (!sigintReceived) { + sizeWritten = read(socket, buffer.data(), BUFFER_SIZE); +diff --git a/meson.build b/meson.build +index 886f4f9c..6a9b7ac5 100644 +--- a/meson.build ++++ b/meson.build +@@ -6,7 +6,7 @@ project('Hyprland', 'cpp', 'c', + 'optimization=3', + 'buildtype=release', + 'debug=false', +- 'cpp_std=c++23', ++ 'cpp_std=c++26', + ]) + + datarootdir = '-DDATAROOTDIR="' + get_option('prefix') / get_option('datadir') + '"' +@@ -34,6 +34,8 @@ xcb_render_dep = dependency('xcb-render', required: get_option('xwayland')) + xcb_res_dep = dependency('xcb-res', required: get_option('xwayland')) + xcb_xfixes_dep = dependency('xcb-xfixes', required: get_option('xwayland')) + ++gio_dep = dependency('gio-2.0', required:true) ++ + cmake = import('cmake') + udis = cmake.subproject('udis86') + udis86 = udis.dependency('libudis86') +diff --git a/nix/default.nix b/nix/default.nix +index e4e12f43..9bae9d83 100644 +--- a/nix/default.nix ++++ b/nix/default.nix +@@ -71,6 +71,11 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov + src = lib.cleanSource ../.; + }; + ++ patches = [ ++ # forces GCC to use -std=c++26 ++ ./stdcxx.patch ++ ]; ++ + postPatch = '' + # Fix hardcoded paths to /usr installation + sed -i "s#/usr#$out#" src/render/OpenGL.cpp +diff --git a/nix/overlays.nix b/nix/overlays.nix +index d8979b45..36206f46 100644 +--- a/nix/overlays.nix ++++ b/nix/overlays.nix +@@ -31,7 +31,7 @@ in { + date = mkDate (self.lastModifiedDate or "19700101"); + in { + hyprland = final.callPackage ./default.nix { +- stdenv = final.gcc13Stdenv; ++ stdenv = final.gcc14Stdenv; + version = "${version}+date=${date}_${self.shortRev or "dirty"}"; + commit = self.rev or ""; + inherit date; +diff --git a/nix/stdcxx.patch b/nix/stdcxx.patch +new file mode 100644 +index 00000000..032e494d +--- /dev/null ++++ b/nix/stdcxx.patch +@@ -0,0 +1,12 @@ ++diff --git a/CMakeLists.txt b/CMakeLists.txt ++index cfbd431f..73e8e0c2 100644 ++--- a/CMakeLists.txt +++++ b/CMakeLists.txt ++@@ -64,6 +64,7 @@ endif() ++ include_directories(. "src/" "subprojects/udis86/" "protocols/") ++ set(CMAKE_CXX_STANDARD 26) ++ add_compile_options( +++ -std=c++26 ++ -Wall ++ -Wextra ++ -Wno-unused-parameter +diff --git a/src/Compositor.cpp b/src/Compositor.cpp +index 49408597..9d247a56 100644 +--- a/src/Compositor.cpp ++++ b/src/Compositor.cpp +@@ -305,6 +305,10 @@ void CCompositor::initServer(std::string socketName, int socketFd) { + + setenv("WAYLAND_DISPLAY", m_szWLDisplaySocket.c_str(), 1); + setenv("XDG_SESSION_TYPE", "wayland", 1); ++ if (!getenv("XDG_CURRENT_DESKTOP")) { ++ setenv("XDG_CURRENT_DESKTOP", "Hyprland", 1); ++ m_bDesktopEnvSet = true; ++ } + + initManagers(STAGE_BASICINIT); + +@@ -393,6 +397,7 @@ void CCompositor::initAllSignals() { + } + + g_pConfigManager->m_bWantsMonitorReload = true; ++ g_pCursorManager->syncGsettings(); + } else { + Debug::log(LOG, "Session got deactivated!"); + +@@ -421,9 +426,10 @@ void CCompositor::cleanEnvironment() { + // in main + unsetenv("HYPRLAND_CMD"); + unsetenv("XDG_BACKEND"); +- unsetenv("XDG_CURRENT_DESKTOP"); ++ if (m_bDesktopEnvSet) ++ unsetenv("XDG_CURRENT_DESKTOP"); + +- if (m_pAqBackend->hasSession()) { ++ if (m_pAqBackend->hasSession() && !envEnabled("HYPRLAND_NO_SD_VARS")) { + const auto CMD = + #ifdef USES_SYSTEMD + "systemctl --user unset-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS && hash " +@@ -552,6 +558,10 @@ void CCompositor::initManagers(eManagersInitStage stage) { + + g_pConfigManager->init(); + g_pWatchdog = std::make_unique(); // requires config ++ // wait for watchdog to initialize to not hit data races in reading config values. ++ while (!g_pWatchdog->m_bWatchdogInitialized) { ++ std::this_thread::yield(); ++ } + + Debug::log(LOG, "Creating the PointerManager!"); + g_pPointerManager = std::make_unique(); +@@ -649,7 +659,11 @@ void CCompositor::prepareFallbackOutput() { + void CCompositor::startCompositor() { + signal(SIGPIPE, SIG_IGN); + +- if (m_pAqBackend->hasSession() /* Session-less Hyprland usually means a nest, don't update the env in that case */) { ++ if ( ++ /* Session-less Hyprland usually means a nest, don't update the env in that case */ ++ m_pAqBackend->hasSession() && ++ /* Activation environment management is not disabled */ ++ !envEnabled("HYPRLAND_NO_SD_VARS")) { + const auto CMD = + #ifdef USES_SYSTEMD + "systemctl --user import-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS && hash " +@@ -683,9 +697,9 @@ void CCompositor::startCompositor() { + g_pEventLoopManager->enterLoop(); + } + +-CMonitor* CCompositor::getMonitorFromID(const int& id) { ++CMonitor* CCompositor::getMonitorFromID(const MONITORID& id) { + for (auto& m : m_vMonitors) { +- if (m->ID == (uint64_t)id) { ++ if (m->ID == id) { + return m.get(); + } + } +@@ -845,8 +859,8 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper + if (properties & FLOATING_ONLY) + return floating(false); + +- const int64_t WORKSPACEID = special ? PMONITOR->activeSpecialWorkspaceID() : PMONITOR->activeWorkspaceID(); +- const auto PWORKSPACE = getWorkspaceByID(WORKSPACEID); ++ const WORKSPACEID WSPID = special ? PMONITOR->activeSpecialWorkspaceID() : PMONITOR->activeWorkspaceID(); ++ const auto PWORKSPACE = getWorkspaceByID(WSPID); + + if (PWORKSPACE->m_bHasFullscreenWindow) + return getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); +@@ -860,7 +874,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper + if (special != w->onSpecialWorkspace()) + continue; + +- if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->workspaceID() == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && ++ if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->workspaceID() == WSPID && !w->isHidden() && !w->m_bX11ShouldntFocus && + !w->m_sWindowData.noFocus.valueOrDefault() && w != pIgnoreWindow) { + if (w->hasPopupAt(pos)) + return w; +@@ -872,7 +886,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper + continue; + + CBox box = (properties & USE_PROP_TILED) ? w->getWindowBoxUnified(properties) : CBox{w->m_vPosition, w->m_vSize}; +- if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->workspaceID() == WORKSPACEID && !w->isHidden() && !w->m_bX11ShouldntFocus && ++ if (!w->m_bIsFloating && w->m_bIsMapped && box.containsPoint(pos) && w->workspaceID() == WSPID && !w->isHidden() && !w->m_bX11ShouldntFocus && + !w->m_sWindowData.noFocus.valueOrDefault() && w != pIgnoreWindow) + return w; + } +@@ -1207,7 +1221,7 @@ PHLWINDOW CCompositor::getWindowFromHandle(uint32_t handle) { + return nullptr; + } + +-PHLWINDOW CCompositor::getFullscreenWindowOnWorkspace(const int& ID) { ++PHLWINDOW CCompositor::getFullscreenWindowOnWorkspace(const WORKSPACEID& ID) { + for (auto& w : m_vWindows) { + if (w->workspaceID() == ID && w->isFullscreen()) + return w; +@@ -1231,7 +1245,7 @@ bool CCompositor::isWorkspaceVisibleNotCovered(PHLWORKSPACE w) { + return PMONITOR->activeWorkspace->m_iID == w->m_iID; + } + +-PHLWORKSPACE CCompositor::getWorkspaceByID(const int& id) { ++PHLWORKSPACE CCompositor::getWorkspaceByID(const WORKSPACEID& id) { + for (auto& w : m_vWorkspaces) { + if (w->m_iID == id && !w->inert()) + return w; +@@ -1255,7 +1269,7 @@ void CCompositor::sanityCheckWorkspaces() { + } + } + +-int CCompositor::getWindowsOnWorkspace(const int& id, std::optional onlyTiled, std::optional onlyVisible) { ++int CCompositor::getWindowsOnWorkspace(const WORKSPACEID& id, std::optional onlyTiled, std::optional onlyVisible) { + int no = 0; + for (auto& w : m_vWindows) { + if (w->workspaceID() != id || !w->m_bIsMapped) +@@ -1270,7 +1284,7 @@ int CCompositor::getWindowsOnWorkspace(const int& id, std::optional onlyTi + return no; + } + +-int CCompositor::getGroupsOnWorkspace(const int& id, std::optional onlyTiled, std::optional onlyVisible) { ++int CCompositor::getGroupsOnWorkspace(const WORKSPACEID& id, std::optional onlyTiled, std::optional onlyVisible) { + int no = 0; + for (auto& w : m_vWindows) { + if (w->workspaceID() != id || !w->m_bIsMapped) +@@ -1295,7 +1309,7 @@ PHLWINDOW CCompositor::getUrgentWindow() { + return nullptr; + } + +-bool CCompositor::hasUrgentWindowOnWorkspace(const int& id) { ++bool CCompositor::hasUrgentWindowOnWorkspace(const WORKSPACEID& id) { + for (auto& w : m_vWindows) { + if (w->workspaceID() == id && w->m_bIsMapped && w->m_bIsUrgent) + return true; +@@ -1304,7 +1318,7 @@ bool CCompositor::hasUrgentWindowOnWorkspace(const int& id) { + return false; + } + +-PHLWINDOW CCompositor::getFirstWindowOnWorkspace(const int& id) { ++PHLWINDOW CCompositor::getFirstWindowOnWorkspace(const WORKSPACEID& id) { + for (auto& w : m_vWindows) { + if (w->workspaceID() == id && w->m_bIsMapped && !w->isHidden()) + return w; +@@ -1313,7 +1327,7 @@ PHLWINDOW CCompositor::getFirstWindowOnWorkspace(const int& id) { + return nullptr; + } + +-PHLWINDOW CCompositor::getTopLeftWindowOnWorkspace(const int& id) { ++PHLWINDOW CCompositor::getTopLeftWindowOnWorkspace(const WORKSPACEID& id) { + const auto PWORKSPACE = getWorkspaceByID(id); + + if (!PWORKSPACE) +@@ -1401,12 +1415,12 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) { + } + } + +-void CCompositor::cleanupFadingOut(const int& monid) { ++void CCompositor::cleanupFadingOut(const MONITORID& monid) { + for (auto& ww : m_vWindowsFadingOut) { + + auto w = ww.lock(); + +- if (w->m_iMonitorID != (long unsigned int)monid) ++ if (w->m_iMonitorID != monid) + continue; + + if (!w->m_bFadingOut || w->m_fAlpha.value() == 0.f) { +@@ -1702,8 +1716,8 @@ PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusabl + return nullptr; + } + +-int CCompositor::getNextAvailableNamedWorkspace() { +- int lowest = -1337 + 1; ++WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() { ++ WORKSPACEID lowest = -1337 + 1; + for (auto& w : m_vWorkspaces) { + if (w->m_iID < -1 && w->m_iID < lowest) + lowest = w->m_iID; +@@ -1927,18 +1941,18 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { + pWindow->updateWindowDecos(); + } + +-int CCompositor::getNextAvailableMonitorID(std::string const& name) { ++MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) { + // reuse ID if it's already in the map, and the monitor with that ID is not being used by another monitor + if (m_mMonitorIDMap.contains(name) && !std::any_of(m_vRealMonitors.begin(), m_vRealMonitors.end(), [&](auto m) { return m->ID == m_mMonitorIDMap[name]; })) + return m_mMonitorIDMap[name]; + + // otherwise, find minimum available ID that is not in the map +- std::unordered_set usedIDs; ++ std::unordered_set usedIDs; + for (auto const& monitor : m_vRealMonitors) { + usedIDs.insert(monitor->ID); + } + +- uint64_t nextID = 0; ++ MONITORID nextID = 0; + while (usedIDs.count(nextID) > 0) { + nextID++; + } +@@ -2078,7 +2092,7 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) { + return m_vMonitors[currentPlace].get(); + } else if (isNumber(name)) { + // change by ID +- int monID = -1; ++ MONITORID monID = MONITOR_INVALID; + try { + monID = std::stoi(name); + } catch (std::exception& e) { +@@ -2087,7 +2101,7 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) { + return nullptr; + } + +- if (monID > -1 && monID < (int)m_vMonitors.size()) { ++ if (monID > -1 && monID < (MONITORID)m_vMonitors.size()) { + return getMonitorFromID(monID); + } else { + Debug::log(ERR, "Error in getMonitorFromString: invalid arg 1"); +@@ -2121,7 +2135,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon + const bool SWITCHINGISACTIVE = POLDMON ? POLDMON->activeWorkspace == pWorkspace : false; + + // fix old mon +- int nextWorkspaceOnMonitorID = -1; ++ WORKSPACEID nextWorkspaceOnMonitorID = WORKSPACE_INVALID; + if (!SWITCHINGISACTIVE) + nextWorkspaceOnMonitorID = pWorkspace->m_iID; + else { +@@ -2132,7 +2146,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon + } + } + +- if (nextWorkspaceOnMonitorID == -1) { ++ if (nextWorkspaceOnMonitorID == WORKSPACE_INVALID) { + nextWorkspaceOnMonitorID = 1; + + while (getWorkspaceByID(nextWorkspaceOnMonitorID) || [&]() -> bool { +@@ -2219,9 +2233,9 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, CMonitor* pMon + EMIT_HOOK_EVENT("moveWorkspace", (std::vector{pWorkspace, pMonitor})); + } + +-bool CCompositor::workspaceIDOutOfBounds(const int64_t& id) { +- int64_t lowestID = INT64_MAX; +- int64_t highestID = INT64_MIN; ++bool CCompositor::workspaceIDOutOfBounds(const WORKSPACEID& id) { ++ WORKSPACEID lowestID = INT64_MAX; ++ WORKSPACEID highestID = INT64_MIN; + + for (auto& w : m_vWorkspaces) { + if (w->m_bIsSpecialWorkspace) +@@ -2370,7 +2384,7 @@ PHLWINDOW CCompositor::getX11Parent(PHLWINDOW pWindow) { + return nullptr; + } + +-void CCompositor::updateWorkspaceWindowDecos(const int& id) { ++void CCompositor::updateWorkspaceWindowDecos(const WORKSPACEID& id) { + for (auto& w : m_vWindows) { + if (w->workspaceID() != id) + continue; +@@ -2379,7 +2393,7 @@ void CCompositor::updateWorkspaceWindowDecos(const int& id) { + } + } + +-void CCompositor::updateWorkspaceWindowData(const int& id) { ++void CCompositor::updateWorkspaceWindowData(const WORKSPACEID& id) { + const auto PWORKSPACE = getWorkspaceByID(id); + const auto WORKSPACERULE = PWORKSPACE ? g_pConfigManager->getWorkspaceRuleFor(PWORKSPACE) : SWorkspaceRule{}; + +@@ -2599,7 +2613,7 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con + return Vector2D(X, Y); + } + +-void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) { ++void CCompositor::forceReportSizesToWindowsOnWorkspace(const WORKSPACEID& wid) { + for (auto& w : m_vWindows) { + if (w->workspaceID() == wid && w->m_bIsMapped && !w->isHidden()) { + g_pXWaylandManager->setWindowSize(w, w->m_vRealSize.value(), true); +@@ -2607,7 +2621,7 @@ void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) { + } + } + +-PHLWORKSPACE CCompositor::createNewWorkspace(const int& id, const int& monid, const std::string& name, bool isEmtpy) { ++PHLWORKSPACE CCompositor::createNewWorkspace(const WORKSPACEID& id, const MONITORID& monid, const std::string& name, bool isEmtpy) { + const auto NAME = name == "" ? std::to_string(id) : name; + auto monID = monid; + +@@ -2625,7 +2639,7 @@ PHLWORKSPACE CCompositor::createNewWorkspace(const int& id, const int& monid, co + return PWORKSPACE; + } + +-void CCompositor::renameWorkspace(const int& id, const std::string& name) { ++void CCompositor::renameWorkspace(const WORKSPACEID& id, const std::string& name) { + const auto PWORKSPACE = getWorkspaceByID(id); + + if (!PWORKSPACE) +@@ -2656,12 +2670,12 @@ void CCompositor::setActiveMonitor(CMonitor* pMonitor) { + m_pLastMonitor = pMonitor->self; + } + +-bool CCompositor::isWorkspaceSpecial(const int& id) { ++bool CCompositor::isWorkspaceSpecial(const WORKSPACEID& id) { + return id >= SPECIAL_WORKSPACE_START && id <= -2; + } + +-int CCompositor::getNewSpecialID() { +- int highest = SPECIAL_WORKSPACE_START; ++WORKSPACEID CCompositor::getNewSpecialID() { ++ WORKSPACEID highest = SPECIAL_WORKSPACE_START; + for (auto& ws : m_vWorkspaces) { + if (ws->m_bIsSpecialWorkspace && ws->m_iID > highest) { + highest = ws->m_iID; +@@ -2918,39 +2932,6 @@ PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) { + return {}; + } + +-static void checkDefaultCursorWarp(SP PNEWMONITOR, std::string monitorName) { +- static auto PCURSORMONITOR = CConfigValue("cursor:default_monitor"); +- static auto firstMonitorAdded = std::chrono::system_clock::now(); +- static bool cursorDefaultDone = false; +- static bool firstLaunch = true; +- +- const auto POS = PNEWMONITOR->middle(); +- +- // by default, cursor should be set to first monitor detected +- // this is needed as a default if the monitor given in config above doesn't exist +- if (firstLaunch) { +- firstLaunch = false; +- g_pCompositor->warpCursorTo(POS, true); +- g_pInputManager->refocus(); +- } +- +- if (cursorDefaultDone || *PCURSORMONITOR == STRVAL_EMPTY) +- return; +- +- // after 10s, don't set cursor to default monitor +- auto timePassedSec = std::chrono::duration_cast(std::chrono::system_clock::now() - firstMonitorAdded); +- if (timePassedSec.count() > 10) { +- cursorDefaultDone = true; +- return; +- } +- +- if (*PCURSORMONITOR == monitorName) { +- cursorDefaultDone = true; +- g_pCompositor->warpCursorTo(POS, true); +- g_pInputManager->refocus(); +- } +-} +- + void CCompositor::onNewMonitor(SP output) { + // add it to real + auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared()); +@@ -2965,7 +2946,7 @@ void CCompositor::onNewMonitor(SP output) { + PNEWMONITOR->output = output; + PNEWMONITOR->self = PNEWMONITOR; + const bool FALLBACK = g_pCompositor->m_pUnsafeOutput ? output == g_pCompositor->m_pUnsafeOutput->output : false; +- PNEWMONITOR->ID = FALLBACK ? -1 : g_pCompositor->getNextAvailableMonitorID(output->name); ++ PNEWMONITOR->ID = FALLBACK ? MONITOR_INVALID : g_pCompositor->getNextAvailableMonitorID(output->name); + PNEWMONITOR->isUnsafeFallback = FALLBACK; + + EMIT_HOOK_EVENT("newMonitor", PNEWMONITOR); +@@ -2986,11 +2967,9 @@ void CCompositor::onNewMonitor(SP output) { + g_pConfigManager->m_bWantsMonitorReload = true; + g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR.get(), IOutput::AQ_SCHEDULE_NEW_MONITOR); + +- checkDefaultCursorWarp(PNEWMONITOR, output->name); +- + for (auto& w : g_pCompositor->m_vWindows) { + if (w->m_iMonitorID == PNEWMONITOR->ID) { +- w->m_iLastSurfaceMonitorID = -1; ++ w->m_iLastSurfaceMonitorID = MONITOR_INVALID; + w->updateSurfaceScaleTransformDetails(); + } + } +diff --git a/src/Compositor.hpp b/src/Compositor.hpp +index 295935c4..a570a06e 100644 +--- a/src/Compositor.hpp ++++ b/src/Compositor.hpp +@@ -46,55 +46,56 @@ class CCompositor { + CCompositor(); + ~CCompositor(); + +- wl_display* m_sWLDisplay; +- wl_event_loop* m_sWLEventLoop; +- int m_iDRMFD = -1; +- bool m_bInitialized = false; +- SP m_pAqBackend; +- +- std::string m_szHyprTempDataRoot = ""; +- +- std::string m_szWLDisplaySocket = ""; +- std::string m_szInstanceSignature = ""; +- std::string m_szInstancePath = ""; +- std::string m_szCurrentSplash = "error"; +- +- std::vector> m_vMonitors; +- std::vector> m_vRealMonitors; // for all monitors, even those turned off +- std::vector m_vWindows; +- std::vector m_vLayers; +- std::vector m_vWorkspaces; +- std::vector m_vWindowsFadingOut; +- std::vector m_vSurfacesFadingOut; +- +- std::unordered_map m_mMonitorIDMap; +- +- void initServer(std::string socketName, int socketFd); +- void startCompositor(); +- void stopCompositor(); +- void cleanup(); +- void createLockFile(); +- void removeLockFile(); +- void bumpNofile(); +- void restoreNofile(); +- +- WP m_pLastFocus; +- PHLWINDOWREF m_pLastWindow; +- WP m_pLastMonitor; +- +- std::vector m_vWindowFocusHistory; // first element is the most recently focused. +- +- bool m_bReadyToProcess = false; +- bool m_bSessionActive = true; +- bool m_bDPMSStateON = true; +- bool m_bUnsafeState = false; // unsafe state is when there is no monitors. +- bool m_bNextIsUnsafe = false; +- CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state +- bool m_bIsShuttingDown = false; ++ wl_display* m_sWLDisplay; ++ wl_event_loop* m_sWLEventLoop; ++ int m_iDRMFD = -1; ++ bool m_bInitialized = false; ++ SP m_pAqBackend; ++ ++ std::string m_szHyprTempDataRoot = ""; ++ ++ std::string m_szWLDisplaySocket = ""; ++ std::string m_szInstanceSignature = ""; ++ std::string m_szInstancePath = ""; ++ std::string m_szCurrentSplash = "error"; ++ ++ std::vector> m_vMonitors; ++ std::vector> m_vRealMonitors; // for all monitors, even those turned off ++ std::vector m_vWindows; ++ std::vector m_vLayers; ++ std::vector m_vWorkspaces; ++ std::vector m_vWindowsFadingOut; ++ std::vector m_vSurfacesFadingOut; ++ ++ std::unordered_map m_mMonitorIDMap; ++ ++ void initServer(std::string socketName, int socketFd); ++ void startCompositor(); ++ void stopCompositor(); ++ void cleanup(); ++ void createLockFile(); ++ void removeLockFile(); ++ void bumpNofile(); ++ void restoreNofile(); ++ ++ WP m_pLastFocus; ++ PHLWINDOWREF m_pLastWindow; ++ WP m_pLastMonitor; ++ ++ std::vector m_vWindowFocusHistory; // first element is the most recently focused. ++ ++ bool m_bReadyToProcess = false; ++ bool m_bSessionActive = true; ++ bool m_bDPMSStateON = true; ++ bool m_bUnsafeState = false; // unsafe state is when there is no monitors. ++ bool m_bNextIsUnsafe = false; ++ CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state ++ bool m_bIsShuttingDown = false; ++ bool m_bDesktopEnvSet = false; + + // ------------------------------------------------- // + +- CMonitor* getMonitorFromID(const int&); ++ CMonitor* getMonitorFromID(const MONITORID&); + CMonitor* getMonitorFromName(const std::string&); + CMonitor* getMonitorFromDesc(const std::string&); + CMonitor* getMonitorFromCursor(); +@@ -114,38 +115,38 @@ class CCompositor { + PHLWINDOW getWindowFromHandle(uint32_t); + bool isWorkspaceVisible(PHLWORKSPACE); + bool isWorkspaceVisibleNotCovered(PHLWORKSPACE); +- PHLWORKSPACE getWorkspaceByID(const int&); ++ PHLWORKSPACE getWorkspaceByID(const WORKSPACEID&); + PHLWORKSPACE getWorkspaceByName(const std::string&); + PHLWORKSPACE getWorkspaceByString(const std::string&); + void sanityCheckWorkspaces(); +- void updateWorkspaceWindowDecos(const int&); +- void updateWorkspaceWindowData(const int&); +- int getWindowsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); +- int getGroupsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); ++ void updateWorkspaceWindowDecos(const WORKSPACEID&); ++ void updateWorkspaceWindowData(const WORKSPACEID&); ++ int getWindowsOnWorkspace(const WORKSPACEID& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); ++ int getGroupsOnWorkspace(const WORKSPACEID& id, std::optional onlyTiled = {}, std::optional onlyVisible = {}); + PHLWINDOW getUrgentWindow(); +- bool hasUrgentWindowOnWorkspace(const int&); +- PHLWINDOW getFirstWindowOnWorkspace(const int&); +- PHLWINDOW getTopLeftWindowOnWorkspace(const int&); +- PHLWINDOW getFullscreenWindowOnWorkspace(const int&); ++ bool hasUrgentWindowOnWorkspace(const WORKSPACEID&); ++ PHLWINDOW getFirstWindowOnWorkspace(const WORKSPACEID&); ++ PHLWINDOW getTopLeftWindowOnWorkspace(const WORKSPACEID&); ++ PHLWINDOW getFullscreenWindowOnWorkspace(const WORKSPACEID&); + bool isWindowActive(PHLWINDOW); + void changeWindowZOrder(PHLWINDOW, bool); +- void cleanupFadingOut(const int& monid); ++ void cleanupFadingOut(const MONITORID& monid); + PHLWINDOW getWindowInDirection(PHLWINDOW, char); + PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); + PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); +- int getNextAvailableNamedWorkspace(); ++ WORKSPACEID getNextAvailableNamedWorkspace(); + bool isPointOnAnyMonitor(const Vector2D&); + bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr); + CMonitor* getMonitorInDirection(const char&); + CMonitor* getMonitorInDirection(CMonitor*, const char&); + void updateAllWindowsAnimatedDecorationValues(); +- void updateWorkspaceWindows(const int64_t& id); ++ void updateWorkspaceWindows(const WORKSPACEID& id); + void updateWindowAnimatedDecorationValues(PHLWINDOW); +- int getNextAvailableMonitorID(std::string const& name); ++ MONITORID getNextAvailableMonitorID(std::string const& name); + void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false); + void swapActiveWorkspaces(CMonitor*, CMonitor*); + CMonitor* getMonitorFromString(const std::string&); +- bool workspaceIDOutOfBounds(const int64_t&); ++ bool workspaceIDOutOfBounds(const WORKSPACEID&); + void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE); + void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE); + void setWindowFullscreenState(const PHLWINDOW PWINDOW, const sFullscreenState state); +@@ -162,12 +163,13 @@ class CCompositor { + PHLLS getLayerSurfaceFromSurface(SP); + void closeWindow(PHLWINDOW); + Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&); +- void forceReportSizesToWindowsOnWorkspace(const int&); +- PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = "", bool isEmtpy = true); // will be deleted next frame if left empty and unfocused! +- void renameWorkspace(const int&, const std::string& name = ""); ++ void forceReportSizesToWindowsOnWorkspace(const WORKSPACEID&); ++ PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "", ++ bool isEmtpy = true); // will be deleted next frame if left empty and unfocused! ++ void renameWorkspace(const WORKSPACEID&, const std::string& name = ""); + void setActiveMonitor(CMonitor*); +- bool isWorkspaceSpecial(const int&); +- int getNewSpecialID(); ++ bool isWorkspaceSpecial(const WORKSPACEID&); ++ WORKSPACEID getNewSpecialID(); + void performUserChecks(); + void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace); + PHLWINDOW getForceFocus(); +diff --git a/src/SharedDefs.hpp b/src/SharedDefs.hpp +index 2a1546c6..9bee7150 100644 +--- a/src/SharedDefs.hpp ++++ b/src/SharedDefs.hpp +@@ -52,4 +52,8 @@ struct SHyprCtlCommand { + std::function fn; + }; + ++typedef int64_t WINDOWID; ++typedef int64_t MONITORID; ++typedef int64_t WORKSPACEID; ++ + typedef std::function HOOK_CALLBACK_FN; +diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp +new file mode 100644 +index 00000000..3c830132 +--- /dev/null ++++ b/src/config/ConfigDescriptions.hpp +@@ -0,0 +1,1344 @@ ++#pragma once ++ ++#include "ConfigManager.hpp" ++ ++inline static const std::vector CONFIG_OPTIONS = { ++ ++ /* ++ * general: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "general:border_size", ++ .description = "size of the border around windows", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{1, 0, 20}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:no_border_on_floating", ++ .description = "disable borders for floating windows", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:gaps_in", ++ .description = "gaps between windows\n\nsupports css style gaps (top, right, bottom, left -> 5 10 15 20)", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{"5"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:gaps_out", ++ .description = "gaps between windows and monitor edges\n\nsupports css style gaps (top, right, bottom, left -> 5 10 15 20)", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{"20"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:gaps_workspaces", ++ .description = "gaps between workspaces. Stacks with gaps_out.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 100}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:col.inactive_border", ++ .description = "border color for inactive windows", ++ .type = CONFIG_OPTION_GRADIENT, ++ .data = SConfigOptionDescription::SGradientData{"0xff444444"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:col.active_border", ++ .description = "border color for the active window", ++ .type = CONFIG_OPTION_GRADIENT, ++ .data = SConfigOptionDescription::SGradientData{"0xffffffff"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:col.nogroup_border", ++ .description = "inactive border color for window that cannot be added to a group (see denywindowfromgroup dispatcher)", ++ .type = CONFIG_OPTION_GRADIENT, ++ .data = SConfigOptionDescription::SGradientData{"0xffffaaff"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:col.nogroup_border_active", ++ .description = "active border color for window that cannot be added to a group", ++ .type = CONFIG_OPTION_GRADIENT, ++ .data = SConfigOptionDescription::SGradientData{"0xffff00ff"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:layout", ++ .description = "which layout to use. [dwindle/master]", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{"dwindle"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:no_focus_fallback", ++ .description = "if true, will not fall back to the next available window when moving focus in a direction where no window was found", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:resize_on_border", ++ .description = "enables resizing windows by clicking and dragging on borders and gaps", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:extend_border_grab_area", ++ .description = "extends the area around the border where you can click and drag on, only used when general:resize_on_border is on.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{15, 0, 100}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:hover_icon_on_border", ++ .description = "show a cursor icon when hovering over borders, only used when general:resize_on_border is on.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:allow_tearing", ++ .description = "master switch for allowing tearing to occur. See the Tearing page.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:resize_corner", ++ .description = "force floating windows to use a specific corner when being resized (1-4 going clockwise from top left, 0 to disable)", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 4}, ++ }, ++ ++ /* ++ * decoration: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "decoration:rounding", ++ .description = "rounded corners' radius (in layout px)", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 20}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:active_opacity", ++ .description = "opacity of active windows. [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{1, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:inactive_opacity", ++ .description = "opacity of inactive windows. [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{1, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:fullscreen_opacity", ++ .description = "opacity of fullscreen windows. [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{1, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:drop_shadow", ++ .description = "enable drop shadows on windows", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:shadow_range", ++ .description = "Shadow range (size) in layout px", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{4, 0, 100}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:shadow_render_power", ++ .description = "in what power to render the falloff (more power, the faster the falloff) [1 - 4]", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{3, 1, 4}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:shadow_ignore_window", ++ .description = "if true, the shadow will not be rendered behind the window itself, only around it.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:col.shadow", ++ .description = "shadow's color. Alpha dictates shadow's opacity.", ++ .type = CONFIG_OPTION_COLOR, ++ .data = SConfigOptionDescription::SColorData{0xee1a1a1a}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:col.shadow_inactive", ++ .description = "inactive shadow color. (if not set, will fall back to col.shadow)", ++ .type = CONFIG_OPTION_COLOR, ++ .data = SConfigOptionDescription::SColorData{}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:shadow_offset", ++ .description = "shadow's rendering offset.", ++ .type = CONFIG_OPTION_VECTOR, ++ .data = SConfigOptionDescription::SVectorData{{}, {-250, -250}, {250, 250}}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:shadow_scale", ++ .description = "shadow's scale. [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{1, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:dim_inactive", ++ .description = "enables dimming of inactive windows", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:dim_strength", ++ .description = "how much inactive windows should be dimmed [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0.5, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:dim_special", ++ .description = "how much to dim the rest of the screen by when a special workspace is open. [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0.2, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:dim_around", ++ .description = "how much the dimaround window rule should dim by. [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0.4, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "decoration:screen_shader", ++ .description = "screen_shader a path to a custom shader to be applied at the end of rendering. See examples/screenShader.frag for an example.", ++ .type = CONFIG_OPTION_STRING_LONG, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ ++ /* ++ * blur: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "blur:enabled", ++ .description = "enable kawase window background blur", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:size", ++ .description = "blur size (distance)", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{8, 0, 100}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:passes", ++ .description = "the amount of passes to perform", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{1, 0, 10}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:ignore_opacity", ++ .description = "make the blur layer ignore the opacity of the window", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:new_optimizations", ++ .description = "whether to enable further optimizations to the blur. Recommended to leave on, as it will massively improve performance.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:xray", ++ .description = "if enabled, floating windows will ignore tiled windows in their blur. Only available if blur_new_optimizations is true. Will reduce overhead on floating " ++ "blur significantly.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:noise", ++ .description = "how much noise to apply. [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0.0117, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:contrast", ++ .description = "contrast modulation for blur. [0.0 - 2.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0.8916, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:brightness", ++ .description = "brightness modulation for blur. [0.0 - 2.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0.8172, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:vibrancy", ++ .description = "Increase saturation of blurred colors. [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0.1696, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:vibrancy_darkness", ++ .description = "How strong the effect of vibrancy is on dark areas . [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:special", ++ .description = "whether to blur behind the special workspace (note: expensive)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:popups", ++ .description = "whether to blur popups (e.g. right-click menus)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "blur:popups_ignorealpha", ++ .description = "works like ignorealpha in layer rules. If pixel opacity is below set value, will not blur. [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0.2, 0, 1}, ++ }, ++ ++ /* ++ * animations: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "animations:enabled", ++ .description = "enable animations", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "animations:first_launch_animation", ++ .description = "enable first launch animation", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ ++ /* ++ * input: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "input:kb_model", ++ .description = "Appropriate XKB keymap parameter. See the note below.", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{STRVAL_EMPTY}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:kb_layout", ++ .description = "Appropriate XKB keymap parameter", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{"us"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:kb_variant", ++ .description = "Appropriate XKB keymap parameter", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:kb_options", ++ .description = "Appropriate XKB keymap parameter", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:kb_rules", ++ .description = "Appropriate XKB keymap parameter", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:kb_file", ++ .description = "Appropriate XKB keymap parameter", ++ .type = CONFIG_OPTION_STRING_LONG, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "input:numlock_by_default", ++ .description = "Engage numlock by default.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:resolve_binds_by_sym", ++ .description = "Determines how keybinds act when multiple layouts are used. If false, keybinds will always act as if the first specified layout is active. If true, " ++ "keybinds specified by symbols are activated when you type the respective symbol with the current layout.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:repeat_rate", ++ .description = "The repeat rate for held-down keys, in repeats per second.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{25, 0, 200}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:repeat_delay", ++ .description = "Delay before a held-down key is repeated, in milliseconds.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{600, 0, 2000}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:sensitivity", ++ .description = "Sets the mouse input sensitivity. Value is clamped to the range -1.0 to 1.0.", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0, -1, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:accel_profile", ++ .description = "Sets the cursor acceleration profile. Can be one of adaptive, flat. Can also be custom, see below. Leave empty to use libinput's default mode for your " ++ "input device. [adaptive/flat/custom]", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "input:force_no_accel", ++ .description = "Force no cursor acceleration. This bypasses most of your pointer settings to get as raw of a signal as possible. Enabling this is not recommended due to " ++ "potential cursor desynchronization.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:left_handed", ++ .description = "Switches RMB and LMB", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:scroll_points", ++ .description = "Sets the scroll acceleration profile, when accel_profile is set to custom. Has to be in the form . Leave empty to have a flat scroll curve.", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "input:scroll_method", ++ .description = "Sets the scroll method. Can be one of 2fg (2 fingers), edge, on_button_down, no_scroll. [2fg/edge/on_button_down/no_scroll]", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "input:scroll_button", ++ .description = "Sets the scroll button. Has to be an int, cannot be a string. Check wev if you have any doubts regarding the ID. 0 means default.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 300}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:scroll_button_lock", ++ .description = "If the scroll button lock is enabled, the button does not need to be held down. Pressing and releasing the button toggles the button lock, which logically " ++ "holds the button down or releases it. While the button is logically held down, motion events are converted to scroll events.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:scroll_factor", ++ .description = "Multiplier added to scroll movement for external mice. Note that there is a separate setting for touchpad scroll_factor.", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{1, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:natural_scroll", ++ .description = "Inverts scrolling direction. When enabled, scrolling moves content directly, rather than manipulating a scrollbar.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:follow_mouse", ++ .description = "Specify if and how cursor movement should affect window focus. See the note below. [0/1/2/3]", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{1, 0, 3}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:mouse_refocus", ++ .description = "if disabled, mouse focus won't switch to the hovered window unless the mouse crosses a window boundary when follow_mouse=1.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:float_switch_override_focus", ++ .description = "If enabled (1 or 2), focus will change to the window under the cursor when changing from tiled-to-floating and vice versa. If 2, focus will also follow " ++ "mouse on float-to-float switches.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{1, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:special_fallthrough", ++ .description = "if enabled, having only floating windows in the special workspace will not block focusing windows in the regular workspace.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:off_window_axis_events", ++ .description = "Handles axis events around (gaps/border for tiled, dragarea/border for floated) a focused window. 0 ignores axis events 1 sends out-of-bound coordinates 2 " ++ "fakes pointer coordinates to the closest point inside the window 3 warps the cursor to the closest point inside the window", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{1, 0, 3}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:emulate_discrete_scroll", ++ .description = "Emulates discrete scrolling from high resolution scrolling events. 0 disables it, 1 enables handling of non-standard events only, and 2 force enables all " ++ "scroll wheel events to be handled", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{1, 0, 2}, ++ }, ++ ++ /* ++ * input:touchpad: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "input:touchpad:disable_while_typing", ++ .description = "Disable the touchpad while typing.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchpad:natural_scroll", ++ .description = "Inverts scrolling direction. When enabled, scrolling moves content directly, rather than manipulating a scrollbar.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchpad:scroll_factor", ++ .description = "Multiplier applied to the amount of scroll movement.", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{1, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchpad:middle_button_emulation", ++ .description = ++ "Sending LMB and RMB simultaneously will be interpreted as a middle click. This disables any touchpad area that would normally send a middle click based on location.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchpad:tap_button_map", ++ .description = "Sets the tap button mapping for touchpad button emulation. Can be one of lrm (default) or lmr (Left, Middle, Right Buttons). [lrm/lmr]", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchpad:clickfinger_behavior", ++ .description = ++ "Button presses with 1, 2, or 3 fingers will be mapped to LMB, RMB, and MMB respectively. This disables interpretation of clicks based on location on the touchpad.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchpad:tap-to-click", ++ .description = "Tapping on the touchpad with 1, 2, or 3 fingers will send LMB, RMB, and MMB respectively.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchpad:drag_lock", ++ .description = "When enabled, lifting the finger off for a short time while dragging will not drop the dragged item.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchpad:tap-and-drag", ++ .description = "Sets the tap and drag mode for the touchpad", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ ++ /* ++ * input:touchdevice: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "input:touchdevice:transform", ++ .description = "Transform the input from touchdevices. The possible transformations are the same as those of the monitors", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 6}, // ##TODO RANGE? ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchdevice:output", ++ .description = "The monitor to bind touch devices. The default is auto-detection. To stop auto-detection, use an empty string or the [[Empty]] value.", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "input:touchdevice:enabled", ++ .description = "Whether input is enabled for touch devices.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ ++ /* ++ * input:tablet: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "input:tablet:transform", ++ .description = "transform the input from tablets. The possible transformations are the same as those of the monitors", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 6}, // ##TODO RANGE? ++ }, ++ SConfigOptionDescription{ ++ .value = "input:tablet:output", ++ .description = "the monitor to bind tablets. Empty means unbound..", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "input:tablet:region_position", ++ .description = "position of the mapped region in monitor layout.", ++ .type = CONFIG_OPTION_VECTOR, ++ .data = SConfigOptionDescription::SVectorData{{}, {-20000, -20000}, {20000, 20000}}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:tablet:region_size", ++ .description = "size of the mapped region. When this variable is set, tablet input will be mapped to the region. [0, 0] or invalid size means unset.", ++ .type = CONFIG_OPTION_VECTOR, ++ .data = SConfigOptionDescription::SVectorData{{}, {-100, -100}, {4000, 4000}}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:tablet:relative_input", ++ .description = "whether the input should be relative", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:tablet:left_handed", ++ .description = "if enabled, the tablet will be rotated 180 degrees", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:tablet:active_area_size", ++ .description = "size of tablet's active area in mm", ++ .type = CONFIG_OPTION_VECTOR, ++ .data = SConfigOptionDescription::SVectorData{{}, {}, {500, 500}}, ++ }, ++ SConfigOptionDescription{ ++ .value = "input:tablet:active_area_position", ++ .description = "position of the active area in mm", ++ .type = CONFIG_OPTION_VECTOR, ++ .data = SConfigOptionDescription::SVectorData{{}, {}, {500, 500}}, ++ }, ++ ++ /* ##TODO ++ * ++ * PER DEVICE SETTINGS? ++ * ++ * */ ++ ++ /* ++ * gestures: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe", ++ .description = "enable workspace swipe gesture on touchpad", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_fingers", ++ .description = "how many fingers for the touchpad gesture", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{3, 0, 5}, //##TODO RANGE? ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_min_fingers", ++ .description = "if enabled, workspace_swipe_fingers is considered the minimum number of fingers to swipe", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_distance", ++ .description = "in px, the distance of the touchpad gesture", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{300, 0, 2000}, //##TODO RANGE? ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_touch", ++ .description = "enable workspace swiping from the edge of a touchscreen", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_invert", ++ .description = "invert the direction (touchpad only)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_touch_invert", ++ .description = "invert the direction (touchscreen only)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_min_speed_to_force", ++ .description = "minimum speed in px per timepoint to force the change ignoring cancel_ratio. Setting to 0 will disable this mechanic.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{30, 0, 200}, //##TODO RANGE? ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_cancel_ratio", ++ .description = "how much the swipe has to proceed in order to commence it. (0.7 -> if > 0.7 * distance, switch, if less, revert) [0.0 - 1.0]", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{0.5, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_create_new", ++ .description = "whether a swipe right on the last workspace should create a new one.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_direction_lock", ++ .description = "if enabled, switching direction will be locked when you swipe past the direction_lock_threshold (touchpad only).", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_direction_lock_threshold", ++ .description = "in px, the distance to swipe before direction lock activates (touchpad only).", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{10, 0, 200}, //##TODO RANGE? ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_forever", ++ .description = "if enabled, swiping will not clamp at the neighboring workspaces but continue to the further ones.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "gestures:workspace_swipe_use_r", ++ .description = "if enabled, swiping will use the r prefix instead of the m prefix for finding workspaces.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ ++ /* ++ * group: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "group:insert_after_current", ++ .description = "whether new windows in a group spawn after current or at group tail", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:focus_removed_window", ++ .description = "whether Hyprland should focus on the window that has just been moved out of the group", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:col.border_active", ++ .description = "border color for inactive windows", ++ .type = CONFIG_OPTION_GRADIENT, ++ .data = SConfigOptionDescription::SGradientData{"0x66ffff00"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:col.border_inactive", ++ .description = "border color for the active window", ++ .type = CONFIG_OPTION_GRADIENT, ++ .data = SConfigOptionDescription::SGradientData{"0x66777700"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:col.border_locked_active", ++ .description = "inactive border color for window that cannot be added to a group (see denywindowfromgroup dispatcher)", ++ .type = CONFIG_OPTION_GRADIENT, ++ .data = SConfigOptionDescription::SGradientData{"0x66ff5500"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "general:col.border_locked_inactive", ++ .description = "active border color for window that cannot be added to a group", ++ .type = CONFIG_OPTION_GRADIENT, ++ .data = SConfigOptionDescription::SGradientData{"0x66775500"}, ++ }, ++ ++ /* ++ * group:groupbar: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "group:groupbar:enabled", ++ .description = "enables groupbars", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:font_family", ++ .description = "font used to display groupbar titles, use misc:font_family if not specified", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{STRVAL_EMPTY}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:font_size", ++ .description = "font size of groupbar title", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{8, 2, 64}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:gradients", ++ .description = "enables gradients", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:height", ++ .description = "height of the groupbar", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{14, 1, 64}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:stacked", ++ .description = "render the groupbar as a vertical stack", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:priority", ++ .description = "sets the decoration priority for groupbars", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{3, 0, 6}, //##TODO RANGE? ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:render_titles", ++ .description = "whether to render titles in the group bar decoration", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:scrolling", ++ .description = "whether scrolling in the groupbar changes group active window", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:text_color", ++ .description = "controls the group bar text color", ++ .type = CONFIG_OPTION_COLOR, ++ .data = SConfigOptionDescription::SColorData{0xffffffff}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:col.active", ++ .description = "active group border color", ++ .type = CONFIG_OPTION_COLOR, ++ .data = SConfigOptionDescription::SColorData{0x66ffff00}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:col.inactive", ++ .description = "inactive (out of focus) group border color", ++ .type = CONFIG_OPTION_COLOR, ++ .data = SConfigOptionDescription::SColorData{0x66777700}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:col.locked_active", ++ .description = "active locked group border color", ++ .type = CONFIG_OPTION_COLOR, ++ .data = SConfigOptionDescription::SColorData{0x66ff5500}, ++ }, ++ SConfigOptionDescription{ ++ .value = "group:groupbar:col.locked_inactive", ++ .description = "controls the group bar text color", ++ .type = CONFIG_OPTION_COLOR, ++ .data = SConfigOptionDescription::SColorData{0x66775500}, ++ }, ++ ++ /* ++ * misc: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "misc:disable_hyprland_logo", ++ .description = "disables the random Hyprland logo / anime girl background. :(", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:disable_splash_rendering", ++ .description = "disables the Hyprland splash rendering. (requires a monitor reload to take effect)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:col.splash", ++ .description = "Changes the color of the splash text (requires a monitor reload to take effect).", ++ .type = CONFIG_OPTION_COLOR, ++ .data = SConfigOptionDescription::SColorData{0xffffffff}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:font_family", ++ .description = "Set the global default font to render the text including debug fps/notification, config error messages and etc., selected from system fonts.", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{"Sans"}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:splash_font_family", ++ .description = "Changes the font used to render the splash text, selected from system fonts (requires a monitor reload to take effect).", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{STRVAL_EMPTY}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:force_default_wallpaper", ++ .description = "Enforce any of the 3 default wallpapers. Setting this to 0 or 1 disables the anime background. -1 means “random”. [-1/0/1/2]", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{-1, -1, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:vfr", ++ .description = "controls the VFR status of Hyprland. Heavily recommended to leave enabled to conserve resources.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:vrr", ++ .description = " controls the VRR (Adaptive Sync) of your monitors. 0 - off, 1 - on, 2 - fullscreen only [0/1/2]", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:mouse_move_enables_dpms", ++ .description = "If DPMS is set to off, wake up the monitors if the mouse move", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:key_press_enables_dpms", ++ .description = "If DPMS is set to off, wake up the monitors if a key is pressed.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:always_follow_on_dnd", ++ .description = "Will make mouse focus follow the mouse when drag and dropping. Recommended to leave it enabled, especially for people using focus follows mouse at 0.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:layers_hog_keyboard_focus", ++ .description = "If true, will make keyboard-interactive layers keep their focus on mouse move (e.g. wofi, bemenu)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:animate_manual_resizes", ++ .description = "If true, will animate manual window resizes/moves", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:animate_mouse_windowdragging", ++ .description = "If true, will animate windows being dragged by mouse, note that this can cause weird behavior on some curves", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:disable_autoreload", ++ .description = "If true, the config will not reload automatically on save, and instead needs to be reloaded with hyprctl reload. Might save on battery.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:enable_swallow", ++ .description = "Enable window swallowing", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:swallow_regex", ++ .description = ++ "The class regex to be used for windows that should be swallowed (usually, a terminal). To know more about the list of regex which can be used use this cheatsheet.", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:swallow_exception_regex", ++ .description = "The title regex to be used for windows that should not be swallowed by the windows specified in swallow_regex (e.g. wev). The regex is matched against the " ++ "parent (e.g. Kitty) window’s title on the assumption that it changes to whatever process it’s running.", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:focus_on_activate", ++ .description = "Whether Hyprland should focus an app that requests to be focused (an activate request)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:mouse_move_focuses_monitor", ++ .description = "Whether mouse moving into a different monitor should focus it", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:render_ahead_of_time", ++ .description = "[Warning: buggy] starts rendering before your monitor displays a frame in order to lower latency", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:render_ahead_safezone", ++ .description = "how many ms of safezone to add to rendering ahead of time. Recommended 1-2.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{1, 1, 10}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:allow_session_lock_restore", ++ .description = "if true, will allow you to restart a lockscreen app in case it crashes (red screen of death)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:background_color", ++ .description = "change the background color. (requires enabled disable_hyprland_logo)", ++ .type = CONFIG_OPTION_COLOR, ++ .data = SConfigOptionDescription::SColorData{0x111111}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:close_special_on_empty", ++ .description = "close the special workspace if the last window is removed", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:new_window_takes_over_fullscreen", ++ .description = "if there is a fullscreen or maximized window, decide whether a new tiled window opened should replace it, stay behind or disable the fullscreen/maximized " ++ "state. 0 - behind, 1 - takes over, 2 - unfullscreen/unmaxize [0/1/2]", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:exit_window_retains_fullscreen", ++ .description = "if true, closing a fullscreen window makes the next focused window fullscreen", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:initial_workspace_tracking", ++ .description = "if enabled, windows will open on the workspace they were invoked on. 0 - disabled, 1 - single-shot, 2 - persistent (all children too)", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{1, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "misc:middle_click_paste", ++ .description = "whether to enable middle-click-paste (aka primary selection)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ ++ /* ++ * binds: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "binds:pass_mouse_when_bound", ++ .description = "if disabled, will not pass the mouse events to apps / dragging windows around if a keybind has been triggered.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "binds:scroll_event_delay", ++ .description = "in ms, how many ms to wait after a scroll event to allow passing another one for the binds.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{300, 0, 2000}, ++ }, ++ SConfigOptionDescription{ ++ .value = "binds:workspace_back_and_forth", ++ .description = "If enabled, an attempt to switch to the currently focused workspace will instead switch to the previous workspace. Akin to i3’s auto_back_and_forth.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "binds:allow_workspace_cycles", ++ .description = "If enabled, workspaces don’t forget their previous workspace, so cycles can be created by switching to the first workspace in a sequence, then endlessly " ++ "going to the previous workspace.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "binds:workspace_center_on", ++ .description = "Whether switching workspaces should center the cursor on the workspace (0) or on the last active window for that workspace (1)", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "binds:focus_preferred_method", ++ .description = "sets the preferred focus finding method when using focuswindow/movewindow/etc with a direction. 0 - history (recent have priority), 1 - length (longer " ++ "shared edges have priority)", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "binds:ignore_group_lock", ++ .description = "If enabled, dispatchers like moveintogroup, moveoutofgroup and movewindoworgroup will ignore lock per group.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "binds:movefocus_cycles_fullscreen", ++ .description = "If enabled, when on a fullscreen window, movefocus will cycle fullscreen, if not, it will move the focus in a direction.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "binds:disable_keybind_grabbing", ++ .description = "If enabled, apps that request keybinds to be disabled (e.g. VMs) will not be able to do so.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "binds:window_direction_monitor_fallback", ++ .description = "If enabled, moving a window or focus over the edge of a monitor with a direction will move it to the next monitor in that direction.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ ++ /* ++ * xwayland: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "xwayland:use_nearest_neighbor", ++ .description = "uses the nearest neighbor filtering for xwayland apps, making them pixelated rather than blurry", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "xwayland:force_zero_scaling", ++ .description = "forces a scale of 1 on xwayland windows on scaled displays.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ ++ /* ++ * opengl: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "opengl:nvidia_anti_flicker", ++ .description = "reduces flickering on nvidia at the cost of possible frame drops on lower-end GPUs. On non-nvidia, this is ignored.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "opengl:force_introspection", ++ .description = "forces introspection at all times. Introspection is aimed at reducing GPU usage in certain cases, but might cause graphical glitches on nvidia. 0 - " ++ "nothing, 1 - force always on, 2 - force always on if nvidia", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{2, 0, 2}, ++ }, ++ ++ /* ++ * render: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "render:explicit_sync", ++ .description = "Whether to enable explicit sync support. Requires a hyprland restart. 0 - no, 1 - yes, 2 - auto based on the gpu driver", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{2, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "render:explicit_sync_kms", ++ .description = "Whether to enable explicit sync support for the KMS layer. Requires explicit_sync to be enabled. 0 - no, 1 - yes, 2 - auto based on the gpu driver", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{2, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "render:direct_scanout", ++ .description = "Enables direct scanout. Direct scanout attempts to reduce lag when there is only one fullscreen application on a screen (e.g. game). It is also " ++ "recommended to set this to false if the fullscreen application shows graphical glitches.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ ++ /* ++ * cursor: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "cursor:use_nearest_neighbor", ++ .description = "sync xcursor theme with gsettings, it applies cursor-theme and cursor-size on theme load to gsettings making most CSD gtk based clients use same xcursor " ++ "theme and size.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:no_hardware_cursors", ++ .description = "disables hardware cursors", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:no_break_fs_vrr", ++ .description = "disables scheduling new frames on cursor movement for fullscreen apps with VRR enabled to avoid framerate spikes (requires no_hardware_cursors = true)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:min_refresh_rate", ++ .description = "minimum refresh rate for cursor movement when no_break_fs_vrr is active. Set to minimum supported refresh rate or higher", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{24, 10, 500}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:hotspot_padding", ++ .description = "the padding, in logical px, between screen edges and the cursor", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{1, 0, 20}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:inactive_timeout", ++ .description = "in seconds, after how many seconds of cursor’s inactivity to hide it. Set to 0 for never.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 20}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:no_warps", ++ .description = "if true, will not warp the cursor in many cases (focusing, keybinds, etc)", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:persistent_warps", ++ .description = "When a window is refocused, the cursor returns to its last position relative to that window, rather than to the centre.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:warp_on_change_workspace", ++ .description = "If true, move the cursor to the last focused window after changing the workspace.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:default_monitor", ++ .description = "the name of a default monitor for the cursor to be set to on startup (see hyprctl monitors for names)", ++ .type = CONFIG_OPTION_STRING_SHORT, ++ .data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET? ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:zoom_factor", ++ .description = "the factor to zoom by around the cursor. Like a magnifying glass. Minimum 1.0 (meaning no zoom)", ++ .type = CONFIG_OPTION_FLOAT, ++ .data = SConfigOptionDescription::SFloatData{1, 1, 10}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:zoom_rigid", ++ .description = "whether the zoom should follow the cursor rigidly (cursor is always centered if it can be) or loosely", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:enable_hyprcursor", ++ .description = "whether to enable hyprcursor support", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:hide_on_key_press", ++ .description = "Hides the cursor when you press any key until the mouse is moved.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:hide_on_touch", ++ .description = "Hides the cursor when the last input was a touch input until a mouse input is done.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "cursor:allow_dumb_copy", ++ .description = "Makes HW cursors work on Nvidia, at the cost of a possible hitch whenever the image changes", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ ++ /* ++ * debug: ++ */ ++ ++ SConfigOptionDescription{ ++ .value = "debug:overlay", ++ .description = "print the debug performance overlay. Disable VFR for accurate results.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:damage_blink", ++ .description = "disable logging to a file", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:disable_logs", ++ .description = "disable logging to a file", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:disable_time", ++ .description = "disables time logging", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:damage_tracking", ++ .description = "redraw only the needed bits of the display. Do not change. (default: full - 2) monitor - 1, none - 0", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{2, 0, 2}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:enable_stdout_logs", ++ .description = "enables logging to stdout", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:manual_crash", ++ .description = "set to 1 and then back to 0 to crash Hyprland.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:suppress_errors", ++ .description = "if true, do not display config file parsing errors.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:watchdog_timeout", ++ .description = "sets the timeout in seconds for watchdog to abort processing of a signal of the main thread. Set to 0 to disable.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{5, 0, 20}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:disable_scale_checks", ++ .description = "disables verification of the scale factors. Will result in pixel alignment and rounding errors.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{false}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:error_limit", ++ .description = "limits the number of displayed config file parsing errors.", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{5, 0, 20}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:error_position", ++ .description = "sets the position of the error bar. top - 0, bottom - 1", ++ .type = CONFIG_OPTION_INT, ++ .data = SConfigOptionDescription::SRangeData{0, 0, 1}, ++ }, ++ SConfigOptionDescription{ ++ .value = "debug:colored_stdout_logs", ++ .description = "enables colors in the stdout logs.", ++ .type = CONFIG_OPTION_BOOL, ++ .data = SConfigOptionDescription::SBoolData{true}, ++ }, ++}; +\ No newline at end of file +diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp +index be6433fa..1856bd49 100644 +--- a/src/config/ConfigManager.cpp ++++ b/src/config/ConfigManager.cpp +@@ -28,7 +28,9 @@ + #include + using namespace Hyprutils::String; + +-extern "C" char** environ; ++extern "C" char** environ; ++ ++#include "ConfigDescriptions.hpp" + + static Hyprlang::CParseResult configHandleGradientSet(const char* VALUE, void** data) { + std::string V = VALUE; +@@ -312,8 +314,6 @@ CConfigManager::CConfigManager() { + configPaths.emplace_back(getMainConfigPath()); + m_pConfig = std::make_unique(configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true}); + +- m_pConfig->addConfigValue("general:sensitivity", {1.0f}); +- m_pConfig->addConfigValue("general:apply_sens_to_raw", Hyprlang::INT{0}); + m_pConfig->addConfigValue("general:border_size", Hyprlang::INT{1}); + m_pConfig->addConfigValue("general:no_border_on_floating", Hyprlang::INT{0}); + m_pConfig->addConfigValue("general:border_part_of_window", Hyprlang::INT{1}); +@@ -531,7 +531,7 @@ CConfigManager::CConfigManager() { + m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0}); + m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24}); + m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0}); +- m_pConfig->addConfigValue("cursor:inactive_timeout", Hyprlang::INT{0}); ++ m_pConfig->addConfigValue("cursor:inactive_timeout", {0.f}); + m_pConfig->addConfigValue("cursor:no_warps", Hyprlang::INT{0}); + m_pConfig->addConfigValue("cursor:persistent_warps", Hyprlang::INT{0}); + m_pConfig->addConfigValue("cursor:warp_on_change_workspace", Hyprlang::INT{0}); +@@ -539,6 +539,7 @@ CConfigManager::CConfigManager() { + m_pConfig->addConfigValue("cursor:zoom_factor", {1.f}); + m_pConfig->addConfigValue("cursor:zoom_rigid", Hyprlang::INT{0}); + m_pConfig->addConfigValue("cursor:enable_hyprcursor", Hyprlang::INT{1}); ++ m_pConfig->addConfigValue("cursor:sync_gsettings_theme", Hyprlang::INT{1}); + m_pConfig->addConfigValue("cursor:hide_on_key_press", Hyprlang::INT{0}); + m_pConfig->addConfigValue("cursor:hide_on_touch", Hyprlang::INT{1}); + m_pConfig->addConfigValue("cursor:allow_dumb_copy", Hyprlang::INT{0}); +@@ -821,9 +822,6 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { + if (!isFirstLaunch) + g_pHyprOpenGL->m_bReloadScreenShader = true; + +- if (!isFirstLaunch && *PENABLEEXPLICIT != prevEnabledExplicit) +- g_pHyprError->queueCreate("Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland.", CColor(0.9, 0.76, 0.221, 1.0)); +- + // parseError will be displayed next frame + + if (result.error) +@@ -836,6 +834,8 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { + else if (std::any_cast(m_pConfig->getConfigValue("autogenerated")) == 1) + g_pHyprError->queueCreate("Warning: You're using an autogenerated config! (config file: " + getMainConfigPath() + " )\nSUPER+Q -> kitty\nSUPER+M -> exit Hyprland", + CColor(1.0, 1.0, 70.0 / 255.0, 1.0)); ++ else if (*PENABLEEXPLICIT != prevEnabledExplicit) ++ g_pHyprError->queueCreate("Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland.", CColor(0.9, 0.76, 0.221, 1.0)); + else + g_pHyprError->destroy(); + +@@ -924,7 +924,10 @@ void CConfigManager::init() { + } + + std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& VALUE) { +- const auto RET = m_pConfig->parseDynamic(COMMAND.c_str(), VALUE.c_str()); ++ static const auto PENABLEEXPLICIT = CConfigValue("render:explicit_sync"); ++ static int prevEnabledExplicit = *PENABLEEXPLICIT; ++ ++ const auto RET = m_pConfig->parseDynamic(COMMAND.c_str(), VALUE.c_str()); + + // invalidate layouts if they changed + if (COMMAND == "monitor" || COMMAND.contains("gaps_") || COMMAND.starts_with("dwindle:") || COMMAND.starts_with("master:")) { +@@ -932,6 +935,13 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std:: + g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID); + } + ++ if (COMMAND.contains("explicit")) { ++ if (*PENABLEEXPLICIT != prevEnabledExplicit) ++ g_pHyprError->queueCreate("Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland.", CColor(0.9, 0.76, 0.221, 1.0)); ++ else ++ g_pHyprError->destroy(); ++ } ++ + // Update window border colors + g_pCompositor->updateAllWindowsAnimatedDecorationValues(); + +@@ -2425,7 +2435,7 @@ std::optional CConfigManager::handleWorkspaceRules(const std::strin + // } + + const static std::string ruleOnCreatedEmpty = "on-created-empty:"; +- const static int ruleOnCreatedEmptyLen = ruleOnCreatedEmpty.length(); ++ const static auto ruleOnCreatedEmptyLen = ruleOnCreatedEmpty.length(); + + auto assignRule = [&](std::string rule) -> std::optional { + size_t delim = std::string::npos; +@@ -2597,3 +2607,60 @@ std::optional CConfigManager::handlePlugin(const std::string& comma + + return {}; + } ++ ++const std::vector& CConfigManager::getAllDescriptions() { ++ return CONFIG_OPTIONS; ++} ++ ++std::string SConfigOptionDescription::jsonify() const { ++ auto parseData = [this]() -> std::string { ++ return std::visit( ++ [](auto&& val) { ++ using T = std::decay_t; ++ if constexpr (std::is_same_v) { ++ return std::format(R"#( "value": "{}")#", val.value); ++ } else if constexpr (std::is_same_v) { ++ return std::format(R"#( "value": {}, ++ "min": {}, ++ "max": {})#", ++ val.value, val.min, val.max); ++ } else if constexpr (std::is_same_v) { ++ return std::format(R"#( "value": {}, ++ "min": {}, ++ "max": {})#", ++ val.value, val.min, val.max); ++ } else if constexpr (std::is_same_v) { ++ return std::format(R"#( "value": {})#", val.color.getAsHex()); ++ } else if constexpr (std::is_same_v) { ++ return std::format(R"#( "value": {})#", val.value); ++ } else if constexpr (std::is_same_v) { ++ return std::format(R"#( "value": {})#", val.choices); ++ } else if constexpr (std::is_same_v) { ++ return std::format(R"#( "x": {}, ++ "y": {}, ++ "min_x": {}, ++ "min_y": {}, ++ "max_x": {}, ++ "max_y": {})#", ++ val.vec.x, val.vec.y, val.min.x, val.min.y, val.max.x, val.max.y); ++ } else if constexpr (std::is_same_v) { ++ return std::format(R"#( "value": "{}")#", val.gradient); ++ } ++ return std::string{""}; ++ }, ++ data); ++ }; ++ ++ std::string json = std::format(R"#({{ ++ "value": "{}", ++ "description": "{}", ++ "type": {}, ++ "flags": {}, ++ "data": {{ ++ {} ++ }} ++}})#", ++ value, description, (uint16_t)type, (uint32_t)flags, parseData()); ++ ++ return json; ++} +diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp +index 75dea9ef..4241031b 100644 +--- a/src/config/ConfigManager.hpp ++++ b/src/config/ConfigManager.hpp +@@ -33,7 +33,7 @@ struct SWorkspaceRule { + std::string monitor = ""; + std::string workspaceString = ""; + std::string workspaceName = ""; +- int workspaceId = -1; ++ WORKSPACEID workspaceId = -1; + bool isDefault = false; + bool isPersistent = false; + std::optional gapsIn; +@@ -83,6 +83,70 @@ struct SExecRequestedRule { + uint64_t iPid = 0; + }; + ++enum eConfigOptionType : uint16_t { ++ CONFIG_OPTION_BOOL = 0, ++ CONFIG_OPTION_INT = 1, /* e.g. 0/1/2*/ ++ CONFIG_OPTION_FLOAT = 2, ++ CONFIG_OPTION_STRING_SHORT = 3, /* e.g. "auto" */ ++ CONFIG_OPTION_STRING_LONG = 4, /* e.g. a command */ ++ CONFIG_OPTION_COLOR = 5, ++ CONFIG_OPTION_CHOICE = 6, /* e.g. "one", "two", "three" */ ++ CONFIG_OPTION_GRADIENT = 7, ++ CONFIG_OPTION_VECTOR = 8, ++}; ++ ++enum eConfigOptionFlags : uint32_t { ++ CONFIG_OPTION_FLAG_PERCENTAGE = (1 << 0), ++}; ++ ++struct SConfigOptionDescription { ++ ++ struct SBoolData { ++ bool value = false; ++ }; ++ ++ struct SRangeData { ++ int value = 0, min = 0, max = 2; ++ }; ++ ++ struct SFloatData { ++ float value = 0, min = 0, max = 100; ++ }; ++ ++ struct SStringData { ++ std::string value; ++ }; ++ ++ struct SColorData { ++ CColor color; ++ }; ++ ++ struct SChoiceData { ++ int firstIndex = 0; ++ std::string choices; // comma-separated ++ }; ++ ++ struct SGradientData { ++ std::string gradient; ++ }; ++ ++ struct SVectorData { ++ Vector2D vec, min, max; ++ }; ++ ++ std::string value; // e.g. general:gaps_in ++ std::string description; ++ std::string specialCategory; // if value is special (e.g. device:abc) value will be abc and special device ++ bool specialKey = false; ++ eConfigOptionType type = CONFIG_OPTION_BOOL; ++ uint32_t flags = 0; // eConfigOptionFlags ++ ++ std::string jsonify() const; ++ ++ // ++ std::variant data; ++}; ++ + class CConfigManager { + public: + CConfigManager(); +@@ -115,6 +179,8 @@ class CConfigManager { + std::vector getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false); + std::vector getMatchingRules(PHLLS); + ++ const std::vector& getAllDescriptions(); ++ + std::unordered_map m_mAdditionalReservedAreas; + + std::unordered_map getAnimationConfig(); +diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp +index d91a1cec..78c8504a 100644 +--- a/src/debug/HyprCtl.cpp ++++ b/src/debug/HyprCtl.cpp +@@ -71,7 +71,7 @@ static std::string availableModesForOutput(CMonitor* pMonitor, eHyprCtlOutputFor + + std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer m, eHyprCtlOutputFormat format) { + std::string result; +- if (!m->output || m->ID == -1ull) ++ if (!m->output || m->ID == -1) + return ""; + + if (format == eHyprCtlOutputFormat::FORMAT_JSON) { +@@ -155,19 +155,19 @@ std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) { + result += "]"; + } else { + for (auto& m : allMonitors ? g_pCompositor->m_vRealMonitors : g_pCompositor->m_vMonitors) { +- if (!m->output || m->ID == -1ull) ++ if (!m->output || m->ID == -1) + continue; + +- result += +- std::format("Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\t" +- "special workspace: {} ({})\n\treserved: {} {} {} {}\n\tscale: {:.2f}\n\ttransform: {}\n\tfocused: {}\n\t" +- "dpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: {}\n\tavailableModes: {}\n\n", +- m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription, +- m->output->make, m->output->model, m->output->serial, m->activeWorkspaceID(), (!m->activeWorkspace ? "" : m->activeWorkspace->m_szName), +- m->activeSpecialWorkspaceID(), (m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x, +- (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, +- (m == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus, (int)(m->output->state ? m->output->state->state().adaptiveSync : false), +- m->tearingState.activelyTearing, !m->m_bEnabled, formatToString(m->output->state->state().drmFormat), availableModesForOutput(m.get(), format)); ++ result += std::format( ++ "Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\t" ++ "special workspace: {} ({})\n\treserved: {} {} {} {}\n\tscale: {:.2f}\n\ttransform: {}\n\tfocused: {}\n\t" ++ "dpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: A {} H {}\n\tavailableModes: {}\n\n", ++ m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription, ++ m->output->make, m->output->model, m->output->serial, m->activeWorkspaceID(), (!m->activeWorkspace ? "" : m->activeWorkspace->m_szName), ++ m->activeSpecialWorkspaceID(), (m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, ++ (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m == g_pCompositor->m_pLastMonitor ? "yes" : "no"), ++ (int)m->dpmsStatus, (int)(m->output->state ? m->output->state->state().adaptiveSync : false), m->tearingState.activelyTearing, !m->m_bEnabled, ++ formatToString(m->output->state->state().drmFormat), formatToString(m->drmFormat), availableModesForOutput(m.get(), format)); + } + } + +@@ -1561,6 +1561,21 @@ std::string getIsLocked(eHyprCtlOutputFormat format, std::string request) { + return lockedStr; + } + ++std::string getDescriptions(eHyprCtlOutputFormat format, std::string request) { ++ std::string json = "{"; ++ const auto& DESCS = g_pConfigManager->getAllDescriptions(); ++ ++ for (const auto& d : DESCS) { ++ json += d.jsonify() + ",\n"; ++ } ++ ++ json.pop_back(); ++ json.pop_back(); ++ ++ json += "}\n"; ++ return json; ++} ++ + CHyprCtl::CHyprCtl() { + registerCommand(SHyprCtlCommand{"workspaces", true, workspacesRequest}); + registerCommand(SHyprCtlCommand{"workspacerules", true, workspaceRulesRequest}); +@@ -1581,6 +1596,7 @@ CHyprCtl::CHyprCtl() { + registerCommand(SHyprCtlCommand{"layouts", true, layoutsRequest}); + registerCommand(SHyprCtlCommand{"configerrors", true, configErrorsRequest}); + registerCommand(SHyprCtlCommand{"locked", true, getIsLocked}); ++ registerCommand(SHyprCtlCommand{"descriptions", true, getDescriptions}); + + registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest}); + registerCommand(SHyprCtlCommand{"reload", false, reloadRequest}); +diff --git a/src/debug/HyprDebugOverlay.cpp b/src/debug/HyprDebugOverlay.cpp +index 889be8ea..fbd8cd71 100644 +--- a/src/debug/HyprDebugOverlay.cpp ++++ b/src/debug/HyprDebugOverlay.cpp +@@ -7,8 +7,8 @@ CHyprDebugOverlay::CHyprDebugOverlay() { + m_pTexture = makeShared(); + } + +-void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) { +- m_dLastRenderTimes.push_back(µs / 1000.f); ++void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) { ++ m_dLastRenderTimes.push_back(durationUs / 1000.f); + + if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate) + m_dLastRenderTimes.pop_front(); +@@ -17,8 +17,8 @@ void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) { + m_pMonitor = pMonitor; + } + +-void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float µs) { +- m_dLastRenderTimesNoOverlay.push_back(µs / 1000.f); ++void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) { ++ m_dLastRenderTimesNoOverlay.push_back(durationUs / 1000.f); + + if (m_dLastRenderTimesNoOverlay.size() > (long unsigned int)pMonitor->refreshRate) + m_dLastRenderTimesNoOverlay.pop_front(); +@@ -188,12 +188,12 @@ int CHyprMonitorDebugOverlay::draw(int offset) { + return posY - offset; + } + +-void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float µs) { +- m_mMonitorOverlays[pMonitor].renderData(pMonitor, µs); ++void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) { ++ m_mMonitorOverlays[pMonitor].renderData(pMonitor, durationUs); + } + +-void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float µs) { +- m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, µs); ++void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) { ++ m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, durationUs); + } + + void CHyprDebugOverlay::frameData(CMonitor* pMonitor) { +diff --git a/src/debug/HyprDebugOverlay.hpp b/src/debug/HyprDebugOverlay.hpp +index a6063ee9..e7742b35 100644 +--- a/src/debug/HyprDebugOverlay.hpp ++++ b/src/debug/HyprDebugOverlay.hpp +@@ -13,8 +13,8 @@ class CHyprMonitorDebugOverlay { + public: + int draw(int offset); + +- void renderData(CMonitor* pMonitor, float µs); +- void renderDataNoOverlay(CMonitor* pMonitor, float µs); ++ void renderData(CMonitor* pMonitor, float durationUs); ++ void renderDataNoOverlay(CMonitor* pMonitor, float durationUs); + void frameData(CMonitor* pMonitor); + + private: +@@ -33,8 +33,8 @@ class CHyprDebugOverlay { + public: + CHyprDebugOverlay(); + void draw(); +- void renderData(CMonitor*, float µs); +- void renderDataNoOverlay(CMonitor*, float µs); ++ void renderData(CMonitor*, float durationUs); ++ void renderDataNoOverlay(CMonitor*, float durationUs); + void frameData(CMonitor*); + + private: +diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp +index 8fd448ef..c352fa74 100644 +--- a/src/desktop/LayerSurface.cpp ++++ b/src/desktop/LayerSurface.cpp +@@ -432,8 +432,8 @@ void CLayerSurface::startAnimation(bool in, bool instant) { + PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x, PMONITOR->vecSize.y / 2}, + }; + +- float closest = std::numeric_limits::max(); +- int leader = force; ++ float closest = std::numeric_limits::max(); ++ size_t leader = force; + if (leader == -1) { + for (size_t i = 0; i < 4; ++i) { + float dist = MIDDLE.distance(edgePoints[i]); +diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp +index 056f66a8..84935b34 100644 +--- a/src/desktop/LayerSurface.hpp ++++ b/src/desktop/LayerSurface.hpp +@@ -42,7 +42,7 @@ class CLayerSurface { + bool mapped = false; + uint32_t layer = 0; + +- int monitorID = -1; ++ MONITORID monitorID = -1; + + bool fadingOut = false; + bool readyToDelete = false; +@@ -51,7 +51,7 @@ class CLayerSurface { + + bool forceBlur = false; + bool forceBlurPopups = false; +- int xray = -1; ++ int64_t xray = -1; + bool ignoreAlpha = false; + float ignoreAlphaValue = 0.f; + bool dimAround = false; +diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp +index 93c208cf..dcdcb573 100644 +--- a/src/desktop/Window.cpp ++++ b/src/desktop/Window.cpp +@@ -1243,7 +1243,7 @@ bool CWindow::isEffectiveInternalFSMode(const eFullscreenMode MODE) { + return (eFullscreenMode)std::bit_floor((uint8_t)m_sFullscreenState.internal) == MODE; + } + +-int CWindow::workspaceID() { ++WORKSPACEID CWindow::workspaceID() { + return m_pWorkspace ? m_pWorkspace->m_iID : m_iLastWorkspace; + } + +diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp +index 11bf662a..2e5b54b1 100644 +--- a/src/desktop/Window.hpp ++++ b/src/desktop/Window.hpp +@@ -270,7 +270,7 @@ class CWindow { + bool m_bDraggingTiled = false; // for dragging around tiled windows + bool m_bWasMaximized = false; + sFullscreenState m_sFullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE}; +- uint64_t m_iMonitorID = -1; ++ MONITORID m_iMonitorID = -1; + std::string m_szTitle = ""; + std::string m_szClass = ""; + std::string m_szInitialTitle = ""; +@@ -358,8 +358,8 @@ class CWindow { + bool m_bStayFocused = false; + + // for toplevel monitor events +- uint64_t m_iLastToplevelMonitorID = -1; +- uint64_t m_iLastSurfaceMonitorID = -1; ++ MONITORID m_iLastToplevelMonitorID = -1; ++ MONITORID m_iLastSurfaceMonitorID = -1; + + // for idle inhibiting windows + eIdleInhibitMode m_eIdleInhibitMode = IDLEINHIBIT_NONE; +@@ -421,7 +421,7 @@ class CWindow { + bool canBeTorn(); + void setSuspended(bool suspend); + bool visibleOnMonitor(CMonitor* pMonitor); +- int workspaceID(); ++ WORKSPACEID workspaceID(); + bool onSpecialWorkspace(); + void activate(bool force = false); + int surfacesCount(); +@@ -490,9 +490,9 @@ class CWindow { + + private: + // For hidden windows and stuff +- bool m_bHidden = false; +- bool m_bSuspended = false; +- int m_iLastWorkspace = WORKSPACE_INVALID; ++ bool m_bHidden = false; ++ bool m_bSuspended = false; ++ WORKSPACEID m_iLastWorkspace = WORKSPACE_INVALID; + }; + + inline bool valid(PHLWINDOW w) { +diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp +index a08f1804..d9ac7927 100644 +--- a/src/desktop/Workspace.cpp ++++ b/src/desktop/Workspace.cpp +@@ -5,13 +5,13 @@ + #include + using namespace Hyprutils::String; + +-PHLWORKSPACE CWorkspace::create(int id, int monitorID, std::string name, bool special, bool isEmtpy) { ++PHLWORKSPACE CWorkspace::create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmtpy) { + PHLWORKSPACE workspace = makeShared(id, monitorID, name, special, isEmtpy); + workspace->init(workspace); + return workspace; + } + +-CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special, bool isEmtpy) { ++CWorkspace::CWorkspace(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmtpy) { + m_iMonitorID = monitorID; + m_iID = id; + m_szName = name; +@@ -190,7 +190,7 @@ void CWorkspace::setActive(bool on) { + ; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40 + } + +-void CWorkspace::moveToMonitor(const int& id) { ++void CWorkspace::moveToMonitor(const MONITORID& id) { + ; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40 + } + +@@ -275,7 +275,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { + i = std::min(NEXTSPACE, std::string::npos - 1); + + if (cur == 'r') { +- int from = 0, to = 0; ++ WORKSPACEID from = 0, to = 0; + if (!prop.starts_with("r[") || !prop.ends_with("]")) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; +@@ -365,7 +365,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { + } + + if (cur == 'w') { +- int from = 0, to = 0; ++ WORKSPACEID from = 0, to = 0; + if (!prop.starts_with("w[") || !prop.ends_with("]")) { + Debug::log(LOG, "Invalid selector {}", selector); + return false; +@@ -446,7 +446,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { + return false; + } + +- int count; ++ WORKSPACEID count; + if (wantsCountGroup) + count = g_pCompositor->getGroupsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled), + wantsCountVisible ? std::optional(wantsCountVisible) : std::nullopt); +@@ -506,7 +506,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { + void CWorkspace::markInert() { + m_bInert = true; + m_iID = WORKSPACE_INVALID; +- m_iMonitorID = -1; ++ m_iMonitorID = MONITOR_INVALID; + m_bVisible = false; + } + +diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp +index 3e9ac8a8..9cacb0cc 100644 +--- a/src/desktop/Workspace.hpp ++++ b/src/desktop/Workspace.hpp +@@ -17,16 +17,16 @@ class CWindow; + + class CWorkspace { + public: +- static PHLWORKSPACE create(int id, int monitorID, std::string name, bool special = false, bool isEmtpy = true); ++ static PHLWORKSPACE create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special = false, bool isEmtpy = true); + // use create() don't use this +- CWorkspace(int id, int monitorID, std::string name, bool special = false, bool isEmpty = true); ++ CWorkspace(WORKSPACEID id, MONITORID monitorID, std::string name, bool special = false, bool isEmpty = true); + ~CWorkspace(); + + // Workspaces ID-based have IDs > 0 + // and workspaces name-based have IDs starting with -1337 +- int m_iID = -1; ++ WORKSPACEID m_iID = WORKSPACE_INVALID; + std::string m_szName = ""; +- uint64_t m_iMonitorID = -1; ++ MONITORID m_iMonitorID = MONITOR_INVALID; + // Previous workspace ID and name is stored during a workspace change, allowing travel + // to the previous workspace. + SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor; +@@ -67,7 +67,7 @@ class CWorkspace { + void startAnim(bool in, bool left, bool instant = false); + void setActive(bool on); + +- void moveToMonitor(const int&); ++ void moveToMonitor(const MONITORID&); + + PHLWINDOW getLastFocusedWindow(); + void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace); +diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp +index 5d29a3b7..2eb7038f 100644 +--- a/src/events/Windows.cpp ++++ b/src/events/Windows.cpp +@@ -148,7 +148,7 @@ void Events::listener_mapWindow(void* owner, void* data) { + PWINDOW->m_iMonitorID = PMONITOR->ID; + } else { + if (isNumber(MONITORSTR)) { +- const long int MONITOR = std::stoi(MONITORSTR); ++ const MONITORID MONITOR = std::stoi(MONITORSTR); + if (!g_pCompositor->getMonitorFromID(MONITOR)) + PWINDOW->m_iMonitorID = 0; + else +diff --git a/src/helpers/Color.cpp b/src/helpers/Color.cpp +index 67526dc7..f9a207bb 100644 +--- a/src/helpers/Color.cpp ++++ b/src/helpers/Color.cpp +@@ -21,6 +21,6 @@ CColor::CColor(uint64_t hex) { + this->a = ALPHA(hex); + } + +-uint32_t CColor::getAsHex() { ++uint32_t CColor::getAsHex() const { + return (uint32_t)(a * 255.f) * 0x1000000 + (uint32_t)(r * 255.f) * 0x10000 + (uint32_t)(g * 255.f) * 0x100 + (uint32_t)(b * 255.f) * 0x1; + } +\ No newline at end of file +diff --git a/src/helpers/Color.hpp b/src/helpers/Color.hpp +index 7ec55b0d..8abfe748 100644 +--- a/src/helpers/Color.hpp ++++ b/src/helpers/Color.hpp +@@ -10,7 +10,7 @@ class CColor { + + float r = 0, g = 0, b = 0, a = 1.f; + +- uint32_t getAsHex(); ++ uint32_t getAsHex() const; + + CColor operator-(const CColor& c2) const { + return CColor(r - c2.r, g - c2.g, b - c2.b, a - c2.a); +diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp +index 53c0dc13..86f24e3a 100644 +--- a/src/helpers/MiscFunctions.cpp ++++ b/src/helpers/MiscFunctions.cpp +@@ -249,7 +249,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + return {WORKSPACE_INVALID}; + } + +- std::set invalidWSes; ++ std::set invalidWSes; + if (same_mon) { + for (auto& rule : g_pConfigManager->getAllWorkspaceRules()) { + const auto PMONITOR = g_pCompositor->getMonitorFromName(rule.monitor); +@@ -258,8 +258,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + } + } + +- int id = next ? g_pCompositor->m_pLastMonitor->activeWorkspaceID() : 0; +- while (++id < INT_MAX) { ++ WORKSPACEID id = next ? g_pCompositor->m_pLastMonitor->activeWorkspaceID() : 0; ++ while (++id < LONG_MAX) { + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id); + if (!invalidWSes.contains(id) && (!PWORKSPACE || g_pCompositor->getWindowsOnWorkspace(id) == 0)) { + result.id = id; +@@ -296,9 +296,9 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + + result.id = (int)PLUSMINUSRESULT.value(); + +- int remains = (int)result.id; ++ WORKSPACEID remains = result.id; + +- std::set invalidWSes; ++ std::set invalidWSes; + + // Collect all the workspaces we can't jump to. + for (auto& ws : g_pCompositor->m_vWorkspaces) { +@@ -318,7 +318,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + } + + // Prepare all named workspaces in case when we need them +- std::vector namedWSes; ++ std::vector namedWSes; + for (auto& ws : g_pCompositor->m_vWorkspaces) { + if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID) || ws->m_iID >= 0) + continue; +@@ -347,18 +347,18 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + } else { + + // Just take a blind guess at where we'll probably end up +- int activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1; +- int predictedWSID = activeWSID + remains; +- int remainingWSes = 0; +- char walkDir = in[1]; ++ WORKSPACEID activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1; ++ WORKSPACEID predictedWSID = activeWSID + remains; ++ int remainingWSes = 0; ++ char walkDir = in[1]; + + // sanitize. 0 means invalid oob in - +- predictedWSID = std::max(predictedWSID, 0); ++ predictedWSID = std::max(predictedWSID, 0L); + + // Count how many invalidWSes are in between (how bad the prediction was) +- int beginID = in[1] == '+' ? activeWSID + 1 : predictedWSID; +- int endID = in[1] == '+' ? predictedWSID : activeWSID; +- auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >= ++ WORKSPACEID beginID = in[1] == '+' ? activeWSID + 1 : predictedWSID; ++ WORKSPACEID endID = in[1] == '+' ? predictedWSID : activeWSID; ++ auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >= + for (auto it = begin; *it <= endID && it != invalidWSes.end(); it++) { + remainingWSes++; + } +@@ -367,7 +367,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + if (activeWSID < 0) { + // Behaviour similar to 'm' + // Find current +- int currentItem = -1; ++ size_t currentItem = -1; + for (size_t i = 0; i < namedWSes.size(); i++) { + if (namedWSes[i] == activeWSID) { + currentItem = i; +@@ -376,14 +376,14 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + } + + currentItem += remains; +- currentItem = std::max(currentItem, 0); +- if (currentItem >= (int)namedWSes.size()) { ++ currentItem = std::max(currentItem, 0UL); ++ if (currentItem >= namedWSes.size()) { + // At the seam between namedWSes and normal WSes. Behave like r+[diff] at imaginary ws 0 +- int diff = currentItem - (namedWSes.size() - 1); +- predictedWSID = diff; +- int beginID = 1; +- int endID = predictedWSID; +- auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >= ++ size_t diff = currentItem - (namedWSes.size() - 1); ++ predictedWSID = diff; ++ WORKSPACEID beginID = 1; ++ WORKSPACEID endID = predictedWSID; ++ auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >= + for (auto it = begin; *it <= endID && it != invalidWSes.end(); it++) { + remainingWSes++; + } +@@ -397,10 +397,10 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + + // Go in the search direction for remainingWSes + // The performance impact is directly proportional to the number of open and bound workspaces +- int finalWSID = predictedWSID; ++ WORKSPACEID finalWSID = predictedWSID; + if (walkDir == '-') { +- int beginID = finalWSID; +- int curID = finalWSID; ++ WORKSPACEID beginID = finalWSID; ++ WORKSPACEID curID = finalWSID; + while (--curID > 0 && remainingWSes > 0) { + if (!invalidWSes.contains(curID)) { + remainingWSes--; +@@ -411,9 +411,9 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + if (namedWSes.size()) { + // Go to the named workspaces + // Need remainingWSes more +- int namedWSIdx = namedWSes.size() - remainingWSes; ++ auto namedWSIdx = namedWSes.size() - remainingWSes; + // Sanitze +- namedWSIdx = std::clamp(namedWSIdx, 0, (int)namedWSes.size() - 1); ++ namedWSIdx = std::clamp(namedWSIdx, 0UL, namedWSes.size() - 1); + finalWSID = namedWSes[namedWSIdx]; + } else { + // Couldn't find valid workspace in negative direction, search last first one back up positive direction +@@ -425,7 +425,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + } + } + if (walkDir == '+') { +- int curID = finalWSID; ++ WORKSPACEID curID = finalWSID; + while (++curID < INT32_MAX && remainingWSes > 0) { + if (!invalidWSes.contains(curID)) { + remainingWSes--; +@@ -460,9 +460,9 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + result.id = (int)PLUSMINUSRESULT.value(); + + // result now has +/- what we should move on mon +- int remains = (int)result.id; ++ int remains = (int)result.id; + +- std::vector validWSes; ++ std::vector validWSes; + for (auto& ws : g_pCompositor->m_vWorkspaces) { + if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID && !onAllMonitors)) + continue; +@@ -472,7 +472,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + + std::sort(validWSes.begin(), validWSes.end()); + +- int currentItem = -1; ++ ssize_t currentItem = -1; + + if (absolute) { + // 1-index +@@ -481,7 +481,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + // clamp + if (currentItem < 0) { + currentItem = 0; +- } else if (currentItem >= (int)validWSes.size()) { ++ } else if (currentItem >= (ssize_t)validWSes.size()) { + currentItem = validWSes.size() - 1; + } + } else { +@@ -489,8 +489,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + remains = remains < 0 ? -((-remains) % validWSes.size()) : remains % validWSes.size(); + + // get the current item +- int activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1; +- for (size_t i = 0; i < validWSes.size(); i++) { ++ WORKSPACEID activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1; ++ for (ssize_t i = 0; i < (ssize_t)validWSes.size(); i++) { + if (validWSes[i] == activeWSID) { + currentItem = i; + break; +@@ -501,7 +501,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { + currentItem += remains; + + // sanitize +- if (currentItem >= (int)validWSes.size()) { ++ if (currentItem >= (ssize_t)validWSes.size()) { + currentItem = currentItem % validWSes.size(); + } else if (currentItem < 0) { + currentItem = validWSes.size() + currentItem; +@@ -547,9 +547,9 @@ std::optional cleanCmdForWorkspace(const std::string& inWorkspaceNa + const std::string workspaceRule = "workspace " + inWorkspaceName; + + if (cmd[0] == '[') { +- const int closingBracketIdx = cmd.find_last_of(']'); +- auto tmpRules = cmd.substr(1, closingBracketIdx - 1); +- cmd = cmd.substr(closingBracketIdx + 1); ++ const auto closingBracketIdx = cmd.find_last_of(']'); ++ auto tmpRules = cmd.substr(1, closingBracketIdx - 1); ++ cmd = cmd.substr(closingBracketIdx + 1); + + auto rulesList = CVarList(tmpRules, 0, ';'); + +@@ -785,13 +785,13 @@ std::vector getBacktrace() { + + #ifdef HAS_EXECINFO + void* bt[1024]; +- size_t btSize; ++ int btSize; + char** btSymbols; + + btSize = backtrace(bt, 1024); + btSymbols = backtrace_symbols(bt, btSize); + +- for (size_t i = 0; i < btSize; ++i) { ++ for (auto i = 0; i < btSize; ++i) { + callstack.emplace_back(SCallstackFrameInfo{bt[i], std::string{btSymbols[i]}}); + } + #else +diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp +index 49e3bced..8b2ea0d1 100644 +--- a/src/helpers/MiscFunctions.hpp ++++ b/src/helpers/MiscFunctions.hpp +@@ -6,6 +6,8 @@ + #include "math/Math.hpp" + #include + #include ++#include "../SharedDefs.hpp" ++#include "../macros.hpp" + + struct SCallstackFrameInfo { + void* adr = nullptr; +@@ -13,7 +15,7 @@ struct SCallstackFrameInfo { + }; + + struct SWorkspaceIDName { +- int id = -1; ++ WORKSPACEID id = WORKSPACE_INVALID; + std::string name; + }; + +diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp +index 8f23c462..9542d2c4 100644 +--- a/src/helpers/Monitor.cpp ++++ b/src/helpers/Monitor.cpp +@@ -389,8 +389,8 @@ bool CMonitor::matchesStaticSelector(const std::string& selector) const { + } + } + +-int CMonitor::findAvailableDefaultWS() { +- for (size_t i = 1; i < INT32_MAX; ++i) { ++WORKSPACEID CMonitor::findAvailableDefaultWS() { ++ for (WORKSPACEID i = 1; i < LONG_MAX; ++i) { + if (g_pCompositor->getWorkspaceByID(i)) + continue; + +@@ -400,7 +400,7 @@ int CMonitor::findAvailableDefaultWS() { + return i; + } + +- return INT32_MAX; // shouldn't be reachable ++ return LONG_MAX; // shouldn't be reachable + } + + void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) { +@@ -638,7 +638,7 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo + g_pCompositor->updateFullscreenFadeOnWorkspace(activeSpecialWorkspace); + } + +-void CMonitor::changeWorkspace(const int& id, bool internal, bool noMouseMove, bool noFocus) { ++void CMonitor::changeWorkspace(const WORKSPACEID& id, bool internal, bool noMouseMove, bool noFocus) { + changeWorkspace(g_pCompositor->getWorkspaceByID(id), internal, noMouseMove, noFocus); + } + +@@ -745,7 +745,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { + g_pCompositor->updateSuspendedStates(); + } + +-void CMonitor::setSpecialWorkspace(const int& id) { ++void CMonitor::setSpecialWorkspace(const WORKSPACEID& id) { + setSpecialWorkspace(g_pCompositor->getWorkspaceByID(id)); + } + +@@ -766,11 +766,11 @@ void CMonitor::updateMatrix() { + } + } + +-int64_t CMonitor::activeWorkspaceID() { ++WORKSPACEID CMonitor::activeWorkspaceID() { + return activeWorkspace ? activeWorkspace->m_iID : 0; + } + +-int64_t CMonitor::activeSpecialWorkspaceID() { ++WORKSPACEID CMonitor::activeSpecialWorkspaceID() { + return activeSpecialWorkspace ? activeSpecialWorkspace->m_iID : 0; + } + +@@ -946,7 +946,7 @@ bool CMonitorState::updateSwapchain() { + Debug::log(WARN, "updateSwapchain: No mode?"); + return true; + } +- options.format = STATE.drmFormat; ++ options.format = m_pOwner->drmFormat; + options.scanout = true; + options.length = 2; + options.size = MODE->pixelSize; +diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp +index fbe26f67..dcfcb63b 100644 +--- a/src/helpers/Monitor.hpp ++++ b/src/helpers/Monitor.hpp +@@ -70,7 +70,7 @@ class CMonitor { + + bool primary = false; + +- uint64_t ID = -1; ++ MONITORID ID = MONITOR_INVALID; + PHLWORKSPACE activeWorkspace = nullptr; + PHLWORKSPACE activeSpecialWorkspace = nullptr; + float setScale = 1; // scale set by cfg +@@ -100,6 +100,7 @@ class CMonitor { + std::optional forceSize; + SP currentMode; + SP cursorSwapchain; ++ uint32_t drmFormat = DRM_FORMAT_INVALID; + + bool dpmsStatus = true; + bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it. +@@ -155,31 +156,31 @@ class CMonitor { + std::array, 4> m_aLayerSurfaceLayers; + + // methods +- void onConnect(bool noRule); +- void onDisconnect(bool destroy = false); +- void addDamage(const pixman_region32_t* rg); +- void addDamage(const CRegion* rg); +- void addDamage(const CBox* box); +- bool shouldSkipScheduleFrameOnMouseEvent(); +- void setMirror(const std::string&); +- bool isMirror(); +- bool matchesStaticSelector(const std::string& selector) const; +- float getDefaultScale(); +- void changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false); +- void changeWorkspace(const int& id, bool internal = false, bool noMouseMove = false, bool noFocus = false); +- void setSpecialWorkspace(const PHLWORKSPACE& pWorkspace); +- void setSpecialWorkspace(const int& id); +- void moveTo(const Vector2D& pos); +- Vector2D middle(); +- void updateMatrix(); +- int64_t activeWorkspaceID(); +- int64_t activeSpecialWorkspaceID(); +- CBox logicalBox(); +- void scheduleDone(); +- bool attemptDirectScanout(); +- +- bool m_bEnabled = false; +- bool m_bRenderingInitPassed = false; ++ void onConnect(bool noRule); ++ void onDisconnect(bool destroy = false); ++ void addDamage(const pixman_region32_t* rg); ++ void addDamage(const CRegion* rg); ++ void addDamage(const CBox* box); ++ bool shouldSkipScheduleFrameOnMouseEvent(); ++ void setMirror(const std::string&); ++ bool isMirror(); ++ bool matchesStaticSelector(const std::string& selector) const; ++ float getDefaultScale(); ++ void changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false); ++ void changeWorkspace(const WORKSPACEID& id, bool internal = false, bool noMouseMove = false, bool noFocus = false); ++ void setSpecialWorkspace(const PHLWORKSPACE& pWorkspace); ++ void setSpecialWorkspace(const WORKSPACEID& id); ++ void moveTo(const Vector2D& pos); ++ Vector2D middle(); ++ void updateMatrix(); ++ WORKSPACEID activeWorkspaceID(); ++ WORKSPACEID activeSpecialWorkspaceID(); ++ CBox logicalBox(); ++ void scheduleDone(); ++ bool attemptDirectScanout(); ++ ++ bool m_bEnabled = false; ++ bool m_bRenderingInitPassed = false; + + // For the list lookup + +@@ -189,7 +190,7 @@ class CMonitor { + + private: + void setupDefaultWS(const SMonitorRule&); +- int findAvailableDefaultWS(); ++ WORKSPACEID findAvailableDefaultWS(); + + wl_event_source* doneSource = nullptr; + +diff --git a/src/helpers/SdDaemon.cpp b/src/helpers/SdDaemon.cpp +index 25e0ca3b..48c23e6b 100644 +--- a/src/helpers/SdDaemon.cpp ++++ b/src/helpers/SdDaemon.cpp +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + namespace Systemd { + int SdBooted(void) { +diff --git a/src/helpers/Timer.cpp b/src/helpers/Timer.cpp +index ec530df4..7b1726df 100644 +--- a/src/helpers/Timer.cpp ++++ b/src/helpers/Timer.cpp +@@ -8,7 +8,7 @@ std::chrono::steady_clock::duration CTimer::getDuration() { + return std::chrono::steady_clock::now() - m_tpLastReset; + } + +-int CTimer::getMillis() { ++long CTimer::getMillis() { + return std::chrono::duration_cast(getDuration()).count(); + } + +diff --git a/src/helpers/Timer.hpp b/src/helpers/Timer.hpp +index a6d1aeed..827e7625 100644 +--- a/src/helpers/Timer.hpp ++++ b/src/helpers/Timer.hpp +@@ -6,7 +6,7 @@ class CTimer { + public: + void reset(); + float getSeconds(); +- int getMillis(); ++ long getMillis(); + const std::chrono::steady_clock::time_point& chrono() const; + + private: +diff --git a/src/helpers/Watchdog.cpp b/src/helpers/Watchdog.cpp +index b9f654da..c7ff648b 100644 +--- a/src/helpers/Watchdog.cpp ++++ b/src/helpers/Watchdog.cpp +@@ -18,15 +18,14 @@ CWatchdog::CWatchdog() { + m_pWatchdog = std::make_unique([this] { + static auto PTIMEOUT = CConfigValue("debug:watchdog_timeout"); + +- while (1337) { +- std::unique_lock lk(m_mWatchdogMutex); ++ m_bWatchdogInitialized = true; ++ while (!m_bExitThread) { ++ std::unique_lock lk(m_mWatchdogMutex); + + if (!m_bWillWatch) +- m_cvWatchdogCondition.wait(lk, [this] { return m_bNotified; }); +- else { +- if (m_cvWatchdogCondition.wait_for(lk, std::chrono::milliseconds((int)(*PTIMEOUT * 1000.0)), [this] { return m_bNotified; }) == false) +- pthread_kill(m_iMainThreadPID, SIGUSR1); +- } ++ m_cvWatchdogCondition.wait(lk, [this] { return m_bNotified || m_bExitThread; }); ++ else if (m_cvWatchdogCondition.wait_for(lk, std::chrono::milliseconds((int)(*PTIMEOUT * 1000.0)), [this] { return m_bNotified || m_bExitThread; }) == false) ++ pthread_kill(m_iMainThreadPID, SIGUSR1); + + if (m_bExitThread) + break; +diff --git a/src/helpers/Watchdog.hpp b/src/helpers/Watchdog.hpp +index 7bb499d6..b16cb518 100644 +--- a/src/helpers/Watchdog.hpp ++++ b/src/helpers/Watchdog.hpp +@@ -11,21 +11,23 @@ class CWatchdog { + CWatchdog(); + ~CWatchdog(); + +- void startWatching(); +- void endWatching(); ++ void startWatching(); ++ void endWatching(); ++ ++ std::atomic m_bWatchdogInitialized{false}; + + private: + std::chrono::high_resolution_clock::time_point m_tTriggered; + + pthread_t m_iMainThreadPID = 0; + +- bool m_bWatching = false; +- bool m_bWillWatch = false; ++ std::atomic m_bWatching = false; ++ std::atomic m_bWillWatch = false; + + std::unique_ptr m_pWatchdog; + std::mutex m_mWatchdogMutex; +- bool m_bNotified = false; +- bool m_bExitThread = false; ++ std::atomic m_bNotified = false; ++ std::atomic m_bExitThread = false; + std::condition_variable m_cvWatchdogCondition; + }; + +diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp +index f287056f..20085ff7 100644 +--- a/src/layout/DwindleLayout.cpp ++++ b/src/layout/DwindleLayout.cpp +@@ -47,7 +47,7 @@ void SDwindleNodeData::getAllChildrenRecursive(std::deque* pD + } + } + +-int CHyprDwindleLayout::getNodesOnWorkspace(const int& id) { ++int CHyprDwindleLayout::getNodesOnWorkspace(const WORKSPACEID& id) { + int no = 0; + for (auto& n : m_lDwindleNodesData) { + if (n.workspaceID == id && n.valid) +@@ -56,7 +56,7 @@ int CHyprDwindleLayout::getNodesOnWorkspace(const int& id) { + return no; + } + +-SDwindleNodeData* CHyprDwindleLayout::getFirstNodeOnWorkspace(const int& id) { ++SDwindleNodeData* CHyprDwindleLayout::getFirstNodeOnWorkspace(const WORKSPACEID& id) { + for (auto& n : m_lDwindleNodesData) { + if (n.workspaceID == id && validMapped(n.pWindow)) + return &n; +@@ -64,7 +64,7 @@ SDwindleNodeData* CHyprDwindleLayout::getFirstNodeOnWorkspace(const int& id) { + return nullptr; + } + +-SDwindleNodeData* CHyprDwindleLayout::getClosestNodeOnWorkspace(const int& id, const Vector2D& point) { ++SDwindleNodeData* CHyprDwindleLayout::getClosestNodeOnWorkspace(const WORKSPACEID& id, const Vector2D& point) { + SDwindleNodeData* res = nullptr; + double distClosest = -1; + for (auto& n : m_lDwindleNodesData) { +@@ -88,7 +88,7 @@ SDwindleNodeData* CHyprDwindleLayout::getNodeFromWindow(PHLWINDOW pWindow) { + return nullptr; + } + +-SDwindleNodeData* CHyprDwindleLayout::getMasterNodeOnWorkspace(const int& id) { ++SDwindleNodeData* CHyprDwindleLayout::getMasterNodeOnWorkspace(const WORKSPACEID& id) { + for (auto& n : m_lDwindleNodesData) { + if (!n.pParent && n.workspaceID == id) + return &n; +@@ -246,6 +246,8 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for + + g_pHyprRenderer->damageWindow(PWINDOW); + } ++ ++ PWINDOW->updateWindowDecos(); + } + + void CHyprDwindleLayout::onWindowCreatedTiling(PHLWINDOW pWindow, eDirection direction) { +@@ -535,7 +537,7 @@ void CHyprDwindleLayout::onWindowRemovedTiling(PHLWINDOW pWindow) { + m_lDwindleNodesData.remove(*PNODE); + } + +-void CHyprDwindleLayout::recalculateMonitor(const int& monid) { ++void CHyprDwindleLayout::recalculateMonitor(const MONITORID& monid) { + const auto PMONITOR = g_pCompositor->getMonitorFromID(monid); + + if (!PMONITOR || !PMONITOR->activeWorkspace) +@@ -872,7 +874,7 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir, + return; + + const auto PNODE = getNodeFromWindow(pWindow); +- const int originalWorkspaceID = pWindow->workspaceID(); ++ const auto originalWorkspaceID = pWindow->workspaceID(); + const Vector2D originalPos = pWindow->middle(); + + if (!PNODE) +diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp +index f638f6a2..bbd511c2 100644 +--- a/src/layout/DwindleLayout.hpp ++++ b/src/layout/DwindleLayout.hpp +@@ -24,7 +24,7 @@ struct SDwindleNodeData { + + CBox box = {0}; + +- int workspaceID = -1; ++ WORKSPACEID workspaceID = WORKSPACE_INVALID; + + float splitRatio = 1.f; + +@@ -48,7 +48,7 @@ class CHyprDwindleLayout : public IHyprLayout { + virtual void onWindowCreatedTiling(PHLWINDOW, eDirection direction = DIRECTION_DEFAULT); + virtual void onWindowRemovedTiling(PHLWINDOW); + virtual bool isWindowTiled(PHLWINDOW); +- virtual void recalculateMonitor(const int&); ++ virtual void recalculateMonitor(const MONITORID&); + virtual void recalculateWindow(PHLWINDOW); + virtual void onBeginDragWindow(); + virtual void resizeActiveWindow(const Vector2D&, eRectCorner corner = CORNER_NONE, PHLWINDOW pWindow = nullptr); +@@ -77,13 +77,13 @@ class CHyprDwindleLayout : public IHyprLayout { + + std::optional m_vOverrideFocalPoint; // for onWindowCreatedTiling. + +- int getNodesOnWorkspace(const int&); ++ int getNodesOnWorkspace(const WORKSPACEID&); + void applyNodeDataToWindow(SDwindleNodeData*, bool force = false); + void calculateWorkspace(const PHLWORKSPACE& pWorkspace); + SDwindleNodeData* getNodeFromWindow(PHLWINDOW); +- SDwindleNodeData* getFirstNodeOnWorkspace(const int&); +- SDwindleNodeData* getClosestNodeOnWorkspace(const int&, const Vector2D&); +- SDwindleNodeData* getMasterNodeOnWorkspace(const int&); ++ SDwindleNodeData* getFirstNodeOnWorkspace(const WORKSPACEID&); ++ SDwindleNodeData* getClosestNodeOnWorkspace(const WORKSPACEID&, const Vector2D&); ++ SDwindleNodeData* getMasterNodeOnWorkspace(const WORKSPACEID&); + + void toggleSplit(PHLWINDOW); + void swapSplit(PHLWINDOW); +diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp +index 4b1b59e3..7e0d5704 100644 +--- a/src/layout/IHyprLayout.hpp ++++ b/src/layout/IHyprLayout.hpp +@@ -63,7 +63,7 @@ class IHyprLayout { + Called when the monitor requires a layout recalculation + this usually means reserved area changes + */ +- virtual void recalculateMonitor(const int&) = 0; ++ virtual void recalculateMonitor(const MONITORID&) = 0; + + /* + Called when the compositor requests a window +diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp +index be00168f..e0b48e98 100644 +--- a/src/layout/MasterLayout.cpp ++++ b/src/layout/MasterLayout.cpp +@@ -14,7 +14,7 @@ SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(PHLWINDOW pWindow) { + return nullptr; + } + +-int CHyprMasterLayout::getNodesOnWorkspace(const int& ws) { ++int CHyprMasterLayout::getNodesOnWorkspace(const WORKSPACEID& ws) { + int no = 0; + for (auto& n : m_lMasterNodesData) { + if (n.workspaceID == ws) +@@ -24,7 +24,7 @@ int CHyprMasterLayout::getNodesOnWorkspace(const int& ws) { + return no; + } + +-int CHyprMasterLayout::getMastersOnWorkspace(const int& ws) { ++int CHyprMasterLayout::getMastersOnWorkspace(const WORKSPACEID& ws) { + int no = 0; + for (auto& n : m_lMasterNodesData) { + if (n.workspaceID == ws && n.isMaster) +@@ -34,7 +34,7 @@ int CHyprMasterLayout::getMastersOnWorkspace(const int& ws) { + return no; + } + +-SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const int& ws) { ++SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const WORKSPACEID& ws) { + for (auto& n : m_lMasterWorkspacesData) { + if (n.workspaceID == ws) + return &n; +@@ -63,7 +63,7 @@ std::string CHyprMasterLayout::getLayoutName() { + return "Master"; + } + +-SMasterNodeData* CHyprMasterLayout::getMasterNodeOnWorkspace(const int& ws) { ++SMasterNodeData* CHyprMasterLayout::getMasterNodeOnWorkspace(const WORKSPACEID& ws) { + for (auto& n : m_lMasterNodesData) { + if (n.isMaster && n.workspaceID == ws) + return &n; +@@ -304,7 +304,7 @@ void CHyprMasterLayout::onWindowRemovedTiling(PHLWINDOW pWindow) { + recalculateMonitor(pWindow->m_iMonitorID); + } + +-void CHyprMasterLayout::recalculateMonitor(const int& monid) { ++void CHyprMasterLayout::recalculateMonitor(const MONITORID& monid) { + const auto PMONITOR = g_pCompositor->getMonitorFromID(monid); + + if (!PMONITOR || !PMONITOR->activeWorkspace) +@@ -732,6 +732,8 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { + + g_pHyprRenderer->damageWindow(PWINDOW); + } ++ ++ PWINDOW->updateWindowDecos(); + } + + bool CHyprMasterLayout::isWindowTiled(PHLWINDOW pWindow) { +diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp +index fdb916e5..b72be74f 100644 +--- a/src/layout/MasterLayout.hpp ++++ b/src/layout/MasterLayout.hpp +@@ -30,7 +30,7 @@ struct SMasterNodeData { + + float percSize = 1.f; // size multiplier for resizing children + +- int workspaceID = -1; ++ WORKSPACEID workspaceID = WORKSPACE_INVALID; + + bool ignoreFullscreenChecks = false; + +@@ -41,7 +41,7 @@ struct SMasterNodeData { + }; + + struct SMasterWorkspaceData { +- int workspaceID = -1; ++ WORKSPACEID workspaceID = WORKSPACE_INVALID; + eOrientation orientation = ORIENTATION_LEFT; + + // +@@ -55,7 +55,7 @@ class CHyprMasterLayout : public IHyprLayout { + virtual void onWindowCreatedTiling(PHLWINDOW, eDirection direction = DIRECTION_DEFAULT); + virtual void onWindowRemovedTiling(PHLWINDOW); + virtual bool isWindowTiled(PHLWINDOW); +- virtual void recalculateMonitor(const int&); ++ virtual void recalculateMonitor(const MONITORID&); + virtual void recalculateWindow(PHLWINDOW); + virtual void resizeActiveWindow(const Vector2D&, eRectCorner corner = CORNER_NONE, PHLWINDOW pWindow = nullptr); + virtual void fullscreenRequestForWindow(PHLWINDOW pWindow, const eFullscreenMode CURRENT_EFFECTIVE_MODE, const eFullscreenMode EFFECTIVE_MODE); +@@ -81,14 +81,14 @@ class CHyprMasterLayout : public IHyprLayout { + void buildOrientationCycleVectorFromEOperation(std::vector& cycle); + void runOrientationCycle(SLayoutMessageHeader& header, CVarList* vars, int next); + eOrientation getDynamicOrientation(PHLWORKSPACE); +- int getNodesOnWorkspace(const int&); ++ int getNodesOnWorkspace(const WORKSPACEID&); + void applyNodeDataToWindow(SMasterNodeData*); + SMasterNodeData* getNodeFromWindow(PHLWINDOW); +- SMasterNodeData* getMasterNodeOnWorkspace(const int&); +- SMasterWorkspaceData* getMasterWorkspaceData(const int&); ++ SMasterNodeData* getMasterNodeOnWorkspace(const WORKSPACEID&); ++ SMasterWorkspaceData* getMasterWorkspaceData(const WORKSPACEID&); + void calculateWorkspace(PHLWORKSPACE); + PHLWINDOW getNextWindow(PHLWINDOW, bool); +- int getMastersOnWorkspace(const int&); ++ int getMastersOnWorkspace(const WORKSPACEID&); + + friend struct SMasterNodeData; + friend struct SMasterWorkspaceData; +diff --git a/src/macros.hpp b/src/macros.hpp +index b2adb036..44014085 100644 +--- a/src/macros.hpp ++++ b/src/macros.hpp +@@ -27,6 +27,8 @@ + #define WORKSPACE_INVALID -1L + #define WORKSPACE_NOT_CHANGED -101 + ++#define MONITOR_INVALID -1L ++ + #define LISTENER(name) \ + void listener_##name(wl_listener*, void*); \ + inline wl_listener listen_##name = {.notify = listener_##name} +diff --git a/src/main.cpp b/src/main.cpp +index e85b0a22..820a248c 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -36,7 +36,6 @@ int main(int argc, char** argv) { + setenv("XDG_BACKEND", "wayland", 1); + setenv("_JAVA_AWT_WM_NONREPARENTING", "1", 1); + setenv("MOZ_ENABLE_WAYLAND", "1", 1); +- setenv("XDG_CURRENT_DESKTOP", "Hyprland", 1); + + // parse some args + std::string configPath; +diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp +index 3f3a25f6..1c047f85 100644 +--- a/src/managers/CursorManager.cpp ++++ b/src/managers/CursorManager.cpp +@@ -102,7 +102,7 @@ CCursorManager::CCursorManager() { + + // since we fallback to xcursor always load it on startup. otherwise we end up with a empty theme if hyprcursor is enabled in the config + // and then later is disabled. +- m_pXcursor->loadTheme(getenv("XCURSOR_THEME") ? getenv("XCURSOR_THEME") : "default", m_iSize * std::ceil(m_fCursorScale)); ++ m_pXcursor->loadTheme(getenv("XCURSOR_THEME") ? getenv("XCURSOR_THEME") : "default", m_iSize, m_fCursorScale); + + m_pAnimationTimer = makeShared(std::nullopt, cursorAnimTimer, this); + g_pEventLoopManager->addTimer(m_pAnimationTimer); +@@ -163,7 +163,7 @@ void CCursorManager::setCursorFromName(const std::string& name) { + auto setXCursor = [this](auto const& name) { + float scale = std::ceil(m_fCursorScale); + +- auto xcursor = m_pXcursor->getShape(name, m_iSize * scale); ++ auto xcursor = m_pXcursor->getShape(name, m_iSize, m_fCursorScale); + auto& icon = xcursor->images.front(); + auto buf = makeShared((uint8_t*)icon.pixels.data(), icon.size, icon.hotspot); + setCursorBuffer(buf, icon.hotspot / scale, scale); +@@ -277,7 +277,7 @@ void CCursorManager::setXWaylandCursor() { + g_pXWayland->setCursor(cairo_image_surface_get_data(CURSOR.surface), cairo_image_surface_get_stride(CURSOR.surface), {CURSOR.size, CURSOR.size}, + {CURSOR.hotspotX, CURSOR.hotspotY}); + else { +- auto xcursor = m_pXcursor->getShape("left_ptr", m_iSize * std::ceil(m_fCursorScale)); ++ auto xcursor = m_pXcursor->getShape("left_ptr", m_iSize, 1); + auto& icon = xcursor->images.front(); + + g_pXWayland->setCursor((uint8_t*)icon.pixels.data(), icon.size.x * 4, icon.size, icon.hotspot); +@@ -329,12 +329,16 @@ bool CCursorManager::changeTheme(const std::string& name, const int size) { + m_pHyprcursor = std::make_unique(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), options); + if (!m_pHyprcursor->valid()) { + Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to XCursor.", m_szTheme); +- m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize); ++ m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize, m_fCursorScale); + } + } else +- m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize); ++ m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize, m_fCursorScale); + + updateTheme(); + + return true; +-} +\ No newline at end of file ++} ++ ++void CCursorManager::syncGsettings() { ++ m_pXcursor->syncGsettings(); ++} +diff --git a/src/managers/CursorManager.hpp b/src/managers/CursorManager.hpp +index ceb4816b..796ab10e 100644 +--- a/src/managers/CursorManager.hpp ++++ b/src/managers/CursorManager.hpp +@@ -53,6 +53,7 @@ class CCursorManager { + void updateTheme(); + SCursorImageData dataFor(const std::string& name); // for xwayland + void setXWaylandCursor(); ++ void syncGsettings(); + + void tickAnimatedCursor(); + +@@ -75,4 +76,4 @@ class CCursorManager { + Hyprcursor::SCursorShapeData m_sCurrentCursorShapeData; + }; + +-inline std::unique_ptr g_pCursorManager; +\ No newline at end of file ++inline std::unique_ptr g_pCursorManager; +diff --git a/src/managers/EventManager.cpp b/src/managers/EventManager.cpp +index 75c98e2a..079a6b68 100644 +--- a/src/managers/EventManager.cpp ++++ b/src/managers/EventManager.cpp +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + CEventManager::CEventManager() { + m_iSocketFD = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); +diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp +index c7b93730..38593497 100644 +--- a/src/managers/KeybindManager.cpp ++++ b/src/managers/KeybindManager.cpp +@@ -180,6 +180,9 @@ uint32_t CKeybindManager::stringToModMask(std::string mods) { + } + + uint32_t CKeybindManager::keycodeToModifier(xkb_keycode_t keycode) { ++ if (keycode == 0) ++ return 0; ++ + switch (keycode - 8) { + case KEY_LEFTMETA: return HL_MODIFIER_META; + case KEY_RIGHTMETA: return HL_MODIFIER_META; +@@ -1163,6 +1166,8 @@ void CKeybindManager::fullscreenStateActive(std::string args) { + if (!PWINDOW) + return; + ++ PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(false, PRIORITY_SET_PROP); ++ + int internalMode, clientMode; + try { + internalMode = std::stoi(ARGS[0]); +@@ -1174,26 +1179,16 @@ void CKeybindManager::fullscreenStateActive(std::string args) { + const sFullscreenState STATE = sFullscreenState{.internal = (internalMode != -1 ? (eFullscreenMode)internalMode : PWINDOW->m_sFullscreenState.internal), + .client = (clientMode != -1 ? (eFullscreenMode)clientMode : PWINDOW->m_sFullscreenState.client)}; + +- if (internalMode != -1 && clientMode != -1 && PWINDOW->m_sFullscreenState.internal == STATE.internal && PWINDOW->m_sFullscreenState.client == STATE.client) { ++ if (internalMode != -1 && clientMode != -1 && PWINDOW->m_sFullscreenState.internal == STATE.internal && PWINDOW->m_sFullscreenState.client == STATE.client) + g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = FSMODE_NONE, .client = FSMODE_NONE}); +- PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(true, PRIORITY_SET_PROP); +- return; +- } +- +- if (internalMode != -1 && clientMode == -1 && PWINDOW->m_sFullscreenState.internal == STATE.internal) { +- g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = PWINDOW->m_sFullscreenState.client, .client = PWINDOW->m_sFullscreenState.client}); +- PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(true, PRIORITY_SET_PROP); +- return; +- } +- +- if (internalMode == -1 && clientMode != -1 && PWINDOW->m_sFullscreenState.client == STATE.client) { +- g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = PWINDOW->m_sFullscreenState.internal, .client = PWINDOW->m_sFullscreenState.internal}); +- PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(true, PRIORITY_SET_PROP); +- return; +- } ++ else if (internalMode != -1 && clientMode == -1 && PWINDOW->m_sFullscreenState.internal == STATE.internal) ++ g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = FSMODE_NONE, .client = PWINDOW->m_sFullscreenState.client}); ++ else if (internalMode == -1 && clientMode != -1 && PWINDOW->m_sFullscreenState.client == STATE.client) ++ g_pCompositor->setWindowFullscreenState(PWINDOW, sFullscreenState{.internal = PWINDOW->m_sFullscreenState.internal, .client = FSMODE_NONE}); ++ else ++ g_pCompositor->setWindowFullscreenState(PWINDOW, STATE); + +- PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(false, PRIORITY_SET_PROP); +- g_pCompositor->setWindowFullscreenState(PWINDOW, STATE); ++ PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(PWINDOW->m_sFullscreenState.internal == PWINDOW->m_sFullscreenState.client, PRIORITY_SET_PROP); + } + + void CKeybindManager::moveActiveToWorkspace(std::string args) { +@@ -1738,7 +1733,7 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) { + return; + } + +- const int WORKSPACEID = getWorkspaceIDNameFromString(workspace).id; ++ const auto WORKSPACEID = getWorkspaceIDNameFromString(workspace).id; + + if (WORKSPACEID == WORKSPACE_INVALID) { + Debug::log(ERR, "moveWorkspaceToMonitor invalid workspace!"); +@@ -1756,7 +1751,7 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) { + } + + void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) { +- int workspaceID = getWorkspaceIDNameFromString(args).id; ++ auto workspaceID = getWorkspaceIDNameFromString(args).id; + if (workspaceID == WORKSPACE_INVALID) { + Debug::log(ERR, "focusWorkspaceOnCurrentMonitor invalid workspace!"); + return; +@@ -1816,7 +1811,7 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) { + + bool requestedWorkspaceIsAlreadyOpen = false; + const auto PMONITOR = g_pCompositor->m_pLastMonitor; +- int specialOpenOnMonitor = PMONITOR->activeSpecialWorkspaceID(); ++ auto specialOpenOnMonitor = PMONITOR->activeSpecialWorkspaceID(); + + for (auto& m : g_pCompositor->m_vMonitors) { + if (m->activeSpecialWorkspaceID() == workspaceID) { +diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp +index 3ba34c11..72ff5ae7 100644 +--- a/src/managers/PointerManager.cpp ++++ b/src/managers/PointerManager.cpp +@@ -11,13 +11,21 @@ + #include + + CPointerManager::CPointerManager() { +- hooks.monitorAdded = g_pHookSystem->hookDynamic("newMonitor", [this](void* self, SCallbackInfo& info, std::any data) { +- auto PMONITOR = std::any_cast>(data); ++ hooks.monitorAdded = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any data) { ++ auto PMONITOR = std::any_cast(data)->self.lock(); + + onMonitorLayoutChange(); + +- PMONITOR->events.modeChanged.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr); +- PMONITOR->events.disconnect.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr); ++ PMONITOR->events.modeChanged.registerStaticListener( ++ [this, PMONITOR](void* owner, std::any data) { ++ g_pEventLoopManager->doLater([this, PMONITOR]() { ++ onMonitorLayoutChange(); ++ checkDefaultCursorWarp(PMONITOR, PMONITOR->output->name); ++ }); ++ }, ++ nullptr); ++ PMONITOR->events.disconnect.registerStaticListener( ++ [this, PMONITOR](void* owner, std::any data) { g_pEventLoopManager->doLater([this, PMONITOR]() { onMonitorLayoutChange(); }); }, nullptr); + PMONITOR->events.destroy.registerStaticListener( + [this](void* owner, std::any data) { + if (g_pCompositor && !g_pCompositor->m_bIsShuttingDown) +@@ -35,6 +43,38 @@ CPointerManager::CPointerManager() { + }); + } + ++void CPointerManager::checkDefaultCursorWarp(SP monitor, std::string monitorName) { ++ static auto PCURSORMONITOR = CConfigValue("cursor:default_monitor"); ++ static bool cursorDefaultDone = false; ++ static bool firstLaunch = true; ++ ++ const auto POS = monitor->middle(); ++ ++ // by default, cursor should be set to first monitor detected ++ // this is needed as a default if the monitor given in config above doesn't exist ++ if (firstLaunch) { ++ firstLaunch = false; ++ g_pCompositor->warpCursorTo(POS, true); ++ g_pInputManager->refocus(); ++ return; ++ } ++ ++ if (!cursorDefaultDone && *PCURSORMONITOR != STRVAL_EMPTY) { ++ if (*PCURSORMONITOR == monitorName) { ++ cursorDefaultDone = true; ++ g_pCompositor->warpCursorTo(POS, true); ++ g_pInputManager->refocus(); ++ return; ++ } ++ } ++ ++ // modechange happend check if cursor is on that monitor and warp it to middle to not place it out of bounds if resolution changed. ++ if (g_pCompositor->getMonitorFromCursor() == monitor.get()) { ++ g_pCompositor->warpCursorTo(POS, true); ++ g_pInputManager->refocus(); ++ } ++} ++ + void CPointerManager::lockSoftwareAll() { + for (auto& state : monitorStates) + state->softwareLocks++; +diff --git a/src/managers/PointerManager.hpp b/src/managers/PointerManager.hpp +index 4a4c4f61..082855b5 100644 +--- a/src/managers/PointerManager.hpp ++++ b/src/managers/PointerManager.hpp +@@ -26,6 +26,7 @@ class CPointerManager { + public: + CPointerManager(); + ++ void checkDefaultCursorWarp(SP monitor, std::string monitorName); + void attachPointer(SP pointer); + void attachTouch(SP touch); + void attachTablet(SP tablet); +diff --git a/src/managers/XCursorManager.cpp b/src/managers/XCursorManager.cpp +index f2a7ab53..6f000f9f 100644 +--- a/src/managers/XCursorManager.cpp ++++ b/src/managers/XCursorManager.cpp +@@ -1,7 +1,11 @@ + #include + #include + #include ++#include ++#include ++#include "config/ConfigValue.hpp" + #include "helpers/CursorShapes.hpp" ++#include "../managers/CursorManager.hpp" + #include "debug/Log.hpp" + #include "XCursorManager.hpp" + +@@ -96,12 +100,13 @@ CXCursorManager::CXCursorManager() { + defaultCursor = hyprCursor; + } + +-void CXCursorManager::loadTheme(std::string const& name, int size) { +- if (lastLoadSize == size && themeName == name) ++void CXCursorManager::loadTheme(std::string const& name, int size, float scale) { ++ if (lastLoadSize == (size * std::ceil(scale)) && themeName == name && lastLoadScale == scale) + return; + +- lastLoadSize = size; +- themeName = name.empty() ? "default" : name; ++ lastLoadSize = size * std::ceil(scale); ++ lastLoadScale = scale; ++ themeName = name.empty() ? "default" : name; + defaultCursor.reset(); + cursors.clear(); + +@@ -146,12 +151,16 @@ void CXCursorManager::loadTheme(std::string const& name, int size) { + + cursors.emplace_back(cursor); + } ++ ++ static auto SYNCGSETTINGS = CConfigValue("cursor:sync_gsettings_theme"); ++ if (*SYNCGSETTINGS) ++ syncGsettings(); + } + +-SP CXCursorManager::getShape(std::string const& shape, int size) { ++SP CXCursorManager::getShape(std::string const& shape, int size, float scale) { + // monitor scaling changed etc, so reload theme with new size. +- if (size != lastLoadSize) +- loadTheme(themeName, size); ++ if ((size * std::ceil(scale)) != lastLoadSize || scale != lastLoadScale) ++ loadTheme(themeName, size, scale); + + // try to get an icon we know if we have one + for (auto const& c : cursors) { +@@ -503,8 +512,11 @@ std::vector> CXCursorManager::loadAllFromDir(std::string const& pa + + if (std::filesystem::exists(path) && std::filesystem::is_directory(path)) { + for (const auto& entry : std::filesystem::directory_iterator(path)) { +- if (!entry.is_regular_file() && !entry.is_symlink()) ++ std::error_code e1, e2; ++ if ((!entry.is_regular_file(e1) && !entry.is_symlink(e2)) || e1 || e2) { ++ Debug::log(WARN, "XCursor failed to load shape {}: {}", entry.path().stem().string(), e1 ? e1.message() : e2.message()); + continue; ++ } + + auto const& full = entry.path().string(); + using PcloseType = int (*)(FILE*); +@@ -542,3 +554,56 @@ std::vector> CXCursorManager::loadAllFromDir(std::string const& pa + + return newCursors; + } ++ ++void CXCursorManager::syncGsettings() { ++ auto checkParamExists = [](std::string const& paramName, std::string const& category) { ++ auto* gSettingsSchemaSource = g_settings_schema_source_get_default(); ++ ++ if (!gSettingsSchemaSource) { ++ Debug::log(WARN, "GSettings default schema source does not exist, can't sync GSettings"); ++ return false; ++ } ++ ++ auto* gSettingsSchema = g_settings_schema_source_lookup(gSettingsSchemaSource, category.c_str(), true); ++ bool hasParam = false; ++ ++ if (gSettingsSchema != NULL) { ++ hasParam = gSettingsSchema && g_settings_schema_has_key(gSettingsSchema, paramName.c_str()); ++ g_settings_schema_unref(gSettingsSchema); ++ } ++ ++ return hasParam; ++ }; ++ ++ using SettingValue = std::variant; ++ auto setValue = [&checkParamExists](std::string const& paramName, const SettingValue& paramValue, std::string const& category) { ++ if (!checkParamExists(paramName, category)) { ++ Debug::log(WARN, "GSettings parameter doesnt exist {} in {}", paramName, category); ++ return; ++ } ++ ++ auto* gsettings = g_settings_new(category.c_str()); ++ ++ if (!gsettings) { ++ Debug::log(WARN, "GSettings failed to allocate new settings with category {}", category); ++ return; ++ } ++ ++ std::visit( ++ [&](auto&& value) { ++ using T = std::decay_t; ++ if constexpr (std::is_same_v) ++ g_settings_set_string(gsettings, paramName.c_str(), value.c_str()); ++ else if constexpr (std::is_same_v) ++ g_settings_set_int(gsettings, paramName.c_str(), value); ++ }, ++ paramValue); ++ ++ g_settings_sync(); ++ g_object_unref(gsettings); ++ }; ++ ++ int unscaledSize = lastLoadSize / std::ceil(lastLoadScale); ++ setValue("cursor-theme", themeName, "org.gnome.desktop.interface"); ++ setValue("cursor-size", unscaledSize, "org.gnome.desktop.interface"); ++} +diff --git a/src/managers/XCursorManager.hpp b/src/managers/XCursorManager.hpp +index 20637055..1f3c24db 100644 +--- a/src/managers/XCursorManager.hpp ++++ b/src/managers/XCursorManager.hpp +@@ -29,8 +29,9 @@ class CXCursorManager { + CXCursorManager(); + ~CXCursorManager() = default; + +- void loadTheme(const std::string& name, int size); +- SP getShape(std::string const& shape, int size); ++ void loadTheme(const std::string& name, int size, float scale); ++ SP getShape(std::string const& shape, int size, float scale); ++ void syncGsettings(); + + private: + SP createCursor(std::string const& shape, XcursorImages* xImages); +@@ -39,9 +40,10 @@ class CXCursorManager { + std::vector> loadStandardCursors(std::string const& name, int size); + std::vector> loadAllFromDir(std::string const& path, int size); + +- int lastLoadSize = 0; +- std::string themeName = ""; ++ int lastLoadSize = 0; ++ float lastLoadScale = 0; ++ std::string themeName = ""; + SP defaultCursor; + SP hyprCursor; + std::vector> cursors; +-}; +\ No newline at end of file ++}; +diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp +index c2c088f8..d1b85cf2 100644 +--- a/src/managers/eventLoop/EventLoopManager.cpp ++++ b/src/managers/eventLoop/EventLoopManager.cpp +@@ -48,7 +48,6 @@ void CEventLoopManager::enterLoop() { + aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs(); + for (auto& fd : aqPollFDs) { + m_sWayland.aqEventSources.emplace_back(wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get())); +- fd->onSignal(); // dispatch outstanding + } + + wl_display_run(m_sWayland.display); +@@ -76,8 +75,8 @@ void CEventLoopManager::removeTimer(SP timer) { + } + + static void timespecAddNs(timespec* pTimespec, int64_t delta) { +- int delta_ns_low = delta % TIMESPEC_NSEC_PER_SEC; +- int delta_s_high = delta / TIMESPEC_NSEC_PER_SEC; ++ auto delta_ns_low = delta % TIMESPEC_NSEC_PER_SEC; ++ auto delta_s_high = delta / TIMESPEC_NSEC_PER_SEC; + + pTimespec->tv_sec += delta_s_high; + +diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp +index c502cb0d..e5f921a2 100644 +--- a/src/managers/input/InputManager.cpp ++++ b/src/managers/input/InputManager.cpp +@@ -82,18 +82,13 @@ CInputManager::~CInputManager() { + } + + void CInputManager::onMouseMoved(IPointer::SMotionEvent e) { +- static auto PSENS = CConfigValue("general:sensitivity"); +- static auto PNOACCEL = CConfigValue("input:force_no_accel"); +- static auto PSENSTORAW = CConfigValue("general:apply_sens_to_raw"); ++ static auto PNOACCEL = CConfigValue("input:force_no_accel"); + + const auto DELTA = *PNOACCEL == 1 ? e.unaccel : e.delta; + +- if (*PSENSTORAW == 1) +- PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA * *PSENS, e.unaccel * *PSENS); +- else +- PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA, e.unaccel); ++ PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA, e.unaccel); + +- g_pPointerManager->move(DELTA * *PSENS); ++ g_pPointerManager->move(DELTA); + + mouseMoveUnified(e.timeMs); + +@@ -1112,8 +1107,9 @@ void CInputManager::setPointerConfigs() { + libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED); + + if (libinput_device_config_tap_get_finger_count(LIBINPUTDEV)) // this is for tapping (like on a laptop) +- if (g_pConfigManager->getDeviceInt(devname, "tap-to-click", "input:touchpad:tap-to-click") == 1) +- libinput_device_config_tap_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_TAP_ENABLED); ++ libinput_device_config_tap_set_enabled(LIBINPUTDEV, ++ g_pConfigManager->getDeviceInt(devname, "tap-to-click", "input:touchpad:tap-to-click") == 1 ? LIBINPUT_CONFIG_TAP_ENABLED : ++ LIBINPUT_CONFIG_TAP_DISABLED); + + if (libinput_device_config_scroll_has_natural_scroll(LIBINPUTDEV)) { + +diff --git a/src/managers/input/InputMethodPopup.hpp b/src/managers/input/InputMethodPopup.hpp +index f6e5c8be..f8e4b962 100644 +--- a/src/managers/input/InputMethodPopup.hpp ++++ b/src/managers/input/InputMethodPopup.hpp +@@ -33,7 +33,7 @@ class CInputPopup { + WP popup; + SP surface; + CBox lastBoxLocal; +- uint64_t lastMonitor = -1; ++ MONITORID lastMonitor = MONITOR_INVALID; + + struct { + CHyprSignalListener map; +diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp +index c0e6c4f0..6ee690cd 100644 +--- a/src/managers/input/Swipe.cpp ++++ b/src/managers/input/Swipe.cpp +@@ -77,7 +77,7 @@ void CInputManager::endWorkspaceSwipe() { + // left of where we started. Instead, it's one more than the greatest + // workspace ID that currently exists. + if (workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID && *PSWIPENEW) { +- int maxWorkspace = 0; ++ WORKSPACEID maxWorkspace = 0; + for (const auto& ws : g_pCompositor->m_vWorkspaces) { + maxWorkspace = std::max(maxWorkspace, ws->m_iID); + } +diff --git a/src/meson.build b/src/meson.build +index 098d8298..475ecc24 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -28,6 +28,7 @@ executable('Hyprland', src, + xcb_xfixes_dep, + backtrace_dep, + epoll_dep, ++ gio_dep, + udis86, + + dependency('pixman-1'), +diff --git a/src/protocols/AlphaModifier.cpp b/src/protocols/AlphaModifier.cpp +index 38b8c800..13597fa9 100644 +--- a/src/protocols/AlphaModifier.cpp ++++ b/src/protocols/AlphaModifier.cpp +@@ -4,8 +4,6 @@ + #include "../render/Renderer.hpp" + #include "core/Compositor.hpp" + +-#define LOGM PROTO::alphaModifier->protoLog +- + CAlphaModifier::CAlphaModifier(SP resource_, SP surface_) : resource(resource_), pSurface(surface_) { + if (!resource->resource()) + return; +diff --git a/src/protocols/CursorShape.cpp b/src/protocols/CursorShape.cpp +index 812afe53..233a5df9 100644 +--- a/src/protocols/CursorShape.cpp ++++ b/src/protocols/CursorShape.cpp +@@ -2,8 +2,6 @@ + #include + #include "../helpers/CursorShapes.hpp" + +-#define LOGM PROTO::cursorShape->protoLog +- + CCursorShapeProtocol::CCursorShapeProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; + } +diff --git a/src/protocols/DRMLease.cpp b/src/protocols/DRMLease.cpp +index 9f5b6312..bc0945f1 100644 +--- a/src/protocols/DRMLease.cpp ++++ b/src/protocols/DRMLease.cpp +@@ -1,10 +1,9 @@ + #include "DRMLease.hpp" + #include "../Compositor.hpp" ++#include "managers/eventLoop/EventLoopManager.hpp" + #include + #include + +-#define LOGM PROTO::lease->protoLog +- + CDRMLeaseResource::CDRMLeaseResource(SP resource_, SP request) : resource(resource_) { + if (!good()) + return; +@@ -247,10 +246,8 @@ CDRMLeaseProtocol::CDRMLeaseProtocol(const wl_interface* iface, const int& ver, + break; + } + +- if (!primaryDevice || primaryDevice->success) { +- PROTO::lease.reset(); +- return; +- } ++ if (!primaryDevice || !primaryDevice->success) ++ g_pEventLoopManager->doLater([]() { PROTO::lease.reset(); }); + } + + void CDRMLeaseProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { +diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp +index 9a48b99a..4993f1a4 100644 +--- a/src/protocols/DRMSyncobj.cpp ++++ b/src/protocols/DRMSyncobj.cpp +@@ -7,8 +7,6 @@ + + #include + +-#define LOGM PROTO::sync->protoLog +- + CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/DataDeviceWlr.cpp b/src/protocols/DataDeviceWlr.cpp +index c039d3b4..ad6ee89a 100644 +--- a/src/protocols/DataDeviceWlr.cpp ++++ b/src/protocols/DataDeviceWlr.cpp +@@ -3,8 +3,6 @@ + #include "../managers/SeatManager.hpp" + #include "core/Seat.hpp" + +-#define LOGM PROTO::dataWlr->protoLog +- + CWLRDataOffer::CWLRDataOffer(SP resource_, SP source_) : source(source_), resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/FocusGrab.cpp b/src/protocols/FocusGrab.cpp +index 40f9af44..2d6b2ee2 100644 +--- a/src/protocols/FocusGrab.cpp ++++ b/src/protocols/FocusGrab.cpp +@@ -8,8 +8,6 @@ + #include + #include + +-#define LOGM PROTO::focusGrab->protoLog +- + CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, SP surface) { + listeners.destroy = surface->events.destroy.registerListener([=](std::any d) { grab->eraseSurface(surface); }); + } +diff --git a/src/protocols/ForeignToplevel.cpp b/src/protocols/ForeignToplevel.cpp +index f7b3886f..59888ce2 100644 +--- a/src/protocols/ForeignToplevel.cpp ++++ b/src/protocols/ForeignToplevel.cpp +@@ -1,8 +1,6 @@ + #include "ForeignToplevel.hpp" + #include "../Compositor.hpp" + +-#define LOGM PROTO::foreignToplevel->protoLog +- + CForeignToplevelHandle::CForeignToplevelHandle(SP resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) { + if (!resource_->resource()) + return; +diff --git a/src/protocols/ForeignToplevelWlr.cpp b/src/protocols/ForeignToplevelWlr.cpp +index 295834ea..bd597a91 100644 +--- a/src/protocols/ForeignToplevelWlr.cpp ++++ b/src/protocols/ForeignToplevelWlr.cpp +@@ -4,8 +4,6 @@ + #include "protocols/core/Output.hpp" + #include "render/Renderer.hpp" + +-#define LOGM PROTO::foreignToplevelWlr->protoLog +- + CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) { + if (!resource_->resource()) + return; +@@ -119,7 +117,7 @@ wl_resource* CForeignToplevelHandleWlr::res() { + } + + void CForeignToplevelHandleWlr::sendMonitor(CMonitor* pMonitor) { +- if (lastMonitorID == (int64_t)pMonitor->ID) ++ if (lastMonitorID == pMonitor->ID) + return; + + const auto CLIENT = resource->client(); +diff --git a/src/protocols/ForeignToplevelWlr.hpp b/src/protocols/ForeignToplevelWlr.hpp +index e3b6f3f3..99f63b47 100644 +--- a/src/protocols/ForeignToplevelWlr.hpp ++++ b/src/protocols/ForeignToplevelWlr.hpp +@@ -20,7 +20,7 @@ class CForeignToplevelHandleWlr { + SP resource; + PHLWINDOWREF pWindow; + bool closed = false; +- int64_t lastMonitorID = -1; ++ MONITORID lastMonitorID = MONITOR_INVALID; + + void sendMonitor(CMonitor* pMonitor); + void sendState(); +diff --git a/src/protocols/FractionalScale.cpp b/src/protocols/FractionalScale.cpp +index 5bf56c5a..d39fa67c 100644 +--- a/src/protocols/FractionalScale.cpp ++++ b/src/protocols/FractionalScale.cpp +@@ -2,8 +2,6 @@ + #include + #include "core/Compositor.hpp" + +-#define LOGM PROTO::fractional->protoLog +- + CFractionalScaleProtocol::CFractionalScaleProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; + } +diff --git a/src/protocols/GammaControl.cpp b/src/protocols/GammaControl.cpp +index 494d9862..c902d00e 100644 +--- a/src/protocols/GammaControl.cpp ++++ b/src/protocols/GammaControl.cpp +@@ -5,8 +5,6 @@ + #include "../Compositor.hpp" + #include "../protocols/core/Output.hpp" + +-#define LOGM PROTO::gamma->protoLog +- + CGammaControl::CGammaControl(SP resource_, wl_resource* output) : resource(resource_) { + if (!resource_->resource()) + return; +@@ -109,7 +107,7 @@ CGammaControl::CGammaControl(SP resource_, wl_resource* out + } + + CGammaControl::~CGammaControl() { +- if (!gammaTableSet || !pMonitor) ++ if (!gammaTableSet || !pMonitor || !pMonitor->output) + return; + + // reset the LUT if the client dies for whatever reason and doesn't unset the gamma +diff --git a/src/protocols/GlobalShortcuts.cpp b/src/protocols/GlobalShortcuts.cpp +index 860004c9..92bfbae4 100644 +--- a/src/protocols/GlobalShortcuts.cpp ++++ b/src/protocols/GlobalShortcuts.cpp +@@ -1,8 +1,6 @@ + #include "GlobalShortcuts.hpp" + #include "../Compositor.hpp" + +-#define LOGM PROTO::globalShortcuts->protoLog +- + CShortcutClient::CShortcutClient(SP resource_) : resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/IdleNotify.cpp b/src/protocols/IdleNotify.cpp +index 2ec7d2a1..8d915ac6 100644 +--- a/src/protocols/IdleNotify.cpp ++++ b/src/protocols/IdleNotify.cpp +@@ -1,8 +1,6 @@ + #include "IdleNotify.hpp" + #include "../managers/eventLoop/EventLoopManager.hpp" + +-#define LOGM PROTO::idle->protoLog +- + static int onTimer(SP self, void* data) { + + const auto NOTIF = (CExtIdleNotification*)data; +diff --git a/src/protocols/InputMethodV2.cpp b/src/protocols/InputMethodV2.cpp +index fd306f09..a0820e0b 100644 +--- a/src/protocols/InputMethodV2.cpp ++++ b/src/protocols/InputMethodV2.cpp +@@ -6,8 +6,6 @@ + #include "core/Compositor.hpp" + #include + +-#define LOGM PROTO::ime->protoLog +- + CInputMethodKeyboardGrabV2::CInputMethodKeyboardGrabV2(SP resource_, SP owner_) : resource(resource_), owner(owner_) { + if (!resource->resource()) + return; +diff --git a/src/protocols/LayerShell.cpp b/src/protocols/LayerShell.cpp +index 17d3b22a..c02d23f3 100644 +--- a/src/protocols/LayerShell.cpp ++++ b/src/protocols/LayerShell.cpp +@@ -4,8 +4,6 @@ + #include "core/Compositor.hpp" + #include "core/Output.hpp" + +-#define LOGM PROTO::layerShell->protoLog +- + void CLayerShellResource::SState::reset() { + anchor = 0; + exclusive = 0; +diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp +index 0fbf832e..32625792 100644 +--- a/src/protocols/LinuxDMABUF.cpp ++++ b/src/protocols/LinuxDMABUF.cpp +@@ -14,8 +14,6 @@ + #include "../render/OpenGL.hpp" + #include "../Compositor.hpp" + +-#define LOGM PROTO::linuxDma->protoLog +- + static std::optional devIDFromFD(int fd) { + struct stat stat; + if (fstat(fd, &stat) != 0) +@@ -425,7 +423,7 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const + auto dev = devIDFromFD(rendererFD); + + if (!dev.has_value()) { +- protoLog(ERR, "failed to get drm dev, disabling linux dmabuf"); ++ LOGM(ERR, "failed to get drm dev, disabling linux dmabuf"); + removeGlobal(); + return; + } +@@ -477,7 +475,7 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const + + drmDevice* device = nullptr; + if (drmGetDeviceFromDevId(mainDevice, 0, &device) != 0) { +- protoLog(ERR, "failed to get drm dev, disabling linux dmabuf"); ++ LOGM(ERR, "failed to get drm dev, disabling linux dmabuf"); + removeGlobal(); + return; + } +@@ -487,14 +485,13 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const + mainDeviceFD = open(name, O_RDWR | O_CLOEXEC); + drmFreeDevice(&device); + if (mainDeviceFD < 0) { +- protoLog(ERR, "failed to open drm dev, disabling linux dmabuf"); ++ LOGM(ERR, "failed to open drm dev, disabling linux dmabuf"); + removeGlobal(); + return; + } + } else { +- protoLog(ERR, "DRM device {} has no render node, disabling linux dmabuf", device->nodes[DRM_NODE_PRIMARY] ? device->nodes[DRM_NODE_PRIMARY] : "null"); ++ LOGM(ERR, "DRM device {} has no render node, disabling linux dmabuf checks", device->nodes[DRM_NODE_PRIMARY] ? device->nodes[DRM_NODE_PRIMARY] : "null"); + drmFreeDevice(&device); +- removeGlobal(); + } + }); + } +diff --git a/src/protocols/MesaDRM.cpp b/src/protocols/MesaDRM.cpp +index ed412555..9fcd5f9b 100644 +--- a/src/protocols/MesaDRM.cpp ++++ b/src/protocols/MesaDRM.cpp +@@ -4,8 +4,6 @@ + #include "../Compositor.hpp" + #include "types/WLBuffer.hpp" + +-#define LOGM PROTO::mesaDRM->protoLog +- + CMesaDRMBufferResource::CMesaDRMBufferResource(uint32_t id, wl_client* client, Aquamarine::SDMABUFAttrs attrs_) { + LOGM(LOG, "Creating a Mesa dmabuf, with id {}: size {}, fmt {}, planes {}", id, attrs_.size, attrs_.format, attrs_.planes); + for (int i = 0; i < attrs_.planes; ++i) { +@@ -115,7 +113,7 @@ CMesaDRMProtocol::CMesaDRMProtocol(const wl_interface* iface, const int& ver, co + drmDevice* dev = nullptr; + int drmFD = g_pCompositor->m_iDRMFD; + if (drmGetDevice2(drmFD, 0, &dev) != 0) { +- protoLog(ERR, "Failed to get device, disabling MesaDRM"); ++ LOGM(ERR, "Failed to get device, disabling MesaDRM"); + removeGlobal(); + return; + } +@@ -126,13 +124,13 @@ CMesaDRMProtocol::CMesaDRMProtocol(const wl_interface* iface, const int& ver, co + ASSERT(dev->available_nodes & (1 << DRM_NODE_PRIMARY)); + + if (!dev->nodes[DRM_NODE_PRIMARY]) { +- protoLog(ERR, "No DRM render node available, both render and primary are null, disabling MesaDRM"); ++ LOGM(ERR, "No DRM render node available, both render and primary are null, disabling MesaDRM"); + drmFreeDevice(&dev); + removeGlobal(); + return; + } + +- protoLog(WARN, "No DRM render node, falling back to primary {}", dev->nodes[DRM_NODE_PRIMARY]); ++ LOGM(WARN, "No DRM render node, falling back to primary {}", dev->nodes[DRM_NODE_PRIMARY]); + nodeName = dev->nodes[DRM_NODE_PRIMARY]; + } + drmFreeDevice(&dev); +diff --git a/src/protocols/OutputManagement.cpp b/src/protocols/OutputManagement.cpp +index 66f4c5f0..cfe388fa 100644 +--- a/src/protocols/OutputManagement.cpp ++++ b/src/protocols/OutputManagement.cpp +@@ -4,8 +4,6 @@ + + using namespace Aquamarine; + +-#define LOGM PROTO::outputManagement->protoLog +- + COutputManager::COutputManager(SP resource_) : resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/OutputPower.cpp b/src/protocols/OutputPower.cpp +index 597b9871..0c324bf0 100644 +--- a/src/protocols/OutputPower.cpp ++++ b/src/protocols/OutputPower.cpp +@@ -2,8 +2,6 @@ + #include "../Compositor.hpp" + #include "core/Output.hpp" + +-#define LOGM PROTO::outputPower->protoLog +- + COutputPower::COutputPower(SP resource_, CMonitor* pMonitor_) : resource(resource_), pMonitor(pMonitor_) { + if (!resource->resource()) + return; +diff --git a/src/protocols/PointerConstraints.cpp b/src/protocols/PointerConstraints.cpp +index fd15242d..0f2dd991 100644 +--- a/src/protocols/PointerConstraints.cpp ++++ b/src/protocols/PointerConstraints.cpp +@@ -5,8 +5,6 @@ + #include "../managers/SeatManager.hpp" + #include "core/Compositor.hpp" + +-#define LOGM PROTO::constraints->protoLog +- + CPointerConstraint::CPointerConstraint(SP resource_, SP surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime_) : + resourceL(resource_), locked(true), lifetime(lifetime_) { + if (!resource_->resource()) +diff --git a/src/protocols/PointerGestures.cpp b/src/protocols/PointerGestures.cpp +index 86510779..c83e3887 100644 +--- a/src/protocols/PointerGestures.cpp ++++ b/src/protocols/PointerGestures.cpp +@@ -4,8 +4,6 @@ + #include "core/Seat.hpp" + #include "core/Compositor.hpp" + +-#define LOGM PROTO::pointerGestures->protoLog +- + CPointerGestureSwipe::CPointerGestureSwipe(SP resource_) : resource(resource_) { + if (!resource->resource()) + return; +diff --git a/src/protocols/PresentationTime.cpp b/src/protocols/PresentationTime.cpp +index a2fc270c..335cf557 100644 +--- a/src/protocols/PresentationTime.cpp ++++ b/src/protocols/PresentationTime.cpp +@@ -6,8 +6,6 @@ + #include "core/Output.hpp" + #include + +-#define LOGM PROTO::presentation->protoLog +- + CQueuedPresentationData::CQueuedPresentationData(SP surf) : surface(surf) { + ; + } +diff --git a/src/protocols/PrimarySelection.cpp b/src/protocols/PrimarySelection.cpp +index 78eb8d63..4fede706 100644 +--- a/src/protocols/PrimarySelection.cpp ++++ b/src/protocols/PrimarySelection.cpp +@@ -4,8 +4,6 @@ + #include "core/Seat.hpp" + #include "../config/ConfigValue.hpp" + +-#define LOGM PROTO::primarySelection->protoLog +- + CPrimarySelectionOffer::CPrimarySelectionOffer(SP resource_, SP source_) : source(source_), resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp +index a8afba84..f246f6dd 100644 +--- a/src/protocols/Screencopy.cpp ++++ b/src/protocols/Screencopy.cpp +@@ -9,8 +9,6 @@ + + #include + +-#define LOGM PROTO::screencopy->protoLog +- + CScreencopyFrame::~CScreencopyFrame() { + if (buffer && buffer->locked()) + buffer->unlock(); +diff --git a/src/protocols/ServerDecorationKDE.cpp b/src/protocols/ServerDecorationKDE.cpp +index 42da52a9..c7b98a9c 100644 +--- a/src/protocols/ServerDecorationKDE.cpp ++++ b/src/protocols/ServerDecorationKDE.cpp +@@ -1,8 +1,6 @@ + #include "ServerDecorationKDE.hpp" + #include "core/Compositor.hpp" + +-#define LOGM PROTO::serverDecorationKDE->protoLog +- + CServerDecorationKDE::CServerDecorationKDE(SP resource_, SP surf) : resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/SessionLock.cpp b/src/protocols/SessionLock.cpp +index df97413c..7b0d8b3b 100644 +--- a/src/protocols/SessionLock.cpp ++++ b/src/protocols/SessionLock.cpp +@@ -5,8 +5,6 @@ + #include "core/Compositor.hpp" + #include "core/Output.hpp" + +-#define LOGM PROTO::sessionLock->protoLog +- + CSessionLockSurface::CSessionLockSurface(SP resource_, SP surface_, CMonitor* pMonitor_, WP owner_) : + resource(resource_), sessionLock(owner_), pSurface(surface_), pMonitor(pMonitor_) { + if (!resource->resource()) +diff --git a/src/protocols/ShortcutsInhibit.cpp b/src/protocols/ShortcutsInhibit.cpp +index 1a0433e6..e4424ed7 100644 +--- a/src/protocols/ShortcutsInhibit.cpp ++++ b/src/protocols/ShortcutsInhibit.cpp +@@ -3,8 +3,6 @@ + #include "../Compositor.hpp" + #include "core/Compositor.hpp" + +-#define LOGM PROTO::shortcutsInhibit->protoLog +- + CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP resource_, SP surf) : resource(resource_), pSurface(surf) { + if (!resource->resource()) + return; +diff --git a/src/protocols/Tablet.cpp b/src/protocols/Tablet.cpp +index 72c7cfde..b974152e 100644 +--- a/src/protocols/Tablet.cpp ++++ b/src/protocols/Tablet.cpp +@@ -7,8 +7,6 @@ + #include + #include + +-#define LOGM PROTO::tablet->protoLog +- + CTabletPadStripV2Resource::CTabletPadStripV2Resource(SP resource_, uint32_t id_) : id(id_), resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/TextInputV1.cpp b/src/protocols/TextInputV1.cpp +index 78e910cb..f25f5aca 100644 +--- a/src/protocols/TextInputV1.cpp ++++ b/src/protocols/TextInputV1.cpp +@@ -3,8 +3,6 @@ + #include "../Compositor.hpp" + #include "core/Compositor.hpp" + +-#define LOGM PROTO::textInputV1->protoLog +- + CTextInputV1::~CTextInputV1() { + events.destroy.emit(); + } +diff --git a/src/protocols/TextInputV3.cpp b/src/protocols/TextInputV3.cpp +index 1302a57f..99d799f3 100644 +--- a/src/protocols/TextInputV3.cpp ++++ b/src/protocols/TextInputV3.cpp +@@ -2,8 +2,6 @@ + #include + #include "core/Compositor.hpp" + +-#define LOGM PROTO::textInputV3->protoLog +- + void CTextInputV3::SState::reset() { + cause = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD; + surrounding.updated = false; +diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp +index fb3fde2b..05e991d6 100644 +--- a/src/protocols/ToplevelExport.cpp ++++ b/src/protocols/ToplevelExport.cpp +@@ -8,8 +8,6 @@ + + #include + +-#define LOGM PROTO::toplevelExport->protoLog +- + CToplevelExportClient::CToplevelExportClient(SP resource_) : resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/Viewporter.cpp b/src/protocols/Viewporter.cpp +index 78f3039f..58cb851d 100644 +--- a/src/protocols/Viewporter.cpp ++++ b/src/protocols/Viewporter.cpp +@@ -2,8 +2,6 @@ + #include "core/Compositor.hpp" + #include + +-#define LOGM PROTO::viewport->protoLog +- + CViewportResource::CViewportResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/VirtualKeyboard.cpp b/src/protocols/VirtualKeyboard.cpp +index 2642ec11..27a4f248 100644 +--- a/src/protocols/VirtualKeyboard.cpp ++++ b/src/protocols/VirtualKeyboard.cpp +@@ -2,8 +2,6 @@ + #include + #include "../devices/IKeyboard.hpp" + +-#define LOGM PROTO::virtualKeyboard->protoLog +- + CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP resource_) : resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/VirtualPointer.cpp b/src/protocols/VirtualPointer.cpp +index 8626241a..eb92a640 100644 +--- a/src/protocols/VirtualPointer.cpp ++++ b/src/protocols/VirtualPointer.cpp +@@ -1,8 +1,6 @@ + #include "VirtualPointer.hpp" + #include "core/Output.hpp" + +-#define LOGM PROTO::virtualPointer->protoLog +- + CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP resource_, WP boundOutput_) : boundOutput(boundOutput_), resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/WaylandProtocol.cpp b/src/protocols/WaylandProtocol.cpp +index 954f160d..0782d323 100644 +--- a/src/protocols/WaylandProtocol.cpp ++++ b/src/protocols/WaylandProtocol.cpp +@@ -21,7 +21,7 @@ IWaylandProtocol::IWaylandProtocol(const wl_interface* iface, const int& ver, co + m_pGlobal = wl_global_create(g_pCompositor->m_sWLDisplay, iface, ver, this, &bindManagerInternal); + + if (!m_pGlobal) { +- protoLog(ERR, "could not create a global"); ++ LOGM(ERR, "could not create a global [{}]", m_szName); + return; + } + +@@ -30,7 +30,7 @@ IWaylandProtocol::IWaylandProtocol(const wl_interface* iface, const int& ver, co + m_liDisplayDestroy.parent = this; + wl_display_add_destroy_listener(g_pCompositor->m_sWLDisplay, &m_liDisplayDestroy.listener); + +- protoLog(LOG, "Registered global"); ++ LOGM(LOG, "Registered global [{}]", m_szName); + } + + IWaylandProtocol::~IWaylandProtocol() { +diff --git a/src/protocols/WaylandProtocol.hpp b/src/protocols/WaylandProtocol.hpp +index 4d4e7925..0fa8daab 100644 +--- a/src/protocols/WaylandProtocol.hpp ++++ b/src/protocols/WaylandProtocol.hpp +@@ -11,6 +11,35 @@ + + #define PROTO NProtocols + ++#define EXTRACT_CLASS_NAME() \ ++ []() constexpr -> std::string_view { \ ++ constexpr std::string_view prettyFunction = __PRETTY_FUNCTION__; \ ++ constexpr size_t colons = prettyFunction.find("::"); \ ++ if (colons != std::string_view::npos) { \ ++ constexpr size_t begin = prettyFunction.substr(0, colons).rfind(' ') + 1; \ ++ constexpr size_t end = colons - begin; \ ++ return prettyFunction.substr(begin, end); \ ++ } else { \ ++ return "Global"; \ ++ } \ ++ }() ++ ++#define LOGM(level, ...) \ ++ do { \ ++ std::ostringstream oss; \ ++ if (level == WARN || level == ERR || level == CRIT) { \ ++ oss << "[" << __FILE__ << ":" << __LINE__ << "] "; \ ++ } else if (level == LOG || level == INFO || level == TRACE) { \ ++ oss << "[" << EXTRACT_CLASS_NAME() << "] "; \ ++ } \ ++ if constexpr (std::is_same_v) { \ ++ oss << __VA_ARGS__; \ ++ Debug::log(level, oss.str()); \ ++ } else { \ ++ Debug::log(level, std::format("{}{}", oss.str(), std::format(__VA_ARGS__))); \ ++ } \ ++ } while (0) ++ + class IWaylandProtocol; + struct IWaylandProtocolDestroyWrapper { + wl_listener listener; +@@ -22,15 +51,10 @@ class IWaylandProtocol { + IWaylandProtocol(const wl_interface* iface, const int& ver, const std::string& name); + virtual ~IWaylandProtocol(); + +- virtual void onDisplayDestroy(); +- virtual void removeGlobal(); +- +- virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) = 0; ++ virtual void onDisplayDestroy(); ++ virtual void removeGlobal(); + +- template +- void protoLog(LogLevel level, std::format_string fmt, Args&&... args) { +- Debug::log(level, std::format("[{}] ", m_szName) + std::vformat(fmt.get(), std::make_format_args(args...))); +- }; ++ virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) = 0; + + IWaylandProtocolDestroyWrapper m_liDisplayDestroy; + +diff --git a/src/protocols/XDGActivation.cpp b/src/protocols/XDGActivation.cpp +index 40f33f02..4a6c7bfe 100644 +--- a/src/protocols/XDGActivation.cpp ++++ b/src/protocols/XDGActivation.cpp +@@ -4,8 +4,6 @@ + #include "core/Compositor.hpp" + #include + +-#define LOGM PROTO::activation->protoLog +- + CXDGActivationToken::CXDGActivationToken(SP resource_) : resource(resource_) { + if (!resource_->resource()) + return; +diff --git a/src/protocols/XDGDecoration.cpp b/src/protocols/XDGDecoration.cpp +index 021a1141..07b1694c 100644 +--- a/src/protocols/XDGDecoration.cpp ++++ b/src/protocols/XDGDecoration.cpp +@@ -1,8 +1,6 @@ + #include "XDGDecoration.hpp" + #include + +-#define LOGM PROTO::xdgDecoration->protoLog +- + CXDGDecoration::CXDGDecoration(SP resource_, wl_resource* toplevel) : resource(resource_), pToplevelResource(toplevel) { + if (!resource->resource()) + return; +diff --git a/src/protocols/XDGOutput.cpp b/src/protocols/XDGOutput.cpp +index 073aa502..9c2c353c 100644 +--- a/src/protocols/XDGOutput.cpp ++++ b/src/protocols/XDGOutput.cpp +@@ -12,8 +12,6 @@ + + // + +-#define LOGM PROTO::xdgOutput->protoLog +- + void CXDGOutputProtocol::onManagerResourceDestroy(wl_resource* res) { + std::erase_if(m_vManagerResources, [&](const auto& other) { return other->resource() == res; }); + } +diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp +index aea23329..eaf5c333 100644 +--- a/src/protocols/XDGShell.cpp ++++ b/src/protocols/XDGShell.cpp +@@ -6,8 +6,6 @@ + #include "core/Compositor.hpp" + #include + +-#define LOGM PROTO::xdgShell->protoLog +- + void SXDGPositionerState::setAnchor(xdgPositionerAnchor edges) { + anchor.setTop(edges == XDG_POSITIONER_ANCHOR_TOP || edges == XDG_POSITIONER_ANCHOR_TOP_LEFT || edges == XDG_POSITIONER_ANCHOR_TOP_RIGHT); + anchor.setLeft(edges == XDG_POSITIONER_ANCHOR_LEFT || edges == XDG_POSITIONER_ANCHOR_TOP_LEFT || edges == XDG_POSITIONER_ANCHOR_BOTTOM_LEFT); +diff --git a/src/protocols/XWaylandShell.cpp b/src/protocols/XWaylandShell.cpp +index 6cc5256f..d6c3b1a8 100644 +--- a/src/protocols/XWaylandShell.cpp ++++ b/src/protocols/XWaylandShell.cpp +@@ -2,8 +2,6 @@ + #include "core/Compositor.hpp" + #include + +-#define LOGM PROTO::xwaylandShell->protoLog +- + CXWaylandSurfaceResource::CXWaylandSurfaceResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp +index a767dd52..8b6f46b1 100644 +--- a/src/protocols/core/Compositor.cpp ++++ b/src/protocols/core/Compositor.cpp +@@ -13,8 +13,6 @@ + #include "../../render/Renderer.hpp" + #include + +-#define LOGM PROTO::compositor->protoLog +- + class CDefaultSurfaceRole : public ISurfaceRole { + public: + virtual eSurfaceRole role() { +diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp +index fe3905d0..4ed28f24 100644 +--- a/src/protocols/core/DataDevice.cpp ++++ b/src/protocols/core/DataDevice.cpp +@@ -6,8 +6,6 @@ + #include "Seat.hpp" + #include "Compositor.hpp" + +-#define LOGM PROTO::data->protoLog +- + CWLDataOfferResource::CWLDataOfferResource(SP resource_, SP source_) : source(source_), resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp +index bb6a9d4d..a111c12c 100644 +--- a/src/protocols/core/Seat.cpp ++++ b/src/protocols/core/Seat.cpp +@@ -9,8 +9,6 @@ + + #include + +-#define LOGM PROTO::seat->protoLog +- + CWLTouchResource::CWLTouchResource(SP resource_, SP owner_) : owner(owner_), resource(resource_) { + if (!good()) + return; +diff --git a/src/protocols/core/Shm.cpp b/src/protocols/core/Shm.cpp +index 75c2134a..9996a607 100644 +--- a/src/protocols/core/Shm.cpp ++++ b/src/protocols/core/Shm.cpp +@@ -7,8 +7,6 @@ + #include "../../Compositor.hpp" + #include "../../helpers/Format.hpp" + +-#define LOGM PROTO::shm->protoLog +- + CWLSHMBuffer::CWLSHMBuffer(SP pool_, uint32_t id, int32_t offset_, const Vector2D& size_, int32_t stride_, uint32_t fmt_) { + if (!pool_->pool->data) + return; +@@ -65,7 +63,7 @@ Aquamarine::SSHMAttrs CWLSHMBuffer::shm() { + } + + std::tuple CWLSHMBuffer::beginDataPtr(uint32_t flags) { +- return {(uint8_t*)pool->data + offset, fmt, size.x * size.y * 4}; ++ return {(uint8_t*)pool->data + offset, fmt, stride * size.y}; + } + + void CWLSHMBuffer::endDataPtr() { +diff --git a/src/protocols/core/Subcompositor.cpp b/src/protocols/core/Subcompositor.cpp +index 2a7c06dc..e0679eff 100644 +--- a/src/protocols/core/Subcompositor.cpp ++++ b/src/protocols/core/Subcompositor.cpp +@@ -2,8 +2,6 @@ + #include "Compositor.hpp" + #include + +-#define LOGM PROTO::subcompositor->protoLog +- + CWLSubsurfaceResource::CWLSubsurfaceResource(SP resource_, SP surface_, SP parent_) : + surface(surface_), parent(parent_), resource(resource_) { + if (!good()) +diff --git a/src/render/Framebuffer.cpp b/src/render/Framebuffer.cpp +index 67629e23..c48ff6f3 100644 +--- a/src/render/Framebuffer.cpp ++++ b/src/render/Framebuffer.cpp +@@ -12,9 +12,10 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) { + uint32_t glFormat = FormatUtils::drmFormatToGL(drmFormat); + uint32_t glType = FormatUtils::glFormatToType(glFormat); + +- if (m_iFb == (uint32_t)-1) { ++ if (!m_iFbAllocated) { + firstAlloc = true; + glGenFramebuffers(1, &m_iFb); ++ m_iFbAllocated = true; + } + + if (m_cTex->m_iTexID == 0) { +@@ -88,12 +89,12 @@ void CFramebuffer::bind() { + } + + void CFramebuffer::release() { +- if (m_iFb != (uint32_t)-1 && m_iFb) ++ if (m_iFbAllocated) + glDeleteFramebuffers(1, &m_iFb); + + m_cTex->destroyTexture(); +- m_iFb = -1; +- m_vSize = Vector2D(); ++ m_iFbAllocated = false; ++ m_vSize = Vector2D(); + } + + CFramebuffer::~CFramebuffer() { +@@ -101,5 +102,5 @@ CFramebuffer::~CFramebuffer() { + } + + bool CFramebuffer::isAllocated() { +- return m_iFb != (GLuint)-1; ++ return m_iFbAllocated; + } +\ No newline at end of file +diff --git a/src/render/Framebuffer.hpp b/src/render/Framebuffer.hpp +index a46a4859..ca7f9e8a 100644 +--- a/src/render/Framebuffer.hpp ++++ b/src/render/Framebuffer.hpp +@@ -18,7 +18,8 @@ class CFramebuffer { + Vector2D m_vSize; + + SP m_cTex; +- GLuint m_iFb = -1; ++ GLuint m_iFb; ++ bool m_iFbAllocated{false}; + + SP m_pStencilTex; + }; +\ No newline at end of file +diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp +index c355f4f9..63cc2203 100644 +--- a/src/render/OpenGL.cpp ++++ b/src/render/OpenGL.cpp +@@ -1247,14 +1247,14 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, int round + + glEnable(GL_STENCIL_TEST); + +- glStencilFunc(GL_ALWAYS, 1, -1); ++ glStencilFunc(GL_ALWAYS, 1, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + renderRect(box, CColor(0, 0, 0, 0), round); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + +- glStencilFunc(GL_EQUAL, 1, -1); ++ glStencilFunc(GL_EQUAL, 1, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + scissor(box); +@@ -1269,7 +1269,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, int round + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); + glDisable(GL_STENCIL_TEST); +- glStencilMask(-1); ++ glStencilMask(0xFF); + glStencilFunc(GL_ALWAYS, 1, 0xFF); + scissor((CBox*)nullptr); + +@@ -1802,12 +1802,12 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o + CRegion tempDamage{damage}; + + // and draw +- for (int i = 1; i <= *PBLURPASSES; ++i) { ++ for (auto i = 1; i <= *PBLURPASSES; ++i) { + tempDamage = damage.copy().scale(1.f / (1 << i)); + drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage); // down + } + +- for (int i = *PBLURPASSES - 1; i >= 0; --i) { ++ for (auto i = *PBLURPASSES - 1; i >= 0; --i) { + tempDamage = damage.copy().scale(1.f / (1 << i)); // when upsampling we make the region twice as big + drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up + } +@@ -2091,7 +2091,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float + + glEnable(GL_STENCIL_TEST); + +- glStencilFunc(GL_ALWAYS, 1, -1); ++ glStencilFunc(GL_ALWAYS, 1, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); +@@ -2101,7 +2101,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float + renderTexture(tex, pBox, a, round, true, true); // discard opaque + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + +- glStencilFunc(GL_EQUAL, 1, -1); ++ glStencilFunc(GL_EQUAL, 1, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + // stencil done. Render everything. +@@ -2124,7 +2124,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float + glDisable(GL_STENCIL_TEST); + renderTextureInternalWithDamage(tex, pBox, a, &texDamage, round, false, false, true, true); + +- glStencilMask(-1); ++ glStencilMask(0xFF); + glStencilFunc(GL_ALWAYS, 1, 0xFF); + scissor((CBox*)nullptr); + } +@@ -2690,7 +2690,7 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) { + // check if wallpapers exist + std::error_code err; + if (!std::filesystem::exists(texPath, err)) { +- Debug::log(ERR, "createBGTextureForMonitor: failed, file doesn't exist or access denied, ec: {}", err.message()); ++ Debug::log(ERR, "createBGTextureForMonitor: failed, file \"{}\" doesn't exist or access denied, ec: {}", texPath, err.message()); + return; // the texture will be empty, oh well. We'll clear with a solid color anyways. + } + +diff --git a/src/render/Renderbuffer.cpp b/src/render/Renderbuffer.cpp +index 58ed88d6..c4425ce9 100644 +--- a/src/render/Renderbuffer.cpp ++++ b/src/render/Renderbuffer.cpp +@@ -35,7 +35,8 @@ CRenderbuffer::CRenderbuffer(SP buffer, uint32_t format) : + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + glGenFramebuffers(1, &m_sFramebuffer.m_iFb); +- m_sFramebuffer.m_vSize = buffer->size; ++ m_sFramebuffer.m_iFbAllocated = true; ++ m_sFramebuffer.m_vSize = buffer->size; + m_sFramebuffer.bind(); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_iRBO); + +diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp +index 7b29eb77..b363c287 100644 +--- a/src/render/Renderer.cpp ++++ b/src/render/Renderer.cpp +@@ -1207,6 +1207,9 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { + } else if (!pMonitor->lastScanout.expired()) { + Debug::log(LOG, "Left a direct scanout."); + pMonitor->lastScanout.reset(); ++ ++ // reset DRM format, make sure it's the one we want. ++ pMonitor->output->state->setFormat(pMonitor->drmFormat); + } + } + +@@ -1395,15 +1398,15 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { + + pMonitor->pendingFrame = false; + +- const float µs = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - renderStart).count() / 1000.f; +- g_pDebugOverlay->renderData(pMonitor, µs); ++ const float durationUs = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - renderStart).count() / 1000.f; ++ g_pDebugOverlay->renderData(pMonitor, durationUs); + + if (*PDEBUGOVERLAY == 1) { + if (pMonitor == g_pCompositor->m_vMonitors.front().get()) { +- const float µsNoOverlay = µs - std::chrono::duration_cast(endRenderOverlay - renderStartOverlay).count() / 1000.f; +- g_pDebugOverlay->renderDataNoOverlay(pMonitor, µsNoOverlay); ++ const float noOverlayUs = durationUs - std::chrono::duration_cast(endRenderOverlay - renderStartOverlay).count() / 1000.f; ++ g_pDebugOverlay->renderDataNoOverlay(pMonitor, noOverlayUs); + } else { +- g_pDebugOverlay->renderDataNoOverlay(pMonitor, µs); ++ g_pDebugOverlay->renderDataNoOverlay(pMonitor, durationUs); + } + } + } +@@ -1658,7 +1661,7 @@ void CHyprRenderer::arrangeLayerArray(CMonitor* pMonitor, const std::vectorgetMonitorFromID(monitor); + + if (!PMONITOR) +@@ -2155,6 +2158,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR + + for (auto& fmt : formats[(int)!RULE->enable10bit]) { + pMonitor->output->state->setFormat(fmt.second); ++ pMonitor->drmFormat = fmt.second; + + if (!pMonitor->state.test()) { + Debug::log(ERR, "output {} failed basic test on format {}", pMonitor->szName, fmt.first); +@@ -2299,7 +2303,7 @@ void CHyprRenderer::setCursorFromName(const std::string& name, bool force) { + } + + void CHyprRenderer::ensureCursorRenderingMode() { +- static auto PCURSORTIMEOUT = CConfigValue("cursor:inactive_timeout"); ++ static auto PCURSORTIMEOUT = CConfigValue("cursor:inactive_timeout"); + static auto PHIDEONTOUCH = CConfigValue("cursor:hide_on_touch"); + static auto PHIDEONKEY = CConfigValue("cursor:hide_on_key_press"); + +diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp +index 84501821..0b16efea 100644 +--- a/src/render/Renderer.hpp ++++ b/src/render/Renderer.hpp +@@ -49,7 +49,7 @@ class CHyprRenderer { + ~CHyprRenderer(); + + void renderMonitor(CMonitor* pMonitor); +- void arrangeLayersForMonitor(const int&); ++ void arrangeLayersForMonitor(const MONITORID&); + void damageSurface(SP, double, double, double scale = 1.0); + void damageWindow(PHLWINDOW, bool forceFull = false); + void damageBox(CBox*, bool skipFrameSchedule = false); +diff --git a/src/signal-safe.cpp b/src/signal-safe.cpp +index 05ca9c65..44d23f9b 100644 +--- a/src/signal-safe.cpp ++++ b/src/signal-safe.cpp +@@ -10,7 +10,7 @@ + extern char** environ; + + char const* sig_getenv(char const* name) { +- int len = strlen(name); ++ size_t len = strlen(name); + for (char** var = environ; *var != NULL; var++) { + if (strncmp(*var, name, len) == 0 && (*var)[len] == '=') { + return (*var) + len + 1; +diff --git a/src/signal-safe.hpp b/src/signal-safe.hpp +index 3a38f043..ef643097 100644 +--- a/src/signal-safe.hpp ++++ b/src/signal-safe.hpp +@@ -139,7 +139,7 @@ class BufFileWriter { + abort(); + } else { + close(pipefd[1]); +- int len; ++ long len; + char readbuf[256]; + while ((len = read(pipefd[0], readbuf, 256)) > 0) { + write(readbuf, len); +@@ -155,7 +155,7 @@ class BufFileWriter { + void flush() { + size_t i = 0; + while (i < m_writeBufPos) { +- int written = ::write(m_fd, m_writeBuf + i, m_writeBufPos - i); ++ auto written = ::write(m_fd, m_writeBuf + i, m_writeBufPos - i); + if (written <= 0) { + return; + } +diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp +index cec582f6..200bec70 100644 +--- a/src/xwayland/Server.cpp ++++ b/src/xwayland/Server.cpp +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + // TODO: cleanup + static bool set_cloexec(int fd, bool cloexec) { diff --git a/hosts/callisto/configuration.nix b/hosts/callisto/configuration.nix new file mode 100755 index 0000000..436419d --- /dev/null +++ b/hosts/callisto/configuration.nix @@ -0,0 +1,212 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running ‘nixos-help’). +{ + config, + inputs, + pkgs, + ... +}: { + imports = [ + # Include the results of the hardware scan. + ./hardware-configuration.nix + # ./apple-silicon-support + ]; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = false; + + hardware.asahi = { + peripheralFirmwareDirectory = ./firmware; + useExperimentalGPUDriver = true; + experimentalGPUInstallMode = "overlay"; + }; + + boot.extraModprobeConfig = '' + options hid_apple iso_layout=0 + ''; + + boot.kernelParams = ["apple_dcp.show_notch=1"]; + + networking.hostName = "callisto"; # Define your hostname. + # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. + + networking.wireless.iwd = { + enable = true; + settings.General.EnableNetworkConfiguration = true; + }; + + nixpkgs.overlays = [ + inputs.apple-silicon.overlays.apple-silicon-overlay + (final: prev: { + hyprland = prev.hyprland.overrideAttrs (oldAttrs: { + src = oldAttrs.src; + patches = + oldAttrs.patches + or [] + ++ [ + ./asahi-fix.patch + ]; + }); + }) + ]; + + programs.light.enable = true; + + # Configure network proxy if necessary + # networking.proxy.default = "http://user:password@proxy:port/"; + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + + # Enable networking + # networking.networkmanager.enable = true; + + # Set your time zone. + time.timeZone = "America/Los_Angeles"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; + + # Enable the X11 windowing system. + # You can disable this if you're only using the Wayland session. + services.xserver.enable = false; + + programs.nix-ld = { + enable = true; + libraries = with pkgs; [icu xorg.libXtst xorg.libXi]; + }; + + # Configure keymap in X11 + services.xserver = { + xkb.layout = "us"; + xkb.variant = ""; + }; + + # Enable CUPS to print documents. + services.printing.enable = true; + + # Enable touchpad support (enabled default in most desktopManager). + # services.xserver.libinput.enable = true; + + # Define a user account. Don't forget to set a password with ‘passwd’. + users.users.youwen = { + isNormalUser = true; + description = "Youwen Wu"; + extraGroups = ["networkmanager" "wheel" "nixos" "realtime"]; + }; + + users.groups.realtime = {}; + + nix.settings = { + trusted-users = ["root" "youwen"]; + experimental-features = ["nix-command" "flakes"]; + }; + + services.udev.extraRules = '' + KERNEL=="cpu_dma_latency", GROUP="realtime" + KERNEL=="macsmc-battery", SUBSYSTEM=="power_supply", ATTR{charge_control_end_threshold}="80", ATTR{charge_control_start_threshold}="70" + ''; + + security.pam.loginLimits = [ + { + domain = "@realtime"; + type = "-"; + item = "rtprio"; + value = 98; + } + { + domain = "@realtime"; + type = "-"; + item = "memlock"; + value = "unlimited"; + } + { + domain = "@realtime"; + type = "-"; + item = "nice"; + value = -11; + } + ]; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + neovim + wget + git + curl + ]; + + environment.variables = { + EDITOR = "nvim"; + NIX_AUTO_RUN = 1; + }; + services.keyd = { + enable = true; + keyboards = { + default = { + ids = ["*"]; + settings = { + main = { + capslock = "esc"; + leftmeta = "leftcontrol"; + leftalt = "leftmeta"; + leftcontrol = "leftalt"; + rightmeta = "leftalt"; + rightalt = "layer(rightalt)"; + }; + rightalt = { + i = "up"; + j = "left"; + k = "down"; + l = "right"; + }; + }; + }; + }; + }; + + services.tlp.enable = true; + + # tells electron apps to use Wayland + environment.sessionVariables.NIXOS_OZONE_WL = "1"; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + + programs.dconf.enable = true; + + programs.hyprland.enable = true; + # programs.hyprland.package = inputs.stablepkgs.legacyPackages.${pkgs.stdenv.hostPlatform.system}.hyprland; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "24.11"; # Did you read the comment? + + programs.zsh.enable = false; + programs.fish.enable = true; + users.users.youwen.shell = pkgs.fish; +} diff --git a/hosts/callisto/default.nix b/hosts/callisto/default.nix old mode 100755 new mode 100644 index e39ca0d..d44fca3 --- a/hosts/callisto/default.nix +++ b/hosts/callisto/default.nix @@ -1,198 +1,41 @@ -# Edit this configuration file to define what should be installed on -# your system. Help is available in the configuration.nix(5) man page -# and in the NixOS manual (accessible by running ‘nixos-help’). { - config, inputs, - pkgs, + system, ... }: { - imports = [ - # Include the results of the hardware scan. - ./hardware-configuration.nix - # ./apple-silicon-support - ]; + imports = with inputs; [ + ./configuration.nix + ../../modules/nixos/audio + ../../modules/nixos/networking + ../../modules/nixos/fonts + ../../modules/nixos/greeter + ../../modules/nixos/core + ../../overlays - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = false; - - hardware.asahi = { - peripheralFirmwareDirectory = ./firmware; - useExperimentalGPUDriver = true; - experimentalGPUInstallMode = "overlay"; - }; - - boot.extraModprobeConfig = '' - options hid_apple iso_layout=0 - ''; - - boot.kernelParams = ["apple_dcp.show_notch=1"]; - - networking.hostName = "callisto"; # Define your hostname. - # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. - - networking.wireless.iwd = { - enable = true; - settings.General.EnableNetworkConfiguration = true; - }; - - nixpkgs.overlays = [inputs.apple-silicon.overlays.apple-silicon-overlay]; - - programs.light.enable = true; - - # Configure network proxy if necessary - # networking.proxy.default = "http://user:password@proxy:port/"; - # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; - - # Enable networking - # networking.networkmanager.enable = true; - - # Set your time zone. - time.timeZone = "America/Los_Angeles"; - - # Select internationalisation properties. - i18n.defaultLocale = "en_US.UTF-8"; - - i18n.extraLocaleSettings = { - LC_ADDRESS = "en_US.UTF-8"; - LC_IDENTIFICATION = "en_US.UTF-8"; - LC_MEASUREMENT = "en_US.UTF-8"; - LC_MONETARY = "en_US.UTF-8"; - LC_NAME = "en_US.UTF-8"; - LC_NUMERIC = "en_US.UTF-8"; - LC_PAPER = "en_US.UTF-8"; - LC_TELEPHONE = "en_US.UTF-8"; - LC_TIME = "en_US.UTF-8"; - }; - - # Enable the X11 windowing system. - # You can disable this if you're only using the Wayland session. - services.xserver.enable = false; - - programs.nix-ld = { - enable = true; - libraries = with pkgs; [icu xorg.libXtst xorg.libXi]; - }; - - # Configure keymap in X11 - services.xserver = { - xkb.layout = "us"; - xkb.variant = ""; - }; - - # Enable CUPS to print documents. - services.printing.enable = true; - - # Enable touchpad support (enabled default in most desktopManager). - # services.xserver.libinput.enable = true; - - # Define a user account. Don't forget to set a password with ‘passwd’. - users.users.youwen = { - isNormalUser = true; - description = "Youwen Wu"; - extraGroups = ["networkmanager" "wheel" "nixos" "realtime"]; - }; - - users.groups.realtime = {}; - - nix.settings = { - trusted-users = ["root" "youwen"]; - experimental-features = ["nix-command" "flakes"]; - }; - - services.udev.extraRules = '' - KERNEL=="cpu_dma_latency", GROUP="realtime" - KERNEL=="macsmc-battery", SUBSYSTEM=="power_supply", ATTR{charge_control_end_threshold}="80", ATTR{charge_control_start_threshold}="70" - ''; - - security.pam.loginLimits = [ + apple-silicon.nixosModules.apple-silicon-support + catppuccin.nixosModules.catppuccin + lix-module.nixosModules.default + home-manager.nixosModules.home-manager { - domain = "@realtime"; - type = "-"; - item = "rtprio"; - value = 98; - } - { - domain = "@realtime"; - type = "-"; - item = "memlock"; - value = "unlimited"; - } - { - domain = "@realtime"; - type = "-"; - item = "nice"; - value = -11; - } - ]; - - # Allow unfree packages - nixpkgs.config.allowUnfree = true; - - # List packages installed in system profile. To search, run: - # $ nix search wget - environment.systemPackages = with pkgs; [ - neovim - wget - git - curl - ]; - - environment.variables = { - EDITOR = "nvim"; - NIX_AUTO_RUN = 1; - }; - services.keyd = { - enable = true; - keyboards = { - default = { - ids = ["*"]; - settings = { - main = { - capslock = "esc"; - leftmeta = "leftcontrol"; - leftalt = "leftmeta"; - leftcontrol = "leftalt"; - rightmeta = "leftalt"; - rightalt = "layer(rightalt)"; - }; - rightalt = { - i = "up"; - j = "left"; - k = "down"; - l = "right"; - }; - }; + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.backupFileExtension = "backup"; + home-manager.extraSpecialArgs = { + inherit inputs; + inherit system; }; - }; - }; + home-manager.users.youwen = { + imports = [ + ../../users/youwen/common + ../../users/youwen/common/neofetch/asahi-only.nix + ../../users/youwen/linux/laptop + ../../users/youwen/linux/packages/aarch-64 + ../../users/youwen/common/neovim - services.tlp.enable = true; - - # tells electron apps to use Wayland - environment.sessionVariables.NIXOS_OZONE_WL = "1"; - - # Some programs need SUID wrappers, can be configured further or are - # started in user sessions. - # programs.mtr.enable = true; - programs.gnupg.agent = { - enable = true; - enableSSHSupport = true; - }; - - programs.dconf.enable = true; - - programs.hyprland.enable = true; - - # This value determines the NixOS release from which the default - # settings for stateful data, like file locations and database versions - # on your system were taken. It‘s perfectly fine and recommended to leave - # this value at the release version of the first install of this system. - # Before changing this value read the documentation for this option - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). - system.stateVersion = "24.11"; # Did you read the comment? - - programs.zsh.enable = false; - programs.fish.enable = true; - users.users.youwen.shell = pkgs.fish; + inputs.catppuccin.homeManagerModules.catppuccin + inputs.nixvim.homeManagerModules.nixvim + ]; + }; + } + ]; } diff --git a/hosts/callisto/hardware-configuration.nix b/hosts/callisto/hardware-configuration.nix old mode 100755 new mode 100644 index c812f7a..b32d2d8 --- a/hosts/callisto/hardware-configuration.nix +++ b/hosts/callisto/hardware-configuration.nix @@ -1,32 +1,32 @@ # Do not modify this file! It was generated by ‘nixos-generate-config’ # and may be overwritten by future invocations. Please make changes # to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + { - config, - lib, - pkgs, - modulesPath, - ... -}: { - imports = [(modulesPath + "/installer/scan/not-detected.nix")]; + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; - boot.initrd.availableKernelModules = ["usb_storage" "sdhci_pci"]; - boot.initrd.kernelModules = []; - boot.kernelModules = []; - boot.extraModulePackages = []; + boot.initrd.availableKernelModules = [ "usb_storage" "sdhci_pci" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; - fileSystems."/" = { - device = "/dev/disk/by-uuid/bc88058e-6e3a-4987-b78e-e19cb5611608"; - fsType = "ext4"; - }; + fileSystems."/" = + { device = "/dev/mapper/crypted"; + fsType = "ext4"; + }; - fileSystems."/boot" = { - device = "/dev/disk/by-uuid/852F-07F1"; - fsType = "vfat"; - options = ["fmask=0022" "dmask=0022"]; - }; + boot.initrd.luks.devices."crypted".device = "/dev/disk/by-uuid/f4c552be-a4c2-4ca0-aec6-ed692d78fe24"; - swapDevices = []; + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/852F-07F1"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + + swapDevices = [ ]; # Enables DHCP on each ethernet and wireless interface. In case of scripted networking # (the default) this is the recommended approach. When using systemd-networkd it's diff --git a/hosts/callisto/hardware-configuration.nix.old b/hosts/callisto/hardware-configuration.nix.old new file mode 100755 index 0000000..c812f7a --- /dev/null +++ b/hosts/callisto/hardware-configuration.nix.old @@ -0,0 +1,39 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { + imports = [(modulesPath + "/installer/scan/not-detected.nix")]; + + boot.initrd.availableKernelModules = ["usb_storage" "sdhci_pci"]; + boot.initrd.kernelModules = []; + boot.kernelModules = []; + boot.extraModulePackages = []; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/bc88058e-6e3a-4987-b78e-e19cb5611608"; + fsType = "ext4"; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/852F-07F1"; + fsType = "vfat"; + options = ["fmask=0022" "dmask=0022"]; + }; + + swapDevices = []; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.wlan0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; +} diff --git a/hosts/demeter/configuration.nix b/hosts/demeter/configuration.nix new file mode 100755 index 0000000..2adccad --- /dev/null +++ b/hosts/demeter/configuration.nix @@ -0,0 +1,210 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running ‘nixos-help’). +{ + config, + inputs, + pkgs, + lib, + ... +}: { + imports = [ + # Include the results of the hardware scan. + ./hardware-configuration.nix + ]; + + # Bootloader. + boot.loader = { + efi.canTouchEfiVariables = true; + timeout = 15; + # Lanzaboote currently replaces the systemd-boot module. + # This setting is usually set to true in configuration.nix + # generated at installation time. So we force it to false + # for now. + systemd-boot = { + enable = false; + consoleMode = "auto"; + }; + }; + + boot.lanzaboote = { + enable = true; + pkiBundle = "/etc/secureboot"; + }; + + boot.initrd.luks.devices."luks-af320a0f-b388-43f5-b5a3-af2b47cfc716".device = "/dev/disk/by-uuid/af320a0f-b388-43f5-b5a3-af2b47cfc716"; + + networking.hostName = "demeter"; # Define your hostname. + # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. + + # select kernel + boot.kernelPackages = pkgs.linuxPackages_zen; + + # Configure network proxy if necessary + # networking.proxy.default = "http://user:password@proxy:port/"; + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + + # Enable networking + networking.networkmanager.enable = true; + + # Set your time zone. + time.timeZone = "America/Los_Angeles"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; + + systemd.services = {NetworkManager-wait-online.enable = false;}; + + # Enable the X11 windowing system. + # You can disable this if you're only using the Wayland session. + services.xserver.enable = false; + + programs.nix-ld = { + enable = true; + libraries = with pkgs; [icu xorg.libXtst xorg.libXi]; + }; + + hardware.nvidia = { + modesetting.enable = true; + powerManagement.enable = true; + powerManagement.finegrained = false; + open = false; + nvidiaSettings = true; + }; + + hardware.bluetooth = { + enable = true; + powerOnBoot = true; + }; + + services.blueman.enable = true; + + hardware.graphics.enable = true; + + hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.stable; + + services.xserver.videoDrivers = ["nvidia"]; + + services.flatpak.enable = true; + + # services.desktopManager.plasma6.enable = true; + + # Configure keymap in X11 + services.xserver = { + xkb.layout = "us"; + xkb.variant = ""; + }; + + # Enable CUPS to print documents. + services.printing.enable = true; + + # Enable touchpad support (enabled default in most desktopManager). + # services.xserver.libinput.enable = true; + + # Define a user account. Don't forget to set a password with ‘passwd’. + users.users.youwen = { + isNormalUser = true; + description = "Youwen Wu"; + extraGroups = ["networkmanager" "wheel" "nixos" "realtime"]; + }; + + users.groups.realtime = {}; + + nix.settings = { + trusted-users = ["root" "youwen"]; + experimental-features = ["nix-command" "flakes"]; + }; + + services.udev.extraRules = '' + KERNEL=="cpu_dma_latency", GROUP="realtime" + ''; + + security.pam.loginLimits = [ + { + domain = "@realtime"; + type = "-"; + item = "rtprio"; + value = 98; + } + { + domain = "@realtime"; + type = "-"; + item = "memlock"; + value = "unlimited"; + } + { + domain = "@realtime"; + type = "-"; + item = "nice"; + value = -11; + } + ]; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + neovim + wget + git + curl + librewolf + gnumake + gcc + cachix + gnupg + openssh + python3 + steam-run + + # deps for neovim compilation + lua51Packages.lua + lua51Packages.luarocks + tree-sitter + ]; + + environment.variables = { + EDITOR = "nvim"; + NIX_AUTO_RUN = 1; + }; + + # tells electron apps to use Wayland + environment.sessionVariables.NIXOS_OZONE_WL = "1"; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + + programs.dconf.enable = true; + + programs.hyprland.enable = true; + + programs.zsh.enable = false; + programs.fish.enable = true; + users.users.youwen.shell = pkgs.fish; + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "24.05"; # Did you read the comment? +} diff --git a/hosts/demeter/default.nix b/hosts/demeter/default.nix old mode 100755 new mode 100644 index 2adccad..dddff51 --- a/hosts/demeter/default.nix +++ b/hosts/demeter/default.nix @@ -1,210 +1,42 @@ -# Edit this configuration file to define what should be installed on -# your system. Help is available in the configuration.nix(5) man page -# and in the NixOS manual (accessible by running ‘nixos-help’). { - config, inputs, - pkgs, - lib, + system, ... }: { - imports = [ - # Include the results of the hardware scan. - ./hardware-configuration.nix - ]; + imports = with inputs; [ + ./configuration.nix + ../../modules/nixos/gaming + ../../modules/nixos/audio + ../../modules/nixos/networking + ../../modules/nixos/fonts + ../../modules/nixos/greeter + ../../modules/nixos/core + ../../overlays - # Bootloader. - boot.loader = { - efi.canTouchEfiVariables = true; - timeout = 15; - # Lanzaboote currently replaces the systemd-boot module. - # This setting is usually set to true in configuration.nix - # generated at installation time. So we force it to false - # for now. - systemd-boot = { - enable = false; - consoleMode = "auto"; - }; - }; - - boot.lanzaboote = { - enable = true; - pkiBundle = "/etc/secureboot"; - }; - - boot.initrd.luks.devices."luks-af320a0f-b388-43f5-b5a3-af2b47cfc716".device = "/dev/disk/by-uuid/af320a0f-b388-43f5-b5a3-af2b47cfc716"; - - networking.hostName = "demeter"; # Define your hostname. - # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. - - # select kernel - boot.kernelPackages = pkgs.linuxPackages_zen; - - # Configure network proxy if necessary - # networking.proxy.default = "http://user:password@proxy:port/"; - # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; - - # Enable networking - networking.networkmanager.enable = true; - - # Set your time zone. - time.timeZone = "America/Los_Angeles"; - - # Select internationalisation properties. - i18n.defaultLocale = "en_US.UTF-8"; - - i18n.extraLocaleSettings = { - LC_ADDRESS = "en_US.UTF-8"; - LC_IDENTIFICATION = "en_US.UTF-8"; - LC_MEASUREMENT = "en_US.UTF-8"; - LC_MONETARY = "en_US.UTF-8"; - LC_NAME = "en_US.UTF-8"; - LC_NUMERIC = "en_US.UTF-8"; - LC_PAPER = "en_US.UTF-8"; - LC_TELEPHONE = "en_US.UTF-8"; - LC_TIME = "en_US.UTF-8"; - }; - - systemd.services = {NetworkManager-wait-online.enable = false;}; - - # Enable the X11 windowing system. - # You can disable this if you're only using the Wayland session. - services.xserver.enable = false; - - programs.nix-ld = { - enable = true; - libraries = with pkgs; [icu xorg.libXtst xorg.libXi]; - }; - - hardware.nvidia = { - modesetting.enable = true; - powerManagement.enable = true; - powerManagement.finegrained = false; - open = false; - nvidiaSettings = true; - }; - - hardware.bluetooth = { - enable = true; - powerOnBoot = true; - }; - - services.blueman.enable = true; - - hardware.graphics.enable = true; - - hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.stable; - - services.xserver.videoDrivers = ["nvidia"]; - - services.flatpak.enable = true; - - # services.desktopManager.plasma6.enable = true; - - # Configure keymap in X11 - services.xserver = { - xkb.layout = "us"; - xkb.variant = ""; - }; - - # Enable CUPS to print documents. - services.printing.enable = true; - - # Enable touchpad support (enabled default in most desktopManager). - # services.xserver.libinput.enable = true; - - # Define a user account. Don't forget to set a password with ‘passwd’. - users.users.youwen = { - isNormalUser = true; - description = "Youwen Wu"; - extraGroups = ["networkmanager" "wheel" "nixos" "realtime"]; - }; - - users.groups.realtime = {}; - - nix.settings = { - trusted-users = ["root" "youwen"]; - experimental-features = ["nix-command" "flakes"]; - }; - - services.udev.extraRules = '' - KERNEL=="cpu_dma_latency", GROUP="realtime" - ''; - - security.pam.loginLimits = [ + catppuccin.nixosModules.catppuccin + lix-module.nixosModules.default + lanzaboote.nixosModules.lanzaboote + home-manager.nixosModules.home-manager { - domain = "@realtime"; - type = "-"; - item = "rtprio"; - value = 98; - } - { - domain = "@realtime"; - type = "-"; - item = "memlock"; - value = "unlimited"; - } - { - domain = "@realtime"; - type = "-"; - item = "nice"; - value = -11; + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.backupFileExtension = "backup"; + home-manager.extraSpecialArgs = { + inherit inputs; + inherit system; + }; + home-manager.users.youwen = { + imports = [ + ../../users/youwen/linux/desktop + ../../users/youwen/linux/packages/x86_64 + ../../users/youwen/linux/programs + ../../users/youwen/common/neofetch + ../../users/youwen/common/neovim + ../../users/youwen/common + catppuccin.homeManagerModules.catppuccin + nixvim.homeManagerModules.nixvim + ]; + }; } ]; - - # Allow unfree packages - nixpkgs.config.allowUnfree = true; - - # List packages installed in system profile. To search, run: - # $ nix search wget - environment.systemPackages = with pkgs; [ - neovim - wget - git - curl - librewolf - gnumake - gcc - cachix - gnupg - openssh - python3 - steam-run - - # deps for neovim compilation - lua51Packages.lua - lua51Packages.luarocks - tree-sitter - ]; - - environment.variables = { - EDITOR = "nvim"; - NIX_AUTO_RUN = 1; - }; - - # tells electron apps to use Wayland - environment.sessionVariables.NIXOS_OZONE_WL = "1"; - - # Some programs need SUID wrappers, can be configured further or are - # started in user sessions. - # programs.mtr.enable = true; - programs.gnupg.agent = { - enable = true; - enableSSHSupport = true; - }; - - programs.dconf.enable = true; - - programs.hyprland.enable = true; - - programs.zsh.enable = false; - programs.fish.enable = true; - users.users.youwen.shell = pkgs.fish; - # This value determines the NixOS release from which the default - # settings for stateful data, like file locations and database versions - # on your system were taken. It‘s perfectly fine and recommended to leave - # this value at the release version of the first install of this system. - # Before changing this value read the documentation for this option - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). - system.stateVersion = "24.05"; # Did you read the comment? } diff --git a/hosts/demeter/hardware-configuration.nix.old b/hosts/demeter/hardware-configuration.nix.old deleted file mode 100755 index df06d01..0000000 --- a/hosts/demeter/hardware-configuration.nix.old +++ /dev/null @@ -1,39 +0,0 @@ -# Do not modify this file! It was generated by ‘nixos-generate-config’ -# and may be overwritten by future invocations. Please make changes -# to /etc/nixos/configuration.nix instead. -{ config, lib, pkgs, modulesPath, ... }: - -{ - imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; - - boot.initrd.availableKernelModules = - [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" ]; - boot.initrd.kernelModules = [ ]; - boot.kernelModules = [ "kvm-intel" ]; - boot.extraModulePackages = [ ]; - - fileSystems."/" = { - device = "/dev/disk/by-uuid/2616d86c-aac2-4780-9527-7b11192e783f"; - fsType = "ext4"; - }; - - fileSystems."/boot" = { - device = "/dev/disk/by-uuid/B826-E14B"; - fsType = "vfat"; - options = [ "fmask=0022" "dmask=0022" ]; - }; - - swapDevices = [ ]; - - # Enables DHCP on each ethernet and wireless interface. In case of scripted networking - # (the default) this is the recommended approach. When using systemd-networkd it's - # still possible to use this option, but it's recommended to use it in conjunction - # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - networking.useDHCP = lib.mkDefault true; - # networking.interfaces.enp6s0.useDHCP = lib.mkDefault true; - # networking.interfaces.wlo1.useDHCP = lib.mkDefault true; - - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - hardware.cpu.intel.updateMicrocode = - lib.mkDefault config.hardware.enableRedistributableFirmware; -} diff --git a/hosts/demeter/home-manager/default.nix b/hosts/demeter/home-manager/default.nix new file mode 100644 index 0000000..e69de29 diff --git a/hosts/phobos/configuration.nix b/hosts/phobos/configuration.nix new file mode 100755 index 0000000..c17278e --- /dev/null +++ b/hosts/phobos/configuration.nix @@ -0,0 +1,57 @@ +{ + inputs, + config, + pkgs, + ... +}: { + # Expose the package set, including overlays, for convenience. + # darwinPackages = inputs.self.darwinConfigurations."Youwens-MacBook-Pro".pkgs; + + # List packages installed in system profile. To search by name, run: + # $ nix-env -qaP | grep wget + environment.systemPackages = with pkgs; []; + + # Use a custom configuration.nix location. + # $ darwin-rebuild switch -I darwin-config=$HOME/.config/nixpkgs/darwin/configuration.nix + # environment.darwinConfig = "$HOME/.config/nixpkgs/darwin/configuration.nix"; + + # Auto upgrade nix package and the daemon service. + services.nix-daemon.enable = true; + # nix.package = pkgs.nix; + + nix.settings.experimental-features = "nix-command flakes"; + + nixpkgs.config.allowUnfree = true; + + # Create /etc/zshrc that loads the nix-darwin environment. + programs.zsh.enable = true; # default shell on catalina + programs.fish.enable = true; + programs.bash.enable = true; + + system.configurationRevision = + config.self.rev or config.self.dirtyRev or null; + + nixpkgs.hostPlatform = "aarch64-darwin"; + + # Used for backwards compatibility, please read the changelog before changing. + # $ darwin-rebuild changelog + system.stateVersion = 4; + + users.users.youwen = { + home = "/Users/youwen"; + description = "Youwen Wu"; + shell = pkgs.fish; + }; + + security.pam.enableSudoTouchIdAuth = true; + + fonts = { + packages = with pkgs; [ + noto-fonts + noto-fonts-cjk + noto-fonts-emoji + (nerdfonts.override {fonts = ["CascadiaCode"];}) + (google-fonts.override {fonts = ["Lora"];}) + ]; + }; +} diff --git a/hosts/phobos/default.nix b/hosts/phobos/default.nix old mode 100755 new mode 100644 index c17278e..c968d8d --- a/hosts/phobos/default.nix +++ b/hosts/phobos/default.nix @@ -1,57 +1,22 @@ -{ - inputs, - config, - pkgs, - ... -}: { - # Expose the package set, including overlays, for convenience. - # darwinPackages = inputs.self.darwinConfigurations."Youwens-MacBook-Pro".pkgs; - - # List packages installed in system profile. To search by name, run: - # $ nix-env -qaP | grep wget - environment.systemPackages = with pkgs; []; - - # Use a custom configuration.nix location. - # $ darwin-rebuild switch -I darwin-config=$HOME/.config/nixpkgs/darwin/configuration.nix - # environment.darwinConfig = "$HOME/.config/nixpkgs/darwin/configuration.nix"; - - # Auto upgrade nix package and the daemon service. - services.nix-daemon.enable = true; - # nix.package = pkgs.nix; - - nix.settings.experimental-features = "nix-command flakes"; - - nixpkgs.config.allowUnfree = true; - - # Create /etc/zshrc that loads the nix-darwin environment. - programs.zsh.enable = true; # default shell on catalina - programs.fish.enable = true; - programs.bash.enable = true; - - system.configurationRevision = - config.self.rev or config.self.dirtyRev or null; - - nixpkgs.hostPlatform = "aarch64-darwin"; - - # Used for backwards compatibility, please read the changelog before changing. - # $ darwin-rebuild changelog - system.stateVersion = 4; - - users.users.youwen = { - home = "/Users/youwen"; - description = "Youwen Wu"; - shell = pkgs.fish; - }; - - security.pam.enableSudoTouchIdAuth = true; - - fonts = { - packages = with pkgs; [ - noto-fonts - noto-fonts-cjk - noto-fonts-emoji - (nerdfonts.override {fonts = ["CascadiaCode"];}) - (google-fonts.override {fonts = ["Lora"];}) - ]; - }; +{inputs, ...}: { + imports = with inputs; [ + ./configuration.nix + home-manager.darwinModules.home-manager + { + extraSpecialArgs = {inherit inputs;}; + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.users.youwen.imports = [ + ../../users/youwen/darwin/darwin-home.nix + ../../users/youwen/common/core.nix + ../../users/youwen/common/neofetch + ../../users/youwen/common/neovim + ]; + home-manager.backupFileExtension = "backup"; + } + nix-homebrew.darwinModules.nix-homebrew + ../../modules/darwin/homebrew.nix + ../../modules/darwin/yabai.nix + ../../modules/darwin/skhd.nix + ]; } diff --git a/users/youwen/linux/hyprland/common.nix b/users/youwen/linux/hyprland/common.nix index c0facf2..7d42737 100644 --- a/users/youwen/linux/hyprland/common.nix +++ b/users/youwen/linux/hyprland/common.nix @@ -1,6 +1,12 @@ -{pkgs, ...}: { +{ + pkgs, + inputs, + system, + ... +}: { wayland.windowManager.hyprland = { enable = true; + # package = inputs.stablepkgs.legacyPackages.${system}.hyprland; settings = { exec-once = ["waypaper --restore"]; "$mod" = "SUPER"; @@ -198,7 +204,6 @@ "col.inactive_border" = "rgba(b4befecc) rgba(6c7086cc) 45deg"; layout = "dwindle"; resize_on_border = "true"; - sensitivity = "0.5"; }; misc = { @@ -224,6 +229,9 @@ special = true; }; }; + input = { + sensitivity = "0.5"; + }; }; }; diff --git a/users/youwen/linux/hyprland/laptop/default.nix b/users/youwen/linux/hyprland/laptop/default.nix index 6512099..499adfd 100644 --- a/users/youwen/linux/hyprland/laptop/default.nix +++ b/users/youwen/linux/hyprland/laptop/default.nix @@ -7,7 +7,7 @@ tap-to-click = false; scroll_factor = 0.5; }; - wayland.windowManager.hyprland.settings.general.sensitivity = lib.mkForce 1.0; + wayland.windowManager.hyprland.settings.input.sensitivity = lib.mkForce 1.0; wayland.windowManager.hyprland.settings.env = [ "HYPRCURSOR_THEME,Bibata-Modern-Ice" "HYPRCURSOR_SIZE,24" diff --git a/users/youwen/linux/packages/common-packages.nix b/users/youwen/linux/packages/common-packages.nix index 68bf4f5..93f60c9 100644 --- a/users/youwen/linux/packages/common-packages.nix +++ b/users/youwen/linux/packages/common-packages.nix @@ -36,7 +36,7 @@ with pkgs; [ # desktop apps dolphin thunderbird - vesktop + # vesktop signal-desktop gcc diff --git a/users/youwen/linux/programs/default.nix b/users/youwen/linux/programs/default.nix index 0e9d2a3..d3307ca 100644 --- a/users/youwen/linux/programs/default.nix +++ b/users/youwen/linux/programs/default.nix @@ -12,11 +12,13 @@ background_opacity = "0.8"; allow_remote_control = "socket-only"; listen_on = "unix:/tmp/kitty"; - action_alias = "kitty_scrollback_nvim kitten /home/youwen/.local/share/nvim/lazy/kitty-scrollback.nvim/python/kitty_scrollback_nvim.py"; + # action_alias = "kitty_scrollback_nvim kitten /home/youwen/.local/share/nvim/lazy/kitty-scrollback.nvim/python/kitty_scrollback_nvim.py"; + scrollback_pager = ''nvim --noplugin -c "set signcolumn=no showtabline=0" -c "silent write! /tmp/kitty_scrollback_buffer | te cat /tmp/kitty_scrollback_buffer - "''; }; keybindings = { - "kitty_mod+h" = "kitty_scrollback_nvim"; - "kitty_mod+g" = "kitty_scrollback_nvim --config ksb_builtin_last_cmd_output"; + # "kitty_mod+h" = "kitty_scrollback_nvim"; + # "kitty_mod+g" = "kitty_scrollback_nvim --config ksb_builtin_last_cmd_output"; + "kitty_mod+h" = "show_scrollback"; }; };