{ config, lib, pkgs, ... }: let workflowName = "a-happy-gnome"; cfg = config.workflows.workflows.${workflowName}; requiredApps = with pkgs; [ # The application menu. junction # The application launcher for your one-handed keyboard handling (the # other is in the mouse, if you're thinking something else). kando (makeDesktopItem { name = "kando"; desktopName = "Kando"; destination = "/etc/xdg/autostart"; exec = "${lib.getExe kando} --gapplication-service"; icon = "kando"; genericName = "Pie Menu"; }) # Valent...ines 'tis season to share... phone data or something. valent ]; # All of the shell extensions plus their required extensions. shellExtensions' = cfg.shellExtensions ++ (with pkgs.gnomeExtensions; [ valent kando-integration paperwm ]); workspaceSubmodule = { name, ... }: { freeformType = with lib.types; attrsOf anything; options = { name = lib.mkOption { type = lib.types.str; default = name; description = "The formal name of the workspace."; example = "Software development"; }; }; }; in { options.workflows.enable = lib.mkOption { type = with lib.types; listOf (enum [ workflowName ]); }; options.workflows.workflows.${workflowName} = { shellExtensions = lib.mkOption { type = with lib.types; listOf package; description = '' A list of extra GNOME Shell extensions to be included. Take note the package should contain `passthru.extensionUuid` to be used for enabling the extensions. ''; default = with pkgs.gnomeExtensions; [ alphabetical-app-grid appindicator arcmenu burn-my-windows caffeine fly-pie just-perfection kimpanel light-style runcat windownavigator ]; example = lib.literalExpression '' with pkgs.gnomeExtensions; [ appindicator gsconnect runcat just-perfection ]; ''; }; extraApps = lib.mkOption { type = with lib.types; listOf package; description = "A list of applications to be included in the theme."; default = with pkgs; [ adw-gtk3 # A nice theme for GTK3. amberol # An unambitious music player. authenticator # 2-factor codes for 2-factor storages. blanket # Zen... dialect # Your gateway to polyglotting. eyedropper # Some nice eyedropper tool. flowtime # Some nice timer for those overworking. fractal # Your gateway to the matrix. gnome-decoder # Go with them QR codes. gnome-frog # Graphical OCR with Tesseract that I always wanted. gnome-solanum # Cute little matodor timers. dconf-editor # A saner version of Windows registry. gnome-boxes # Virtual machines, son. mission-center # It is your duty to monitor your system. polari # Your gateway to one of the most hidden and cobweb-ridden parts of the internet. ;) gradience # Make it rain! handbrake # Take a break from those custom ffmpeg conversion scripts. shortwave # Yer' humble internet radio. symbolic-preview # Them symbols... it's important. gtranslator # It's not a Google translator app, I'll tell you that. tangram # Your social media manager, probably. ymuse # I muse with a simple MPD client. gnome-secrets # Feel the secureness, O Keeper of Secrets. gnome-backgrounds # Default backgrounds. gnome-menus # It is required for custom menus in extensions. gnome-extension-manager # The cooler GNOME extensions app. gnome-search-provider-recoll # This is here for some reason. # Nautilus extensions nautilus-annotations nautilus-open-any-terminal # Extra background images. fedora-backgrounds.f38 fedora-backgrounds.f37 ]; example = lib.literalExpression '' with pkgs; [ gnome.polari ]; ''; }; disableSearchProviders = lib.mkOption { type = with lib.types; listOf (coercedTo str (lib.removeSuffix ".desktop") str); description = '' A list of the application filenames (without the `.desktop` part) where its GNOME Shell search provider is to be disabled. By default, it disables some of the search providers from the default list of applications in {option}`workflows.workflows.a-happy-gnome.extraApps`. ''; default = [ "org.gnome.seahorse.Application" "org.gnome.Photos" "org.gnome.Epiphany" "app.drey.Dialect" "com.belmoussaoui.Authenticator" ]; apply = lib.map (x: "${x}.desktop"); }; disableNotifications = lib.mkOption { type = with lib.types; listOf str; description = '' A list of identifiers of the application's notification to be disabled within GNOME Shell. By default, it just list a few from the default value of {option}`workflows.workflows.a-happy-gnome.extraApps`. ''; default = [ "re-sonny-tangram" "org-gnome-polari" "io-github-hexchat" "org-gnome-evolution-alarm-notify" "thunderbird" ]; }; paperwm = { workspaces = lib.mkOption { type = with lib.types; attrsOf (submodule workspaceSubmodule); default = { }; description = '' A set of workspaces and their properties for PaperWM. ''; example = lib.literalExpression '' { media = { name = "Media"; index = lib.gvariant.mkInt32 0; color = "rgb(98,160,234)"; }; dev = { name = "Software dev't"; index = lib.gvariant.mkInt32 1; color = "#99c1f1"; }; } ''; }; enablePresetWorkspaces = lib.mkEnableOption "preset workspace options for PaperWM" // { default = true; }; enableStaticWorkspace = lib.mkEnableOption "static workspaces configuration for PaperWM"; winprops = lib.mkOption { type = let inherit (lib.types) listOf; settingsFormat = pkgs.formats.json { }; in with lib.types; listOf (settingsFormat.type); description = '' A list of default winprops settings for PaperWM. ''; default = [ ]; example = lib.literalExpression '' [ { wm_class = "Firefox"; preferredWidth = "100%"; spaceIndex = 0; } { wm_class = "org.wezfurlong.wezterm"; preferredWidth = "100%"; spaceIndex = 1; } { wm_class = "Spotify"; title = "Spotify Premium"; spaceIndex = 0; } ] ''; }; }; }; config = lib.mkIf (lib.elem workflowName config.workflows.enable) { # Enable GNOME. services.xserver = { enable = true; desktopManager.gnome.enable = true; }; workflows.workflows.a-happy-gnome.paperwm.workspaces = lib.mkIf cfg.paperwm.enablePresetWorkspaces { media = { name = "Media"; index = lib.gvariant.mkInt32 0; color = "#99c1f1"; # GNOME Blue 1 }; research = { name = "Research"; index = lib.gvariant.mkInt32 1; color = "#613583"; # GNOME Purple 5 }; creative = { name = "Creative work"; index = lib.gvariant.mkInt32 2; color = "#f8e45c"; # GNOME Yellow 2 }; dev = { name = "Software dev't"; index = lib.gvariant.mkInt32 3; color = "#1c71d8"; # GNOME Blue 4 }; work = { name = "Work"; index = lib.gvariant.mkInt32 4; color = "#ff7800"; # GNOME Orange 3 }; }; # All GNOME-related additional options. services.gnome = { core-os-services.enable = true; core-shell.enable = true; core-utilities.enable = true; # It doesn't need to since we're not first-timers, yeah? gnome-initial-setup.enable = false; }; # It makes Nix store directory read/write so no... services.packagekit.enable = false; # Bring all of the dconf keyfiles in there. programs.dconf = { enable = true; # In this case, we're using the default user dconf profile which is the # fallback for every dconf-using components. Pretty handy. profiles.user.databases = lib.singleton { # Get them keyfiles. keyfiles = [ ./config/dconf ]; settings = lib.mkMerge [ { "org/gnome/desktop/search-providers" = { disabled = cfg.disableSearchProviders; }; "org/gnome/shell" = { enabled-extensions = lib.map (p: p.extensionUuid) shellExtensions'; }; } # Disable all of the messenger's notification (only the annoying # ones). (lib.pipe cfg.disableNotifications [ (lib.map (app: lib.nameValuePair "org/gnome/desktop/notifications/application/${app}" { show-banners = false; })) lib.listToAttrs ]) (lib.mkIf (cfg.paperwm.winprops != [ ]) { "org/gnome/shell/extensions/paperwm".winprops = lib.map lib.strings.toJSON cfg.winprops; }) (lib.mkIf (cfg.paperwm.workspaces != { }) ( let mkWorkspaceConfig = name: value: lib.nameValuePair "org/gnome/shell/extensions/paperwm/workspaces/${name}" value; workspaces = lib.attrNames cfg.paperwm.workspaces; in { "org/gnome/shell/extensions/paperwm/workspaces".list = workspaces; } // lib.mapAttrs' mkWorkspaceConfig cfg.paperwm.workspaces )) (lib.mkIf cfg.paperwm.enableStaticWorkspace { "org/gnome/mutter/dynamic-workspaces" = false; "org/gnome/desktop/wm/preferences/num-workspaces" = let workspaces = lib.attrNames cfg.paperwm.workspaces; in lib.gvariant.mkInt32 (lib.length workspaces); }) ]; }; }; xdg.autostart.enable = true; xdg.mime = { enable = true; desktops.gnome.defaultApplications = { # Default application for web browser. "text/html" = "re.sonny.Junction.desktop"; # Default handler for all files. Not all applications will # respect it, though. "x-scheme-handler/file" = "re.sonny.Junction.desktop"; # Default handler for directories. "inode/directory" = "re.sonny.Junction.desktop"; }; }; environment.systemPackages = requiredApps ++ shellExtensions' ++ cfg.extraApps; }; }