From fa698a64cc5e5fd507389d7855fd21b1d1c23281 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Fri, 11 Aug 2023 15:42:34 +0800 Subject: [PATCH] workflows/mosey-branch: init It's not yet fully working and the design is not yet complete. The foundation should be set with the custom gnome-session configuration though. --- modules/nixos/workflows/default.nix | 1 + .../nixos/workflows/mosey-branch/README.adoc | 26 ++ .../config/gnome-session/hyprland.session | 3 + .../config/hyprland/hyprland.conf | 86 +++++++ .../config/wayland-sessions/hyprland.desktop | 7 + .../nixos/workflows/mosey-branch/default.nix | 224 ++++++++++++++++++ 6 files changed, 347 insertions(+) create mode 100644 modules/nixos/workflows/mosey-branch/README.adoc create mode 100644 modules/nixos/workflows/mosey-branch/config/gnome-session/hyprland.session create mode 100644 modules/nixos/workflows/mosey-branch/config/hyprland/hyprland.conf create mode 100644 modules/nixos/workflows/mosey-branch/config/wayland-sessions/hyprland.desktop create mode 100644 modules/nixos/workflows/mosey-branch/default.nix diff --git a/modules/nixos/workflows/default.nix b/modules/nixos/workflows/default.nix index 054fa46e..8b73d0c9 100644 --- a/modules/nixos/workflows/default.nix +++ b/modules/nixos/workflows/default.nix @@ -18,6 +18,7 @@ in { imports = [ ./a-happy-gnome ./knome + ./mosey-branch ]; config = { diff --git a/modules/nixos/workflows/mosey-branch/README.adoc b/modules/nixos/workflows/mosey-branch/README.adoc new file mode 100644 index 00000000..29d0d190 --- /dev/null +++ b/modules/nixos/workflows/mosey-branch/README.adoc @@ -0,0 +1,26 @@ += Mosey branch +:toc: + +A workflow module of a Hyprland desktop environment featuring my link:https://github.com/foo-dogsquared/base16-bark-on-a-tree-scheme[custom colorscheme]. + +// TODO: Screenshot + +It's a dolled up setup that is mainly inspired from GNOME Shell's layout (being an enthusiastic GNOME user myself) and link:https://github.com/PoSayDone/.dotfiles_wayland/[PoSayDone's Wayland dotfiles]. +In here, I tried to recreate GNOME Shell's workflow and link:../a-happy-gnome[my GNOME configuration] as close as possible, keybindings and everything. + +Here's a list of components used for this workflow module. + +- Hyprland as the Wayland window compositor. + +- link:https://github.com/Aylur/ags/[ags] as a widget system with link:https://github.com/wmww/gtk4-layer-shell[gtk4-layer-shell]. +Since Hyprland has implemented Layer Shell protocol, we may as well try to implement them widgets ourselves (which is quite fun). + +- link:https://github.com/Kirottu/anyrun[anyrun] as the application launcher and also uses custom menu. + +- Expects GDM as the display manager. +Though you should be able to easily replace it with something else. + +- Uses a custom desktop session with link:https://gitlab.gnome.org/GNOME/gnome-session/[gnome-session]. +This allows me to make this workflow as a full desktop environment with easy access for link:https://systemd.io/DESKTOP_ENVIRONMENTS/[systemd integration]. footnote:[Some might say Hyprland is not a desktop environment but for me, every single graphical session IS a desktop environment.] + +- As most workflows, it makes use of link:https://github.com/Misterio77/nix-colors/[nix-colors] as it makes color scheme management easier. diff --git a/modules/nixos/workflows/mosey-branch/config/gnome-session/hyprland.session b/modules/nixos/workflows/mosey-branch/config/gnome-session/hyprland.session new file mode 100644 index 00000000..dec3317d --- /dev/null +++ b/modules/nixos/workflows/mosey-branch/config/gnome-session/hyprland.session @@ -0,0 +1,3 @@ +[GNOME Session] +Name=Hyprland +RequiredComponents=@requiredComponents@ diff --git a/modules/nixos/workflows/mosey-branch/config/hyprland/hyprland.conf b/modules/nixos/workflows/mosey-branch/config/hyprland/hyprland.conf new file mode 100644 index 00000000..bde09cda --- /dev/null +++ b/modules/nixos/workflows/mosey-branch/config/hyprland/hyprland.conf @@ -0,0 +1,86 @@ +# Take note not everything here is complete as the +# workflow module will also generated dynamic +# configuration for certain settings such as the +# keybindings related to the chosen terminal emulator. +decoration { + dim_inactive = true + dim_strength = 0.66 +} + +animations { + enabled = true + + bezier = ease, .84, .91, .69, 1.04 + + animation = windows, 1, 2, ease, slide + animation = workspaces, 1, 1, ease, slide + animation = fadeDim, 0, 0.5, ease +} + +input { + touchpad { + disable_while_typing = false + scroll_factor = 1.1 + middle_button_emulation = true + tap-to-click = true + } +} + +gestures { + workspace_swipe = true + workspace_swipe_fingers = 3 + workspace_swipe_invert = false +} + +misc { + disable_hyprland_logo = true + animate_manual_resizes = true + animate_mouse_windowdragging = true + + # We're going to force using this configuration + # anyways so... + disable_autoreload = true +} + +binds { + allow_workspace_cycles = true +} + +$mainMod = SUPER + +# Windows management. +bind = $mainMod, q, killactive +bind = $mainMod, y, togglefloating +bind = $mainMod, f, fullscreen +bind = $mainMod SHIFT, f, pin + +# Mouse bindings for window management. +bindm = $mainMod, mouse:272, movewindow +bindm = $mainMod, mouse:273, resizewindow + +# Workspace-related movements. +# With Vim keybindings. +bind = $mainMod, l, movefocus, r +bind = $mainMod, h, movefocus, l +bind = $mainMod, j, movefocus, u +bind = $mainMod, k, movefocus, d + +bind = $mainMod, Right, movefocus, r +bind = $mainMod, Left, movefocus, l +bind = $mainMod, Up, movefocus, u +bind = $mainMod, Down, movefocus, d + +bind = $mainMod, Tab, focuscurrentorlast +bind = $mainMod, grave, cyclenext +bind = $mainMod SHIFT, grave, cyclenext + +# Workspace management. +bind = $mainMod CTRL, l, workspace, +1 +bind = $mainMod CTRL, h, workspace, -1 +bind = $mainMod, 0, workspace, empty + +bind = $mainMod SHIFT, l, movetoworkspace, +1 +bind = $mainMod SHIFT, h, movetoworkspace, -1 + +# Applications. +bind = $mainMod, Return, exec, wezterm diff --git a/modules/nixos/workflows/mosey-branch/config/wayland-sessions/hyprland.desktop b/modules/nixos/workflows/mosey-branch/config/wayland-sessions/hyprland.desktop new file mode 100644 index 00000000..a6f304fe --- /dev/null +++ b/modules/nixos/workflows/mosey-branch/config/wayland-sessions/hyprland.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=Hyprland +Comment=foodogsquared's Hyprland-based desktop environment setup +Exec=@script@ +TryExec=@script@ +Type=Application +DesktopNames=Hyprland diff --git a/modules/nixos/workflows/mosey-branch/default.nix b/modules/nixos/workflows/mosey-branch/default.nix new file mode 100644 index 00000000..149bfafc --- /dev/null +++ b/modules/nixos/workflows/mosey-branch/default.nix @@ -0,0 +1,224 @@ +{ config, options, lib, pkgs, ... }@attrs: + +let + cfg = config.workflows.workflows.mosey-branch; + workflowName = "mosey-branch"; + + # This is used in a similar manner for GNOME desktop applications and its + # services. + prefix = "one.foodogsquared.${workflowName}."; + + hyprlandCustomGnomeSession = pkgs.substituteAll { + src = ./config/gnome-session/hyprland.session; + name = "${workflowName}.session"; + dir = "share/gnome-session"; + requiredComponents = + lib.concatMapString (component: "${prefix}${component};") ([ + "ags" + "polkit" + ] + ++ lib.optional (config.i18n.inputMethod == "fcitx5") "fcitx5" + ++ lib.optional (config.i18n.inputMethod == "ibus") "ibus"); + }; + + hyprlandStartScript = pkgs.writeShellScript "${workflowName}-hyprland-custom-start" '' + ${pkgs.gnome.gnome-session}/bin/gnome-session --session=${workflowName} + ''; + + hyprlandSessionPackage = + (pkgs.substituteAll { + src = ./config/wayland-sessions/hyprland.desktop; + name = "${workflowName}.desktop"; + dir = "share/wayland-sessions"; + script = hyprlandStartScript; + }).overrideAttrs { + passthru.providedSessions = [ workflowName ]; + }; + + requiredPackages = with pkgs; [ + # The star of this show: the window manager (or Wayland compositor if you + # want to be a hair-pulling semantic bastard). + hyprland + + # Setting up the widget system that will be used for notifications, + # bar and its widgets, and custom menus. + gjs + ags + gtk4-layer-shell + + # Install with the custom session. + hyprlandCustomGnomeSession + + # Optional dependencies that are required in this workflow module. + socat + qt5.qtwayland + qt6.qtwayland + + # The authentication agent. + polkit_gnome + + # The themes. + hicolor-icon-theme + + # The chosen terminal emulator. + wezterm + ]; + + createPrefixedServices = name: value: + lib.nameValuePair "${prefix}${name}" (value // { + partOf = [ "graphical-session.target" ]; + wantedBy = [ "gnome-session.target" ]; + }); +in +{ + options.workflows.workflows.mosey-branch = { + enable = lib.mkEnableOption "${workflowName}, foodogsquared's Hyprland-based desktop environment"; + + extraApps = lib.mkOption { + description = '' + Extra applications to be installed alongside the desktop environment. + ''; + internal = true; + type = with lib.types; listOf package; + default = with pkgs; [ + amberol # Simplest music player. + gradience # Gradually theme your shell with cadence. + blanket # Blanket yourself in ambient sounds. + eyedropper # Some nice eyedropper tool. + shortwave # Your internet radio. + flowtime # A nice timer for overworked students. + gnome-solanum # Cute little matador timer. + gnome-frog # Read them QR codes where it sends you to that one video everytime. + gnome.gnome-boxes # Virtual machines, son. + tangram # Make yourself a professional social media manager. + ]; + }; + }; + + config = lib.mkIf cfg.enable (lib.mkMerge [ + { + environment.systemPackages = cfg.extraApps ++ requiredPackages; + + # Our preferred display manager. + services.xserver = { + enable = true; + displayManager = { + gdm.enable = lib.mkDefault true; + sessionPackages = [ hyprlandSessionPackage ]; + }; + updateDbusEnvironment = true; + }; + + # Setting up some hardware settings. + hardware.opengl.enable = true; + hardware.bluetooth.enable = true; + services.udisks2.enable = true; + services.upower.enable = true; + services.power-profiles-daemon.enable = true; + services.colord.enable = true; + services.system-config-printer.enable = config.services.printing.enable; + + # Setting up some more core services. + security.polkit.enable = true; + services.accounts-daemon.enable = true; + services.dleyna-renderer.enable = true; + services.dleyna-server.enable = true; + programs.dconf.enable = true; + programs.xwayland.enable = true; + + fonts.enableDefaultPackages = true; + + # The phone sync component which is handy. + programs.kdeconnect = { + enable = true; + package = pkgs.valent; + }; + + # Harmonious themes. Since we're making this very similar to GNOME + # appearance-wise, layout-wise, and setup-wise, we may as well make it + # similar. + qt = { + enable = true; + platformTheme = "gnome"; + style = "adwaita"; + }; + + xdg.portal = { + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-hyprland + xdg-desktop-portal-gtk + ]; + }; + } + + # These are all intended to be started with gnome-session. + # Much of the templates used are from Phosh systemd templates at + # https://gitlab.gnome.org/World/Phosh/phosh/-/blob/main/data/systemd. + # Big thanks to them! :) + { + systemd.user.targets."${prefix}" = { + description = "${workflowName} Hyprland shell"; + documentation = [ "man:systemd.special(7)" ]; + unitConfig.DefaultDependencies = "no"; + requisite = [ "gnome-session-initialized.target" ]; + partOf = [ "gnome-session-initialized.target" ]; + before = [ "gnome-session-initialized.target" ]; + + wants = [ "${prefix}.service" ]; + after = [ "${prefix}.service" ]; + }; + + systemd.user.services = lib.mapAttrs' createPrefixedServices { + ags = { + description = "Widget system layer for the desktop"; + script = "${pkgs.ags}/bin/ags"; + }; + + polkit = { + description = "Authentication agent for the desktop session"; + script = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"; + }; + + fcitx5 = lib.mkIf (config.i18n.inputMethod.enabled == "fcitx5") { + description = "Input method engine for the desktop session"; + script = "${config.i18n.inputMethod.package}/bin/fcitx5"; + }; + + ibus = lib.mkIf (config.i18n.inputMethod.enabled == "ibus") { + description = "Input method engine for the desktop session"; + script = "${config.i18n.inputMethod.package}/bin/ibus start"; + }; + } // { + "${prefix}" = { + description = "${workflowName}, a custom desktop session with Hyprland"; + documentation = [ "https://wiki.hyprland.org" ]; + after = [ "gnome-manager-manager.target" ]; + requisite = [ "gnome-session-initialized.target" ]; + partOf = [ "gnome-session-initialized.target" ]; + + unitConfig = { + OnFailure = "gnome-session-shutdown.target"; + OnFailureJobMode = "replace-irreversibly"; + CollectMode = "inactive-or-failed"; + RefuseManualStart = true; + RefuseManualStop = true; + }; + + script = "${pkgs.hyprland}/bin/Hyprland --config ${./config/hyprland/hyprland.conf}"; + }; + }; + } + + # Setting up my project-specific profiles. This is only to be applied for + # my setup. If you're not foodogsquared and you're using my project as one + # of the flake input, this shouldn't be applied nor be used in the first + # place. + (lib.mkIf (attrs ? _isfoodogsquaredcustom && attrs._isfoodogsquaredcustom) { + profiles.i18n = { + enable = true; + fcitx5.enable = true; + }; + }) + ]); +}